merge
authorGustavo J. A. M. Carneiro <gjc@inescporto.pt>
Tue Jun 09 18:00:52 2009 +0100 (9 months ago)
changeset 4559c9bdb91e40cb
parent 4558 f9509a42bc87
parent 4541 4d3213e6eecd
child 4560 8566a9f6725a
merge
src/common/tag-list.cc
src/common/tag-list.h
     1.1 --- a/AUTHORS	Tue Jun 09 18:00:24 2009 +0100
     1.2 +++ b/AUTHORS	Tue Jun 09 18:00:52 2009 +0100
     1.3 @@ -1,3 +1,5 @@
     1.4 +Nicola Baldo (nbaldo@cttc.es)
     1.5 +Mirko Banchi (mk.banchi@gmail.com)
     1.6  Raj Bhattacharjea (raj.b@gatech.edu)
     1.7  Gustavo Carneiro (gjc@inescporto.pt, gjcarneiro@gmail.com)
     1.8  Craig Dowell (craigdo@ee.washington.edu)
     1.9 @@ -24,4 +26,5 @@
    1.10  Liu Jian (liujatp@gmail.com)
    1.11  Andrey Hippo (ahippo@yandex.ru)
    1.12  Francesco Malandrino (francesco.malandrino@gmail.com)
    1.13 -
    1.14 +Faker Moatamri (faker.moatamri@sophia.inria.fr)
    1.15 +Guangyu Pei (guangyu.pei@boeing.com)
     2.1 --- a/CHANGES.html	Tue Jun 09 18:00:24 2009 +0100
     2.2 +++ b/CHANGES.html	Tue Jun 09 18:00:52 2009 +0100
     2.3 @@ -51,16 +51,82 @@
     2.4  </ul>
     2.5  
     2.6  <h2>New API:</h2>
     2.7 +
     2.8  <ul>
     2.9 +<li><b>YansWifiPhyHelper supporting radiotap and prism PCAP output</b>
    2.10 +<p>The newly supported pcap formats can be adopted by calling the following new method of YansWifiPhyHelper:</p>
    2.11 +<pre>
    2.12 + +  void SetPcapFormat (enum PcapFormat format);
    2.13 +</pre>
    2.14 +where format is one of PCAP_FORMAT_80211_RADIOTAP, PCAP_FORMAT_80211_PRISM or  PCAP_FORMAT_80211. By default, PCAP_FORMAT_80211 is used, so the default PCAP format is the same as before.</p>
    2.15 +</li>
    2.16 +
    2.17  <li> <b>attributes for class Ipv4</b>
    2.18  <p> class Ipv4 now contains attributes in ipv4.cc; the first one
    2.19  is called "IpForward" that will enable/disable Ipv4 forwarding.  
    2.20  </li>
    2.21 +
    2.22 +<li> <b>packet tags</b>
    2.23 +<p>class Packet now contains AddPacketTag, RemovePacketTag and PeekPacketTag 
    2.24 +which can be used to attach a tag to a packet, as opposed to the old 
    2.25 +AddTag method which attached a tag to a set of bytes. The main 
    2.26 +semantic difference is in how these tags behave in the presence of 
    2.27 +fragmentation and reassembly.
    2.28 +</li>
    2.29 +
    2.30  </ul>
    2.31  
    2.32  <h2>Changes to existing API:</h2>
    2.33  <ul>
    2.34  
    2.35 +<li> <b>packet byte tags renaming</b>
    2.36 +  <ul>
    2.37 +  <li>Packet::AddTag to Packet::AddByteTag</li>
    2.38 +  <li>Packet::FindFirstMatchingTag to Packet::FindFirstMatchingByteTag</li>
    2.39 +  <li>Packet::RemoveAllTags to Packet::RemoveAllByteTags</li>
    2.40 +  <li>Packet::PrintTags to Packet::PrintByteTags</li>
    2.41 +  <li>Packet::GetTagIterator to Packet::GetByteTagIterator</li>
    2.42 +  </ul>
    2.43 +</li>
    2.44 +
    2.45 +<li><b>YansWifiPhyHelper::EnablePcap* methods not static any more</b>
    2.46 +<p>To accommodate the possibility of configuring the PCAP format used for wifi promiscuous mode traces, several methods of YansWifiPhyHelper had to be made non-static:
    2.47 +<pre>
    2.48 +-  static void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid);
    2.49 ++         void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid);
    2.50 +-  static void EnablePcap (std::string filename, Ptr<NetDevice> nd);
    2.51 ++         void EnablePcap (std::string filename, Ptr<NetDevice> nd);
    2.52 +-  static void EnablePcap (std::string filename, std::string ndName);
    2.53 ++         void EnablePcap (std::string filename, std::string ndName);
    2.54 +-  static void EnablePcap (std::string filename, NetDeviceContainer d);
    2.55 ++         void EnablePcap (std::string filename, NetDeviceContainer d);
    2.56 +-  static void EnablePcap (std::string filename, NodeContainer n);
    2.57 ++         void EnablePcap (std::string filename, NodeContainer n);
    2.58 +-  static void EnablePcapAll (std::string filename);
    2.59 ++         void EnablePcapAll (std::string filename);
    2.60 +</pre>
    2.61 +</p>
    2.62 +</li>
    2.63 +
    2.64 +<li><b>Wifi Promisc Sniff interface modified </b>
    2.65 +<p> 
    2.66 +To accommodate support for the radiotap and prism headers in PCAP traces, the interface for promiscuos mode sniff in the wifi device was changed. The new implementation was heavily inspired by the way the madwifi driver handles monitor mode. A distinction between TX and RX events is introduced, to account for the fact that different information is to be put in the radiotap/prism header (e.g., RSSI and noise make sense only for RX packets). The following are the relevant modifications to the WifiPhy class:
    2.67 +<pre>
    2.68 +-  void NotifyPromiscSniff (Ptr<const Packet> packet);
    2.69 ++  void NotifyPromiscSniffRx (Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble, double signalDbm, double noiseDbm);
    2.70 ++  void NotifyPromiscSniffTx (Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble);
    2.71 +-  TracedCallback<Ptr<const Packet> > m_phyPromiscSnifferTrace;
    2.72 ++  TracedCallback<Ptr<const Packet>, uint16_t, uint32_t, bool, double, double> m_phyPromiscSniffRxTrace;
    2.73 ++  TracedCallback<Ptr<const Packet>, uint16_t, uint32_t, bool> m_phyPromiscSniffTxTrace;
    2.74 +</pre>
    2.75 +The above mentioned callbacks are expected to be used to call the following method to write Wifi PCAP traces in promiscuous mode:
    2.76 +<pre>
    2.77 ++  void WriteWifiMonitorPacket(Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble, bool isTx, double signalDbm, double noiseDbm);
    2.78 +</pre>
    2.79 +In the above method, the isTx parameter is to be used to differentiate between TX and RX packets. For an example of how to implement these callbacks, see the implementation of PcapSniffTxEvent and PcapSniffRxEvent in src/helper/yans-wifi-helper.cc
    2.80 +</p>
    2.81 +</li>
    2.82 +
    2.83  <li><b> Routing decoupled from class Ipv4</b>
    2.84  <p> All calls of the form "Ipv4::AddHostRouteTo ()" etc. (i.e. to 
    2.85  add static routes, both unicast and multicast) have been moved to a new 
     3.1 --- a/RELEASE_NOTES	Tue Jun 09 18:00:24 2009 +0100
     3.2 +++ b/RELEASE_NOTES	Tue Jun 09 18:00:52 2009 +0100
     3.3 @@ -25,6 +25,7 @@
     3.4    b) 802.11 PHY:
     3.5       - 802.11b PHY support (Gary Pei)
     3.6       - Nakagami propagation loss model (Timo Bingmann)
     3.7 +     - radiotap and prism headers for PCAP output (Nicola Baldo)
     3.8    c) GammaVariable and ErlangVariable (Timo Bingmann)
     3.9   
    3.10  API changes from ns-3.4
     4.1 --- a/bindings/python/ns3_module_common.py	Tue Jun 09 18:00:24 2009 +0100
     4.2 +++ b/bindings/python/ns3_module_common.py	Tue Jun 09 18:00:52 2009 +0100
     4.3 @@ -9,6 +9,16 @@
     4.4      module.add_class('Buffer')
     4.5      ## buffer.h: ns3::Buffer::Iterator [class]
     4.6      module.add_class('Iterator', outer_class=root_module['ns3::Buffer'])
     4.7 +    ## packet.h: ns3::ByteTagIterator [class]
     4.8 +    module.add_class('ByteTagIterator')
     4.9 +    ## packet.h: ns3::ByteTagIterator::Item [class]
    4.10 +    module.add_class('Item', outer_class=root_module['ns3::ByteTagIterator'])
    4.11 +    ## byte-tag-list.h: ns3::ByteTagList [class]
    4.12 +    module.add_class('ByteTagList')
    4.13 +    ## byte-tag-list.h: ns3::ByteTagList::Iterator [class]
    4.14 +    module.add_class('Iterator', outer_class=root_module['ns3::ByteTagList'])
    4.15 +    ## byte-tag-list.h: ns3::ByteTagList::Iterator::Item [struct]
    4.16 +    module.add_class('Item', outer_class=root_module['ns3::ByteTagList::Iterator'])
    4.17      ## data-rate.h: ns3::DataRate [class]
    4.18      module.add_class('DataRate')
    4.19      ## packet.h: ns3::Packet [class]
    4.20 @@ -21,20 +31,18 @@
    4.21      module.add_enum('', ['PAYLOAD', 'HEADER', 'TRAILER'], outer_class=root_module['ns3::PacketMetadata::Item'])
    4.22      ## packet-metadata.h: ns3::PacketMetadata::ItemIterator [class]
    4.23      module.add_class('ItemIterator', outer_class=root_module['ns3::PacketMetadata'])
    4.24 +    ## packet.h: ns3::PacketTagIterator [class]
    4.25 +    module.add_class('PacketTagIterator')
    4.26 +    ## packet.h: ns3::PacketTagIterator::Item [class]
    4.27 +    module.add_class('Item', outer_class=root_module['ns3::PacketTagIterator'])
    4.28 +    ## packet-tag-list.h: ns3::PacketTagList [class]
    4.29 +    module.add_class('PacketTagList')
    4.30 +    ## packet-tag-list.h: ns3::PacketTagList::TagData [struct]
    4.31 +    module.add_class('TagData', outer_class=root_module['ns3::PacketTagList'])
    4.32      ## tag.h: ns3::Tag [class]
    4.33      module.add_class('Tag', parent=root_module['ns3::ObjectBase'])
    4.34      ## tag-buffer.h: ns3::TagBuffer [class]
    4.35      module.add_class('TagBuffer')
    4.36 -    ## packet.h: ns3::TagIterator [class]
    4.37 -    module.add_class('TagIterator')
    4.38 -    ## packet.h: ns3::TagIterator::Item [class]
    4.39 -    module.add_class('Item', outer_class=root_module['ns3::TagIterator'])
    4.40 -    ## tag-list.h: ns3::TagList [class]
    4.41 -    module.add_class('TagList')
    4.42 -    ## tag-list.h: ns3::TagList::Iterator [class]
    4.43 -    module.add_class('Iterator', outer_class=root_module['ns3::TagList'])
    4.44 -    ## tag-list.h: ns3::TagList::Iterator::Item [struct]
    4.45 -    module.add_class('Item', outer_class=root_module['ns3::TagList::Iterator'])
    4.46      ## chunk.h: ns3::Chunk [class]
    4.47      module.add_class('Chunk', parent=root_module['ns3::ObjectBase'])
    4.48      ## data-rate.h: ns3::DataRateChecker [class]
    4.49 @@ -107,18 +115,22 @@
    4.50  def register_methods(root_module):
    4.51      register_Ns3Buffer_methods(root_module, root_module['ns3::Buffer'])
    4.52      register_Ns3BufferIterator_methods(root_module, root_module['ns3::Buffer::Iterator'])
    4.53 +    register_Ns3ByteTagIterator_methods(root_module, root_module['ns3::ByteTagIterator'])
    4.54 +    register_Ns3ByteTagIteratorItem_methods(root_module, root_module['ns3::ByteTagIterator::Item'])
    4.55 +    register_Ns3ByteTagList_methods(root_module, root_module['ns3::ByteTagList'])
    4.56 +    register_Ns3ByteTagListIterator_methods(root_module, root_module['ns3::ByteTagList::Iterator'])
    4.57 +    register_Ns3ByteTagListIteratorItem_methods(root_module, root_module['ns3::ByteTagList::Iterator::Item'])
    4.58      register_Ns3DataRate_methods(root_module, root_module['ns3::DataRate'])
    4.59      register_Ns3Packet_methods(root_module, root_module['ns3::Packet'])
    4.60      register_Ns3PacketMetadata_methods(root_module, root_module['ns3::PacketMetadata'])
    4.61      register_Ns3PacketMetadataItem_methods(root_module, root_module['ns3::PacketMetadata::Item'])
    4.62      register_Ns3PacketMetadataItemIterator_methods(root_module, root_module['ns3::PacketMetadata::ItemIterator'])
    4.63 +    register_Ns3PacketTagIterator_methods(root_module, root_module['ns3::PacketTagIterator'])
    4.64 +    register_Ns3PacketTagIteratorItem_methods(root_module, root_module['ns3::PacketTagIterator::Item'])
    4.65 +    register_Ns3PacketTagList_methods(root_module, root_module['ns3::PacketTagList'])
    4.66 +    register_Ns3PacketTagListTagData_methods(root_module, root_module['ns3::PacketTagList::TagData'])
    4.67      register_Ns3Tag_methods(root_module, root_module['ns3::Tag'])
    4.68      register_Ns3TagBuffer_methods(root_module, root_module['ns3::TagBuffer'])
    4.69 -    register_Ns3TagIterator_methods(root_module, root_module['ns3::TagIterator'])
    4.70 -    register_Ns3TagIteratorItem_methods(root_module, root_module['ns3::TagIterator::Item'])
    4.71 -    register_Ns3TagList_methods(root_module, root_module['ns3::TagList'])
    4.72 -    register_Ns3TagListIterator_methods(root_module, root_module['ns3::TagList::Iterator'])
    4.73 -    register_Ns3TagListIteratorItem_methods(root_module, root_module['ns3::TagList::Iterator::Item'])
    4.74      register_Ns3Chunk_methods(root_module, root_module['ns3::Chunk'])
    4.75      register_Ns3DataRateChecker_methods(root_module, root_module['ns3::DataRateChecker'])
    4.76      register_Ns3DataRateValue_methods(root_module, root_module['ns3::DataRateValue'])
    4.77 @@ -191,6 +203,11 @@
    4.78                     'int32_t', 
    4.79                     [], 
    4.80                     is_const=True)
    4.81 +    ## buffer.h: void ns3::Buffer::CopyData(std::ostream * os, uint32_t size) const [member function]
    4.82 +    cls.add_method('CopyData', 
    4.83 +                   'void', 
    4.84 +                   [param('std::ostream *', 'os'), param('uint32_t', 'size')], 
    4.85 +                   is_const=True)
    4.86      ## buffer.h: ns3::Buffer::Buffer(ns3::Buffer const & o) [copy constructor]
    4.87      cls.add_constructor([param('ns3::Buffer const &', 'o')])
    4.88      ## buffer.h: ns3::Buffer::Buffer() [constructor]
    4.89 @@ -346,6 +363,113 @@
    4.90                     is_const=True)
    4.91      return
    4.92  
    4.93 +def register_Ns3ByteTagIterator_methods(root_module, cls):
    4.94 +    ## packet.h: ns3::ByteTagIterator::ByteTagIterator(ns3::ByteTagIterator const & arg0) [copy constructor]
    4.95 +    cls.add_constructor([param('ns3::ByteTagIterator const &', 'arg0')])
    4.96 +    ## packet.h: bool ns3::ByteTagIterator::HasNext() const [member function]
    4.97 +    cls.add_method('HasNext', 
    4.98 +                   'bool', 
    4.99 +                   [], 
   4.100 +                   is_const=True)
   4.101 +    ## packet.h: ns3::ByteTagIterator::Item ns3::ByteTagIterator::Next() [member function]
   4.102 +    cls.add_method('Next', 
   4.103 +                   'ns3::ByteTagIterator::Item', 
   4.104 +                   [])
   4.105 +    return
   4.106 +
   4.107 +def register_Ns3ByteTagIteratorItem_methods(root_module, cls):
   4.108 +    ## packet.h: ns3::ByteTagIterator::Item::Item(ns3::ByteTagIterator::Item const & arg0) [copy constructor]
   4.109 +    cls.add_constructor([param('ns3::ByteTagIterator::Item const &', 'arg0')])
   4.110 +    ## packet.h: ns3::TypeId ns3::ByteTagIterator::Item::GetTypeId() const [member function]
   4.111 +    cls.add_method('GetTypeId', 
   4.112 +                   'ns3::TypeId', 
   4.113 +                   [], 
   4.114 +                   is_const=True)
   4.115 +    ## packet.h: uint32_t ns3::ByteTagIterator::Item::GetStart() const [member function]
   4.116 +    cls.add_method('GetStart', 
   4.117 +                   'uint32_t', 
   4.118 +                   [], 
   4.119 +                   is_const=True)
   4.120 +    ## packet.h: uint32_t ns3::ByteTagIterator::Item::GetEnd() const [member function]
   4.121 +    cls.add_method('GetEnd', 
   4.122 +                   'uint32_t', 
   4.123 +                   [], 
   4.124 +                   is_const=True)
   4.125 +    ## packet.h: void ns3::ByteTagIterator::Item::GetTag(ns3::Tag & tag) const [member function]
   4.126 +    cls.add_method('GetTag', 
   4.127 +                   'void', 
   4.128 +                   [param('ns3::Tag &', 'tag')], 
   4.129 +                   is_const=True)
   4.130 +    return
   4.131 +
   4.132 +def register_Ns3ByteTagList_methods(root_module, cls):
   4.133 +    ## byte-tag-list.h: ns3::ByteTagList::ByteTagList() [constructor]
   4.134 +    cls.add_constructor([])
   4.135 +    ## byte-tag-list.h: ns3::ByteTagList::ByteTagList(ns3::ByteTagList const & o) [copy constructor]
   4.136 +    cls.add_constructor([param('ns3::ByteTagList const &', 'o')])
   4.137 +    ## byte-tag-list.h: ns3::TagBuffer ns3::ByteTagList::Add(ns3::TypeId tid, uint32_t bufferSize, int32_t start, int32_t end) [member function]
   4.138 +    cls.add_method('Add', 
   4.139 +                   'ns3::TagBuffer', 
   4.140 +                   [param('ns3::TypeId', 'tid'), param('uint32_t', 'bufferSize'), param('int32_t', 'start'), param('int32_t', 'end')])
   4.141 +    ## byte-tag-list.h: void ns3::ByteTagList::Add(ns3::ByteTagList const & o) [member function]
   4.142 +    cls.add_method('Add', 
   4.143 +                   'void', 
   4.144 +                   [param('ns3::ByteTagList const &', 'o')])
   4.145 +    ## byte-tag-list.h: void ns3::ByteTagList::RemoveAll() [member function]
   4.146 +    cls.add_method('RemoveAll', 
   4.147 +                   'void', 
   4.148 +                   [])
   4.149 +    ## byte-tag-list.h: ns3::ByteTagList::Iterator ns3::ByteTagList::Begin(int32_t offsetStart, int32_t offsetEnd) const [member function]
   4.150 +    cls.add_method('Begin', 
   4.151 +                   'ns3::ByteTagList::Iterator', 
   4.152 +                   [param('int32_t', 'offsetStart'), param('int32_t', 'offsetEnd')], 
   4.153 +                   is_const=True)
   4.154 +    ## byte-tag-list.h: void ns3::ByteTagList::AddAtEnd(int32_t adjustment, int32_t appendOffset) [member function]
   4.155 +    cls.add_method('AddAtEnd', 
   4.156 +                   'void', 
   4.157 +                   [param('int32_t', 'adjustment'), param('int32_t', 'appendOffset')])
   4.158 +    ## byte-tag-list.h: void ns3::ByteTagList::AddAtStart(int32_t adjustment, int32_t prependOffset) [member function]
   4.159 +    cls.add_method('AddAtStart', 
   4.160 +                   'void', 
   4.161 +                   [param('int32_t', 'adjustment'), param('int32_t', 'prependOffset')])
   4.162 +    return
   4.163 +
   4.164 +def register_Ns3ByteTagListIterator_methods(root_module, cls):
   4.165 +    ## byte-tag-list.h: ns3::ByteTagList::Iterator::Iterator(ns3::ByteTagList::Iterator const & arg0) [copy constructor]
   4.166 +    cls.add_constructor([param('ns3::ByteTagList::Iterator const &', 'arg0')])
   4.167 +    ## byte-tag-list.h: bool ns3::ByteTagList::Iterator::HasNext() const [member function]
   4.168 +    cls.add_method('HasNext', 
   4.169 +                   'bool', 
   4.170 +                   [], 
   4.171 +                   is_const=True)
   4.172 +    ## byte-tag-list.h: ns3::ByteTagList::Iterator::Item ns3::ByteTagList::Iterator::Next() [member function]
   4.173 +    cls.add_method('Next', 
   4.174 +                   'ns3::ByteTagList::Iterator::Item', 
   4.175 +                   [])
   4.176 +    ## byte-tag-list.h: uint32_t ns3::ByteTagList::Iterator::GetOffsetStart() const [member function]
   4.177 +    cls.add_method('GetOffsetStart', 
   4.178 +                   'uint32_t', 
   4.179 +                   [], 
   4.180 +                   is_const=True)
   4.181 +    return
   4.182 +
   4.183 +def register_Ns3ByteTagListIteratorItem_methods(root_module, cls):
   4.184 +    ## byte-tag-list.h: ns3::ByteTagList::Iterator::Item::tid [variable]
   4.185 +    cls.add_instance_attribute('tid', 'ns3::TypeId', is_const=False)
   4.186 +    ## byte-tag-list.h: ns3::ByteTagList::Iterator::Item::size [variable]
   4.187 +    cls.add_instance_attribute('size', 'uint32_t', is_const=False)
   4.188 +    ## byte-tag-list.h: ns3::ByteTagList::Iterator::Item::start [variable]
   4.189 +    cls.add_instance_attribute('start', 'int32_t', is_const=False)
   4.190 +    ## byte-tag-list.h: ns3::ByteTagList::Iterator::Item::end [variable]
   4.191 +    cls.add_instance_attribute('end', 'int32_t', is_const=False)
   4.192 +    ## byte-tag-list.h: ns3::ByteTagList::Iterator::Item::buf [variable]
   4.193 +    cls.add_instance_attribute('buf', 'ns3::TagBuffer', is_const=False)
   4.194 +    ## byte-tag-list.h: ns3::ByteTagList::Iterator::Item::Item(ns3::ByteTagList::Iterator::Item const & arg0) [copy constructor]
   4.195 +    cls.add_constructor([param('ns3::ByteTagList::Iterator::Item const &', 'arg0')])
   4.196 +    ## byte-tag-list.h: ns3::ByteTagList::Iterator::Item::Item(ns3::TagBuffer buf) [constructor]
   4.197 +    cls.add_constructor([param('ns3::TagBuffer', 'buf')])
   4.198 +    return
   4.199 +
   4.200  def register_Ns3DataRate_methods(root_module, cls):
   4.201      cls.add_output_stream_operator()
   4.202      cls.add_binary_comparison_operator('!=')
   4.203 @@ -388,19 +512,24 @@
   4.204      cls.add_method('AddAtEnd', 
   4.205                     'void', 
   4.206                     [param('ns3::Ptr< ns3::Packet const >', 'packet')])
   4.207 +    ## packet.h: void ns3::Packet::AddByteTag(ns3::Tag const & tag) const [member function]
   4.208 +    cls.add_method('AddByteTag', 
   4.209 +                   'void', 
   4.210 +                   [param('ns3::Tag const &', 'tag')], 
   4.211 +                   is_const=True)
   4.212      ## packet.h: void ns3::Packet::AddHeader(ns3::Header const & header) [member function]
   4.213      cls.add_method('AddHeader', 
   4.214                     'void', 
   4.215                     [param('ns3::Header const &', 'header')])
   4.216 +    ## packet.h: void ns3::Packet::AddPacketTag(ns3::Tag const & tag) const [member function]
   4.217 +    cls.add_method('AddPacketTag', 
   4.218 +                   'void', 
   4.219 +                   [param('ns3::Tag const &', 'tag')], 
   4.220 +                   is_const=True)
   4.221      ## packet.h: void ns3::Packet::AddPaddingAtEnd(uint32_t size) [member function]
   4.222      cls.add_method('AddPaddingAtEnd', 
   4.223                     'void', 
   4.224                     [param('uint32_t', 'size')])
   4.225 -    ## packet.h: void ns3::Packet::AddTag(ns3::Tag const & tag) const [member function]
   4.226 -    cls.add_method('AddTag', 
   4.227 -                   'void', 
   4.228 -                   [param('ns3::Tag const &', 'tag')], 
   4.229 -                   is_const=True)
   4.230      ## packet.h: void ns3::Packet::AddTrailer(ns3::Trailer const & trailer) [member function]
   4.231      cls.add_method('AddTrailer', 
   4.232                     'void', 
   4.233 @@ -420,6 +549,11 @@
   4.234                     'uint32_t', 
   4.235                     [param('uint8_t *', 'buffer'), param('uint32_t', 'size')], 
   4.236                     is_const=True)
   4.237 +    ## packet.h: void ns3::Packet::CopyData(std::ostream * os, uint32_t size) const [member function]
   4.238 +    cls.add_method('CopyData', 
   4.239 +                   'void', 
   4.240 +                   [param('std::ostream *', 'os'), param('uint32_t', 'size')], 
   4.241 +                   is_const=True)
   4.242      ## packet.h: ns3::Ptr<ns3::Packet> ns3::Packet::CreateFragment(uint32_t start, uint32_t length) const [member function]
   4.243      cls.add_method('CreateFragment', 
   4.244                     'ns3::Ptr< ns3::Packet >', 
   4.245 @@ -439,21 +573,26 @@
   4.246                     'void', 
   4.247                     [], 
   4.248                     is_static=True)
   4.249 -    ## packet.h: bool ns3::Packet::FindFirstMatchingTag(ns3::Tag & tag) const [member function]
   4.250 -    cls.add_method('FindFirstMatchingTag', 
   4.251 +    ## packet.h: bool ns3::Packet::FindFirstMatchingByteTag(ns3::Tag & tag) const [member function]
   4.252 +    cls.add_method('FindFirstMatchingByteTag', 
   4.253                     'bool', 
   4.254                     [param('ns3::Tag &', 'tag')], 
   4.255                     is_const=True)
   4.256 +    ## packet.h: ns3::ByteTagIterator ns3::Packet::GetByteTagIterator() const [member function]
   4.257 +    cls.add_method('GetByteTagIterator', 
   4.258 +                   'ns3::ByteTagIterator', 
   4.259 +                   [], 
   4.260 +                   is_const=True)
   4.261 +    ## packet.h: ns3::PacketTagIterator ns3::Packet::GetPacketTagIterator() const [member function]
   4.262 +    cls.add_method('GetPacketTagIterator', 
   4.263 +                   'ns3::PacketTagIterator', 
   4.264 +                   [], 
   4.265 +                   is_const=True)
   4.266      ## packet.h: uint32_t ns3::Packet::GetSize() const [member function]
   4.267      cls.add_method('GetSize', 
   4.268                     'uint32_t', 
   4.269                     [], 
   4.270                     is_const=True)
   4.271 -    ## packet.h: ns3::TagIterator ns3::Packet::GetTagIterator() const [member function]
   4.272 -    cls.add_method('GetTagIterator', 
   4.273 -                   'ns3::TagIterator', 
   4.274 -                   [], 
   4.275 -                   is_const=True)
   4.276      ## packet.h: uint32_t ns3::Packet::GetUid() const [member function]
   4.277      cls.add_method('GetUid', 
   4.278                     'uint32_t', 
   4.279 @@ -469,6 +608,11 @@
   4.280                     'uint32_t', 
   4.281                     [param('ns3::Header &', 'header')], 
   4.282                     is_const=True)
   4.283 +    ## packet.h: bool ns3::Packet::PeekPacketTag(ns3::Tag & tag) const [member function]
   4.284 +    cls.add_method('PeekPacketTag', 
   4.285 +                   'bool', 
   4.286 +                   [param('ns3::Tag &', 'tag')], 
   4.287 +                   is_const=True)
   4.288      ## packet.h: uint32_t ns3::Packet::PeekTrailer(ns3::Trailer & trailer) [member function]
   4.289      cls.add_method('PeekTrailer', 
   4.290                     'uint32_t', 
   4.291 @@ -478,13 +622,22 @@
   4.292                     'void', 
   4.293                     [param('std::ostream &', 'os')], 
   4.294                     is_const=True)
   4.295 -    ## packet.h: void ns3::Packet::PrintTags(std::ostream & os) const [member function]
   4.296 -    cls.add_method('PrintTags', 
   4.297 +    ## packet.h: void ns3::Packet::PrintByteTags(std::ostream & os) const [member function]
   4.298 +    cls.add_method('PrintByteTags', 
   4.299                     'void', 
   4.300                     [param('std::ostream &', 'os')], 
   4.301                     is_const=True)
   4.302 -    ## packet.h: void ns3::Packet::RemoveAllTags() [member function]
   4.303 -    cls.add_method('RemoveAllTags', 
   4.304 +    ## packet.h: void ns3::Packet::PrintPacketTags(std::ostream & os) const [member function]
   4.305 +    cls.add_method('PrintPacketTags', 
   4.306 +                   'void', 
   4.307 +                   [param('std::ostream &', 'os')], 
   4.308 +                   is_const=True)
   4.309 +    ## packet.h: void ns3::Packet::RemoveAllByteTags() [member function]
   4.310 +    cls.add_method('RemoveAllByteTags', 
   4.311 +                   'void', 
   4.312 +                   [])
   4.313 +    ## packet.h: void ns3::Packet::RemoveAllPacketTags() [member function]
   4.314 +    cls.add_method('RemoveAllPacketTags', 
   4.315                     'void', 
   4.316                     [])
   4.317      ## packet.h: void ns3::Packet::RemoveAtEnd(uint32_t size) [member function]
   4.318 @@ -499,6 +652,10 @@
   4.319      cls.add_method('RemoveHeader', 
   4.320                     'uint32_t', 
   4.321                     [param('ns3::Header &', 'header')])
   4.322 +    ## packet.h: bool ns3::Packet::RemovePacketTag(ns3::Tag & tag) [member function]
   4.323 +    cls.add_method('RemovePacketTag', 
   4.324 +                   'bool', 
   4.325 +                   [param('ns3::Tag &', 'tag')])
   4.326      ## packet.h: uint32_t ns3::Packet::RemoveTrailer(ns3::Trailer & trailer) [member function]
   4.327      cls.add_method('RemoveTrailer', 
   4.328                     'uint32_t', 
   4.329 @@ -623,6 +780,80 @@
   4.330                     [])
   4.331      return
   4.332  
   4.333 +def register_Ns3PacketTagIterator_methods(root_module, cls):
   4.334 +    ## packet.h: ns3::PacketTagIterator::PacketTagIterator(ns3::PacketTagIterator const & arg0) [copy constructor]
   4.335 +    cls.add_constructor([param('ns3::PacketTagIterator const &', 'arg0')])
   4.336 +    ## packet.h: bool ns3::PacketTagIterator::HasNext() const [member function]
   4.337 +    cls.add_method('HasNext', 
   4.338 +                   'bool', 
   4.339 +                   [], 
   4.340 +                   is_const=True)
   4.341 +    ## packet.h: ns3::PacketTagIterator::Item ns3::PacketTagIterator::Next() [member function]
   4.342 +    cls.add_method('Next', 
   4.343 +                   'ns3::PacketTagIterator::Item', 
   4.344 +                   [])
   4.345 +    return
   4.346 +
   4.347 +def register_Ns3PacketTagIteratorItem_methods(root_module, cls):
   4.348 +    ## packet.h: ns3::PacketTagIterator::Item::Item(ns3::PacketTagIterator::Item const & arg0) [copy constructor]
   4.349 +    cls.add_constructor([param('ns3::PacketTagIterator::Item const &', 'arg0')])
   4.350 +    ## packet.h: ns3::TypeId ns3::PacketTagIterator::Item::GetTypeId() const [member function]
   4.351 +    cls.add_method('GetTypeId', 
   4.352 +                   'ns3::TypeId', 
   4.353 +                   [], 
   4.354 +                   is_const=True)
   4.355 +    ## packet.h: void ns3::PacketTagIterator::Item::GetTag(ns3::Tag & tag) const [member function]
   4.356 +    cls.add_method('GetTag', 
   4.357 +                   'void', 
   4.358 +                   [param('ns3::Tag &', 'tag')], 
   4.359 +                   is_const=True)
   4.360 +    return
   4.361 +
   4.362 +def register_Ns3PacketTagList_methods(root_module, cls):
   4.363 +    ## packet-tag-list.h: ns3::PacketTagList::PacketTagList() [constructor]
   4.364 +    cls.add_constructor([])
   4.365 +    ## packet-tag-list.h: ns3::PacketTagList::PacketTagList(ns3::PacketTagList const & o) [copy constructor]
   4.366 +    cls.add_constructor([param('ns3::PacketTagList const &', 'o')])
   4.367 +    ## packet-tag-list.h: void ns3::PacketTagList::Add(ns3::Tag const & tag) const [member function]
   4.368 +    cls.add_method('Add', 
   4.369 +                   'void', 
   4.370 +                   [param('ns3::Tag const &', 'tag')], 
   4.371 +                   is_const=True)
   4.372 +    ## packet-tag-list.h: bool ns3::PacketTagList::Remove(ns3::Tag & tag) [member function]
   4.373 +    cls.add_method('Remove', 
   4.374 +                   'bool', 
   4.375 +                   [param('ns3::Tag &', 'tag')])
   4.376 +    ## packet-tag-list.h: bool ns3::PacketTagList::Peek(ns3::Tag & tag) const [member function]
   4.377 +    cls.add_method('Peek', 
   4.378 +                   'bool', 
   4.379 +                   [param('ns3::Tag &', 'tag')], 
   4.380 +                   is_const=True)
   4.381 +    ## packet-tag-list.h: void ns3::PacketTagList::RemoveAll() [member function]
   4.382 +    cls.add_method('RemoveAll', 
   4.383 +                   'void', 
   4.384 +                   [])
   4.385 +    ## packet-tag-list.h: ns3::PacketTagList::TagData const * ns3::PacketTagList::Head() const [member function]
   4.386 +    cls.add_method('Head', 
   4.387 +                   'ns3::PacketTagList::TagData const *', 
   4.388 +                   [], 
   4.389 +                   is_const=True)
   4.390 +    return
   4.391 +
   4.392 +def register_Ns3PacketTagListTagData_methods(root_module, cls):
   4.393 +    ## packet-tag-list.h: ns3::PacketTagList::TagData::data [variable]
   4.394 +    cls.add_instance_attribute('data', 'uint8_t [ 20 ]', is_const=False)
   4.395 +    ## packet-tag-list.h: ns3::PacketTagList::TagData::next [variable]
   4.396 +    cls.add_instance_attribute('next', 'ns3::PacketTagList::TagData *', is_const=False)
   4.397 +    ## packet-tag-list.h: ns3::PacketTagList::TagData::tid [variable]
   4.398 +    cls.add_instance_attribute('tid', 'ns3::TypeId', is_const=False)
   4.399 +    ## packet-tag-list.h: ns3::PacketTagList::TagData::count [variable]
   4.400 +    cls.add_instance_attribute('count', 'uint32_t', is_const=False)
   4.401 +    ## packet-tag-list.h: ns3::PacketTagList::TagData::TagData(ns3::PacketTagList::TagData const & arg0) [copy constructor]
   4.402 +    cls.add_constructor([param('ns3::PacketTagList::TagData const &', 'arg0')])
   4.403 +    ## packet-tag-list.h: ns3::PacketTagList::TagData::TagData() [constructor]
   4.404 +    cls.add_constructor([])
   4.405 +    return
   4.406 +
   4.407  def register_Ns3Tag_methods(root_module, cls):
   4.408      ## tag.h: ns3::Tag::Tag(ns3::Tag const & arg0) [copy constructor]
   4.409      cls.add_constructor([param('ns3::Tag const &', 'arg0')])
   4.410 @@ -718,113 +949,6 @@
   4.411                     [param('uint8_t *', 'buffer'), param('uint32_t', 'size')])
   4.412      return
   4.413  
   4.414 -def register_Ns3TagIterator_methods(root_module, cls):
   4.415 -    ## packet.h: ns3::TagIterator::TagIterator(ns3::TagIterator const & arg0) [copy constructor]
   4.416 -    cls.add_constructor([param('ns3::TagIterator const &', 'arg0')])
   4.417 -    ## packet.h: bool ns3::TagIterator::HasNext() const [member function]
   4.418 -    cls.add_method('HasNext', 
   4.419 -                   'bool', 
   4.420 -                   [], 
   4.421 -                   is_const=True)
   4.422 -    ## packet.h: ns3::TagIterator::Item ns3::TagIterator::Next() [member function]
   4.423 -    cls.add_method('Next', 
   4.424 -                   'ns3::TagIterator::Item', 
   4.425 -                   [])
   4.426 -    return
   4.427 -
   4.428 -def register_Ns3TagIteratorItem_methods(root_module, cls):
   4.429 -    ## packet.h: ns3::TagIterator::Item::Item(ns3::TagIterator::Item const & arg0) [copy constructor]
   4.430 -    cls.add_constructor([param('ns3::TagIterator::Item const &', 'arg0')])
   4.431 -    ## packet.h: ns3::TypeId ns3::TagIterator::Item::GetTypeId() const [member function]
   4.432 -    cls.add_method('GetTypeId', 
   4.433 -                   'ns3::TypeId', 
   4.434 -                   [], 
   4.435 -                   is_const=True)
   4.436 -    ## packet.h: uint32_t ns3::TagIterator::Item::GetStart() const [member function]
   4.437 -    cls.add_method('GetStart', 
   4.438 -                   'uint32_t', 
   4.439 -                   [], 
   4.440 -                   is_const=True)
   4.441 -    ## packet.h: uint32_t ns3::TagIterator::Item::GetEnd() const [member function]
   4.442 -    cls.add_method('GetEnd', 
   4.443 -                   'uint32_t', 
   4.444 -                   [], 
   4.445 -                   is_const=True)
   4.446 -    ## packet.h: void ns3::TagIterator::Item::GetTag(ns3::Tag & tag) const [member function]
   4.447 -    cls.add_method('GetTag', 
   4.448 -                   'void', 
   4.449 -                   [param('ns3::Tag &', 'tag')], 
   4.450 -                   is_const=True)
   4.451 -    return
   4.452 -
   4.453 -def register_Ns3TagList_methods(root_module, cls):
   4.454 -    ## tag-list.h: ns3::TagList::TagList() [constructor]
   4.455 -    cls.add_constructor([])
   4.456 -    ## tag-list.h: ns3::TagList::TagList(ns3::TagList const & o) [copy constructor]
   4.457 -    cls.add_constructor([param('ns3::TagList const &', 'o')])
   4.458 -    ## tag-list.h: ns3::TagBuffer ns3::TagList::Add(ns3::TypeId tid, uint32_t bufferSize, int32_t start, int32_t end) [member function]
   4.459 -    cls.add_method('Add', 
   4.460 -                   'ns3::TagBuffer', 
   4.461 -                   [param('ns3::TypeId', 'tid'), param('uint32_t', 'bufferSize'), param('int32_t', 'start'), param('int32_t', 'end')])
   4.462 -    ## tag-list.h: void ns3::TagList::Add(ns3::TagList const & o) [member function]
   4.463 -    cls.add_method('Add', 
   4.464 -                   'void', 
   4.465 -                   [param('ns3::TagList const &', 'o')])
   4.466 -    ## tag-list.h: void ns3::TagList::RemoveAll() [member function]
   4.467 -    cls.add_method('RemoveAll', 
   4.468 -                   'void', 
   4.469 -                   [])
   4.470 -    ## tag-list.h: ns3::TagList::Iterator ns3::TagList::Begin(int32_t offsetStart, int32_t offsetEnd) const [member function]
   4.471 -    cls.add_method('Begin', 
   4.472 -                   'ns3::TagList::Iterator', 
   4.473 -                   [param('int32_t', 'offsetStart'), param('int32_t', 'offsetEnd')], 
   4.474 -                   is_const=True)
   4.475 -    ## tag-list.h: void ns3::TagList::AddAtEnd(int32_t adjustment, int32_t appendOffset) [member function]
   4.476 -    cls.add_method('AddAtEnd', 
   4.477 -                   'void', 
   4.478 -                   [param('int32_t', 'adjustment'), param('int32_t', 'appendOffset')])
   4.479 -    ## tag-list.h: void ns3::TagList::AddAtStart(int32_t adjustment, int32_t prependOffset) [member function]
   4.480 -    cls.add_method('AddAtStart', 
   4.481 -                   'void', 
   4.482 -                   [param('int32_t', 'adjustment'), param('int32_t', 'prependOffset')])
   4.483 -    return
   4.484 -
   4.485 -def register_Ns3TagListIterator_methods(root_module, cls):
   4.486 -    ## tag-list.h: ns3::TagList::Iterator::Iterator(ns3::TagList::Iterator const & arg0) [copy constructor]
   4.487 -    cls.add_constructor([param('ns3::TagList::Iterator const &', 'arg0')])
   4.488 -    ## tag-list.h: bool ns3::TagList::Iterator::HasNext() const [member function]
   4.489 -    cls.add_method('HasNext', 
   4.490 -                   'bool', 
   4.491 -                   [], 
   4.492 -                   is_const=True)
   4.493 -    ## tag-list.h: ns3::TagList::Iterator::Item ns3::TagList::Iterator::Next() [member function]
   4.494 -    cls.add_method('Next', 
   4.495 -                   'ns3::TagList::Iterator::Item', 
   4.496 -                   [])
   4.497 -    ## tag-list.h: uint32_t ns3::TagList::Iterator::GetOffsetStart() const [member function]
   4.498 -    cls.add_method('GetOffsetStart', 
   4.499 -                   'uint32_t', 
   4.500 -                   [], 
   4.501 -                   is_const=True)
   4.502 -    return
   4.503 -
   4.504 -def register_Ns3TagListIteratorItem_methods(root_module, cls):
   4.505 -    ## tag-list.h: ns3::TagList::Iterator::Item::tid [variable]
   4.506 -    cls.add_instance_attribute('tid', 'ns3::TypeId', is_const=False)
   4.507 -    ## tag-list.h: ns3::TagList::Iterator::Item::size [variable]
   4.508 -    cls.add_instance_attribute('size', 'uint32_t', is_const=False)
   4.509 -    ## tag-list.h: ns3::TagList::Iterator::Item::start [variable]
   4.510 -    cls.add_instance_attribute('start', 'int32_t', is_const=False)
   4.511 -    ## tag-list.h: ns3::TagList::Iterator::Item::end [variable]
   4.512 -    cls.add_instance_attribute('end', 'int32_t', is_const=False)
   4.513 -    ## tag-list.h: ns3::TagList::Iterator::Item::buf [variable]
   4.514 -    cls.add_instance_attribute('buf', 'ns3::TagBuffer', is_const=False)
   4.515 -    ## tag-list.h: ns3::TagList::Iterator::Item::Item(ns3::TagList::Iterator::Item const & arg0) [copy constructor]
   4.516 -    cls.add_constructor([param('ns3::TagList::Iterator::Item const &', 'arg0')])
   4.517 -    ## tag-list.h: ns3::TagList::Iterator::Item::Item(ns3::TagBuffer buf) [constructor]
   4.518 -    cls.add_constructor([param('ns3::TagBuffer', 'buf')])
   4.519 -    return
   4.520 -
   4.521  def register_Ns3Chunk_methods(root_module, cls):
   4.522      ## chunk.h: ns3::Chunk::Chunk(ns3::Chunk const & arg0) [copy constructor]
   4.523      cls.add_constructor([param('ns3::Chunk const &', 'arg0')])
   4.524 @@ -941,6 +1065,14 @@
   4.525      cls.add_method('WriteWifiHeader', 
   4.526                     'void', 
   4.527                     [])
   4.528 +    ## pcap-writer.h: void ns3::PcapWriter::WriteWifiRadiotapHeader() [member function]
   4.529 +    cls.add_method('WriteWifiRadiotapHeader', 
   4.530 +                   'void', 
   4.531 +                   [])
   4.532 +    ## pcap-writer.h: void ns3::PcapWriter::WriteWifiPrismHeader() [member function]
   4.533 +    cls.add_method('WriteWifiPrismHeader', 
   4.534 +                   'void', 
   4.535 +                   [])
   4.536      ## pcap-writer.h: void ns3::PcapWriter::WritePppHeader() [member function]
   4.537      cls.add_method('WritePppHeader', 
   4.538                     'void', 
   4.539 @@ -949,6 +1081,10 @@
   4.540      cls.add_method('WritePacket', 
   4.541                     'void', 
   4.542                     [param('ns3::Ptr< ns3::Packet const >', 'packet')])
   4.543 +    ## pcap-writer.h: void ns3::PcapWriter::WriteWifiMonitorPacket(ns3::Ptr<ns3::Packet const> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble, bool isTx, double signalDbm, double noiseDbm) [member function]
   4.544 +    cls.add_method('WriteWifiMonitorPacket', 
   4.545 +                   'void', 
   4.546 +                   [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint16_t', 'channelFreqMhz'), param('uint32_t', 'rate'), param('bool', 'isShortPreamble'), param('bool', 'isTx'), param('double', 'signalDbm'), param('double', 'noiseDbm')])
   4.547      return
   4.548  
   4.549  def register_Ns3Trailer_methods(root_module, cls):
     5.1 --- a/bindings/python/ns3_module_core.py	Tue Jun 09 18:00:24 2009 +0100
     5.2 +++ b/bindings/python/ns3_module_core.py	Tue Jun 09 18:00:52 2009 +0100
     5.3 @@ -495,10 +495,10 @@
     5.4      cls.add_constructor([param('ns3::Names const &', 'arg0')])
     5.5      ## names.h: ns3::Names::Names() [constructor]
     5.6      cls.add_constructor([])
     5.7 -    ## names.h: static void ns3::Names::Add(std::string name, ns3::Ptr<ns3::Object> obj) [member function]
     5.8 +    ## names.h: static void ns3::Names::Add(std::string name, ns3::Ptr<ns3::Object> object) [member function]
     5.9      cls.add_method('Add', 
    5.10                     'void', 
    5.11 -                   [param('std::string', 'name'), param('ns3::Ptr< ns3::Object >', 'obj')], 
    5.12 +                   [param('std::string', 'name'), param('ns3::Ptr< ns3::Object >', 'object')], 
    5.13                     is_static=True)
    5.14      ## names.h: static void ns3::Names::Add(std::string path, std::string name, ns3::Ptr<ns3::Object> object) [member function]
    5.15      cls.add_method('Add', 
    5.16 @@ -2043,7 +2043,7 @@
    5.17      cls.add_method('ConnectWithoutContext', 
    5.18                     'void', 
    5.19                     [param('ns3::CallbackBase const &', 'cb')])
    5.20 -    ## traced-value.h: void ns3::TracedValue<unsigned int>::Connect(ns3::CallbackBase const & cb, std::basic_string<char,std::char_traits<char>,std::allocator<char> > path) [member function]
    5.21 +    ## traced-value.h: void ns3::TracedValue<unsigned int>::Connect(ns3::CallbackBase const & cb, std::string path) [member function]
    5.22      cls.add_method('Connect', 
    5.23                     'void', 
    5.24                     [param('ns3::CallbackBase const &', 'cb'), param('std::string', 'path')])
    5.25 @@ -2051,7 +2051,7 @@
    5.26      cls.add_method('DisconnectWithoutContext', 
    5.27                     'void', 
    5.28                     [param('ns3::CallbackBase const &', 'cb')])
    5.29 -    ## traced-value.h: void ns3::TracedValue<unsigned int>::Disconnect(ns3::CallbackBase const & cb, std::basic_string<char,std::char_traits<char>,std::allocator<char> > path) [member function]
    5.30 +    ## traced-value.h: void ns3::TracedValue<unsigned int>::Disconnect(ns3::CallbackBase const & cb, std::string path) [member function]
    5.31      cls.add_method('Disconnect', 
    5.32                     'void', 
    5.33                     [param('ns3::CallbackBase const &', 'cb'), param('std::string', 'path')])
    5.34 @@ -2199,7 +2199,7 @@
    5.35      module.add_function('TypeNameGet', 
    5.36                          'std::string', 
    5.37                          [], 
    5.38 -                        template_parameters=['long'])
    5.39 +                        template_parameters=['long long'])
    5.40      ## type-name.h: extern std::string ns3::TypeNameGet() [free function]
    5.41      module.add_function('TypeNameGet', 
    5.42                          'std::string', 
    5.43 @@ -2219,7 +2219,7 @@
    5.44      module.add_function('TypeNameGet', 
    5.45                          'std::string', 
    5.46                          [], 
    5.47 -                        template_parameters=['unsigned long'])
    5.48 +                        template_parameters=['unsigned long long'])
    5.49      ## type-name.h: extern std::string ns3::TypeNameGet() [free function]
    5.50      module.add_function('TypeNameGet', 
    5.51                          'std::string', 
     6.1 --- a/bindings/python/ns3_module_helper.py	Tue Jun 09 18:00:24 2009 +0100
     6.2 +++ b/bindings/python/ns3_module_helper.py	Tue Jun 09 18:00:52 2009 +0100
     6.3 @@ -55,6 +55,8 @@
     6.4      module.add_class('YansWifiChannelHelper', allow_subclassing=False)
     6.5      ## yans-wifi-helper.h: ns3::YansWifiPhyHelper [class]
     6.6      module.add_class('YansWifiPhyHelper', allow_subclassing=False, parent=root_module['ns3::WifiPhyHelper'])
     6.7 +    ## yans-wifi-helper.h: ns3::YansWifiPhyHelper::PcapFormat [enumeration]
     6.8 +    module.add_enum('PcapFormat', ['PCAP_FORMAT_80211', 'PCAP_FORMAT_80211_PRISM', 'PCAP_FORMAT_80211_RADIOTAP'], outer_class=root_module['ns3::YansWifiPhyHelper'])
     6.9      ## nqos-wifi-mac-helper.h: ns3::NqosWifiMacHelper [class]
    6.10      module.add_class('NqosWifiMacHelper', allow_subclassing=False, parent=root_module['ns3::WifiMacHelper'])
    6.11      ## qos-wifi-mac-helper.h: ns3::QosWifiMacHelper [class]
    6.12 @@ -1160,36 +1162,34 @@
    6.13      cls.add_method('SetErrorRateModel', 
    6.14                     'void', 
    6.15                     [param('std::string', 'name'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue const &', 'v0', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue const &', 'v5', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue const &', 'v6', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue const &', 'v7', default_value='ns3::EmptyAttributeValue()')])
    6.16 -    ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function]
    6.17 +    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::SetPcapFormat(ns3::YansWifiPhyHelper::PcapFormat format) [member function]
    6.18 +    cls.add_method('SetPcapFormat', 
    6.19 +                   'void', 
    6.20 +                   [param('ns3::YansWifiPhyHelper::PcapFormat', 'format')])
    6.21 +    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function]
    6.22      cls.add_method('EnablePcap', 
    6.23                     'void', 
    6.24 -                   [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], 
    6.25 -                   is_static=True)
    6.26 -    ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::Ptr<ns3::NetDevice> nd) [member function]
    6.27 +                   [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')])
    6.28 +    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::Ptr<ns3::NetDevice> nd) [member function]
    6.29      cls.add_method('EnablePcap', 
    6.30                     'void', 
    6.31 -                   [param('std::string', 'filename'), param('ns3::Ptr< ns3::NetDevice >', 'nd')], 
    6.32 -                   is_static=True)
    6.33 -    ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, std::string ndName) [member function]
    6.34 +                   [param('std::string', 'filename'), param('ns3::Ptr< ns3::NetDevice >', 'nd')])
    6.35 +    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, std::string ndName) [member function]
    6.36      cls.add_method('EnablePcap', 
    6.37                     'void', 
    6.38 -                   [param('std::string', 'filename'), param('std::string', 'ndName')], 
    6.39 -                   is_static=True)
    6.40 -    ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function]
    6.41 +                   [param('std::string', 'filename'), param('std::string', 'ndName')])
    6.42 +    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function]
    6.43      cls.add_method('EnablePcap', 
    6.44                     'void', 
    6.45 -                   [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')], 
    6.46 -                   is_static=True)
    6.47 -    ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function]
    6.48 +                   [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')])
    6.49 +    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function]
    6.50      cls.add_method('EnablePcap', 
    6.51                     'void', 
    6.52 -                   [param('std::string', 'filename'), param('ns3::NodeContainer', 'n')], 
    6.53 -                   is_static=True)
    6.54 -    ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnablePcapAll(std::string filename) [member function]
    6.55 +                   [param('std::string', 'filename'), param('ns3::NodeContainer', 'n')])
    6.56 +    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcapAll(std::string filename) [member function]
    6.57      cls.add_method('EnablePcapAll', 
    6.58                     'void', 
    6.59 -                   [param('std::string', 'filename')], 
    6.60 -                   is_static=True)
    6.61 +                   [param('std::string', 'filename')])
    6.62      ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function]
    6.63      cls.add_method('EnableAscii', 
    6.64                     'void', 
     7.1 --- a/bindings/python/ns3_module_internet_stack.py	Tue Jun 09 18:00:24 2009 +0100
     7.2 +++ b/bindings/python/ns3_module_internet_stack.py	Tue Jun 09 18:00:52 2009 +0100
     7.3 @@ -181,10 +181,10 @@
     7.4                     'uint16_t', 
     7.5                     [], 
     7.6                     is_const=True)
     7.7 -    ## icmpv4.h: ns3::Ptr<ns3::Packet const> ns3::Icmpv4Echo::GetData() const [member function]
     7.8 +    ## icmpv4.h: uint32_t ns3::Icmpv4Echo::GetData(uint8_t * payload) const [member function]
     7.9      cls.add_method('GetData', 
    7.10 -                   'ns3::Ptr< ns3::Packet const >', 
    7.11 -                   [], 
    7.12 +                   'uint32_t', 
    7.13 +                   [param('uint8_t *', 'payload')], 
    7.14                     is_const=True)
    7.15      ## icmpv4.h: static ns3::TypeId ns3::Icmpv4Echo::GetTypeId() [member function]
    7.16      cls.add_method('GetTypeId', 
     8.1 --- a/bindings/python/ns3_module_node.py	Tue Jun 09 18:00:24 2009 +0100
     8.2 +++ b/bindings/python/ns3_module_node.py	Tue Jun 09 18:00:52 2009 +0100
     8.3 @@ -1443,10 +1443,10 @@
     8.4                     'ns3::Ipv4Address', 
     8.5                     [], 
     8.6                     is_const=True)
     8.7 -    ## ipv4-route.h: void ns3::Ipv4MulticastRoute::SetOrigin(ns3::Ipv4Address const group) [member function]
     8.8 +    ## ipv4-route.h: void ns3::Ipv4MulticastRoute::SetOrigin(ns3::Ipv4Address const origin) [member function]
     8.9      cls.add_method('SetOrigin', 
    8.10                     'void', 
    8.11 -                   [param('ns3::Ipv4Address const', 'group')])
    8.12 +                   [param('ns3::Ipv4Address const', 'origin')])
    8.13      ## ipv4-route.h: ns3::Ipv4Address ns3::Ipv4MulticastRoute::GetOrigin() const [member function]
    8.14      cls.add_method('GetOrigin', 
    8.15                     'ns3::Ipv4Address', 
     9.1 --- a/bindings/python/ns3_module_olsr.py	Tue Jun 09 18:00:24 2009 +0100
     9.2 +++ b/bindings/python/ns3_module_olsr.py	Tue Jun 09 18:00:52 2009 +0100
     9.3 @@ -102,13 +102,13 @@
     9.4      module.add_container('std::vector< ns3::olsr::MessageHeader::Hello::LinkMessage >', 'ns3::olsr::MessageHeader::Hello::LinkMessage', container_type='vector')
     9.5      module.add_container('std::vector< ns3::olsr::MessageHeader::Hna::Association >', 'ns3::olsr::MessageHeader::Hna::Association', container_type='vector')
     9.6      typehandlers.add_type_alias('std::vector< ns3::olsr::DuplicateTuple, std::allocator< ns3::olsr::DuplicateTuple > >', 'ns3::olsr::DuplicateSet')
     9.7 -    typehandlers.add_type_alias('std::vector< ns3::olsr::TopologyTuple, std::allocator< ns3::olsr::TopologyTuple > >', 'ns3::olsr::TopologySet')
     9.8      typehandlers.add_type_alias('std::set< ns3::Ipv4Address, std::less< ns3::Ipv4Address >, std::allocator< ns3::Ipv4Address > >', 'ns3::olsr::MprSet')
     9.9      typehandlers.add_type_alias('std::vector< ns3::olsr::MprSelectorTuple, std::allocator< ns3::olsr::MprSelectorTuple > >', 'ns3::olsr::MprSelectorSet')
    9.10      typehandlers.add_type_alias('std::vector< ns3::olsr::MessageHeader, std::allocator< ns3::olsr::MessageHeader > >', 'ns3::olsr::MessageList')
    9.11      typehandlers.add_type_alias('std::vector< ns3::olsr::IfaceAssocTuple, std::allocator< ns3::olsr::IfaceAssocTuple > >', 'ns3::olsr::IfaceAssocSet')
    9.12      typehandlers.add_type_alias('std::vector< ns3::olsr::NeighborTuple, std::allocator< ns3::olsr::NeighborTuple > >', 'ns3::olsr::NeighborSet')
    9.13      typehandlers.add_type_alias('std::vector< ns3::olsr::TwoHopNeighborTuple, std::allocator< ns3::olsr::TwoHopNeighborTuple > >', 'ns3::olsr::TwoHopNeighborSet')
    9.14 +    typehandlers.add_type_alias('std::vector< ns3::olsr::TopologyTuple, std::allocator< ns3::olsr::TopologyTuple > >', 'ns3::olsr::TopologySet')
    9.15      typehandlers.add_type_alias('std::vector< ns3::olsr::LinkTuple, std::allocator< ns3::olsr::LinkTuple > >', 'ns3::olsr::LinkSet')
    9.16  
    9.17  def register_methods(root_module):
    10.1 --- a/bindings/python/ns3_module_wifi.py	Tue Jun 09 18:00:24 2009 +0100
    10.2 +++ b/bindings/python/ns3_module_wifi.py	Tue Jun 09 18:00:52 2009 +0100
    10.3 @@ -8,7 +8,7 @@
    10.4      ## wifi-preamble.h: ns3::WifiPreamble [enumeration]
    10.5      module.add_enum('WifiPreamble', ['WIFI_PREAMBLE_LONG', 'WIFI_PREAMBLE_SHORT'])
    10.6      ## wifi-phy-standard.h: ns3::WifiPhyStandard [enumeration]
    10.7 -    module.add_enum('WifiPhyStandard', ['WIFI_PHY_STANDARD_80211a', 'WIFI_PHY_STANDARD_holland'])
    10.8 +    module.add_enum('WifiPhyStandard', ['WIFI_PHY_STANDARD_80211a', 'WIFI_PHY_STANDARD_80211b', 'WIFI_PHY_STANDARD_holland'])
    10.9      ## qos-utils.h: ns3::AccessClass [enumeration]
   10.10      module.add_enum('AccessClass', ['AC_VO', 'AC_VI', 'AC_BE', 'AC_BK', 'AC_UNDEF'])
   10.11      ## edca-txop-n.h: ns3::TypeOfStation [enumeration]
   10.12 @@ -26,7 +26,7 @@
   10.13      ## wifi-mode.h: ns3::WifiMode [class]
   10.14      module.add_class('WifiMode')
   10.15      ## wifi-mode.h: ns3::WifiMode::ModulationType [enumeration]
   10.16 -    module.add_enum('ModulationType', ['BPSK', 'QAM'], outer_class=root_module['ns3::WifiMode'])
   10.17 +    module.add_enum('ModulationType', ['BPSK', 'DBPSK', 'DQPSK', 'QAM'], outer_class=root_module['ns3::WifiMode'])
   10.18      ## wifi-mode.h: ns3::WifiModeFactory [class]
   10.19      module.add_class('WifiModeFactory')
   10.20      ## wifi-phy.h: ns3::WifiPhyListener [class]
   10.21 @@ -101,6 +101,8 @@
   10.22      module.add_class('EdcaTxopN', parent=root_module['ns3::Object'])
   10.23      ## error-rate-model.h: ns3::ErrorRateModel [class]
   10.24      module.add_class('ErrorRateModel', parent=root_module['ns3::Object'])
   10.25 +    ## propagation-loss-model.h: ns3::FixedRssLossModel [class]
   10.26 +    module.add_class('FixedRssLossModel', parent=root_module['ns3::PropagationLossModel'])
   10.27      ## propagation-loss-model.h: ns3::FriisPropagationLossModel [class]
   10.28      module.add_class('FriisPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
   10.29      ## ideal-wifi-manager.h: ns3::IdealWifiManager [class]
   10.30 @@ -111,6 +113,8 @@
   10.31      module.add_class('LogDistancePropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
   10.32      ## msdu-aggregator.h: ns3::MsduAggregator [class]
   10.33      module.add_class('MsduAggregator', parent=root_module['ns3::Object'])
   10.34 +    ## propagation-loss-model.h: ns3::NakagamiPropagationLossModel [class]
   10.35 +    module.add_class('NakagamiPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
   10.36      ## nqap-wifi-mac.h: ns3::NqapWifiMac [class]
   10.37      module.add_class('NqapWifiMac', parent=root_module['ns3::WifiMac'])
   10.38      ## nqsta-wifi-mac.h: ns3::NqstaWifiMac [class]
   10.39 @@ -228,11 +232,13 @@
   10.40      register_Ns3DcaTxop_methods(root_module, root_module['ns3::DcaTxop'])
   10.41      register_Ns3EdcaTxopN_methods(root_module, root_module['ns3::EdcaTxopN'])
   10.42      register_Ns3ErrorRateModel_methods(root_module, root_module['ns3::ErrorRateModel'])
   10.43 +    register_Ns3FixedRssLossModel_methods(root_module, root_module['ns3::FixedRssLossModel'])
   10.44      register_Ns3FriisPropagationLossModel_methods(root_module, root_module['ns3::FriisPropagationLossModel'])
   10.45      register_Ns3IdealWifiManager_methods(root_module, root_module['ns3::IdealWifiManager'])
   10.46      register_Ns3JakesPropagationLossModel_methods(root_module, root_module['ns3::JakesPropagationLossModel'])
   10.47      register_Ns3LogDistancePropagationLossModel_methods(root_module, root_module['ns3::LogDistancePropagationLossModel'])
   10.48      register_Ns3MsduAggregator_methods(root_module, root_module['ns3::MsduAggregator'])
   10.49 +    register_Ns3NakagamiPropagationLossModel_methods(root_module, root_module['ns3::NakagamiPropagationLossModel'])
   10.50      register_Ns3NqapWifiMac_methods(root_module, root_module['ns3::NqapWifiMac'])
   10.51      register_Ns3NqstaWifiMac_methods(root_module, root_module['ns3::NqstaWifiMac'])
   10.52      register_Ns3OnoeWifiManager_methods(root_module, root_module['ns3::OnoeWifiManager'])
   10.53 @@ -267,6 +273,10 @@
   10.54      cls.add_method('Configure80211aParameters', 
   10.55                     'void', 
   10.56                     [])
   10.57 +    ## interference-helper.h: void ns3::InterferenceHelper::Configure80211bParameters() [member function]
   10.58 +    cls.add_method('Configure80211bParameters', 
   10.59 +                   'void', 
   10.60 +                   [])
   10.61      ## interference-helper.h: ns3::Time ns3::InterferenceHelper::GetEnergyDuration(double energyW) [member function]
   10.62      cls.add_method('GetEnergyDuration', 
   10.63                     'ns3::Time', 
   10.64 @@ -487,6 +497,16 @@
   10.65                     'ns3::WifiMode', 
   10.66                     [param('std::string', 'uniqueName'), param('bool', 'isMandatory'), param('uint32_t', 'bandwidth'), param('uint32_t', 'dataRate'), param('uint32_t', 'phyRate'), param('uint8_t', 'constellationSize')], 
   10.67                     is_static=True)
   10.68 +    ## wifi-mode.h: static ns3::WifiMode ns3::WifiModeFactory::CreateDbpsk(std::string uniqueName, bool isMandatory, uint32_t bandwidth, uint32_t dataRate, uint32_t phyRate) [member function]
   10.69 +    cls.add_method('CreateDbpsk', 
   10.70 +                   'ns3::WifiMode', 
   10.71 +                   [param('std::string', 'uniqueName'), param('bool', 'isMandatory'), param('uint32_t', 'bandwidth'), param('uint32_t', 'dataRate'), param('uint32_t', 'phyRate')], 
   10.72 +                   is_static=True)
   10.73 +    ## wifi-mode.h: static ns3::WifiMode ns3::WifiModeFactory::CreateDqpsk(std::string uniqueName, bool isMandatory, uint32_t bandwidth, uint32_t dataRate, uint32_t phyRate) [member function]
   10.74 +    cls.add_method('CreateDqpsk', 
   10.75 +                   'ns3::WifiMode', 
   10.76 +                   [param('std::string', 'uniqueName'), param('bool', 'isMandatory'), param('uint32_t', 'bandwidth'), param('uint32_t', 'dataRate'), param('uint32_t', 'phyRate')], 
   10.77 +                   is_static=True)
   10.78      return
   10.79  
   10.80  def register_Ns3WifiPhyListener_methods(root_module, cls):
   10.81 @@ -2013,6 +2033,26 @@
   10.82                     'ns3::WifiMode', 
   10.83                     [], 
   10.84                     is_static=True)
   10.85 +    ## wifi-phy.h: static ns3::WifiMode ns3::WifiPhy::Get1mbb() [member function]
   10.86 +    cls.add_method('Get1mbb', 
   10.87 +                   'ns3::WifiMode', 
   10.88 +                   [], 
   10.89 +                   is_static=True)
   10.90 +    ## wifi-phy.h: static ns3::WifiMode ns3::WifiPhy::Get2mbb() [member function]
   10.91 +    cls.add_method('Get2mbb', 
   10.92 +                   'ns3::WifiMode', 
   10.93 +                   [], 
   10.94 +                   is_static=True)
   10.95 +    ## wifi-phy.h: static ns3::WifiMode ns3::WifiPhy::Get5_5mbb() [member function]
   10.96 +    cls.add_method('Get5_5mbb', 
   10.97 +                   'ns3::WifiMode', 
   10.98 +                   [], 
   10.99 +                   is_static=True)
  10.100 +    ## wifi-phy.h: static ns3::WifiMode ns3::WifiPhy::Get11mbb() [member function]
  10.101 +    cls.add_method('Get11mbb', 
  10.102 +                   'ns3::WifiMode', 
  10.103 +                   [], 
  10.104 +                   is_static=True)
  10.105      ## wifi-phy.h: void ns3::WifiPhy::NotifyTxBegin(ns3::Ptr<ns3::Packet const> packet) [member function]
  10.106      cls.add_method('NotifyTxBegin', 
  10.107                     'void', 
  10.108 @@ -2037,10 +2077,14 @@
  10.109      cls.add_method('NotifyRxDrop', 
  10.110                     'void', 
  10.111                     [param('ns3::Ptr< ns3::Packet const >', 'packet')])
  10.112 -    ## wifi-phy.h: void ns3::WifiPhy::NotifyPromiscSniff(ns3::Ptr<ns3::Packet const> packet) [member function]
  10.113 -    cls.add_method('NotifyPromiscSniff', 
  10.114 -                   'void', 
  10.115 -                   [param('ns3::Ptr< ns3::Packet const >', 'packet')])
  10.116 +    ## wifi-phy.h: void ns3::WifiPhy::NotifyPromiscSniffRx(ns3::Ptr<ns3::Packet const> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble, double signalDbm, double noiseDbm) [member function]
  10.117 +    cls.add_method('NotifyPromiscSniffRx', 
  10.118 +                   'void', 
  10.119 +                   [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint16_t', 'channelFreqMhz'), param('uint32_t', 'rate'), param('bool', 'isShortPreamble'), param('double', 'signalDbm'), param('double', 'noiseDbm')])
  10.120 +    ## wifi-phy.h: void ns3::WifiPhy::NotifyPromiscSniffTx(ns3::Ptr<ns3::Packet const> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble) [member function]
  10.121 +    cls.add_method('NotifyPromiscSniffTx', 
  10.122 +                   'void', 
  10.123 +                   [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint16_t', 'channelFreqMhz'), param('uint32_t', 'rate'), param('bool', 'isShortPreamble')])
  10.124      return
  10.125  
  10.126  def register_Ns3WifiRemoteStationManager_methods(root_module, cls):
  10.127 @@ -2972,6 +3016,25 @@
  10.128                     is_pure_virtual=True, is_const=True, is_virtual=True)
  10.129      return
  10.130  
  10.131 +def register_Ns3FixedRssLossModel_methods(root_module, cls):
  10.132 +    ## propagation-loss-model.h: static ns3::TypeId ns3::FixedRssLossModel::GetTypeId() [member function]
  10.133 +    cls.add_method('GetTypeId', 
  10.134 +                   'ns3::TypeId', 
  10.135 +                   [], 
  10.136 +                   is_static=True)
  10.137 +    ## propagation-loss-model.h: ns3::FixedRssLossModel::FixedRssLossModel() [constructor]
  10.138 +    cls.add_constructor([])
  10.139 +    ## propagation-loss-model.h: void ns3::FixedRssLossModel::SetRss(double rss) [member function]
  10.140 +    cls.add_method('SetRss', 
  10.141 +                   'void', 
  10.142 +                   [param('double', 'rss')])
  10.143 +    ## propagation-loss-model.h: double ns3::FixedRssLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
  10.144 +    cls.add_method('DoCalcRxPower', 
  10.145 +                   'double', 
  10.146 +                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
  10.147 +                   is_const=True, visibility='private', is_virtual=True)
  10.148 +    return
  10.149 +
  10.150  def register_Ns3FriisPropagationLossModel_methods(root_module, cls):
  10.151      ## propagation-loss-model.h: static ns3::TypeId ns3::FriisPropagationLossModel::GetTypeId() [member function]
  10.152      cls.add_method('GetTypeId', 
  10.153 @@ -3122,6 +3185,21 @@
  10.154                     is_static=True)
  10.155      return
  10.156  
  10.157 +def register_Ns3NakagamiPropagationLossModel_methods(root_module, cls):
  10.158 +    ## propagation-loss-model.h: static ns3::TypeId ns3::NakagamiPropagationLossModel::GetTypeId() [member function]
  10.159 +    cls.add_method('GetTypeId', 
  10.160 +                   'ns3::TypeId', 
  10.161 +                   [], 
  10.162 +                   is_static=True)
  10.163 +    ## propagation-loss-model.h: ns3::NakagamiPropagationLossModel::NakagamiPropagationLossModel() [constructor]
  10.164 +    cls.add_constructor([])
  10.165 +    ## propagation-loss-model.h: double ns3::NakagamiPropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
  10.166 +    cls.add_method('DoCalcRxPower', 
  10.167 +                   'double', 
  10.168 +                   [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')], 
  10.169 +                   is_const=True, visibility='private', is_virtual=True)
  10.170 +    return
  10.171 +
  10.172  def register_Ns3NqapWifiMac_methods(root_module, cls):
  10.173      ## nqap-wifi-mac.h: static ns3::TypeId ns3::NqapWifiMac::GetTypeId() [member function]
  10.174      cls.add_method('GetTypeId', 
    11.1 --- a/doc/manual/Makefile	Tue Jun 09 18:00:24 2009 +0100
    11.2 +++ b/doc/manual/Makefile	Tue Jun 09 18:00:52 2009 +0100
    11.3 @@ -17,6 +17,8 @@
    11.4  	$(FIGURES)/node.eps \
    11.5  	$(FIGURES)/buffer.eps \
    11.6  	$(FIGURES)/sockets-overview.eps \
    11.7 +	$(FIGURES)/routing.eps \
    11.8 +	$(FIGURES)/routing-specialization.eps \
    11.9  	$(FIGURES)/testbed.eps \
   11.10  	$(FIGURES)/emulated-channel.eps \
   11.11  	$(FIGURES)/snir.eps \
    12.1 Binary file doc/manual/figures/packet.dia has changed
    13.1 Binary file doc/manual/figures/routing-specialization.dia has changed
    14.1 Binary file doc/manual/figures/routing.dia has changed
    15.1 --- a/doc/manual/packets.texi	Tue Jun 09 18:00:24 2009 +0100
    15.2 +++ b/doc/manual/packets.texi	Tue Jun 09 18:00:52 2009 +0100
    15.3 @@ -15,11 +15,14 @@
    15.4  emulated applications
    15.5  @end itemize
    15.6  
    15.7 -@emph{ns} Packet objects contain a buffer of bytes: protocol headers and
    15.8 -trailers are serialized in this buffer of bytes using user-provided
    15.9 -serialization and deserialization routines. The content of this byte
   15.10 -buffer is expected to match bit-for-bit the content of a real packet on
   15.11 -a real network implementing the protocol of interest.
   15.12 +Each network packet contains a byte buffer, a set of byte tags, a set of
   15.13 +packet tags, and metadata.
   15.14 +
   15.15 +The byte buffer stores the serialized content of the headers and trailers 
   15.16 +added to a packet. The serialized representation of these headers is expected
   15.17 +to match that of real network packets bit for bit (although nothing
   15.18 +forces you to do this) which means that the content of a packet buffer
   15.19 +is expected to be that of a real packet.
   15.20  
   15.21  Fragmentation and defragmentation are quite natural to implement within
   15.22  this context: since we have a buffer of real bytes, we can split it in
   15.23 @@ -29,19 +32,37 @@
   15.24  the simulator. We also expect that performing a real-time plug of the
   15.25  simulator to a real-world network will be easy.
   15.26  
   15.27 -Because we understand that simulation developers often wish to store in
   15.28 -packet objects data which is not found in the real packets (such as
   15.29 -timestamps or any kind of similar in-band data), the @emph{ns} Packet class
   15.30 -can also store extra per-packet "Tags" which are 16 bytes blobs of data.
   15.31 -Any Packet can store any number of unique Tags, each of which is
   15.32 -uniquely identified by its C++ type. These tags make it easy to attach
   15.33 -per-model data to a packet without having to patch the main Packet
   15.34 -class or Packet facilities.
   15.35 +One problem  that this design choice raises is that it is difficult to
   15.36 +pretty-print the packet headers without context.  The packet metadata 
   15.37 +describes the type of the headers and trailers which
   15.38 +were serialized in the byte buffer. The maintenance of metadata is
   15.39 +optional and disabled by default. To enable it, you must call
   15.40 +Packet::EnableMetadata() and this will allow you to get non-empty
   15.41 +output from Packet::Print and Packet::Print.
   15.42  
   15.43 +Also, developers often want to store data in packet objects that is not found
   15.44 +in the real packets (such as timestamps or flow-ids).  The Packet class
   15.45 +deals with this requirement by storing a set of tags (class Tag).  
   15.46 +We have found two classes of use cases for these tags, which leads to
   15.47 +two different types of tags.  So-called
   15.48 +'byte' tags are used to tag a subset of the bytes in the packet byte buffer
   15.49 +while 'packet' tags are used to tag the packet itself. The main difference
   15.50 +between these two kinds of tags is what happens when packets are copied,
   15.51 +fragmented, and reassembled: 'byte' tags follow bytes while 'packet' tags
   15.52 +follow packets. Another important difference between these two kinds of tags
   15.53 +is that byte tags cannot be removed and are expected to be written once,
   15.54 +and read many times, while packet tags are expected to be written once,
   15.55 +read many times, and removed exactly once. An example of a 'byte' 
   15.56 +tag is a FlowIdTag which contains a flow id and is set by the application
   15.57 +generating traffic. An example of a 'packet' tag is a cross-layer 
   15.58 +QoS class id set by an application and processed by a lower-level MAC 
   15.59 +layer.
   15.60 + 
   15.61  Memory management of Packet objects is entirely automatic and extremely
   15.62  efficient: memory for the application-level payload can be modelized by
   15.63  a virtual buffer of zero-filled bytes for which memory is never allocated
   15.64 -unless explicitely requested by the user or unless the packet is fragmented.
   15.65 +unless explicitly requested by the user or unless the packet is fragmented
   15.66 +or serialized out to a real network device.
   15.67  Furthermore, copying, adding, and, removing headers or trailers to a packet
   15.68  has been optimized to be virtually free through a technique known as
   15.69  Copy On Write.
   15.70 @@ -54,32 +75,12 @@
   15.71  tension between ease-of-use, performance, and safe interface
   15.72  design. 
   15.73  
   15.74 -There are a few requirements on this object design:
   15.75 -@itemize @bullet 
   15.76 -@item Creation, management, and deletion of this object
   15.77 -should be as simple as possible, while avoiding the
   15.78 -chance for memory leaks and/or heap corruption; 
   15.79 -@item Packets should support serialization and deserialization
   15.80 -so that network emulation is supported;
   15.81 -@item Packets should support fragmentation and concatenation
   15.82 -(multiple packets in a data link frame), especially for wireless
   15.83 -support;
   15.84 -@item It should be natural for packets to carry actual application
   15.85 -data, or if there is only an emulated application and there is
   15.86 -no need to carry dummy bytes, smaller packets could be used with
   15.87 -just the headers and a record of the payload size, but not actual
   15.88 -application bytes, conveyed in the simulated packet.
   15.89 -@item Packets should facilitate BSD-like operations on mbufs, for
   15.90 -support of ported operating system stacks.
   15.91 -@item Additional side-information should be supported, such as
   15.92 -a tag for cross-layer information.
   15.93 -@end itemize
   15.94 -
   15.95  @section Packet design overview
   15.96  
   15.97  Unlike @emph{ns-2}, in which Packet objects contain a buffer of C++
   15.98  structures corresponding to protocol headers, each network packet in
   15.99 -@emph{ns-3} contains a byte Buffer and a list of Tags:
  15.100 +@emph{ns-3} contains a byte Buffer, a list of byte Tags, a list of
  15.101 +packet Tags, and a PacketMetadata object:
  15.102  @itemize @bullet
  15.103  @item The byte buffer stores the serialized content of the chunks 
  15.104  added to a packet. The serialized representation of these chunks is 
  15.105 @@ -88,16 +89,12 @@
  15.106  of a packet buffer is expected to be that of a real packet.
  15.107  Packets can also be created with an arbitrary zero-filled payload
  15.108  for which no real memory is allocated.
  15.109 -@item The list of tags stores an arbitrarily large set of arbitrary 
  15.110 +@item Each list of tags stores an arbitrarily large set of arbitrary 
  15.111  user-provided data structures in the packet.  Each Tag is uniquely
  15.112  identified by its type; only one instance of each 
  15.113  type of data structure is allowed in a list of tags. These tags typically 
  15.114  contain per-packet cross-layer information or flow identifiers (i.e.,
  15.115 -things that you wouldn't find in the bits on the wire). Each tag 
  15.116 -stored in the tag list can be at most 16 bytes.
  15.117 -Trying to attach bigger data structures will trigger 
  15.118 -crashes at runtime.  The 16 byte limit is a modifiable compilation
  15.119 -constant.
  15.120 +things that you wouldn't find in the bits on the wire). 
  15.121  @end itemize
  15.122  
  15.123  @float Figure,fig:packets
  15.124 @@ -110,17 +107,29 @@
  15.125  is provided later in Figure @ref{fig:buffer}.
  15.126  In \nsthree, the Packet byte buffer is analogous to a Linux skbuff
  15.127  or BSD mbuf; it is a serialized representation of the actual
  15.128 -data in the packet.  The tag list is a container for extra
  15.129 +data in the packet.  The tag lists are containers for extra
  15.130  items useful for simulation convenience; if a Packet is converted
  15.131  to an emulated packet and put over an actual network, the tags
  15.132  are stripped off and the byte buffer is copied directly
  15.133  into a real packet.
  15.134  
  15.135 -The Packet class has value semantics:  it can be freely copied around,
  15.136 -allocated on the stack, and passed to functions as arguments.  Whenever
  15.137 -an instance is copied, the full underlying data is not copied; it
  15.138 -has ``copy-on-write'' (COW) semantics.  Packet instances can be passed
  15.139 -by value to function arguments without any performance hit.
  15.140 +Packets are reference counted objects.  They are handled with smart
  15.141 +pointer (Ptr) objects like many of the objects in the ns-3 system.
  15.142 +One small difference you will see is that class Packet does not
  15.143 +inherit from class Object or class RefCountBase, and implements the
  15.144 +Ref() and Unref() methods directly.  This was designed to avoid the overhead
  15.145 +of a vtable in class Packet.
  15.146 +
  15.147 +The Packet class is designed to be copied cheaply; the overall design
  15.148 +is based on Copy on Write (COW).  When there are multiple references
  15.149 +to a packet object, and there is an operation on one of them, only 
  15.150 +so-called "dirty" operations will trigger a deep copy of the packet:
  15.151 +@itemize @bullet
  15.152 +@item @code{ns3::Packet::AddHeader()}
  15.153 +@item @code{ns3::Packet::AddTrailer()}
  15.154 +@item @code{both versions of ns3::Packet::AddAtEnd()}
  15.155 +@item @code{Packet::RemovePacketTag()}
  15.156 +@end itemize
  15.157  
  15.158  The fundamental classes for adding to and removing from the byte
  15.159  buffer are @code{class Header} and @code{class Trailer}.  
  15.160 @@ -149,78 +158,203 @@
  15.161  
  15.162  Similarly, user-defined Tags can be appended to the packet. 
  15.163  Unlike Headers, Tags are not serialized into a contiguous buffer
  15.164 -but are stored in an array.  By default, Tags are limited to 16 bytes in
  15.165 -size.  Tags can be flexibly defined to be any type, but there
  15.166 +but are stored in lists.  Tags can be flexibly defined to be any 
  15.167 +type, but there
  15.168  can only be one instance of any particular object type in
  15.169  the Tags buffer at any time.  
  15.170  
  15.171 -@section Packet interface
  15.172 +@section Using the packet interface
  15.173  
  15.174 -The public member functions of a Packet object are as follows:
  15.175 +This section describes how to create and use the @code{ns3::Packet} object.
  15.176  
  15.177 -@subsection Constructors
  15.178 +@subsection Creating a new packet
  15.179 +
  15.180 +The following command will create a new packet with a new unique
  15.181 +Id.
  15.182 +
  15.183  @verbatim
  15.184 -    /**
  15.185 -     * Create an empty packet with a new uid (as returned
  15.186 -     * by getUid).
  15.187 -     */
  15.188 -    Packet ();
  15.189 -    /**
  15.190 -     * Create a packet with a zero-filled payload.
  15.191 -     * The memory necessary for the payload is not allocated:
  15.192 -     * it will be allocated at any later point if you attempt
  15.193 -     * to fragment this packet or to access the zero-filled
  15.194 -     * bytes. The packet is allocated with a new uid (as
  15.195 -     * returned by getUid).
  15.196 -     *
  15.197 -     * \param size the size of the zero-filled payload
  15.198 -     */
  15.199 -    Packet (uint32_t size);
  15.200 +  Ptr<Packet> pkt = Create<Packet> ();
  15.201  @end verbatim
  15.202  
  15.203 +What is the Uid (unique Id)?  It is an internal id that the
  15.204 +system uses to identify packets.  It can be fetched via the following
  15.205 +method:
  15.206 +@verbatim
  15.207 +  uint32_t uid = pkt->GetUid ();
  15.208 +@end verbatim
  15.209 +
  15.210 +But please note the following.  This uid is an internal uid and cannot 
  15.211 +be counted on to provide an accurate counter of how many 
  15.212 +"simulated packets" of a particular protocol are in the system. 
  15.213 +It is not trivial to make this uid into such a counter, because of 
  15.214 +questions such as what should the uid be when the packet is 
  15.215 +sent over broadcast media, or when fragmentation occurs. If a user 
  15.216 +wants to trace actual packet counts, he or she should look at 
  15.217 +e.g. the IP ID field or transport sequence numbers, or other packet 
  15.218 +or frame counters at other protocol layers.
  15.219 +
  15.220 +We mentioned above that it is possible to create packets with zero-filled
  15.221 +payloads that do not actually require a memory allocation (i.e.,
  15.222 +the packet may behave, when delays such as serialization or transmission
  15.223 +delays are computed, to have a certain number of payload bytes, but
  15.224 +the bytes will only be allocated on-demand when needed).  The command to do 
  15.225 +this is, when the packet
  15.226 +is created:
  15.227 +@verbatim
  15.228 +  Ptr<Packet> pkt = Create<Packet> (N);
  15.229 +@end verbatim
  15.230 +where N is a positive integer.  
  15.231 +
  15.232 +The packet now has a size of N bytes, which can be verified by the GetSize()
  15.233 +method:
  15.234 +@verbatim
  15.235 +  /**
  15.236 +   * \returns the size in bytes of the packet (including the zero-filled
  15.237 +   *          initial payload)
  15.238 +   */
  15.239 +  uint32_t GetSize (void) const;
  15.240 +@end verbatim
  15.241 +
  15.242 +You can also initialize a packet with a character buffer.  The input
  15.243 +data is copied and the input buffer is untouched.  The constructor
  15.244 +applied is:
  15.245 +@verbatim
  15.246 +  Packet (uint8_t const *buffer, uint32_t size);
  15.247 +@end verbatim
  15.248 +Here is an example:
  15.249 +@verbatim
  15.250 +  Ptr<Packet> pkt1 = Create<Packet> (reinterpret_cast<const uint8_t*> ("hello"), 5);
  15.251 +@end verbatim
  15.252 +
  15.253 +Packets are freed when there are no more references to them, as with
  15.254 +all ns-3 objects referenced by the Ptr class.
  15.255 +
  15.256  @subsection Adding and removing Buffer data
  15.257 -The below code is reproduced for Header class only; similar functions
  15.258 -exist for Trailers.
  15.259 +
  15.260 +After the initial packet creation (which may possibly create some 
  15.261 +fake initial bytes of payload), all subsequent buffer data is added by adding
  15.262 +objects of class Header or class Trailer.  Note that, even if you are 
  15.263 +in the application layer, handling packets, and want to write application
  15.264 +data, you write it as an ns3::Header or ns3::Trailer.  If you add a Header,
  15.265 +it is prepended to the packet, and if you add a Trailer, it is added to
  15.266 +the end of the packet.  If you have no data in the packet, then it
  15.267 +makes no difference whether you add a Header or Trailer.  Since the
  15.268 +APIs and classes for header and trailer are pretty much identical, we'll
  15.269 +just look at class Header here.
  15.270 +
  15.271 +The first step is to create a new header class.  All new Header classes
  15.272 +must inherit from class Header, and implement the following methods:
  15.273 +@itemize @bullet
  15.274 +@item @code{Serialize ()}
  15.275 +@item @code{Deserialize ()}
  15.276 +@item @code{GetSerializedSize ()}
  15.277 +@item @code{Print ()}
  15.278 +@end itemize 
  15.279 +
  15.280 +To see a simple example of how these are done, look at the UdpHeader
  15.281 +class headers src/internet-stack/udp-header.cc.  There are many other
  15.282 +examples within the source code. 
  15.283 +
  15.284 +Once you have a header (or you have a preexisting header), the following
  15.285 +Packet API can be used to add or remove such headers.
  15.286 +
  15.287  @verbatim
  15.288 -    /**
  15.289 -     * Add header to this packet. This method invokes the
  15.290 -     * ns3::Header::serializeTo method to request the header to serialize
  15.291 -     * itself in the packet buffer.
  15.292 -     *
  15.293 -     * \param header a reference to the header to add to this packet.
  15.294 -     */
  15.295 -    void Add (Header const &header);
  15.296 -    /**
  15.297 -     * Deserialize header from this packet. This method invokes the
  15.298 -     * ns3::Header::deserializeFrom method to request the header to deserialize
  15.299 -     * itself from the packet buffer. This method does not remove
  15.300 -     * the data from the buffer. It merely reads it.
  15.301 -     *
  15.302 -     * \param header a reference to the header to deserialize from the buffer
  15.303 -     */
  15.304 -    void Peek (Header &header);
  15.305 -    /**
  15.306 -     * Remove a deserialized header from the internal buffer.
  15.307 -     * This method removes the bytes read by Packet::peek from
  15.308 -     * the packet buffer.
  15.309 -     *
  15.310 -     * \param header a reference to the header to remove from the internal buffer.
  15.311 -     */
  15.312 -    void Remove (Header const &header);
  15.313 -    /**
  15.314 -     * Add trailer to this packet. This method invokes the
  15.315 -     * ns3::Trailer::serializeTo method to request the trailer to serialize
  15.316 -     * itself in the packet buffer.
  15.317 -     *
  15.318 -     * \param trailer a reference to the trailer to add to this packet.
  15.319 -     */
  15.320 +  /**
  15.321 +   * Add header to this packet. This method invokes the
  15.322 +   * Header::GetSerializedSize and Header::Serialize
  15.323 +   * methods to reserve space in the buffer and request the 
  15.324 +   * header to serialize itself in the packet buffer.
  15.325 +   *
  15.326 +   * \param header a reference to the header to add to this packet.
  15.327 +   */
  15.328 +  void AddHeader (const Header & header);
  15.329 +  /**
  15.330 +   * Deserialize and remove the header from the internal buffer.
  15.331 +   * This method invokes Header::Deserialize.
  15.332 +   *
  15.333 +   * \param header a reference to the header to remove from the internal buffer.
  15.334 +   * \returns the number of bytes removed from the packet.
  15.335 +   */
  15.336 +  uint32_t RemoveHeader (Header &header);
  15.337 +  /**
  15.338 +   * Deserialize but does _not_ remove the header from the internal buffer.
  15.339 +   * This method invokes Header::Deserialize.
  15.340 +   *
  15.341 +   * \param header a reference to the header to read from the internal buffer.
  15.342 +   * \returns the number of bytes read from the packet.
  15.343 +   */
  15.344 +  uint32_t PeekHeader (Header &header) const;
  15.345 +@end verbatim
  15.346 +
  15.347 +For instance, here are the typical operations to add and remove a UDP header.
  15.348 +
  15.349 +@verbatim
  15.350 + // add header
  15.351 + Ptr<Packet> packet = Create<Packet> ();
  15.352 + UdpHeader udpHeader;
  15.353 + // Fill out udpHeader fields appropriately
  15.354 + packet->AddHeader (udpHeader);
  15.355 + ...
  15.356 + // remove header
  15.357 + UdpHeader udpHeader;
  15.358 + packet->RemoveHeader (udpHeader); 
  15.359 + // Read udpHeader fields as needed
  15.360  @end verbatim
  15.361  
  15.362  @subsection Adding and removing Tags
  15.363  
  15.364 -@strong{Note:  This part of ns-3 will change for ns-3.5; see this mail message:
  15.365 -http://mailman.isi.edu/pipermail/ns-developers/2009-March/005557.html}
  15.366 +There is a single base class of Tag that all packet tags must derive from.
  15.367 +They are used in two different tag lists in the packet; the lists have
  15.368 +different semantics and different expected use cases.
  15.369  
  15.370 +As the names imply, ByteTags follow bytes and PacketTags follow packets.
  15.371 +What this means is that when operations are done on packets, such as
  15.372 +fragmentation, concatenation, and appending or removing headers, the
  15.373 +byte tags keep track of which packet bytes they cover.  For instance,
  15.374 +if a user creates a TCP segment, and applies a ByteTag to the segment,
  15.375 +each byte of the TCP segment will be tagged.  However, if the next
  15.376 +layer down inserts an IPv4 header, this ByteTag will not cover those
  15.377 +bytes.  The converse is true for the PacketTag; it covers a packet
  15.378 +despite the operations on it.
  15.379 +
  15.380 +PacketTags are limited in size to 20 bytes.  This is a modifiable 
  15.381 +compile-time constant in @code{src/common/packet-tag-list.h}.  ByteTags
  15.382 +have no such restriction.
  15.383 +
  15.384 +Each tag type must subclass @code{ns3::Tag}, and only one instance of
  15.385 +each Tag type may be in each tag list.  Here are a few differences 
  15.386 +in the behavior of packet tags and byte tags.
  15.387 +@itemize @bullet
  15.388 +@item @strong{Fragmentation:}  As mentioned above, when a packet is fragmented,
  15.389 +each packet fragment (which is a new packet) will get a copy of all packet
  15.390 +tags, and byte tags will follow the new packet boundaries (i.e. if the
  15.391 +fragmented packets fragment across a buffer region covered by the byte
  15.392 +tag, both packet fragments will still have the appropriate buffer regions
  15.393 +byte tagged).
  15.394 +@item @strong{Concatenation:}  When packets are combined, two different
  15.395 +buffer regions will become one.  For byte tags, the byte tags simply
  15.396 +follow the respective buffer regions.  For packet tags, only the
  15.397 +tags on the first packet survive the merge.
  15.398 +@item @strong{Finding and Printing:}  Both classes allow you to iterate
  15.399 +over all of the tags and print them.
  15.400 +@item @strong{Removal:}  Users can add and remove the same packet tag
  15.401 +multiple times on a single packet (AddPacketTag () and RemovePacketTag ()).  
  15.402 +The packet However, once a byte tag is added,
  15.403 +it can only be removed by stripping all byte tags from the packet.  
  15.404 +Removing one of possibly multiple byte tags is not supported by the 
  15.405 +current API.  
  15.406 +@end itemize  
  15.407 +
  15.408 +As of ns-3.5, Tags are not serialized and deserialized to a buffer when
  15.409 +@code{Packet::Serialize ()} and @code{Packet::Deserialize ()} are called; 
  15.410 +this is an open bug.
  15.411 +
  15.412 +If a user wants to take an existing packet object and reuse it as a new
  15.413 +packet, he or she should remove all byte tags and packet tags before doing so.
  15.414 +An example is the UdpEchoServer class, which takes the received packet
  15.415 +and "turns it around" to send back to the echo client. 
  15.416 +
  15.417 +The Packet API for byte tags is given below.
  15.418  @verbatim
  15.419    /**
  15.420     * \param tag the new tag to add to this packet
  15.421 @@ -228,7 +362,7 @@
  15.422     * Tag each byte included in this packet with the
  15.423     * new tag.
  15.424     *
  15.425 -   * Note that adding a tag is a const operation which is pretty
  15.426 +   * Note that adding a tag is a const operation which is pretty 
  15.427     * un-intuitive. The rationale is that the content and behavior of
  15.428     * a packet is _not_ changed when a tag is added to a packet: any
  15.429     * code which was not aware of the new tag is going to work just
  15.430 @@ -239,216 +373,159 @@
  15.431     * totally evil to allow a trace sink to modify the content of a
  15.432     * packet).
  15.433     */
  15.434 -  void AddTag (const Tag &tag) const;
  15.435 +  void AddByteTag (const Tag &tag) const;
  15.436    /**
  15.437 -   * \returns an iterator over the set of tags included in this packet.
  15.438 +   * \returns an iterator over the set of byte tags included in this packet.
  15.439     */
  15.440 -  TagIterator GetTagIterator (void) const;
  15.441 +  ByteTagIterator GetByteTagIterator (void) const;
  15.442    /**
  15.443     * \param tag the tag to search in this packet
  15.444     * \returns true if the requested tag type was found, false otherwise.
  15.445     *
  15.446 -   * If the requested tag type is found, it is copied in the user's
  15.447 +   * If the requested tag type is found, it is copied in the user's 
  15.448     * provided tag instance.
  15.449     */
  15.450 -  bool FindFirstMatchingTag (Tag &tag) const;
  15.451 -
  15.452 +  bool FindFirstMatchingByteTag (Tag &tag) const;
  15.453 +  
  15.454    /**
  15.455     * Remove all the tags stored in this packet.
  15.456     */
  15.457 -  void RemoveAllTags (void);
  15.458 +  void RemoveAllByteTags (void);
  15.459 +
  15.460 +  /**
  15.461 +   * \param os output stream in which the data should be printed.
  15.462 +   *
  15.463 +   * Iterate over the tags present in this packet, and
  15.464 +   * invoke the Print method of each tag stored in the packet.
  15.465 +   */
  15.466 +  void PrintByteTags (std::ostream &os) const;
  15.467  @end verbatim
  15.468  
  15.469 -@subsection Fragmentation
  15.470 +The Packet API for packet tags is given below.
  15.471  @verbatim
  15.472 -    /**
  15.473 -     * Create a new packet which contains a fragment of the original
  15.474 -     * packet. The returned packet shares the same uid as this packet.
  15.475 -     *
  15.476 -     * \param start offset from start of packet to start of fragment to create
  15.477 -     * \param length length of fragment to create
  15.478 -     * \returns a fragment of the original packet
  15.479 -     */
  15.480 -    Packet CreateFragment (uint32_t start, uint32_t length) const;
  15.481 -
  15.482 -        /**
  15.483 -         * Concatenate the input packet at the end of the current
  15.484 -         * packet. This does not alter the uid of either packet.
  15.485 -         * 
  15.486 -         * \param packet packet to concatenate
  15.487 -         */
  15.488 -    void addAtEnd (Packet packet);
  15.489 -
  15.490 -        /oncatenate the input packet at the end of the current
  15.491 -     * packet. This does not alter the uid of either packet.
  15.492 -     *
  15.493 -     * \param packet packet to concatenate
  15.494 -     */
  15.495 -    void AddAtEnd (Packet packet);
  15.496 -    /**
  15.497 -     * Concatenate the fragment of the input packet identified
  15.498 -     * by the offset and size parameters at the end of the current
  15.499 -     * packet. This does not alter the uid of either packet.
  15.500 -     *
  15.501 -     * \param packet to concatenate
  15.502 -     * \param offset offset of fragment to copy from the start of the input packet
  15.503 -     * \param size size of fragment of input packet to copy.
  15.504 -     */
  15.505 -    void AddAtEnd (Packet packet, uint32_t offset, uint32_t size);
  15.506 -    /**
  15.507 -     * Remove size bytes from the end of the current packet
  15.508 -     * It is safe to remove more bytes that what is present in
  15.509 -     * the packet.
  15.510 -     *
  15.511 -     * \param size number of bytes from remove
  15.512 -     */
  15.513 -    void RemoveAtEnd (uint32_t size);
  15.514 -    /**
  15.515 -     * Remove size bytes from the start of the current packet.
  15.516 -     * It is safe to remove more bytes that what is present in
  15.517 -     * the packet.
  15.518 -     *
  15.519 -     * \param size number of bytes from remove
  15.520 -     */
  15.521 -    void RemoveAtStart (uint32_t size);
  15.522 +  /**
  15.523 +   * \param tag the tag to store in this packet
  15.524 +   *
  15.525 +   * Add a tag to this packet. This method calls the
  15.526 +   * Tag::GetSerializedSize and, then, Tag::Serialize.
  15.527 +   *
  15.528 +   * Note that this method is const, that is, it does not
  15.529 +   * modify the state of this packet, which is fairly
  15.530 +   * un-intuitive.
  15.531 +   */
  15.532 +  void AddPacketTag (const Tag &tag) const;
  15.533 +  /**
  15.534 +   * \param tag the tag to remove from this packet
  15.535 +   * \returns true if the requested tag is found, false
  15.536 +   *          otherwise.
  15.537 +   *
  15.538 +   * Remove a tag from this packet. This method calls
  15.539 +   * Tag::Deserialize if the tag is found.
  15.540 +   */
  15.541 +  bool RemovePacketTag (Tag &tag);
  15.542 +  /**
  15.543 +   * \param tag the tag to search in this packet
  15.544 +   * \returns true if the requested tag is found, false
  15.545 +   *          otherwise.
  15.546 +   *
  15.547 +   * Search a matching tag and call Tag::Deserialize if it is found.
  15.548 +   */
  15.549 +  bool PeekPacketTag (Tag &tag) const;
  15.550 +  /**
  15.551 +   * Remove all packet tags.
  15.552 +   */
  15.553 +  void RemoveAllPacketTags (void);
  15.554 +  
  15.555 +  /**
  15.556 +   * \param os the stream in which we want to print data.
  15.557 +   *
  15.558 +   * Print the list of 'packet' tags.
  15.559 +   *
  15.560 +   * \sa Packet::AddPacketTag, Packet::RemovePacketTag, Packet::PeekPacketTag,
  15.561 +   *  Packet::RemoveAllPacketTags
  15.562 +   */
  15.563 +  void PrintPacketTags (std::ostream &os) const;
  15.564 +  
  15.565 +  /**
  15.566 +   * \returns an object which can be used to iterate over the list of
  15.567 +   *  packet tags.
  15.568 +   */
  15.569 +  PacketTagIterator GetPacketTagIterator (void) const;
  15.570  @end verbatim
  15.571  
  15.572 -@subsection Miscellaneous
  15.573 +Here is a simple example illustrating the use of tags from the
  15.574 +code in @code{src/internet-stack/udp-socket-impl.cc}:
  15.575  @verbatim
  15.576 -    /**
  15.577 -     * \returns the size in bytes of the packet (including the zero-filled
  15.578 -     *          initial payload)
  15.579 -     */
  15.580 -    uint32_t GetSize (void) const;
  15.581 -    /**
  15.582 -     * If you try to change the content of the buffer
  15.583 -     * returned by this method, you will die.
  15.584 -     *
  15.585 -     * \returns a pointer to the internal buffer of the packet.
  15.586 -     */
  15.587 -    uint8_t const *PeekData (void) const;
  15.588 -    /**
  15.589 -     * A packet is allocated a new uid when it is created
  15.590 -     * empty or with zero-filled payload.
  15.591 -     *
  15.592 -     * \returns an integer identifier which uniquely
  15.593 -     *          identifies this packet.
  15.594 -     */
  15.595 -    uint32_t GetUid (void) const;
  15.596 +  Ptr<Packet> p;  // pointer to a pre-existing packet
  15.597 +  SocketIpTtlTag tag
  15.598 +  tag.SetTtl (m_ipMulticastTtl); // Convey the TTL from Udp layer to IP layer
  15.599 +  p->AddPacketTag (tag);
  15.600  @end verbatim
  15.601  
  15.602 -@section Using Headers
  15.603 -@emph{walk through an example of adding a UDP header}
  15.604 +This tag is read at the IP layer, then stripped (@code{src/internet-stack/ipv4-l3-protocol.cc}:
  15.605 +@verbatim
  15.606 +  uint8_t ttl = m_defaultTtl;
  15.607 +  SocketIpTtlTag tag;
  15.608 +  bool found = packet->RemovePacketTag (tag);
  15.609 +  if (found)
  15.610 +    {
  15.611 +      ttl = tag.GetTtl ();
  15.612 +    }
  15.613 +@end verbatim
  15.614  
  15.615 -@section Using Tags
  15.616 -@emph{walk through an example of adding a flow ID}
  15.617 +@subsection Fragmentation and concatenation
  15.618  
  15.619 -@section Using Fragmentation
  15.620 -@emph{walk through an example of link-layer fragmentation/reassembly}
  15.621 +Packets may be fragmented or merged together.  For example, to 
  15.622 +fragment a packet @code{p} of 90 bytes into two packets, one containing
  15.623 +the first 10 bytes and the other containing the remaining 80, one may call the
  15.624 +following code:
  15.625 +@verbatim
  15.626 +  Ptr<Packet> frag0 = p->CreateFragment (0, 10);
  15.627 +  Ptr<Packet> frag1 = p->CreateFragment (10, 90);
  15.628 +@end verbatim
  15.629  
  15.630 -@section Sample program
  15.631 -The below sample program (from @code{ns3/samples/main-packet.cc}) illustrates
  15.632 -some use of the Packet, Header, and Tag classes.
  15.633 +As discussed above, the packet tags from @code{p} will follow to both
  15.634 +packet fragments, and the byte tags will follow the byte ranges as needed.
  15.635  
  15.636 +Now, to put them back together:
  15.637  @verbatim
  15.638 -/* -*-    Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */
  15.639 -#include "ns3/packet.h"
  15.640 -#include "ns3/header.h"
  15.641 -#include <iostream>
  15.642 +  frag0->AddAtEnd (frag1);
  15.643 +@end verbatim
  15.644 +Now frag0 should be equivalent to the original packet @code{p}.  If,
  15.645 +however, there were operations on the fragments before being reassembled
  15.646 +(such as tag operations or header operations), the new packet will not
  15.647 +be the same.
  15.648  
  15.649 -using namespace ns3;
  15.650 +@subsection Enabling metadata
  15.651  
  15.652 -/* A sample Header implementation
  15.653 - */
  15.654 -class MyHeader : public Header {
  15.655 -public:
  15.656 -    MyHeader ();
  15.657 -    virtual ~MyHeader ();
  15.658 +We mentioned above that packets, being on-the-wire representations of
  15.659 +byte buffers, present a problem to print out in a structured way
  15.660 +unless the printing function has access to the context of the header.
  15.661 +For instance, consider a tcpdump-like printer that wants to pretty-print
  15.662 +the contents of a packet.
  15.663  
  15.664 -    void SetData (uint16_t data);
  15.665 -    uint16_t GetData (void) const;
  15.666 -private:
  15.667 -    virtual void PrintTo (std::ostream &os) const;
  15.668 -    virtual void SerializeTo (Buffer::Iterator start) const;
  15.669 -    virtual void DeserializeFrom (Buffer::Iterator start);
  15.670 -    virtual uint32_t GetSerializedSize (void) const;
  15.671 +To enable this usage, packets may have metadata enabled (disabled by
  15.672 +default for performance reasons).  This class is used by the Packet
  15.673 +class to record every operation performed on the packet's buffer, and
  15.674 +provides an implementation of @code{Packet::Print ()} method that uses
  15.675 +the metadata to analyze the content of the packet's buffer.
  15.676  
  15.677 -    uint16_t m_data;
  15.678 -};
  15.679 +The metadata is also used to perform extensive sanity checks at runtime 
  15.680 +when performing operations on a Packet. For example, this metadata is 
  15.681 +used to verify that when you remove a header from a packet, this 
  15.682 +same header was actually present at the front of the packet. These
  15.683 +errors will be detected and will abort the program.
  15.684  
  15.685 -MyHeader::MyHeader ()
  15.686 -{}
  15.687 -MyHeader::~MyHeader ()
  15.688 -{}
  15.689 -void 
  15.690 -MyHeader::PrintTo (std::ostream &os) const
  15.691 -{
  15.692 -    os << "MyHeader data=" << m_data << std::endl;
  15.693 -}
  15.694 -uint32_t
  15.695 -MyHeader::GetSerializedSize (void) const
  15.696 -{
  15.697 -    return 2;
  15.698 -}
  15.699 -void 
  15.700 -MyHeader::SerializeTo (Buffer::Iterator start) const
  15.701 -{
  15.702 -    // serialize in head of buffer
  15.703 -    start.WriteHtonU16 (m_data);
  15.704 -}
  15.705 -void 
  15.706 -MyHeader::DeserializeFrom (Buffer::Iterator start)
  15.707 -{
  15.708 -    // deserialize from head of buffer
  15.709 -    m_data = start.ReadNtohU16 ();
  15.710 -}
  15.711 +To enable this operation, users will typically insert one or both
  15.712 +of these statements at the beginning of their programs:
  15.713 +@verbatim
  15.714 +  Packet::EnablePrinting ();
  15.715 +  Packet::EnableChecking ();
  15.716 +@end verbatim
  15.717  
  15.718 -void 
  15.719 -MyHeader::SetData (uint16_t data)
  15.720 -{
  15.721 -    m_data = data;
  15.722 -}
  15.723 -uint16_t 
  15.724 -MyHeader::GetData (void) const
  15.725 -{
  15.726 -    return m_data;
  15.727 -}
  15.728 +@section Sample programs
  15.729  
  15.730 -/* A sample Tag implementation
  15.731 - */
  15.732 -struct MyTag {
  15.733 -    uint16_t m_streamId;
  15.734 -};
  15.735 -
  15.736 -static TagRegistration<struct MyTag> g_MyTagRegistration ("ns3::MyTag", 0);
  15.737 -
  15.738 -
  15.739 -static void
  15.740 -Receive (Packet p)
  15.741 -{
  15.742 -    MyHeader my;
  15.743 -    p.Peek (my);
  15.744 -    p.Remove (my);
  15.745 -    std::cout << "received data=" << my.GetData () << std::endl;
  15.746 -    struct MyTag myTag;
  15.747 -    p.PeekTag (myTag);
  15.748 -}
  15.749 -
  15.750 -
  15.751 -int main (int argc, char *argv[])
  15.752 -{
  15.753 -    Packet p;
  15.754 -    MyHeader my;
  15.755 -    my.SetData (2);
  15.756 -    std::cout << "send data=2" << std::endl;
  15.757 -    p.Add (my);
  15.758 -    struct MyTag myTag;
  15.759 -    myTag.m_streamId = 5;
  15.760 -    p.AddTag (myTag);
  15.761 -    Receive (p);
  15.762 -    return 0;
  15.763 -}
  15.764 -@end verbatim
  15.765 +See @code{samples/main-packet.cc} and @code{samples/main-packet-tag.cc}.
  15.766  
  15.767  @section Implementation details
  15.768  
  15.769 @@ -457,13 +534,19 @@
  15.770  A Packet object's interface provides access to some private
  15.771  data:
  15.772  @verbatim
  15.773 -    Buffer m_buffer;
  15.774 -    Tags m_tags;
  15.775 -    uint32_t m_uid; 
  15.776 -    static uint32_t m_global_uid;
  15.777 +  Buffer m_buffer;
  15.778 +  ByteTagList m_byteTagList;
  15.779 +  PacketTagList m_packetTagList;
  15.780 +  PacketMetadata m_metadata;
  15.781 +  mutable uint32_t m_refCount;
  15.782 +  static uint32_t m_globalUid;
  15.783  @end verbatim
  15.784 -Each Packet has a Buffer and a Tags object, and a 32-bit unique ID (m\_uid).
  15.785 -A static member variable keeps track of the UIDs allocated.  Note
  15.786 +Each Packet has a Buffer and two Tags lists, a PacketMetadata object,
  15.787 +and a ref count.
  15.788 +A static member variable keeps track of the UIDs allocated.  
  15.789 +The actual uid of the packet is stored in the PacketMetadata.
  15.790 +
  15.791 +Note
  15.792  that real network packets do not have a UID; the UID is therefore an
  15.793  instance of data that normally would be stored as a Tag in the packet.
  15.794  However, it was felt that a UID is a special case that is so often
  15.795 @@ -525,6 +608,9 @@
  15.796  then complete their state-changing operation.
  15.797  
  15.798  @subsection Tags implementation
  15.799 +
  15.800 +(XXX revise me)
  15.801 +
  15.802  Tags are implemented by a single pointer which points to the start of a 
  15.803  linked list ofTagData data structures. Each TagData structure points 
  15.804  to the next TagData in the list (its next pointer contains zero to 
  15.805 @@ -562,12 +648,8 @@
  15.806  };
  15.807  @end verbatim
  15.808  
  15.809 -@emph{add description of TagRegistration for printing}
  15.810 -
  15.811  @subsection Memory management
  15.812  
  15.813 -@emph{Describe free list.}
  15.814 -
  15.815  @emph{Describe dataless vs. data-full packets.}
  15.816  
  15.817  @subsection Copy-on-write semantics
  15.818 @@ -590,21 +672,26 @@
  15.819  
  15.820  Dirty operations:
  15.821  @itemize @bullet
  15.822 -@item Packet::RemoveTag()
  15.823 -@item Packet::Add()
  15.824 -@item both versions of ns3::Packet::AddAtEnd()
  15.825 +@item ns3::Packet::AddHeader
  15.826 +@item ns3::Packet::AddTrailer
  15.827 +@item both versions of ns3::Packet::AddAtEnd
  15.828 +@item  ns3::Packet::RemovePacketTag
  15.829  @end itemize
  15.830  
  15.831  Non-dirty operations:
  15.832  @itemize @bullet
  15.833 -@item Packet::AddTag()
  15.834 -@item Packet::RemoveAllTags()
  15.835 -@item Packet::PeekTag()
  15.836 -@item Packet::Peek()
  15.837 -@item Packet::Remove()
  15.838 -@item Packet::CreateFragment()
  15.839 -@item Packet::RemoveAtStart()
  15.840 -@item Packet::RemoveAtEnd()
  15.841 +@item ns3::Packet::AddPacketTag
  15.842 +@item ns3::Packet::PeekPacketTag
  15.843 +@item ns3::Packet::RemoveAllPacketTags
  15.844 +@item ns3::Packet::AddByteTag
  15.845 +@item ns3::Packet::FindFirstMatchingByteTag
  15.846 +@item ns3::Packet::RemoveAllByteTags
  15.847 +@item ns3::Packet::RemoveHeader
  15.848 +@item ns3::Packet::RemoveTrailer
  15.849 +@item ns3::Packet::CreateFragment
  15.850 +@item ns3::Packet::RemoveAtStart
  15.851 +@item ns3::Packet::RemoveAtEnd
  15.852 +@item ns3::Packet::CopyData
  15.853  @end itemize
  15.854  
  15.855  Dirty operations will always be slower than non-dirty operations,
    16.1 --- a/doc/manual/routing.texi	Tue Jun 09 18:00:24 2009 +0100
    16.2 +++ b/doc/manual/routing.texi	Tue Jun 09 18:00:52 2009 +0100
    16.3 @@ -2,40 +2,213 @@
    16.4  @chapter Routing overview
    16.5  
    16.6  @menu
    16.7 -* Routing-Overview::
    16.8 -* Support for multiple routing protocols::
    16.9 -* Roadmap and Future work::
   16.10 -* Static routing::
   16.11 +* Routing architecture::
   16.12 +* Global centralized routing::
   16.13  * Unicast routing::
   16.14  * Multicast routing::
   16.15 -* Global centralized routing::
   16.16 -* Global Unicast Routing API::
   16.17 -* Global Routing Implementation::
   16.18 -* Optimized Link State Routing (OLSR)::
   16.19  @end menu
   16.20  
   16.21 -This chapter describes the overall design of routing in the 
   16.22 -@code{src/internet-stack}
   16.23 -module, and some details about the routing approachs currently
   16.24 -implemented.
   16.25 +ns-3 is intended to support traditional routing approaches and protocols,
   16.26 +support ports of open source routing implementations, and facilitate research
   16.27 +into unorthodox routing techniques.  The overall routing architecture
   16.28 +is described below in @ref{Routing architecture}.  Users who wish to 
   16.29 +just read about how to configure global routing for wired topologies
   16.30 +can read @ref{Global centralized routing}.  Unicast routing protocols 
   16.31 +are described in @ref{Unicast routing}.  Multicast routing is documented in
   16.32 +@ref{Multicast routing}.
   16.33  
   16.34 -@node Routing-Overview
   16.35 -@section Overview
   16.36 +@node Routing architecture
   16.37 +@section Routing architecture
   16.38  
   16.39 -We intend to support traditional routing approaches and protocols,
   16.40 -ports of open source routing implementations, and facilitate research
   16.41 -into unorthodox routing techniques.
   16.42 -For simulations that are not primarily focused on routing and that
   16.43 -simply want correct routing tables to occur somehow, we have an
   16.44 -global centralized routing capability.  A singleton object
   16.45 -(GlobalRouteManager) be instantiated, builds a network map, and
   16.46 -populates a forwarding table on each node at time t=0 in the
   16.47 -simulation.  Simulation script writers can use the same node
   16.48 -API to manually enter routes as well.
   16.49 +@float Figure,fig:routing
   16.50 +@caption{Overview of routing}
   16.51 +@image{figures/routing, 6in}
   16.52 +@end float
   16.53  
   16.54 -@node Support for multiple routing protocols
   16.55 -@section Support for multiple routing protocols
   16.56 +Figure 11-1 shows the overall routing architecture for Ipv4.  The key objects
   16.57 +are Ipv4L3Protocol, Ipv4RoutingProtocol(s) (a class to which all 
   16.58 +routing/forwarding has been delegated from Ipv4L3Protocol), and Ipv4Route(s).
   16.59  
   16.60 +Ipv4L3Protocol must have at least one Ipv4RoutingProtocol added to
   16.61 +it at simulation setup time.  This is done explicitly by calling
   16.62 +Ipv4::SetRoutingProtocol ().
   16.63 +
   16.64 +The abstract base class Ipv4RoutingProtocol () declares a minimal interface,
   16.65 +consisting of two methods:  RouteOutput () and RouteInput ().  
   16.66 +For packets traveling outbound from a host, the transport protocol will query
   16.67 +Ipv4 for the Ipv4RoutingProtocol object interface, and will request
   16.68 +a route via Ipv4RoutingProtocol::RouteOutput ().
   16.69 +A Ptr to Ipv4Route object is returned.  This is analagous to a
   16.70 +dst_cache entry in Linux.  The Ipv4Route is carried down to the
   16.71 +Ipv4L3Protocol to avoid a second lookup there.  However, some
   16.72 +cases (e.g. Ipv4 raw sockets) will require a call to RouteOutput()
   16.73 +directly from Ipv4L3Protocol.
   16.74 +
   16.75 +For packets received inbound for forwarding or delivery, 
   16.76 +the following steps occur.  Ipv4L3Protocol::Receive() calls 
   16.77 +Ipv4RoutingProtocol::RouteInput().
   16.78 +This passes the packet ownership to the Ipv4RoutingProtocol object.  There
   16.79 +are four callbacks associated with this call:
   16.80 +@itemize @bullet
   16.81 +@item LocalDeliver 
   16.82 +@item UnicastForward
   16.83 +@item MulticastForward
   16.84 +@item Error
   16.85 +@end itemize  
   16.86 +The Ipv4RoutingProtocol must eventually call one of these callbacks for each
   16.87 +packet that it takes responsibility for.  This is basically
   16.88 +how the input routing process works in Linux.
   16.89 +
   16.90 +@float Figure,fig:routing-specialization
   16.91 +@caption{Ipv4Routing specialization}
   16.92 +@image{figures/routing-specialization, 5in}
   16.93 +@end float
   16.94 +
   16.95 +This overall architecture is designed to support different routing
   16.96 +approaches, including (in the future) a Linux-like policy-based routing
   16.97 +implementation, proactive and on-demand routing protocols, and simple
   16.98 +routing protocols for when the simulation user does not really care
   16.99 +about routing.
  16.100 +
  16.101 +@ref{fig:routing-specialization} illustrates how multiple routing protocols
  16.102 +derive from this base class.  A class Ipv4ListRouting
  16.103 +(implementation class Ipv4ListRoutingImpl) provides the existing
  16.104 +list routing approach in ns-3.  Its API is the same as base class
  16.105 +Ipv4Routing except for the ability to add multiple prioritized routing
  16.106 +protocols 
  16.107 +(Ipv4ListRouting::AddRoutingProtocol(), Ipv4ListRouting::GetRoutingProtocol()).
  16.108 +
  16.109 +The details of these routing protocols are described below in
  16.110 +@ref{Unicast routing}.  For now, we will first start with a basic
  16.111 +unicast routing capability that is intended to globally build routing
  16.112 +tables at simulation time t=0 for simulation users who do not care
  16.113 +about dynamic routing.
  16.114 +
  16.115 +@node Global centralized routing
  16.116 +@section Global centralized routing
  16.117 +
  16.118 +Global centralized routing is sometimes called ''God'' routing; it
  16.119 +is a special implementation that walks the simulation topology and
  16.120 +runs a shortest path algorithm, and populates each node's routing
  16.121 +tables.  No actual protocol overhead (on the simulated links) is incurred
  16.122 +with this approach.  It does have a few constraints:
  16.123 +
  16.124 +@itemize @bullet
  16.125 +@item @strong{Wired only:}  It is not intended for use in wireless networks.
  16.126 +@item @strong{Unicast only:} It does not do multicast.
  16.127 +@item @strong{Scalability:}  Some users of this on large topologies 
  16.128 +(e.g. 1000 nodes) 
  16.129 +have noticed that the current implementation is not very scalable.  
  16.130 +The global centralized routing will be modified in the future to
  16.131 +reduce computations and runtime performance.
  16.132 +@end itemize
  16.133 +
  16.134 +Presently, global centralized IPv4 unicast routing over both 
  16.135 +point-to-point and shared (CSMA) links is supported.
  16.136 +
  16.137 +@subsection Global Unicast Routing API
  16.138 +
  16.139 +The public API is very minimal.  User scripts include the following:
  16.140 +@verbatim
  16.141 +#include "ns3/global-route-manager.h"
  16.142 +@end verbatim
  16.143 +
  16.144 +After IP addresses are configured, the following function call will
  16.145 +cause all of the nodes that have an Ipv4 interface to receive
  16.146 +forwarding tables entered automatically by the GlobalRouteManager:
  16.147 +@verbatim
  16.148 +  GlobalRouteManager::PopulateRoutingTables ();
  16.149 +@end verbatim
  16.150 +
  16.151 +@emph{Note:} A reminder that the wifi NetDevice will work but does not
  16.152 +take any wireless effects into account.  For wireless, we recommend
  16.153 +OLSR dynamic routing described below.
  16.154 +
  16.155 +It is possible to call this function again in the midst of a simulation
  16.156 +using the following additional public function:
  16.157 +@verbatim
  16.158 +  GlobalRouteManager::RecomputeRoutingTables ();
  16.159 +@end verbatim
  16.160 +which flushes the old tables, queries the nodes for new interface information,
  16.161 +and rebuilds the routes.
  16.162 +
  16.163 +For instance, this scheduling call will cause the tables to be rebuilt
  16.164 +at time 5 seconds:
  16.165 +@verbatim
  16.166 +  Simulator::Schedule (Seconds (5),&GlobalRouteManager::RecomputeRoutingTables);
  16.167 +@end verbatim
  16.168 +
  16.169 +@subsection Global Routing Implementation
  16.170 +
  16.171 +This section is for those readers who care about how this is implemented.
  16.172 +A singleton object (GlobalRouteManager) is responsible for populating
  16.173 +the static routes on each node, using the public Ipv4 API of that node.
  16.174 +It queries each node in the topology for a "globalRouter" interface.
  16.175 +If found, it uses the API of that interface to obtain a "link state
  16.176 +advertisement (LSA)" for the router.  Link State Advertisements
  16.177 +are used in OSPF routing, and we follow their formatting.
  16.178 +
  16.179 +The GlobalRouteManager populates a link state database with LSAs
  16.180 +gathered from the entire topology.  Then, for each router in the topology,
  16.181 +the GlobalRouteManager executes the OSPF shortest path first (SPF)
  16.182 +computation on the database, and populates the routing tables on each
  16.183 +node.
  16.184 +
  16.185 +The quagga (http://www.quagga.net) OSPF implementation was used as the
  16.186 +basis for the routing computation logic.
  16.187 +One benefit of following an existing OSPF SPF implementation is that
  16.188 +OSPF already has defined link state advertisements for all common
  16.189 +types of network links:
  16.190 +@itemize @bullet
  16.191 +@item point-to-point (serial links)
  16.192 +@item point-to-multipoint (Frame Relay, ad hoc wireless)
  16.193 +@item non-broadcast multiple access (ATM)
  16.194 +@item broadcast (Ethernet)
  16.195 +@end itemize
  16.196 +Therefore, we think that enabling these other link types will be more
  16.197 +straightforward now that the underlying OSPF SPF framework is in place.
  16.198 +
  16.199 +Presently, we can handle IPv4 point-to-point, numbered links, as well
  16.200 +as shared broadcast (CSMA) links, and we do not do equal-cost multipath.  
  16.201 +
  16.202 +The GlobalRouteManager first walks the list of nodes and aggregates
  16.203 +a GlobalRouter interface to each one as follows:
  16.204 +@verbatim
  16.205 +  typedef std::vector < Ptr<Node> >::iterator Iterator;
  16.206 +  for (Iterator i = NodeList::Begin (); i != NodeList::End (); i++)
  16.207 +    {
  16.208 +      Ptr<Node> node = *i;
  16.209 +      Ptr<GlobalRouter> globalRouter = CreateObject<GlobalRouter> (node);
  16.210 +      node->AggregateObject (globalRouter);
  16.211 +    }
  16.212 +@end verbatim
  16.213 +
  16.214 +This interface is later queried and used to generate a Link State
  16.215 +Advertisement for each router, and this link state database is
  16.216 +fed into the OSPF shortest path computation logic.  The Ipv4 API
  16.217 +is finally used to populate the routes themselves. 
  16.218 +
  16.219 +@node Unicast routing
  16.220 +@section Unicast routing
  16.221 +
  16.222 +There are presently four routing protocols defined:
  16.223 +@itemize @bullet
  16.224 +@item class Ipv4StaticRouting (covering both unicast and multicast)
  16.225 +@item  Optimized Link State Routing (a MANET protocol defined in
  16.226 +@uref{http://www.ietf.org/rfc/rfc3626.txt,,RFC 3626})
  16.227 +@item class Ipv4ListRouting (used to store a prioritized list of routing
  16.228 +protocols)
  16.229 +@item class Ipv4GlobalRouting (used to store routes computed by the global
  16.230 +route manager, if that is used)
  16.231 +@end itemize
  16.232 +
  16.233 +In the future, this architecture should also allow someone to implement
  16.234 +a Linux-like implementation with routing cache, or a Click modular
  16.235 +router, but those are out of scope for now.
  16.236 +
  16.237 +@subsection Ipv4ListRouting
  16.238 +
  16.239 +This section describes the current default ns-3 Ipv4RoutingProtocol.
  16.240  Typically, multiple routing protocols are supported in user space and
  16.241  coordinate to write a single forwarding table in the kernel.  Presently
  16.242  in @command{ns-3}, the implementation instead allows for multiple routing 
  16.243 @@ -50,163 +223,54 @@
  16.244  routing) is used to determine the next hop, and on-demand
  16.245  routing approaches where packets must be cached.  
  16.246  
  16.247 -There are presently two routing protocols defined:
  16.248 -@itemize @bullet
  16.249 -@item class Ipv4StaticRouting (covering both unicast and multicast)
  16.250 -@item  Optimized Link State Routing (a MANET protocol defined in
  16.251 -@uref{http://www.ietf.org/rfc/rfc3626.txt,,RFC 3626})
  16.252 -@end itemize
  16.253 -but first we describe how multiple routing protocols are supported. 
  16.254 +@subsubsection Ipv4ListRouting::AddRoutingProtocol
  16.255  
  16.256 -@subsection class Ipv4RoutingProtocol
  16.257 -
  16.258 -@code{class Ipv4RoutingProtocol} derives from ns-3 Object which means
  16.259 -that it supports interface aggregation and reference counting.  Routing
  16.260 -protocols should inherit from this class, defined in src/node/ipv4.cc. 
  16.261 -
  16.262 -The main function that must be supported by these protocols is called
  16.263 -@code{RequestRoute}.
  16.264 -@verbatim
  16.265 -   * This method is called whenever a node's IPv4 forwarding engine
  16.266 -   * needs to lookup a route for a given packet and IP header.
  16.267 -   *
  16.268 -   * The routing protocol implementation may determine immediately it
  16.269 -   * should not be handling this particular the route request.  For
  16.270 -   * instance, a routing protocol may decline to search for routes for
  16.271 -   * certain classes of addresses, like link-local.  In this case,
  16.272 -   * RequestRoute() should return false and the routeReply callback
  16.273 -   * must not be invoked.
  16.274 -   * 
  16.275 -   * If the routing protocol implementations assumes it can provide
  16.276 -   * the requested route, then it should return true, and the
  16.277 -   * routeReply callback must be invoked, either immediately before
  16.278 -   * returning true (synchronously), or in the future (asynchronous).
  16.279 -   * The routing protocol may use any information available in the IP
  16.280 -   * header and packet as routing key, although most routing protocols
  16.281 -   * use only the destination address (as given by
  16.282 -   * ipHeader.GetDestination ()).  The routing protocol is also
  16.283 -   * allowed to add a new header to the packet, which will appear
  16.284 -   * immediately after the IP header, although most routing do not
  16.285 -   * insert any extra header.
  16.286 -   */
  16.287 -  virtual bool RequestRoute (uint32_t interface,
  16.288 -                             const Ipv4Header &ipHeader,
  16.289 -                             Ptr<Packet> packet,
  16.290 -                             RouteReplyCallback routeReply) = 0;
  16.291 -@end verbatim
  16.292 -
  16.293 -This class also provides a typedef (used above) for a special Callback 
  16.294 -that will pass to the callback function the Ipv4Route that is found (see the
  16.295 -Doxygen documentation):
  16.296 -@verbatim
  16.297 -  typedef Callback<void, bool, const Ipv4Route&, Ptr<Packet>, const Ipv4Header&> RouteReplyCallback;
  16.298 -@end verbatim
  16.299 -
  16.300 -@subsection Ipv4::AddRoutingProtocol
  16.301 -
  16.302 -Class Ipv4 provides a pure virtual function declaration for the
  16.303 +Class Ipv4ListRouting provides a pure virtual function declaration for the
  16.304  method that allows one to add a routing protocol:
  16.305  @verbatim
  16.306    void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
  16.307                             int16_t priority);
  16.308  @end verbatim
  16.309 -This method is implemented by class Ipv4L3Protocol in the internet-stack
  16.310 +This method is implemented by class Ipv4ListRoutingImpl in the internet-stack
  16.311  module.
  16.312  
  16.313  The priority variable above governs the priority in which the routing
  16.314  protocols are inserted.  Notice that it is a signed int.
  16.315 -When the class Ipv4L3Protocol is instantiated, a single routing
  16.316 -protocol (Ipv4StaticRouting, introduced below) is added at priority
  16.317 -zero.  Internally, a list of Ipv4RoutingProtocols is stored, and
  16.318 +By default in ns-3, the helper classes will instantiate a Ipv4ListRoutingImpl
  16.319 +object, and add to it an Ipv4StaticRoutingImpl object at priority zero. 
  16.320 +Internally, a list of Ipv4RoutingProtocols is stored, and
  16.321  and the routing protocols are each consulted in decreasing order
  16.322  of priority to see whether a match is found.  Therefore, if you
  16.323  want your Ipv4RoutingProtocol to have priority lower than the static
  16.324  routing, insert it with priority less than 0; e.g.:
  16.325  @verbatim
  16.326 -  m_ipv4->AddRoutingProtocol (m_routingTable, -10);
  16.327 +  Ptr<MyRoutingProtocol> myRoutingProto = CreateObject<MyRoutingProtocol> ();
  16.328 +  listRoutingPtr->AddRoutingProtocol (myRoutingProto, -10);
  16.329  @end verbatim
  16.330  
  16.331 -@subsection Ipv4L3Protocol::Lookup
  16.332 +Upon calls to RouteOutput() or RouteInput(), the list routing object will 
  16.333 +search the list of routing protocols, in priority order, until a route 
  16.334 +is found.  Such routing protocol will invoke the appropriate callback
  16.335 +and no further routing protocols will be searched.  
  16.336  
  16.337 -The main function for obtaining a route is shown below:  
  16.338 +@subsection Optimized Link State Routing (OLSR)
  16.339 +
  16.340 +This is the first dynamic routing protocol for @command{ns-3}.  The implementation
  16.341 +is found in the src/routing/olsr directory, and an example script is in
  16.342 +examples/simple-point-to-point-olsr.cc.
  16.343 +
  16.344 +The following commands will enable OLSR in a simulation.  
  16.345 +
  16.346  @verbatim
  16.347 -Ipv4L3Protocol::Lookup (
  16.348 -  uint32_t interface,
  16.349 -  Ipv4Header const &ipHeader,
  16.350 -  Ptr<Packet> packet,
  16.351 -  Ipv4RoutingProtocol::RouteReplyCallback routeReply)
  16.352 +  olsr::EnableAllNodes ();  // Start OLSR on all nodes
  16.353 +  olsr::EnableNodes(InputIterator begin, InputIterator end); // Start on
  16.354 +    // a list of nodes
  16.355 +  olsr::EnableNode (Ptr<Node> node);  // Start OLSR on "node" only
  16.356  @end verbatim
  16.357  
  16.358 -This function will search the list of routing protocols, in priority order,
  16.359 -until a route is found.  It will then invoke the RouteReplyCallback
  16.360 -and no further routing protocols will be searched.  If the caller does
  16.361 -not want to constrain the possible interface, it can be wildcarded
  16.362 -as such:
  16.363 -@verbatim
  16.364 -  Lookup (Ipv4RoutingProtocol::IF_INDEX_ANY, ipHeader, packet, routeReply);
  16.365 -@end verbatim
  16.366 -
  16.367 -@node Roadmap and Future work
  16.368 -@section Roadmap and Future work
  16.369 -
  16.370 -Some goals for future support are:
  16.371 -
  16.372 -Users should be able to trace (either debug print, or redirect to a trace
  16.373 -file) the routing table in a format such as used in an
  16.374 -Unix implementation:
  16.375 -@verbatim
  16.376 -# netstat -nr (or # route -n)
  16.377 -Kernel IP routing table
  16.378 -Destination   Gateway      Genmask         Flags  MSS Window  irtt Iface
  16.379 -127.0.0.1     *            255.255.255.255 UH       0 0          0 lo
  16.380 -172.16.1.0    *            255.255.255.0   U        0 0          0 eth0
  16.381 -172.16.2.0    172.16.1.1   255.255.255.0   UG       0 0          0 eth0
  16.382 -
  16.383 -# ip route show
  16.384 -192.168.99.0/24 dev eth0  scope link 
  16.385 -127.0.0.0/8 dev lo  scope link 
  16.386 -default via 192.168.99.254 dev eth0
  16.387 -@end verbatim
  16.388 -
  16.389 -Global computation of multicast routing should be implemented as well.  
  16.390 -This would ignore group membership and ensure that a copy of every 
  16.391 -sourced multicast datagram would be delivered to each node.  
  16.392 -This might be implemented as an RPF mechanism that functioned on-demand 
  16.393 -by querying the forwarding table,
  16.394 -and perhaps optimized by a small multicast forwarding cache.  It is
  16.395 -a bit trickier to implement over wireless links where the input
  16.396 -interface is the same as the output interface; other aspects of the
  16.397 -packet must be considered and the forwarding logic slightly changed
  16.398 -to allow for forwarding out the same interface.
  16.399 -
  16.400 -In the future, work on bringing XORP or quagga routing to ns, but it will
  16.401 -take several months to port and enable.
  16.402 -
  16.403 -There are presently no roadmap plans for IPv6.
  16.404 -
  16.405 -@node Static routing
  16.406 -@section Static routing
  16.407 -
  16.408 -The internet-stack module provides one routing protocol (Ipv4StaticRouting)
  16.409 -by default.  This routing protocol allows one to add unicast or multicast
  16.410 -static routes to a node.
  16.411 -
  16.412 -@node Unicast routing
  16.413 -@section Unicast routing
  16.414 -
  16.415 -The unicast static routing API may be accessed via the functions
  16.416 -@verbatim
  16.417 -void Ipv4::AddHostRouteTo ()
  16.418 -void Ipv4::AddNetworkRouteTo () 
  16.419 -void Ipv4::SetDefaultRoute ()
  16.420 -uint32_t Ipv4::GetNRoutes ()
  16.421 -Ipv4Route Ipv4::GetRoute ()
  16.422 -@end verbatim
  16.423 -
  16.424 -@uref{http://www.nsnam.org/doxygen/index.html,,Doxygen} documentation
  16.425 -provides full documentation of these methods.  These methods are forwarding
  16.426 -functions to the actual implementation in Ipv4StaticRouting, when using
  16.427 -the internet-stack module.
  16.428 +Once instantiated, the agent can be started with the Start() command,
  16.429 +and the OLSR "main interface" can be set with the SetMainInterface()
  16.430 +command.  A number of protocol constants are defined in olsr-agent-impl.cc.
  16.431  
  16.432  @node Multicast routing
  16.433  @section Multicast routing
  16.434 @@ -288,113 +352,4 @@
  16.435    void RemoveMulticastRoute (uint32_t index);
  16.436  @end verbatim
  16.437  
  16.438 -@node Global centralized routing
  16.439 -@section Global centralized routing
  16.440  
  16.441 -Presently, global centralized IPv4 @emph{unicast} routing over both 
  16.442 -point-to-point and shared (CSMA) links is supported.
  16.443 -The global centralized routing will be modified in the future to
  16.444 -reduce computations once profiling finds the performance bottlenecks.
  16.445 -
  16.446 -@node Global Unicast Routing API
  16.447 -@section Global Unicast Routing API
  16.448 -
  16.449 -The public API is very minimal.  User scripts include the following:
  16.450 -@verbatim
  16.451 -#include "ns3/global-route-manager.h"
  16.452 -@end verbatim
  16.453 -
  16.454 -After IP addresses are configured, the following function call will
  16.455 -cause all of the nodes that have an Ipv4 interface to receive
  16.456 -forwarding tables entered automatically by the GlobalRouteManager:
  16.457 -@verbatim
  16.458 -  GlobalRouteManager::PopulateRoutingTables ();
  16.459 -@end verbatim
  16.460 -
  16.461 -@emph{Note:} A reminder that the wifi NetDevice is not yet supported
  16.462 -(only CSMA and PointToPoint).
  16.463 -
  16.464 -It is possible to call this function again in the midst of a simulation
  16.465 -using the following additional public function:
  16.466 -@verbatim
  16.467 -  GlobalRouteManager::RecomputeRoutingTables ();
  16.468 -@end verbatim
  16.469 -which flushes the old tables, queries the nodes for new interface information,
  16.470 -and rebuilds the routes.
  16.471 -
  16.472 -For instance, this scheduling call will cause the tables to be rebuilt
  16.473 -at time 5 seconds:
  16.474 -@verbatim
  16.475 -  Simulator::Schedule (Seconds (5),&GlobalRouteManager::RecomputeRoutingTables);
  16.476 -@end verbatim
  16.477 -
  16.478 -@node Global Routing Implementation
  16.479 -@section Global Routing Implementation
  16.480 -
  16.481 -A singleton object (GlobalRouteManager) is responsible for populating
  16.482 -the static routes on each node, using the public Ipv4 API of that node.
  16.483 -It queries each node in the topology for a "globalRouter" interface.
  16.484 -If found, it uses the API of that interface to obtain a "link state
  16.485 -advertisement (LSA)" for the router.  Link State Advertisements
  16.486 -are used in OSPF routing, and we follow their formatting.
  16.487 -
  16.488 -The GlobalRouteManager populates a link state database with LSAs
  16.489 -gathered from the entire topology.  Then, for each router in the topology,
  16.490 -the GlobalRouteManager executes the OSPF shortest path first (SPF)
  16.491 -computation on the database, and populates the routing tables on each
  16.492 -node.
  16.493 -
  16.494 -The quagga (http://www.quagga.net) OSPF implementation was used as the
  16.495 -basis for the routing computation logic.
  16.496 -One benefit of following an existing OSPF SPF implementation is that
  16.497 -OSPF already has defined link state advertisements for all common
  16.498 -types of network links:
  16.499 -@itemize @bullet
  16.500 -@item point-to-point (serial links)
  16.501 -@item point-to-multipoint (Frame Relay, ad hoc wireless)
  16.502 -@item non-broadcast multiple access (ATM)
  16.503 -@item broadcast (Ethernet)
  16.504 -@end itemize
  16.505 -Therefore, we think that enabling these other link types will be more
  16.506 -straightforward now that the underlying OSPF SPF framework is in place.
  16.507 -
  16.508 -Presently, we can handle IPv4 point-to-point, numbered links, as well
  16.509 -as shared broadcast (CSMA) links, and we do not do equal-cost multipath.  
  16.510 -
  16.511 -The GlobalRouteManager first walks the list of nodes and aggregates
  16.512 -a GlobalRouter interface to each one as follows:
  16.513 -@verbatim
  16.514 -  typedef std::vector < Ptr<Node> >::iterator Iterator;
  16.515 -  for (Iterator i = NodeList::Begin (); i != NodeList::End (); i++)
  16.516 -    {
  16.517 -      Ptr<Node> node = *i;
  16.518 -      Ptr<GlobalRouter> globalRouter = CreateObject<GlobalRouter> (node);
  16.519 -      node->AggregateObject (globalRouter);
  16.520 -    }
  16.521 -@end verbatim
  16.522 -
  16.523 -This interface is later queried and used to generate a Link State
  16.524 -Advertisement for each router, and this link state database is
  16.525 -fed into the OSPF shortest path computation logic.  The Ipv4 API
  16.526 -is finally used to populate the routes themselves. 
  16.527 -
  16.528 -@node Optimized Link State Routing (OLSR)
  16.529 -@section Optimized Link State Routing (OLSR)
  16.530 -
  16.531 -This is the first dynamic routing protocol for @command{ns-3}.  The implementation
  16.532 -is found in the src/routing/olsr directory, and an example script is in
  16.533 -examples/simple-point-to-point-olsr.cc.
  16.534 -
  16.535 -The following commands will enable OLSR in a simulation.  
  16.536 -
  16.537 -@verbatim
  16.538 -  olsr::EnableAllNodes ();  // Start OLSR on all nodes
  16.539 -  olsr::EnableNodes(InputIterator begin, InputIterator end); // Start on
  16.540 -    // a list of nodes
  16.541 -  olsr::EnableNode (Ptr<Node> node);  // Start OLSR on "node" only
  16.542 -@end verbatim
  16.543 -
  16.544 -Once instantiated, the agent can be started with the Start() command,
  16.545 -and the OLSR "main interface" can be set with the SetMainInterface()
  16.546 -command.  A number of protocol constants are defined in olsr-agent-impl.cc.
  16.547 -
    17.1 --- a/examples/mixed-wireless.cc	Tue Jun 09 18:00:24 2009 +0100
    17.2 +++ b/examples/mixed-wireless.cc	Tue Jun 09 18:00:52 2009 +0100
    17.3 @@ -392,9 +392,9 @@
    17.4        // Let's do a pcap trace on the application source and sink, ifIndex 0
    17.5        // Csma captures in non-promiscuous mode
    17.6        CsmaHelper::EnablePcap ("mixed-wireless", appSource->GetId (), 0, false);
    17.7 -      YansWifiPhyHelper::EnablePcap ("mixed-wireless", appSink->GetId (), 0);
    17.8 -      YansWifiPhyHelper::EnablePcap ("mixed-wireless", 9, 2);
    17.9 -      YansWifiPhyHelper::EnablePcap ("mixed-wireless", 9, 0);
   17.10 +      wifiPhy.EnablePcap ("mixed-wireless", appSink->GetId (), 0);
   17.11 +      wifiPhy.EnablePcap ("mixed-wireless", 9, 2);
   17.12 +      wifiPhy.EnablePcap ("mixed-wireless", 9, 0);
   17.13      }
   17.14  
   17.15    if (useCourseChangeCallback == true)
    18.1 --- a/examples/object-names.cc	Tue Jun 09 18:00:24 2009 +0100
    18.2 +++ b/examples/object-names.cc	Tue Jun 09 18:00:52 2009 +0100
    18.3 @@ -151,7 +151,7 @@
    18.4    // prefix is always required since the _Config_ system always expects to 
    18.5    // see a fully qualified path name 
    18.6    //
    18.7 -  Config::Connect ("/Names/client/eth0/Rx", MakeCallback (&RxEvent));
    18.8 +  Config::Connect ("/Names/client/eth0/MacRx", MakeCallback (&RxEvent));
    18.9  
   18.10    Simulator::Run ();
   18.11    Simulator::Destroy ();
    19.1 --- a/examples/simple-wifi-frame-aggregation.cc	Tue Jun 09 18:00:24 2009 +0100
    19.2 +++ b/examples/simple-wifi-frame-aggregation.cc	Tue Jun 09 18:00:52 2009 +0100
    19.3 @@ -141,7 +141,7 @@
    19.4  
    19.5    Simulator::Stop (Seconds (10.0));
    19.6    
    19.7 -  YansWifiPhyHelper::EnablePcap ("test-802.11n", 
    19.8 +  phy.EnablePcap ("test-802.11n", 
    19.9      wifiNodes.Get (nWifi - 1)->GetId (), 0);
   19.10  
   19.11    Simulator::Run ();
    20.1 --- a/examples/stats/wifi-example-apps.cc	Tue Jun 09 18:00:24 2009 +0100
    20.2 +++ b/examples/stats/wifi-example-apps.cc	Tue Jun 09 18:00:52 2009 +0100
    20.3 @@ -131,7 +131,7 @@
    20.4  
    20.5    TimestampTag timestamp;
    20.6    timestamp.SetTimestamp(Simulator::Now());
    20.7 -  packet->AddTag(timestamp);
    20.8 +  packet->AddByteTag (timestamp);
    20.9  
   20.10    // Could connect the socket since the address never changes; using SendTo
   20.11    // here simply because all of the standard apps do not.
   20.12 @@ -250,7 +250,7 @@
   20.13      }
   20.14  
   20.15      TimestampTag timestamp;
   20.16 -    packet->FindFirstMatchingTag(timestamp);
   20.17 +    packet->FindFirstMatchingByteTag(timestamp);
   20.18      Time tx = timestamp.GetTimestamp();
   20.19  
   20.20      if (m_delay != 0) {
    21.1 --- a/examples/third.cc	Tue Jun 09 18:00:24 2009 +0100
    21.2 +++ b/examples/third.cc	Tue Jun 09 18:00:52 2009 +0100
    21.3 @@ -164,7 +164,7 @@
    21.4    Simulator::Stop (Seconds (10.0));
    21.5  
    21.6    PointToPointHelper::EnablePcapAll ("third");
    21.7 -  YansWifiPhyHelper::EnablePcap ("third", apDevices.Get (0));
    21.8 +  phy.EnablePcap ("third", apDevices.Get (0));
    21.9    CsmaHelper::EnablePcap ("third", csmaDevices.Get (0), true);
   21.10  
   21.11    Simulator::Run ();
    22.1 --- a/examples/wifi-wired-bridging.cc	Tue Jun 09 18:00:24 2009 +0100
    22.2 +++ b/examples/wifi-wired-bridging.cc	Tue Jun 09 18:00:52 2009 +0100
    22.3 @@ -89,6 +89,10 @@
    22.4    backboneDevices = csma.Install (backboneNodes);
    22.5  
    22.6    double wifiX = 0.0;
    22.7 +
    22.8 +  YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
    22.9 +  wifiPhy.SetPcapFormat(YansWifiPhyHelper::PCAP_FORMAT_80211_RADIOTAP);
   22.10 +
   22.11    for (uint32_t i = 0; i < nWifis; ++i)
   22.12      {
   22.13        // calculate ssid for wifi subnetwork
   22.14 @@ -105,7 +109,6 @@
   22.15        BridgeHelper bridge;
   22.16        WifiHelper wifi = WifiHelper::Default ();
   22.17        NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
   22.18 -      YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
   22.19        YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
   22.20        wifiPhy.SetChannel (wifiChannel.Create ());
   22.21  
   22.22 @@ -182,8 +185,8 @@
   22.23    apps.Start (Seconds (0.5));
   22.24    apps.Stop (Seconds (3.0));
   22.25    
   22.26 -  YansWifiPhyHelper::EnablePcap ("wifi-wired-bridging", apDevices[0]);
   22.27 -  YansWifiPhyHelper::EnablePcap ("wifi-wired-bridging", apDevices[1]);
   22.28 +  wifiPhy.EnablePcap ("wifi-wired-bridging", apDevices[0]);
   22.29 +  wifiPhy.EnablePcap ("wifi-wired-bridging", apDevices[1]);
   22.30  
   22.31    std::ofstream os;
   22.32    os.open ("wifi-wired-bridging.mob");
    23.1 --- a/samples/main-packet-tag.cc	Tue Jun 09 18:00:24 2009 +0100
    23.2 +++ b/samples/main-packet-tag.cc	Tue Jun 09 18:00:52 2009 +0100
    23.3 @@ -101,19 +101,19 @@
    23.4  
    23.5    // store the tag in a packet.
    23.6    Ptr<Packet> p = Create<Packet> (100);
    23.7 -  p->AddTag (tag);
    23.8 +  p->AddPacketTag (tag);
    23.9  
   23.10    // create a copy of the packet
   23.11    Ptr<Packet> aCopy = p->Copy ();
   23.12  
   23.13    // read the tag from the packet copy
   23.14    MyTag tagCopy;
   23.15 -  p->FindFirstMatchingTag (tagCopy);
   23.16 +  p->PeekPacketTag (tagCopy);
   23.17  
   23.18    // the copy and the original are the same !
   23.19    NS_ASSERT (tagCopy.GetSimpleValue () == tag.GetSimpleValue ());
   23.20  
   23.21 -  aCopy->PrintTags (std::cout);
   23.22 +  aCopy->PrintPacketTags (std::cout);
   23.23    std::cout << std::endl;
   23.24  
   23.25    return 0;
    24.1 --- a/samples/wscript	Tue Jun 09 18:00:24 2009 +0100
    24.2 +++ b/samples/wscript	Tue Jun 09 18:00:52 2009 +0100
    24.3 @@ -10,6 +10,9 @@
    24.4      obj = bld.create_ns3_program('main-simulator')
    24.5      obj.source = 'main-simulator.cc'
    24.6  
    24.7 +    obj = bld.create_ns3_program('main-ptr')
    24.8 +    obj.source = 'main-ptr.cc'
    24.9 +
   24.10      obj = bld.create_ns3_program('main-random-variable')
   24.11      obj.source = 'main-random-variable.cc'
   24.12  
    25.1 --- a/src/applications/packet-sink/packet-sink.cc	Tue Jun 09 18:00:24 2009 +0100
    25.2 +++ b/src/applications/packet-sink/packet-sink.cc	Tue Jun 09 18:00:52 2009 +0100
    25.3 @@ -142,8 +142,7 @@
    25.4          {
    25.5            InetSocketAddress address = InetSocketAddress::ConvertFrom (from);
    25.6            NS_LOG_INFO ("Received " << packet->GetSize() << " bytes from " << 
    25.7 -            address.GetIpv4() << " [" << address << "]---'" << 
    25.8 -            packet->PeekData() << "'");
    25.9 +            address.GetIpv4() << " [" << address << "]");
   25.10          }    
   25.11        m_rxTrace (packet, from);
   25.12      }
    26.1 --- a/src/applications/udp-echo/udp-echo-server.cc	Tue Jun 09 18:00:24 2009 +0100
    26.2 +++ b/src/applications/udp-echo/udp-echo-server.cc	Tue Jun 09 18:00:52 2009 +0100
    26.3 @@ -121,7 +121,8 @@
    26.4            NS_LOG_INFO ("Received " << packet->GetSize() << " bytes from " << 
    26.5              address.GetIpv4());
    26.6  
    26.7 -          packet->RemoveAllTags ();
    26.8 +          packet->RemoveAllPacketTags ();
    26.9 +          packet->RemoveAllByteTags ();
   26.10  
   26.11            NS_LOG_LOGIC ("Echoing packet");
   26.12            socket->SendTo (packet, 0, from);
    27.1 --- a/src/applications/v4ping/v4ping.cc	Tue Jun 09 18:00:24 2009 +0100
    27.2 +++ b/src/applications/v4ping/v4ping.cc	Tue Jun 09 18:00:52 2009 +0100
    27.3 @@ -87,10 +87,11 @@
    27.4  	  if (echo.GetSequenceNumber () == (m_seq - 1) &&
    27.5  	      echo.GetIdentifier () == 0)
    27.6  	    {
    27.7 -	      Ptr<const Packet> data = echo.GetData ();
    27.8 -	      if (data->GetSize () == 16)
    27.9 +	      uint8_t data[16];
   27.10 +	      uint32_t dataSize = echo.GetData (data);
   27.11 +	      if (dataSize == 16)
   27.12  		{
   27.13 -		  uint32_t *buf = (uint32_t *)data->PeekData ();
   27.14 +		  uint32_t *buf = (uint32_t *)data;
   27.15  		  if (buf[0] == GetNode ()->GetId () &&
   27.16  		      buf[1] == GetApplicationId ())
   27.17  		    {
    28.1 --- a/src/common/buffer.cc	Tue Jun 09 18:00:24 2009 +0100
    28.2 +++ b/src/common/buffer.cc	Tue Jun 09 18:00:52 2009 +0100
    28.3 @@ -643,6 +643,32 @@
    28.4    return m_data->m_data + m_start;
    28.5  }
    28.6  
    28.7 +void
    28.8 +Buffer::CopyData(std::ostream *os, uint32_t size) const
    28.9 +{
   28.10 +  if (size == GetSize ())
   28.11 +    {
   28.12 +      // fast path
   28.13 +      os->write((const char*)(m_data->m_data + m_start), m_zeroAreaStart-m_start);
   28.14 +      char zero = 0;
   28.15 +      for (uint32_t i = 0; i < m_zeroAreaEnd - m_zeroAreaStart; ++i)
   28.16 +        {
   28.17 +          os->write (&zero, 1);
   28.18 +        }
   28.19 +      os->write ((const char*)(m_data->m_data + m_zeroAreaStart), m_end - m_zeroAreaEnd);
   28.20 +    }
   28.21 +  else
   28.22 +    {
   28.23 +      // slow path
   28.24 +      Buffer::Iterator i = Begin ();
   28.25 +      while (!i.IsEnd () && size > 0)
   28.26 +        {
   28.27 +          char byte = i.ReadU8 ();
   28.28 +          os->write (&byte, 1);
   28.29 +        }
   28.30 +    }
   28.31 +}
   28.32 +
   28.33  /******************************************************
   28.34   *            The buffer iterator below.
   28.35   ******************************************************/
    29.1 --- a/src/common/buffer.h	Tue Jun 09 18:00:24 2009 +0100
    29.2 +++ b/src/common/buffer.h	Tue Jun 09 18:00:52 2009 +0100
    29.3 @@ -22,6 +22,7 @@
    29.4  
    29.5  #include <stdint.h>
    29.6  #include <vector>
    29.7 +#include <ostream>
    29.8  
    29.9  #define BUFFER_HEURISTICS 1
   29.10  #define BUFFER_USE_INLINE 1
   29.11 @@ -486,6 +487,8 @@
   29.12    int32_t GetCurrentStartOffset (void) const;
   29.13    int32_t GetCurrentEndOffset (void) const;
   29.14  
   29.15 +  void CopyData (std::ostream *os, uint32_t size) const;
   29.16 +
   29.17    Buffer (Buffer const &o);
   29.18    Buffer &operator = (Buffer const &o);
   29.19    Buffer ();
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/src/common/byte-tag-list.cc	Tue Jun 09 18:00:52 2009 +0100
    30.3 @@ -0,0 +1,421 @@
    30.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
    30.5 +/*
    30.6 + * Copyright (c) 2008 INRIA
    30.7 + *
    30.8 + * This program is free software; you can redistribute it and/or modify
    30.9 + * it under the terms of the GNU General Public License version 2 as
   30.10 + * published by the Free Software Foundation;
   30.11 + *
   30.12 + * This program is distributed in the hope that it will be useful,
   30.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   30.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   30.15 + * GNU General Public License for more details.
   30.16 + *
   30.17 + * You should have received a copy of the GNU General Public License
   30.18 + * along with this program; if not, write to the Free Software
   30.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   30.20 + *
   30.21 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
   30.22 + */
   30.23 +#include "byte-tag-list.h"
   30.24 +#include "ns3/log.h"
   30.25 +#include <vector>
   30.26 +#include <string.h>
   30.27 +
   30.28 +NS_LOG_COMPONENT_DEFINE ("ByteTagList");
   30.29 +
   30.30 +#define USE_FREE_LIST 1
   30.31 +#define FREE_LIST_SIZE 1000
   30.32 +#define OFFSET_MAX (2147483647)
   30.33 +
   30.34 +namespace ns3 {
   30.35 +
   30.36 +struct ByteTagListData {
   30.37 +  uint32_t size;
   30.38 +  uint32_t count;
   30.39 +  uint32_t dirty;
   30.40 +  uint8_t data[4];
   30.41 +};
   30.42 +
   30.43 +#ifdef USE_FREE_LIST
   30.44 +static class ByteTagListDataFreeList : public std::vector<struct ByteTagListData *>
   30.45 +{
   30.46 +public:
   30.47 +  ~ByteTagListDataFreeList ();
   30.48 +} g_freeList;
   30.49 +static uint32_t g_maxSize = 0;
   30.50 +
   30.51 +ByteTagListDataFreeList::~ByteTagListDataFreeList ()
   30.52 +{
   30.53 +  for (ByteTagListDataFreeList::iterator i = begin ();
   30.54 +       i != end (); i++)
   30.55 +    {
   30.56 +      uint8_t *buffer = (uint8_t *)(*i);
   30.57 +      delete [] buffer;
   30.58 +    }
   30.59 +}
   30.60 +#endif /* USE_FREE_LIST */
   30.61 +
   30.62 +ByteTagList::Iterator::Item::Item (TagBuffer buf_)
   30.63 +    : buf (buf_)
   30.64 +{}
   30.65 +
   30.66 +bool 
   30.67 +ByteTagList::Iterator::HasNext (void) const
   30.68 +{
   30.69 +  return m_current < m_end;
   30.70 +}
   30.71 +struct ByteTagList::Iterator::Item 
   30.72 +ByteTagList::Iterator::Next (void)
   30.73 +{
   30.74 +  NS_ASSERT (HasNext ());
   30.75 +  struct Item item = Item (TagBuffer (m_current+16, m_end));
   30.76 +  item.tid.SetUid (m_nextTid);
   30.77 +  item.size = m_nextSize;
   30.78 +  item.start = std::max (m_nextStart, m_offsetStart);
   30.79 +  item.end = std::min (m_nextEnd, m_offsetEnd);
   30.80 +  m_current += 4 + 4 + 4 + 4 + item.size;
   30.81 +  item.buf.TrimAtEnd (m_end - m_current);
   30.82 +  PrepareForNext ();
   30.83 +  return item;
   30.84 +}
   30.85 +void
   30.86 +ByteTagList::Iterator::PrepareForNext (void)
   30.87 +{
   30.88 +  while (m_current < m_end)
   30.89 +    {
   30.90 +      TagBuffer buf = TagBuffer (m_current, m_end);
   30.91 +      m_nextTid = buf.ReadU32 ();
   30.92 +      m_nextSize = buf.ReadU32 ();
   30.93 +      m_nextStart = buf.ReadU32 ();
   30.94 +      m_nextEnd = buf.ReadU32 ();
   30.95 +      if (m_nextStart >= m_offsetEnd || m_nextEnd <= m_offsetStart)
   30.96 +	{
   30.97 +	  m_current += 4 + 4 + 4 + 4 + m_nextSize;
   30.98 +	}
   30.99 +      else
  30.100 +	{
  30.101 +	  break;
  30.102 +	}
  30.103 +    }
  30.104 +}
  30.105 +ByteTagList::Iterator::Iterator (uint8_t *start, uint8_t *end, int32_t offsetStart, int32_t offsetEnd)
  30.106 +  : m_current (start),
  30.107 +    m_end (end),
  30.108 +    m_offsetStart (offsetStart),
  30.109 +    m_offsetEnd (offsetEnd)
  30.110 +{
  30.111 +  PrepareForNext ();
  30.112 +}
  30.113 +
  30.114 +uint32_t 
  30.115 +ByteTagList::Iterator::GetOffsetStart (void) const
  30.116 +{
  30.117 +  return m_offsetStart;
  30.118 +}
  30.119 +
  30.120 +
  30.121 +ByteTagList::ByteTagList ()
  30.122 +  : m_used (0),
  30.123 +    m_data (0)
  30.124 +{
  30.125 +  NS_LOG_FUNCTION (this);
  30.126 +}
  30.127 +ByteTagList::ByteTagList (const ByteTagList &o)
  30.128 +  : m_used (o.m_used),
  30.129 +    m_data (o.m_data)
  30.130 +{
  30.131 +  NS_LOG_FUNCTION (this << &o);
  30.132 +  if (m_data != 0)
  30.133 +    {
  30.134 +      m_data->count++;
  30.135 +    }
  30.136 +}
  30.137 +ByteTagList &
  30.138 +ByteTagList::operator = (const ByteTagList &o)
  30.139 +{
  30.140 +  NS_LOG_FUNCTION (this << &o);
  30.141 +  if (this == &o)
  30.142 +    {
  30.143 +      return *this;
  30.144 +    }
  30.145 +
  30.146 +  Deallocate (m_data);
  30.147 +  m_data = o.m_data;
  30.148 +  m_used = o.m_used;
  30.149 +  if (m_data != 0)
  30.150 +    {
  30.151 +      m_data->count++;
  30.152 +    }
  30.153 +  return *this;
  30.154 +}
  30.155 +ByteTagList::~ByteTagList ()
  30.156 +{
  30.157 +  NS_LOG_FUNCTION (this);
  30.158 +  Deallocate (m_data);
  30.159 +  m_data = 0;
  30.160 +  m_used = 0;
  30.161 +}
  30.162 +
  30.163 +TagBuffer
  30.164 +ByteTagList::Add (TypeId tid, uint32_t bufferSize, int32_t start, int32_t end)
  30.165 +{
  30.166 +  NS_LOG_FUNCTION (this << tid << bufferSize << start << end);
  30.167 +  uint32_t spaceNeeded = m_used + bufferSize + 4 + 4 + 4 + 4;
  30.168 +  NS_ASSERT (m_used <= spaceNeeded);
  30.169 +  if (m_data == 0)
  30.170 +    {
  30.171 +      m_data = Allocate (spaceNeeded);
  30.172 +      m_used = 0;
  30.173 +    } 
  30.174 +  else if (m_data->size < spaceNeeded ||
  30.175 +	   (m_data->count != 1 && m_data->dirty != m_used))
  30.176 +    {
  30.177 +      struct ByteTagListData *newData = Allocate (spaceNeeded);
  30.178 +      memcpy (&newData->data, &m_data->data, m_used);
  30.179 +      Deallocate (m_data);
  30.180 +      m_data = newData;
  30.181 +    }
  30.182 +  TagBuffer tag = TagBuffer (&m_data->data[m_used], 
  30.183 +			     &m_data->data[spaceNeeded]);
  30.184 +  tag.WriteU32 (tid.GetUid ());
  30.185 +  tag.WriteU32 (bufferSize);
  30.186 +  tag.WriteU32 (start);
  30.187 +  tag.WriteU32 (end);
  30.188 +  m_used = spaceNeeded;
  30.189 +  m_data->dirty = m_used;
  30.190 +  return tag;
  30.191 +}
  30.192 +
  30.193 +void 
  30.194 +ByteTagList::Add (const ByteTagList &o)
  30.195 +{
  30.196 +  NS_LOG_FUNCTION (this << &o);
  30.197 +  ByteTagList::Iterator i = o.BeginAll ();
  30.198 +  while (i.HasNext ())
  30.199 +    {
  30.200 +      ByteTagList::Iterator::Item item = i.Next ();
  30.201 +      TagBuffer buf = Add (item.tid, item.size, item.start, item.end);
  30.202 +      buf.CopyFrom (item.buf);
  30.203 +    }
  30.204 +}
  30.205 +
  30.206 +void 
  30.207 +ByteTagList::RemoveAll (void)
  30.208 +{
  30.209 +  NS_LOG_FUNCTION (this);
  30.210 +  Deallocate (m_data);
  30.211 +  m_data = 0;
  30.212 +  m_used = 0;
  30.213 +}
  30.214 +
  30.215 +ByteTagList::Iterator 
  30.216 +ByteTagList::BeginAll (void) const
  30.217 +{
  30.218 +  NS_LOG_FUNCTION (this);
  30.219 +  // I am not totally sure but I might need to use 
  30.220 +  // INT32_MIN instead of zero below.
  30.221 +  return Begin (0, OFFSET_MAX);
  30.222 +}
  30.223 +
  30.224 +ByteTagList::Iterator 
  30.225 +ByteTagList::Begin (int32_t offsetStart, int32_t offsetEnd) const
  30.226 +{
  30.227 +  NS_LOG_FUNCTION (this << offsetStart << offsetEnd);
  30.228 +  if (m_data == 0)
  30.229 +    {
  30.230 +      return Iterator (0, 0, offsetStart, offsetEnd);
  30.231 +    }
  30.232 +  else
  30.233 +    {
  30.234 +      return Iterator (m_data->data, &m_data->data[m_used], offsetStart, offsetEnd);
  30.235 +    }
  30.236 +}
  30.237 +
  30.238 +bool 
  30.239 +ByteTagList::IsDirtyAtEnd (int32_t appendOffset)
  30.240 +{
  30.241 +  NS_LOG_FUNCTION (this << appendOffset);
  30.242 +  ByteTagList::Iterator i = BeginAll ();
  30.243 +  while (i.HasNext ())
  30.244 +    {
  30.245 +      ByteTagList::Iterator::Item item = i.Next ();
  30.246 +      if (item.end > appendOffset)
  30.247 +	{
  30.248 +	  return true;
  30.249 +	}
  30.250 +    }
  30.251 +  return false;
  30.252 +}
  30.253 +
  30.254 +bool 
  30.255 +ByteTagList::IsDirtyAtStart (int32_t prependOffset)
  30.256 +{
  30.257 +  NS_LOG_FUNCTION (this << prependOffset);
  30.258 +  ByteTagList::Iterator i = BeginAll ();
  30.259 +  while (i.HasNext ())
  30.260 +    {
  30.261 +      ByteTagList::Iterator::Item item = i.Next ();
  30.262 +      if (item.start < prependOffset)
  30.263 +	{
  30.264 +	  return true;
  30.265 +	}
  30.266 +    }
  30.267 +  return false;
  30.268 +}
  30.269 +
  30.270 +void 
  30.271 +ByteTagList::AddAtEnd (int32_t adjustment, int32_t appendOffset)
  30.272 +{
  30.273 +  NS_LOG_FUNCTION (this << adjustment << appendOffset);
  30.274 +  if (adjustment == 0 && !IsDirtyAtEnd (appendOffset))
  30.275 +    {
  30.276 +      return;
  30.277 +    }
  30.278 +  ByteTagList list;
  30.279 +  ByteTagList::Iterator i = BeginAll ();
  30.280 +  while (i.HasNext ())
  30.281 +    {
  30.282 +      ByteTagList::Iterator::Item item = i.Next ();
  30.283 +      item.start += adjustment;
  30.284 +      item.end += adjustment;
  30.285 +
  30.286 +      if (item.start >= appendOffset)
  30.287 +	{
  30.288 +	  continue;
  30.289 +	}
  30.290 +      else if (item.start < appendOffset && item.end > appendOffset)
  30.291 +	{
  30.292 +	  item.end = appendOffset;
  30.293 +	}
  30.294 +      else
  30.295 +	{
  30.296 +	  // nothing to do.
  30.297 +	}
  30.298 +      TagBuffer buf = list.Add (item.tid, item.size, item.start, item.end);
  30.299 +      buf.CopyFrom (item.buf);
  30.300 +    }
  30.301 +  *this = list;  
  30.302 +}
  30.303 +
  30.304 +void 
  30.305 +ByteTagList::AddAtStart (int32_t adjustment, int32_t prependOffset)
  30.306 +{
  30.307 +  NS_LOG_FUNCTION (this << adjustment << prependOffset);
  30.308 +  if (adjustment == 0 && !IsDirtyAtStart (prependOffset))
  30.309 +    {
  30.310 +      return;
  30.311 +    }
  30.312 +  ByteTagList list;
  30.313 +  ByteTagList::Iterator i = BeginAll ();
  30.314 +  while (i.HasNext ())
  30.315 +    {
  30.316 +      ByteTagList::Iterator::Item item = i.Next ();
  30.317 +      item.start += adjustment;
  30.318 +      item.end += adjustment;
  30.319 +
  30.320 +      if (item.end <= prependOffset)
  30.321 +	{
  30.322 +	  continue;
  30.323 +	}
  30.324 +      else if (item.end > prependOffset && item.start < prependOffset)
  30.325 +	{
  30.326 +	  item.start = prependOffset;
  30.327 +	}
  30.328 +      else
  30.329 +	{
  30.330 +	  // nothing to do.
  30.331 +	}
  30.332 +      TagBuffer buf = list.Add (item.tid, item.size, item.start, item.end);
  30.333 +      buf.CopyFrom (item.buf);
  30.334 +    }
  30.335 +  *this = list;
  30.336 +}
  30.337 +
  30.338 +#ifdef USE_FREE_LIST
  30.339 +
  30.340 +struct ByteTagListData *
  30.341 +ByteTagList::Allocate (uint32_t size)
  30.342 +{
  30.343 +  NS_LOG_FUNCTION (this << size);
  30.344 +  while (!g_freeList.empty ())
  30.345 +    {
  30.346 +      struct ByteTagListData *data = g_freeList.back ();
  30.347 +      g_freeList.pop_back ();
  30.348 +      NS_ASSERT (data != 0);
  30.349 +      if (data->size >= size)
  30.350 +	{
  30.351 +	  data->count = 1;
  30.352 +	  data->dirty = 0;
  30.353 +	  return data;
  30.354 +	}
  30.355 +      uint8_t *buffer = (uint8_t *)data;
  30.356 +      delete [] buffer;
  30.357 +    }
  30.358 +  uint8_t *buffer = new uint8_t [std::max (size, g_maxSize) + sizeof (struct ByteTagListData) - 4];
  30.359 +  struct ByteTagListData *data = (struct ByteTagListData *)buffer;
  30.360 +  data->count = 1;
  30.361 +  data->size = size;
  30.362 +  data->dirty = 0;
  30.363 +  return data;
  30.364 +}
  30.365 +
  30.366 +void 
  30.367 +ByteTagList::Deallocate (struct ByteTagListData *data)
  30.368 +{
  30.369 +  NS_LOG_FUNCTION (this << data);
  30.370 +  if (data == 0)
  30.371 +    {
  30.372 +      return;
  30.373 +    }
  30.374 +  g_maxSize = std::max (g_maxSize, data->size);
  30.375 +  data->count--;
  30.376 +  if (data->count == 0)
  30.377 +    {
  30.378 +      if (g_freeList.size () > FREE_LIST_SIZE ||
  30.379 +	  data->size < g_maxSize)
  30.380 +	{
  30.381 +	  uint8_t *buffer = (uint8_t *)data;
  30.382 +	  delete [] buffer;
  30.383 +	}
  30.384 +      else
  30.385 +	{
  30.386 +	  g_freeList.push_back (data);
  30.387 +	}
  30.388 +    }
  30.389 +}
  30.390 +
  30.391 +#else /* USE_FREE_LIST */
  30.392 +
  30.393 +struct ByteTagListData *
  30.394 +ByteTagList::Allocate (uint32_t size)
  30.395 +{
  30.396 +  NS_LOG_FUNCTION (this << size);
  30.397 +  uint8_t *buffer = new uint8_t [size + sizeof (struct ByteTagListData) - 4];
  30.398 +  struct ByteTagListData *data = (struct ByteTagListData *)buffer;
  30.399 +  data->count = 1;
  30.400 +  data->size = size;
  30.401 +  data->dirty = 0;
  30.402 +  return data;
  30.403 +}
  30.404 +
  30.405 +void 
  30.406 +ByteTagList::Deallocate (struct ByteTagListData *data)
  30.407 +{
  30.408 +  NS_LOG_FUNCTION (this << data);
  30.409 +  if (data == 0)
  30.410 +    {
  30.411 +      return;
  30.412 +    }
  30.413 +  data->count--;
  30.414 +  if (data->count == 0)
  30.415 +    {
  30.416 +      uint8_t *buffer = (uint8_t *)data;
  30.417 +      delete [] buffer;
  30.418 +    }
  30.419 +}
  30.420 +
  30.421 +#endif /* USE_FREE_LIST */
  30.422 +
  30.423 +
  30.424 +} // namespace ns3
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/src/common/byte-tag-list.h	Tue Jun 09 18:00:52 2009 +0100
    31.3 @@ -0,0 +1,170 @@
    31.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
    31.5 +/*
    31.6 + * Copyright (c) 2008 INRIA
    31.7 + *
    31.8 + * This program is free software; you can redistribute it and/or modify
    31.9 + * it under the terms of the GNU General Public License version 2 as
   31.10 + * published by the Free Software Foundation;
   31.11 + *
   31.12 + * This program is distributed in the hope that it will be useful,
   31.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   31.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   31.15 + * GNU General Public License for more details.
   31.16 + *
   31.17 + * You should have received a copy of the GNU General Public License
   31.18 + * along with this program; if not, write to the Free Software
   31.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   31.20 + *
   31.21 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
   31.22 + */
   31.23 +#ifndef BYTE_TAG_LIST_H
   31.24 +#define BYTE_TAG_LIST_H
   31.25 +
   31.26 +#include <stdint.h>
   31.27 +#include "ns3/type-id.h"
   31.28 +#include "tag-buffer.h"
   31.29 +
   31.30 +namespace ns3 {
   31.31 +
   31.32 +struct ByteTagListData;
   31.33 +
   31.34 +/**
   31.35 + * \ingroup packet
   31.36 + *
   31.37 + * \brief keep track of the tags stored in a packet.
   31.38 + *
   31.39 + * This class is mostly private to the Packet implementation and users
   31.40 + * should never have to access it directly.
   31.41 + *
   31.42 + * \internal
   31.43 + * The implementation of this class is a bit tricky so, there are a couple
   31.44 + * of things to keep in mind here:
   31.45 + *
   31.46 + *   - it stores all tags in a single byte buffer: each tag is stored
   31.47 + *     as 4 32bit integers (TypeId, tag data size, start, end) followed 
   31.48 + *     by the tag data as generated by Tag::Serialize.
   31.49 + *
   31.50 + *   - the struct ByteTagListData structure which contains the tag byte buffer
   31.51 + *     is shared and, thus, reference-counted. This data structure is unshared
   31.52 + *     as-needed to emulate COW semantics.
   31.53 + *
   31.54 + *   - each tag tags a unique set of bytes identified by the pair of offsets 
   31.55 + *     (start,end). These offsets are provided by Buffer::GetCurrentStartOffset
   31.56 + *     and Buffer::GetCurrentEndOffset which means that they are relative to 
   31.57 + *     the start of the 'virtual byte buffer' as explained in the documentation
   31.58 + *     for the ns3::Buffer class. Whenever the origin of the offset of the Buffer
   31.59 + *     instance associated to this ByteTagList instance changes, the Buffer class
   31.60 + *     reports this to its container Packet class as a bool return value
   31.61 + *     in Buffer::AddAtStart and Buffer::AddAtEnd. In both cases, when this happens
   31.62 + *     the Packet class calls ByteTagList::AddAtEnd and ByteTagList::AddAtStart to update
   31.63 + *     the byte offsets of each tag in the ByteTagList.
   31.64 + *
   31.65 + *   - whenever bytes are removed from the packet byte buffer, the ByteTagList offsets 
   31.66 + *     are never updated because we rely on the fact that they will be updated in
   31.67 + *     either the next call to Packet::AddHeader or Packet::AddTrailer or when
   31.68 + *     the user iterates the tag list with Packet::GetTagIterator and 
   31.69 + *     TagIterator::Next.
   31.70 + */
   31.71 +class ByteTagList
   31.72 +{
   31.73 +public:
   31.74 +
   31.75 +  class Iterator
   31.76 +  {
   31.77 +  public:
   31.78 +    struct Item 
   31.79 +    {
   31.80 +      TypeId tid;
   31.81 +      uint32_t size;
   31.82 +      int32_t start;
   31.83 +      int32_t end;
   31.84 +      TagBuffer buf;
   31.85 +      Item (TagBuffer buf);
   31.86 +    private:
   31.87 +      friend class ByteTagList;
   31.88 +      friend class ByteTagList::Iterator;
   31.89 +    };
   31.90 +    bool HasNext (void) const;
   31.91 +    struct ByteTagList::Iterator::Item Next (void);
   31.92 +    uint32_t GetOffsetStart (void) const;
   31.93 +  private:
   31.94 +    friend class ByteTagList;
   31.95 +    Iterator (uint8_t *start, uint8_t *end, int32_t offsetStart, int32_t offsetEnd);
   31.96 +    void PrepareForNext (void);
   31.97 +    uint8_t *m_current;
   31.98 +    uint8_t *m_end;
   31.99 +    int32_t m_offsetStart;
  31.100 +    int32_t m_offsetEnd;
  31.101 +    uint32_t m_nextTid;
  31.102 +    uint32_t m_nextSize;
  31.103 +    int32_t m_nextStart;
  31.104 +    int32_t m_nextEnd;
  31.105 +  };
  31.106 +
  31.107 +  ByteTagList ();
  31.108 +  ByteTagList (const ByteTagList &o);
  31.109 +  ByteTagList &operator = (const ByteTagList &o);
  31.110 +  ~ByteTagList ();
  31.111 +
  31.112 +  /**
  31.113 +   * \param tid the typeid of the tag added
  31.114 +   * \param bufferSize the size of the tag when its serialization will 
  31.115 +   *        be completed. Typically, the return value of Tag::GetSerializedSize
  31.116 +   * \param start offset which uniquely identifies the first byte tagged by this tag.
  31.117 +   * \param end offset which uniquely identifies the last byte tagged by this tag.
  31.118 +   * \returns a buffer which can be used to write the tag data.     
  31.119 +   *
  31.120 +   * 
  31.121 +   */
  31.122 +  TagBuffer Add (TypeId tid, uint32_t bufferSize, int32_t start, int32_t end);
  31.123 +
  31.124 +  /**
  31.125 +   * \param o the other list of tags to aggregate.
  31.126 +   *
  31.127 +   * Aggregate the two lists of tags.
  31.128 +   */
  31.129 +  void Add (const ByteTagList &o);
  31.130 +
  31.131 +  void RemoveAll (void);
  31.132 +
  31.133 +  /**
  31.134 +   * \param offsetStart the offset which uniquely identifies the first data byte 
  31.135 +   *        present in the byte buffer associated to this ByteTagList.
  31.136 +   * \param offsetEnd the offset which uniquely identifies the last data byte 
  31.137 +   *        present in the byte buffer associated to this ByteTagList.
  31.138 +   * \returns an iterator
  31.139 +   *
  31.140 +   * The returned iterator will allow you to loop through the set of tags present
  31.141 +   * in this list: the boundaries of each tag as reported by their start and
  31.142 +   * end offsets will be included within the input offsetStart and offsetEnd.
  31.143 +   */
  31.144 +  ByteTagList::Iterator Begin (int32_t offsetStart, int32_t offsetEnd) const;
  31.145 +
  31.146 +  /**
  31.147 +   * Adjust the offsets stored internally by the adjustment delta and
  31.148 +   * make sure that all offsets are smaller than appendOffset which represents
  31.149 +   * the location where new bytes have been added to the byte buffer.
  31.150 +   */
  31.151 +  void AddAtEnd (int32_t adjustment, int32_t appendOffset);
  31.152 +  /**
  31.153 +   * Adjust the offsets stored internally by the adjustment delta and
  31.154 +   * make sure that all offsets are bigger than prependOffset which represents
  31.155 +   * the location where new bytes have been added to the byte buffer.
  31.156 +   */
  31.157 +  void AddAtStart (int32_t adjustment, int32_t prependOffset);
  31.158 +
  31.159 +private:
  31.160 +  bool IsDirtyAtEnd (int32_t appendOffset);
  31.161 +  bool IsDirtyAtStart (int32_t prependOffset);
  31.162 +  ByteTagList::Iterator BeginAll (void) const;
  31.163 +
  31.164 +  struct ByteTagListData *Allocate (uint32_t size);
  31.165 +  void Deallocate (struct ByteTagListData *data);
  31.166 +
  31.167 +  uint16_t m_used;
  31.168 +  struct ByteTagListData *m_data;
  31.169 +};
  31.170 +
  31.171 +} // namespace ns3
  31.172 +
  31.173 +#endif /* BYTE_TAG_LIST_H */
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/src/common/packet-tag-list.cc	Tue Jun 09 18:00:52 2009 +0100
    32.3 @@ -0,0 +1,177 @@
    32.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
    32.5 +/*
    32.6 + * Copyright (c) 2006 INRIA
    32.7 + *
    32.8 + * This program is free software; you can redistribute it and/or modify
    32.9 + * it under the terms of the GNU General Public License version 2 as
   32.10 + * published by the Free Software Foundation;
   32.11 + *
   32.12 + * This program is distributed in the hope that it will be useful,
   32.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   32.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   32.15 + * GNU General Public License for more details.
   32.16 + *
   32.17 + * You should have received a copy of the GNU General Public License
   32.18 + * along with this program; if not, write to the Free Software
   32.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   32.20 + *
   32.21 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
   32.22 + */
   32.23 +#include "packet-tag-list.h"
   32.24 +#include "tag-buffer.h"
   32.25 +#include "tag.h"
   32.26 +#include "ns3/fatal-error.h"
   32.27 +#include "ns3/log.h"
   32.28 +#include <string.h>
   32.29 +
   32.30 +NS_LOG_COMPONENT_DEFINE ("PacketTagList");
   32.31 +
   32.32 +namespace ns3 {
   32.33 +
   32.34 +#ifdef USE_FREE_LIST
   32.35 +
   32.36 +struct PacketTagList::TagData *PacketTagList::g_free = 0;
   32.37 +uint32_t PacketTagList::g_nfree = 0;
   32.38 +
   32.39 +struct PacketTagList::TagData *
   32.40 +PacketTagList::AllocData (void) const
   32.41 +{
   32.42 +  NS_LOG_FUNCTION (g_nfree);
   32.43 +  struct PacketTagList::TagData *retval;
   32.44 +  if (g_free != 0) 
   32.45 +    {
   32.46 +      retval = g_free;
   32.47 +      g_free = g_free->m_next;
   32.48 +      g_nfree--;
   32.49 +    } 
   32.50 +  else 
   32.51 +    {
   32.52 +      retval = new struct PacketTagList::TagData ();
   32.53 +    }
   32.54 +  return retval;
   32.55 +}
   32.56 +
   32.57 +void
   32.58 +PacketTagList::FreeData (struct TagData *data) const
   32.59 +{
   32.60 +  NS_LOG_FUNCTION (g_nfree << data);
   32.61 +  if (g_nfree > 1000) 
   32.62 +    {
   32.63 +      delete data;
   32.64 +      return;
   32.65 +    }
   32.66 +  g_nfree++;
   32.67 +  data->next = g_free;
   32.68 +  data->tid = TypeId ();
   32.69 +  g_free = data;
   32.70 +}
   32.71 +#else
   32.72 +struct PacketTagList::TagData *
   32.73 +PacketTagList::AllocData (void) const
   32.74 +{
   32.75 +  NS_LOG_FUNCTION_NOARGS ();
   32.76 +  struct PacketTagList::TagData *retval;
   32.77 +  retval = new struct PacketTagList::TagData ();
   32.78 +  return retval;
   32.79 +}
   32.80 +
   32.81 +void
   32.82 +PacketTagList::FreeData (struct TagData *data) const
   32.83 +{
   32.84 +  NS_LOG_FUNCTION (data);
   32.85 +  delete data;
   32.86 +}
   32.87 +#endif
   32.88 +
   32.89 +bool
   32.90 +PacketTagList::Remove (Tag &tag)
   32.91 +{
   32.92 +  NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ());
   32.93 +  TypeId tid = tag.GetInstanceTypeId ();
   32.94 +  bool found = false;
   32.95 +  for (struct TagData *cur = m_next; cur != 0; cur = cur->next) 
   32.96 +    {
   32.97 +      if (cur->tid == tid) 
   32.98 +        {
   32.99 +          found = true;
  32.100 +          tag.Deserialize (TagBuffer (cur->data, cur->data+PACKET_TAG_MAX_SIZE));
  32.101 +        }
  32.102 +    }
  32.103 +  if (!found) 
  32.104 +    {
  32.105 +      return false;
  32.106 +    }
  32.107 +  struct TagData *start = 0;
  32.108 +  struct TagData **prevNext = &start;
  32.109 +  for (struct TagData *cur = m_next; cur != 0; cur = cur->next) 
  32.110 +    {
  32.111 +      if (cur->tid == tid) 
  32.112 +        {
  32.113 +          /**
  32.114 +           * XXX
  32.115 +           * Note: I believe that we could optimize this to
  32.116 +           * avoid copying each TagData located after the target id
  32.117 +           * and just link the already-copied list to the next tag.
  32.118 +           */
  32.119 +          continue;
  32.120 +        }
  32.121 +      struct TagData *copy = AllocData ();
  32.122 +      copy->tid = cur->tid;
  32.123 +      copy->count = 1;
  32.124 +      copy->next = 0;
  32.125 +      memcpy (copy->data, cur->data, PACKET_TAG_MAX_SIZE);
  32.126 +      *prevNext = copy;
  32.127 +      prevNext = &copy->next;
  32.128 +    }
  32.129 +  *prevNext = 0;
  32.130 +  RemoveAll ();
  32.131 +  m_next = start;
  32.132 +  return true;
  32.133 +}
  32.134 +
  32.135 +void 
  32.136 +PacketTagList::Add (const Tag &tag) const
  32.137 +{
  32.138 +  NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ());
  32.139 +  // ensure this id was not yet added
  32.140 +  for (struct TagData *cur = m_next; cur != 0; cur = cur->next) 
  32.141 +    {
  32.142 +      NS_ASSERT (cur->tid != tag.GetInstanceTypeId ());
  32.143 +    }
  32.144 +  struct TagData *head = AllocData ();
  32.145 +  head->count = 1;
  32.146 +  head->next = 0;
  32.147 +  head->tid = tag.GetInstanceTypeId ();
  32.148 +  head->next = m_next;
  32.149 +  NS_ASSERT (tag.GetSerializedSize () < PACKET_TAG_MAX_SIZE);
  32.150 +  tag.Serialize (TagBuffer (head->data, head->data+tag.GetSerializedSize ()));
  32.151 +
  32.152 +  const_cast<PacketTagList *> (this)->m_next = head;
  32.153 +}
  32.154 +
  32.155 +bool
  32.156 +PacketTagList::Peek (Tag &tag) const
  32.157 +{
  32.158 +  NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ());
  32.159 +  TypeId tid = tag.GetInstanceTypeId ();
  32.160 +  for (struct TagData *cur = m_next; cur != 0; cur = cur->next) 
  32.161 +    {
  32.162 +      if (cur->tid == tid) 
  32.163 +        {
  32.164 +          /* found tag */
  32.165 +          tag.Deserialize (TagBuffer (cur->data, cur->data+PACKET_TAG_MAX_SIZE));
  32.166 +          return true;
  32.167 +        }
  32.168 +    }
  32.169 +  /* no tag found */
  32.170 +  return false;
  32.171 +}
  32.172 +
  32.173 +const struct PacketTagList::TagData *
  32.174 +PacketTagList::Head (void) const
  32.175 +{
  32.176 +  return m_next;
  32.177 +}
  32.178 +
  32.179 +} // namespace ns3
  32.180 +
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/src/common/packet-tag-list.h	Tue Jun 09 18:00:52 2009 +0100
    33.3 @@ -0,0 +1,142 @@
    33.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
    33.5 +/*
    33.6 + * Copyright (c) 2006 INRIA
    33.7 + *
    33.8 + * This program is free software; you can redistribute it and/or modify
    33.9 + * it under the terms of the GNU General Public License version 2 as
   33.10 + * published by the Free Software Foundation;
   33.11 + *
   33.12 + * This program is distributed in the hope that it will be useful,
   33.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   33.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   33.15 + * GNU General Public License for more details.
   33.16 + *
   33.17 + * You should have received a copy of the GNU General Public License
   33.18 + * along with this program; if not, write to the Free Software
   33.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   33.20 + *
   33.21 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
   33.22 + */
   33.23 +#ifndef PACKET_TAG_LIST_H
   33.24 +#define PACKET_TAG_LIST_H
   33.25 +
   33.26 +#include <stdint.h>
   33.27 +#include <ostream>
   33.28 +#include "ns3/type-id.h"
   33.29 +
   33.30 +namespace ns3 {
   33.31 +
   33.32 +class Tag;
   33.33 +
   33.34 +/**
   33.35 + * \ingroup constants
   33.36 + * \brief Tag maximum size
   33.37 + * The maximum size (in bytes) of a Tag is stored
   33.38 + * in this constant.
   33.39 + */
   33.40 +#define PACKET_TAG_MAX_SIZE 20
   33.41 +
   33.42 +class PacketTagList 
   33.43 +{
   33.44 +public:
   33.45 +  struct TagData {
   33.46 +    uint8_t data[PACKET_TAG_MAX_SIZE];
   33.47 +    struct TagData *next;
   33.48 +    TypeId tid;
   33.49 +    uint32_t count;
   33.50 +  };
   33.51 +
   33.52 +  inline PacketTagList ();
   33.53 +  inline PacketTagList (PacketTagList const &o);
   33.54 +  inline PacketTagList &operator = (PacketTagList const &o);
   33.55 +  inline ~PacketTagList ();
   33.56 +
   33.57 +  void Add (Tag const&tag) const;
   33.58 +  bool Remove (Tag &tag);
   33.59 +  bool Peek (Tag &tag) const;
   33.60 +  inline void RemoveAll (void);
   33.61 +
   33.62 +  const struct PacketTagList::TagData *Head (void) const;
   33.63 +
   33.64 +private:
   33.65 +
   33.66 +  bool Remove (TypeId tid);
   33.67 +  struct PacketTagList::TagData *AllocData (void) const;
   33.68 +  void FreeData (struct TagData *data) const;
   33.69 +
   33.70 +  static struct PacketTagList::TagData *g_free;
   33.71 +  static uint32_t g_nfree;
   33.72 +
   33.73 +  struct TagData *m_next;
   33.74 +};
   33.75 +
   33.76 +} // namespace ns3
   33.77 +
   33.78 +/****************************************************
   33.79 + *  Implementation of inline methods for performance
   33.80 + ****************************************************/
   33.81 +
   33.82 +namespace ns3 {
   33.83 +
   33.84 +PacketTagList::PacketTagList ()
   33.85 +  : m_next ()
   33.86 +{}
   33.87 +
   33.88 +PacketTagList::PacketTagList (PacketTagList const &o)
   33.89 +  : m_next (o.m_next)
   33.90 +{
   33.91 +  if (m_next != 0) 
   33.92 +    {
   33.93 +      m_next->count++;
   33.94 +    }
   33.95 +}
   33.96 +
   33.97 +PacketTagList &
   33.98 +PacketTagList::operator = (PacketTagList const &o)
   33.99 +{
  33.100 +  // self assignment
  33.101 +  if (m_next == o.m_next) 
  33.102 +    {
  33.103 +      return *this;
  33.104 +    }
  33.105 +  RemoveAll ();
  33.106 +  m_next = o.m_next;
  33.107 +  if (m_next != 0) 
  33.108 +    {
  33.109 +      m_next->count++;
  33.110 +    }
  33.111 +  return *this;
  33.112 +}
  33.113 +
  33.114 +PacketTagList::~PacketTagList ()
  33.115 +{
  33.116 +  RemoveAll ();
  33.117 +}
  33.118 +
  33.119 +void
  33.120 +PacketTagList::RemoveAll (void)
  33.121 +{
  33.122 +  struct TagData *prev = 0;
  33.123 +  for (struct TagData *cur = m_next; cur != 0; cur = cur->next) 
  33.124 +    {
  33.125 +      cur->count--;
  33.126 +      if (cur->count > 0) 
  33.127 +        {
  33.128 +          break;
  33.129 +        }
  33.130 +      if (prev != 0) 
  33.131 +        {
  33.132 +          FreeData (prev);
  33.133 +        }
  33.134 +      prev = cur;
  33.135 +    }
  33.136 +  if (prev != 0) 
  33.137 +    {
  33.138 +      FreeData (prev);
  33.139 +    }
  33.140 +  m_next = 0;
  33.141 +}
  33.142 +
  33.143 +} // namespace ns3
  33.144 +
  33.145 +#endif /* PACKET_TAG_LIST_H */
    34.1 --- a/src/common/packet.cc	Tue Jun 09 18:00:24 2009 +0100
    34.2 +++ b/src/common/packet.cc	Tue Jun 09 18:00:52 2009 +0100
    34.3 @@ -28,22 +28,22 @@
    34.4  uint32_t Packet::m_globalUid = 0;
    34.5  
    34.6  TypeId 
    34.7 -TagIterator::Item::GetTypeId (void) const
    34.8 +ByteTagIterator::Item::GetTypeId (void) const
    34.9  {
   34.10    return m_tid;
   34.11  }
   34.12  uint32_t 
   34.13 -TagIterator::Item::GetStart (void) const
   34.14 +ByteTagIterator::Item::GetStart (void) const
   34.15  {
   34.16    return m_start;
   34.17  }
   34.18  uint32_t 
   34.19 -TagIterator::Item::GetEnd (void) const
   34.20 +ByteTagIterator::Item::GetEnd (void) const
   34.21  {
   34.22    return m_end;
   34.23  }
   34.24  void 
   34.25 -TagIterator::Item::GetTag (Tag &tag) const
   34.26 +ByteTagIterator::Item::GetTag (Tag &tag) const
   34.27  {
   34.28    if (tag.GetInstanceTypeId () != GetTypeId ())
   34.29      {
   34.30 @@ -51,31 +51,64 @@
   34.31      }
   34.32    tag.Deserialize (m_buffer);
   34.33  }
   34.34 -TagIterator::Item::Item (TypeId tid, uint32_t start, uint32_t end, TagBuffer buffer)
   34.35 +ByteTagIterator::Item::Item (TypeId tid, uint32_t start, uint32_t end, TagBuffer buffer)
   34.36    : m_tid (tid),
   34.37      m_start (start),
   34.38      m_end (end),
   34.39      m_buffer (buffer)
   34.40  {}
   34.41  bool 
   34.42 -TagIterator::HasNext (void) const
   34.43 +ByteTagIterator::HasNext (void) const
   34.44  {
   34.45    return m_current.HasNext ();
   34.46  }
   34.47 -TagIterator::Item 
   34.48 -TagIterator::Next (void)
   34.49 +ByteTagIterator::Item 
   34.50 +ByteTagIterator::Next (void)
   34.51  {
   34.52 -  TagList::Iterator::Item i = m_current.Next ();
   34.53 -  return TagIterator::Item (i.tid, 
   34.54 -                            i.start-m_current.GetOffsetStart (), 
   34.55 -                            i.end-m_current.GetOffsetStart (), 
   34.56 -                            i.buf);
   34.57 +  ByteTagList::Iterator::Item i = m_current.Next ();
   34.58 +  return ByteTagIterator::Item (i.tid, 
   34.59 +                                i.start-m_current.GetOffsetStart (), 
   34.60 +                                i.end-m_current.GetOffsetStart (), 
   34.61 +                                i.buf);
   34.62  }
   34.63 -TagIterator::TagIterator (TagList::Iterator i)
   34.64 +ByteTagIterator::ByteTagIterator (ByteTagList::Iterator i)
   34.65    : m_current (i)
   34.66  {}
   34.67  
   34.68  
   34.69 +PacketTagIterator::PacketTagIterator (const struct PacketTagList::TagData *head)
   34.70 +  : m_current (head)
   34.71 +{}
   34.72 +bool 
   34.73 +PacketTagIterator::HasNext (void) const
   34.74 +{
   34.75 +  return m_current != 0;
   34.76 +}
   34.77 +PacketTagIterator::Item 
   34.78 +PacketTagIterator::Next (void)
   34.79 +{
   34.80 +  NS_ASSERT (HasNext ());
   34.81 +  const struct PacketTagList::TagData *prev = m_current;
   34.82 +  m_current = m_current->next;
   34.83 +  return PacketTagIterator::Item (prev);
   34.84 +}
   34.85 +
   34.86 +PacketTagIterator::Item::Item (const struct PacketTagList::TagData *data)
   34.87 +  : m_data (data)
   34.88 +{}
   34.89 +TypeId 
   34.90 +PacketTagIterator::Item::GetTypeId (void) const
   34.91 +{
   34.92 +  return m_data->tid;
   34.93 +}
   34.94 +void 
   34.95 +PacketTagIterator::Item::GetTag (Tag &tag) const
   34.96 +{
   34.97 +  NS_ASSERT (tag.GetInstanceTypeId () == m_data->tid);
   34.98 +  tag.Deserialize (TagBuffer ((uint8_t*)m_data->data, (uint8_t*)m_data->data+PACKET_TAG_MAX_SIZE));
   34.99 +}
  34.100 +
  34.101 +
  34.102  void 
  34.103  Packet::Ref (void) const
  34.104  {
  34.105 @@ -102,7 +135,8 @@
  34.106  
  34.107  Packet::Packet ()
  34.108    : m_buffer (),
  34.109 -    m_tagList (),
  34.110 +    m_byteTagList (),
  34.111 +    m_packetTagList (),
  34.112      m_metadata (m_globalUid, 0),
  34.113      m_refCount (1)
  34.114  {
  34.115 @@ -111,7 +145,8 @@
  34.116  
  34.117  Packet::Packet (const Packet &o)
  34.118    : m_buffer (o.m_buffer),
  34.119 -    m_tagList (o.m_tagList),
  34.120 +    m_byteTagList (o.m_byteTagList),
  34.121 +    m_packetTagList (o.m_packetTagList),
  34.122      m_metadata (o.m_metadata),
  34.123      m_refCount (1)
  34.124  {}
  34.125 @@ -124,14 +159,16 @@
  34.126        return *this;
  34.127      }
  34.128    m_buffer = o.m_buffer;
  34.129 -  m_tagList = o.m_tagList;
  34.130 +  m_byteTagList = o.m_byteTagList;
  34.131 +  m_packetTagList = o.m_packetTagList;
  34.132    m_metadata = o.m_metadata;
  34.133    return *this;
  34.134  }
  34.135  
  34.136  Packet::Packet (uint32_t size)
  34.137    : m_buffer (size),
  34.138 -    m_tagList (),
  34.139 +    m_byteTagList (),
  34.140 +    m_packetTagList (),
  34.141      m_metadata (m_globalUid, size),
  34.142      m_refCount (1)
  34.143  {
  34.144 @@ -139,7 +176,8 @@
  34.145  }
  34.146  Packet::Packet (uint8_t const*buffer, uint32_t size)
  34.147    : m_buffer (),
  34.148 -    m_tagList (),
  34.149 +    m_byteTagList (),
  34.150 +    m_packetTagList (),
  34.151      m_metadata (m_globalUid, size),
  34.152      m_refCount (1)
  34.153  {
  34.154 @@ -149,9 +187,11 @@
  34.155    i.Write (buffer, size);
  34.156  }
  34.157  
  34.158 -Packet::Packet (const Buffer &buffer,  const TagList &tagList, const PacketMetadata &metadata)
  34.159 +Packet::Packet (const Buffer &buffer,  const ByteTagList &byteTagList, 
  34.160 +                const PacketTagList &packetTagList, const PacketMetadata &metadata)
  34.161    : m_buffer (buffer),
  34.162 -    m_tagList (tagList),
  34.163 +    m_byteTagList (byteTagList),
  34.164 +    m_packetTagList (packetTagList),
  34.165      m_metadata (metadata),
  34.166      m_refCount (1)
  34.167  {}
  34.168 @@ -166,7 +206,7 @@
  34.169    PacketMetadata metadata = m_metadata.CreateFragment (start, end);
  34.170    // again, call the constructor directly rather than
  34.171    // through Create because it is private.
  34.172 -  return Ptr<Packet> (new Packet (buffer, m_tagList, metadata), false);
  34.173 +  return Ptr<Packet> (new Packet (buffer, m_byteTagList, m_packetTagList, metadata), false);
  34.174  }
  34.175  
  34.176  uint32_t 
  34.177 @@ -178,14 +218,14 @@
  34.178  void
  34.179  Packet::AddHeader (const Header &header)
  34.180  {
  34.181 -  NS_LOG_FUNCTION (this << &header);
  34.182    uint32_t size = header.GetSerializedSize ();
  34.183 +  NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << size);
  34.184    uint32_t orgStart = m_buffer.GetCurrentStartOffset ();
  34.185    bool resized = m_buffer.AddAtStart (size);
  34.186    if (resized)
  34.187      {
  34.188 -      m_tagList.AddAtStart (m_buffer.GetCurrentStartOffset () + size - orgStart,
  34.189 -                            m_buffer.GetCurrentStartOffset () + size);
  34.190 +      m_byteTagList.AddAtStart (m_buffer.GetCurrentStartOffset () + size - orgStart,
  34.191 +                                m_buffer.GetCurrentStartOffset () + size);
  34.192      }
  34.193    header.Serialize (m_buffer.Begin ());
  34.194    m_metadata.AddHeader (header, size);
  34.195 @@ -193,8 +233,8 @@
  34.196  uint32_t
  34.197  Packet::RemoveHeader (Header &header)
  34.198  {
  34.199 -  NS_LOG_FUNCTION (this << &header);
  34.200    uint32_t deserialized = header.Deserialize (m_buffer.Begin ());
  34.201 +  NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << deserialized);
  34.202    m_buffer.RemoveAtStart (deserialized);
  34.203    m_metadata.RemoveHeader (header, deserialized);
  34.204    return deserialized;
  34.205 @@ -202,21 +242,21 @@
  34.206  uint32_t
  34.207  Packet::PeekHeader (Header &header) const
  34.208  {
  34.209 -  NS_LOG_FUNCTION (this << &header);
  34.210    uint32_t deserialized = header.Deserialize (m_buffer.Begin ());
  34.211 +  NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << deserialized);
  34.212    return deserialized;
  34.213  }
  34.214  void
  34.215  Packet::AddTrailer (const Trailer &trailer)
  34.216  {
  34.217 -  NS_LOG_FUNCTION (this << &trailer);
  34.218    uint32_t size = trailer.GetSerializedSize ();
  34.219 +  NS_LOG_FUNCTION (this << trailer.GetInstanceTypeId ().GetName () << size);
  34.220    uint32_t orgStart = m_buffer.GetCurrentStartOffset ();
  34.221    bool resized = m_buffer.AddAtEnd (size);
  34.222    if (resized)
  34.223      {
  34.224 -      m_tagList.AddAtEnd (m_buffer.GetCurrentStartOffset () - orgStart,
  34.225 -                          m_buffer.GetCurrentEndOffset () - size);
  34.226 +      m_byteTagList.AddAtEnd (m_buffer.GetCurrentStartOffset () - orgStart,
  34.227 +                              m_buffer.GetCurrentEndOffset () - size);
  34.228      }
  34.229    Buffer::Iterator end = m_buffer.End ();
  34.230    trailer.Serialize (end);
  34.231 @@ -225,8 +265,8 @@
  34.232  uint32_t
  34.233  Packet::RemoveTrailer (Trailer &trailer)
  34.234  {
  34.235 -  NS_LOG_FUNCTION (this << &trailer);
  34.236    uint32_t deserialized = trailer.Deserialize (m_buffer.End ());
  34.237 +  NS_LOG_FUNCTION (this << trailer.GetInstanceTypeId ().GetName () << deserialized);
  34.238    m_buffer.RemoveAtEnd (deserialized);
  34.239    m_metadata.RemoveTrailer (trailer, deserialized);
  34.240    return deserialized;
  34.241 @@ -234,25 +274,25 @@
  34.242  uint32_t
  34.243  Packet::PeekTrailer (Trailer &trailer)
  34.244  {
  34.245 -  NS_LOG_FUNCTION (this << &trailer);
  34.246    uint32_t deserialized = trailer.Deserialize (m_buffer.End ());
  34.247 +  NS_LOG_FUNCTION (this << trailer.GetInstanceTypeId ().GetName () << deserialized);
  34.248    return deserialized;
  34.249  }
  34.250  
  34.251  void 
  34.252  Packet::AddAtEnd (Ptr<const Packet> packet)
  34.253  {
  34.254 -  NS_LOG_FUNCTION (this << packet);
  34.255 +  NS_LOG_FUNCTION (this << packet << packet->GetSize ());
  34.256    uint32_t aStart = m_buffer.GetCurrentStartOffset ();
  34.257    uint32_t bEnd = packet->m_buffer.GetCurrentEndOffset ();
  34.258    m_buffer.AddAtEnd (packet->m_buffer);
  34.259    uint32_t appendPrependOffset = m_buffer.GetCurrentEndOffset () - packet->m_buffer.GetSize ();
  34.260 -  m_tagList.AddAtEnd (m_buffer.GetCurrentStartOffset () - aStart, 
  34.261 -                      appendPrependOffset);
  34.262 -  TagList copy = packet->m_tagList;
  34.263 +  m_byteTagList.AddAtEnd (m_buffer.GetCurrentStartOffset () - aStart, 
  34.264 +                          appendPrependOffset);
  34.265 +  ByteTagList copy = packet->m_byteTagList;
  34.266    copy.AddAtStart (m_buffer.GetCurrentEndOffset () - bEnd,
  34.267                     appendPrependOffset);
  34.268 -  m_tagList.Add (copy);
  34.269 +  m_byteTagList.Add (copy);
  34.270    m_metadata.AddAtEnd (packet->m_metadata);
  34.271  }
  34.272  void
  34.273 @@ -263,8 +303,8 @@
  34.274    bool resized = m_buffer.AddAtEnd (size);
  34.275    if (resized)
  34.276      {
  34.277 -      m_tagList.AddAtEnd (m_buffer.GetCurrentEndOffset () - orgEnd,
  34.278 -                          m_buffer.GetCurrentEndOffset () - size);
  34.279 +      m_byteTagList.AddAtEnd (m_buffer.GetCurrentEndOffset () - orgEnd,
  34.280 +                              m_buffer.GetCurrentEndOffset () - size);
  34.281      }
  34.282    m_metadata.AddPaddingAtEnd (size);
  34.283  }
  34.284 @@ -284,16 +324,23 @@
  34.285  }
  34.286  
  34.287  void 
  34.288 -Packet::RemoveAllTags (void)
  34.289 +Packet::RemoveAllByteTags (void)
  34.290  {
  34.291    NS_LOG_FUNCTION (this);
  34.292 -  m_tagList.RemoveAll ();
  34.293 +  m_byteTagList.RemoveAll ();
  34.294  }
  34.295  
  34.296  uint8_t const *
  34.297  Packet::PeekData (void) const
  34.298  {
  34.299 -  return m_buffer.PeekData ();
  34.300 +  NS_LOG_FUNCTION (this);
  34.301 +  uint32_t oldStart = m_buffer.GetCurrentStartOffset ();
  34.302 +  uint8_t const * data = m_buffer.PeekData ();
  34.303 +  uint32_t newStart = m_buffer.GetCurrentStartOffset ();
  34.304 + 
  34.305 +  // Update tag offsets if buffer offsets were changed
  34.306 +  const_cast<ByteTagList &>(m_byteTagList).AddAtStart (newStart - oldStart, newStart);
  34.307 +  return data;
  34.308  }
  34.309  
  34.310  uint32_t 
  34.311 @@ -309,6 +356,12 @@
  34.312    return cur;
  34.313  }
  34.314  
  34.315 +void
  34.316 +Packet::CopyData(std::ostream *os, uint32_t size) const
  34.317 +{
  34.318 +  return m_buffer.CopyData (os, size);
  34.319 +}
  34.320 +
  34.321  uint32_t 
  34.322  Packet::GetUid (void) const
  34.323  {
  34.324 @@ -316,12 +369,12 @@
  34.325  }
  34.326  
  34.327  void 
  34.328 -Packet::PrintTags (std::ostream &os) const
  34.329 +Packet::PrintByteTags (std::ostream &os) const
  34.330  {
  34.331 -  TagIterator i = GetTagIterator ();
  34.332 +  ByteTagIterator i = GetByteTagIterator ();
  34.333    while (i.HasNext ())
  34.334      {
  34.335 -      TagIterator::Item item = i.Next ();
  34.336 +      ByteTagIterator::Item item = i.Next ();
  34.337        os << item.GetTypeId ().GetName () << " [" << item.GetStart () << "-" << item.GetEnd () << "]";
  34.338        Callback<ObjectBase *> constructor = item.GetTypeId ().GetConstructor ();
  34.339        if (constructor.IsNull ())
  34.340 @@ -537,29 +590,29 @@
  34.341  }
  34.342  
  34.343  void 
  34.344 -Packet::AddTag (const Tag &tag) const
  34.345 +Packet::AddByteTag (const Tag &tag) const
  34.346  {
  34.347 -  NS_LOG_FUNCTION (this << &tag);
  34.348 -  TagList *list = const_cast<TagList *> (&m_tagList);
  34.349 +  NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ());
  34.350 +  ByteTagList *list = const_cast<ByteTagList *> (&m_byteTagList);
  34.351    TagBuffer buffer = list->Add (tag.GetInstanceTypeId (), tag.GetSerializedSize (), 
  34.352 -                                 m_buffer.GetCurrentStartOffset (),
  34.353 -                                 m_buffer.GetCurrentEndOffset ());
  34.354 +                                m_buffer.GetCurrentStartOffset (),
  34.355 +                                m_buffer.GetCurrentEndOffset ());
  34.356    tag.Serialize (buffer);
  34.357  }
  34.358 -TagIterator 
  34.359 -Packet::GetTagIterator (void) const
  34.360 +ByteTagIterator 
  34.361 +Packet::GetByteTagIterator (void) const
  34.362  {
  34.363 -  return TagIterator (m_tagList.Begin (m_buffer.GetCurrentStartOffset (), m_buffer.GetCurrentEndOffset ()));
  34.364 +  return ByteTagIterator (m_byteTagList.Begin (m_buffer.GetCurrentStartOffset (), m_buffer.GetCurrentEndOffset ()));
  34.365  }
  34.366  
  34.367  bool 
  34.368 -Packet::FindFirstMatchingTag (Tag &tag) const
  34.369 +Packet::FindFirstMatchingByteTag (Tag &tag) const
  34.370  {
  34.371    TypeId tid = tag.GetInstanceTypeId ();
  34.372 -  TagIterator i = GetTagIterator ();
  34.373 +  ByteTagIterator i = GetByteTagIterator ();
  34.374    while (i.HasNext ())
  34.375      {
  34.376 -      TagIterator::Item item = i.Next ();
  34.377 +      ByteTagIterator::Item item = i.Next ();
  34.378        if (tid == item.GetTypeId ())
  34.379          {
  34.380            item.GetTag (tag);
  34.381 @@ -569,6 +622,62 @@
  34.382    return false;
  34.383  }
  34.384  
  34.385 +void 
  34.386 +Packet::AddPacketTag (const Tag &tag) const
  34.387 +{
  34.388 +  NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ());
  34.389 +  m_packetTagList.Add (tag);
  34.390 +}
  34.391 +bool 
  34.392 +Packet::RemovePacketTag (Tag &tag)
  34.393 +{