181 lines
5.1 KiB
C++
181 lines
5.1 KiB
C++
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
|
/**
|
|
* Copyright (C) 2014 Named Data Networking Project
|
|
* See COPYING for copyright and distribution information.
|
|
*/
|
|
|
|
#ifndef NFD_FACE_LOCAL_FACE_HPP
|
|
#define NFD_FACE_LOCAL_FACE_HPP
|
|
|
|
#include "face.hpp"
|
|
|
|
namespace nfd {
|
|
|
|
/* \brief indicates a feature in LocalControlHeader
|
|
*/
|
|
enum LocalControlHeaderFeature
|
|
{
|
|
/// any feature
|
|
LOCAL_CONTROL_HEADER_FEATURE_ANY,
|
|
/// in-faceid
|
|
LOCAL_CONTROL_HEADER_FEATURE_IN_FACEID,
|
|
/// out-faceid
|
|
LOCAL_CONTROL_HEADER_FEATURE_NEXTHOP_FACEID,
|
|
/// upper bound of enum
|
|
LOCAL_CONTROL_HEADER_FEATURE_MAX
|
|
};
|
|
|
|
|
|
/** \brief represents a face
|
|
*/
|
|
class LocalFace : public Face
|
|
{
|
|
public:
|
|
explicit
|
|
LocalFace(const FaceUri& uri);
|
|
|
|
/** \brief get whether a LocalControlHeader feature is enabled
|
|
*
|
|
* \param feature The feature. Cannot be LOCAL_CONTROL_HEADER_FEATURE_MAX
|
|
* LOCAL_CONTROL_HEADER_FEATURE_ANY returns true if any feature is enabled.
|
|
*/
|
|
bool
|
|
isLocalControlHeaderEnabled(LocalControlHeaderFeature feature =
|
|
LOCAL_CONTROL_HEADER_FEATURE_ANY) const;
|
|
|
|
/** \brief enable or disable a LocalControlHeader feature
|
|
*
|
|
* \param feature The feature. Cannot be LOCAL_CONTROL_HEADER_FEATURE_ANY
|
|
* or LOCAL_CONTROL_HEADER_FEATURE_MAX
|
|
*/
|
|
void
|
|
setLocalControlHeaderFeature(LocalControlHeaderFeature feature, bool enabled = true);
|
|
|
|
protected:
|
|
// statically overridden from Face
|
|
|
|
/** \brief Decode block into Interest/Data, considering potential LocalControlHeader
|
|
*
|
|
* If LocalControlHeader is present, the encoded data is filtered out, based
|
|
* on enabled features on the face.
|
|
*/
|
|
bool
|
|
decodeAndDispatchInput(const Block& element);
|
|
|
|
// LocalFace-specific methods
|
|
|
|
/** \brief Check if LocalControlHeader needs to be included, taking into account
|
|
* both set parameters in supplied LocalControlHeader and features
|
|
* enabled on the local face.
|
|
*/
|
|
bool
|
|
isEmptyFilteredLocalControlHeader(const ndn::nfd::LocalControlHeader& header) const;
|
|
|
|
/** \brief Create LocalControlHeader, considering enabled features
|
|
*/
|
|
template<class Packet>
|
|
Block
|
|
filterAndEncodeLocalControlHeader(const Packet& packet);
|
|
|
|
private:
|
|
std::vector<bool> m_localControlHeaderFeatures;
|
|
};
|
|
|
|
inline
|
|
LocalFace::LocalFace(const FaceUri& uri)
|
|
: Face(uri, true)
|
|
, m_localControlHeaderFeatures(LOCAL_CONTROL_HEADER_FEATURE_MAX)
|
|
{
|
|
}
|
|
|
|
inline bool
|
|
LocalFace::isLocalControlHeaderEnabled(LocalControlHeaderFeature feature) const
|
|
{
|
|
BOOST_ASSERT(feature < m_localControlHeaderFeatures.size());
|
|
return m_localControlHeaderFeatures[feature];
|
|
}
|
|
|
|
inline void
|
|
LocalFace::setLocalControlHeaderFeature(LocalControlHeaderFeature feature, bool enabled/* = true*/)
|
|
{
|
|
BOOST_ASSERT(feature > LOCAL_CONTROL_HEADER_FEATURE_ANY &&
|
|
feature < m_localControlHeaderFeatures.size());
|
|
m_localControlHeaderFeatures[feature] = enabled;
|
|
|
|
BOOST_STATIC_ASSERT(LOCAL_CONTROL_HEADER_FEATURE_ANY == 0);
|
|
m_localControlHeaderFeatures[LOCAL_CONTROL_HEADER_FEATURE_ANY] =
|
|
std::find(m_localControlHeaderFeatures.begin() + 1,
|
|
m_localControlHeaderFeatures.end(), true) <
|
|
m_localControlHeaderFeatures.end();
|
|
// 'find(..) < .end()' instead of 'find(..) != .end()' due to LLVM Bug 16816
|
|
}
|
|
|
|
inline bool
|
|
LocalFace::decodeAndDispatchInput(const Block& element)
|
|
{
|
|
const Block& payload = ndn::nfd::LocalControlHeader::getPayload(element);
|
|
|
|
// If received LocalControlHeader, but it is not enabled on the face
|
|
if ((&payload != &element) && !this->isLocalControlHeaderEnabled())
|
|
return false;
|
|
|
|
if (payload.type() == tlv::Interest)
|
|
{
|
|
shared_ptr<Interest> i = make_shared<Interest>();
|
|
i->wireDecode(payload);
|
|
if (&payload != &element)
|
|
{
|
|
i->getLocalControlHeader().wireDecode(element,
|
|
false,
|
|
this->isLocalControlHeaderEnabled(LOCAL_CONTROL_HEADER_FEATURE_NEXTHOP_FACEID));
|
|
}
|
|
|
|
this->onReceiveInterest(*i);
|
|
}
|
|
else if (payload.type() == tlv::Data)
|
|
{
|
|
shared_ptr<Data> d = make_shared<Data>();
|
|
d->wireDecode(payload);
|
|
|
|
/// \todo Uncomment and correct the following when we have more
|
|
/// options in LocalControlHeader that apply for incoming
|
|
/// Data packets (if ever)
|
|
// if (&payload != &element)
|
|
// {
|
|
//
|
|
// d->getLocalControlHeader().wireDecode(element,
|
|
// false,
|
|
// false);
|
|
// }
|
|
|
|
this->onReceiveData(*d);
|
|
}
|
|
else
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
inline bool
|
|
LocalFace::isEmptyFilteredLocalControlHeader(const ndn::nfd::LocalControlHeader& header) const
|
|
{
|
|
if (!this->isLocalControlHeaderEnabled())
|
|
return true;
|
|
|
|
return header.empty(this->isLocalControlHeaderEnabled(LOCAL_CONTROL_HEADER_FEATURE_IN_FACEID),
|
|
false);
|
|
}
|
|
|
|
template<class Packet>
|
|
inline Block
|
|
LocalFace::filterAndEncodeLocalControlHeader(const Packet& packet)
|
|
{
|
|
return packet.getLocalControlHeader().wireEncode(packet,
|
|
this->isLocalControlHeaderEnabled(LOCAL_CONTROL_HEADER_FEATURE_IN_FACEID),
|
|
false);
|
|
}
|
|
|
|
} // namespace nfd
|
|
|
|
#endif // NFD_FACE_LOCAL_FACE_HPP
|