renaming: ndn-cpp to ndn-cpp-dev
Change-Id: Iff3e4ff53a0005b7dd35c57d03da76b347170d03
diff --git a/include/ndn-cpp-dev/c/common.h b/include/ndn-cpp-dev/c/common.h
new file mode 100644
index 0000000..42edcef
--- /dev/null
+++ b/include/ndn-cpp-dev/c/common.h
@@ -0,0 +1,33 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_COMMON_H
+#define NDN_COMMON_H
+
+#include <ndn-cpp-dev/ndn-cpp-config.h>
+#include <stdint.h>
+// TODO: Is stddef.h portable?
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * A time interval represented as the number of milliseconds.
+ */
+typedef int64_t ndn_Milliseconds;
+
+/**
+ * The calendar time represented as the number of milliseconds since 1/1/1970.
+ */
+typedef int64_t ndn_MillisecondsSince1970;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/ndn-cpp-dev/c/data-types.h b/include/ndn-cpp-dev/c/data-types.h
new file mode 100644
index 0000000..668786b
--- /dev/null
+++ b/include/ndn-cpp-dev/c/data-types.h
@@ -0,0 +1,27 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_DATA_TYPES_H
+#define NDN_DATA_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ ndn_ContentType_DATA = 0,
+ ndn_ContentType_ENCR = 1,
+ ndn_ContentType_GONE = 2,
+ ndn_ContentType_KEY = 3,
+ ndn_ContentType_LINK = 4,
+ ndn_ContentType_NACK = 5
+} ndn_ContentType;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/ndn-cpp-dev/c/encoding/element-listener.h b/include/ndn-cpp-dev/c/encoding/element-listener.h
new file mode 100644
index 0000000..af88a85
--- /dev/null
+++ b/include/ndn-cpp-dev/c/encoding/element-listener.h
@@ -0,0 +1,39 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_ELEMENT_LISTENER_H
+#define NDN_ELEMENT_LISTENER_H
+
+#include "../common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** An ndn_ElementListener struct holds a function pointer onReceivedElement. You can extend this struct with data that
+ * will be passed to onReceivedElement.
+ */
+struct ndn_ElementListener {
+ void (*onReceivedElement)(struct ndn_ElementListener *self, uint8_t *element, size_t elementLength); /**< see ndn_ElementListener_initialize */
+};
+
+/**
+ * Initialize an ndn_ElementListener struct to use the onReceivedElement function pointer.
+ * @param self pointer to the ndn_ElementListener struct
+ * @param onReceivedElement pointer to a function which is called when an entire binary XML element is received.
+ * self is the pointer to this ndn_ElementListener struct. See ndn_BinaryXmlElementReader_onReceivedData.
+ */
+static inline void ndn_ElementListener_initialize
+ (struct ndn_ElementListener *self, void (*onReceivedElement)(struct ndn_ElementListener *self, uint8_t *element, size_t elementLength))
+{
+ self->onReceivedElement = onReceivedElement;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/ndn-cpp-dev/c/forwarding-flags.h b/include/ndn-cpp-dev/c/forwarding-flags.h
new file mode 100644
index 0000000..863bf04
--- /dev/null
+++ b/include/ndn-cpp-dev/c/forwarding-flags.h
@@ -0,0 +1,55 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_FORWARDING_FLAGS_H
+#define NDN_FORWARDING_FLAGS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * An ndn_ForwardingFlags object holds the flags which specify how the forwarding daemon should forward an interest for
+ * a registered prefix. We use a separate ForwardingFlags object to retain future compatibility if the daemon forwarding
+ * bits are changed, amended or deprecated.
+ */
+struct ndn_ForwardingFlags {
+ int active; /**< 1 if the flag is set, 0 if cleared. */
+ int childInherit;
+ int advertise;
+ int last;
+ int capture;
+ int local;
+ int tap;
+ int captureOk;
+};
+
+/**
+ * Initialize an ndn_ForwardingFlags struct with the default with "active" and "childInherit" set and all other flags cleared.
+ * @param self A pointer to the ndn_ForwardingFlags struct.
+ */
+void ndn_ForwardingFlags_initialize(struct ndn_ForwardingFlags *self);
+
+/**
+ * Get an integer with the bits set according to the flags as used by the ForwardingEntry message.
+ * @param self A pointer to the ndn_ForwardingFlags struct.
+ * @return An integer with the bits set.
+ */
+int ndn_ForwardingFlags_getForwardingEntryFlags(struct ndn_ForwardingFlags *self);
+
+/**
+ * Set the flags according to the bits in forwardingEntryFlags as used by the ForwardingEntry message.
+ * @param self A pointer to the ndn_ForwardingFlags struct.
+ * @param flags An integer with the bits set.
+ */
+void ndn_ForwardingFlags_setForwardingEntryFlags(struct ndn_ForwardingFlags *self, int forwardingEntryFlags);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/ndn-cpp-dev/c/interest-types.h b/include/ndn-cpp-dev/c/interest-types.h
new file mode 100644
index 0000000..a464e17
--- /dev/null
+++ b/include/ndn-cpp-dev/c/interest-types.h
@@ -0,0 +1,36 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_INTEREST_TYPES_H
+#define NDN_INTEREST_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ ndn_Exclude_COMPONENT = 0,
+ ndn_Exclude_ANY = 1
+} ndn_ExcludeType;
+
+enum {
+ ndn_Interest_CHILD_SELECTOR_LEFT = 0,
+ ndn_Interest_CHILD_SELECTOR_RIGHT = 1,
+
+ ndn_Interest_ANSWER_NO_CONTENT_STORE = 0,
+ ndn_Interest_ANSWER_CONTENT_STORE = 1,
+ ndn_Interest_ANSWER_GENERATED = 2,
+ ndn_Interest_ANSWER_STALE = 4, // Stale answer OK
+ ndn_Interest_MARK_STALE = 16, // Must have scope 0. Michael calls this a "hack"
+
+ ndn_Interest_DEFAULT_ANSWER_ORIGIN_KIND = ndn_Interest_ANSWER_CONTENT_STORE | ndn_Interest_ANSWER_GENERATED
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/ndn-cpp-dev/c/key-types.h b/include/ndn-cpp-dev/c/key-types.h
new file mode 100644
index 0000000..712aee8
--- /dev/null
+++ b/include/ndn-cpp-dev/c/key-types.h
@@ -0,0 +1,31 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_KEY_TYPES_H
+#define NDN_KEY_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ ndn_KeyLocatorType_KEY = 1,
+ ndn_KeyLocatorType_CERTIFICATE = 2,
+ ndn_KeyLocatorType_KEYNAME = 3
+} ndn_KeyLocatorType;
+
+typedef enum {
+ ndn_KeyNameType_PUBLISHER_PUBLIC_KEY_DIGEST = 1,
+ ndn_KeyNameType_PUBLISHER_CERTIFICATE_DIGEST = 2,
+ ndn_KeyNameType_PUBLISHER_ISSUER_KEY_DIGEST = 3,
+ ndn_KeyNameType_PUBLISHER_ISSUER_CERTIFICATE_DIGEST = 4
+} ndn_KeyNameType;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/ndn-cpp-dev/c/util/crypto.h b/include/ndn-cpp-dev/c/util/crypto.h
new file mode 100644
index 0000000..43d47eb
--- /dev/null
+++ b/include/ndn-cpp-dev/c/util/crypto.h
@@ -0,0 +1,30 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_CRYPTO_H
+#define NDN_CRYPTO_H
+
+#include <openssl/ssl.h>
+#include <openssl/rsa.h>
+#include <ndn-cpp-dev/c/common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Compute the sha-256 digest of data.
+ * @param data Pointer to the input byte array.
+ * @param dataLength The length of data.
+ * @param digest A pointer to a buffer of size SHA256_DIGEST_LENGTH to receive the data.
+ */
+void ndn_digestSha256(const uint8_t *data, size_t dataLength, uint8_t *digest);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/ndn-cpp-dev/common.hpp b/include/ndn-cpp-dev/common.hpp
new file mode 100644
index 0000000..59c49b5
--- /dev/null
+++ b/include/ndn-cpp-dev/common.hpp
@@ -0,0 +1,101 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_COMMON_HPP
+#define NDN_COMMON_HPP
+
+#include <vector>
+// common.h include ndn-cpp-config.h.
+#include "c/common.h"
+
+#if NDN_CPP_HAVE_CXX11
+
+#if (__cplusplus < 201103L)
+#error "NDN-CPP-DEV library is configured and compiled in C++11 mode, but the current compiler is not C++11 enabled"
+#endif
+
+// Depending on where ./configure found shared_ptr, define the ptr_lib namespace.
+// We always use ndn::ptr_lib.
+// #if NDN_CPP_HAVE_STD_SHARED_PTR
+#include <memory>
+namespace ndn { namespace ptr_lib = std; }
+
+// #if NDN_CPP_HAVE_STD_FUNCTION
+#include <functional>
+namespace ndn { namespace func_lib = std; }
+
+#elif NDN_CPP_USE_SYSTEM_BOOST
+
+// #if NDN_CPP_HAVE_BOOST_SHARED_PTR
+#include <boost/shared_ptr.hpp>
+#include <boost/make_shared.hpp>
+namespace ndn { namespace ptr_lib = boost; }
+
+// #if NDN_CPP_HAVE_BOOST_FUNCTION
+#include <boost/function.hpp>
+#include <boost/bind.hpp>
+namespace ndn { namespace func_lib = boost; }
+
+#else // use embedded boost headers
+/* Use the boost header files in this distribution that were extracted with:
+cd <BOOST DEVELOPMENT DIRECTORY WITH boost SUBDIRECTORY>
+dist/bin/bcp --namespace=ndnboost shared_ptr make_shared weak_ptr function bind any iostreams <NDN-CPP-DEV ROOT>/include
+cd <NDN-CPP-DEV ROOT>/include
+rm -rf boost.css boost.png Jamroot libs
+mv boost ndnboost
+cd ndnboost
+# Replace when including files.
+(unset LANG; find . -type f -exec sed -i '' 's/\<boost\//\<ndnboost\//g' {} +)
+(unset LANG; find . -type f -exec sed -i '' 's/\"boost\//\"ndnboost\//g' {} +)
+(unset LANG; find . -type f -exec sed -i '' 's/ boost\// ndnboost\//g' {} +)
+(unset LANG; find . -type f -exec sed -i '' 's/(boost\//(ndnboost\//g' {} +)
+# Replace macro definitions.
+(unset LANG; find . -type f -exec sed -i '' 's/BOOST_/NDNBOOST_/g' {} +)
+# Replace header include guards which don't start with BOOST_ . This may result in some with NDNBOOST twice, but that is OK.
+(unset LANG; find . -type f -exec sed -i '' 's/_DWA/_NDNBOOST_DWA/g' {} +)
+(unset LANG; find . -type f -exec sed -i '' 's/ UUID_/ NDNBOOST_UUID_/g' {} +)
+(unset LANG; find . -type f -exec sed -i '' 's/ FILE_boost/ FILE_ndnboost/g' {} +)
+# Replace the mpl_ barrier namespace. This should only change file adl_barrier.hpp.
+(unset LANG; find . -type f -exec sed -i '' 's/ mpl_/ ndnboost_mpl_/g' {} +)
+ */
+#include <ndnboost/shared_ptr.hpp>
+#include <ndnboost/make_shared.hpp>
+namespace ndn { namespace ptr_lib = ndnboost; }
+
+// Use the boost header files in this distribution that were extracted as above:
+#include <ndnboost/function.hpp>
+#include <ndnboost/bind.hpp>
+namespace ndn { namespace func_lib = ndnboost; }
+
+#endif
+
+namespace ndn {
+
+/**
+ * A time interval represented as the number of milliseconds.
+ */
+typedef int64_t Milliseconds;
+
+/**
+ * The calendar time represented as the number of milliseconds since 1/1/1970.
+ */
+typedef int64_t MillisecondsSince1970;
+
+/**
+ * Return the hex representation of the bytes in array.
+ * @param array The array of bytes.
+ * @return Hex string.
+ */
+std::string
+toHex(const std::vector<uint8_t>& array);
+
+MillisecondsSince1970
+getNow();
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/data.hpp b/include/ndn-cpp-dev/data.hpp
new file mode 100644
index 0000000..e2d9451
--- /dev/null
+++ b/include/ndn-cpp-dev/data.hpp
@@ -0,0 +1,289 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_DATA_HPP
+#define NDN_DATA_HPP
+
+#include "common.hpp"
+#include "name.hpp"
+#include "encoding/block.hpp"
+
+#include "signature.hpp"
+#include "meta-info.hpp"
+#include "key-locator.hpp"
+
+namespace ndn {
+
+class Data {
+public:
+ struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+ /**
+ * @brief Create an empty Data object
+ */
+ inline
+ Data();
+
+ /**
+ * @brief Create a new Data object with the given name
+ * @param name A reference to the name which is copied.
+ */
+ inline
+ Data(const Name& name);
+
+ /**
+ * @brief The virtual destructor.
+ */
+ inline virtual
+ ~Data();
+
+ /**
+ * @brief Encode this Data for a wire format.
+ * @return The encoded byte array.
+ */
+ const Block&
+ wireEncode() const;
+
+ /**
+ * @brief Decode the input using a particular wire format and update this Data.
+ * @param input The input byte array to be decoded.
+ */
+ void
+ wireDecode(const Block &wire);
+
+ inline const Name&
+ getName() const;
+
+ /**
+ * @brief Set name to a copy of the given Name.
+ *
+ * @param name The Name which is copied.
+ * @return This Data so that you can chain calls to update values.
+ */
+ inline void
+ setName(const Name& name);
+
+ inline const MetaInfo&
+ getMetaInfo() const;
+
+ /**
+ * @brief Set metaInfo to a copy of the given MetaInfo.
+ * @param metaInfo The MetaInfo which is copied.
+ * @return This Data so that you can chain calls to update values.
+ */
+ inline void
+ setMetaInfo(const MetaInfo& metaInfo);
+
+ ///////////////////////////////////////////////////////////////
+ // MetaInfo proxy methods
+ inline uint32_t
+ getContentType() const;
+
+ inline void
+ setContentType(uint32_t type);
+
+ inline Milliseconds
+ getFreshnessPeriod() const;
+
+ inline void
+ setFreshnessPeriod(Milliseconds freshnessPeriod);
+
+ /**
+ * @brief Get content Block
+ *
+ * To access content value, one can use value()/value_size() or
+ * value_begin()/value_end() methods of the Block class
+ */
+ inline const Block&
+ getContent() const;
+
+ /**
+ * @brief Set the content to a copy of the data in the vector.
+ * @param content A vector whose contents are copied.
+ * @return This Data so that you can chain calls to update values.
+ */
+ inline void
+ setContent(const uint8_t* content, size_t contentLength);
+
+ inline void
+ setContent(const Block& content);
+
+ inline void
+ setContent(const ConstBufferPtr &contentValue);
+
+ inline const Signature&
+ getSignature() const;
+
+ /**
+ * @brief Set the signature to a copy of the given signature.
+ * @param signature The signature object which is cloned.
+ */
+ inline void
+ setSignature(const Signature& signature);
+
+ inline void
+ setSignatureValue(const Block &value);
+
+private:
+ /**
+ * @brief Clear the wire encoding.
+ */
+ inline void
+ onChanged();
+
+private:
+ Name name_;
+ MetaInfo metaInfo_;
+ mutable Block content_;
+ Signature signature_;
+
+ mutable Block wire_;
+};
+
+inline
+Data::Data()
+ : content_(Tlv::Content) // empty content
+{
+}
+
+inline
+Data::Data(const Name& name)
+ : name_(name)
+{
+}
+
+inline
+Data::~Data()
+{
+}
+
+inline const Name&
+Data::getName() const
+{
+ return name_;
+}
+
+inline void
+Data::setName(const Name& name)
+{
+ onChanged();
+ name_ = name;
+}
+
+inline const MetaInfo&
+Data::getMetaInfo() const
+{
+ return metaInfo_;
+}
+
+inline void
+Data::setMetaInfo(const MetaInfo& metaInfo)
+{
+ onChanged();
+ metaInfo_ = metaInfo;
+}
+
+inline uint32_t
+Data::getContentType() const
+{
+ return metaInfo_.getType();
+}
+
+inline void
+Data::setContentType(uint32_t type)
+{
+ onChanged();
+ metaInfo_.setType(type);
+}
+
+inline Milliseconds
+Data::getFreshnessPeriod() const
+{
+ return metaInfo_.getFreshnessPeriod();
+}
+
+inline void
+Data::setFreshnessPeriod(Milliseconds freshnessPeriod)
+{
+ onChanged();
+ metaInfo_.setFreshnessPeriod(freshnessPeriod);
+}
+
+inline const Block&
+Data::getContent() const
+{
+ if (!content_.hasWire())
+ content_.encode();
+ return content_;
+}
+
+inline void
+Data::setContent(const uint8_t* content, size_t contentLength)
+{
+ onChanged();
+
+ content_ = dataBlock(Tlv::Content, content, contentLength);
+}
+
+inline void
+Data::setContent(const ConstBufferPtr &contentValue)
+{
+ onChanged();
+
+ content_ = Block(Tlv::Content, contentValue); // not real a wire encoding yet
+}
+
+inline void
+Data::setContent(const Block& content)
+{
+ onChanged();
+
+ if (content.type() == Tlv::Content)
+ content_ = content;
+ else {
+ content_ = Block(Tlv::Content, content);
+ }
+}
+
+inline const Signature&
+Data::getSignature() const
+{
+ return signature_;
+}
+
+inline void
+Data::setSignature(const Signature& signature)
+{
+ onChanged();
+ signature_ = signature;
+}
+
+inline void
+Data::setSignatureValue(const Block &value)
+{
+ onChanged();
+ signature_.setValue(value);
+}
+
+
+inline void
+Data::onChanged()
+{
+ // The values have changed, so the wire format is invalidated
+
+ // !!!Note!!! Signature is not invalidated and it is responsibility of
+ // the application to do proper re-signing if necessary
+
+ wire_.reset();
+}
+
+std::ostream&
+operator << (std::ostream &os, const Data &data);
+
+} // namespace ndn
+
+#endif
diff --git a/include/ndn-cpp-dev/encoding/binary-xml-wire-format.hpp b/include/ndn-cpp-dev/encoding/binary-xml-wire-format.hpp
new file mode 100644
index 0000000..cb4f0aa
--- /dev/null
+++ b/include/ndn-cpp-dev/encoding/binary-xml-wire-format.hpp
@@ -0,0 +1,88 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_BINARYXMLWIREFORMAT_HPP
+#define NDN_BINARYXMLWIREFORMAT_HPP
+
+#include "wire-format.hpp"
+
+namespace ndn {
+
+/**
+ * A BinaryXmlWireFormat extends WireFormat to override its virtual methods to implement encoding and decoding
+ * using binary XML.
+ */
+class BinaryXmlWireFormat : public WireFormat {
+public:
+ /**
+ * Encode interest in binary XML and return the encoding.
+ * @param interest The Interest object to encode.
+ * @return A Blob containing the encoding.
+ */
+ virtual Blob
+ encodeInterest(const Interest& interest);
+
+ /**
+ * Decode input as an interest in binary XML and set the fields of the interest object.
+ * @param interest The Interest object whose fields are updated.
+ * @param input A pointer to the input buffer to decode.
+ * @param inputLength The number of bytes in input.
+ */
+ virtual void
+ decodeInterest(Interest& interest, const uint8_t *input, size_t inputLength);
+
+ /**
+ * Encode data with binary XML and return the encoding.
+ * @param data The Data object to encode.
+ * @param signedPortionBeginOffset Return the offset in the encoding of the beginning of the signed portion.
+ * If you are not encoding in order to sign, you can call encodeData(const Data& data) to ignore this returned value.
+ * @param signedPortionEndOffset Return the offset in the encoding of the end of the signed portion.
+ * If you are not encoding in order to sign, you can call encodeData(const Data& data) to ignore this returned value.
+ * @return A Blob containing the encoding.
+ */
+ virtual Blob
+ encodeData
+ (const Data& data, size_t *signedPortionBeginOffset, size_t *signedPortionEndOffset);
+
+ /**
+ * Decode input as a data packet in binary XML and set the fields in the data object.
+ * @param data The Data object whose fields are updated.
+ * @param input A pointer to the input buffer to decode.
+ * @param inputLength The number of bytes in input.
+ * @param signedPortionBeginOffset Return the offset in the input buffer of the beginning of the signed portion.
+ * If you are not decoding in order to verify, you can call
+ * decodeData(Data& data, const uint8_t *input, size_t inputLength) to ignore this returned value.
+ * @param signedPortionEndOffset Return the offset in the input buffer of the end of the signed portion.
+ * If you are not decoding in order to verify, you can call
+ * decodeData(Data& data, const uint8_t *input, size_t inputLength) to ignore this returned value.
+ */
+ virtual void
+ decodeData
+ (Data& data, const uint8_t *input, size_t inputLength, size_t *signedPortionBeginOffset, size_t *signedPortionEndOffset);
+
+ /**
+ * Encode forwardingEntry in binary XML and return the encoding.
+ * @param forwardingEntry The ForwardingEntry object to encode.
+ * @return A Blob containing the encoding.
+ */
+ virtual Blob
+ encodeForwardingEntry(const ForwardingEntry& forwardingEntry);
+
+ /**
+ * Decode input as a forwarding entry in binary XML and set the fields of the forwardingEntry object.
+ * @param forwardingEntry The ForwardingEntry object whose fields are updated.
+ * @param input A pointer to the input buffer to decode.
+ * @param inputLength The number of bytes in input.
+ */
+ virtual void
+ decodeForwardingEntry(ForwardingEntry& forwardingEntry, const uint8_t *input, size_t inputLength);
+};
+
+}
+
+#endif
+
diff --git a/include/ndn-cpp-dev/encoding/block-helpers.hpp b/include/ndn-cpp-dev/encoding/block-helpers.hpp
new file mode 100644
index 0000000..c3ae196
--- /dev/null
+++ b/include/ndn-cpp-dev/encoding/block-helpers.hpp
@@ -0,0 +1,62 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_BLOCK_HELPERS_HPP
+#define NDN_BLOCK_HELPERS_HPP
+
+#include "block.hpp"
+
+namespace ndn {
+
+inline Block
+nonNegativeIntegerBlock(uint32_t type, uint64_t value)
+{
+ OBufferStream os;
+ Tlv::writeVarNumber(os, type);
+ Tlv::writeVarNumber(os, Tlv::sizeOfNonNegativeInteger(value));
+ Tlv::writeNonNegativeInteger(os, value);
+ return Block(os.buf());
+}
+
+inline uint64_t
+readNonNegativeInteger(const Block &block)
+{
+ Buffer::const_iterator begin = block.value_begin();
+ return Tlv::readNonNegativeInteger(block.value_size(), begin, block.value_end());
+}
+
+inline Block
+booleanBlock(uint32_t type)
+{
+ OBufferStream os;
+ Tlv::writeVarNumber(os, type);
+ Tlv::writeVarNumber(os, 0);
+ return Block(os.buf());
+}
+
+inline Block
+dataBlock(uint32_t type, const char *data, size_t dataSize)
+{
+ OBufferStream os;
+ Tlv::writeVarNumber(os, type);
+ Tlv::writeVarNumber(os, dataSize);
+ os.write(data, dataSize);
+
+ return Block(os.buf());
+}
+
+inline Block
+dataBlock(uint32_t type, const unsigned char *data, size_t dataSize)
+{
+ return dataBlock(type, reinterpret_cast<const char*>(data), dataSize);
+}
+
+} // namespace ndn
+
+#endif // NDN_BLOCK_HELPERS_HPP
diff --git a/include/ndn-cpp-dev/encoding/block.hpp b/include/ndn-cpp-dev/encoding/block.hpp
new file mode 100644
index 0000000..85cdaf5
--- /dev/null
+++ b/include/ndn-cpp-dev/encoding/block.hpp
@@ -0,0 +1,423 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_BLOCK_HPP
+#define NDN_BLOCK_HPP
+
+#include <ndn-cpp-dev/common.hpp>
+
+#include <list>
+#include <exception>
+
+#include "buffer.hpp"
+#include "tlv.hpp"
+
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+
+/**
+ * @brief Class representing wire element of the NDN packet
+ */
+class Block
+{
+public:
+ typedef std::list<Block>::iterator element_iterator;
+ typedef std::list<Block>::const_iterator element_const_iterator;
+
+ /// @brief Error that can be thrown from the block
+ struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+ /**
+ * @brief Default constructor to create an empty Block
+ */
+ Block();
+
+ /**
+ * @brief A helper version of a constructor to create Block from the raw buffer (type and value-length parsing)
+ */
+ Block(const ConstBufferPtr &buffer);
+
+ /**
+ * @brief A helper version of a constructor to create Block from the raw buffer (type and value-length parsing)
+ */
+ Block(const uint8_t *buffer, size_t maxlength);
+
+ Block(const void *buffer, size_t maxlength);
+
+ /**
+ * @brief Create Block from the wire buffer (no parsing)
+ *
+ * This version of the constructor does not do any parsing
+ */
+ Block(const ConstBufferPtr &wire,
+ uint32_t type,
+ const Buffer::const_iterator &begin, Buffer::const_iterator &end,
+ const Buffer::const_iterator &valueBegin, Buffer::const_iterator &valueEnd);
+
+ /**
+ * @brief Create Block of a specific type with empty wire buffer
+ */
+ explicit
+ Block(uint32_t type);
+
+ /**
+ * @brief Create Block of a specific type with the specified value
+ *
+ * The underlying buffer hold only value, additional operations are needed
+ * to construct wire encoding, one need to prepend the wire buffer with type
+ * and value-length VAR-NUMBERs
+ */
+ Block(uint32_t type, const ConstBufferPtr &value);
+
+ /**
+ * @brief Create nested Block of a specific type with the specified value
+ *
+ * The underlying buffer hold only value, additional operations are needed
+ * to construct wire encoding, one need to prepend the wire buffer with type
+ * and value-length VAR-NUMBERs
+ */
+ explicit
+ Block(uint32_t type, const Block &value);
+
+ /**
+ * @brief Check if the Block has fully encoded wire
+ */
+ inline bool
+ hasWire() const;
+
+ /**
+ * @brief Check if the Block has value block (no type and length are encoded)
+ */
+ inline bool
+ hasValue() const;
+
+ /**
+ * @brief Reset wire buffer of the element
+ */
+ inline void
+ reset();
+
+ void
+ parse();
+
+ void
+ encode();
+
+ inline uint32_t
+ type() const;
+
+ /**
+ * @brief Get the first subelement of the requested type
+ */
+ inline const Block &
+ get(uint32_t type) const;
+
+ inline Block &
+ get(uint32_t type);
+
+ inline element_iterator
+ find(uint32_t type);
+
+ inline element_const_iterator
+ find(uint32_t type) const;
+
+ inline void
+ remove(uint32_t type);
+
+ inline element_iterator
+ erase(element_iterator position);
+
+ inline element_iterator
+ erase(element_iterator first, element_iterator last);
+
+ inline void
+ push_back(const Block &element);
+
+ /**
+ * @brief Get all subelements
+ */
+ inline const std::list<Block>&
+ getAll () const;
+
+ inline std::list<Block>&
+ getAll ();
+
+ /**
+ * @brief Get all elements of the requested type
+ */
+ std::list<Block>
+ getAll(uint32_t type) const;
+
+ inline Buffer::const_iterator
+ begin() const;
+
+ inline Buffer::const_iterator
+ end() const;
+
+ inline size_t
+ size() const;
+
+ inline Buffer::const_iterator
+ value_begin() const;
+
+ inline Buffer::const_iterator
+ value_end() const;
+
+ inline const uint8_t*
+ wire() const;
+
+ inline const uint8_t*
+ value() const;
+
+ inline size_t
+ value_size() const;
+
+protected:
+ ConstBufferPtr m_buffer;
+
+ uint32_t m_type;
+
+ Buffer::const_iterator m_begin;
+ Buffer::const_iterator m_end;
+ uint32_t m_size;
+
+ Buffer::const_iterator m_value_begin;
+ Buffer::const_iterator m_value_end;
+
+ std::list<Block> m_subBlocks;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+inline bool
+Block::hasWire() const
+{
+ return m_buffer && (m_begin != m_end);
+}
+
+inline bool
+Block::hasValue() const
+{
+ return static_cast<bool>(m_buffer);
+}
+
+inline void
+Block::reset()
+{
+ m_buffer.reset(); // reset of the shared_ptr
+ m_subBlocks.clear(); // remove all parsed subelements
+
+ m_type = std::numeric_limits<uint32_t>::max();
+ m_begin = m_end = m_value_begin = m_value_end = Buffer::const_iterator(); // not really necessary, but for safety
+}
+
+inline uint32_t
+Block::type() const
+{
+ return m_type;
+}
+
+inline const Block &
+Block::get(uint32_t type) const
+{
+ for (element_const_iterator i = m_subBlocks.begin ();
+ i != m_subBlocks.end();
+ i++)
+ {
+ if (i->type () == type)
+ {
+ return *i;
+ }
+ }
+
+ throw Error("(Block::get) Requested a non-existed type [" + boost::lexical_cast<std::string>(type) + "] from Block");
+}
+
+inline Block &
+Block::get(uint32_t type)
+{
+ for (element_iterator i = m_subBlocks.begin ();
+ i != m_subBlocks.end();
+ i++)
+ {
+ if (i->type () == type)
+ {
+ return *i;
+ }
+ }
+
+ throw Error("(Block::get) Requested a non-existed type [" + boost::lexical_cast<std::string>(type) + "] from Block");
+}
+
+inline Block::element_const_iterator
+Block::find(uint32_t type) const
+{
+ for (element_const_iterator i = m_subBlocks.begin ();
+ i != m_subBlocks.end();
+ i++)
+ {
+ if (i->type () == type)
+ {
+ return i;
+ }
+ }
+ return m_subBlocks.end();
+}
+
+inline Block::element_iterator
+Block::find(uint32_t type)
+{
+ for (element_iterator i = m_subBlocks.begin ();
+ i != m_subBlocks.end();
+ i++)
+ {
+ if (i->type () == type)
+ {
+ return i;
+ }
+ }
+ return m_subBlocks.end();
+}
+
+struct block_type
+{
+ block_type(uint32_t type)
+ : m_type(type)
+ {
+ }
+
+ inline bool
+ operator()(const Block &block)
+ {
+ return (block.type() == m_type);
+ }
+private:
+ uint32_t m_type;
+};
+
+inline void
+Block::remove(uint32_t type)
+{
+ m_subBlocks.remove_if(block_type(type));
+}
+
+inline Block::element_iterator
+Block::erase(Block::element_iterator position)
+{
+ return m_subBlocks.erase(position);
+}
+
+inline Block::element_iterator
+Block::erase(Block::element_iterator first, Block::element_iterator last)
+{
+ return m_subBlocks.erase(first, last);
+}
+
+
+inline void
+Block::push_back(const Block &element)
+{
+ m_subBlocks.push_back(element);
+}
+
+
+inline const std::list<Block>&
+Block::getAll () const
+{
+ return m_subBlocks;
+}
+
+inline std::list<Block>&
+Block::getAll ()
+{
+ return m_subBlocks;
+}
+
+
+inline Buffer::const_iterator
+Block::begin() const
+{
+ if (!hasWire())
+ throw Error("Underlying wire buffer is empty");
+
+ return m_begin;
+}
+
+inline Buffer::const_iterator
+Block::end() const
+{
+ if (!hasWire())
+ throw Error("Underlying wire buffer is empty");
+
+ return m_end;
+}
+
+inline size_t
+Block::size() const
+{
+ if (hasWire() || hasValue()) {
+ return m_size;
+ }
+ else
+ throw Error("Block size cannot be determined (undefined block size)");
+}
+
+inline Buffer::const_iterator
+Block::value_begin() const
+{
+ if (!hasValue())
+ throw Error("(Block::value_begin) Underlying value buffer is empty");
+
+ return m_value_begin;
+}
+
+inline Buffer::const_iterator
+Block::value_end() const
+{
+ if (!hasValue())
+ throw Error("(Block::value_end) Underlying value buffer is empty");
+
+ return m_value_end;
+}
+
+inline const uint8_t*
+Block::wire() const
+{
+ if (!hasWire())
+ throw Error("(Block::wire) Underlying wire buffer is empty");
+
+ return &*m_begin;
+}
+
+inline const uint8_t*
+Block::value() const
+{
+ if (!hasValue())
+ throw Error("(Block::value) Underlying value buffer is empty");
+
+ return &*m_value_begin;
+}
+
+inline size_t
+Block::value_size() const
+{
+ if (!hasValue())
+ throw Error("(Block::value_size) Underlying value buffer is empty");
+
+ return m_value_end - m_value_begin;
+}
+
+} // ndn
+
+#include "block-helpers.hpp"
+
+#endif // NDN_BLOCK_HPP
diff --git a/include/ndn-cpp-dev/encoding/buffer.hpp b/include/ndn-cpp-dev/encoding/buffer.hpp
new file mode 100644
index 0000000..368b445
--- /dev/null
+++ b/include/ndn-cpp-dev/encoding/buffer.hpp
@@ -0,0 +1,199 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_BUFFER_HPP
+#define NDN_BUFFER_HPP
+
+#include <ndn-cpp-dev/common.hpp>
+
+#include <boost/iostreams/detail/ios.hpp>
+#include <boost/iostreams/categories.hpp>
+#include <boost/iostreams/stream.hpp>
+
+#include <vector>
+
+namespace ndn {
+
+class Buffer;
+typedef ptr_lib::shared_ptr<const Buffer> ConstBufferPtr;
+typedef ptr_lib::shared_ptr<Buffer> BufferPtr;
+
+/**
+ * @brief Class representing a general-use automatically managed/resized buffer
+ *
+ * In most respect, Buffer class is equivalent to std::vector<uint8_t> and is in fact
+ * uses it as a base class. In addition to that, it provides buf() and buf<T>() helper
+ * method for easier access to the underlying data (buf<T>() casts pointer to the requested class)
+ */
+class Buffer : public std::vector<uint8_t>
+{
+public:
+ /**
+ * @brief Creates an empty buffer
+ */
+ Buffer ()
+ {
+ }
+
+ /**
+ * @brief Create a buffer by copying the supplied data from a const buffer
+ * @param buf const pointer to buffer
+ * @param length length of the buffer to copy
+ */
+ Buffer (const void *buf, size_t length)
+ : std::vector<uint8_t> (reinterpret_cast<const uint8_t*> (buf), reinterpret_cast<const uint8_t*> (buf) + length)
+ {
+ }
+
+ /**
+ * @brief Create a buffer by copying the supplied data using iterator interface
+ *
+ * Note that the supplied iterators must be compatible with std::vector<uint8_t> interface
+ *
+ * @param first iterator to a first element to copy
+ * @param last iterator to an element immediately following the last element to copy
+ */
+ template <class InputIterator>
+ Buffer (InputIterator first, InputIterator last)
+ : std::vector<uint8_t> (first, last)
+ {
+ }
+
+ /**
+ * @brief Get pointer to the first byte of the buffer
+ */
+ inline uint8_t*
+ get ()
+ {
+ return &front ();
+ }
+
+ /**
+ * @brief Get pointer to the first byte of the buffer (alternative version)
+ */
+ inline uint8_t*
+ buf ()
+ {
+ return &front ();
+ }
+
+ /**
+ * @brief Get pointer to the first byte of the buffer and cast
+ * it (reinterpret_cast) to the requested type T
+ */
+ template<class T>
+ inline T*
+ get ()
+ {
+ return reinterpret_cast<T *>(&front ());
+ }
+
+ /**
+ * @brief Get pointer to the first byte of the buffer (alternative version)
+ */
+ inline const uint8_t*
+ buf () const
+ {
+ return &front ();
+ }
+
+ /**
+ * @brief Get const pointer to the first byte of the buffer
+ */
+ inline const uint8_t*
+ get () const
+ {
+ return &front ();
+ }
+
+ /**
+ * @brief Get const pointer to the first byte of the buffer and cast
+ * it (reinterpret_cast) to the requested type T
+ */
+ template<class T>
+ inline const T*
+ get () const
+ {
+ return reinterpret_cast<const T *>(&front ());
+ }
+};
+
+/// @cond include_hidden
+namespace iostreams
+{
+
+class buffer_append_device {
+public:
+ typedef char char_type;
+ typedef boost::iostreams::sink_tag category;
+
+ buffer_append_device (Buffer& container)
+ : m_container (container)
+ {
+ }
+
+ std::streamsize
+ write(const char_type* s, std::streamsize n)
+ {
+ std::copy (s, s+n, std::back_inserter(m_container));
+ return n;
+ }
+
+protected:
+ Buffer& m_container;
+};
+
+} // iostreams
+/// @endcond
+
+/**
+ * Class implementing interface similar to ostringstream, but to construct ndn::Buffer
+ *
+ * The benefit of using stream interface is that it provides automatic buffering of written data
+ * and eliminates (or reduces) overhead of resizing the underlying buffer when writing small pieces of data.
+ *
+ * Usage example:
+ * @code
+ * OBufferStream obuf;
+ * obuf.put(0);
+ * obuf.write(another_buffer, another_buffer_size);
+ * ptr_lib::shared_ptr<Buffer> buf = obuf.get();
+ * @endcode
+ */
+struct OBufferStream : public boost::iostreams::stream<iostreams::buffer_append_device>
+{
+ /**
+ * Default constructor
+ */
+ OBufferStream ()
+ : m_buffer (ptr_lib::make_shared<Buffer> ())
+ , m_device (*m_buffer)
+ {
+ open (m_device);
+ }
+
+ /**
+ * Flush written data to the stream and return shared pointer to the underlying buffer
+ */
+ ptr_lib::shared_ptr<Buffer>
+ buf ()
+ {
+ flush ();
+ return m_buffer;
+ }
+
+private:
+ BufferPtr m_buffer;
+ iostreams::buffer_append_device m_device;
+};
+
+
+} // ndn
+
+#endif // NDN_BUFFER_HPP
diff --git a/include/ndn-cpp-dev/encoding/element-listener.hpp b/include/ndn-cpp-dev/encoding/element-listener.hpp
new file mode 100644
index 0000000..7d13312
--- /dev/null
+++ b/include/ndn-cpp-dev/encoding/element-listener.hpp
@@ -0,0 +1,48 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_ELEMENT_LISTENER_HPP
+#define NDN_ELEMENT_LISTENER_HPP
+
+#include "../c/encoding/element-listener.h"
+
+namespace ndn {
+
+/**
+ * An ElementListener extends an ndn_ElementListener struct to proved an abstract virtual onReceivedElement function which wraps
+ * the onReceivedElement used by the ndn_ElementListener struct. You must extend this class to override onReceivedElement.
+ */
+class ElementListener : public ndn_ElementListener {
+public:
+ ElementListener()
+ {
+ ndn_ElementListener_initialize(this, staticOnReceivedElement);
+ }
+
+ /**
+ * This is called when an entire binary XML element is received. You must extend this class to override this method.
+ * @param element pointer to the binary XML element. This buffer is only valid during this call. If you need the data
+ * later, you must copy.
+ * @param elementLength length of element
+ */
+ virtual void
+ onReceivedElement(const uint8_t *element, size_t elementLength) = 0;
+
+private:
+ /**
+ * Call the virtual method onReceivedElement. This is used to initialize the base ndn_ElementListener struct.
+ * @param self
+ * @param element
+ * @param elementLength
+ */
+ static void
+ staticOnReceivedElement(struct ndn_ElementListener *self, uint8_t *element, size_t elementLength);
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/encoding/endian.h b/include/ndn-cpp-dev/encoding/endian.h
new file mode 100644
index 0000000..9ea5c96
--- /dev/null
+++ b/include/ndn-cpp-dev/encoding/endian.h
@@ -0,0 +1,39 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Junxiao Shi <shijunxiao@email.arizona.edu>
+ */
+
+#ifdef __linux__
+
+#include <endian.h>
+
+#endif
+
+#ifdef __FreeBSD__
+
+#include <sys/endian.h>
+
+#endif
+
+#ifdef __APPLE__
+
+#include <libkern/OSByteOrder.h>
+#define htobe16(x) OSSwapHostToBigInt16(x)
+#define htole16(x) OSSwapHostToLittleInt16(x)
+#define be16toh(x) OSSwapBigToHostInt16(x)
+#define le16toh(x) OSSwapLittleToHostInt16(x)
+#define htobe32(x) OSSwapHostToBigInt32(x)
+#define htole32(x) OSSwapHostToLittleInt32(x)
+#define be32toh(x) OSSwapBigToHostInt32(x)
+#define le32toh(x) OSSwapLittleToHostInt32(x)
+#define htobe64(x) OSSwapHostToBigInt64(x)
+#define htole64(x) OSSwapHostToLittleInt64(x)
+#define be64toh(x) OSSwapBigToHostInt64(x)
+#define le64toh(x) OSSwapLittleToHostInt64(x)
+
+#endif
+
diff --git a/include/ndn-cpp-dev/encoding/oid.hpp b/include/ndn-cpp-dev/encoding/oid.hpp
new file mode 100644
index 0000000..e755c05
--- /dev/null
+++ b/include/ndn-cpp-dev/encoding/oid.hpp
@@ -0,0 +1,78 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_OID_HPP
+#define NDN_OID_HPP
+
+#include <vector>
+#include <string>
+
+namespace CryptoPP { class BufferedTransformation; }
+
+namespace ndn {
+
+class OID {
+public:
+ OID ()
+ {
+ }
+
+ OID(const char *oid);
+
+ OID(const std::string& oid);
+
+ OID(const std::vector<int>& oid)
+ : oid_(oid)
+ {
+ }
+
+ const std::vector<int> &
+ getIntegerList() const
+ {
+ return oid_;
+ }
+
+ void
+ setIntegerList(const std::vector<int>& value){
+ oid_ = value;
+ }
+
+ std::string
+ toString() const;
+
+ bool operator == (const OID& oid) const
+ {
+ return equal(oid);
+ }
+
+ bool operator != (const OID& oid) const
+ {
+ return !equal(oid);
+ }
+
+ void
+ encode(CryptoPP::BufferedTransformation &out) const;
+
+ void
+ decode(CryptoPP::BufferedTransformation &in);
+
+
+private:
+ void
+ construct(const std::string &value);
+
+ bool
+ equal(const OID& oid) const;
+
+private:
+ std::vector<int> oid_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/encoding/tlv-face-management.hpp b/include/ndn-cpp-dev/encoding/tlv-face-management.hpp
new file mode 100644
index 0000000..86798df
--- /dev/null
+++ b/include/ndn-cpp-dev/encoding/tlv-face-management.hpp
@@ -0,0 +1,50 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_TLV_FACE_MANAGEMENT_HPP
+#define NDN_TLV_FACE_MANAGEMENT_HPP
+
+#include "tlv.hpp"
+
+namespace ndn {
+namespace Tlv {
+namespace FaceManagement {
+
+enum {
+ FaceInstance = 128,
+ ForwardingEntry = 129,
+ StatusResponse = 130,
+ Action = 131,
+ FaceID = 132,
+ IPProto = 133,
+ Host = 134,
+ Port = 135,
+ MulticastInterface = 136,
+ MulticastTTL = 137,
+ ForwardingFlags = 138,
+ StatusCode = 139,
+ StatusText = 140
+};
+
+enum {
+ FORW_ACTIVE = 1,
+ FORW_CHILD_INHERIT = 2,
+ FORW_ADVERTISE = 4,
+ FORW_LAST = 8,
+ FORW_CAPTURE = 16,
+ FORW_LOCAL = 32,
+ FORW_TAP = 64,
+ FORW_CAPTURE_OK = 128
+};
+
+} // namespace FaceManagement
+} // namespace Tlv
+} // namespace ndn
+
+#endif // NDN_TLV_FACE_MANAGEMENT_HPP
diff --git a/include/ndn-cpp-dev/encoding/tlv.hpp b/include/ndn-cpp-dev/encoding/tlv.hpp
new file mode 100644
index 0000000..dfa11fe
--- /dev/null
+++ b/include/ndn-cpp-dev/encoding/tlv.hpp
@@ -0,0 +1,327 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_TLV_HPP
+#define NDN_TLV_HPP
+
+#include <stdexcept>
+#include "buffer.hpp"
+#include "endian.h"
+
+namespace ndn {
+
+/**
+ * @brief Namespace defining NDN-TLV related constants and procedures
+ */
+namespace Tlv {
+
+struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+enum {
+ Interest = 1,
+ Data = 2,
+ Name = 3,
+ NameComponent = 4,
+ Selectors = 5,
+ Nonce = 6,
+ Scope = 7,
+ InterestLifetime = 8,
+ MinSuffixComponents = 9,
+ MaxSuffixComponents = 10,
+ PublisherPublicKeyLocator = 11,
+ Exclude = 12,
+ ChildSelector = 13,
+ MustBeFresh = 14,
+ Any = 15,
+ MetaInfo = 16,
+ Content = 17,
+ SignatureInfo = 18,
+ SignatureValue = 19,
+ ContentType = 20,
+ FreshnessPeriod = 21,
+ SignatureType = 22,
+ KeyLocator = 23,
+ KeyLocatorDigest = 24,
+
+ AppPrivateBlock1 = 128,
+ AppPrivateBlock2 = 32767
+};
+
+enum SignatureType {
+ DigestSha256 = 0,
+ SignatureSha256WithRsa = 1,
+};
+
+enum ConentType {
+ ContentType_Default = 0,
+ ContentType_Link = 1,
+ ContentType_Key = 2,
+};
+
+/**
+ * @brief Read VAR-NUMBER in NDN-TLV encoding
+ *
+ * This call will throw ndn::Tlv::Error (aka std::runtime_error) if number cannot be read
+ *
+ * Note that after call finished, begin will point to the first byte after the read VAR-NUMBER
+ */
+template<class InputIterator>
+inline uint64_t
+readVarNumber(InputIterator &begin, const InputIterator &end);
+
+/**
+ * @brief Read TLV Type
+ *
+ * This call is largely equivalent to tlv::readVarNumber, but exception will be thrown if type
+ * is larger than 2^32-1 (type in this library is implemented as uint32_t)
+ */
+template<class InputIterator>
+inline uint32_t
+readType(InputIterator &begin, const InputIterator &end);
+
+/**
+ * @brief Get number of bytes necessary to hold value of VAR-NUMBER
+ */
+inline size_t
+sizeOfVarNumber(uint64_t varNumber);
+
+/**
+ * @brief Write VAR-NUMBER to the specified stream
+ */
+inline size_t
+writeVarNumber(std::ostream &os, uint64_t varNumber);
+
+/**
+ * @brief Read nonNegativeInteger in NDN-TLV encoding
+ *
+ * This call will throw ndn::Tlv::Error (aka std::runtime_error) if number cannot be read
+ *
+ * Note that after call finished, begin will point to the first byte after the read VAR-NUMBER
+ *
+ * How many bytes will be read is directly controlled by the size parameter, which can be either
+ * 1, 2, 4, or 8. If the value of size is different, then an exception will be thrown.
+ */
+template<class InputIterator>
+inline uint64_t
+readNonNegativeInteger(size_t size, InputIterator &begin, const InputIterator &end);
+
+/**
+ * @brief Get number of bytes necessary to hold value of nonNegativeInteger
+ */
+inline size_t
+sizeOfNonNegativeInteger(uint64_t varNumber);
+
+/**
+ * @brief Write nonNegativeInteger to the specified stream
+ */
+inline size_t
+writeNonNegativeInteger(std::ostream &os, uint64_t varNumber);
+
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+
+// Inline implementations
+
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+
+template<class InputIterator>
+inline uint64_t
+readVarNumber(InputIterator &begin, const InputIterator &end)
+{
+ if (begin == end)
+ throw Error("Empty buffer during TLV processing");
+
+ uint8_t value = *begin;
+ ++begin;
+ if (value < 253)
+ {
+ return value;
+ }
+ else if (value == 253)
+ {
+ if (end - begin < 2)
+ throw Error("Insufficient data during TLV processing");
+
+ uint16_t value = *reinterpret_cast<const uint16_t*>(&*begin); // kind of dangerous... but should be efficient
+ begin += 2;
+ return be16toh(value);
+ }
+ else if (value == 254)
+ {
+ if (end - begin < 4)
+ throw Error("Insufficient data during TLV processing");
+
+ uint32_t value = *reinterpret_cast<const uint32_t*>(&*begin); // kind of dangerous... but should be efficient
+ begin += 4;
+ return be32toh(value);
+ }
+ else // if (value == 255)
+ {
+ if (end - begin < 8)
+ throw Error("Insufficient data during TLV processing");
+
+ uint64_t value = *reinterpret_cast<const uint64_t*>(&*begin);
+ begin += 8;
+
+ return be64toh(value);
+ }
+}
+
+template<class InputIterator>
+inline uint32_t
+readType(InputIterator &begin, const InputIterator &end)
+{
+ uint64_t type = readVarNumber(begin, end);
+ if (type > std::numeric_limits<uint32_t>::max())
+ {
+ throw Error("TLV type code exceeds allowed maximum");
+ }
+
+ return static_cast<uint32_t> (type);
+}
+
+size_t
+sizeOfVarNumber(uint64_t varNumber)
+{
+ if (varNumber < 253) {
+ return 1;
+ }
+ else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
+ return 3;
+ }
+ else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
+ return 5;
+ }
+ else {
+ return 9;
+ }
+}
+
+inline size_t
+writeVarNumber(std::ostream &os, uint64_t varNumber)
+{
+ if (varNumber < 253) {
+ os.put(static_cast<uint8_t> (varNumber));
+ return 1;
+ }
+ else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
+ os.put(253);
+ uint16_t value = htobe16(static_cast<uint16_t> (varNumber));
+ os.write(reinterpret_cast<const char*> (&value), 2);
+ return 3;
+ }
+ else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
+ os.put(254);
+ uint32_t value = htobe32(static_cast<uint32_t> (varNumber));
+ os.write(reinterpret_cast<const char*> (&value), 4);
+ return 5;
+ }
+ else {
+ os.put(255);
+ uint64_t value = htobe64(varNumber);
+ os.write(reinterpret_cast<const char*> (&value), 8);
+ return 9;
+ }
+}
+
+template<class InputIterator>
+inline uint64_t
+readNonNegativeInteger(size_t size, InputIterator &begin, const InputIterator &end)
+{
+ switch (size) {
+ case 1:
+ {
+ if (end - begin < 1)
+ throw Error("Insufficient data during TLV processing");
+
+ uint8_t value = *begin;
+ begin++;
+ return value;
+ }
+ case 2:
+ {
+ if (end - begin < 2)
+ throw Error("Insufficient data during TLV processing");
+
+ uint16_t value = *reinterpret_cast<const uint16_t*>(&*begin); // kind of dangerous... but should be efficient
+ begin += 2;
+ return be16toh(value);
+ }
+ case 4:
+ {
+ if (end - begin < 4)
+ throw Error("Insufficient data during TLV processing");
+
+ uint32_t value = *reinterpret_cast<const uint32_t*>(&*begin); // kind of dangerous... but should be efficient
+ begin += 4;
+ return be32toh(value);
+ }
+ case 8:
+ {
+ if (end - begin < 8)
+ throw Error("Insufficient data during TLV processing");
+
+ uint64_t value = *reinterpret_cast<const uint64_t*>(&*begin);
+ begin += 8;
+ return be64toh(value);
+ }
+ }
+ throw Error("Invalid length for nonNegativeInteger (only 1, 2, 4, and 8 are allowed)");
+}
+
+inline size_t
+sizeOfNonNegativeInteger(uint64_t varNumber)
+{
+ if (varNumber < 253) {
+ return 1;
+ }
+ else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
+ return 2;
+ }
+ else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
+ return 4;
+ }
+ else {
+ return 8;
+ }
+}
+
+
+inline size_t
+writeNonNegativeInteger(std::ostream &os, uint64_t varNumber)
+{
+ if (varNumber < 253) {
+ os.put(static_cast<uint8_t> (varNumber));
+ return 1;
+ }
+ else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
+ uint16_t value = htobe16(static_cast<uint16_t> (varNumber));
+ os.write(reinterpret_cast<const char*> (&value), 2);
+ return 2;
+ }
+ else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
+ uint32_t value = htobe32(static_cast<uint32_t> (varNumber));
+ os.write(reinterpret_cast<const char*> (&value), 4);
+ return 4;
+ }
+ else {
+ uint64_t value = htobe64(varNumber);
+ os.write(reinterpret_cast<const char*> (&value), 8);
+ return 8;
+ }
+}
+
+
+} // namespace tlv
+} // namespace ndn
+
+#endif // NDN_TLV_HPP
diff --git a/include/ndn-cpp-dev/encoding/wire-format.hpp b/include/ndn-cpp-dev/encoding/wire-format.hpp
new file mode 100644
index 0000000..1a40cd1
--- /dev/null
+++ b/include/ndn-cpp-dev/encoding/wire-format.hpp
@@ -0,0 +1,146 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_WIREFORMAT_HPP
+#define NDN_WIREFORMAT_HPP
+
+#include "../common.hpp"
+#include "../util/blob.hpp"
+
+namespace ndn {
+
+class Interest;
+class Data;
+class ForwardingEntry;
+
+class WireFormat {
+public:
+ /**
+ * Encode interest and return the encoding. Your derived class should override.
+ * @param interest The Interest object to encode.
+ * @return A Blob containing the encoding.
+ * @throw logic_error for unimplemented if the derived class does not override.
+ */
+ virtual Blob
+ encodeInterest(const Interest& interest);
+
+ /**
+ * Decode input as an interest and set the fields of the interest object. Your derived class should override.
+ * @param interest The Interest object whose fields are updated.
+ * @param input A pointer to the input buffer to decode.
+ * @param inputLength The number of bytes in input.
+ * @throw logic_error for unimplemented if the derived class does not override.
+ */
+ virtual void
+ decodeInterest(Interest& interest, const uint8_t *input, size_t inputLength);
+
+ /**
+ * Encode data and return the encoding. Your derived class should override.
+ * @param data The Data object to encode.
+ * @param signedPortionBeginOffset Return the offset in the encoding of the beginning of the signed portion.
+ * If you are not encoding in order to sign, you can call encodeData(const Data& data) to ignore this returned value.
+ * @param signedPortionEndOffset Return the offset in the encoding of the end of the signed portion.
+ * If you are not encoding in order to sign, you can call encodeData(const Data& data) to ignore this returned value.
+ * @return A Blob containing the encoding.
+ * @throw logic_error for unimplemented if the derived class does not override.
+ */
+ virtual Blob
+ encodeData
+ (const Data& data, size_t *signedPortionBeginOffset, size_t *signedPortionEndOffset);
+
+ /**
+ * Encode data and return the encoding.
+ * @param data The Data object to encode.
+ * @return A Blob containing the encoding.
+ * @throw logic_error for unimplemented if the derived class does not override.
+ */
+ Blob
+ encodeData(const Data& data)
+ {
+ size_t dummyBeginOffset, dummyEndOffset;
+ return encodeData(data, &dummyBeginOffset, &dummyEndOffset);
+ }
+
+ /**
+ * Decode input as a data packet and set the fields in the data object. Your derived class should override.
+ * @param data The Data object whose fields are updated.
+ * @param input A pointer to the input buffer to decode.
+ * @param inputLength The number of bytes in input.
+ * @param signedPortionBeginOffset Return the offset in the input buffer of the beginning of the signed portion.
+ * If you are not decoding in order to verify, you can call
+ * decodeData(Data& data, const uint8_t *input, size_t inputLength) to ignore this returned value.
+ * @param signedPortionEndOffset Return the offset in the input buffer of the end of the signed portion.
+ * If you are not decoding in order to verify, you can call
+ * decodeData(Data& data, const uint8_t *input, size_t inputLength) to ignore this returned value.
+ * @throw logic_error for unimplemented if the derived class does not override.
+ */
+ virtual void
+ decodeData
+ (Data& data, const uint8_t *input, size_t inputLength, size_t *signedPortionBeginOffset, size_t *signedPortionEndOffset);
+
+ void
+ decodeData(Data& data, const uint8_t *input, size_t inputLength)
+ {
+ size_t dummyBeginOffset, dummyEndOffset;
+ decodeData(data, input, inputLength, &dummyBeginOffset, &dummyEndOffset);
+ }
+
+ /**
+ * Encode forwardingEntry and return the encoding. Your derived class should override.
+ * @param forwardingEntry The ForwardingEntry object to encode.
+ * @return A Blob containing the encoding.
+ * @throw logic_error for unimplemented if the derived class does not override.
+ */
+ virtual Blob
+ encodeForwardingEntry(const ForwardingEntry& forwardingEntry);
+
+ /**
+ * Decode input as a forwarding entry and set the fields of the forwardingEntry object. Your derived class should override.
+ * @param forwardingEntry The ForwardingEntry object whose fields are updated.
+ * @param input A pointer to the input buffer to decode.
+ * @param inputLength The number of bytes in input.
+ * @throw logic_error for unimplemented if the derived class does not override.
+ */
+ virtual void
+ decodeForwardingEntry(ForwardingEntry& forwardingEntry, const uint8_t *input, size_t inputLength);
+
+ /**
+ * Set the static default WireFormat used by default encoding and decoding methods.
+ * @param wireFormat A Pointer to an object of a subclass of WireFormat. This does not make a copy and
+ * the caller must ensure that the object remains allocated.
+ */
+ static void
+ setDefaultWireFormat(WireFormat *wireFormat)
+ {
+ defaultWireFormat_ = wireFormat;
+ }
+
+ /**
+ * Return the default WireFormat used by default encoding and decoding methods which was set with
+ * setDefaultWireFormat.
+ * @return A pointer to the WireFormat object.
+ */
+ static WireFormat*
+ getDefaultWireFormat();
+
+private:
+ /**
+ * This is implemented by only one of the subclasses of WireFormat to return a new object used
+ * as the initial value for the default WireFormat. If the application doesn't include that class, then the application
+ * needs to include another subclass which defines WireFormat::newInitialDefaultWireFormat.
+ * @return a new object, which is held by a shared_ptr and freed when the application exits.
+ */
+ static WireFormat*
+ newInitialDefaultWireFormat();
+
+ static WireFormat *defaultWireFormat_;
+};
+
+}
+
+#endif
+
diff --git a/include/ndn-cpp-dev/exclude.hpp b/include/ndn-cpp-dev/exclude.hpp
new file mode 100644
index 0000000..e26ec31
--- /dev/null
+++ b/include/ndn-cpp-dev/exclude.hpp
@@ -0,0 +1,233 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * Alexander Afanasyev
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_EXCLUDE_H
+#define NDN_EXCLUDE_H
+
+#include "name.hpp"
+
+#include <map>
+
+namespace ndn {
+
+/**
+ * @brief Class to represent Exclude component in NDN interests
+ */
+class Exclude
+{
+public:
+ struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+
+ typedef std::map< Name::Component, bool /*any*/, std::greater<Name::Component> > exclude_type;
+
+ typedef exclude_type::iterator iterator;
+ typedef exclude_type::const_iterator const_iterator;
+ typedef exclude_type::reverse_iterator reverse_iterator;
+ typedef exclude_type::const_reverse_iterator const_reverse_iterator;
+
+ /**
+ * @brief Default constructor an empty exclude
+ */
+ Exclude ();
+
+ /**
+ * @brief Check if name component is excluded
+ * @param comp Name component to check against exclude filter
+ */
+ bool
+ isExcluded (const Name::Component &comp) const;
+
+ /**
+ * @brief Exclude specific name component
+ * @param comp component to exclude
+ * @returns *this to allow chaining
+ */
+ Exclude &
+ excludeOne (const Name::Component &comp);
+
+ /**
+ * @brief Exclude components from range [from, to]
+ * @param from first element of the range
+ * @param to last element of the range
+ * @returns *this to allow chaining
+ */
+ Exclude &
+ excludeRange (const Name::Component &from, const Name::Component &to);
+
+ /**
+ * @brief Exclude all components from range [/, to]
+ * @param to last element of the range
+ * @returns *this to allow chaining
+ */
+ inline Exclude &
+ excludeBefore (const Name::Component &to);
+
+ /**
+ * @brief Exclude all components from range [from, +Inf]
+ * @param to last element of the range
+ * @returns *this to allow chaining
+ */
+ Exclude &
+ excludeAfter (const Name::Component &from);
+
+ /**
+ * @brief Method to directly append exclude element
+ * @param name excluded name component
+ * @param any flag indicating if there is a postfix ANY component after the name
+ *
+ * This method is used during conversion from wire format of exclude filter
+ *
+ * If there is an error with ranges (e.g., order of components is wrong) an exception is thrown
+ */
+ inline void
+ appendExclude (const Name::Component &name, bool any);
+
+ /**
+ * @brief Check if exclude filter is empty
+ */
+ inline bool
+ empty () const;
+
+ /**
+ * @brief Clear the exclude filter
+ */
+ inline void
+ clear();
+
+ /**
+ * @brief Get number of exclude terms
+ */
+ inline size_t
+ size () const;
+
+ /**
+ * @brief Get begin iterator of the exclude terms
+ */
+ inline const_iterator
+ begin () const;
+
+ /**
+ * @brief Get end iterator of the exclude terms
+ */
+ inline const_iterator
+ end () const;
+
+ /**
+ * @brief Get begin iterator of the exclude terms
+ */
+ inline const_reverse_iterator
+ rbegin () const;
+
+ /**
+ * @brief Get end iterator of the exclude terms
+ */
+ inline const_reverse_iterator
+ rend () const;
+
+ /**
+ * @brief Get escaped string representation (e.g., for use in URI) of the exclude filter
+ */
+ inline std::string
+ toUri () const;
+
+ /**
+ * Encode this Interest for a particular wire format.
+ * @return The encoded byte array.
+ */
+ const Block&
+ wireEncode() const;
+
+ /**
+ * Decode the input using a particular wire format and update this Interest.
+ * @param input The input byte array to be decoded.
+ */
+ void
+ wireDecode(const Block &wire);
+
+private:
+ Exclude &
+ excludeRange (iterator fromLowerBound, iterator toLowerBound);
+
+private:
+ exclude_type m_exclude;
+
+ mutable Block wire_;
+};
+
+std::ostream&
+operator << (std::ostream &os, const Exclude &name);
+
+inline Exclude &
+Exclude::excludeBefore (const Name::Component &to)
+{
+ return excludeRange (Name::Component (), to);
+}
+
+inline void
+Exclude::appendExclude (const Name::Component &name, bool any)
+{
+ m_exclude[name] = any;
+}
+
+inline bool
+Exclude::empty () const
+{
+ return m_exclude.empty ();
+}
+
+inline void
+Exclude::clear ()
+{
+ m_exclude.clear ();
+}
+
+
+inline size_t
+Exclude::size () const
+{
+ return m_exclude.size ();
+}
+
+inline Exclude::const_iterator
+Exclude::begin () const
+{
+ return m_exclude.begin ();
+}
+
+inline Exclude::const_iterator
+Exclude::end () const
+{
+ return m_exclude.end ();
+}
+
+inline Exclude::const_reverse_iterator
+Exclude::rbegin () const
+{
+ return m_exclude.rbegin ();
+}
+
+inline Exclude::const_reverse_iterator
+Exclude::rend () const
+{
+ return m_exclude.rend ();
+}
+
+inline std::string
+Exclude::toUri () const
+{
+ std::ostringstream os;
+ os << *this;
+ return os.str();
+}
+
+} // ndn
+
+#endif // NDN_EXCLUDE_H
diff --git a/include/ndn-cpp-dev/face-instance.hpp b/include/ndn-cpp-dev/face-instance.hpp
new file mode 100644
index 0000000..74feee1
--- /dev/null
+++ b/include/ndn-cpp-dev/face-instance.hpp
@@ -0,0 +1,344 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_FACE_INSTANCE_HPP
+#define NDN_FACE_INSTANCE_HPP
+
+#include "encoding/tlv-face-management.hpp"
+#include "name.hpp"
+#include "encoding/block.hpp"
+
+namespace ndn {
+
+/**
+ * An FaceInstance holds an action and Name prefix and other fields for an forwarding entry.
+ */
+class FaceInstance {
+public:
+ FaceInstance(const std::string &action,
+ int64_t faceId,
+ uint32_t ipProto,
+ const std::string &host,
+ const std::string &port,
+ const std::string &multicastInterface,
+ uint32_t multicastTtl,
+ Milliseconds freshnessPeriod)
+ : action_(action)
+ , faceId_(faceId)
+ , ipProto_(ipProto)
+ , host_(host)
+ , port_(port)
+ , multicastInterface_(multicastInterface)
+ , multicastTtl_(multicastTtl)
+ , freshnessPeriod_(freshnessPeriod)
+ {
+ }
+
+ FaceInstance()
+ : faceId_(-1)
+ , ipProto_(-1)
+ , multicastTtl_(-1)
+ , freshnessPeriod_(-1)
+ {
+ }
+
+ // Action
+ const std::string&
+ getAction() const { return action_; }
+
+ void
+ setAction(const std::string& action) { action_ = action; wire_.reset(); }
+
+ // FaceID
+ int64_t
+ getFaceId() const { return faceId_; }
+
+ void
+ setFaceId(int64_t faceId) { faceId_ = faceId; wire_.reset(); }
+
+ // IPProto
+ int32_t
+ getIpProto() const { return ipProto_; }
+
+ void
+ setIpProto(int32_t ipProto) { ipProto_ = ipProto; wire_.reset(); }
+
+ // Host
+ const std::string&
+ getHost() const { return host_; }
+
+ void
+ setHost(const std::string& host) { host_ = host; wire_.reset(); }
+
+ // Port
+ const std::string&
+ getPort() const { return port_; }
+
+ void
+ setPort(const std::string &port) { port_ = port; wire_.reset(); }
+
+ // MulticastInterface
+ const std::string&
+ getMulticastInterface() const { return multicastInterface_; }
+
+ void
+ setMulticastInterface(const std::string& multicastInterface) { multicastInterface_ = multicastInterface; wire_.reset(); }
+
+ // MulticastTTL
+ int32_t
+ getMulticastTtl() const { return multicastTtl_; }
+
+ void
+ setMulticastTtl(int32_t multicastTtl) { multicastTtl_ = multicastTtl; wire_.reset(); }
+
+ // Freshness
+ int
+ getFreshnessPeriod() const { return freshnessPeriod_; }
+
+ void
+ setFreshnessPeriod(int freshnessPeriod) { freshnessPeriod_ = freshnessPeriod; wire_.reset(); }
+
+ // Wire
+ inline const Block&
+ wireEncode() const;
+
+ inline void
+ wireDecode(const Block &wire);
+
+private:
+ std::string action_;
+ int64_t faceId_;
+ int32_t ipProto_;
+ std::string host_;
+ std::string port_;
+ std::string multicastInterface_;
+ int32_t multicastTtl_;
+ Milliseconds freshnessPeriod_;
+
+ mutable Block wire_;
+};
+
+inline const Block&
+FaceInstance::wireEncode() const
+{
+ if (wire_.hasWire())
+ return wire_;
+
+ // FaceInstance ::= FACE-INSTANCE-TYPE TLV-LENGTH
+ // Action?
+ // FaceID?
+ // IPProto?
+ // Host?
+ // Port?
+ // MulticastInterface?
+ // MulticastTTL?
+ // FreshnessPeriod?
+
+ wire_ = Block(Tlv::FaceManagement::FaceInstance);
+
+ // Action
+ if (!action_.empty())
+ {
+ wire_.push_back
+ (dataBlock(Tlv::FaceManagement::Action, action_.c_str(), action_.size()));
+ }
+
+ // FaceID
+ if (faceId_ >= 0)
+ {
+ wire_.push_back
+ (nonNegativeIntegerBlock(Tlv::FaceManagement::FaceID, faceId_));
+ }
+
+ // IPProto
+ if (ipProto_ >= 0)
+ {
+ wire_.push_back
+ (nonNegativeIntegerBlock(Tlv::FaceManagement::IPProto, ipProto_));
+ }
+
+ // Host
+ if (!host_.empty())
+ {
+ wire_.push_back
+ (dataBlock(Tlv::FaceManagement::Host, host_.c_str(), host_.size()));
+ }
+
+ // Port
+ if (!port_.empty())
+ {
+ wire_.push_back
+ (dataBlock(Tlv::FaceManagement::Port, port_.c_str(), port_.size()));
+ }
+
+ // MulticastInterface
+ if (!multicastInterface_.empty())
+ {
+ wire_.push_back
+ (dataBlock(Tlv::FaceManagement::MulticastInterface, multicastInterface_.c_str(), multicastInterface_.size()));
+ }
+
+ // MulticastTTL
+ if (multicastTtl_ >= 0)
+ {
+ wire_.push_back
+ (nonNegativeIntegerBlock(Tlv::FaceManagement::MulticastTTL, multicastTtl_));
+ }
+
+ // FreshnessPeriod
+ if (freshnessPeriod_ >= 0)
+ {
+ wire_.push_back
+ (nonNegativeIntegerBlock(Tlv::FreshnessPeriod, freshnessPeriod_));
+ }
+
+ wire_.encode();
+ return wire_;
+}
+
+inline void
+FaceInstance::wireDecode(const Block &wire)
+{
+ action_.clear();
+ faceId_ = -1;
+ ipProto_ = -1;
+ host_.clear();
+ port_.clear();
+ multicastInterface_.clear();
+ multicastTtl_ = -1;
+ freshnessPeriod_ = -1;
+
+ wire_ = wire;
+ wire_.parse();
+
+ // FaceInstance ::= FACE-INSTANCE-TYPE TLV-LENGTH
+ // Action?
+ // FaceID?
+ // IPProto?
+ // Host?
+ // Port?
+ // MulticastInterface?
+ // MulticastTTL?
+ // FreshnessPeriod?
+
+ // Action
+ Block::element_iterator val = wire_.find(Tlv::FaceManagement::Action);
+ if (val != wire_.getAll().end())
+ {
+ action_ = std::string(reinterpret_cast<const char*>(val->value()), val->value_size());
+ }
+
+ // FaceID
+ val = wire_.find(Tlv::FaceManagement::FaceID);
+ if (val != wire_.getAll().end())
+ {
+ faceId_ = readNonNegativeInteger(*val);
+ }
+
+ // IPProto
+ val = wire_.find(Tlv::FaceManagement::IPProto);
+ if (val != wire_.getAll().end())
+ {
+ ipProto_ = readNonNegativeInteger(*val);
+ }
+
+ // Host
+ val = wire_.find(Tlv::FaceManagement::Host);
+ if (val != wire_.getAll().end())
+ {
+ host_ = std::string(reinterpret_cast<const char*>(val->value()), val->value_size());
+ }
+
+ // Port
+ val = wire_.find(Tlv::FaceManagement::Port);
+ if (val != wire_.getAll().end())
+ {
+ port_ = std::string(reinterpret_cast<const char*>(val->value()), val->value_size());
+ }
+
+ // MulticastInterface
+ val = wire_.find(Tlv::FaceManagement::MulticastInterface);
+ if (val != wire_.getAll().end())
+ {
+ multicastInterface_ = std::string(reinterpret_cast<const char*>(val->value()), val->value_size());
+ }
+
+ // MulticastTTL
+ val = wire_.find(Tlv::FaceManagement::MulticastTTL);
+ if (val != wire_.getAll().end())
+ {
+ multicastTtl_ = readNonNegativeInteger(*val);
+ }
+
+ // FreshnessPeriod
+ val = wire_.find(Tlv::FreshnessPeriod);
+ if (val != wire_.getAll().end())
+ {
+ freshnessPeriod_ = readNonNegativeInteger(*val);
+ }
+}
+
+inline std::ostream&
+operator << (std::ostream &os, const FaceInstance &entry)
+{
+ os << "FaceInstance(";
+
+ // Action
+ if (!entry.getAction().empty())
+ {
+ os << "Action:" << entry.getAction() << ", ";
+ }
+
+ // FaceID
+ if (entry.getFaceId() >= 0)
+ {
+ os << "FaceID:" << entry.getFaceId() << ", ";
+ }
+
+ // IPProto
+ if (entry.getIpProto() >= 0)
+ {
+ os << "IPProto:" << entry.getIpProto() << ", ";
+ }
+
+ // Host
+ if (!entry.getHost().empty())
+ {
+ os << "Host:" << entry.getHost() << ", ";
+ }
+
+ // Port
+ if (!entry.getPort().empty())
+ {
+ os << "Port:" << entry.getPort() << ", ";
+ }
+
+ // MulticastInterface
+ if (!entry.getMulticastInterface().empty())
+ {
+ os << "MulticastInterface:" << entry.getMulticastInterface() << ", ";
+ }
+
+ // MulticastTTL
+ if (entry.getMulticastTtl() >= 0)
+ {
+ os << "MulticastTTL:" << entry.getMulticastTtl() << ", ";
+ }
+
+ // FreshnessPeriod
+ if (entry.getFreshnessPeriod() >= 0)
+ {
+ os << "FreshnessPeriod:" << entry.getFreshnessPeriod() << ", ";
+ }
+
+ os << ")";
+ return os;
+}
+
+}
+
+#endif // FACE_INSTANCE
diff --git a/include/ndn-cpp-dev/face.hpp b/include/ndn-cpp-dev/face.hpp
new file mode 100644
index 0000000..e006458
--- /dev/null
+++ b/include/ndn-cpp-dev/face.hpp
@@ -0,0 +1,193 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_FACE_HPP
+#define NDN_FACE_HPP
+
+#include "node.hpp"
+#include "transport/transport.hpp"
+#include "transport/unix-transport.hpp"
+
+namespace ndn {
+
+/**
+ * The Face class provides the main methods for NDN communication.
+ */
+class Face {
+public:
+ /**
+ * Create a new Face for communication with an NDN hub at host:port using the default TcpTransport.
+ * @param host The host of the NDN hub.
+ * @param port The port of the NDN hub. If omitted. use 6363.
+ */
+ Face()
+ : node_(ptr_lib::shared_ptr<UnixTransport>(new UnixTransport()))
+ {
+ }
+
+ /**
+ * Create a new Face for communication with an NDN hub with the given Transport object and connectionInfo.
+ * @param transport A shared_ptr to a Transport object used for communication.
+ * @param transport A shared_ptr to a Transport::ConnectionInfo to be used to connect to the transport.
+ */
+ Face(const ptr_lib::shared_ptr<Transport>& transport)
+ : node_(transport)
+ {
+ }
+
+ /**
+ * Create a new Face for communication with an NDN hub at host:port using the default TcpTransport.
+ * @param host The host of the NDN hub.
+ * @param port The port of the NDN hub. If omitted. use 6363.
+ */
+ // Face(const char *host, unsigned short port = 6363)
+ // : node_(ptr_lib::shared_ptr<TcpTransport>(new TcpTransport(host, port)))
+ // {
+ // }
+
+ /**
+ * Send the Interest through the transport, read the entire response and call onData(interest, data).
+ * @param interest A reference to the Interest. This copies the Interest.
+ * @param onData A function object to call when a matching data packet is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ * @param onTimeout A function object to call if the interest times out. If onTimeout is an empty OnTimeout(), this does not use it.
+ * This copies the function object, so you may need to use func_lib::ref() as appropriate.
+ * @param wireFormat A WireFormat object used to encode the message. If omitted, use WireFormat getDefaultWireFormat().
+ * @return The pending interest ID which can be used with removePendingInterest.
+ */
+ uint64_t
+ expressInterest
+ (const Interest& interest, const OnData& onData, const OnTimeout& onTimeout = OnTimeout())
+ {
+ return node_.expressInterest(interest, onData, onTimeout);
+ }
+
+ /**
+ * Encode name as an Interest. If interestTemplate is not 0, use its interest selectors.
+ * Send the interest through the transport, read the entire response and call onData(interest, data).
+ * @param name A reference to a Name for the interest. This copies the Name.
+ * @param interestTemplate if not 0, copy interest selectors from the template. This does not keep a pointer to the Interest object.
+ * @param onData A function object to call when a matching data packet is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ * @param onTimeout A function object to call if the interest times out. If onTimeout is an empty OnTimeout(), this does not use it.
+ * This copies the function object, so you may need to use func_lib::ref() as appropriate.
+ * @param wireFormat A WireFormat object used to encode the message. If omitted, use WireFormat getDefaultWireFormat().
+ * @return The pending interest ID which can be used with removePendingInterest.
+ */
+ uint64_t
+ expressInterest
+ (const Name& name, const Interest *interestTemplate, const OnData& onData, const OnTimeout& onTimeout = OnTimeout());
+
+ /**
+ * Encode name as an Interest, using a default interest lifetime.
+ * Send the interest through the transport, read the entire response and call onData(interest, data).
+ * @param name A reference to a Name for the interest. This copies the Name.
+ * @param onData A function object to call when a matching data packet is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ * @param onTimeout A function object to call if the interest times out. If onTimeout is an empty OnTimeout(), this does not use it.
+ * This copies the function object, so you may need to use func_lib::ref() as appropriate.
+ * @param wireFormat A WireFormat object used to encode the message. If omitted, use WireFormat getDefaultWireFormat().
+ * @return The pending interest ID which can be used with removePendingInterest.
+ */
+ uint64_t
+ expressInterest
+ (const Name& name, const OnData& onData, const OnTimeout& onTimeout = OnTimeout())
+ {
+ return expressInterest(name, 0, onData, onTimeout);
+ }
+
+ /**
+ * Remove the pending interest entry with the pendingInterestId from the pending interest table.
+ * This does not affect another pending interest with a different pendingInterestId, even it if has the same interest name.
+ * If there is no entry with the pendingInterestId, do nothing.
+ * @param pendingInterestId The ID returned from expressInterest.
+ */
+ void
+ removePendingInterest(uint64_t pendingInterestId)
+ {
+ node_.removePendingInterest(pendingInterestId);
+ }
+
+ /**
+ * Register prefix with the connected NDN hub and call onInterest when a matching interest is received.
+ * @param prefix A reference to a Name for the prefix to register. This copies the Name.
+ * @param onInterest A function object to call when a matching interest is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ * @param onRegisterFailed A function object to call if failed to retrieve the connected hub’s ID or failed to register the prefix.
+ * This calls onRegisterFailed(prefix) where prefix is the prefix given to registerPrefix.
+ * @param flags The flags for finer control of which interests are forward to the application. If omitted, use
+ * the default flags defined by the default ForwardingFlags constructor.
+ * @param wireFormat A WireFormat object used to encode the message. If omitted, use WireFormat getDefaultWireFormat().
+ * @return The registered prefix ID which can be used with removeRegisteredPrefix.
+ */
+ uint64_t
+ setInterestFilter
+ (const Name& prefix, const OnInterest& onInterest, const OnRegisterFailed& onRegisterFailed, const ForwardingFlags& flags = ForwardingFlags())
+ {
+ return node_.registerPrefix(prefix, onInterest, onRegisterFailed, flags);
+ }
+
+ /**
+ * Remove the registered prefix entry with the registeredPrefixId from the pending interest table.
+ * This does not affect another registered prefix with a different registeredPrefixId, even it if has the same prefix name.
+ * If there is no entry with the registeredPrefixId, do nothing.
+ * @param registeredPrefixId The ID returned from registerPrefix.
+ */
+ void
+ unsetInterestFilter(uint64_t registeredPrefixId)
+ {
+ node_.removeRegisteredPrefix(registeredPrefixId);
+ }
+
+ /**
+ * @brief Publish data packet
+ *
+ * This method can be called to satisfy the incoming Interest or to put Data packet into the cache
+ * of the local NDN forwarder
+ */
+ void
+ put(const Data &data)
+ {
+ node_.put(data);
+ }
+
+ /**
+ * Process any data to receive or call timeout callbacks.
+ *
+ * This call will block forever (default timeout == 0) to process IO on the face.
+ * To exit, one expected to call face.shutdown() from one of the callback methods.
+ *
+ * If positive timeout is specified, then processEvents will exit after this timeout,
+ * if not stopped earlier with face.shutdown() or when all active events finish.
+ * The call can be called repeatedly, if desired.
+ *
+ * If negative timeout is specified, then processEvents will not block and process only pending
+ * events.
+ *
+ * @throw This may throw an exception for reading data or in the callback for processing the data. If you
+ * call this from an main event loop, you may want to catch and log/disregard all exceptions.
+ */
+ void
+ processEvents(Milliseconds timeout = 0, bool keepThread = false)
+ {
+ // Just call Node's processEvents.
+ node_.processEvents(timeout, keepThread);
+ }
+
+ /**
+ * Shut down and disconnect this Face.
+ */
+ void
+ shutdown();
+
+private:
+ Node node_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/forwarding-entry.hpp b/include/ndn-cpp-dev/forwarding-entry.hpp
new file mode 100644
index 0000000..182dc38
--- /dev/null
+++ b/include/ndn-cpp-dev/forwarding-entry.hpp
@@ -0,0 +1,226 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_FORWARDING_ENTRY_HPP
+#define NDN_FORWARDING_ENTRY_HPP
+
+#include "encoding/tlv-face-management.hpp"
+#include "name.hpp"
+#include "forwarding-flags.hpp"
+#include "encoding/block.hpp"
+
+namespace ndn {
+
+/**
+ * An ForwardingEntry holds an action and Name prefix and other fields for an forwarding entry.
+ */
+class ForwardingEntry {
+public:
+ ForwardingEntry(const std::string& action,
+ const Name& prefix,
+ int faceId = -1,
+ const ForwardingFlags& forwardingFlags = ForwardingFlags(),
+ int freshnessPeriod = -1)
+ : action_(action)
+ , prefix_(prefix)
+ , faceId_(faceId)
+ , forwardingFlags_(forwardingFlags)
+ , freshnessPeriod_(freshnessPeriod)
+ {
+ }
+
+ ForwardingEntry()
+ : faceId_(-1)
+ , freshnessPeriod_(-1)
+ {
+ }
+
+ const std::string&
+ getAction() const { return action_; }
+
+ void
+ setAction(const std::string& action) { action_ = action; wire_.reset(); }
+
+ const Name&
+ getPrefix() const { return prefix_; }
+
+ void
+ setPrefix(const Name &prefix) { prefix_ = prefix; wire_.reset(); }
+
+ int
+ getFaceId() const { return faceId_; }
+
+ void
+ setFaceId(int faceId) { faceId_ = faceId; wire_.reset(); }
+
+ const ForwardingFlags&
+ getForwardingFlags() const { return forwardingFlags_; }
+
+ void
+ setForwardingFlags(const ForwardingFlags& forwardingFlags) { forwardingFlags_ = forwardingFlags; wire_.reset(); }
+
+ int
+ getFreshnessPeriod() const { return freshnessPeriod_; }
+
+ void
+ setFreshnessPeriod(int freshnessPeriod) { freshnessPeriod_ = freshnessPeriod; wire_.reset(); }
+
+ inline const Block&
+ wireEncode() const;
+
+ inline void
+ wireDecode(const Block &wire);
+
+private:
+ std::string action_; /**< empty for none. */
+ Name prefix_;
+ int faceId_; /**< -1 for none. */
+ ForwardingFlags forwardingFlags_;
+ int freshnessPeriod_; /**< -1 for none. */
+
+ mutable Block wire_;
+};
+
+inline const Block&
+ForwardingEntry::wireEncode() const
+{
+ if (wire_.hasWire())
+ return wire_;
+
+ // ForwardingEntry ::= FORWARDING-ENTRY TLV-LENGTH
+ // Action?
+ // Name?
+ // FaceID?
+ // ForwardingFlags?
+ // FreshnessPeriod?
+
+ wire_ = Block(Tlv::FaceManagement::ForwardingEntry);
+
+ // Action
+ if (!action_.empty())
+ {
+ wire_.push_back
+ (dataBlock(Tlv::FaceManagement::Action, action_.c_str(), action_.size()));
+ }
+
+ // Name
+ wire_.push_back
+ (prefix_.wireEncode());
+
+ // FaceID
+ if (faceId_ >= 0)
+ {
+ wire_.push_back
+ (nonNegativeIntegerBlock(Tlv::FaceManagement::FaceID, faceId_));
+ }
+
+ // ForwardingFlags
+ wire_.push_back
+ (forwardingFlags_.wireEncode());
+
+ // FreshnessPeriod
+ if (freshnessPeriod_ >= 0)
+ {
+ wire_.push_back
+ (nonNegativeIntegerBlock(Tlv::FreshnessPeriod, freshnessPeriod_));
+ }
+
+ wire_.encode();
+ return wire_;
+}
+
+inline void
+ForwardingEntry::wireDecode(const Block &wire)
+{
+ action_.clear();
+ prefix_.clear();
+ faceId_ = -1;
+ forwardingFlags_ = ForwardingFlags();
+ freshnessPeriod_ = -1;
+
+ wire_ = wire;
+ wire_.parse();
+
+ // ForwardingEntry ::= FORWARDING-ENTRY TLV-LENGTH
+ // Action?
+ // Name?
+ // FaceID?
+ // ForwardingFlags?
+ // FreshnessPeriod?
+
+ // Action
+ Block::element_iterator val = wire_.find(Tlv::FaceManagement::Action);
+ if (val != wire_.getAll().end())
+ {
+ action_ = std::string(reinterpret_cast<const char*>(val->value()), val->value_size());
+ }
+
+ // Name
+ val = wire_.find(Tlv::Name);
+ if (val != wire_.getAll().end())
+ {
+ prefix_.wireDecode(*val);
+ }
+
+ // FaceID
+ val = wire_.find(Tlv::FaceManagement::FaceID);
+ if (val != wire_.getAll().end())
+ {
+ faceId_ = readNonNegativeInteger(*val);
+ }
+
+ // ForwardingFlags
+ val = wire_.find(Tlv::FaceManagement::ForwardingFlags);
+ if (val != wire_.getAll().end())
+ {
+ forwardingFlags_.wireDecode(*val);
+ }
+
+ // FreshnessPeriod
+ val = wire_.find(Tlv::FreshnessPeriod);
+ if (val != wire_.getAll().end())
+ {
+ freshnessPeriod_ = readNonNegativeInteger(*val);
+ }
+}
+
+inline std::ostream&
+operator << (std::ostream &os, const ForwardingEntry &entry)
+{
+ os << "ForwardingEntry(";
+
+ // Action
+ if (!entry.getAction().empty())
+ {
+ os << "Action:" << entry.getAction() << ", ";
+ }
+
+ // Name
+ os << "Prefix:" << entry.getPrefix() << ", ";
+
+ // FaceID
+ if (entry.getFaceId() >= 0)
+ {
+ os << "FaceID:" << entry.getFaceId() << ", ";
+ }
+
+ // ForwardingFlags
+ os << "ForwardingFlags:" << entry.getForwardingFlags() << ", ";
+
+ // FreshnessPeriod
+ if (entry.getFreshnessPeriod() >= 0)
+ {
+ os << "FreshnessPeriod:" << entry.getFreshnessPeriod() << ", ";
+ }
+
+ os << ")";
+ return os;
+}
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/forwarding-flags.hpp b/include/ndn-cpp-dev/forwarding-flags.hpp
new file mode 100644
index 0000000..a0c81c1
--- /dev/null
+++ b/include/ndn-cpp-dev/forwarding-flags.hpp
@@ -0,0 +1,224 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_FORWARDING_FLAGS_HPP
+#define NDN_FORWARDING_FLAGS_HPP
+
+#include "encoding/block.hpp"
+#include "encoding/tlv-face-management.hpp"
+
+namespace ndn {
+
+/**
+ * A ForwardingFlags object holds the flags which specify how the forwarding daemon should forward an interest for
+ * a registered prefix. We use a separate ForwardingFlags object to retain future compatibility if the daemon forwarding
+ * bits are changed, amended or deprecated.
+ */
+class ForwardingFlags {
+public:
+ /**
+ * Create a new ForwardingFlags with "active" and "childInherit" set and all other flags cleared.
+ */
+ ForwardingFlags()
+ : active_(true)
+ , childInherit_(true)
+ , advertise_(false)
+ , last_(false)
+ , capture_(false)
+ , local_(false)
+ , tap_(false)
+ , captureOk_(false)
+ {
+ }
+
+ /**
+ * Get the value of the "active" flag.
+ * @return true if the flag is set, false if it is cleared.
+ */
+ bool getActive() const { return active_; }
+
+ /**
+ * Get the value of the "childInherit" flag.
+ * @return true if the flag is set, false if it is cleared.
+ */
+ bool getChildInherit() const { return childInherit_; }
+
+ /**
+ * Get the value of the "advertise" flag.
+ * @return true if the flag is set, false if it is cleared.
+ */
+ bool getAdvertise() const { return advertise_; }
+
+ /**
+ * Get the value of the "last" flag.
+ * @return true if the flag is set, false if it is cleared.
+ */
+ bool getLast() const { return last_; }
+
+ /**
+ * Get the value of the "capture" flag.
+ * @return true if the flag is set, false if it is cleared.
+ */
+ bool getCapture() const { return capture_; }
+
+ /**
+ * Get the value of the "local" flag.
+ * @return true if the flag is set, false if it is cleared.
+ */
+ bool getLocal() const { return local_; }
+
+ /**
+ * Get the value of the "tap" flag.
+ * @return true if the flag is set, false if it is cleared.
+ */
+ bool getTap() const { return tap_; }
+
+ /**
+ * Get the value of the "captureOk" flag.
+ * @return true if the flag is set, false if it is cleared.
+ */
+ bool getCaptureOk() const { return captureOk_; }
+
+ /**
+ * Set the value of the "active" flag
+ * @param active true to set the flag, false to clear it.
+ */
+ void setActive(bool active) { this->active_ = active; wire_.reset(); }
+
+ /**
+ * Set the value of the "childInherit" flag
+ * @param childInherit true to set the flag, false to clear it.
+ */
+ void setChildInherit(bool childInherit) { this->childInherit_ = childInherit; wire_.reset(); }
+
+ /**
+ * Set the value of the "advertise" flag
+ * @param advertise true to set the flag, false to clear it.
+ */
+ void setAdvertise(bool advertise) { this->advertise_ = advertise; wire_.reset(); }
+
+ /**
+ * Set the value of the "last" flag
+ * @param last true to set the flag, false to clear it.
+ */
+ void setLast(bool last) { this->last_ = last; wire_.reset(); }
+
+ /**
+ * Set the value of the "capture" flag
+ * @param capture true to set the flag, false to clear it.
+ */
+ void setCapture(bool capture) { this->capture_ = capture; wire_.reset(); }
+
+ /**
+ * Set the value of the "local" flag
+ * @param local true to set the flag, false to clear it.
+ */
+ void setLocal(bool local) { this->local_ = local; wire_.reset(); }
+
+ /**
+ * Set the value of the "tap" flag
+ * @param tap true to set the flag, false to clear it.
+ */
+ void setTap(bool tap) { this->tap_ = tap; wire_.reset(); }
+
+ /**
+ * Set the value of the "captureOk" flag
+ * @param captureOk true to set the flag, false to clear it.
+ */
+ void setCaptureOk(bool captureOk) { this->captureOk_ = captureOk; wire_.reset(); }
+
+ inline const Block&
+ wireEncode() const;
+
+ inline void
+ wireDecode(const Block &block);
+
+private:
+ bool active_;
+ bool childInherit_;
+ bool advertise_;
+ bool last_;
+ bool capture_;
+ bool local_;
+ bool tap_;
+ bool captureOk_;
+
+ mutable Block wire_;
+};
+
+inline const Block&
+ForwardingFlags::wireEncode() const
+{
+ if (wire_.hasWire())
+ return wire_;
+
+ uint32_t result = 0;
+ if (active_)
+ result |= Tlv::FaceManagement::FORW_ACTIVE;
+ if (childInherit_)
+ result |= Tlv::FaceManagement::FORW_CHILD_INHERIT;
+ if (advertise_)
+ result |= Tlv::FaceManagement::FORW_ADVERTISE;
+ if (last_)
+ result |= Tlv::FaceManagement::FORW_LAST;
+ if (capture_)
+ result |= Tlv::FaceManagement::FORW_CAPTURE;
+ if (local_)
+ result |= Tlv::FaceManagement::FORW_LOCAL;
+ if (tap_)
+ result |= Tlv::FaceManagement::FORW_TAP;
+ if (captureOk_)
+ result |= Tlv::FaceManagement::FORW_CAPTURE_OK;
+
+ wire_ = nonNegativeIntegerBlock(Tlv::FaceManagement::ForwardingFlags, result);
+
+ return wire_;
+}
+
+inline void
+ForwardingFlags::wireDecode(const Block &wire)
+{
+ wire_ = wire;
+
+ uint32_t flags = readNonNegativeInteger(wire_);
+
+ active_ = (flags & Tlv::FaceManagement::FORW_ACTIVE) ? true : false;
+ childInherit_ = (flags & Tlv::FaceManagement::FORW_CHILD_INHERIT) ? true : false;
+ advertise_ = (flags & Tlv::FaceManagement::FORW_ADVERTISE) ? true : false;
+ last_ = (flags & Tlv::FaceManagement::FORW_LAST) ? true : false;
+ capture_ = (flags & Tlv::FaceManagement::FORW_CAPTURE) ? true : false;
+ local_ = (flags & Tlv::FaceManagement::FORW_LOCAL) ? true : false;
+ tap_ = (flags & Tlv::FaceManagement::FORW_TAP) ? true : false;
+ captureOk_ = (flags & Tlv::FaceManagement::FORW_CAPTURE_OK) ? true : false;
+}
+
+inline std::ostream&
+operator << (std::ostream &os, const ForwardingFlags &flags)
+{
+ if (flags.getActive())
+ os << "ACTIVE ";
+ if (flags.getChildInherit())
+ os << "CHILE_INHERIT ";
+ if (flags.getAdvertise())
+ os << "ADVERTISE ";
+ if (flags.getLast())
+ os << "LAST ";
+ if (flags.getCapture())
+ os << "CAPTURE ";
+ if (flags.getLocal())
+ os << "LOCAL ";
+ if (flags.getTap())
+ os << "TAP ";
+ if (flags.getCaptureOk())
+ os << "CAPTURE_OK ";
+
+ return os;
+}
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/interest.hpp b/include/ndn-cpp-dev/interest.hpp
new file mode 100644
index 0000000..8fe3119
--- /dev/null
+++ b/include/ndn-cpp-dev/interest.hpp
@@ -0,0 +1,243 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_INTEREST_HPP
+#define NDN_INTEREST_HPP
+
+#include "name.hpp"
+#include "exclude.hpp"
+#include "encoding/block.hpp"
+
+namespace ndn {
+
+/**
+ * An Interest holds a Name and other fields for an interest.
+ */
+class Interest {
+public:
+ /**
+ * Create a new Interest for the given name and values.
+ * @param name
+ * @param minSuffixComponents
+ * @param maxSuffixComponents
+ * @param exclude
+ * @param childSelector
+ * @param mustBeFresh
+ * @param scope
+ * @param interestLifetime
+ * @param nonce
+ */
+ Interest(const Name& name,
+ int minSuffixComponents, int maxSuffixComponents,
+ const Exclude& exclude,
+ int childSelector,
+ bool mustBeFresh,
+ int scope,
+ Milliseconds interestLifetime,
+ uint32_t nonce = 0)
+ : name_(name)
+ , minSuffixComponents_(minSuffixComponents)
+ , maxSuffixComponents_(maxSuffixComponents)
+ , exclude_(exclude), childSelector_(childSelector)
+ , mustBeFresh_(mustBeFresh)
+ , scope_(scope)
+ , interestLifetime_(interestLifetime)
+ , nonce_(nonce)
+ {
+ }
+
+ /**
+ * Create a new Interest with the given name and interest lifetime and "none" for other values.
+ * @param name The name for the interest.
+ * @param interestLifetimeMilliseconds The interest lifetime in milliseconds, or -1 for none.
+ */
+ Interest(const Name& name, Milliseconds interestLifetime)
+ : name_(name)
+ {
+ construct();
+ interestLifetime_ = interestLifetime;
+ }
+
+ /**
+ * Create a new Interest with the given name and "none" for other values.
+ * @param name The name for the interest.
+ */
+ Interest(const Name& name)
+ : name_(name)
+ {
+ construct();
+ }
+
+ /**
+ * Create a new Interest with an empty name and "none" for all values.
+ */
+ Interest()
+ {
+ construct();
+ }
+
+ /**
+ * Encode this Interest for a particular wire format.
+ * @return The encoded byte array.
+ */
+ const Block&
+ wireEncode() const;
+
+ /**
+ * Decode the input using a particular wire format and update this Interest.
+ * @param input The input byte array to be decoded.
+ */
+ void
+ wireDecode(const Block &wire);
+
+ /**
+ * Encode the name according to the "NDN URI Scheme". If there are interest selectors, append "?" and
+ * added the selectors as a query string. For example "/test/name?ndn.ChildSelector=1".
+ * @return The URI string.
+ */
+ inline std::string
+ toUri() const;
+
+ Name&
+ getName() { return name_; }
+
+ const Name&
+ getName() const { return name_; }
+
+ int
+ getMinSuffixComponents() const { return minSuffixComponents_; }
+
+ int
+ getMaxSuffixComponents() const { return maxSuffixComponents_; }
+
+ Exclude&
+ getExclude() { return exclude_; }
+
+ const Exclude&
+ getExclude() const { return exclude_; }
+
+ int
+ getChildSelector() const { return childSelector_; }
+
+ int
+ getMustBeFresh() const { return mustBeFresh_; }
+
+ int
+ getScope() const { return scope_; }
+
+ Milliseconds
+ getInterestLifetime() const { return interestLifetime_; }
+
+ /**
+ * @brief Get Interest's nonce
+ *
+ * If nonce was not set before this call, it will be automatically assigned to a random value
+ *
+ * Const reference needed for C decoding
+ */
+ const uint32_t&
+ getNonce() const;
+
+ void
+ setName(const Name& name) { name_ = name; }
+
+ void
+ setMinSuffixComponents(int minSuffixComponents) { minSuffixComponents_ = minSuffixComponents; }
+
+ void
+ setMaxSuffixComponents(int maxSuffixComponents) { maxSuffixComponents_ = maxSuffixComponents; }
+
+ void
+ setChildSelector(int childSelector) { childSelector_ = childSelector; }
+
+ void
+ setMustBeFresh(bool mustBeFresh) { mustBeFresh_ = mustBeFresh; }
+
+ void
+ setScope(int scope) { scope_ = scope; }
+
+ void
+ setInterestLifetime(Milliseconds interestLifetime) { interestLifetime_ = interestLifetime; }
+
+ void
+ setNonce(uint32_t nonce) { nonce_ = nonce; }
+
+ inline bool
+ hasSelectors() const;
+
+ inline bool
+ hasGuiders() const;
+
+ /**
+ * @brief Check if Interest name matches the given name (using ndn_Name_match) and the given name also conforms to the
+ * interest selectors.
+ * @param self A pointer to the ndn_Interest struct.
+ * @param name A pointer to the name to check.
+ * @return 1 if the name and interest selectors match, 0 otherwise.
+ */
+ bool
+ matchesName(const Name &name) const;
+
+private:
+ void
+ construct()
+ {
+ minSuffixComponents_ = -1;
+ maxSuffixComponents_ = -1;
+ childSelector_ = -1;
+ mustBeFresh_ = false; // default
+ scope_ = -1;
+ interestLifetime_ = -1.0;
+ nonce_ = 0;
+ }
+
+ Name name_;
+ int minSuffixComponents_;
+ int maxSuffixComponents_;
+ Exclude exclude_;
+ int childSelector_;
+ bool mustBeFresh_;
+ int scope_;
+ Milliseconds interestLifetime_;
+ mutable uint32_t nonce_;
+
+ mutable Block wire_;
+};
+
+std::ostream &
+operator << (std::ostream &os, const Interest &interest);
+
+inline std::string
+Interest::toUri() const
+{
+ std::ostringstream os;
+ os << *this;
+ return os.str();
+}
+
+inline bool
+Interest::hasSelectors() const
+{
+ return minSuffixComponents_ >= 0 ||
+ maxSuffixComponents_ >= 0 ||
+ !exclude_.empty() ||
+ childSelector_ >= 0 ||
+ mustBeFresh_ == true ||
+ scope_ >= 0;
+}
+
+inline bool
+Interest::hasGuiders() const
+{
+ return scope_ >= 0 ||
+ interestLifetime_ >= 0 ||
+ nonce_ > 0;
+}
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/key-locator.hpp b/include/ndn-cpp-dev/key-locator.hpp
new file mode 100644
index 0000000..2ff85f0
--- /dev/null
+++ b/include/ndn-cpp-dev/key-locator.hpp
@@ -0,0 +1,135 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_KEY_LOCATOR_HPP
+#define NDN_KEY_LOCATOR_HPP
+
+#include "encoding/block.hpp"
+#include "name.hpp"
+
+namespace ndn {
+
+class KeyLocator {
+public:
+ struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+ enum {
+ KeyLocator_None = -1,
+ KeyLocator_Name = 0,
+
+ KeyLocator_Unknown = 255
+ };
+
+ inline
+ KeyLocator()
+ : type_(KeyLocator_None)
+ {
+ }
+
+ inline
+ KeyLocator(const Name &name);
+
+ inline const Block&
+ wireEncode() const;
+
+ inline void
+ wireDecode(const Block &value);
+
+ inline bool
+ empty() const
+ {
+ return type_ == KeyLocator_None;
+ }
+
+ uint32_t
+ getType() const { return type_; }
+
+ ////////////////////////////////////////////////////////
+ // Helper methods for different types of key locators
+ //
+ // For now only Name type is actually supported
+
+ inline const Name&
+ getName() const;
+
+ inline void
+ setName(const Name &name);
+
+private:
+ uint32_t type_;
+ Name name_;
+
+ mutable Block wire_;
+};
+
+inline
+KeyLocator::KeyLocator(const Name &name)
+{
+ setName(name);
+}
+
+inline const Block&
+KeyLocator::wireEncode() const
+{
+ if (wire_.hasWire())
+ return wire_;
+
+ // KeyLocator
+
+ switch (type_) {
+ case KeyLocator_None:
+ wire_ = dataBlock(Tlv::KeyLocator, reinterpret_cast<const uint8_t*>(0), 0);
+ break;
+ case KeyLocator_Name:
+ wire_ = Block(Tlv::KeyLocator);
+ wire_.push_back(name_.wireEncode());
+ wire_.encode();
+ break;
+ default:
+ throw Error("Unsupported KeyLocator type");
+ }
+
+ return wire_;
+}
+
+inline void
+KeyLocator::wireDecode(const Block &value)
+{
+ wire_ = value;
+ wire_.parse();
+
+ if (!wire_.getAll().empty() && wire_.getAll().front().type() == Tlv::Name)
+ {
+ type_ = KeyLocator_Name;
+ name_.wireDecode(wire_.getAll().front());
+ }
+ else
+ {
+ type_ = KeyLocator_Unknown;
+ }
+}
+
+inline const Name&
+KeyLocator::getName() const
+{
+ if (type_ != KeyLocator_Name)
+ throw Error("Requested Name, but KeyLocator is not of the Name type");
+
+ return name_;
+}
+
+inline void
+KeyLocator::setName(const Name &name)
+{
+ type_ = KeyLocator_Name;
+ name_ = name;
+}
+
+
+} // namespace ndn
+
+#endif
diff --git a/include/ndn-cpp-dev/meta-info.hpp b/include/ndn-cpp-dev/meta-info.hpp
new file mode 100644
index 0000000..5ad07f6
--- /dev/null
+++ b/include/ndn-cpp-dev/meta-info.hpp
@@ -0,0 +1,127 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_META_INFO_HPP
+#define NDN_META_INFO_HPP
+
+namespace ndn {
+
+/**
+ * An MetaInfo holds the meta info which is signed inside the data packet.
+ */
+class MetaInfo {
+public:
+ enum {
+ TYPE_DEFAULT = 0,
+ TYPE_LINK = 1,
+ TYPE_KEY = 2
+ };
+
+ MetaInfo()
+ : type_(TYPE_DEFAULT)
+ , freshnessPeriod_(-1)
+ {
+ }
+
+ uint32_t
+ getType() const
+ { return type_; }
+
+ void
+ setType(uint32_t type)
+ { type_ = type; }
+
+ Milliseconds
+ getFreshnessPeriod() const
+ { return freshnessPeriod_; }
+
+ void
+ setFreshnessPeriod(Milliseconds freshnessPeriod)
+ { freshnessPeriod_ = freshnessPeriod; }
+
+ inline const Block&
+ wireEncode() const;
+
+ inline void
+ wireDecode(const Block &wire);
+
+private:
+ uint32_t type_;
+ Milliseconds freshnessPeriod_;
+
+ mutable Block wire_;
+};
+
+inline const Block&
+MetaInfo::wireEncode() const
+{
+ if (wire_.hasWire())
+ return wire_;
+
+ // MetaInfo ::= META-INFO-TYPE TLV-LENGTH
+ // ContentType?
+ // FreshnessPeriod?
+
+ wire_ = Block(Tlv::MetaInfo);
+
+ // ContentType
+ if (type_ != TYPE_DEFAULT) {
+ wire_.push_back
+ (nonNegativeIntegerBlock(Tlv::ContentType, type_));
+ }
+
+ // FreshnessPeriod
+ if (freshnessPeriod_ >= 0) {
+ wire_.push_back
+ (nonNegativeIntegerBlock(Tlv::FreshnessPeriod, freshnessPeriod_));
+ }
+
+ wire_.encode();
+ return wire_;
+}
+
+inline void
+MetaInfo::wireDecode(const Block &wire)
+{
+ wire_ = wire;
+ wire_.parse();
+
+ // MetaInfo ::= META-INFO-TYPE TLV-LENGTH
+ // ContentType?
+ // FreshnessPeriod?
+
+ // ContentType
+ Block::element_iterator val = wire_.find(Tlv::ContentType);
+ if (val != wire_.getAll().end())
+ {
+ type_ = readNonNegativeInteger(*val);
+ }
+
+ // FreshnessPeriod
+ val = wire_.find(Tlv::FreshnessPeriod);
+ if (val != wire_.getAll().end())
+ {
+ freshnessPeriod_ = readNonNegativeInteger(*val);
+ }
+}
+
+inline std::ostream&
+operator << (std::ostream &os, const MetaInfo &info)
+{
+ // ContentType
+ os << "ContentType: " << info.getType();
+
+ // FreshnessPeriod
+ if (info.getFreshnessPeriod() >= 0) {
+ os << ", FreshnessPeriod: " << info.getFreshnessPeriod();
+ }
+ return os;
+}
+
+} // namespace ndn
+
+#endif // NDN_META_INFO_HPP
diff --git a/include/ndn-cpp-dev/name.hpp b/include/ndn-cpp-dev/name.hpp
new file mode 100644
index 0000000..c4e7e5c
--- /dev/null
+++ b/include/ndn-cpp-dev/name.hpp
@@ -0,0 +1,799 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * @author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ * @author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_NAME_HPP
+#define NDN_NAME_HPP
+
+#include <vector>
+#include <string>
+#include <sstream>
+#include <string.h>
+#include "encoding/block.hpp"
+
+namespace ndn {
+
+/**
+ * A Name holds an array of Name::Component and represents an NDN name.
+ */
+class Name {
+public:
+ /**
+ * A Name::Component holds a read-only name component value.
+ */
+ class Component
+ {
+ public:
+ /**
+ * Create a new Name::Component with a null value.
+ */
+ Component()
+ {
+ }
+
+ // copy constructor OK
+
+ /**
+ * Create a new Name::Component, taking another pointer to the Blob value.
+ * @param value A blob with a pointer to an immutable array. The pointer is copied.
+ */
+ Component(const ConstBufferPtr &buffer)
+ : value_ (buffer)
+ {
+ }
+
+ /**
+ * Create a new Name::Component, copying the given value.
+ * @param value The value byte array.
+ */
+ Component(const Buffer& value)
+ : value_ (new Buffer(value))
+ {
+ }
+
+ /**
+ * Create a new Name::Component, copying the given value.
+ * @param value Pointer to the value byte array.
+ * @param valueLen Length of value.
+ */
+ Component(const uint8_t *value, size_t valueLen)
+ : value_ (new Buffer(value, valueLen))
+ {
+ }
+
+ template<class InputIterator>
+ Component(InputIterator begin, InputIterator end)
+ : value_ (new Buffer(begin, end))
+ {
+ }
+
+ Component(const char *string)
+ : value_ (new Buffer(string, ::strlen(string)))
+ {
+ }
+
+ const Buffer&
+ getValue() const { return *value_; }
+
+ /**
+ * Write this component value to result, escaping characters according to the NDN URI Scheme.
+ * This also adds "..." to a value with zero or more ".".
+ * @param result the string stream to write to.
+ */
+ void
+ toEscapedString(std::ostream& result) const
+ {
+ Name::toEscapedString(*value_, result);
+ }
+
+ /**
+ * Convert this component value by escaping characters according to the NDN URI Scheme.
+ * This also adds "..." to a value with zero or more ".".
+ * @return The escaped string.
+ */
+ std::string
+ toEscapedString() const
+ {
+ return Name::toEscapedString(*value_);
+ }
+
+ /**
+ * Interpret this name component as a network-ordered number and return an integer.
+ * @return The integer number.
+ */
+ uint64_t
+ toNumber() const;
+
+ /**
+ * Interpret this name component as a network-ordered number with a marker and return an integer.
+ * @param marker The required first byte of the component.
+ * @return The integer number.
+ * @throw runtime_error If the first byte of the component does not equal the marker.
+ */
+ uint64_t
+ toNumberWithMarker(uint8_t marker) const;
+
+ /**
+ * Interpret this name component as a segment number according to NDN name conventions (a network-ordered number
+ * where the first byte is the marker 0x00).
+ * @return The integer segment number.
+ * @throw runtime_error If the first byte of the component is not the expected marker.
+ */
+ uint64_t
+ toSegment() const
+ {
+ return toNumberWithMarker(0x00);
+ }
+
+ /**
+ * @deprecated Use toSegment.
+ */
+ uint64_t
+ toSeqNum() const
+ {
+ return toSegment();
+ }
+
+ /**
+ * Interpret this name component as a version number according to NDN name conventions (a network-ordered number
+ * where the first byte is the marker 0xFD). Note that this returns the exact number from the component
+ * without converting it to a time representation.
+ * @return The integer segment number.
+ * @throw runtime_error If the first byte of the component is not the expected marker.
+ */
+ uint64_t
+ toVersion() const
+ {
+ return toNumberWithMarker(0xFD);
+ }
+
+ /**
+ * Create a component whose value is the network-ordered encoding of the number.
+ * Note: if the number is zero, the result is empty.
+ * @param number The number to be encoded.
+ * @return The component value.
+ */
+ static Component
+ fromNumber(uint64_t number);
+
+ /**
+ * Create a component whose value is the marker appended with the network-ordered encoding of the number.
+ * Note: if the number is zero, no bytes are used for the number - the result will have only the marker.
+ * @param number The number to be encoded.
+ * @param marker The marker to use as the first byte of the component.
+ * @return The component value.
+ */
+ static Component
+ fromNumberWithMarker(uint64_t number, uint8_t marker);
+
+ /**
+ * Check if this is the same component as other.
+ * @param other The other Component to compare with.
+ * @return true if the components are equal, otherwise false.
+ */
+ bool
+ equals(const Component& other) const
+ {
+ return *value_ == *other.value_;
+ }
+
+ bool
+ empty() const
+ {
+ return !value_ || value_->empty();
+ }
+
+ /**
+ * Check if this is the same component as other.
+ * @param other The other Component to compare with.
+ * @return true if the components are equal, otherwise false.
+ */
+ bool
+ operator == (const Component& other) const { return equals(other); }
+
+ /**
+ * Check if this is not the same component as other.
+ * @param other The other Component to compare with.
+ * @return true if the components are not equal, otherwise false.
+ */
+ bool
+ operator != (const Component& other) const { return !equals(other); }
+
+ /**
+ * Compare this to the other Component using NDN canonical ordering.
+ * @param other The other Component to compare with.
+ * @return 0 If they compare equal, -1 if *this comes before other in the canonical ordering, or
+ * 1 if *this comes after other in the canonical ordering.
+ *
+ * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
+ */
+ int
+ compare(const Component& other) const;
+
+ /**
+ * Return true if this is less than or equal to the other Component in the NDN canonical ordering.
+ * @param other The other Component to compare with.
+ *
+ * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
+ */
+ bool
+ operator <= (const Component& other) const { return compare(other) <= 0; }
+
+ /**
+ * Return true if this is less than the other Component in the NDN canonical ordering.
+ * @param other The other Component to compare with.
+ *
+ * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
+ */
+ bool
+ operator < (const Component& other) const { return compare(other) < 0; }
+
+ /**
+ * Return true if this is less than or equal to the other Component in the NDN canonical ordering.
+ * @param other The other Component to compare with.
+ *
+ * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
+ */
+ bool
+ operator >= (const Component& other) const { return compare(other) >= 0; }
+
+ /**
+ * Return true if this is greater than the other Component in the NDN canonical ordering.
+ * @param other The other Component to compare with.
+ *
+ * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
+ */
+ bool
+ operator > (const Component& other) const { return compare(other) > 0; }
+ private:
+ ConstBufferPtr value_;
+ };
+
+ /**
+ * Create a new Name with no components.
+ */
+ Name() {
+ }
+
+ /**
+ * Create a new Name, copying the name components.
+ * @param components A vector of Component
+ */
+ Name(const std::vector<Component>& components)
+ : components_(components)
+ {
+ }
+
+ Name(const Block &name)
+ {
+ for (Block::element_const_iterator i = name.getAll().begin();
+ i != name.getAll().end();
+ ++i)
+ {
+ append(Component(i->value_begin(), i->value_end()));
+ }
+ }
+
+ /**
+ * Parse the uri according to the NDN URI Scheme and create the name with the components.
+ * @param uri The URI string.
+ */
+ Name(const char* uri)
+ {
+ set(uri);
+ }
+
+ /**
+ * Parse the uri according to the NDN URI Scheme and create the name with the components.
+ * @param uri The URI string.
+ */
+ Name(const std::string& uri)
+ {
+ set(uri.c_str());
+ }
+
+ const Block &
+ wireEncode() const;
+
+ void
+ wireDecode(const Block &wire);
+
+ /**
+ * Parse the uri according to the NDN URI Scheme and set the name with the components.
+ * @param uri The null-terminated URI string.
+ */
+ void
+ set(const char *uri);
+
+ /**
+ * Parse the uri according to the NDN URI Scheme and set the name with the components.
+ * @param uri The URI string.
+ */
+ void
+ set(const std::string& uri) { set(uri.c_str()); }
+
+ /**
+ * Append a new component, copying from value of length valueLength.
+ * @return This name so that you can chain calls to append.
+ */
+ Name&
+ append(const uint8_t *value, size_t valueLength)
+ {
+ components_.push_back(Component(value, valueLength));
+ return *this;
+ }
+
+ /**
+ * Append a new component, copying from value.
+ * @return This name so that you can chain calls to append.
+ */
+ Name&
+ append(const Buffer& value)
+ {
+ components_.push_back(value);
+ return *this;
+ }
+
+ Name&
+ append(const ConstBufferPtr &value)
+ {
+ components_.push_back(value);
+ return *this;
+ }
+
+ Name&
+ append(const Component &value)
+ {
+ components_.push_back(value);
+ return *this;
+ }
+
+ /**
+ * @brief Append name component that represented as a string
+ *
+ * Note that this method is necessary to ensure correctness and unambiguity of
+ * ``append("string")`` operations (both Component and Name can be implicitly
+ * converted from string, each having different outcomes
+ */
+ Name&
+ append(const char *value)
+ {
+ components_.push_back(Component(value));
+ return *this;
+ }
+
+ Name&
+ append(const Block &value)
+ {
+ components_.push_back(Component(value.begin(), value.end()));
+ return *this;
+ }
+
+ /**
+ * Append the components of the given name to this name.
+ * @param name The Name with components to append.
+ * @return This name so that you can chain calls to append.
+ */
+ Name&
+ append(const Name& name);
+
+ /**
+ * @deprecated Use append.
+ */
+ Name&
+ appendComponent(const uint8_t *value, size_t valueLength)
+ {
+ return append(value, valueLength);
+ }
+
+ /**
+ * @deprecated Use append.
+ */
+ Name&
+ appendComponent(const Buffer& value)
+ {
+ return append(value);
+ }
+
+ /**
+ * @deprecated Use append.
+ */
+ Name&
+ appendComponent(const ConstBufferPtr &value)
+ {
+ return append(value);
+ }
+
+ /**
+ * @deprecated Use append.
+ */
+ Name&
+ addComponent(const uint8_t *value, size_t valueLength)
+ {
+ return append(value, valueLength);
+ }
+
+ /**
+ * @deprecated Use append.
+ */
+ Name&
+ addComponent(const Buffer& value)
+ {
+ return append(value);
+ }
+
+ /**
+ * @deprecated Use append.
+ */
+ Name&
+ addComponent(const ConstBufferPtr &value)
+ {
+ return append(value);
+ }
+
+ /**
+ * Clear all the components.
+ */
+ void
+ clear() {
+ components_.clear();
+ }
+
+ /**
+ * @deprecated use size().
+ */
+ size_t
+ getComponentCount() const { return size(); }
+
+ /**
+ * @deprecated Use get(i).
+ */
+ const Component&
+ getComponent(size_t i) const { return get(i); }
+
+ /**
+ * Get a new name, constructed as a subset of components.
+ * @param iStartComponent The index if the first component to get.
+ * @param nComponents The number of components starting at iStartComponent.
+ * @return A new name.
+ */
+ Name
+ getSubName(size_t iStartComponent, size_t nComponents) const;
+
+ /**
+ * Get a new name, constructed as a subset of components starting at iStartComponent until the end of the name.
+ * @param iStartComponent The index if the first component to get.
+ * @return A new name.
+ */
+ Name
+ getSubName(size_t iStartComponent) const;
+
+ /**
+ * Return a new Name with the first nComponents components of this Name.
+ * @param nComponents The number of prefix components. If nComponents is -N then return the prefix up
+ * to name.size() - N. For example getPrefix(-1) returns the name without the final component.
+ * @return A new Name.
+ */
+ Name
+ getPrefix(int nComponents) const
+ {
+ if (nComponents < 0)
+ return getSubName(0, components_.size() + nComponents);
+ else
+ return getSubName(0, nComponents);
+ }
+
+ /**
+ * Encode this name as a URI.
+ * @return The encoded URI.
+ */
+ std::string
+ toUri() const;
+
+ /**
+ * Append a component with the encoded segment number.
+ * @param segment The segment number.
+ * @return This name so that you can chain calls to append.
+ */
+ Name&
+ appendSegment(uint64_t segment)
+ {
+ components_.push_back(Component::fromNumberWithMarker(segment, 0x00));
+ return *this;
+ }
+
+ /**
+ * Append a component with the encoded version number.
+ * Note that this encodes the exact value of version without converting from a time representation.
+ * @param version The version number.
+ * @return This name so that you can chain calls to append.
+ */
+ Name&
+ appendVersion(uint64_t version)
+ {
+ components_.push_back(Component::fromNumberWithMarker(version, 0xFD));
+ return *this;
+ }
+
+ /**
+ * @brief Append a component with the encoded version number.
+ *
+ * This version of the method creates version number based on the current timestamp
+ * @return This name so that you can chain calls to append.
+ */
+ Name&
+ appendVersion();
+
+ /**
+ * Check if this name has the same component count and components as the given name.
+ * @param name The Name to check.
+ * @return true if the names are equal, otherwise false.
+ */
+ bool
+ equals(const Name& name) const;
+
+ /**
+ * Check if the N components of this name are the same as the first N components of the given name.
+ * @param name The Name to check.
+ * @return true if this matches the given name, otherwise false. This always returns true if this name is empty.
+ */
+ bool
+ isPrefixOf(const Name& name) const;
+
+ bool
+ match(const Name& name) const
+ {
+ return isPrefixOf(name);
+ }
+
+ /**
+ * Make a Blob value by decoding the escapedString between beginOffset and endOffset according to the NDN URI Scheme.
+ * If the escaped string is "", "." or ".." then return a Blob with a null pointer,
+ * which means the component should be skipped in a URI name.
+ * @param escapedString The escaped string. It does not need to be null-terminated because we only scan to endOffset.
+ * @param beginOffset The offset in escapedString of the beginning of the portion to decode.
+ * @param endOffset The offset in escapedString of the end of the portion to decode.
+ * @return The Blob value. If the escapedString is not a valid escaped component, then the Blob is a null pointer.
+ */
+ static Component
+ fromEscapedString(const char *escapedString, size_t beginOffset, size_t endOffset);
+
+ /**
+ * Make a Blob value by decoding the escapedString according to the NDN URI Scheme.
+ * If the escaped string is "", "." or ".." then return a Blob with a null pointer,
+ * which means the component should be skipped in a URI name.
+ * @param escapedString The null-terminated escaped string.
+ * @return The Blob value. If the escapedString is not a valid escaped component, then the Blob is a null pointer.
+ */
+ static Component
+ fromEscapedString(const char *escapedString);
+
+ /**
+ * Make a Blob value by decoding the escapedString according to the NDN URI Scheme.
+ * If the escaped string is "", "." or ".." then return a Blob with a null pointer,
+ * which means the component should be skipped in a URI name.
+ * @param escapedString The escaped string.
+ * @return The Blob value. If the escapedString is not a valid escaped component, then the Blob is a null pointer.
+ */
+ static Component
+ fromEscapedString(const std::string& escapedString) { return fromEscapedString(escapedString.c_str()); }
+
+ /**
+ * Write the value to result, escaping characters according to the NDN URI Scheme.
+ * This also adds "..." to a value with zero or more ".".
+ * @param value the buffer with the value to escape
+ * @param result the string stream to write to.
+ */
+ static void
+ toEscapedString(const uint8_t *value, size_t valueSize, std::ostream& result);
+
+ inline static void
+ toEscapedString(const std::vector<uint8_t>& value, std::ostream& result)
+ {
+ toEscapedString(&*value.begin(), value.size(), result);
+ }
+
+ /**
+ * Convert the value by escaping characters according to the NDN URI Scheme.
+ * This also adds "..." to a value with zero or more ".".
+ * @param value the buffer with the value to escape
+ * @return The escaped string.
+ */
+ inline static std::string
+ toEscapedString(const uint8_t *value, size_t valueSize)
+ {
+ std::ostringstream result;
+ toEscapedString(value, valueSize, result);
+ return result.str();
+ }
+
+ static inline std::string
+ toEscapedString(const std::vector<uint8_t>& value)
+ {
+ return toEscapedString(&*value.begin(), value.size());
+ }
+
+ //
+ // vector equivalent interface.
+ //
+
+ /**
+ * @brief Check if name is emtpy
+ */
+ bool
+ empty() const { return components_.empty(); }
+
+ /**
+ * Get the number of components.
+ * @return The number of components.
+ */
+ size_t
+ size() const { return components_.size(); }
+
+ /**
+ * Get the component at the given index.
+ * @param i The index of the component, starting from 0.
+ * @return The name component at the index.
+ */
+ const Component&
+ get(ssize_t i) const
+ {
+ if (i >= 0)
+ return components_[i];
+ else
+ return components_[size() + i];
+ }
+
+
+ const Component&
+ operator [] (int i) const
+ {
+ return get(i);
+ }
+
+ /**
+ * Append the component
+ * @param component The component of type T.
+ */
+ template<class T> void
+ push_back(const T &component)
+ {
+ append(component);
+ }
+
+ /**
+ * Check if this name has the same component count and components as the given name.
+ * @param name The Name to check.
+ * @return true if the names are equal, otherwise false.
+ */
+ bool
+ operator == (const Name &name) const { return equals(name); }
+
+ /**
+ * Check if this name has the same component count and components as the given name.
+ * @param name The Name to check.
+ * @return true if the names are not equal, otherwise false.
+ */
+ bool
+ operator != (const Name &name) const { return !equals(name); }
+
+ /**
+ * Compare two names for "less than" using breadth first. If the first components of each name are not equal,
+ * this returns true if the first comes before the second using the NDN canonical ordering for name components.
+ * If they are equal, this compares the second components of each name, etc. If both names are the same up to
+ * the size of the shorter name, this returns true if the first name is shorter than the second. For example, if you
+ * use breadthFirstLess in std::sort, it gives: /a/b/d /a/b/cc /c /c/a /bb . This is intuitive because all names
+ * with the prefix /a are next to each other. But it may be also be counter-intuitive because /c comes before /bb
+ * according to NDN canonical ordering since it is shorter. Note: We don't define this directly as the Name
+ * less than operation because there are other valid ways to sort names.
+ * @param name1 The first name to compare.
+ * @param name2 The second name to compare.
+ * @return True if the first name is less than the second using breadth first comparison.
+ */
+ static bool
+ breadthFirstLess(const Name& name1, const Name& name2);
+
+ /**
+ * Name::BreadthFirstLess is a function object which calls breadthFirstLess, for use as the "less" operator in map, etc.
+ * For example, you can use Name as the key type in a map as follows: map<Name, int, Name::BreadthFirstLess>.
+ */
+ struct BreadthFirstLess {
+ bool operator() (const Name& name1, const Name& name2) const { return breadthFirstLess(name1, name2); }
+ };
+
+ //
+ // Iterator interface to name components.
+ //
+ typedef std::vector<Component>::iterator iterator;
+ typedef std::vector<Component>::const_iterator const_iterator;
+ typedef std::vector<Component>::reverse_iterator reverse_iterator;
+ typedef std::vector<Component>::const_reverse_iterator const_reverse_iterator;
+ typedef std::vector<Component>::reference reference;
+ typedef std::vector<Component>::const_reference const_reference;
+
+ typedef std::vector<Component>::difference_type difference_type;
+ typedef std::vector<Component>::size_type size_type;
+
+ typedef std::vector<Component>::value_type value_type;
+
+ /**
+ * Begin iterator (const).
+ */
+ const_iterator
+ begin() const { return components_.begin(); }
+
+ /**
+ * Begin iterator.
+ */
+ iterator
+ begin() { return components_.begin(); }
+
+ /**
+ * End iterator (const).
+ */
+ const_iterator
+ end() const { return components_.end(); }
+
+ /**
+ * End iterator.
+ */
+ iterator
+ end() { return components_.end(); }
+
+ /**
+ * Reverse begin iterator (const).
+ */
+ const_reverse_iterator
+ rbegin() const { return components_.rbegin(); }
+
+ /**
+ * Reverse begin iterator.
+ */
+ reverse_iterator
+ rbegin() { return components_.rbegin(); }
+
+ /**
+ * Reverse end iterator (const).
+ */
+ const_reverse_iterator
+ rend() const { return components_.rend(); }
+
+ /**
+ * Reverse end iterator.
+ */
+ reverse_iterator
+ rend() { return components_.rend(); }
+
+private:
+ std::vector<Component> components_;
+
+ mutable Block wire_;
+};
+
+std::ostream &
+operator << (std::ostream &os, const Name &name);
+
+inline std::ostream &
+operator << (std::ostream &os, const Name::Component &component)
+{
+ component.toEscapedString(os);
+ return os;
+}
+
+inline std::string
+Name::toUri() const
+{
+ std::ostringstream os;
+ os << *this;
+ return os.str();
+}
+
+}
+
+#endif
+
diff --git a/include/ndn-cpp-dev/node.hpp b/include/ndn-cpp-dev/node.hpp
new file mode 100644
index 0000000..b5e4e97
--- /dev/null
+++ b/include/ndn-cpp-dev/node.hpp
@@ -0,0 +1,340 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_NODE_HPP
+#define NDN_NODE_HPP
+
+#include "common.hpp"
+#include "interest.hpp"
+#include "data.hpp"
+#include "forwarding-flags.hpp"
+#include "transport/transport.hpp"
+
+
+namespace ndn {
+
+/**
+ * An OnData function object is used to pass a callback to expressInterest.
+ */
+typedef func_lib::function<void(const ptr_lib::shared_ptr<const Interest>&, const ptr_lib::shared_ptr<Data>&)> OnData;
+
+/**
+ * An OnTimeout function object is used to pass a callback to expressInterest.
+ */
+typedef func_lib::function<void(const ptr_lib::shared_ptr<const Interest>&)> OnTimeout;
+
+/**
+ * An OnInterest function object is used to pass a callback to registerPrefix.
+ */
+typedef func_lib::function<void
+ (const ptr_lib::shared_ptr<const Name>&, const ptr_lib::shared_ptr<const Interest>&, Transport&, uint64_t)> OnInterest;
+
+/**
+ * An OnRegisterFailed function object is used to report when registerPrefix fails.
+ */
+typedef func_lib::function<void(const ptr_lib::shared_ptr<const Name>&)> OnRegisterFailed;
+
+class Face;
+
+class Node {
+public:
+ struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+ /**
+ * Create a new Node for communication with an NDN hub with the given Transport object and connectionInfo.
+ * @param transport A shared_ptr to a Transport object used for communication.
+ * @param transport A shared_ptr to a Transport::ConnectionInfo to be used to connect to the transport.
+ */
+ Node(const ptr_lib::shared_ptr<Transport>& transport);
+
+ /**
+ * @brief Alternative (special use case) version of the constructor, can be used to aggregate
+ * several Faces within one processing thread
+ *
+ * <code>
+ * Face face1(...);
+ * Face face2(..., face1.getAsyncService());
+ *
+ * // Now the following ensures that events on both faces are processed
+ * face1.processEvents();
+ * </code>
+ */
+ Node(const ptr_lib::shared_ptr<Transport>& transport, const ptr_lib::shared_ptr<boost::asio::io_service> &ioService);
+
+ /**
+ * Send the Interest through the transport, read the entire response and call onData(interest, data).
+ * @param interest A reference to the Interest. This copies the Interest.
+ * @param onData A function object to call when a matching data packet is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ * @param onTimeout A function object to call if the interest times out. If onTimeout is an empty OnTimeout(), this does not use it.
+ * This copies the function object, so you may need to use func_lib::ref() as appropriate.
+ * @param wireFormat A WireFormat object used to encode the message.
+ * @return The pending interest ID which can be used with removePendingInterest.
+ */
+ uint64_t
+ expressInterest(const Interest& interest, const OnData& onData, const OnTimeout& onTimeout);
+
+ /**
+ * Remove the pending interest entry with the pendingInterestId from the pending interest table.
+ * This does not affect another pending interest with a different pendingInterestId, even it if has the same interest name.
+ * If there is no entry with the pendingInterestId, do nothing.
+ * @param pendingInterestId The ID returned from expressInterest.
+ */
+ void
+ removePendingInterest(uint64_t pendingInterestId);
+
+ /**
+ * Register prefix with the connected NDN hub and call onInterest when a matching interest is received.
+ * @param prefix A reference to a Name for the prefix to register. This copies the Name.
+ * @param onInterest A function object to call when a matching interest is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ * @param onRegisterFailed A function object to call if failed to retrieve the connected hub’s ID or failed to register the prefix.
+ * This calls onRegisterFailed(prefix) where prefix is the prefix given to registerPrefix.
+ * @param flags The flags for finer control of which interests are forward to the application.
+ * @param wireFormat A WireFormat object used to encode the message.
+ * @return The registered prefix ID which can be used with removeRegisteredPrefix.
+ */
+ uint64_t
+ registerPrefix
+ (const Name& prefix, const OnInterest& onInterest, const OnRegisterFailed& onRegisterFailed, const ForwardingFlags& flags);
+
+ /**
+ * Remove the registered prefix entry with the registeredPrefixId from the pending interest table.
+ * This does not affect another registered prefix with a different registeredPrefixId, even it if has the same prefix name.
+ * If there is no entry with the registeredPrefixId, do nothing.
+ * @param registeredPrefixId The ID returned from registerPrefix.
+ */
+ void
+ removeRegisteredPrefix(uint64_t registeredPrefixId);
+
+ /**
+ * @brief Publish data packet
+ *
+ * This method can be called to satisfy the incoming Interest or to put Data packet into the cache
+ * of the local NDN forwarder
+ */
+ void
+ put(const Data &data);
+
+ /**
+ * Process any data to receive or call timeout callbacks.
+ *
+ * This call will block forever (default timeout == 0) to process IO on the face.
+ * To exit, one expected to call face.shutdown() from one of the callback methods.
+ *
+ * If positive timeout is specified, then processEvents will exit after this timeout,
+ * if not stopped earlier with face.shutdown() or when all active events finish.
+ * The call can be called repeatedly, if desired.
+ *
+ * If negative timeout is specified, then processEvents will not block and process only pending
+ * events.
+ *
+ * @throw This may throw an exception for reading data or in the callback for processing the data. If you
+ * call this from an main event loop, you may want to catch and log/disregard all exceptions.
+ */
+ void
+ processEvents(Milliseconds timeout = 0, bool keepThread = false);
+
+ const ptr_lib::shared_ptr<Transport>&
+ getTransport() { return transport_; }
+
+ void
+ shutdown();
+
+private:
+ void
+ onReceiveElement(const Block &wire);
+
+ struct ProcessEventsTimeout {};
+ static void
+ fireProcessEventsTimeout(const boost::system::error_code& error);
+
+private:
+ class PendingInterest {
+ public:
+ /**
+ * Create a new PitEntry and set the timeoutTime_ based on the current time and the interest lifetime.
+ * @param pendingInterestId A unique ID for this entry, which you should get with getNextPendingInteresId().
+ * @param interest A shared_ptr for the interest.
+ * @param onData A function object to call when a matching data packet is received.
+ * @param onTimeout A function object to call if the interest times out. If onTimeout is an empty OnTimeout(), this does not use it.
+ */
+ PendingInterest
+ (uint64_t pendingInterestId, const ptr_lib::shared_ptr<const Interest>& interest, const OnData& onData,
+ const OnTimeout& onTimeout);
+
+ /**
+ * Return the next unique pending interest ID.
+ */
+ static uint64_t
+ getNextPendingInterestId()
+ {
+ return ++lastPendingInterestId_;
+ }
+
+ /**
+ * Return the pendingInterestId given to the constructor.
+ */
+ uint64_t
+ getPendingInterestId() { return pendingInterestId_; }
+
+ const ptr_lib::shared_ptr<const Interest>&
+ getInterest() { return interest_; }
+
+ const OnData&
+ getOnData() { return onData_; }
+
+ /**
+ * Check if this interest is timed out.
+ * @param nowMilliseconds The current time in milliseconds from ndn_getNowMilliseconds.
+ * @return true if this interest timed out, otherwise false.
+ */
+ bool
+ isTimedOut(MillisecondsSince1970 nowMilliseconds)
+ {
+ return timeoutTimeMilliseconds_ >= 0.0 && nowMilliseconds >= timeoutTimeMilliseconds_;
+ }
+
+ /**
+ * Call onTimeout_ (if defined). This ignores exceptions from the onTimeout_.
+ */
+ void
+ callTimeout();
+
+ private:
+ static uint64_t lastPendingInterestId_; /**< A class variable used to get the next unique ID. */
+
+ uint64_t pendingInterestId_; /**< A unique identifier for this entry so it can be deleted */
+ ptr_lib::shared_ptr<const Interest> interest_;
+ const OnData onData_;
+ const OnTimeout onTimeout_;
+
+ MillisecondsSince1970 timeoutTimeMilliseconds_; /**< The time when the interest times out in milliseconds according to ndn_getNowMilliseconds, or -1 for no timeout. */
+ };
+
+ class RegisteredPrefix {
+ public:
+ /**
+ * Create a new PrefixEntry.
+ * @param registeredPrefixId A unique ID for this entry, which you should get with getNextRegisteredPrefixId().
+ * @param prefix A shared_ptr for the prefix.
+ * @param onInterest A function object to call when a matching data packet is received.
+ */
+ RegisteredPrefix(uint64_t registeredPrefixId, const ptr_lib::shared_ptr<const Name>& prefix, const OnInterest& onInterest)
+ : registeredPrefixId_(registeredPrefixId)
+ , prefix_(prefix)
+ , onInterest_(onInterest)
+ {
+ }
+
+ /**
+ * Return the next unique entry ID.
+ */
+ static uint64_t
+ getNextRegisteredPrefixId()
+ {
+ return ++lastRegisteredPrefixId_;
+ }
+
+ /**
+ * Return the registeredPrefixId given to the constructor.
+ */
+ uint64_t
+ getRegisteredPrefixId()
+ {
+ return registeredPrefixId_;
+ }
+
+ const ptr_lib::shared_ptr<const Name>&
+ getPrefix()
+ {
+ return prefix_;
+ }
+
+ const OnInterest&
+ getOnInterest()
+ {
+ return onInterest_;
+ }
+
+ private:
+ static uint64_t lastRegisteredPrefixId_; /**< A class variable used to get the next unique ID. */
+
+ uint64_t registeredPrefixId_; /**< A unique identifier for this entry so it can be deleted */
+ ptr_lib::shared_ptr<const Name> prefix_;
+ const OnInterest onInterest_;
+ };
+
+ typedef std::vector<ptr_lib::shared_ptr<PendingInterest> > PendingInterestTable;
+ typedef std::vector<ptr_lib::shared_ptr<RegisteredPrefix> > RegisteredPrefixTable;
+
+ /**
+ * Find the entry from the pit_ where the name conforms to the entry's interest selectors, and
+ * the entry interest name is the longest that matches name.
+ * @param name The name to find the interest for (from the incoming data packet).
+ * @return The index in pit_ of the pit entry, or -1 if not found.
+ */
+ PendingInterestTable::iterator
+ getEntryIndexForExpressedInterest(const Name& name);
+
+ /**
+ * Find the first entry from the registeredPrefixTable_ where the entry prefix is the longest that matches name.
+ * @param name The name to find the PrefixEntry for (from the incoming interest packet).
+ * @return A pointer to the entry, or 0 if not found.
+ */
+ RegisteredPrefixTable::iterator
+ getEntryForRegisteredPrefix(const Name& name);
+
+ /**
+ * Do the work of registerPrefix once we know we are connected with an ndndId_.
+ * @param registeredPrefixId The PrefixEntry::getNextRegisteredPrefixId() which registerPrefix got so it could return it to the caller.
+ * @param prefix
+ * @param onInterest
+ * @param onRegisterFailed
+ * @param flags
+ * @param wireFormat
+ */
+ void
+ registerPrefixHelper
+ (uint64_t registeredPrefixId, const ptr_lib::shared_ptr<const Name>& prefix, const OnInterest& onInterest,
+ const OnRegisterFailed& onRegisterFailed, const ForwardingFlags& flags);
+
+ /**
+ * @brief Final stage of prefix registration, invoked when registration succeeded
+ *
+ * This method actually sets entry in a local interest filter table
+ */
+ void
+ registerPrefixFinal(uint64_t registeredPrefixId,
+ const ptr_lib::shared_ptr<const Name>& prefix,
+ const OnInterest& onInterest,
+ const OnRegisterFailed& onRegisterFailed,
+ const ptr_lib::shared_ptr<const Interest>&, const ptr_lib::shared_ptr<Data>&);
+
+ void
+ checkPitExpire();
+
+private:
+ ptr_lib::shared_ptr<boost::asio::io_service> ioService_;
+ ptr_lib::shared_ptr<boost::asio::io_service::work> ioServiceWork_; // needed if thread needs to be preserved
+ ptr_lib::shared_ptr<boost::asio::deadline_timer> pitTimeoutCheckTimer_;
+ bool pitTimeoutCheckTimerActive_;
+ ptr_lib::shared_ptr<boost::asio::deadline_timer> processEventsTimeoutTimer_;
+
+ ptr_lib::shared_ptr<Transport> transport_;
+
+ PendingInterestTable pendingInterestTable_;
+ RegisteredPrefixTable registeredPrefixTable_;
+ Interest ndndIdFetcherInterest_;
+
+ int64_t faceId_; // internal face ID (needed for prefix de-registration)
+ Buffer ndndId_;
+};
+
+} // namespace ndn
+
+#endif
diff --git a/include/ndn-cpp-dev/security/certificate-extension.hpp b/include/ndn-cpp-dev/security/certificate-extension.hpp
new file mode 100644
index 0000000..61f7dd2
--- /dev/null
+++ b/include/ndn-cpp-dev/security/certificate-extension.hpp
@@ -0,0 +1,78 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_CERTIFICATE_EXTENSION_HPP
+#define NDN_CERTIFICATE_EXTENSION_HPP
+
+#include "../common.hpp"
+#include "../encoding/buffer.hpp"
+#include "../encoding/oid.hpp"
+
+namespace CryptoPP { class BufferedTransformation; }
+
+namespace ndn {
+
+/**
+ * A CertificateExtension represents the Extension entry in a certificate.
+ */
+class CertificateExtension
+{
+public:
+ struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+ CertificateExtension(CryptoPP::BufferedTransformation &in)
+ {
+ decode(in);
+ }
+
+ /**
+ * Create a new CertificateExtension.
+ * @param oid The oid of subject description entry.
+ * @param isCritical If true, the extension must be handled.
+ * @param value The extension value.
+ */
+ CertificateExtension(const OID& oid, const bool isCritical, const Buffer& value)
+ : extensionId_(oid), isCritical_(isCritical), extensionValue_(value)
+ {
+ }
+
+ CertificateExtension(const OID& oid, const bool isCritical, const uint8_t* value, size_t valueSize)
+ : extensionId_(oid), isCritical_(isCritical), extensionValue_(value, valueSize)
+ {
+ }
+
+ /**
+ * The virtual destructor.
+ */
+ virtual
+ ~CertificateExtension() {}
+
+ void
+ encode(CryptoPP::BufferedTransformation &out) const;
+
+ void
+ decode(CryptoPP::BufferedTransformation &in);
+
+ inline const OID&
+ getOid() const { return extensionId_; }
+
+ inline const bool
+ getIsCritical() const { return isCritical_; }
+
+ inline const Buffer&
+ getValue() const { return extensionValue_; }
+
+protected:
+ OID extensionId_;
+ bool isCritical_;
+ Buffer extensionValue_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/certificate-subject-description.hpp b/include/ndn-cpp-dev/security/certificate-subject-description.hpp
new file mode 100644
index 0000000..fc26d37
--- /dev/null
+++ b/include/ndn-cpp-dev/security/certificate-subject-description.hpp
@@ -0,0 +1,64 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_CERTIFICATE_SUBJECT_DESCRIPTION_HPP
+#define NDN_CERTIFICATE_SUBJECT_DESCRIPTION_HPP
+
+#include "../common.hpp"
+#include "../encoding/oid.hpp"
+
+namespace CryptoPP { class BufferedTransformation; }
+
+namespace ndn {
+
+/**
+ * A CertificateSubjectDescription represents the SubjectDescription entry in a Certificate.
+ */
+class CertificateSubjectDescription {
+public:
+ CertificateSubjectDescription(CryptoPP::BufferedTransformation &in)
+ {
+ decode(in);
+ }
+
+ /**
+ * Create a new CertificateSubjectDescription.
+ * @param oid The oid of the subject description entry.
+ * @param value The value of the subject description entry.
+ */
+ CertificateSubjectDescription(const OID &oid, const std::string &value)
+ : oid_(oid), value_(value)
+ {
+ }
+
+ void
+ encode(CryptoPP::BufferedTransformation &out) const;
+
+ void
+ decode(CryptoPP::BufferedTransformation &in);
+
+ std::string
+ getOidString() const
+ {
+ return oid_.toString();
+ }
+
+ const std::string &
+ getValue() const
+ {
+ return value_;
+ }
+
+private:
+ OID oid_;
+ std::string value_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/certificate.hpp b/include/ndn-cpp-dev/security/certificate.hpp
new file mode 100644
index 0000000..9871733
--- /dev/null
+++ b/include/ndn-cpp-dev/security/certificate.hpp
@@ -0,0 +1,156 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_CERTIFICATE_HPP
+#define NDN_CERTIFICATE_HPP
+
+#include "../data.hpp"
+#include "../common.hpp"
+
+#include "certificate-subject-description.hpp"
+#include "certificate-extension.hpp"
+#include "public-key.hpp"
+
+namespace ndn {
+
+class Certificate : public Data {
+public:
+ struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+ typedef std::vector<CertificateSubjectDescription> SubjectDescriptionList;
+ typedef std::vector<CertificateExtension> ExtensionList;
+
+ /**
+ * The default constructor.
+ */
+ Certificate();
+
+ /**
+ * Create a Certificate from the content in the data packet.
+ * @param data The data packet with the content to decode.
+ */
+ Certificate(const Data& data);
+
+ /**
+ * The virtual destructor.
+ */
+ virtual
+ ~Certificate();
+
+ inline void
+ wireDecode(const Block &wire);
+
+ /**
+ * encode certificate info into content
+ */
+ void
+ encode();
+
+ /**
+ * Add a subject description.
+ * @param description The description to be added.
+ */
+ void
+ addSubjectDescription(const CertificateSubjectDescription& description) { subjectDescriptionList_.push_back(description); }
+
+ const SubjectDescriptionList&
+ getSubjectDescriptionList() const { return subjectDescriptionList_; }
+
+ SubjectDescriptionList&
+ getSubjectDescriptionList() { return subjectDescriptionList_; }
+
+ /**
+ * Add a certificate extension.
+ * @param extension the extension to be added
+ */
+ void
+ addExtension(const CertificateExtension& extension) { extensionList_.push_back(extension); }
+
+ const ExtensionList&
+ getExtensionList() const { return extensionList_; }
+
+ ExtensionList&
+ getExtensionList() { return extensionList_; }
+
+ void
+ setNotBefore(const MillisecondsSince1970& notBefore) { notBefore_ = notBefore; }
+
+ MillisecondsSince1970&
+ getNotBefore() { return notBefore_; }
+
+ const MillisecondsSince1970&
+ getNotBefore() const { return notBefore_; }
+
+ void
+ setNotAfter(const MillisecondsSince1970& notAfter) { notAfter_ = notAfter; }
+
+ MillisecondsSince1970&
+ getNotAfter() { return notAfter_; }
+
+ const MillisecondsSince1970&
+ getNotAfter() const { return notAfter_; }
+
+ void
+ setPublicKeyInfo(const PublicKey& key) { key_ = key; }
+
+ PublicKey&
+ getPublicKeyInfo() { return key_; }
+
+ const PublicKey&
+ getPublicKeyInfo() const { return key_; }
+
+ // virtual Name
+ // getPublicKeyName() const = 0;
+
+ /**
+ * Check if the certificate is valid.
+ * @return True if the current time is earlier than notBefore.
+ */
+ bool
+ isTooEarly();
+
+ /**
+ * Check if the certificate is valid.
+ * @return True if the current time is later than notAfter.
+ */
+ bool
+ isTooLate();
+
+ void
+ printCertificate(std::ostream &os) const;
+
+protected:
+ void
+ decode();
+
+protected:
+ SubjectDescriptionList subjectDescriptionList_;
+ MillisecondsSince1970 notBefore_;
+ MillisecondsSince1970 notAfter_;
+ PublicKey key_;
+ ExtensionList extensionList_;
+};
+
+inline void
+Certificate::wireDecode(const Block &wire)
+{
+ Data::wireDecode(wire);
+ decode();
+}
+
+
+inline std::ostream&
+operator <<(std::ostream &os, const Certificate &cert)
+{
+ cert.printCertificate(os);
+ return os;
+}
+
+} // namespace ndn
+
+#endif
diff --git a/include/ndn-cpp-dev/security/encryption-manager.hpp b/include/ndn-cpp-dev/security/encryption-manager.hpp
new file mode 100644
index 0000000..44eafb7
--- /dev/null
+++ b/include/ndn-cpp-dev/security/encryption-manager.hpp
@@ -0,0 +1,34 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_ENCRYPTION_MANAGER_HPP
+#define NDN_ENCRYPTION_MANAGER_HPP
+
+#include "../../name.hpp"
+#include "../security-common.hpp"
+
+namespace ndn {
+
+class EncryptionManager {
+public:
+ virtual ~EncryptionManager() {}
+
+ virtual void
+ createSymmetricKey(const Name& keyName, KeyType keyType, const Name& signkeyName = Name(), bool isSymmetric = true) = 0;
+
+ virtual ConstBufferPtr
+ encrypt(const Name& keyName, const uint8_t* data, size_t dataLength, bool useSymmetric = false,
+ EncryptMode encryptMode = ENCRYPT_MODE_DEFAULT) = 0;
+
+ virtual ConstBufferPtr
+ decrypt(const Name& keyName, const uint8_t* data, size_t dataLength, bool useSymmetric = false,
+ EncryptMode encryptMode = ENCRYPT_MODE_DEFAULT) = 0;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/identity-certificate.hpp b/include/ndn-cpp-dev/security/identity-certificate.hpp
new file mode 100644
index 0000000..65b07af
--- /dev/null
+++ b/include/ndn-cpp-dev/security/identity-certificate.hpp
@@ -0,0 +1,112 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_IDENTITY_CERTIFICATE_HPP
+#define NDN_IDENTITY_CERTIFICATE_HPP
+
+#include "certificate.hpp"
+
+namespace ndn {
+
+class IdentityCertificate : public Certificate
+{
+public:
+ struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+ /**
+ * The default constructor.
+ */
+ inline
+ IdentityCertificate();
+
+ // Note: The copy constructor works because publicKeyName_ has a copy constructor.
+
+ /**
+ * Create an IdentityCertificate from the content in the data packet.
+ * @param data The data packet with the content to decode.
+ */
+ inline
+ IdentityCertificate(const Data& data);
+
+ /**
+ * The virtual destructor.
+ */
+ inline virtual
+ ~IdentityCertificate();
+
+ inline void
+ wireDecode(const Block &wire);
+
+ inline void
+ setName(const Name &name);
+
+ inline const Name &
+ getPublicKeyName () const;
+
+ static bool
+ isIdentityCertificate(const Certificate& certificate);
+
+ /**
+ * Get the public key name from the full certificate name.
+ * @param certificateName The full certificate name.
+ * @return The related public key name.
+ */
+ static Name
+ certificateNameToPublicKeyName(const Name& certificateName);
+
+private:
+ static bool
+ isCorrectName(const Name& name);
+
+ void
+ setPublicKeyName();
+
+protected:
+ Name publicKeyName_;
+};
+
+inline
+IdentityCertificate::IdentityCertificate()
+{
+}
+
+inline
+IdentityCertificate::IdentityCertificate(const Data& data)
+ : Certificate(data)
+{
+ setPublicKeyName();
+}
+
+inline
+IdentityCertificate::~IdentityCertificate()
+{
+}
+
+inline void
+IdentityCertificate::wireDecode(const Block &wire)
+{
+ Certificate::wireDecode(wire);
+ setPublicKeyName();
+}
+
+inline void
+IdentityCertificate::setName(const Name &name)
+{
+ Certificate::setName(name);
+ setPublicKeyName();
+}
+
+inline const Name &
+IdentityCertificate::getPublicKeyName () const
+{
+ return publicKeyName_;
+}
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/key-chain.hpp b/include/ndn-cpp-dev/security/key-chain.hpp
new file mode 100644
index 0000000..fffa05d
--- /dev/null
+++ b/include/ndn-cpp-dev/security/key-chain.hpp
@@ -0,0 +1,366 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_KEY_CHAIN_HPP
+#define NDN_KEY_CHAIN_HPP
+
+#include "identity-certificate.hpp"
+#include "public-key.hpp"
+#include "signature-sha256-with-rsa.hpp"
+
+#include "sec-public-info-sqlite3.hpp"
+#include "sec-public-info-memory.hpp"
+#include "sec-tpm-osx.hpp"
+#include "sec-tpm-memory.hpp"
+
+
+namespace ndn {
+
+/**
+ * KeyChain is one of the main classes of the security library.
+ *
+ * The KeyChain class provides a set of interfaces of identity management and private key related operations.
+ */
+template<class Info, class Tpm>
+class KeyChainImpl : public Info, public Tpm
+{
+public:
+ // struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+ /**
+ * Create an identity by creating a pair of Key-Signing-Key (KSK) for this identity and a self-signed certificate of the KSK.
+ * @param identityName The name of the identity.
+ * @return The key name of the auto-generated KSK of the identity.
+ */
+ Name
+ createIdentity(const Name& identityName)
+ {
+ if (!Info::doesIdentityExist(identityName)) {
+ Info::addIdentity(identityName);
+
+ Name keyName = generateRSAKeyPairAsDefault(identityName, true);
+
+ ptr_lib::shared_ptr<IdentityCertificate> selfCert = selfSign(keyName);
+
+ Info::addCertificateAsDefault(*selfCert);
+
+ return keyName;
+ }
+ else
+ return Name();
+ }
+
+ /**
+ * Generate a pair of RSA keys for the specified identity.
+ * @param identityName The name of the identity.
+ * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
+ * @param keySize The size of the key.
+ * @return The generated key name.
+ */
+ Name
+ generateRSAKeyPair(const Name& identityName, bool isKsk = false, int keySize = 2048)
+ {
+ return generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
+ }
+
+ /**
+ * Generate a pair of RSA keys for the specified identity and set it as default key for the identity.
+ * @param identityName The name of the identity.
+ * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
+ * @param keySize The size of the key.
+ * @return The generated key name.
+ */
+ Name
+ generateRSAKeyPairAsDefault(const Name& identityName, bool isKsk = false, int keySize = 2048)
+ {
+ Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
+
+ Info::setDefaultKeyNameForIdentity(keyName);
+
+ return keyName;
+ }
+
+ /**
+ * Create an identity certificate for a public key managed by this IdentityManager.
+ * @param certificatePrefix The name of public key to be signed.
+ * @param signerCertificateName The name of signing certificate.
+ * @param notBefore The notBefore value in the validity field of the generated certificate.
+ * @param notAfter The notAfter vallue in validity field of the generated certificate.
+ * @return The name of generated identity certificate.
+ */
+ ptr_lib::shared_ptr<IdentityCertificate>
+ createIdentityCertificate
+ (const Name& certificatePrefix,
+ const Name& signerCertificateName,
+ const MillisecondsSince1970& notBefore,
+ const MillisecondsSince1970& notAfter)
+ {
+ Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);
+
+ ptr_lib::shared_ptr<PublicKey> pubKey = Info::getPublicKey(keyName);
+ if (!pubKey)
+ throw std::runtime_error("Requested public key [" + keyName.toUri() + "] doesn't exist");
+
+ ptr_lib::shared_ptr<IdentityCertificate> certificate =
+ createIdentityCertificate(certificatePrefix,
+ *pubKey,
+ signerCertificateName,
+ notBefore, notAfter);
+
+ Info::addCertificate(*certificate);
+
+ return certificate;
+ }
+
+
+ /**
+ * Create an identity certificate for a public key supplied by the caller.
+ * @param certificatePrefix The name of public key to be signed.
+ * @param publickey The public key to be signed.
+ * @param signerCertificateName The name of signing certificate.
+ * @param notBefore The notBefore value in the validity field of the generated certificate.
+ * @param notAfter The notAfter vallue in validity field of the generated certificate.
+ * @return The generated identity certificate.
+ */
+ ptr_lib::shared_ptr<IdentityCertificate>
+ createIdentityCertificate
+ (const Name& certificatePrefix,
+ const PublicKey& publicKey,
+ const Name& signerCertificateName,
+ const MillisecondsSince1970& notBefore,
+ const MillisecondsSince1970& notAfter)
+ {
+ ptr_lib::shared_ptr<IdentityCertificate> certificate (new IdentityCertificate());
+ Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);
+
+ Name certificateName = certificatePrefix;
+ certificateName.append("ID-CERT").appendVersion();
+
+ certificate->setName(certificateName);
+ certificate->setNotBefore(notBefore);
+ certificate->setNotAfter(notAfter);
+ certificate->setPublicKeyInfo(publicKey);
+ certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
+ certificate->encode();
+
+ sign(*certificate, signerCertificateName);
+
+ return certificate;
+ }
+
+ void
+ sign(Data &data)
+ {
+ if (!Info::defaultCertificate())
+ {
+ Info::refreshDefaultCertificate();
+
+ if(!Info::defaultCertificate())
+ throw std::runtime_error("Default IdentityCertificate cannot be determined");
+ }
+
+ sign(data, *Info::defaultCertificate());
+ }
+
+ /**
+ * Wire encode the Data object, sign it and set its signature.
+ * @param data The Data object to be signed. This updates its signature and key locator field and wireEncoding.
+ * @param certificateName The certificate name of the key to use for signing. If omitted, infer the signing identity from the data packet name.
+ */
+ void
+ sign(Data& data, const Name& certificateName)
+ {
+ ptr_lib::shared_ptr<IdentityCertificate> cert = Info::getCertificate(certificateName);
+ if (!cert)
+ throw std::runtime_error("Requested certificate [" + certificateName.toUri() + "] doesn't exist");
+
+ SignatureSha256WithRsa signature;
+ signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
+ data.setSignature(signature);
+
+ // For temporary usage, we support RSA + SHA256 only, but will support more.
+ Tpm::signInTpm(data, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
+ }
+
+ void
+ sign(Data& data, const IdentityCertificate& certificate)
+ {
+ SignatureSha256WithRsa signature;
+ signature.setKeyLocator(certificate.getName().getPrefix(-1));
+ data.setSignature(signature);
+
+ // For temporary usage, we support RSA + SHA256 only, but will support more.
+ Tpm::signInTpm(data, certificate.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
+ }
+
+ /**
+ * Sign the byte array using a certificate name and return a Signature object.
+ * @param buffer The byte array to be signed.
+ * @param bufferLength the length of buffer.
+ * @param certificateName The certificate name used to get the signing key and which will be put into KeyLocator.
+ * @return The Signature.
+ */
+ Signature
+ sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
+ {
+ ptr_lib::shared_ptr<IdentityCertificate> cert = Info::getCertificate(certificateName);
+ if (!cert)
+ throw std::runtime_error("Requested certificate [" + certificateName.toUri() + "] doesn't exist");
+
+ SignatureSha256WithRsa signature;
+ signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
+
+ // For temporary usage, we support RSA + SHA256 only, but will support more.
+ signature.setValue(Tpm::signInTpm(buffer, bufferLength, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
+ return signature;
+ }
+
+ /**
+ * Wire encode the Data object, sign it and set its signature.
+ * @param data The Data object to be signed. This updates its signature and key locator field and wireEncoding.
+ * @param identityName The identity name for the key to use for signing. If omitted, infer the signing identity from the data packet name.
+ */
+ void
+ signByIdentity(Data& data, const Name& identityName = Name())
+ {
+ Name signingCertificateName = Info::getDefaultCertificateNameForIdentity(identityName);
+
+ if (signingCertificateName.getComponentCount() == 0)
+ throw std::runtime_error("No qualified certificate name found!");
+
+ sign(data, signingCertificateName);
+ }
+
+ /**
+ * Sign the byte array using an identity name and return a Signature object.
+ * @param buffer The byte array to be signed.
+ * @param bufferLength the length of buffer.
+ * @param identityName The identity name.
+ * @return The Signature.
+ */
+ Signature
+ signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName = Name())
+ {
+ Name signingCertificateName = Info::getDefaultCertificateNameForIdentity(identityName);
+
+ if (signingCertificateName.size() == 0)
+ throw std::runtime_error("No qualified certificate name found!");
+
+ return sign(buffer, bufferLength, signingCertificateName);
+ }
+
+ /**
+ * Generate a self-signed certificate for a public key.
+ * @param keyName The name of the public key.
+ * @return The generated certificate.
+ */
+ ptr_lib::shared_ptr<IdentityCertificate>
+ selfSign(const Name& keyName)
+ {
+ if(keyName.empty())
+ throw std::runtime_error("Incorrect key name: " + keyName.toUri());
+
+ ptr_lib::shared_ptr<IdentityCertificate> certificate = ptr_lib::make_shared<IdentityCertificate>();
+
+ Name certificateName = keyName.getPrefix(-1);
+ certificateName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion();
+
+ ptr_lib::shared_ptr<PublicKey> pubKey = Info::getPublicKey(keyName);
+ if (!pubKey)
+ throw std::runtime_error("Requested public key [" + keyName.toUri() + "] doesn't exist");
+
+ certificate->setName(certificateName);
+ certificate->setNotBefore(getNow());
+ certificate->setNotAfter(getNow() + 630720000 /* 20 years*/);
+ certificate->setPublicKeyInfo(*pubKey);
+ certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
+ certificate->encode();
+
+ selfSign(*certificate);
+ return certificate;
+ }
+
+ /**
+ * @brief Self-sign the supplied identity certificate
+ */
+ void
+ selfSign (IdentityCertificate& cert)
+ {
+ SignatureSha256WithRsa signature;
+ signature.setKeyLocator(cert.getName().getPrefix(-1)); // implicit conversion should take care
+ cert.setSignature(signature);
+
+ // For temporary usage, we support RSA + SHA256 only, but will support more.
+ Tpm::signInTpm(cert, cert.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
+ }
+
+
+private:
+ /**
+ * Generate a key pair for the specified identity.
+ * @param identityName The name of the specified identity.
+ * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
+ * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
+ * @param keySize The size of the key pair.
+ * @return The name of the generated key.
+ */
+ Name
+ generateKeyPair(const Name& identityName, bool isKsk = false, KeyType keyType = KEY_TYPE_RSA, int keySize = 2048)
+ {
+ Name keyName = Info::getNewKeyName(identityName, isKsk);
+
+ Tpm::generateKeyPairInTpm(keyName.toUri(), keyType, keySize);
+
+ ptr_lib::shared_ptr<PublicKey> pubKey = Tpm::getPublicKeyFromTpm(keyName.toUri());
+ Info::addPublicKey(keyName, keyType, *pubKey);
+
+ return keyName;
+ }
+
+ static Name
+ getKeyNameFromCertificatePrefix(const Name& certificatePrefix)
+ {
+ Name result;
+
+ std::string keyString("KEY");
+ int i = 0;
+ for(; i < certificatePrefix.size(); i++) {
+ if (certificatePrefix.get(i).toEscapedString() == keyString)
+ break;
+ }
+
+ if (i >= certificatePrefix.size())
+ throw std::runtime_error("Identity Certificate Prefix does not have a KEY component");
+
+ result.append(certificatePrefix.getSubName(0, i));
+ result.append(certificatePrefix.getSubName(i + 1, certificatePrefix.size()-i-1));
+
+ return result;
+ }
+
+};
+
+}
+
+#ifdef NDN_CPP_HAVE_OSX_SECURITY
+
+namespace ndn
+{
+typedef KeyChainImpl<SecPublicInfoSqlite3, SecTpmOsx> KeyChain;
+};
+
+#else
+
+namespace ndn
+{
+typedef KeyChainImpl<SecPublicInfoMemory, SecTpmMemory> KeyChain;
+};
+
+#endif //NDN_CPP_HAVE_OSX_SECURITY
+
+#endif
diff --git a/include/ndn-cpp-dev/security/public-key.hpp b/include/ndn-cpp-dev/security/public-key.hpp
new file mode 100644
index 0000000..5a70e38
--- /dev/null
+++ b/include/ndn-cpp-dev/security/public-key.hpp
@@ -0,0 +1,84 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_PUBLIC_KEY_HPP
+#define NDN_PUBLIC_KEY_HPP
+
+#include <stdexcept>
+#include "../encoding/oid.hpp"
+#include "../encoding/buffer.hpp"
+#include "security-common.hpp"
+
+namespace ndn {
+
+class PublicKey {
+public:
+ struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+ /**
+ * The default constructor.
+ */
+ PublicKey();
+
+ /**
+ * Create a new PublicKey with the given values.
+ * @param algorithm The algorithm of the public key.
+ * @param keyDer The blob of the PublicKeyInfo in terms of DER.
+ *
+ * @throws PublicKey::Error If algorithm is not supported or keyDer cannot be decoded
+ */
+ PublicKey(const uint8_t *keyDerBuf, size_t keyDerSize);
+
+ inline const Buffer&
+ get() const
+ {
+ return key_;
+ }
+
+ inline void
+ set(const uint8_t *keyDerBuf, size_t keyDerSize)
+ {
+ Buffer buf(keyDerBuf, keyDerSize);
+ key_.swap(buf);
+ }
+
+ void
+ encode(CryptoPP::BufferedTransformation &out) const;
+
+ void
+ decode(CryptoPP::BufferedTransformation &in);
+
+ // /*
+ // * Get the digest of the public key.
+ // * @param digestAlgorithm The digest algorithm. If omitted, use DIGEST_ALGORITHM_SHA256 by default.
+ // */
+ // Blob
+ // getDigest(DigestAlgorithm digestAlgorithm = DIGEST_ALGORITHM_SHA256) const;
+
+ inline bool
+ operator ==(const PublicKey &key) const
+ {
+ return key_ == key.key_;
+ }
+
+ inline bool
+ operator !=(const PublicKey &key) const
+ {
+ return key_ != key.key_;
+ }
+
+private:
+ Buffer key_;
+};
+
+std::ostream &
+operator <<(std::ostream &os, const PublicKey &key);
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/sec-policy-no-verify.hpp b/include/ndn-cpp-dev/security/sec-policy-no-verify.hpp
new file mode 100644
index 0000000..1d2927e
--- /dev/null
+++ b/include/ndn-cpp-dev/security/sec-policy-no-verify.hpp
@@ -0,0 +1,72 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SEC_POLICY_NO_VERIFY_HPP
+#define NDN_SEC_POLICY_NO_VERIFY_HPP
+
+#include "sec-policy.hpp"
+
+namespace ndn {
+
+class SecPolicyNoVerify : public SecPolicy {
+public:
+ /**
+ * The virtual destructor.
+ */
+ virtual
+ ~SecPolicyNoVerify();
+
+ /**
+ * Override to always skip verification and trust as valid.
+ * @param data The received data packet.
+ * @return true.
+ */
+ virtual bool
+ skipVerifyAndTrust(const Data& data);
+
+ /**
+ * Override to return false for no verification rule for the received data.
+ * @param data The received data packet.
+ * @return false.
+ */
+ virtual bool
+ requireVerify(const Data& data);
+
+ /**
+ * Override to call onVerified(data) and to indicate no further verification step.
+ * @param data The Data object with the signature to check.
+ * @param stepCount The number of verification steps that have been done, used to track the verification progress.
+ * @param onVerified This does override to call onVerified(data).
+ * @param onVerifyFailed Override to ignore this.
+ * @return null for no further step.
+ */
+ virtual ptr_lib::shared_ptr<ValidationRequest>
+ checkVerificationPolicy
+ (const ptr_lib::shared_ptr<Data>& data, int stepCount, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed);
+
+ /**
+ * Override to always indicate that the signing certificate name and data name satisfy the signing policy.
+ * @param dataName The name of data to be signed.
+ * @param certificateName The name of signing certificate.
+ * @return true to indicate that the signing certificate can be used to sign the data.
+ */
+ virtual bool
+ checkSigningPolicy(const Name& dataName, const Name& certificateName);
+
+ /**
+ * Override to indicate that the signing identity cannot be inferred.
+ * @param dataName The name of data to be signed.
+ * @return An empty name because cannot infer.
+ */
+ virtual Name
+ inferSigningIdentity(const Name& dataName);
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/sec-policy-self-verify.hpp b/include/ndn-cpp-dev/security/sec-policy-self-verify.hpp
new file mode 100644
index 0000000..111b61a
--- /dev/null
+++ b/include/ndn-cpp-dev/security/sec-policy-self-verify.hpp
@@ -0,0 +1,91 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SEC_POLICY_SELF_VERIFY_HPP
+#define NDN_SEC_POLICY_SELF_VERIFY_HPP
+
+#include "sec-policy.hpp"
+
+namespace ndn {
+
+/**
+ * A SecPolicySelfVerify implements a PolicyManager to use the public key DER in the data packet's KeyLocator (if available)
+ * or look in the IdentityStorage for the public key with the name in the KeyLocator (if available) and use
+ * it to verify the data packet, without searching a certificate chain. If the public key can't be found, the
+ * verification fails.
+ */
+class SecPolicySelfVerify : public SecPolicy {
+public:
+ /**
+ * Create a new SecPolicySelfVerify which will look up the public key in the given identityManager.
+ * @param identityManager (optional) The IdentityManager for looking up the public key. This points to an object must which remain
+ * valid during the life of this SecPolicySelfVerify. If omitted, then don't look for a public key with the name
+ * in the KeyLocator and rely on the KeyLocator having the full public key DER.
+ */
+ SecPolicySelfVerify()
+ {
+ }
+
+ /**
+ * The virtual destructor.
+ */
+ virtual
+ ~SecPolicySelfVerify();
+
+ /**
+ * Never skip verification.
+ * @param data The received data packet.
+ * @return false.
+ */
+ virtual bool
+ skipVerifyAndTrust(const Data& data);
+
+ /**
+ * Always return true to use the self-verification rule for the received data.
+ * @param data The received data packet.
+ * @return true.
+ */
+ virtual bool
+ requireVerify(const Data& data);
+
+ /**
+ * Use the public key DER in the data packet's KeyLocator (if available) or look in the IdentityStorage for the
+ * public key with the name in the KeyLocator (if available) and use it to verify the data packet. If the public key can't
+ * be found, call onVerifyFailed.
+ * @param data The Data object with the signature to check.
+ * @param stepCount The number of verification steps that have been done, used to track the verification progress.
+ * (stepCount is ignored.)
+ * @param onVerified If the signature is verified, this calls onVerified(data).
+ * @param onVerifyFailed If the signature check fails or can't find the public key, this calls onVerifyFailed(data).
+ * @return null for no further step for looking up a certificate chain.
+ */
+ virtual ptr_lib::shared_ptr<ValidationRequest>
+ checkVerificationPolicy
+ (const ptr_lib::shared_ptr<Data>& data, int stepCount, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed);
+
+ /**
+ * Override to always indicate that the signing certificate name and data name satisfy the signing policy.
+ * @param dataName The name of data to be signed.
+ * @param certificateName The name of signing certificate.
+ * @return true to indicate that the signing certificate can be used to sign the data.
+ */
+ virtual bool
+ checkSigningPolicy(const Name& dataName, const Name& certificateName);
+
+ /**
+ * Override to indicate that the signing identity cannot be inferred.
+ * @param dataName The name of data to be signed.
+ * @return An empty name because cannot infer.
+ */
+ virtual Name
+ inferSigningIdentity(const Name& dataName);
+
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/sec-policy.hpp b/include/ndn-cpp-dev/security/sec-policy.hpp
new file mode 100644
index 0000000..e3879bb
--- /dev/null
+++ b/include/ndn-cpp-dev/security/sec-policy.hpp
@@ -0,0 +1,79 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SEC_POLICY_HPP
+#define NDN_SEC_POLICY_HPP
+
+#include "../data.hpp"
+#include "validation-request.hpp"
+
+namespace ndn {
+
+/**
+ * A SecPolicy is an abstract base class to represent the policy for verifying data packets.
+ * You must create an object of a subclass.
+ */
+class SecPolicy {
+public:
+ struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+ /**
+ * The virtual destructor.
+ */
+ virtual
+ ~SecPolicy() {}
+
+ /**
+ * Check if the received data packet can escape from verification and be trusted as valid.
+ * @param data The received data packet.
+ * @return true if the data does not need to be verified to be trusted as valid, otherwise false.
+ */
+ virtual bool
+ skipVerifyAndTrust(const Data& data) = 0;
+
+ /**
+ * Check if this SecPolicy has a verification rule for the received data.
+ * @param data The received data packet.
+ * @return true if the data must be verified, otherwise false.
+ */
+ virtual bool
+ requireVerify(const Data& data) = 0;
+
+ /**
+ * Check whether the received data packet complies with the verification policy, and get the indication of the next verification step.
+ * @param data The Data object with the signature to check.
+ * @param stepCount The number of verification steps that have been done, used to track the verification progress.
+ * @param onVerified If the signature is verified, this calls onVerified(data).
+ * @param onVerifyFailed If the signature check fails, this calls onVerifyFailed(data).
+ * @return the indication of next verification step, null if there is no further step.
+ */
+ virtual ptr_lib::shared_ptr<ValidationRequest>
+ checkVerificationPolicy
+ (const ptr_lib::shared_ptr<Data>& data, int stepCount, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed) = 0;
+
+ /**
+ * Check if the signing certificate name and data name satisfy the signing policy.
+ * @param dataName The name of data to be signed.
+ * @param certificateName The name of signing certificate.
+ * @return true if the signing certificate can be used to sign the data, otherwise false.
+ */
+ virtual bool
+ checkSigningPolicy(const Name& dataName, const Name& certificateName) = 0;
+
+ /**
+ * Infer the signing identity name according to the policy. If the signing identity cannot be inferred, return an empty name.
+ * @param dataName The name of data to be signed.
+ * @return The signing identity or an empty name if cannot infer.
+ */
+ virtual Name
+ inferSigningIdentity(const Name& dataName) = 0;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/sec-public-info-memory.hpp b/include/ndn-cpp-dev/security/sec-public-info-memory.hpp
new file mode 100644
index 0000000..c991f1a
--- /dev/null
+++ b/include/ndn-cpp-dev/security/sec-public-info-memory.hpp
@@ -0,0 +1,217 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SEC_PUBLIC_INFO_MEMORY_HPP
+#define NDN_SEC_PUBLIC_INFO_MEMORY_HPP
+
+#include <vector>
+#include <map>
+#include "sec-public-info.hpp"
+
+namespace ndn {
+
+/**
+ * MemoryKeyMetaInfo extends IdentityStorage and implements its methods to store identity, public key and certificate objects in memory.
+ * The application must get the objects through its own means and add the objects to the MemoryKeyMetaInfo object.
+ * To use permanent file-based storage, see BasicKeyMetaInfo.
+ */
+class SecPublicInfoMemory : public SecPublicInfo {
+public:
+ struct Error : public SecPublicInfo::Error { Error(const std::string &what) : SecPublicInfo::Error(what) {} };
+
+ /**
+ * The virtual Destructor.
+ */
+ virtual
+ ~SecPublicInfoMemory();
+
+ /**
+ * Check if the specified identity already exists.
+ * @param identityName The identity name.
+ * @return true if the identity exists, otherwise false.
+ */
+ virtual bool
+ doesIdentityExist(const Name& identityName);
+
+ /**
+ * Add a new identity. An exception will be thrown if the identity already exists.
+ * @param identityName The identity name to be added.
+ */
+ virtual void
+ addIdentity(const Name& identityName);
+
+ /**
+ * Revoke the identity.
+ * @return true if the identity was revoked, false if not.
+ */
+ virtual bool
+ revokeIdentity();
+
+ /**
+ * Check if the specified key already exists.
+ * @param keyName The name of the key.
+ * @return true if the key exists, otherwise false.
+ */
+ virtual bool
+ doesPublicKeyExist(const Name& keyName);
+
+ /**
+ * Add a public key to the identity storage.
+ * @param keyName The name of the public key to be added.
+ * @param keyType Type of the public key to be added.
+ * @param publicKeyDer A blob of the public key DER to be added.
+ */
+ virtual void
+ addPublicKey(const Name& keyName, KeyType keyType, const PublicKey& publicKeyDer);
+
+ /**
+ * Get the public key DER blob from the identity storage.
+ * @param keyName The name of the requested public key.
+ * @return The DER Blob. If not found, return a Blob with a null pointer.
+ */
+ virtual ptr_lib::shared_ptr<PublicKey>
+ getPublicKey(const Name& keyName);
+
+ /**
+ * Activate a key. If a key is marked as inactive, its private part will not be used in packet signing.
+ * @param keyName name of the key
+ */
+ virtual void
+ activatePublicKey(const Name& keyName);
+
+ /**
+ * Deactivate a key. If a key is marked as inactive, its private part will not be used in packet signing.
+ * @param keyName name of the key
+ */
+ virtual void
+ deactivatePublicKey(const Name& keyName);
+
+ /**
+ * Check if the specified certificate already exists.
+ * @param certificateName The name of the certificate.
+ * @return true if the certificate exists, otherwise false.
+ */
+ virtual bool
+ doesCertificateExist(const Name& certificateName);
+
+ /**
+ * Add a certificate to the identity storage.
+ * @param certificate The certificate to be added. This makes a copy of the certificate.
+ */
+ virtual void
+ addCertificate(const IdentityCertificate& certificate);
+
+ /**
+ * Get a certificate from the identity storage.
+ * @param certificateName The name of the requested certificate.
+ * @param allowAny If false, only a valid certificate will be returned, otherwise validity is disregarded.
+ * @return The requested certificate. If not found, return a shared_ptr with a null pointer.
+ */
+ virtual ptr_lib::shared_ptr<IdentityCertificate>
+ getCertificate(const Name &certificateName);
+
+
+ /*****************************************
+ * Get/Set Default *
+ *****************************************/
+
+ /**
+ * Get the default identity.
+ * @param return The name of default identity, or an empty name if there is no default.
+ */
+ virtual Name
+ getDefaultIdentity();
+
+ /**
+ * Get the default key name for the specified identity.
+ * @param identityName The identity name.
+ * @return The default key name.
+ */
+ virtual Name
+ getDefaultKeyNameForIdentity(const Name& identityName);
+
+ /**
+ * Get the default certificate name for the specified key.
+ * @param keyName The key name.
+ * @return The default certificate name.
+ */
+ virtual Name
+ getDefaultCertificateNameForKey(const Name& keyName);
+
+ virtual std::vector<Name>
+ getAllIdentities(bool isDefault);
+
+ virtual std::vector<Name>
+ getAllKeyNames(bool isDefault);
+
+ virtual std::vector<Name>
+ getAllKeyNamesOfIdentity(const Name& identity, bool isDefault);
+
+ virtual std::vector<Name>
+ getAllCertificateNames(bool isDefault);
+
+ virtual std::vector<Name>
+ getAllCertificateNamesOfKey(const Name& keyName, bool isDefault);
+
+protected:
+ /**
+ * Set the default identity. If the identityName does not exist, then clear the default identity
+ * so that getDefaultIdentity() returns an empty name.
+ * @param identityName The default identity name.
+ */
+ virtual void
+ setDefaultIdentityInternal(const Name& identityName);
+
+ /**
+ * Set the default key name for the specified identity.
+ * @param keyName The key name.
+ * @param identityNameCheck (optional) The identity name to check the keyName.
+ */
+ virtual void
+ setDefaultKeyNameForIdentityInternal(const Name& keyName);
+
+ /**
+ * Set the default key name for the specified identity.
+ * @param keyName The key name.
+ * @param certificateName The certificate name.
+ */
+ virtual void
+ setDefaultCertificateNameForKeyInternal(const Name& certificateName);
+
+
+private:
+ class KeyRecord {
+ public:
+ KeyRecord(KeyType keyType, const PublicKey &key)
+ : keyType_(keyType), key_(key)
+ {
+ }
+
+ const KeyType getKeyType() const { return keyType_; }
+
+ const PublicKey& getKey() { return key_; }
+
+ private:
+ KeyType keyType_;
+ PublicKey key_;
+ };
+
+ std::vector<std::string> identityStore_; /**< A list of name URI. */
+ std::string defaultIdentity_; /**< The default identity in identityStore_, or "" if not defined. */
+ Name defaultKeyName_;
+ Name defaultCert_;
+
+ typedef std::map< std::string, ptr_lib::shared_ptr<KeyRecord> > KeyStore; /**< The map key is the keyName.toUri() */
+ typedef std::map< std::string, ptr_lib::shared_ptr<IdentityCertificate> > CertificateStore; /**< The map key is the certificateName.toUri() */
+
+ KeyStore keyStore_;
+ CertificateStore certificateStore_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/sec-public-info-sqlite3.hpp b/include/ndn-cpp-dev/security/sec-public-info-sqlite3.hpp
new file mode 100644
index 0000000..f83c27e
--- /dev/null
+++ b/include/ndn-cpp-dev/security/sec-public-info-sqlite3.hpp
@@ -0,0 +1,223 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SEC_PUBLIC_INFO_SQLITE3_HPP
+#define NDN_SEC_PUBLIC_INFO_SQLITE3_HPP
+
+// Only compile if ndn-cpp-config.h defines NDN_CPP_HAVE_SQLITE3.
+#include <ndn-cpp-dev/ndn-cpp-config.h>
+#ifdef NDN_CPP_HAVE_SQLITE3
+
+#include <sqlite3.h>
+#include "../common.hpp"
+#include "sec-public-info.hpp"
+
+namespace ndn
+{
+
+/**
+ * BasicIdentityStorage extends IdentityStorage to implement a basic storage of identity, public keys and certificates
+ * using SQLite.
+ */
+class SecPublicInfoSqlite3 : public SecPublicInfo {
+public:
+ struct Error : public SecPublicInfo::Error { Error(const std::string &what) : SecPublicInfo::Error(what) {} };
+
+ SecPublicInfoSqlite3();
+
+ /**
+ * The virtual Destructor.
+ */
+ virtual
+ ~SecPublicInfoSqlite3();
+
+ // from SecPublicInfo
+ /**
+ * Check if the specified identity already exists.
+ * @param identityName The identity name.
+ * @return true if the identity exists, otherwise false.
+ */
+ virtual bool
+ doesIdentityExist(const Name& identityName);
+
+ /**
+ * Add a new identity. An exception will be thrown if the identity already exists.
+ * @param identityName The identity name to be added.
+ */
+ virtual void
+ addIdentity(const Name& identityName);
+
+ /**
+ * Revoke the identity.
+ * @return true if the identity was revoked, false if not.
+ */
+ virtual bool
+ revokeIdentity();
+
+ /**
+ * Check if the specified key already exists.
+ * @param keyName The name of the key.
+ * @return true if the key exists, otherwise false.
+ */
+ virtual bool
+ doesPublicKeyExist(const Name& keyName);
+
+ /**
+ * Add a public key to the identity storage.
+ * @param keyName The name of the public key to be added.
+ * @param keyType Type of the public key to be added.
+ * @param publicKeyDer A blob of the public key DER to be added.
+ */
+ virtual void
+ addPublicKey(const Name& keyName, KeyType keyType, const PublicKey& publicKeyDer);
+
+ /**
+ * Get the public key DER blob from the identity storage.
+ * @param keyName The name of the requested public key.
+ * @return The DER Blob. If not found, return a Blob with a null pointer.
+ */
+ virtual ptr_lib::shared_ptr<PublicKey>
+ getPublicKey(const Name& keyName);
+
+ /**
+ * Activate a key. If a key is marked as inactive, its private part will not be used in packet signing.
+ * @param keyName name of the key
+ */
+ virtual inline void
+ activatePublicKey(const Name& keyName);
+
+ /**
+ * Deactivate a key. If a key is marked as inactive, its private part will not be used in packet signing.
+ * @param keyName name of the key
+ */
+ virtual inline void
+ deactivatePublicKey(const Name& keyName);
+
+ /**
+ * Check if the specified certificate already exists.
+ * @param certificateName The name of the certificate.
+ * @return true if the certificate exists, otherwise false.
+ */
+ virtual bool
+ doesCertificateExist(const Name& certificateName);
+
+ /**
+ * Add a certificate in to the identity storage without checking if the identity and key exists.
+ * @param certificate The certificate to be added.
+ */
+ virtual void
+ addAnyCertificate (const IdentityCertificate& certificate);
+
+ /**
+ * Add a certificate to the identity storage.
+ * @param certificate The certificate to be added. This makes a copy of the certificate.
+ */
+ virtual void
+ addCertificate(const IdentityCertificate& certificate);
+
+ /**
+ * Get a certificate from the identity storage.
+ * @param certificateName The name of the requested certificate.
+ * @param allowAny If false, only a valid certificate will be returned, otherwise validity is disregarded.
+ * @return The requested certificate. If not found, return a shared_ptr with a null pointer.
+ */
+ virtual ptr_lib::shared_ptr<IdentityCertificate>
+ getCertificate(const Name &certificateName);
+
+
+ /*****************************************
+ * Default Getter *
+ *****************************************/
+
+ /**
+ * Get the default identity.
+ * @param return The name of default identity, or an empty name if there is no default.
+ */
+ virtual Name
+ getDefaultIdentity();
+
+ /**
+ * Get the default key name for the specified identity.
+ * @param identityName The identity name.
+ * @return The default key name.
+ */
+ virtual Name
+ getDefaultKeyNameForIdentity(const Name& identityName);
+
+ /**
+ * Get the default certificate name for the specified key.
+ * @param keyName The key name.
+ * @return The default certificate name.
+ */
+ virtual Name
+ getDefaultCertificateNameForKey(const Name& keyName);
+
+ virtual std::vector<Name>
+ getAllIdentities(bool isDefault);
+
+ virtual std::vector<Name>
+ getAllKeyNames(bool isDefault);
+
+ virtual std::vector<Name>
+ getAllKeyNamesOfIdentity(const Name& identity, bool isDefault);
+
+ virtual std::vector<Name>
+ getAllCertificateNames(bool isDefault);
+
+ virtual std::vector<Name>
+ getAllCertificateNamesOfKey(const Name& keyName, bool isDefault);
+
+protected:
+ /**
+ * Set the default identity. If the identityName does not exist, then clear the default identity
+ * so that getDefaultIdentity() returns an empty name.
+ * @param identityName The default identity name.
+ */
+ virtual void
+ setDefaultIdentityInternal(const Name& identityName);
+
+ /**
+ * Set the default key name for the specified identity.
+ * @param keyName The key name.
+ * @param identityNameCheck (optional) The identity name to check the keyName.
+ */
+ virtual void
+ setDefaultKeyNameForIdentityInternal(const Name& keyName);
+
+ /**
+ * Set the default key name for the specified identity.
+ * @param keyName The key name.
+ * @param certificateName The certificate name.
+ */
+ virtual void
+ setDefaultCertificateNameForKeyInternal(const Name& certificateName);
+
+private:
+ void
+ updateKeyStatus(const Name& keyName, bool isActive);
+
+ sqlite3 *database_;
+};
+
+void
+SecPublicInfoSqlite3::activatePublicKey(const Name& keyName)
+{
+ updateKeyStatus(keyName, true);
+}
+
+void
+SecPublicInfoSqlite3::deactivatePublicKey(const Name& keyName)
+{
+ updateKeyStatus(keyName, false);
+}
+
+}
+
+#endif // NDN_CPP_HAVE_SQLITE3
+
+#endif
diff --git a/include/ndn-cpp-dev/security/sec-public-info.hpp b/include/ndn-cpp-dev/security/sec-public-info.hpp
new file mode 100644
index 0000000..7cd7230
--- /dev/null
+++ b/include/ndn-cpp-dev/security/sec-public-info.hpp
@@ -0,0 +1,380 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SEC_PUBLIC_INFO_HPP
+#define NDN_SEC_PUBLIC_INFO_HPP
+
+#include "../name.hpp"
+#include "security-common.hpp"
+#include "public-key.hpp"
+#include "identity-certificate.hpp"
+
+
+namespace ndn {
+
+/**
+ * SecPublicInfo is a base class for the storage of identity, public keys and certificates.
+ * Private keys are stored in SecTpm.
+ * This is an abstract base class. A subclass must implement the methods.
+ */
+class SecPublicInfo {
+public:
+ struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+ /**
+ * The virtual Destructor.
+ */
+ virtual
+ ~SecPublicInfo() {}
+
+ /**
+ * Check if the specified identity already exists.
+ * @param identityName The identity name.
+ * @return true if the identity exists, otherwise false.
+ */
+ virtual bool
+ doesIdentityExist(const Name& identityName) = 0;
+
+ /**
+ * Add a new identity. An exception will be thrown if the identity already exists.
+ * @param identityName The identity name to be added.
+ */
+ virtual void
+ addIdentity(const Name& identityName) = 0;
+
+ /**
+ * Revoke the identity.
+ * @return true if the identity was revoked, false if not.
+ */
+ virtual bool
+ revokeIdentity() = 0;
+
+ /**
+ * Check if the specified key already exists.
+ * @param keyName The name of the key.
+ * @return true if the key exists, otherwise false.
+ */
+ virtual bool
+ doesPublicKeyExist(const Name& keyName) = 0;
+
+ /**
+ * Add a public key to the identity storage.
+ * @param keyName The name of the public key to be added.
+ * @param keyType Type of the public key to be added.
+ * @param publicKeyDer A blob of the public key DER to be added.
+ */
+ virtual void
+ addPublicKey(const Name& keyName, KeyType keyType, const PublicKey& publicKeyDer) = 0;
+
+ /**
+ * Get the public key DER blob from the identity storage.
+ * @param keyName The name of the requested public key.
+ * @return The DER Blob. If not found, return a Blob with a null pointer.
+ */
+ virtual ptr_lib::shared_ptr<PublicKey>
+ getPublicKey(const Name& keyName) = 0;
+
+ /**
+ * Activate a key. If a key is marked as inactive, its private part will not be used in packet signing.
+ * @param keyName name of the key
+ */
+ virtual void
+ activatePublicKey(const Name& keyName) = 0;
+
+ /**
+ * Deactivate a key. If a key is marked as inactive, its private part will not be used in packet signing.
+ * @param keyName name of the key
+ */
+ virtual void
+ deactivatePublicKey(const Name& keyName) = 0;
+
+ /**
+ * Check if the specified certificate already exists.
+ * @param certificateName The name of the certificate.
+ * @return true if the certificate exists, otherwise false.
+ */
+ virtual bool
+ doesCertificateExist(const Name& certificateName) = 0;
+
+ /**
+ * Add a certificate to the identity storage.
+ * @param certificate The certificate to be added. This makes a copy of the certificate.
+ */
+ virtual void
+ addCertificate(const IdentityCertificate& certificate) = 0;
+
+ /**
+ * Get a certificate from the identity storage.
+ * @param certificateName The name of the requested certificate.
+ * @param allowAny If false, only a valid certificate will be returned, otherwise validity is disregarded.
+ * @return The requested certificate. If not found, return a shared_ptr with a null pointer.
+ */
+ virtual ptr_lib::shared_ptr<IdentityCertificate>
+ getCertificate(const Name &certificateName) = 0;
+
+
+ /*****************************************
+ * Default Getter *
+ *****************************************/
+
+ /**
+ * Get the default identity.
+ * @param return The name of default identity, or an empty name if there is no default.
+ */
+ virtual Name
+ getDefaultIdentity() = 0;
+
+ /**
+ * Get the default key name for the specified identity.
+ * @param identityName The identity name.
+ * @return The default key name.
+ */
+ virtual Name
+ getDefaultKeyNameForIdentity(const Name& identityName) = 0;
+
+ /**
+ * Get the default certificate name for the specified key.
+ * @param keyName The key name.
+ * @return The default certificate name.
+ */
+ virtual Name
+ getDefaultCertificateNameForKey(const Name& keyName) = 0;
+
+ virtual std::vector<Name>
+ getAllIdentities(bool isDefault) = 0;
+
+ virtual std::vector<Name>
+ getAllKeyNames(bool isDefault) = 0;
+
+ virtual std::vector<Name>
+ getAllKeyNamesOfIdentity(const Name& identity, bool isDefault) = 0;
+
+ virtual std::vector<Name>
+ getAllCertificateNames(bool isDefault) = 0;
+
+ virtual std::vector<Name>
+ getAllCertificateNamesOfKey(const Name& keyName, bool isDefault) = 0;
+
+protected:
+
+ /*****************************************
+ * Default Setter *
+ *****************************************/
+
+ /**
+ * Set the default identity. If the identityName does not exist, then clear the default identity
+ * so that getDefaultIdentity() returns an empty name.
+ * @param identityName The default identity name.
+ */
+ virtual void
+ setDefaultIdentityInternal(const Name& identityName) = 0;
+
+ /**
+ * Set the default key name for the corresponding identity.
+ * @param keyName The key name.
+ */
+ virtual void
+ setDefaultKeyNameForIdentityInternal(const Name& keyName) = 0;
+
+ /**
+ * Set the default certificate name for the corresponding key.
+ * @param certificateName The certificate name.
+ */
+ virtual void
+ setDefaultCertificateNameForKeyInternal(const Name& certificateName) = 0;
+
+public:
+
+ /*****************************************
+ * Helper Methods *
+ *****************************************/
+
+ /**
+ * Set the default identity. If the identityName does not exist, then clear the default identity
+ * so that getDefaultIdentity() returns an empty name.
+ * @param identityName The default identity name.
+ */
+ inline void
+ setDefaultIdentity(const Name& identityName);
+
+ /**
+ * Set the default key name for the corresponding identity.
+ * @param keyName The key name.
+ */
+ inline void
+ setDefaultKeyNameForIdentity(const Name& keyName);
+
+ /**
+ * Set the default certificate name for the corresponding key.
+ * @param certificateName The certificate name.
+ */
+ inline void
+ setDefaultCertificateNameForKey(const Name& certificateName);
+
+ /**
+ * Generate a name for a new key belonging to the identity.
+ * @param identityName The identity name.
+ * @param useKsk If true, generate a KSK name, otherwise a DSK name.
+ * @return The generated key name.
+ */
+ inline Name
+ getNewKeyName(const Name& identityName, bool useKsk);
+
+ /**
+ * Get the default certificate name for the specified identity.
+ * @param identityName The identity name.
+ * @return The default certificate name.
+ */
+ inline Name
+ getDefaultCertificateNameForIdentity(const Name& identityName);
+
+ /**
+ * Get the default certificate name of the default identity, which will be used when signing is based on identity and
+ * the identity is not specified.
+ * @return The requested certificate name.
+ */
+ inline Name
+ getDefaultCertificateName();
+
+ /**
+ * Add a certificate and set the certificate as the default of its corresponding key.
+ * @param certificate The certificate to be added. This makes a copy of the certificate.
+ */
+ inline void
+ addCertificateAsKeyDefault(const IdentityCertificate& certificate);
+
+ /**
+ * Add a certificate into the public key identity storage and set the certificate as the default for its corresponding identity.
+ * @param certificate The certificate to be added. This makes a copy of the certificate.
+ */
+ inline void
+ addCertificateAsIdentityDefault(const IdentityCertificate& certificate);
+
+ inline void
+ addCertificateAsSystemDefault(const IdentityCertificate& certificate);
+
+ inline ptr_lib::shared_ptr<IdentityCertificate>
+ defaultCertificate();
+
+ inline void
+ refreshDefaultCertificate();
+
+protected:
+ ptr_lib::shared_ptr<IdentityCertificate> defaultCertificate_;
+
+};
+
+void
+SecPublicInfo::setDefaultIdentity(const Name& identityName)
+{
+ setDefaultIdentityInternal(identityName);
+ refreshDefaultCertificate();
+}
+
+void
+SecPublicInfo::setDefaultKeyNameForIdentity(const Name& keyName)
+{
+ setDefaultKeyNameForIdentityInternal(keyName);
+ refreshDefaultCertificate();
+}
+
+void
+SecPublicInfo::setDefaultCertificateNameForKey(const Name& certificateName)
+{
+ setDefaultCertificateNameForKeyInternal(certificateName);
+ refreshDefaultCertificate();
+}
+
+Name
+SecPublicInfo::getDefaultCertificateNameForIdentity(const Name& identityName)
+{
+ return getDefaultCertificateNameForKey(getDefaultKeyNameForIdentity(identityName));
+}
+
+Name
+SecPublicInfo::getNewKeyName (const Name& identityName, bool useKsk)
+{
+ std::ostringstream oss;
+
+ if (useKsk)
+ oss << "ksk-";
+ else
+ oss << "dsk-";
+
+ oss << static_cast<int>(getNow()/1000);
+
+ Name keyName = Name(identityName).append(oss.str());
+
+ if (doesPublicKeyExist(keyName))
+ throw Error("Key name already exists");
+
+ return keyName;
+}
+
+Name
+SecPublicInfo::getDefaultCertificateName()
+{
+ if(!static_cast<bool>(defaultCertificate_))
+ refreshDefaultCertificate();
+
+ if(!static_cast<bool>(defaultCertificate_))
+ return Name();
+
+ return defaultCertificate_->getName();
+}
+
+void
+SecPublicInfo::addCertificateAsKeyDefault(const IdentityCertificate& certificate)
+{
+ addCertificate(certificate);
+ setDefaultCertificateNameForKeyInternal(certificate.getName());
+ refreshDefaultCertificate();
+}
+
+void
+SecPublicInfo::addCertificateAsIdentityDefault(const IdentityCertificate& certificate)
+{
+ addCertificate(certificate);
+ Name certName = certificate.getName();
+ setDefaultKeyNameForIdentityInternal(IdentityCertificate::certificateNameToPublicKeyName(certName));
+ setDefaultCertificateNameForKeyInternal(certName);
+ refreshDefaultCertificate();
+}
+
+void
+SecPublicInfo::addCertificateAsSystemDefault(const IdentityCertificate& certificate)
+{
+ addCertificate(certificate);
+ Name certName = certificate.getName();
+ Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certName);
+ setDefaultIdentityInternal(keyName.getPrefix(-1));
+ setDefaultKeyNameForIdentityInternal(keyName);
+ setDefaultCertificateNameForKeyInternal(certName);
+ refreshDefaultCertificate();
+}
+
+ptr_lib::shared_ptr<IdentityCertificate>
+SecPublicInfo::defaultCertificate()
+{
+ return defaultCertificate_;
+}
+
+void
+SecPublicInfo::refreshDefaultCertificate()
+{
+ Name certName = getDefaultCertificateNameForIdentity(getDefaultIdentity());
+ if(certName.empty())
+ defaultCertificate_.reset();
+ else
+ defaultCertificate_ = getCertificate(certName);
+}
+
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/sec-tpm-memory.hpp b/include/ndn-cpp-dev/security/sec-tpm-memory.hpp
new file mode 100644
index 0000000..8203272
--- /dev/null
+++ b/include/ndn-cpp-dev/security/sec-tpm-memory.hpp
@@ -0,0 +1,127 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SEC_TPM_MEMORY_HPP
+#define NDN_SEC_TPM_MEMORY_HPP
+
+#include <map>
+#include "sec-tpm.hpp"
+
+struct rsa_st;
+
+namespace ndn {
+
+/**
+ * MemoryPrivateKeyStorage extends PrivateKeyStorage to implement a simple in-memory private key store. You should
+ * initialize by calling setKeyPairForKeyName.
+ */
+class SecTpmMemory : public SecTpm {
+public:
+ struct Error : public SecTpm::Error { Error(const std::string &what) : SecTpm::Error(what) {} };
+
+ /**
+ * The virtual destructor
+ */
+ virtual
+ ~SecTpmMemory();
+
+ /**
+ * Set the public and private key for the keyName.
+ * @param keyName The key name.
+ * @param publicKeyDer The public key DER byte array.
+ * @param publicKeyDerLength The length of publicKeyDer.
+ * @param privateKeyDer The private key DER byte array.
+ * @param privateKeyDerLength The length of privateKeyDer.
+ */
+ void setKeyPairForKeyName(const Name& keyName,
+ uint8_t *publicKeyDer, size_t publicKeyDerLength,
+ uint8_t *privateKeyDer, size_t privateKeyDerLength);
+
+ /**
+ * Generate a pair of asymmetric keys.
+ * @param keyName The name of the key pair.
+ * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
+ * @param keySize The size of the key pair.
+ */
+ virtual void
+ generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize);
+
+ /**
+ * Get the public key
+ * @param keyName The name of public key.
+ * @return The public key.
+ */
+ virtual ptr_lib::shared_ptr<PublicKey>
+ getPublicKeyFromTpm(const Name& keyName);
+
+ /**
+ * Fetch the private key for keyName and sign the data, returning a signature Blob.
+ * @param data Pointer to the input byte array.
+ * @param dataLength The length of data.
+ * @param keyName The name of the signing key.
+ * @param digestAlgorithm the digest algorithm.
+ * @return The signature, or a null pointer if signing fails.
+ */
+ virtual Block
+ signInTpm(const uint8_t *data, size_t dataLength, const Name& keyName, DigestAlgorithm digestAlgorithm);
+
+ virtual void
+ signInTpm(Data &data, const Name& keyName, DigestAlgorithm digestAlgorithm);
+
+ /**
+ * Decrypt data.
+ * @param keyName The name of the decrypting key.
+ * @param data The byte to be decrypted.
+ * @param dataLength the length of data.
+ * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric decryption is used.
+ * @return The decrypted data.
+ */
+ virtual ConstBufferPtr
+ decryptInTpm(const Name& keyName, const uint8_t* data, size_t dataLength, bool isSymmetric);
+
+ /**
+ * Encrypt data.
+ * @param keyName The name of the encrypting key.
+ * @param data The byte to be encrypted.
+ * @param dataLength the length of data.
+ * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric decryption is used.
+ * @return The encrypted data.
+ */
+ virtual ConstBufferPtr
+ encryptInTpm(const Name& keyName, const uint8_t* data, size_t dataLength, bool isSymmetric);
+
+ /**
+ * @brief Generate a symmetric key.
+ * @param keyName The name of the key.
+ * @param keyType The type of the key, e.g. KEY_TYPE_AES.
+ * @param keySize The size of the key.
+ */
+ virtual void
+ generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize);
+
+ /**
+ * Check if a particular key exists.
+ * @param keyName The name of the key.
+ * @param keyClass The class of the key, e.g. KEY_CLASS_PUBLIC, KEY_CLASS_PRIVATE, or KEY_CLASS_SYMMETRIC.
+ * @return True if the key exists, otherwise false.
+ */
+ virtual bool
+ doesKeyExistInTpm(const Name& keyName, KeyClass keyClass);
+
+private:
+ class RsaPrivateKey;
+
+ typedef std::map<std::string, ptr_lib::shared_ptr<PublicKey> > PublicKeyStore;
+ typedef std::map<std::string, ptr_lib::shared_ptr<RsaPrivateKey> > PrivateKeyStore;
+
+ PublicKeyStore publicKeyStore_; /**< The map key is the keyName.toUri() */
+ PrivateKeyStore privateKeyStore_; /**< The map key is the keyName.toUri() */
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/sec-tpm-osx.hpp b/include/ndn-cpp-dev/security/sec-tpm-osx.hpp
new file mode 100644
index 0000000..4839e3d
--- /dev/null
+++ b/include/ndn-cpp-dev/security/sec-tpm-osx.hpp
@@ -0,0 +1,127 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SEC_TPM_OSX_HPP
+#define NDN_SEC_TPM_OSX_HPP
+
+// Only compile if ndn-cpp-config.h defines NDN_CPP_HAVE_OSX_SECURITY 1.
+#include <ndn-cpp-dev/ndn-cpp-config.h>
+#if NDN_CPP_HAVE_OSX_SECURITY
+
+#include "../common.hpp"
+#include "sec-tpm.hpp"
+
+namespace ndn
+{
+
+class SecTpmOsx : public SecTpm {
+public:
+ struct Error : public SecTpm::Error { Error(const std::string &what) : SecTpm::Error(what) {} };
+
+ /**
+ * constructor of OSXKeyChainTpm
+ * @param keychainName the name of keychain
+ */
+ SecTpmOsx(const std::string & keychainName = "");
+
+ /**
+ * destructor of OSXKeyChainTpm
+ */
+ virtual
+ ~SecTpmOsx();
+
+
+ // From TrustedPlatformModule
+ virtual void
+ generateKeyPairInTpm(const Name& keyName, KeyType keyType = KEY_TYPE_RSA, int keySize = 2048);
+
+ virtual ptr_lib::shared_ptr<PublicKey>
+ getPublicKeyFromTpm(const Name& keyName);
+
+ virtual Block
+ signInTpm(const uint8_t *data, size_t dataLength, const Name& keyName, DigestAlgorithm digestAlgorithm);
+
+ virtual void
+ signInTpm(Data &data, const Name& keyName, DigestAlgorithm digestAlgorithm);
+
+ /**
+ * Decrypt data.
+ * @param keyName The name of the decrypting key.
+ * @param data The byte to be decrypted.
+ * @param dataLength the length of data.
+ * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric decryption is used.
+ * @return The decrypted data.
+ */
+ virtual ConstBufferPtr
+ decryptInTpm(const Name& keyName, const uint8_t* data, size_t dataLength, bool isSymmetric);
+
+ /**
+ * Encrypt data.
+ * @param keyName The name of the encrypting key.
+ * @param data The byte to be encrypted.
+ * @param dataLength the length of data.
+ * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric decryption is used.
+ * @return The encrypted data.
+ */
+ virtual ConstBufferPtr
+ encryptInTpm(const Name& keyName, const uint8_t* data, size_t dataLength, bool isSymmetric);
+
+ /**
+ * Generate a symmetric key.
+ * @param keyName The name of the key.
+ * @param keyType The type of the key, e.g. KEY_TYPE_AES.
+ * @param keySize The size of the key.
+ */
+ virtual void
+ generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize);
+
+ /**
+ * Check if a particular key exists.
+ * @param keyName The name of the key.
+ * @param keyClass The class of the key, e.g. KEY_CLASS_PUBLIC, KEY_CLASS_PRIVATE, or KEY_CLASS_SYMMETRIC.
+ * @return True if the key exists, otherwise false.
+ */
+ virtual bool
+ doesKeyExistInTpm(const Name& keyName, KeyClass keyClass);
+
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // OSX-specifics
+ ////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * configure ACL of a particular key
+ * @param keyName the name of key
+ * @param keyClass the class of key, e.g. Private Key
+ * @param acl the new acl of the key
+ * @param appPath the absolute path to the application
+ * @returns true if setting succeeds
+ */
+ bool
+ setACL(const Name & keyName, KeyClass keyClass, int acl, const std::string & appPath);
+
+ // /**
+ // * verify data (test only)
+ // * @param keyName the name of key
+ // * @param pData the data to be verified
+ // * @param pSig the signature associated with the data
+ // * @param digestAlgo digest algorithm
+ // * @return true if signature can be verified, otherwise false
+ // */
+ // bool
+ // verifyData(const Name & keyName, const Blob & pData, const Blob & pSig, DigestAlgorithm digestAlgo = DIGEST_ALGORITHM_SHA256);
+
+ private:
+ class Impl;
+ std::auto_ptr<Impl> impl_;
+};
+
+}
+
+#endif // NDN_CPP_HAVE_OSX_SECURITY
+
+#endif
diff --git a/include/ndn-cpp-dev/security/sec-tpm.hpp b/include/ndn-cpp-dev/security/sec-tpm.hpp
new file mode 100644
index 0000000..c6b5328
--- /dev/null
+++ b/include/ndn-cpp-dev/security/sec-tpm.hpp
@@ -0,0 +1,104 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SEC_TPM_HPP
+#define NDN_SEC_TPM_HPP
+
+#include <string>
+#include "security-common.hpp"
+#include "../name.hpp"
+#include "../data.hpp"
+#include "public-key.hpp"
+
+namespace ndn {
+
+class SecTpm {
+public:
+ struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+ /**
+ * The virtual destructor.
+ */
+ virtual
+ ~SecTpm() {}
+
+ /**
+ * Generate a pair of asymmetric keys.
+ * @param keyName The name of the key pair.
+ * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
+ * @param keySize The size of the key pair.
+ */
+ virtual void
+ generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize) = 0;
+
+ /**
+ * Get the public key
+ * @param keyName The name of public key.
+ * @return The public key.
+ */
+ virtual ptr_lib::shared_ptr<PublicKey>
+ getPublicKeyFromTpm(const Name& keyName) = 0;
+
+ /**
+ * Fetch the private key for keyName and sign the data, returning a signature Blob.
+ * @param data Pointer to the input byte array.
+ * @param dataLength The length of data.
+ * @param keyName The name of the signing key.
+ * @param digestAlgorithm the digest algorithm.
+ * @return The signature, or a null pointer if signing fails.
+ */
+ virtual Block
+ signInTpm(const uint8_t *data, size_t dataLength, const Name& keyName, DigestAlgorithm digestAlgorithm) = 0;
+
+ virtual void
+ signInTpm(Data &data, const Name& keyName, DigestAlgorithm digestAlgorithm) = 0;
+
+ /**
+ * Decrypt data.
+ * @param keyName The name of the decrypting key.
+ * @param data The byte to be decrypted.
+ * @param dataLength the length of data.
+ * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric encryption is used.
+ * @return The decrypted data.
+ */
+ virtual ConstBufferPtr
+ decryptInTpm(const Name& keyName, const uint8_t* data, size_t dataLength, bool isSymmetric) = 0;
+
+ /**
+ * Encrypt data.
+ * @param keyName The name of the encrypting key.
+ * @param data The byte to be encrypted.
+ * @param dataLength the length of data.
+ * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric encryption is used.
+ * @return The encrypted data.
+ */
+ virtual ConstBufferPtr
+ encryptInTpm(const Name& keyName, const uint8_t* data, size_t dataLength, bool isSymmetric) = 0;
+
+ /**
+ * @brief Generate a symmetric key.
+ * @param keyName The name of the key.
+ * @param keyType The type of the key, e.g. KEY_TYPE_AES.
+ * @param keySize The size of the key.
+ */
+ virtual void
+ generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize) = 0;
+
+ /**
+ * Check if a particular key exists.
+ * @param keyName The name of the key.
+ * @param keyClass The class of the key, e.g. KEY_CLASS_PUBLIC, KEY_CLASS_PRIVATE, or KEY_CLASS_SYMMETRIC.
+ * @return True if the key exists, otherwise false.
+ */
+ virtual bool
+ doesKeyExistInTpm(const Name& keyName, KeyClass keyClass) = 0;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/security-common.hpp b/include/ndn-cpp-dev/security/security-common.hpp
new file mode 100644
index 0000000..9ce4599
--- /dev/null
+++ b/include/ndn-cpp-dev/security/security-common.hpp
@@ -0,0 +1,43 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SECURITY_COMMON_HPP
+#define NDN_SECURITY_COMMON_HPP
+
+namespace ndn {
+
+enum KeyType {
+ KEY_TYPE_RSA,
+ // KEY_TYPE_DSA,
+ KEY_TYPE_AES,
+ // KEY_TYPE_DES,
+ // KEY_TYPE_RC4,
+ // KEY_TYPE_RC2
+};
+
+enum KeyClass {
+ KEY_CLASS_PUBLIC,
+ KEY_CLASS_PRIVATE,
+ KEY_CLASS_SYMMETRIC
+};
+
+enum DigestAlgorithm {
+ // DIGEST_ALGORITHM_MD2,
+ // DIGEST_ALGORITHM_MD5,
+ // DIGEST_ALGORITHM_SHA1,
+ DIGEST_ALGORITHM_SHA256
+};
+
+enum EncryptMode {
+ ENCRYPT_MODE_DEFAULT,
+ ENCRYPT_MODE_CFB_AES,
+ // ENCRYPT_MODE_CBC_AES
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/security-exception.hpp b/include/ndn-cpp-dev/security/security-exception.hpp
new file mode 100644
index 0000000..daf1d61
--- /dev/null
+++ b/include/ndn-cpp-dev/security/security-exception.hpp
@@ -0,0 +1,49 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SECURITY_EXCEPTION_HPP
+#define NDN_SECURITY_EXCEPTION_HPP
+
+#include <exception>
+#include <string>
+
+namespace ndn {
+
+class SecurityException : public std::exception {
+public:
+ SecurityException(const std::string& errorMessage) throw();
+
+ virtual ~SecurityException() throw();
+
+ std::string Msg() { return errorMessage_; }
+
+ virtual const char* what() const throw() { return errorMessage_.c_str(); }
+
+private:
+ const std::string errorMessage_;
+};
+
+class UnrecognizedKeyFormatException : public SecurityException {
+public:
+ UnrecognizedKeyFormatException(const std::string& errorMessage)
+ : SecurityException(errorMessage)
+ {
+ }
+};
+
+class UnrecognizedDigestAlgorithmException : public SecurityException {
+public:
+ UnrecognizedDigestAlgorithmException(const std::string& errorMessage)
+ : SecurityException(errorMessage)
+ {
+ }
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/sha256-with-rsa-handler.hpp b/include/ndn-cpp-dev/security/sha256-with-rsa-handler.hpp
new file mode 100644
index 0000000..6627f02
--- /dev/null
+++ b/include/ndn-cpp-dev/security/sha256-with-rsa-handler.hpp
@@ -0,0 +1,38 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SHA256_RSA_HANDLER_HPP
+#define NDN_SHA256_RSA_HANDLER_HPP
+
+#include "../../data.hpp"
+#include "../certificate/public-key.hpp"
+
+namespace ndn{
+
+class Sha256WithRsaHandler {
+public:
+ Sha256WithRsaHandler() {}
+
+ virtual
+ ~Sha256WithRsaHandler() {}
+
+ /**
+ * Verify the signature on the data packet using the given public key. If there is no data.getDefaultWireEncoding(),
+ * this calls data.wireEncode() to set it.
+ * @param data The data packet with the signed portion and the signature to verify. The data packet must have a
+ * Sha256WithRsaSignature.
+ * @param publicKey The public key used to verify the signature.
+ * @return true if the signature verifies, false if not.
+ * @throw SecurityException if data does not have a Sha256WithRsaSignature.
+ */
+ static bool
+ verifySignature(const Data& data, const PublicKey& publicKey);
+
+};
+
+}
+#endif
diff --git a/include/ndn-cpp-dev/security/signature-sha256-with-rsa.hpp b/include/ndn-cpp-dev/security/signature-sha256-with-rsa.hpp
new file mode 100644
index 0000000..b59c765
--- /dev/null
+++ b/include/ndn-cpp-dev/security/signature-sha256-with-rsa.hpp
@@ -0,0 +1,64 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SIGNATURE_SHA256_WITH_RSA_HPP
+#define NDN_SIGNATURE_SHA256_WITH_RSA_HPP
+
+#include "../data.hpp"
+
+namespace ndn {
+
+/**
+ * Representing of SHA256-with-RSA signature in a data packet.
+ */
+class SignatureSha256WithRsa : public Signature {
+public:
+ SignatureSha256WithRsa()
+ {
+ info_ = Block(Tlv::SignatureInfo);
+
+ type_ = Signature::Sha256WithRsa;
+ info_.push_back(nonNegativeIntegerBlock(Tlv::SignatureType, Tlv::SignatureSha256WithRsa));
+ info_.push_back(keyLocator_.wireEncode());
+ }
+
+ SignatureSha256WithRsa(const Signature &signature)
+ : Signature(signature)
+ {
+ if (getType() != Signature::Sha256WithRsa)
+ throw Signature::Error("Incorrect signature type");
+
+ info_.parse();
+ Block::element_iterator i = info_.find(Tlv::KeyLocator);
+ if (i != info_.getAll().end())
+ {
+ keyLocator_.wireDecode(*i);
+ }
+ }
+
+ const KeyLocator&
+ getKeyLocator() const
+ {
+ return keyLocator_;
+ }
+
+ void
+ setKeyLocator(const KeyLocator& keyLocator)
+ {
+ keyLocator_ = keyLocator;
+
+ info_.remove(ndn::Tlv::KeyLocator);
+ info_.push_back(keyLocator_.wireEncode());
+ }
+
+private:
+ KeyLocator keyLocator_;
+};
+
+} // namespace ndn
+
+#endif
diff --git a/include/ndn-cpp-dev/security/validation-request.hpp b/include/ndn-cpp-dev/security/validation-request.hpp
new file mode 100644
index 0000000..7471065
--- /dev/null
+++ b/include/ndn-cpp-dev/security/validation-request.hpp
@@ -0,0 +1,48 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_VALIDATION_REQUEST_HPP
+#define NDN_VALIDATION_REQUEST_HPP
+
+#include "../interest.hpp"
+
+namespace ndn {
+
+/**
+ * An OnVerified function object is used to pass a callback to verifyData to report a successful verification.
+ */
+typedef func_lib::function<void(const ptr_lib::shared_ptr<Data>& data)> OnVerified;
+
+/**
+ * An OnVerifyFailed function object is used to pass a callback to verifyData to report a failed verification.
+ */
+typedef func_lib::function<void(const ptr_lib::shared_ptr<Data>& data)> OnVerifyFailed;
+
+
+class ValidationRequest {
+public:
+ ValidationRequest
+ (const ptr_lib::shared_ptr<Interest> &interest, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed,
+ int retry, int stepCount)
+ : interest_(interest), onVerified_(onVerified), onVerifyFailed_(onVerifyFailed), retry_(retry), stepCount_(stepCount)
+ {
+ }
+
+ virtual
+ ~ValidationRequest() {}
+
+ ptr_lib::shared_ptr<Interest> interest_; // An interest packet to fetch the requested data.
+ OnVerified onVerified_; // A callback function if the requested certificate has been validated.
+ OnVerifyFailed onVerifyFailed_; // A callback function if the requested certificate cannot be validated.
+ int retry_; // The number of retrials when there is an interest timeout.
+ int stepCount_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/security/verifier.hpp b/include/ndn-cpp-dev/security/verifier.hpp
new file mode 100644
index 0000000..2dbd995
--- /dev/null
+++ b/include/ndn-cpp-dev/security/verifier.hpp
@@ -0,0 +1,102 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_VERIFIER_HPP
+#define NDN_VERIFIER_HPP
+
+#include "../data.hpp"
+#include "../face.hpp"
+#include "sec-policy.hpp"
+#include "validation-request.hpp"
+#include "public-key.hpp"
+#include "signature-sha256-with-rsa.hpp"
+
+namespace ndn {
+
+/**
+ * Verifier is one of the main classes of the security librar .
+ *
+ * The Verifier class provides the interfaces for packet verification.
+ */
+class Verifier {
+public:
+ struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+ Verifier(const ptr_lib::shared_ptr<SecPolicy> &policy = DefaultPolicy);
+
+ /**
+ * @brief Set the Face which will be used to fetch required certificates.
+ * @param face A pointer to the Face object.
+ *
+ * Setting face is necessary for verifier operation that involve fetching data.
+ */
+ void
+ setFace(const ptr_lib::shared_ptr<Face> &face) { face_ = face; }
+
+ /**
+ * @brief Get the policy.
+ * @return The Policy.
+ */
+ inline SecPolicy&
+ policy()
+ {
+ if (!policy_)
+ throw Error("policy is not assigned to the KeyChain");
+
+ return *policy_;
+ }
+
+
+ /**
+ * Check the signature on the Data object and call either onVerify or onVerifyFailed.
+ * We use callback functions because verify may fetch information to check the signature.
+ * @param data The Data object with the signature to check. It is an error if data does not have a wireEncoding.
+ * To set the wireEncoding, you can call data.wireDecode.
+ * @param onVerified If the signature is verified, this calls onVerified(data).
+ * @param onVerifyFailed If the signature check fails, this calls onVerifyFailed(data).
+ */
+ void
+ verifyData
+ (const ptr_lib::shared_ptr<Data>& data, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed, int stepCount = 0);
+
+ /*****************************************
+ * verifySignature method set *
+ *****************************************/
+ static bool
+ verifySignature(const Data &data, const Signature &sig, const PublicKey &publicKey);
+
+ static bool
+ verifySignature(const Buffer &data, const Signature &sig, const PublicKey &publicKey);
+
+ static bool
+ verifySignature(const Data& data, const SignatureSha256WithRsa& sig, const PublicKey& publicKey);
+
+ static bool
+ verifySignature(const Buffer &data, const SignatureSha256WithRsa &sig, const PublicKey &publicKey);
+
+public:
+ static const ptr_lib::shared_ptr<SecPolicy> DefaultPolicy;
+
+private:
+ void
+ onCertificateData
+ (const ptr_lib::shared_ptr<const Interest> &interest, const ptr_lib::shared_ptr<Data> &data, ptr_lib::shared_ptr<ValidationRequest> nextStep);
+
+ void
+ onCertificateInterestTimeout
+ (const ptr_lib::shared_ptr<const Interest> &interest, int retry, const OnVerifyFailed& onVerifyFailed,
+ const ptr_lib::shared_ptr<Data> &data, ptr_lib::shared_ptr<ValidationRequest> nextStep);
+
+private:
+ ptr_lib::shared_ptr<SecPolicy> policy_;
+ ptr_lib::shared_ptr<Face> face_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/signature.hpp b/include/ndn-cpp-dev/signature.hpp
new file mode 100644
index 0000000..e38ad3e
--- /dev/null
+++ b/include/ndn-cpp-dev/signature.hpp
@@ -0,0 +1,100 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SIGNATURE_HPP
+#define NDN_SIGNATURE_HPP
+
+namespace ndn {
+
+/**
+ * A Signature is storage for the signature-related information (info and value) in a Data packet.
+ */
+class Signature {
+public:
+ struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+ enum {
+ Sha256 = 0,
+ Sha256WithRsa = 1
+ };
+
+ Signature()
+ : type_(-1)
+ {
+ }
+
+ Signature(const Block &info, const Block &value = Block())
+ : value_(value)
+ {
+ setInfo(info);
+ }
+
+ operator bool() const
+ {
+ return type_ != -1;
+ }
+
+ uint32_t
+ getType() const
+ {
+ return type_;
+ }
+
+ const Block&
+ getInfo() const
+ {
+ info_.encode(); // will do nothing if wire already exists
+ return info_;
+ }
+
+ void
+ setInfo(const Block &info)
+ {
+ info_ = info;
+ if (info_.hasWire() || info_.hasValue())
+ {
+ info_.parse();
+ const Block &signatureType = info_.get(Tlv::SignatureType);
+ type_ = readNonNegativeInteger(signatureType);
+ }
+ else
+ {
+ type_ = -1;
+ }
+ }
+
+ const Block&
+ getValue() const
+ {
+ value_.encode(); // will do nothing if wire already exists
+ return value_;
+ }
+
+ void
+ setValue(const Block &value)
+ {
+ value_ = value;
+ }
+
+ void
+ reset()
+ {
+ type_ = -1;
+ info_.reset();
+ value_.reset();
+ }
+
+protected:
+ int32_t type_;
+
+ mutable Block info_;
+ mutable Block value_;
+};
+
+} // namespace ndn
+
+#endif // NDN_SIGNATURE_HPP
diff --git a/include/ndn-cpp-dev/status-response.hpp b/include/ndn-cpp-dev/status-response.hpp
new file mode 100644
index 0000000..a222951
--- /dev/null
+++ b/include/ndn-cpp-dev/status-response.hpp
@@ -0,0 +1,124 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_STATUS_RESPONSE_HPP
+#define NDN_STATUS_RESPONSE_HPP
+
+#include "encoding/block.hpp"
+#include "encoding/tlv-face-management.hpp"
+
+namespace ndn {
+
+class StatusResponse {
+public:
+ StatusResponse()
+ : code_(0)
+ {
+ }
+
+ StatusResponse(uint32_t code, const std::string &info)
+ : code_(code)
+ , info_(info)
+ {
+ }
+
+ inline uint32_t
+ getCode() const;
+
+ inline void
+ setCode(uint32_t code);
+
+ inline const std::string &
+ getInfo() const;
+
+ inline void
+ setInfo(const std::string &info);
+
+ inline const Block&
+ wireEncode() const;
+
+ inline void
+ wireDecode(const Block &block);
+
+private:
+ uint32_t code_;
+ std::string info_;
+
+ mutable Block wire_;
+};
+
+inline uint32_t
+StatusResponse::getCode() const
+{
+ return code_;
+}
+
+inline void
+StatusResponse::setCode(uint32_t code)
+{
+ code_ = code;
+ wire_.reset();
+}
+
+inline const std::string &
+StatusResponse::getInfo() const
+{
+ return info_;
+}
+
+inline void
+StatusResponse::setInfo(const std::string &info)
+{
+ info_ = info;
+ wire_.reset();
+}
+
+
+inline const Block&
+StatusResponse::wireEncode() const
+{
+ if (wire_.hasWire())
+ return wire_;
+
+ wire_ = Block(Tlv::FaceManagement::StatusResponse);
+ wire_.push_back
+ (nonNegativeIntegerBlock(Tlv::FaceManagement::StatusCode, code_));
+
+ if (!info_.empty())
+ {
+ wire_.push_back
+ (dataBlock(Tlv::FaceManagement::StatusText, info_.c_str(), info_.size()));
+ }
+
+ wire_.encode();
+ return wire_;
+}
+
+inline void
+StatusResponse::wireDecode(const Block &wire)
+{
+ wire_ = wire;
+ wire_.parse();
+
+ code_ = readNonNegativeInteger(wire_.get(Tlv::FaceManagement::StatusCode));
+
+ Block::element_iterator val = wire_.find(Tlv::FaceManagement::StatusText);
+ if (val != wire_.getAll().end())
+ {
+ info_.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
+ }
+}
+
+inline std::ostream&
+operator << (std::ostream &os, const StatusResponse &status)
+{
+ os << status.getCode() << " " << status.getInfo();
+ return os;
+}
+
+}
+
+#endif // NDN_STATUS_RESPONSE_HPP
diff --git a/include/ndn-cpp-dev/transport/transport.hpp b/include/ndn-cpp-dev/transport/transport.hpp
new file mode 100644
index 0000000..ddbff52
--- /dev/null
+++ b/include/ndn-cpp-dev/transport/transport.hpp
@@ -0,0 +1,107 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_TRANSPORT_HPP
+#define NDN_TRANSPORT_HPP
+
+#include <ndn-cpp-dev/common.hpp>
+
+#include <vector>
+#include <boost/asio.hpp>
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+
+class Transport {
+public:
+ struct Error : public std::runtime_error { inline Error(const boost::system::error_code &code, const std::string &msg); };
+
+ typedef ptr_lib::function<void (const Block &wire)> ReceiveCallback;
+ typedef ptr_lib::function<void ()> ErrorCallback;
+
+ inline
+ Transport();
+
+ inline virtual
+ ~Transport();
+
+ /**
+ * Connect transport
+ *
+ * @throws If connection cannot be established
+ */
+ inline virtual void
+ connect(boost::asio::io_service &io_service,
+ const ReceiveCallback &receiveCallback);
+
+ /**
+ * Close the connection.
+ */
+ virtual void
+ close() = 0;
+
+ /**
+ * Set data to the host
+ * @param data A pointer to the buffer of data to send.
+ * @param dataLength The number of bytes in data.
+ */
+ virtual void
+ send(const Block &wire) = 0;
+
+ inline bool
+ isConnected();
+
+protected:
+ inline void
+ receive(const Block &wire);
+
+protected:
+ boost::asio::io_service *ioService_;
+ bool isConnected_;
+ ReceiveCallback receiveCallback_;
+};
+
+inline
+Transport::Transport()
+ : ioService_(0)
+ , isConnected_(false)
+{
+}
+
+inline Transport::Error::Error(const boost::system::error_code &code, const std::string &msg)
+ : std::runtime_error(msg + (code.value() ? " (" + code.category().message(code.value()) + ")" : ""))
+{
+}
+
+inline
+Transport::~Transport()
+{
+}
+
+inline void
+Transport::connect(boost::asio::io_service &ioService,
+ const ReceiveCallback &receiveCallback)
+{
+ ioService_ = &ioService;
+ receiveCallback_ = receiveCallback;
+}
+
+inline bool
+Transport::isConnected()
+{
+ return isConnected_;
+}
+
+inline void
+Transport::receive(const Block &wire)
+{
+ receiveCallback_(wire);
+}
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/transport/unix-transport.hpp b/include/ndn-cpp-dev/transport/unix-transport.hpp
new file mode 100644
index 0000000..c2ee204
--- /dev/null
+++ b/include/ndn-cpp-dev/transport/unix-transport.hpp
@@ -0,0 +1,42 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_UDPTRANSPORT_HPP
+#define NDN_UDPTRANSPORT_HPP
+
+#include <string>
+#include "transport.hpp"
+
+namespace ndn {
+
+class UnixTransport : public Transport
+{
+public:
+ UnixTransport(const std::string &unixSocket = "/tmp/.ndnd.sock");
+ ~UnixTransport();
+
+ // from Transport
+ virtual void
+ connect(boost::asio::io_service &ioService,
+ const ReceiveCallback &receiveCallback);
+
+ virtual void
+ close();
+
+ virtual void
+ send(const Block &wire);
+
+private:
+ std::string unixSocket_;
+
+ class Impl;
+ ptr_lib::shared_ptr<Impl> impl_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/util/blob.hpp b/include/ndn-cpp-dev/util/blob.hpp
new file mode 100644
index 0000000..4de7a02
--- /dev/null
+++ b/include/ndn-cpp-dev/util/blob.hpp
@@ -0,0 +1,112 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_BLOB_HPP
+#define NDN_BLOB_HPP
+
+#include "../common.hpp"
+
+struct ndn_Blob;
+
+namespace ndn {
+
+/**
+ * A Blob holds a pointer to an immutable byte array implemented as const std::vector<uint8_t>.
+ * This is like a JavaScript string which is a pointer to an immutable string.
+ * It is OK to pass a pointer to the string because the new owner can't change the bytes
+ * of the string. However, like a JavaScript string, it is possible to change the pointer, and so this does allow
+ * the copy constructor and assignment to change the pointer. Also remember that the pointer can be null.
+ * (Note that we could have made Blob derive directly from vector<uint8_t> and then explicitly use
+ * a pointer to it like Blob, but this does not enforce immutability because we can't declare
+ * Blob as derived from const vector<uint8_t>.)
+ */
+class Blob : public ptr_lib::shared_ptr<const std::vector<uint8_t> > {
+public:
+ /**
+ * Create a new Blob with a null pointer.
+ */
+ Blob()
+ {
+ }
+
+ /**
+ * Create a new Blob with an immutable copy of the given array.
+ * @param value A pointer to the byte array which is copied.
+ * @param valueLength The length of value.
+ */
+ Blob(const uint8_t* value, size_t valueLength)
+ : ptr_lib::shared_ptr<const std::vector<uint8_t> >(new std::vector<uint8_t>(value, value + valueLength))
+ {
+ }
+
+ /**
+ * Create a new Blob with an immutable copy of the array in the given vector.
+ * If you want to transfer the array without copying, the the vector has to start as a
+ * ptr_lib::shared_ptr<std::vector<uint8_t> > and you can use the Blob constructor with this type.
+ * @param value A reference to a vector which is copied.
+ */
+ Blob(const std::vector<uint8_t> &value)
+ : ptr_lib::shared_ptr<const std::vector<uint8_t> >(new std::vector<uint8_t>(value))
+ {
+ }
+
+ /**
+ * Create a new Blob with an immutable copy of the array in the given Blob struct.
+ * @param blobStruct The C ndn_Blob struct to receive the pointer.
+ */
+ Blob(const struct ndn_Blob& blobStruct);
+
+ /**
+ * Create a new Blob to point to an existing byte array. IMPORTANT: After calling this constructor,
+ * if you keep a pointer to the array then you must treat the array as immutable and promise not to change it.
+ * @param value A pointer to a vector with the byte array. This takes another reference and does not copy the bytes.
+ */
+ Blob(const ptr_lib::shared_ptr<std::vector<uint8_t> > &value)
+ : ptr_lib::shared_ptr<const std::vector<uint8_t> >((const ptr_lib::shared_ptr<const std::vector<uint8_t> > &)value)
+ {
+ }
+ Blob(const ptr_lib::shared_ptr<const std::vector<uint8_t> > &value)
+ : ptr_lib::shared_ptr<const std::vector<uint8_t> >(value)
+ {
+ }
+
+ /**
+ * Return the length of the immutable byte array.
+ */
+ size_t
+ size() const
+ {
+ if (*this)
+ return (*this)->size();
+ else
+ return 0;
+ }
+
+ /**
+ * Return a const pointer to the first byte of the immutable byte array, or 0 if the pointer is null.
+ */
+ const uint8_t*
+ buf() const
+ {
+ if (*this)
+ return &(*this)->front();
+ else
+ return 0;
+ }
+
+ /**
+ * Set the blobStruct to point to this Blob's byte array, without copying any memory.
+ * WARNING: The resulting pointer in blobStruct is invalid after a further use of this object which could reallocate memory.
+ * @param blobStruct The C ndn_Blob struct to receive the pointer.
+ */
+ void
+ get(struct ndn_Blob& blobStruct) const;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp-dev/util/signed-blob.hpp b/include/ndn-cpp-dev/util/signed-blob.hpp
new file mode 100644
index 0000000..1ad2d25
--- /dev/null
+++ b/include/ndn-cpp-dev/util/signed-blob.hpp
@@ -0,0 +1,121 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ * @author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SIGNED_BLOB_HPP
+#define NDN_SIGNED_BLOB_HPP
+
+#include "blob.hpp"
+
+namespace ndn {
+
+/**
+ * A SignedBlob extends Blob to keep the offsets of a signed portion (e.g., the bytes of Data packet).
+ */
+class SignedBlob : public Blob {
+public:
+ /**
+ * Create a new SignedBlob with a null pointer.
+ */
+ SignedBlob()
+ : signedPortionBeginOffset_(0), signedPortionEndOffset_(0)
+ {
+ }
+
+ /**
+ * Create a new SignedBlob with an immutable copy of the given array.
+ * @param value A pointer to the byte array which is copied.
+ * @param valueLength The length of value.
+ * @param signedPortionBeginOffset The offset in the encoding of the beginning of the signed portion.
+ * @param signedPortionEndOffset The offset in the encoding of the end of the signed portion.
+ */
+ SignedBlob
+ (const uint8_t* value, size_t valueLength, size_t signedPortionBeginOffset, size_t signedPortionEndOffset)
+ : Blob(value, valueLength), signedPortionBeginOffset_(signedPortionBeginOffset), signedPortionEndOffset_(signedPortionEndOffset)
+ {
+ }
+
+ /**
+ * Create a new SignedBlob with an immutable copy of the array in the given vector.
+ * If you want to transfer the array without copying, the the vector has to start as a
+ * ptr_lib::shared_ptr<std::vector<uint8_t> > and you can use the SignedBlob constructor with this type.
+ * @param value A reference to a vector which is copied.
+ * @param signedPortionBeginOffset The offset in the encoding of the beginning of the signed portion.
+ * @param signedPortionEndOffset The offset in the encoding of the end of the signed portion.
+ */
+ SignedBlob
+ (const std::vector<uint8_t> &value, size_t signedPortionBeginOffset, size_t signedPortionEndOffset)
+ : Blob(value), signedPortionBeginOffset_(signedPortionBeginOffset), signedPortionEndOffset_(signedPortionEndOffset)
+ {
+ }
+
+ /**
+ * Create a new SignedBlob to point to an existing byte array. IMPORTANT: After calling this constructor,
+ * if you keep a pointer to the array then you must treat the array as immutable and promise not to change it.
+ * @param value A pointer to a vector with the byte array. This takes another reference and does not copy the bytes.
+ * @param signedPortionBeginOffset The offset in the array of the beginning of the signed portion.
+ * @param signedPortionEndOffset The offset in the array of the end of the signed portion.
+ */
+ SignedBlob
+ (const ptr_lib::shared_ptr<std::vector<uint8_t> > &value,
+ size_t signedPortionBeginOffset, size_t signedPortionEndOffset)
+ : Blob(value), signedPortionBeginOffset_(signedPortionBeginOffset), signedPortionEndOffset_(signedPortionEndOffset)
+ {
+ }
+ SignedBlob
+ (const ptr_lib::shared_ptr<const std::vector<uint8_t> > &value,
+ size_t signedPortionBeginOffset, size_t signedPortionEndOffset)
+ : Blob(value), signedPortionBeginOffset_(signedPortionBeginOffset), signedPortionEndOffset_(signedPortionEndOffset)
+ {
+ }
+
+ /**
+ * Return the length of the signed portion of the immutable byte array, or 0 of the pointer to the array is null.
+ */
+ size_t
+ signedSize() const
+ {
+ if (*this)
+ return signedPortionEndOffset_ - signedPortionBeginOffset_;
+ else
+ return 0;
+ }
+
+ /**
+ * Return a const pointer to the first byte of the signed portion of the immutable byte array, or 0 if the
+ * pointer to the array is null.
+ */
+ const uint8_t*
+ signedBuf() const
+ {
+ if (*this)
+ return &(*this)->front() + signedPortionBeginOffset_;
+ else
+ return 0;
+ }
+
+ /**
+ * Return the offset in the array of the beginning of the signed portion.
+ */
+ size_t
+ getSignedPortionBeginOffset() const { return signedPortionBeginOffset_; }
+
+ /**
+ * Return the offset in the array of the end of the signed portion.
+ */
+ size_t
+ getSignedPortionEndOffset() const { return signedPortionEndOffset_; }
+
+private:
+ size_t signedPortionBeginOffset_;
+ size_t signedPortionEndOffset_;
+};
+
+}
+
+#endif