ndnSIM实现添加自定义字段–自定义域(二)

实现自定义域,在原有的数据包或兴趣包结构上添加字段,两种修改的方式一致,本次演示实现修改数据包,兴趣包的方式与数据包一致。需要修改如下文件:

  • ns-3/src/ndnSIM/ndn-cxx/ndn-cxx/data.hpp
  • ns-3/src/ndnSIM/ndn-cxx/ndn-cxx/data.cpp
  • ns-3/src/ndnSIM/ndn-cxx/ndn-cxx/encoding/tlv.hpp

1.修改tlv

首先,打开tlv.hpp,在第一个enum中加入Soure = 40,如下红色字体所示

enum {
  Interest                        = 5,
  Data                            = 6,
  Name                            = 7,
  GenericNameComponent            = 8,
  ImplicitSha256DigestComponent   = 1,
  ParametersSha256DigestComponent = 2,
  CanBePrefix                     = 33,
  MustBeFresh                     = 18,
  ForwardingHint                  = 30,
  Nonce                           = 10,
  InterestLifetime                = 12,
  HopLimit                        = 34,
  Parameters                      = 35,
  MetaInfo                        = 20,
  Content                         = 21,
  SignatureInfo                   = 22,
  SignatureValue                  = 23,
  ContentType                     = 24,
  FreshnessPeriod                 = 25,
  FinalBlockId                    = 26,
  SignatureType                   = 27,
  KeyLocator                      = 28,
  KeyDigest                       = 29,
  LinkDelegation                  = 31,
  LinkPreference                  = 30,
  Source                          = 40,    //添加字段
  NameComponentMin = 1,
  NameComponentMax = 65535,
  

  AppPrivateBlock1 = 128,
  AppPrivateBlock2 = 32767
};

2.实现Set和Get函数

打开data.hpp,首先在字段列表中加入source字段。

private:
  int m_source;   //添加字段
  Name m_name;
  MetaInfo m_metaInfo;
  Block m_content;
  Signature m_signature;

  mutable Block m_wire;
  mutable Name m_fullName; ///< cached FullName computed from m_wire
};

然后,参照其他字段加入getter和setter函数。

  const int&
  getSource()const
  {
    return m_source;
  }
  Data&
  setSource(const int& source);

在data.cpp中实现setter函数。

Data&
Data::setSource(const int& source)
{
  resetWire();
  m_source=source;
  return *this;
}

3.实现变量的编码与解码

在data.cpp中,需要对新增的Source变量增加编码和解码方法。

编码wireEncode函数,仅需要在代码中加入一个语句即可,详见下方代码中的红色部分。这里Source是整数,因此使用prependNonNegativeIntegerBlock()函数,其他数据类型可以在ns-3/src/ndnSIM/ndn-cxx/src/encoding/block-helpers.hpp和.cpp中查找。

Data::wireEncode(EncodingImpl<TAG>& encoder, bool wantUnsignedPortionOnly) const
{
  size_t totalLength = 0;

  // SignatureValue
  if (!wantUnsignedPortionOnly) {
    if (!m_signature) {
      BOOST_THROW_EXCEPTION(Error("Requested wire format, but Data has not been signed"));
    }
    totalLength += encoder.prependBlock(m_signature.getValue());
  }

  // SignatureInfo
  totalLength += encoder.prependBlock(m_signature.getInfo());
  
  //Source
  totalLength += prependNonNegativeIntegerBlock(encoder,tlv::Source,getSource());

  // Content
  totalLength += encoder.prependBlock(getContent());

  // MetaInfo
  totalLength += getMetaInfo().wireEncode(encoder);

  // Name
  totalLength += getName().wireEncode(encoder);

  if (!wantUnsignedPortionOnly) {
    totalLength += encoder.prependVarNumber(totalLength);
    totalLength += encoder.prependVarNumber(tlv::Data);
  }
  return totalLength;
}

解码wireDecode函数,对于整型的Source使用readNonNegativeInteger()方法获得具体值并放在字段source中,即实现了解码(如红色部分所示)。

void
Data::wireDecode(const Block& wire)
{
  m_wire = wire;
  m_wire.parse();
  auto element = m_wire.elements_begin();
  if (element == m_wire.elements_end() || element->type() != tlv::Name) {
    BOOST_THROW_EXCEPTION(Error("Name element is missing or out of order"));
  }
  m_name.wireDecode(*element);
  int lastElement = 1; // last recognized element index, in spec order
  m_metaInfo = MetaInfo();
  m_content = Block(tlv::Content);
  m_signature = Signature();
  m_fullName.clear();

  for (++element; element != m_wire.elements_end(); ++element) {
    switch (element->type()) {
      case tlv::MetaInfo: {
        if (lastElement >= 2) {
          BOOST_THROW_EXCEPTION(Error("MetaInfo element is out of order"));
        }
        m_metaInfo.wireDecode(*element);
        lastElement = 2;
        break;
      }
      case tlv::Content: {
        if (lastElement >= 3) {
          BOOST_THROW_EXCEPTION(Error("Content element is out of order"));
        }
        m_content = *element;
        lastElement = 3;
        break;
      }
      case tlv::SignatureInfo: {
        if (lastElement >= 4) {
          BOOST_THROW_EXCEPTION(Error("SignatureInfo element is out of order"));
        }
        m_signature.setInfo(*element);
        lastElement = 4;
        break;
      }
      case tlv::SignatureValue: {
        if (lastElement >= 5) {
          BOOST_THROW_EXCEPTION(Error("SignatureValue element is out of order"));
        }
        m_signature.setValue(*element);
        lastElement = 5;
        break;
      }
      default: {
        if (tlv::isCriticalType(element->type())) {
          BOOST_THROW_EXCEPTION(Error("unrecognized element of critical type " +
                                      to_string(element->type())));
        }
         m_source=readNonNegativeInteger(*element);
        break;
      }
    }
  }
}

4.测试

首先在producer中准备数据包时,即函数OnInterest(),调用刚刚实现的setter函数,将source设置为某值。

auto data = make_shared();
data->setName((*iter).name);
data->setFreshnessPeriod(::ndn::time::milliseconds(m_freshness.GetMilliSeconds()));
data->setContent(make_shared< ::ndn::Buffer>(m_virtualPayloadSize));
data->setSource(100);

然后在forwarder.cpp的onIncomingData()中将这个值打印出来即可。

void
Forwarder::onIncomingData(Face& inFace, const Data& data)
{
  int node = ns3::Simulator::GetContext();
  cout<<"node "<<node<<" get data with field value "<<data.getSource()<<endl;
  ...
}

最后运行代码,可诶看到如下结果:

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇