merge with lena-pem for moving from BuildingsMobilityModel to MobilityBuildingInfo
--- a/.hgignore Tue Jun 04 16:57:16 2013 +0200
+++ b/.hgignore Tue Jun 04 17:20:40 2013 +0200
@@ -36,4 +36,6 @@
\.diff$
\.tr$
\#[^\#/]+\#$
+^coverity
syntax: glob
+TAGS
\ No newline at end of file
--- a/.hgtags Tue Jun 04 16:57:16 2013 +0200
+++ b/.hgtags Tue Jun 04 17:20:40 2013 +0200
@@ -64,3 +64,4 @@
ae540de68a2534213342c5e0b12afb47d7518a90 ns-3.14
26a511d6dbad7284e66de0f3b2ad5bebe6b76405 ns-3.15
49d343e55caec257bb01e400eef6c14522f37e1b ns-3.16
+b4a70b99171ade6e9628a87780994238950a1df1 ns-3.17
--- a/CHANGES.html Tue Jun 04 16:57:16 2013 +0200
+++ b/CHANGES.html Tue Jun 04 17:20:40 2013 +0200
@@ -51,11 +51,44 @@
us a note on ns-developers mailing list.</p>
<hr>
+<h1>Changes from ns-3.17 to ns-3.18</h1>
+
+<h2>New API:</h2>
+<ul>
+</ul>
+
+<h2>Changes to existing API:</h2>
+<ul>
+</ul>
+
+<h2>Changes to build system:</h2>
+<ul>
+</ul>
+
+<h2>Changed behavior:</h2>
+<ul>
+</ul>
+
+<hr>
<h1>Changes from ns-3.16 to ns-3.17</h1>
<h2>New API:</h2>
<ul>
- <li>New TCP Westwood and Westwood+ models
+ <li>New TCP Westwood and Westwood+ models
+ <li>New FdNetDevice class providing a special NetDevice that is able to read
+ and write traffic from a file descriptor. Three helpers are provided
+ to associate the file descriptor with different underlying devices:
+ <ul>
+ <li> EmuFdNetDeviceHelper (to associate the |ns3| device with a physical
+ device in the host machine). This helper is intended to
+ eventually replace the EmuNetDevice in src/emu. </li>
+ <li> TapFdNetDeviceHelper (to associate the ns-3 device with the file
+ descriptor from a tap device in the host machine) </li>
+ <li> PlanteLabFdNetDeviceHelper (to automate the creation of tap devices
+ in PlanetLab nodes, enabling |ns3| simulations that can send and
+ receive traffic though the Internet using PlanetLab resource.</li>
+ </ul>
+ </li>
<li>In Ipv4ClickRouting, the following APIs were added:
<ul>
<li>Ipv4ClickRouting::SetDefines(), accessible through ClickInternetStackHelper::SetDefines(), for the user to set Click defines from the ns-3 simulation file.</li>
@@ -65,97 +98,98 @@
<li>LTE module
<ul>
<li> New user-visible LTE API
- <ul>
- <li>Two new methods have been added to LteHelper to enable the X2-based handover functionality: AddX2Interface, which setups the X2 interface between two eNBs, and HandoverRequest, which is a convenience method that schedules an explicit handover event to be executed at a given point in the simulation. </li>
- <li>the new LteHelper method EnablePhyTraces can now be used to enable the new PHY traces</li>
- </ul>
+ <ul>
+ <li>Two new methods have been added to LteHelper to enable the X2-based handover functionality: AddX2Interface, which setups the X2 interface between two eNBs, and HandoverRequest, which is a convenience method that schedules an explicit handover event to be executed at a given point in the simulation. </li>
+ <li>the new LteHelper method EnablePhyTraces can now be used to enable the new PHY traces</li>
+ </ul>
</li>
<li> New internal LTE API
- <ul>
- <li>New LTE control message classes DlHarqFeedbackLteControlMessage,
- RachPreambleLteControlMessage, RarLteControlMessage, MibLteControlMessage</li>
- <li>New class UeManager
- <li>New LteRadioBearerInfo subclasses LteSignalingRadioBearerInfo,
- LteDataRadioBearerInfo</li>
- <li>New LteSinrChunkProcessor subclasses LteRsReceivedPowerChunkProcessor,
- LteInterferencePowerChunkProcessor</li>
- </ul>
+ <ul>
+ <li>New LTE control message classes DlHarqFeedbackLteControlMessage,
+ RachPreambleLteControlMessage, RarLteControlMessage, MibLteControlMessage</li>
+ <li>New class UeManager
+ <li>New LteRadioBearerInfo subclasses LteSignalingRadioBearerInfo,
+ LteDataRadioBearerInfo</li>
+ <li>New LteSinrChunkProcessor subclasses LteRsReceivedPowerChunkProcessor,
+ LteInterferencePowerChunkProcessor</li>
+ </ul>
</li>
</ul>
</li>
-<li>New DSR API
-<ul>
- <li>Added PassiveBuffer class to save maintenance packet entry for passive acknowledgment option</li>
- <li>Added FindSourceEntry function in RreqTable class to keep track of route request entry received from same source node</li>
- <li>Added NotifyDataReciept function in DsrRouting class to notify the data receipt of the next hop from link layer. This is used for the link layer acknowledgment.</li>
-</ul>
-</li>
-<li>New Tag, PacketSocketTag, to carry the destination address of a packet and the packet type</li>
-<li>New Tag, DeviceNameTag, to carry the ns3 device name from where a packet is coming</li>
-<li>New Error Model, BurstError model, to determine which bursts of packets are errored corresponding to an underlying distribution, burst rate, and burst size</li>
+ <li>New DSR API
+ <ul>
+ <li>Added PassiveBuffer class to save maintenance packet entry for passive acknowledgment option</li>
+ <li>Added FindSourceEntry function in RreqTable class to keep track of route request entry received from same source node</li>
+ <li>Added NotifyDataReciept function in DsrRouting class to notify the data receipt of the next hop from link layer. This is used for the link layer acknowledgment.</li>
+ </ul>
+ </li>
+ <li>New Tag, PacketSocketTag, to carry the destination address of a packet and the packet type</li>
+ <li>New Tag, DeviceNameTag, to carry the ns3 device name from where a packet is coming</li>
+ <li>New Error Model, BurstError model, to determine which bursts of packets are errored corresponding to an underlying distribution, burst rate, and burst size</li>
</ul>
<h2>Changes to existing API:</h2>
<ul>
-<li>ns3::Object and subclasses DoStart has been renamed to DoInitialize</li>
-<li>ns3::Object and subclasses Start has been renamed to Initialize</li>
-<li>EnergySource StartDeviceModels renamed to InitializeDeviceModels</li>
-<li>A typo was fixed in an LTE variable name. The variable ns3::AllocationRetentionPriority::preemprionVulnerability was changed to preemptionVulnerability.</li>
-<li>Changes in TestCase API
-<ul>
- <li>TestCase has new enumeration TestDuration containing QUICK, EXTENSIVE, TAKES_FOREVER</li>
- <li>TestCase constructor now requires TestDuration, old constructor marked deprecated</li>
-</ul>
-</li>
-<li>Changes in LTE API
-<ul>
- <li> User-visible LTE API
- <ul>
- <li>The previous LteHelper method ActivateEpsBearer has been now replaced by two alternative methods: ActivateDataRadioBearer (to be used when the EPC model is not used) and ActivateDedicatedEpsBearer (to be used when the EPC model is used). In the case where the EPC model is used, the default EPS bearer is not automatically activated without the need for a specific method to be called.</li>
- </ul>
- </li>
- <li> Internal LTE API
- <ul>
- <li>EpcHelper added methods AddUe, AddX2Interface. Method AddEnb now requires a cellId. Signature of ActivateEpsBearer changed to void ActivateEpsBearer (Ptr<NetDevice> ueLteDevice, uint64_t imsi, Ptr<EpcTft> tft, EpsBearer bearer) </li>
- <li>LteHelper added methods EnableDlPhyTraces, EnableUlPhyTraces, EnableDlTxPhyTraces, EnableUlTxPhyTraces, EnableDlRxPhyTraces, EnableUlRxPhyTraces</li>
- <li>LteHelper removed methods EnableDlRlcTraces, EnableUlRlcTraces, EnableDlPdcpTraces, EnableUlPdcpTraces</li>
- <li>RadioBearerStatsCalculator added methods (Set/Get)StartTime, (Set/Get)Epoch, RescheduleEndEpoch, EndEpoch</li>
- <li>RadioBearerStatsCalculator removed methods StartEpoch, CheckEpoch</li>
- <li>RadioBearerStatsCalculator methods UlTxPdu, DlRxPdu now require a cellId</li>
- <li>EpcEnbApplication constructor now requires Ipv4Addresses enbS1uAddress and sgwS1uAddress as well as cellId</li>
- <li>EpcEnbApplication added methods SetS1SapUser, GetS1SapProvider, SetS1apSapMme and GetS1apSapEnb</li>
- <li>EpcEnbApplication removed method ErabSetupRequest</li>
- <li>EpcSgwPgwApplication added methods SetS11SapMme, GetS11SapSgw, AddEnb, AddUe, SetUeAddress</li>
- <li>lte-common.h new structs PhyTransmissionStatParameters and PhyReceptionStatParameters used in TracedCallbacks</li>
- <li>LteControlMessage new message types DL_HARQ, RACH_PREAMBLE, RAR, MIB</li>
- <li>LteEnbCmacSapProvider new methods RemoveUe, GetRachConfig, AllocateNcRaPreamble, AllocateTemporaryCellRnti</li>
- <li>LteEnbPhy new methods GetLteEnbCphySapProvider, SetLteEnbCphySapUser, GetDlSpectrumPhy, GetUlSpectrumPhy, CreateSrsReport</li>
- <li>LteEnbPhy methods DoSendMacPdu, DoSetTransmissionMode, DoSetSrsConfigurationIndex, DoGetMacChTtiDelay, DoSendLteControlMessage, AddUePhy, DeleteUePhy made private</li>
- <li>LteEnbPhySapProvider removed methods SetBandwidth, SetTransmissionMode, SetSrsConfigurationIndex, SetCellId</li>
- <li>LteEnbPhySapUser added methods ReceiveRachPreamble, UlInfoListElementHarqFeeback, DlInfoListElementHarqFeeback</li>
- <li>LtePdcp added methods (Set/Get)Status</li>
- <li>LtePdcp DoTransmitRrcPdu renamed DoTransmitPdcpSdu</li>
- <li>LteUeRrc new enum State. New methods SetLteUeCphySapProvider, GetLteUeCphySapUser, SetLteUeRrcSapUser, GetLteUeRrcSapProvider, GetState, GetDlEarfcn, GetDlBandwidth, GetUlBandwidth, GetCellId, SetUseRlcSm . GetRnti made const.</li>
- <li>LteUeRrc removed methods ReleaseRadioBearer, GetLcIdVector, SetForwardUpCallback, DoRrcConfigurationUpdateInd</li>
- <li>LtePdcpSapProvider struct TransmitRrcPduParameters renamed TransmitPdcpSduParameters. Method TransmitRrcPdu renamed TransmitPdcpSdu </li>
- <li>LtePdcpSapUser struct ReceiveRrcPduParameters renamed ReceivePdcpSduParameters. Method ReceiveRrcPdu renamed TransmitPdcpSdu</li>
- <li>LtePdcpSpecificLtePdcpSapProvider method TransmitRrcPdu renamed TransmitPdcpSdu</li>
- <li>LtePdcpSpecificLtePdcpSapUser method ReceiveRrcPdu renamed ReceivePdcpSdu. Method ReceiveRrcPdu renamed ReceivePdcpSdu</li>
- <li>LtePhy removed methods DoSetBandwidth and DoSetEarfcn</li>
- <li>LtePhy added methods ReportInterference and ReportRsReceivedPower</li>
- <li>LteSpectrumPhy added methods SetHarqPhyModule, Reset, SetLtePhyDlHarqFeedbackCallback, SetLtePhyUlHarqFeedbackCallback, AddRsPowerChunkProcessor, AddInterferenceChunkProcessor</li>
- <li>LteUeCphySapProvider removed methods ConfigureRach, StartContentionBasedRandomAccessProcedure, StartNonContentionBasedRandomAccessProcedure</li>
- <li>LteUeMac added method AssignStreams</li>
- <li>LteUeNetDevice methods GetMac, GetRrc, GetImsi made const</li>
- <li>LteUeNetDevice new method GetNas</li>
- <li>LteUePhy new methods GetLteUeCphySapProvider, SetLteUeCphySapUser, GetDlSpectrumPhy, GetUlSpectrumPhy, ReportInterference, ReportRsReceivedPower, ReceiveLteDlHarqFeedback</li>
- <li>LteUePhy DoSendMacPdu, DoSendLteControlMessage, DoSetTransmissionMode, DoSetSrsConfigurationIndex made private</li>
- <li>LteUePhySapProvider removed methods SetBandwidth, SetTransmissionMode, SetSrsConfigurationIndex</li>
- <li>LteUePhySapProvider added method SendRachPreamble</li>
- </li>
-</ul>
-<li>AnimationInterface method EnableIpv4RouteTracking returns reference to calling AnimationInterface object</li>
-<li>To make the API more uniform across the various
+ <li>ns3::Object and subclasses DoStart has been renamed to DoInitialize</li>
+ <li>ns3::Object and subclasses Start has been renamed to Initialize</li>
+ <li>EnergySource StartDeviceModels renamed to InitializeDeviceModels</li>
+ <li>A typo was fixed in an LTE variable name. The variable ns3::AllocationRetentionPriority::preemprionVulnerability was changed to preemptionVulnerability.</li>
+ <li>Changes in TestCase API
+ <ul>
+ <li>TestCase has new enumeration TestDuration containing QUICK, EXTENSIVE, TAKES_FOREVER</li>
+ <li>TestCase constructor now requires TestDuration, old constructor marked deprecated</li>
+ </ul>
+ </li>
+ <li>Changes in LTE API
+ <ul>
+ <li> User-visible LTE API
+ <ul>
+ <li>The previous LteHelper method ActivateEpsBearer has been now replaced by two alternative methods: ActivateDataRadioBearer (to be used when the EPC model is not used) and ActivateDedicatedEpsBearer (to be used when the EPC model is used). In the case where the EPC model is used, the default EPS bearer is not automatically activated without the need for a specific method to be called.</li>
+ </ul>
+ </li>
+ <li> Internal LTE API
+ <ul>
+ <li>EpcHelper added methods AddUe, AddX2Interface. Method AddEnb now requires a cellId. Signature of ActivateEpsBearer changed to void ActivateEpsBearer (Ptr<NetDevice> ueLteDevice, uint64_t imsi, Ptr<EpcTft> tft, EpsBearer bearer)</li>
+ <li>LteHelper added methods EnableDlPhyTraces, EnableUlPhyTraces, EnableDlTxPhyTraces, EnableUlTxPhyTraces, EnableDlRxPhyTraces, EnableUlRxPhyTraces</li>
+ <li>LteHelper removed methods EnableDlRlcTraces, EnableUlRlcTraces, EnableDlPdcpTraces, EnableUlPdcpTraces</li>
+ <li>RadioBearerStatsCalculator added methods (Set/Get)StartTime, (Set/Get)Epoch, RescheduleEndEpoch, EndEpoch</li>
+ <li>RadioBearerStatsCalculator removed methods StartEpoch, CheckEpoch</li>
+ <li>RadioBearerStatsCalculator methods UlTxPdu, DlRxPdu now require a cellId</li>
+ <li>EpcEnbApplication constructor now requires Ipv4Addresses enbS1uAddress and sgwS1uAddress as well as cellId</li>
+ <li>EpcEnbApplication added methods SetS1SapUser, GetS1SapProvider, SetS1apSapMme and GetS1apSapEnb</li>
+ <li>EpcEnbApplication removed method ErabSetupRequest</li>
+ <li>EpcSgwPgwApplication added methods SetS11SapMme, GetS11SapSgw, AddEnb, AddUe, SetUeAddress</li>
+ <li>lte-common.h new structs PhyTransmissionStatParameters and PhyReceptionStatParameters used in TracedCallbacks</li>
+ <li>LteControlMessage new message types DL_HARQ, RACH_PREAMBLE, RAR, MIB</li>
+ <li>LteEnbCmacSapProvider new methods RemoveUe, GetRachConfig, AllocateNcRaPreamble, AllocateTemporaryCellRnti</li>
+ <li>LteEnbPhy new methods GetLteEnbCphySapProvider, SetLteEnbCphySapUser, GetDlSpectrumPhy, GetUlSpectrumPhy, CreateSrsReport</li>
+ <li>LteEnbPhy methods DoSendMacPdu, DoSetTransmissionMode, DoSetSrsConfigurationIndex, DoGetMacChTtiDelay, DoSendLteControlMessage, AddUePhy, DeleteUePhy made private</li>
+ <li>LteEnbPhySapProvider removed methods SetBandwidth, SetTransmissionMode, SetSrsConfigurationIndex, SetCellId</li>
+ <li>LteEnbPhySapUser added methods ReceiveRachPreamble, UlInfoListElementHarqFeeback, DlInfoListElementHarqFeeback</li>
+ <li>LtePdcp added methods (Set/Get)Status</li>
+ <li>LtePdcp DoTransmitRrcPdu renamed DoTransmitPdcpSdu</li>
+ <li>LteUeRrc new enum State. New methods SetLteUeCphySapProvider, GetLteUeCphySapUser, SetLteUeRrcSapUser, GetLteUeRrcSapProvider, GetState, GetDlEarfcn, GetDlBandwidth, GetUlBandwidth, GetCellId, SetUseRlcSm . GetRnti made const.</li>
+ <li>LteUeRrc removed methods ReleaseRadioBearer, GetLcIdVector, SetForwardUpCallback, DoRrcConfigurationUpdateInd</li>
+ <li>LtePdcpSapProvider struct TransmitRrcPduParameters renamed TransmitPdcpSduParameters. Method TransmitRrcPdu renamed TransmitPdcpSdu </li>
+ <li>LtePdcpSapUser struct ReceiveRrcPduParameters renamed ReceivePdcpSduParameters. Method ReceiveRrcPdu renamed TransmitPdcpSdu</li>
+ <li>LtePdcpSpecificLtePdcpSapProvider method TransmitRrcPdu renamed TransmitPdcpSdu</li>
+ <li>LtePdcpSpecificLtePdcpSapUser method ReceiveRrcPdu renamed ReceivePdcpSdu. Method ReceiveRrcPdu renamed ReceivePdcpSdu</li>
+ <li>LtePhy removed methods DoSetBandwidth and DoSetEarfcn</li>
+ <li>LtePhy added methods ReportInterference and ReportRsReceivedPower</li>
+ <li>LteSpectrumPhy added methods SetHarqPhyModule, Reset, SetLtePhyDlHarqFeedbackCallback, SetLtePhyUlHarqFeedbackCallback, AddRsPowerChunkProcessor, AddInterferenceChunkProcessor</li>
+ <li>LteUeCphySapProvider removed methods ConfigureRach, StartContentionBasedRandomAccessProcedure, StartNonContentionBasedRandomAccessProcedure</li>
+ <li>LteUeMac added method AssignStreams</li>
+ <li>LteUeNetDevice methods GetMac, GetRrc, GetImsi made const</li>
+ <li>LteUeNetDevice new method GetNas</li>
+ <li>LteUePhy new methods GetLteUeCphySapProvider, SetLteUeCphySapUser, GetDlSpectrumPhy, GetUlSpectrumPhy, ReportInterference, ReportRsReceivedPower, ReceiveLteDlHarqFeedback</li>
+ <li>LteUePhy DoSendMacPdu, DoSendLteControlMessage, DoSetTransmissionMode, DoSetSrsConfigurationIndex made private</li>
+ <li>LteUePhySapProvider removed methods SetBandwidth, SetTransmissionMode, SetSrsConfigurationIndex</li>
+ <li>LteUePhySapProvider added method SendRachPreamble</li>
+ </ul>
+ </li>
+ </ul>
+ <li>AnimationInterface method EnableIpv4RouteTracking returns reference to calling AnimationInterface object</li>
+ <li>To make the API more uniform across the various
PropagationLossModel classes, the Set/GetLambda methods of the
FriisPropagationLossModel and TwoRayGroundPropagationLossModel
classes have been changed to Set/GetFrequency, and now a Frequency
@@ -163,25 +197,24 @@
attribute. Any previous user code setting a value for Lambda should
be changed to set instead a value of Frequency = C / Lambda, with C
= 299792458.0. </li>
-
</ul>
<h2>Changes to build system:</h2>
<ul>
-<li>Waf shipped with ns-3 has been upgraded to version 1.7.10 and custom
+ <li>Waf shipped with ns-3 has been upgraded to version 1.7.10 and custom
pkg-config generator has been replaced by Waf's builtin tool.
-</li>
+ </li>
</ul>
<h2>Changed behavior:</h2>
<ul>
-<li>DSR link layer notification has changed. The model originally used
-"TxErrHeader" in Ptr<WifiMac> to indicate the transmission
-error of a specific packet in link layer; however, it was not working
-correctly. The model now uses a different path to implement
-the link layer notification mechanism; specifically, looking into the
-trace file to find packet receive events. If the model finds one
-receive event for the data packet, it is used as the indicator for
-successful data delivery.</li>
+ <li>DSR link layer notification has changed. The model originally used
+ "TxErrHeader" in Ptr<WifiMac> to indicate the transmission
+ error of a specific packet in link layer; however, it was not working
+ correctly. The model now uses a different path to implement
+ the link layer notification mechanism; specifically, looking into the
+ trace file to find packet receive events. If the model finds one
+ receive event for the data packet, it is used as the indicator for
+ successful data delivery.</li>
</ul>
<hr>
@@ -199,7 +232,7 @@
<li>(Set/Is)Ipv6RecvTclass - tells the socket to pass information about IPv6 TCLASS up the stack (by adding SocketIpv6TclassTag to the packet).</li>
<li>(Set/Get)Ipv6HopLimit - sets Hop Limit field in the IPv6 headers.</li>
<li>(Set/Is)Ipv6RecvHopLimit - tells the socket to pass information about IPv6 HOPLIMIT up the stack (by adding SocketIpv6HoplimitTag to the packet).</li>
- </ul>
+ </ul>
A user can call these functions to set/get the corresponding socket option. See examples/socket/socket-options-ipv4.cc and examples/socket/socket-options-ipv6.cc for examples.
</ul>
@@ -1053,16 +1086,16 @@
<pre>
void
SimpleChannel::Send (Ptr<Packet> p, uint16_t protocol,
- Mac48Address to, Mac48Address from,
- Ptr<SimpleNetDevice> sender)
+ Mac48Address to, Mac48Address from,
+ Ptr<SimpleNetDevice> sender)
{
for (std::vector<Ptr<SimpleNetDevice> >::const_iterator i = m_devices.begin (); i != m_devices.end (); ++i)
{
Ptr<SimpleNetDevice> tmp = *i;
if (tmp == sender)
- {
- continue;
- }
+ {
+ continue;
+ }
Simulator::ScheduleNow (&SimpleNetDevice::Receive, tmp, p->Copy (), protocol, to, from);
}
}
@@ -1071,16 +1104,16 @@
<pre>
void
SimpleChannel::Send (Ptr<Packet> p, uint16_t protocol,
- Mac48Address to, Mac48Address from,
- Ptr<SimpleNetDevice> sender)
+ Mac48Address to, Mac48Address from,
+ Ptr<SimpleNetDevice> sender)
{
for (std::vector<Ptr<SimpleNetDevice> >::const_iterator i = m_devices.begin (); i != m_devices.end (); ++i)
{
Ptr<SimpleNetDevice> tmp = *i;
if (tmp == sender)
- {
- continue;
- }
+ {
+ continue;
+ }
Simulator::ScheduleWithContext (tmp->GetNode ()->GetId (), Seconds (0),
&SimpleNetDevice::Receive, tmp, p->Copy (), protocol, to, from);
}
--- a/RELEASE_NOTES Tue Jun 04 16:57:16 2013 +0200
+++ b/RELEASE_NOTES Tue Jun 04 17:20:40 2013 +0200
@@ -18,11 +18,52 @@
Supported platforms
-------------------
-To be determined
+
+New user-visible features
+-------------------------
+
+Bugs fixed
+----------
+- Bug 1643 - NdiscCache creation and existence checks
+- Bug 1662 - m_type not set for Ipv6OptionRouterAlertHeader
+- Bug 1678 - C++11 compliance problem with std::pair"
+- Bug 1683 - IPv6 autoconfigured don't use *infinite* lifetimes
+- Bug 1669 - ns-3 should support binding two and three (possibly more) arguments
+- Bug 1689 - IPv6 shouldn't add a default gateway without checking the Router lifetime
+
+Known issues
+------------
+In general, known issues are tracked on the project tracker available
+at http://www.nsnam.org/bugzilla/
+
+Release 3.17
+============
+
+Availability
+------------
+This release is available from:
+http://www.nsnam.org/release/ns-allinone-3.17.tar.bz2
+
+Supported platforms
+-------------------
+These platforms have been tested; others may work also:
+- Fedora Core 18 (32/64 bit) with g++-4.7.2
+- Fedora Core 17 (32/64 bit) with g++-4.7.0
+- Ubuntu 13.04 (32/64 bit) with g++-4.7.3
+- Ubuntu 12.10 (32/64 bit) with g++-4.6.3
+- Ubuntu 12.04 (32/64 bit) with g++-4.6.3
+- Ubuntu 10.04.4 LTS (64 bit) with g++-4.4.3
+- OS X Mountain Lion 10.8.3 with g++-4.2.1
+- FreeBSD 9.1-RELEASE (64 bit) with g++-4.2.1
New user-visible features
-------------------------
- new TCP Westwood and Westwood+ models
+- new FdNetDevice model and associated helpers. The FdNetDevice is able
+ to read and write from a file descriptor. Various helpers are provided
+ to associate this descriptor with underlying devices or sockets on the
+ host operating system, including a packet socket for emulation, and
+ tap devices including a version specialized for use on PlanetLab.
- ns-3-click: it's now possible to (i) have Click pull random numbers from
ns-3 and (ii) have ns-3 set "defines" in Click via the simulation file
(see src/click/examples/nsclick-defines.cc).
--- a/doc/doxygen.conf Tue Jun 04 16:57:16 2013 +0200
+++ b/doc/doxygen.conf Tue Jun 04 17:20:40 2013 +0200
@@ -193,9 +193,14 @@
# will result in a user-defined paragraph with heading "Side Effects:".
# You can put \n's in the value part of an alias to insert newlines.
-ALIASES = \
- "intern=\internal \par \b Internal:" \
- "pname{1}=<span class=\"params\"><span class=\"paramname\">\1</span></span>"
+ALIASES =
+
+# Set off \internal docs
+ALIASES += intern="\internal \par \b Internal:"
+
+# Typeset parameter name in docs as in the "Parameters:" list
+# Usage: /** \param [in/out] tag If found, \pname{tag} is ... */
+ALIASES += pname{1}="<span class=\"params\"><span class=\"paramname\">\1</span></span>"
# This tag can be used to specify a number of word-keyword mappings (TCL only).
# A mapping has the form "name=value". For example adding
--- a/doc/models/Makefile Tue Jun 04 16:57:16 2013 +0200
+++ b/doc/models/Makefile Tue Jun 04 17:20:40 2013 +0200
@@ -36,7 +36,7 @@
$(SRC)/dsr/doc/dsr.rst \
$(SRC)/mpi/doc/distributed.rst \
$(SRC)/energy/doc/energy.rst \
- $(SRC)/emu/doc/emu.rst \
+ $(SRC)/fd-net-device/doc/fd-net-device.rst \
$(SRC)/tap-bridge/doc/tap.rst \
$(SRC)/mesh/doc/mesh.rst \
$(SRC)/lte/doc/source/lte.rst \
Binary file doc/models/figures/testbed.dia has changed
--- a/doc/models/source/emulation-overview.rst Tue Jun 04 16:57:16 2013 +0200
+++ b/doc/models/source/emulation-overview.rst Tue Jun 04 17:20:40 2013 +0200
@@ -5,17 +5,28 @@
|ns3| has been designed for integration into testbed and virtual machine
environments. We have addressed this need by providing two kinds of net devices.
-The first kind, which we call an ``Emu`` ``NetDevice`` allows |ns3| simulations
+The first kind of device is a file descriptor net device (``FdNetDevice``),
+which is a generic device type that can read and write from a file descriptor.
+By associating this file descriptor with different things on the host
+system, different capabilities can be provided. For instance, the
+FdNetDevice can be associated with an underlying packet socket to provide
+emulation capabilities. This allows |ns3| simulations
to send data on a "real" network. The second kind, called a ``Tap``
``NetDevice`` allows a "real" host to participate in an |ns3| simulation as if
it were one of the simulated nodes. An |ns3| simulation may be constructed with
-any combination of simulated, ``Emu``, or ``Tap`` devices.
+any combination of simulated or emulated devices.
+
+**Note:** Prior to ns-3.17, the emulation capability was provided by a
+special device called an ``Emu`` NetDevice; the ``Emu`` NetDevice has
+been superseded by the ``FdNetDevice``, and will be deprecated and removed
+in future revisions of |ns3|.
One of the use-cases we want to support is that of a testbed. A concrete example
of an environment of this kind is the ORBIT testbed. ORBIT is a laboratory
emulator/field trial network arranged as a two dimensional grid of 400 802.11
radio nodes. We integrate with ORBIT by using their "imaging" process to load
-and run |ns3| simulations on the ORBIT array. We use our ``Emu`` ``NetDevice``
+and run |ns3| simulations on the ORBIT array. We can use our
+``EmuFdNetDevice``
to drive the hardware in the testbed and we can accumulate results either using
the |ns3| tracing and logging functions, or the native ORBIT data gathering
techniques. See `<http://www.orbit-lab.org/>`_ for details on the ORBIT
@@ -72,5 +83,5 @@
.. toctree::
- emu
+ fd-net-device
tap
--- a/doc/tutorial/source/building-topologies.rst Tue Jun 04 16:57:16 2013 +0200
+++ b/doc/tutorial/source/building-topologies.rst Tue Jun 04 17:20:40 2013 +0200
@@ -1326,7 +1326,8 @@
trace source to originate the trace events. We will need to write a trace
sink to connect to that source that will display some pretty information for
us. Despite its reputation as being difficult, it's really quite simple.
-Just before the main program of the ``scratch/mythird.cc`` script, add the
+Just before the main program of the ``scratch/mythird.cc`` script (i.e.,
+just after the ``NS_LOG_COMPONENT_DEFINE`` statement), add the
following function:
::
--- a/src/core/model/callback.h Tue Jun 04 16:57:16 2013 +0200
+++ b/src/core/model/callback.h Tue Jun 04 17:20:40 2013 +0200
@@ -319,6 +319,105 @@
typename TypeTraits<TX>::ReferencedType m_a;
};
+template <typename T, typename R, typename TX1, typename TX2, typename T1, typename T2, typename T3, typename T4,typename T5, typename T6, typename T7>
+class TwoBoundFunctorCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,empty,empty> {
+public:
+ template <typename FUNCTOR, typename ARG1, typename ARG2>
+ TwoBoundFunctorCallbackImpl (FUNCTOR functor, ARG1 arg1, ARG2 arg2)
+ : m_functor (functor), m_a1 (arg1), m_a2 (arg2) {}
+ virtual ~TwoBoundFunctorCallbackImpl () {}
+ R operator() (void) {
+ return m_functor (m_a1,m_a2);
+ }
+ R operator() (T1 a1) {
+ return m_functor (m_a1,m_a2,a1);
+ }
+ R operator() (T1 a1,T2 a2) {
+ return m_functor (m_a1,m_a2,a1,a2);
+ }
+ R operator() (T1 a1,T2 a2,T3 a3) {
+ return m_functor (m_a1,m_a2,a1,a2,a3);
+ }
+ R operator() (T1 a1,T2 a2,T3 a3,T4 a4) {
+ return m_functor (m_a1,m_a2,a1,a2,a3,a4);
+ }
+ R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
+ return m_functor (m_a1,m_a2,a1,a2,a3,a4,a5);
+ }
+ R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6) {
+ return m_functor (m_a1,m_a2,a1,a2,a3,a4,a5,a6);
+ }
+ R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7) {
+ return m_functor (m_a1,m_a2,a1,a2,a3,a4,a5,a6,a7);
+ }
+ virtual bool IsEqual (Ptr<const CallbackImplBase> other) const {
+ TwoBoundFunctorCallbackImpl<T,R,TX1,TX2,T1,T2,T3,T4,T5,T6,T7> const *otherDerived =
+ dynamic_cast<TwoBoundFunctorCallbackImpl<T,R,TX1,TX2,T1,T2,T3,T4,T5,T6,T7> const *> (PeekPointer (other));
+ if (otherDerived == 0)
+ {
+ return false;
+ }
+ else if (otherDerived->m_functor != m_functor ||
+ otherDerived->m_a1 != m_a1 || otherDerived->m_a2 != m_a2)
+ {
+ return false;
+ }
+ return true;
+ }
+private:
+ T m_functor;
+ typename TypeTraits<TX1>::ReferencedType m_a1;
+ typename TypeTraits<TX2>::ReferencedType m_a2;
+};
+
+template <typename T, typename R, typename TX1, typename TX2, typename TX3, typename T1, typename T2, typename T3, typename T4,typename T5, typename T6>
+class ThreeBoundFunctorCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5,T6,empty,empty,empty> {
+public:
+ template <typename FUNCTOR, typename ARG1, typename ARG2, typename ARG3>
+ ThreeBoundFunctorCallbackImpl (FUNCTOR functor, ARG1 arg1, ARG2 arg2, ARG3 arg3)
+ : m_functor (functor), m_a1 (arg1), m_a2 (arg2), m_a3 (arg3) {}
+ virtual ~ThreeBoundFunctorCallbackImpl () {}
+ R operator() (void) {
+ return m_functor (m_a1,m_a2,m_a3);
+ }
+ R operator() (T1 a1) {
+ return m_functor (m_a1,m_a2,m_a3,a1);
+ }
+ R operator() (T1 a1,T2 a2) {
+ return m_functor (m_a1,m_a2,m_a3,a1,a2);
+ }
+ R operator() (T1 a1,T2 a2,T3 a3) {
+ return m_functor (m_a1,m_a2,m_a3,a1,a2,a3);
+ }
+ R operator() (T1 a1,T2 a2,T3 a3,T4 a4) {
+ return m_functor (m_a1,m_a2,m_a3,a1,a2,a3,a4);
+ }
+ R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
+ return m_functor (m_a1,m_a2,m_a3,a1,a2,a3,a4,a5);
+ }
+ R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6) {
+ return m_functor (m_a1,m_a2,m_a3,a1,a2,a3,a4,a5,a6);
+ }
+ virtual bool IsEqual (Ptr<const CallbackImplBase> other) const {
+ ThreeBoundFunctorCallbackImpl<T,R,TX1,TX2,TX3,T1,T2,T3,T4,T5,T6> const *otherDerived =
+ dynamic_cast<ThreeBoundFunctorCallbackImpl<T,R,TX1,TX2,TX3,T1,T2,T3,T4,T5,T6> const *> (PeekPointer (other));
+ if (otherDerived == 0)
+ {
+ return false;
+ }
+ else if (otherDerived->m_functor != m_functor ||
+ otherDerived->m_a1 != m_a1 || otherDerived->m_a2 != m_a2 || otherDerived->m_a3 != m_a3)
+ {
+ return false;
+ }
+ return true;
+ }
+private:
+ T m_functor;
+ typename TypeTraits<TX1>::ReferencedType m_a1;
+ typename TypeTraits<TX2>::ReferencedType m_a2;
+ typename TypeTraits<TX3>::ReferencedType m_a3;
+};
class CallbackBase {
public:
@@ -396,6 +495,26 @@
return Callback<R,T2,T3,T4,T5,T6,T7,T8,T9> (impl);
}
+ template <typename TX1, typename TX2>
+ Callback<R,T3,T4,T5,T6,T7,T8,T9> TwoBind (TX1 a1, TX2 a2) {
+ Ptr<CallbackImpl<R,T3,T4,T5,T6,T7,T8,T9,empty,empty> > impl =
+ Ptr<CallbackImpl<R,T3,T4,T5,T6,T7,T8,T9,empty,empty> > (
+ new TwoBoundFunctorCallbackImpl<
+ Callback<R,T1,T2,T3,T4,T5,T6,T7,T8,T9>,
+ R,T1,T2,T3,T4,T5,T6,T7,T8,T9> (*this, a1, a2), false);
+ return Callback<R,T3,T4,T5,T6,T7,T8,T9> (impl);
+ }
+
+ template <typename TX1, typename TX2, typename TX3>
+ Callback<R,T4,T5,T6,T7,T8,T9> ThreeBind (TX1 a1, TX2 a2, TX3 a3) {
+ Ptr<CallbackImpl<R,T4,T5,T6,T7,T8,T9,empty,empty,empty> > impl =
+ Ptr<CallbackImpl<R,T4,T5,T6,T7,T8,T9,empty,empty,empty> > (
+ new ThreeBoundFunctorCallbackImpl<
+ Callback<R,T1,T2,T3,T4,T5,T6,T7,T8,T9>,
+ R,T1,T2,T3,T4,T5,T6,T7,T8,T9> (*this, a1, a2, a3), false);
+ return Callback<R,T4,T5,T6,T7,T8,T9> (impl);
+ }
+
bool IsNull (void) const {
return (DoPeekImpl () == 0) ? true : false;
}
@@ -954,6 +1073,114 @@
Create<BoundFunctorCallbackImpl<R (*)(TX,T1,T2,T3,T4,T5,T6,T7,T8),R,TX,T1,T2,T3,T4,T5,T6,T7,T8> > (fnPtr, a);
return Callback<R,T1,T2,T3,T4,T5,T6,T7,T8> (impl);
}
+
+template <typename R, typename TX1, typename TX2, typename ARG1, typename ARG2>
+Callback<R> MakeBoundCallback (R (*fnPtr)(TX1,TX2), ARG1 a1, ARG2 a2) {
+ Ptr<CallbackImpl<R,empty,empty,empty,empty,empty,empty,empty,empty,empty> > impl =
+ Create<TwoBoundFunctorCallbackImpl<R (*)(TX1,TX2),R,TX1,TX2,empty,empty,empty,empty,empty,empty,empty> >(fnPtr, a1, a2);
+ return Callback<R> (impl);
+}
+
+template <typename R, typename TX1, typename TX2, typename ARG1, typename ARG2,
+ typename T1>
+Callback<R,T1> MakeBoundCallback (R (*fnPtr)(TX1,TX2,T1), ARG1 a1, ARG2 a2) {
+ Ptr<CallbackImpl<R,T1,empty,empty,empty,empty,empty,empty,empty,empty> > impl =
+ Create<TwoBoundFunctorCallbackImpl<R (*)(TX1,TX2,T1),R,TX1,TX2,T1,empty,empty,empty,empty,empty,empty> > (fnPtr, a1, a2);
+ return Callback<R,T1> (impl);
+}
+template <typename R, typename TX1, typename TX2, typename ARG1, typename ARG2,
+ typename T1, typename T2>
+Callback<R,T1,T2> MakeBoundCallback (R (*fnPtr)(TX1,TX2,T1,T2), ARG1 a1, ARG2 a2) {
+ Ptr<CallbackImpl<R,T1,T2,empty,empty,empty,empty,empty,empty,empty> > impl =
+ Create<TwoBoundFunctorCallbackImpl<R (*)(TX1,TX2,T1,T2),R,TX1,TX2,T1,T2,empty,empty,empty,empty,empty> > (fnPtr, a1, a2);
+ return Callback<R,T1,T2> (impl);
+}
+template <typename R, typename TX1, typename TX2, typename ARG1, typename ARG2,
+ typename T1, typename T2,typename T3>
+Callback<R,T1,T2,T3> MakeBoundCallback (R (*fnPtr)(TX1,TX2,T1,T2,T3), ARG1 a1, ARG2 a2) {
+ Ptr<CallbackImpl<R,T1,T2,T3,empty,empty,empty,empty,empty,empty> > impl =
+ Create<TwoBoundFunctorCallbackImpl<R (*)(TX1,TX2,T1,T2,T3),R,TX1,TX2,T1,T2,T3,empty,empty,empty,empty> > (fnPtr, a1, a2);
+ return Callback<R,T1,T2,T3> (impl);
+}
+template <typename R, typename TX1, typename TX2, typename ARG1, typename ARG2,
+ typename T1, typename T2,typename T3,typename T4>
+Callback<R,T1,T2,T3,T4> MakeBoundCallback (R (*fnPtr)(TX1,TX2,T1,T2,T3,T4), ARG1 a1, ARG2 a2) {
+ Ptr<CallbackImpl<R,T1,T2,T3,T4,empty,empty,empty,empty,empty> > impl =
+ Create<TwoBoundFunctorCallbackImpl<R (*)(TX1,TX2,T1,T2,T3,T4),R,TX1,TX2,T1,T2,T3,T4,empty,empty,empty> > (fnPtr, a1, a2);
+ return Callback<R,T1,T2,T3,T4> (impl);
+}
+template <typename R, typename TX1, typename TX2, typename ARG1, typename ARG2,
+ typename T1, typename T2,typename T3,typename T4,typename T5>
+Callback<R,T1,T2,T3,T4,T5> MakeBoundCallback (R (*fnPtr)(TX1,TX2,T1,T2,T3,T4,T5), ARG1 a1, ARG2 a2) {
+ Ptr<CallbackImpl<R,T1,T2,T3,T4,T5,empty,empty,empty,empty> > impl =
+ Create<TwoBoundFunctorCallbackImpl<R (*)(TX1,TX2,T1,T2,T3,T4,T5),R,TX1,TX2,T1,T2,T3,T4,T5,empty,empty> > (fnPtr, a1, a2);
+ return Callback<R,T1,T2,T3,T4,T5> (impl);
+}
+template <typename R, typename TX1, typename TX2, typename ARG1, typename ARG2,
+ typename T1, typename T2,typename T3,typename T4,typename T5, typename T6>
+Callback<R,T1,T2,T3,T4,T5,T6> MakeBoundCallback (R (*fnPtr)(TX1,TX2,T1,T2,T3,T4,T5,T6), ARG1 a1, ARG2 a2) {
+ Ptr<CallbackImpl<R,T1,T2,T3,T4,T5,T6,empty,empty,empty> > impl =
+ Create<TwoBoundFunctorCallbackImpl<R (*)(TX1,TX2,T1,T2,T3,T4,T5,T6),R,TX1,TX2,T1,T2,T3,T4,T5,T6,empty> > (fnPtr, a1, a2);
+ return Callback<R,T1,T2,T3,T4,T5,T6> (impl);
+}
+template <typename R, typename TX1, typename TX2, typename ARG1, typename ARG2,
+ typename T1, typename T2,typename T3,typename T4,typename T5, typename T6, typename T7>
+Callback<R,T1,T2,T3,T4,T5,T6,T7> MakeBoundCallback (R (*fnPtr)(TX1,TX2,T1,T2,T3,T4,T5,T6,T7), ARG1 a1, ARG2 a2) {
+ Ptr<CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,empty,empty> > impl =
+ Create<TwoBoundFunctorCallbackImpl<R (*)(TX1,TX2,T1,T2,T3,T4,T5,T6,T7),R,TX1,TX2,T1,T2,T3,T4,T5,T6,T7> > (fnPtr, a1, a2);
+ return Callback<R,T1,T2,T3,T4,T5,T6,T7> (impl);
+}
+
+template <typename R, typename TX1, typename TX2, typename TX3, typename ARG1, typename ARG2, typename ARG3>
+Callback<R> MakeBoundCallback (R (*fnPtr)(TX1,TX2,TX3), ARG1 a1, ARG2 a2, ARG3 a3) {
+ Ptr<CallbackImpl<R,empty,empty,empty,empty,empty,empty,empty,empty,empty> > impl =
+ Create<ThreeBoundFunctorCallbackImpl<R (*)(TX1,TX2,TX3),R,TX1,TX2,TX3,empty,empty,empty,empty,empty,empty> >(fnPtr, a1, a2, a3);
+ return Callback<R> (impl);
+}
+
+template <typename R, typename TX1, typename TX2, typename TX3, typename ARG1, typename ARG2, typename ARG3,
+ typename T1>
+Callback<R,T1> MakeBoundCallback (R (*fnPtr)(TX1,TX2,TX3,T1), ARG1 a1, ARG2 a2, ARG3 a3) {
+ Ptr<CallbackImpl<R,T1,empty,empty,empty,empty,empty,empty,empty,empty> > impl =
+ Create<ThreeBoundFunctorCallbackImpl<R (*)(TX1,TX2,TX3,T1),R,TX1,TX2,TX3,T1,empty,empty,empty,empty,empty> > (fnPtr, a1, a2, a3);
+ return Callback<R,T1> (impl);
+}
+template <typename R, typename TX1, typename TX2, typename TX3, typename ARG1, typename ARG2, typename ARG3,
+ typename T1, typename T2>
+Callback<R,T1,T2> MakeBoundCallback (R (*fnPtr)(TX1,TX2,TX3,T1,T2), ARG1 a1, ARG2 a2, ARG3 a3) {
+ Ptr<CallbackImpl<R,T1,T2,empty,empty,empty,empty,empty,empty,empty> > impl =
+ Create<ThreeBoundFunctorCallbackImpl<R (*)(TX1,TX2,TX3,T1,T2),R,TX1,TX2,TX3,T1,T2,empty,empty,empty,empty> > (fnPtr, a1, a2, a3);
+ return Callback<R,T1,T2> (impl);
+}
+template <typename R, typename TX1, typename TX2, typename TX3, typename ARG1, typename ARG2, typename ARG3,
+ typename T1, typename T2,typename T3>
+Callback<R,T1,T2,T3> MakeBoundCallback (R (*fnPtr)(TX1,TX2,TX3,T1,T2,T3), ARG1 a1, ARG2 a2, ARG3 a3) {
+ Ptr<CallbackImpl<R,T1,T2,T3,empty,empty,empty,empty,empty,empty> > impl =
+ Create<ThreeBoundFunctorCallbackImpl<R (*)(TX1,TX2,TX3,T1,T2,T3),R,TX1,TX2,TX3,T1,T2,T3,empty,empty,empty> > (fnPtr, a1, a2, a3);
+ return Callback<R,T1,T2,T3> (impl);
+}
+template <typename R, typename TX1, typename TX2, typename TX3, typename ARG1, typename ARG2, typename ARG3,
+ typename T1, typename T2,typename T3,typename T4>
+Callback<R,T1,T2,T3,T4> MakeBoundCallback (R (*fnPtr)(TX1,TX2,TX3,T1,T2,T3,T4), ARG1 a1, ARG2 a2, ARG3 a3) {
+ Ptr<CallbackImpl<R,T1,T2,T3,T4,empty,empty,empty,empty,empty> > impl =
+ Create<ThreeBoundFunctorCallbackImpl<R (*)(TX1,TX2,TX3,T1,T2,T3,T4),R,TX1,TX2,TX3,T1,T2,T3,T4,empty,empty> > (fnPtr, a1, a2, a3);
+ return Callback<R,T1,T2,T3,T4> (impl);
+}
+template <typename R, typename TX1, typename TX2, typename TX3, typename ARG1, typename ARG2, typename ARG3,
+ typename T1, typename T2,typename T3,typename T4,typename T5>
+Callback<R,T1,T2,T3,T4,T5> MakeBoundCallback (R (*fnPtr)(TX1,TX2,TX3,T1,T2,T3,T4,T5), ARG1 a1, ARG2 a2, ARG3 a3) {
+ Ptr<CallbackImpl<R,T1,T2,T3,T4,T5,empty,empty,empty,empty> > impl =
+ Create<ThreeBoundFunctorCallbackImpl<R (*)(TX1,TX2,TX3,T1,T2,T3,T4,T5),R,TX1,TX2,TX3,T1,T2,T3,T4,T5,empty> > (fnPtr, a1, a2, a3);
+ return Callback<R,T1,T2,T3,T4,T5> (impl);
+}
+template <typename R, typename TX1, typename TX2, typename TX3, typename ARG1, typename ARG2, typename ARG3,
+ typename T1, typename T2,typename T3,typename T4,typename T5, typename T6>
+Callback<R,T1,T2,T3,T4,T5,T6> MakeBoundCallback (R (*fnPtr)(TX1,TX2,TX3,T1,T2,T3,T4,T5,T6), ARG1 a1, ARG2 a2, ARG3 a3) {
+ Ptr<CallbackImpl<R,T1,T2,T3,T4,T5,T6,empty,empty,empty> > impl =
+ Create<ThreeBoundFunctorCallbackImpl<R (*)(TX1,TX2,TX3,T1,T2,T3,T4,T5,T6),R,TX1,TX2,TX3,T1,T2,T3,T4,T5,T6> > (fnPtr, a1, a2, a3);
+ return Callback<R,T1,T2,T3,T4,T5,T6> (impl);
+}
+
} // namespace ns3
namespace ns3 {
--- a/src/core/model/object-factory.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/core/model/object-factory.cc Tue Jun 04 17:20:40 2013 +0200
@@ -92,6 +92,7 @@
Callback<ObjectBase *> cb = m_tid.GetConstructor ();
ObjectBase *base = cb ();
Object *derived = dynamic_cast<Object *> (base);
+ NS_ASSERT (derived != 0);
derived->SetTypeId (m_tid);
derived->Construct (m_parameters);
Ptr<Object> object = Ptr<Object> (derived, false);
--- a/src/core/model/system-path.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/core/model/system-path.cc Tue Jun 04 17:20:40 2013 +0200
@@ -308,11 +308,17 @@
{
std::string tmp = Join (elements.begin (), i);
#if defined(HAVE_MKDIR_H)
- mkdir (tmp.c_str (), S_IRWXU);
+ if (mkdir (tmp.c_str (), S_IRWXU))
+ {
+ NS_LOG_ERROR ("failed creating directory " << tmp);
+ }
#endif
}
#if defined(HAVE_MKDIR_H)
- mkdir (path.c_str (), S_IRWXU);
+ if (mkdir (path.c_str (), S_IRWXU))
+ {
+ NS_LOG_ERROR ("failed creating directory " << path);
+ }
#endif
}
--- a/src/core/model/test.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/core/model/test.cc Tue Jun 04 17:20:40 2013 +0200
@@ -278,7 +278,7 @@
{
NS_LOG_FUNCTION (this << filename);
const TestCase *current = this;
- while (current->m_dataDir == "" && current != 0)
+ while (current != 0 && current->m_dataDir == "")
{
current = current->m_parent;
}
@@ -595,6 +595,8 @@
}
}
}
+
+ os->unsetf(std::ios_base::floatfield);
}
void
@@ -652,6 +654,7 @@
for (std::list<TestCase *>::const_iterator i = begin; i != end; ++i)
{
TestSuite * test= dynamic_cast<TestSuite *>(*i);
+ NS_ASSERT (test != 0);
if (printTestType)
{
std::cout << label[test->GetTestType ()];
--- a/src/core/test/callback-test-suite.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/core/test/callback-test-suite.cc Tue Jun 04 17:20:40 2013 +0200
@@ -300,6 +300,24 @@
static bool *gMakeBoundCallbackTest2;
static bool *gMakeBoundCallbackTest3a;
static int gMakeBoundCallbackTest3b;
+static int gMakeBoundCallbackTest4a;
+static int gMakeBoundCallbackTest4b;
+static int gMakeBoundCallbackTest5a;
+static int gMakeBoundCallbackTest5b;
+static int gMakeBoundCallbackTest5c;
+static int gMakeBoundCallbackTest6a;
+static int gMakeBoundCallbackTest6b;
+static int gMakeBoundCallbackTest6c;
+static int gMakeBoundCallbackTest7a;
+static int gMakeBoundCallbackTest7b;
+static int gMakeBoundCallbackTest7c;
+static int gMakeBoundCallbackTest8a;
+static int gMakeBoundCallbackTest8b;
+static int gMakeBoundCallbackTest8c;
+static int gMakeBoundCallbackTest9a;
+static int gMakeBoundCallbackTest9b;
+static int gMakeBoundCallbackTest9c;
+static int gMakeBoundCallbackTest9d;
void
MakeBoundCallbackTarget1 (int a)
@@ -321,6 +339,57 @@
return 1234;
}
+void
+MakeBoundCallbackTarget4 (int a, int b)
+{
+ gMakeBoundCallbackTest4a = a;
+ gMakeBoundCallbackTest4b = b;
+}
+
+int
+MakeBoundCallbackTarget5 (int a, int b)
+{
+ gMakeBoundCallbackTest5a = a;
+ gMakeBoundCallbackTest5b = b;
+ return 1234;
+}
+
+int
+MakeBoundCallbackTarget6 (int a, int b, int c)
+{
+ gMakeBoundCallbackTest6a = a;
+ gMakeBoundCallbackTest6b = b;
+ gMakeBoundCallbackTest6c = c;
+ return 1234;
+}
+
+void
+MakeBoundCallbackTarget7 (int a, int b, int c)
+{
+ gMakeBoundCallbackTest7a = a;
+ gMakeBoundCallbackTest7b = b;
+ gMakeBoundCallbackTest7c = c;
+}
+
+int
+MakeBoundCallbackTarget8 (int a, int b, int c)
+{
+ gMakeBoundCallbackTest8a = a;
+ gMakeBoundCallbackTest8b = b;
+ gMakeBoundCallbackTest8c = c;
+ return 1234;
+}
+
+int
+MakeBoundCallbackTarget9 (int a, int b, int c, int d)
+{
+ gMakeBoundCallbackTest9a = a;
+ gMakeBoundCallbackTest9b = b;
+ gMakeBoundCallbackTest9c = c;
+ gMakeBoundCallbackTest9d = d;
+ return 1234;
+}
+
MakeBoundCallbackTestCase::MakeBoundCallbackTestCase ()
: TestCase ("Check MakeBoundCallback() mechanism")
{
@@ -333,6 +402,24 @@
gMakeBoundCallbackTest2 = 0;
gMakeBoundCallbackTest3a = 0;
gMakeBoundCallbackTest3b = 0;
+ gMakeBoundCallbackTest4a = 0;
+ gMakeBoundCallbackTest4b = 0;
+ gMakeBoundCallbackTest5a = 0;
+ gMakeBoundCallbackTest5b = 0;
+ gMakeBoundCallbackTest5c = 0;
+ gMakeBoundCallbackTest6a = 0;
+ gMakeBoundCallbackTest6b = 0;
+ gMakeBoundCallbackTest6c = 0;
+ gMakeBoundCallbackTest7a = 0;
+ gMakeBoundCallbackTest7b = 0;
+ gMakeBoundCallbackTest7c = 0;
+ gMakeBoundCallbackTest8a = 0;
+ gMakeBoundCallbackTest8b = 0;
+ gMakeBoundCallbackTest8c = 0;
+ gMakeBoundCallbackTest9a = 0;
+ gMakeBoundCallbackTest9b = 0;
+ gMakeBoundCallbackTest9c = 0;
+ gMakeBoundCallbackTest9d = 0;
}
void
@@ -376,6 +463,51 @@
NS_TEST_ASSERT_MSG_EQ (result, 1234, "Return value of callback not correct");
NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest3a, &a, "Callback did not fire or binding not correct");
NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest3b, 2468, "Callback did not fire or argument not correct");
+
+ //
+ // Test the TwoBound variant
+ //
+ Callback<void> target4 = MakeBoundCallback (&MakeBoundCallbackTarget4, 3456, 5678);
+ target4 ();
+ NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest4a, 3456, "Callback did not fire or binding not correct");
+ NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest4b, 5678, "Callback did not fire or binding not correct");
+
+ Callback<int> target5 = MakeBoundCallback (&MakeBoundCallbackTarget5, 3456, 5678);
+ int resultTwoA = target5 ();
+ NS_TEST_ASSERT_MSG_EQ (resultTwoA, 1234, "Return value of callback not correct");
+ NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest5a, 3456, "Callback did not fire or binding not correct");
+ NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest5b, 5678, "Callback did not fire or binding not correct");
+
+ Callback<int, int> target6 = MakeBoundCallback (&MakeBoundCallbackTarget6, 3456, 5678);
+ int resultTwoB = target6 (6789);
+ NS_TEST_ASSERT_MSG_EQ (resultTwoB, 1234, "Return value of callback not correct");
+ NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest6a, 3456, "Callback did not fire or binding not correct");
+ NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest6b, 5678, "Callback did not fire or binding not correct");
+ NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest6c, 6789, "Callback did not fire or argument not correct");
+
+ //
+ // Test the ThreeBound variant
+ //
+ Callback<void> target7 = MakeBoundCallback (&MakeBoundCallbackTarget7, 2345, 3456, 4567);
+ target7 ();
+ NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest7a, 2345, "Callback did not fire or binding not correct");
+ NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest7b, 3456, "Callback did not fire or binding not correct");
+ NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest7c, 4567, "Callback did not fire or binding not correct");
+
+ Callback<int> target8 = MakeBoundCallback (&MakeBoundCallbackTarget8, 2345, 3456, 4567);
+ int resultThreeA = target8 ();
+ NS_TEST_ASSERT_MSG_EQ (resultThreeA, 1234, "Return value of callback not correct");
+ NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest8a, 2345, "Callback did not fire or binding not correct");
+ NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest8b, 3456, "Callback did not fire or binding not correct");
+ NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest8c, 4567, "Callback did not fire or binding not correct");
+
+ Callback<int, int> target9 = MakeBoundCallback (&MakeBoundCallbackTarget9, 2345, 3456, 4567);
+ int resultThreeB = target9 (5678);
+ NS_TEST_ASSERT_MSG_EQ (resultThreeB, 1234, "Return value of callback not correct");
+ NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest9a, 2345, "Callback did not fire or binding not correct");
+ NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest9b, 3456, "Callback did not fire or binding not correct");
+ NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest9c, 4567, "Callback did not fire or binding not correct");
+ NS_TEST_ASSERT_MSG_EQ (gMakeBoundCallbackTest9d, 5678, "Callback did not fire or binding not correct");
}
// ===========================================================================
--- a/src/core/test/command-line-test-suite.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/core/test/command-line-test-suite.cc Tue Jun 04 17:20:40 2013 +0200
@@ -60,6 +60,7 @@
args[i+1] = arg;
i++;
}
+ va_end (ap);
int argc = n + 1;
cmd.Parse (argc, args);
delete [] args;
--- a/src/dsr/model/dsr-options.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/dsr/model/dsr-options.cc Tue Jun 04 17:20:40 2013 +0200
@@ -946,7 +946,7 @@
return rreq.GetSerializedSize ();
}
}
- return rreq.GetSerializedSize ();
+ //unreachable: return rreq.GetSerializedSize ();
}
NS_OBJECT_ENSURE_REGISTERED (DsrOptionRrep);
--- a/src/dsr/model/dsr-routing.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/dsr/model/dsr-routing.cc Tue Jun 04 17:20:40 2013 +0200
@@ -2513,7 +2513,10 @@
networkKey.m_destination = newEntry.GetDst ();
m_addressForwardCnt[networkKey] = 0;
- m_maintainBuffer.Enqueue (newEntry);
+ if (! m_maintainBuffer.Enqueue (newEntry))
+ {
+ NS_LOG_ERROR ("Failed to enqueue packet retry");
+ }
if (m_addressForwardTimer.find (networkKey) == m_addressForwardTimer.end ())
{
--- a/src/emu/doc/emu.rst Tue Jun 04 16:57:16 2013 +0200
+++ b/src/emu/doc/emu.rst Tue Jun 04 17:20:40 2013 +0200
@@ -3,6 +3,10 @@
Emu NetDevice
-------------
+**Note:** The ``EmuNetDevice`` is being deprecated as of ns-3.17. The
+``EmuFdNetDeviceHelper`` class replaces this functionality and API
+entirely.
+
Behavior
********
--- a/src/internet/model/global-route-manager-impl.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/internet/model/global-route-manager-impl.cc Tue Jun 04 17:20:40 2013 +0200
@@ -772,6 +772,7 @@
// shortest path calculation.
//
l = v->GetLSA ()->GetLinkRecord (i);
+ NS_ASSERT (l != 0);
if (l->GetLinkType () == GlobalRoutingLinkRecord::StubNetwork)
{
NS_LOG_LOGIC ("Found a Stub record to " << l->GetLinkId ());
@@ -841,6 +842,7 @@
//
if (v->GetLSA ()->GetLSType () == GlobalRoutingLSA::RouterLSA)
{
+ NS_ASSERT (l != 0);
distance = v->GetDistanceFromRoot () + l->GetMetric ();
}
else
--- a/src/internet/model/icmpv6-header.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/internet/model/icmpv6-header.cc Tue Jun 04 17:20:40 2013 +0200
@@ -1895,6 +1895,7 @@
SetType (i.ReadU8 ());
SetLength (i.ReadU8 ());
+ NS_ASSERT (GetLength () * 8 - 2 <= 32);
i.Read (mac, (GetLength () * 8) - 2);
m_addr.CopyFrom (mac, (GetLength () * 8)-2);
--- a/src/internet/model/icmpv6-l4-protocol.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/internet/model/icmpv6-l4-protocol.cc Tue Jun 04 17:20:40 2013 +0200
@@ -292,9 +292,15 @@
bool next = true;
bool hasLla = false;
bool hasMtu = false;
+ Ipv6Address defaultRouter = Ipv6Address::GetZero ();
p->RemoveHeader (raHeader);
+ if (raHeader.GetLifeTime())
+ {
+ defaultRouter = src;
+ }
+
while (next == true)
{
uint8_t type = 0;
@@ -305,7 +311,7 @@
case Icmpv6Header::ICMPV6_OPT_PREFIX:
p->RemoveHeader (prefixHdr);
ipv6->AddAutoconfiguredAddress (ipv6->GetInterfaceForDevice (interface->GetDevice ()), prefixHdr.GetPrefix (), prefixHdr.GetPrefixLength (),
- prefixHdr.GetFlags (), prefixHdr.GetValidTime (), prefixHdr.GetPreferredTime (), src);
+ prefixHdr.GetFlags (), prefixHdr.GetValidTime (), prefixHdr.GetPreferredTime (), defaultRouter);
break;
case Icmpv6Header::ICMPV6_OPT_MTU:
/* take in account the first MTU option */
@@ -590,6 +596,10 @@
if (!entry)
{
/* ouch!! we are victim of a DAD */
+
+ /* Logically dead code (DEADCODE)
+ * b/c loop test compares default Ipv6InterfaceAddress to target
+
Ipv6InterfaceAddress ifaddr;
bool found = false;
uint32_t i = 0;
@@ -611,6 +621,7 @@
interface->SetState (ifaddr.GetAddress (), Ipv6InterfaceAddress::INVALID);
}
}
+ */
/* we have not initiated any communication with the target so... discard the NA */
return;
}
@@ -1231,8 +1242,26 @@
/* try to find the cache */
cache = FindCache (device);
}
-
- return cache->Lookup (dst);
+ if (cache)
+ {
+ NdiscCache::Entry* entry = cache->Lookup (dst);
+ if (entry)
+ {
+ if (entry->IsReachable () || entry->IsDelay ())
+ {
+ *hardwareDestination = entry->GetMacAddress ();
+ return true;
+ }
+ else if (entry->IsStale ())
+ {
+ entry->StartDelayTimer ();
+ entry->MarkDelay ();
+ *hardwareDestination = entry->GetMacAddress ();
+ return true;
+ }
+ }
+ }
+ return false;
}
bool Icmpv6L4Protocol::Lookup (Ptr<Packet> p, Ipv6Address dst, Ptr<NetDevice> device, Ptr<NdiscCache> cache, Address* hardwareDestination)
@@ -1244,6 +1273,10 @@
/* try to find the cache */
cache = FindCache (device);
}
+ if (!cache)
+ {
+ return false;
+ }
NdiscCache::Entry* entry = cache->Lookup (dst);
if (entry)
--- a/src/internet/model/ipv4-l3-protocol.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/internet/model/ipv4-l3-protocol.cc Tue Jun 04 17:20:40 2013 +0200
@@ -1329,7 +1329,7 @@
m_moreFragment = moreFragment;
}
- m_fragments.insert (it, std::make_pair<Ptr<Packet>, uint16_t> (fragment, fragmentOffset));
+ m_fragments.insert (it, std::pair<Ptr<Packet>, uint16_t> (fragment, fragmentOffset));
}
bool
--- a/src/internet/model/ipv6-autoconfigured-prefix.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/internet/model/ipv6-autoconfigured-prefix.cc Tue Jun 04 17:20:40 2013 +0200
@@ -118,30 +118,42 @@
void Ipv6AutoconfiguredPrefix::StartPreferredTimer ()
{
- NS_LOG_INFO ("Start PreferredTimer for " << m_prefix);
- m_preferredTimer.SetFunction (&Ipv6AutoconfiguredPrefix::FunctionPreferredTimeout, this);
- m_preferredTimer.SetDelay (Seconds (m_preferredLifeTime));
- m_preferredTimer.Schedule ();
+ if (m_preferredLifeTime != 0xffffffff)
+ {
+ NS_LOG_INFO ("Start PreferredTimer for " << m_prefix);
+ m_preferredTimer.SetFunction (&Ipv6AutoconfiguredPrefix::FunctionPreferredTimeout, this);
+ m_preferredTimer.SetDelay (Seconds (m_preferredLifeTime));
+ m_preferredTimer.Schedule ();
+ }
}
void Ipv6AutoconfiguredPrefix::StartValidTimer ()
{
- NS_LOG_INFO ("Start ValidTimer for " << m_prefix);
- m_validTimer.SetFunction (&Ipv6AutoconfiguredPrefix::FunctionValidTimeout, this);
- m_validTimer.SetDelay (Seconds (m_validLifeTime - m_preferredLifeTime));
- m_validTimer.Schedule ();
+ if (m_validLifeTime != 0xffffffff)
+ {
+ NS_LOG_INFO ("Start ValidTimer for " << m_prefix);
+ m_validTimer.SetFunction (&Ipv6AutoconfiguredPrefix::FunctionValidTimeout, this);
+ m_validTimer.SetDelay (Seconds (m_validLifeTime - m_preferredLifeTime));
+ m_validTimer.Schedule ();
+ }
}
void Ipv6AutoconfiguredPrefix::StopPreferredTimer ()
{
- NS_LOG_INFO ("Stop PreferredTimer for " << m_prefix);
- m_preferredTimer.Cancel ();
+ if (m_preferredTimer.IsRunning())
+ {
+ NS_LOG_INFO ("Stop PreferredTimer for " << m_prefix);
+ m_preferredTimer.Cancel ();
+ }
}
void Ipv6AutoconfiguredPrefix::StopValidTimer ()
{
- NS_LOG_INFO ("Stop ValidTimer for " << m_prefix);
- m_validTimer.Cancel ();
+ if (m_validTimer.IsRunning())
+ {
+ NS_LOG_INFO ("Stop ValidTimer for " << m_prefix);
+ m_validTimer.Cancel ();
+ }
}
void Ipv6AutoconfiguredPrefix::RemoveMe ()
--- a/src/internet/model/ipv6-extension.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/internet/model/ipv6-extension.cc Tue Jun 04 17:20:40 2013 +0200
@@ -347,7 +347,7 @@
uint32_t identification = fragmentHeader.GetIdentification ();
Ipv6Address src = ipv6Header.GetSourceAddress ();
- std::pair<Ipv6Address, uint32_t> fragmentsId = std::make_pair<Ipv6Address, uint32_t> (src, identification);
+ std::pair<Ipv6Address, uint32_t> fragmentsId = std::pair<Ipv6Address, uint32_t> (src, identification);
Ptr<Fragments> fragments;
Ipv6Header ipHeader = ipv6Header;
@@ -441,7 +441,7 @@
hopbyhopHeader->SetNextHeader (Ipv6Header::IPV6_EXT_FRAGMENTATION);
}
- unfragmentablePart.push_back (std::make_pair<Ipv6ExtensionHeader *, uint8_t> (hopbyhopHeader, Ipv6Header::IPV6_EXT_HOP_BY_HOP));
+ unfragmentablePart.push_back (std::pair<Ipv6ExtensionHeader *, uint8_t> (hopbyhopHeader, Ipv6Header::IPV6_EXT_HOP_BY_HOP));
unfragmentablePartSize += extensionHeaderLength;
}
else if (nextHeader == Ipv6Header::IPV6_EXT_ROUTING)
@@ -465,7 +465,7 @@
routingHeader->SetNextHeader (Ipv6Header::IPV6_EXT_FRAGMENTATION);
}
- unfragmentablePart.push_back (std::make_pair<Ipv6ExtensionHeader *, uint8_t> (routingHeader, Ipv6Header::IPV6_EXT_ROUTING));
+ unfragmentablePart.push_back (std::pair<Ipv6ExtensionHeader *, uint8_t> (routingHeader, Ipv6Header::IPV6_EXT_ROUTING));
unfragmentablePartSize += extensionHeaderLength;
}
else if (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION)
@@ -485,7 +485,7 @@
destinationHeader->SetNextHeader (Ipv6Header::IPV6_EXT_FRAGMENTATION);
}
- unfragmentablePart.push_back (std::make_pair<Ipv6ExtensionHeader *, uint8_t> (destinationHeader, Ipv6Header::IPV6_EXT_DESTINATION));
+ unfragmentablePart.push_back (std::pair<Ipv6ExtensionHeader *, uint8_t> (destinationHeader, Ipv6Header::IPV6_EXT_DESTINATION));
unfragmentablePartSize += extensionHeaderLength;
}
}
@@ -530,15 +530,24 @@
{
if (it->second == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
{
- fragment->AddHeader (*dynamic_cast<Ipv6ExtensionHopByHopHeader *> (it->first));
+ Ipv6ExtensionHopByHopHeader * p =
+ dynamic_cast<Ipv6ExtensionHopByHopHeader *> (it->first);
+ NS_ASSERT (p != 0);
+ fragment->AddHeader (*p);
}
else if (it->second == Ipv6Header::IPV6_EXT_ROUTING)
{
- fragment->AddHeader (*dynamic_cast<Ipv6ExtensionLooseRoutingHeader *> (it->first));
+ Ipv6ExtensionLooseRoutingHeader * p =
+ dynamic_cast<Ipv6ExtensionLooseRoutingHeader *> (it->first);
+ NS_ASSERT (p != 0);
+ fragment->AddHeader (*p);
}
else if (it->second == Ipv6Header::IPV6_EXT_DESTINATION)
{
- fragment->AddHeader (*dynamic_cast<Ipv6ExtensionDestinationHeader *> (it->first));
+ Ipv6ExtensionDestinationHeader * p =
+ dynamic_cast<Ipv6ExtensionDestinationHeader *> (it->first);
+ NS_ASSERT (p != 0);
+ fragment->AddHeader (*p);
}
}
@@ -611,7 +620,7 @@
m_moreFragment = moreFragment;
}
- m_packetFragments.insert (it, std::make_pair<Ptr<Packet>, uint16_t> (fragment, fragmentOffset));
+ m_packetFragments.insert (it, std::pair<Ptr<Packet>, uint16_t> (fragment, fragmentOffset));
}
void Ipv6ExtensionFragment::Fragments::SetUnfragmentablePart (Ptr<Packet> unfragmentablePart)
--- a/src/internet/model/ipv6-interface.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/internet/model/ipv6-interface.cc Tue Jun 04 17:20:40 2013 +0200
@@ -103,7 +103,10 @@
}
Ptr<Icmpv6L4Protocol> icmpv6 = m_node->GetObject<Ipv6L3Protocol> ()->GetIcmpv6 ();
- m_ndCache = icmpv6->CreateCache (m_device, this);
+ if (m_device->NeedsArp ())
+ {
+ m_ndCache = icmpv6->CreateCache (m_device, this);
+ }
}
void Ipv6Interface::SetNode (Ptr<Node> node)
--- a/src/internet/model/ipv6-l3-protocol.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/internet/model/ipv6-l3-protocol.cc Tue Jun 04 17:20:40 2013 +0200
@@ -293,7 +293,10 @@
/* add default router
* if a previous default route exists, the new ones is simply added
*/
- GetRoutingProtocol ()->NotifyAddRoute (Ipv6Address::GetAny (), Ipv6Prefix ((uint8_t)0), defaultRouter, interface, network);
+ if (!defaultRouter.IsAny())
+ {
+ GetRoutingProtocol ()->NotifyAddRoute (Ipv6Address::GetAny (), Ipv6Prefix ((uint8_t)0), defaultRouter, interface, network);
+ }
Ptr<Ipv6AutoconfiguredPrefix> aPrefix = CreateObject<Ipv6AutoconfiguredPrefix> (m_node, interface, network, mask, preferredTime, validTime, defaultRouter);
aPrefix->StartPreferredTimer ();
@@ -814,6 +817,7 @@
// To get specific method GetFragments from Ipv6ExtensionFragmentation
Ipv6ExtensionFragment *ipv6Fragment = dynamic_cast<Ipv6ExtensionFragment *> (PeekPointer (ipv6ExtensionDemux->GetExtension (Ipv6Header::IPV6_EXT_FRAGMENTATION)));
+ NS_ASSERT (ipv6Fragment != 0);
ipv6Fragment->GetFragments (packet, outInterface->GetDevice ()->GetMtu (), fragments);
}
--- a/src/internet/model/ipv6-option-header.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/internet/model/ipv6-option-header.cc Tue Jun 04 17:20:40 2013 +0200
@@ -317,6 +317,7 @@
Ipv6OptionRouterAlertHeader::Ipv6OptionRouterAlertHeader ()
: m_value (0)
{
+ SetType (5);
SetLength (2);
}
--- a/src/internet/model/pending-data.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/internet/model/pending-data.cc Tue Jun 04 17:20:40 2013 +0200
@@ -103,14 +103,7 @@
void PendingData::Add (uint32_t s, const uint8_t* d)
{
NS_LOG_FUNCTION (this << s);
- if (d == 0)
- {
- data.push_back (Create<Packet> (d,s));
- }
- else
- {
- data.push_back (Create<Packet> (s));
- }
+ data.push_back (Create<Packet> (d,s));
size += s;
}
--- a/src/lte/examples/lena-dual-stripe.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/lte/examples/lena-dual-stripe.cc Tue Jun 04 17:20:40 2013 +0200
@@ -222,7 +222,7 @@
static ns3::GlobalValue g_nBlocks ("nBlocks",
"Number of femtocell blocks",
- ns3::UintegerValue (10),
+ ns3::UintegerValue (1),
ns3::MakeUintegerChecker<uint32_t> ());
static ns3::GlobalValue g_nApartmentsX ("nApartmentsX",
"Number of apartments along the X axis in a femtocell block",
@@ -251,7 +251,7 @@
ns3::MakeDoubleChecker<double> ());
static ns3::GlobalValue g_macroUeDensity ("macroUeDensity",
"How many macrocell UEs there are per square meter",
- ns3::DoubleValue (0.0001),
+ ns3::DoubleValue (0.00002),
ns3::MakeDoubleChecker<double> ());
static ns3::GlobalValue g_homeEnbDeploymentRatio ("homeEnbDeploymentRatio",
"The HeNB deployment ratio as per 3GPP R4-092042",
--- a/src/lte/examples/lena-rlc-traces.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/lte/examples/lena-rlc-traces.cc Tue Jun 04 17:20:40 2013 +0200
@@ -73,7 +73,7 @@
EpsBearer bearer (q);
lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
- Simulator::Stop (Seconds (2));
+ Simulator::Stop (Seconds (0.5));
lteHelper->EnablePhyTraces ();
lteHelper->EnableMacTraces ();
--- a/src/lte/examples/lena-simple-epc.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/lte/examples/lena-simple-epc.cc Tue Jun 04 17:20:40 2013 +0200
@@ -44,7 +44,7 @@
{
uint16_t numberOfNodes = 2;
- double simTime = 5.0;
+ double simTime = 1.1;
double distance = 60.0;
double interPacketInterval = 100;
--- a/src/lte/helper/lte-helper.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/lte/helper/lte-helper.cc Tue Jun 04 17:20:40 2013 +0200
@@ -138,18 +138,24 @@
.SetParent<Object> ()
.AddConstructor<LteHelper> ()
.AddAttribute ("Scheduler",
- "The type of scheduler to be used for eNBs",
+ "The type of scheduler to be used for eNBs. "
+ "The allowed values for this attributes are the type names "
+ "of any class inheriting from ns3::FfMacScheduler.",
StringValue ("ns3::PfFfMacScheduler"),
MakeStringAccessor (&LteHelper::SetSchedulerType),
MakeStringChecker ())
.AddAttribute ("PathlossModel",
- "The type of pathloss model to be used",
+ "The type of pathloss model to be used. "
+ "The allowed values for this attributes are the type names "
+ "of any class inheriting from ns3::PropagationLossModel.",
StringValue ("ns3::FriisPropagationLossModel"),
MakeStringAccessor (&LteHelper::SetPathlossModelType),
MakeStringChecker ())
.AddAttribute ("FadingModel",
- "The type of fading model to be used. If the type is set "
- "to an empty string, no fading model is used.",
+ "The type of fading model to be used."
+ "The allowed values for this attributes are the type names "
+ "of any class inheriting from ns3::SpectrumPropagationLossModel."
+ "If the type is set to an empty string, no fading model is used.",
StringValue (""),
MakeStringAccessor (&LteHelper::SetFadingModel),
MakeStringChecker ())
--- a/src/lte/helper/lte-hex-grid-enb-topology-helper.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/lte/helper/lte-hex-grid-enb-topology-helper.cc Tue Jun 04 17:20:40 2013 +0200
@@ -153,8 +153,7 @@
y -= m_offset*xydfactor;
break;
- default:
- break;
+ // no default, n%3 = 0, 1, 2
}
Ptr<Node> node = c.Get (n);
Ptr<MobilityModel> mm = node->GetObject<MobilityModel> ();
--- a/src/lte/helper/radio-bearer-stats-calculator.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/lte/helper/radio-bearer-stats-calculator.cc Tue Jun 04 17:20:40 2013 +0200
@@ -135,7 +135,7 @@
{
NS_LOG_FUNCTION (this << "UlTxPDU" << cellId << imsi << rnti << (uint32_t) lcid << packetSize);
ImsiLcidPair_t p (imsi, lcid);
- if (Simulator::Now () > m_startTime)
+ if (Simulator::Now () >= m_startTime)
{
m_ulCellId[p] = cellId;
m_flowId[p] = LteFlowId_t (rnti, lcid);
@@ -150,7 +150,7 @@
{
NS_LOG_FUNCTION (this << "DlTxPDU" << cellId << imsi << rnti << (uint32_t) lcid << packetSize);
ImsiLcidPair_t p (imsi, lcid);
- if (Simulator::Now () > m_startTime)
+ if (Simulator::Now () >= m_startTime)
{
m_dlCellId[p] = cellId;
m_flowId[p] = LteFlowId_t (rnti, lcid);
@@ -166,7 +166,7 @@
{
NS_LOG_FUNCTION (this << "UlRxPDU" << cellId << imsi << rnti << (uint32_t) lcid << packetSize << delay);
ImsiLcidPair_t p (imsi, lcid);
- if (Simulator::Now () > m_startTime)
+ if (Simulator::Now () >= m_startTime)
{
m_ulCellId[p] = cellId;
m_ulRxPackets[p]++;
@@ -190,7 +190,7 @@
{
NS_LOG_FUNCTION (this << "DlRxPDU" << cellId << imsi << rnti << (uint32_t) lcid << packetSize << delay);
ImsiLcidPair_t p (imsi, lcid);
- if (Simulator::Now () > m_startTime)
+ if (Simulator::Now () >= m_startTime)
{
m_dlCellId[p] = cellId;
m_dlRxPackets[p]++;
--- a/src/lte/model/fdbet-ff-mac-scheduler.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/lte/model/fdbet-ff-mac-scheduler.cc Tue Jun 04 17:20:40 2013 +0200
@@ -29,6 +29,7 @@
#include <ns3/lte-vendor-specific-parameters.h>
#include <ns3/boolean.h>
#include <set>
+#include <cfloat>
NS_LOG_COMPONENT_DEFINE ("FdBetFfMacScheduler");
@@ -1098,6 +1099,11 @@
uint16_t lcActives = LcActivePerFlow ((*itMap).first);
NS_LOG_INFO (this << "Allocate user " << newEl.m_rnti << " rbg " << lcActives);
+ if (lcActives == 0)
+ {
+ // Set to max value, to avoid divide by 0 below
+ lcActives = (uint16_t)65535; // UINT16_MAX;
+ }
uint16_t RgbPerRnti = (*itMap).second.size ();
std::map <uint16_t,uint8_t>::iterator itCqi;
itCqi = m_p10CqiRxed.find ((*itMap).first);
@@ -1334,7 +1340,7 @@
sinrNum++;
}
}
- double estimatedSinr = sinrSum / (double)sinrNum;
+ double estimatedSinr = (sinrNum > 0) ? (sinrSum / sinrNum) : DBL_MAX;
// store the value
(*itCqi).second.at (rb) = estimatedSinr;
return (estimatedSinr);
--- a/src/lte/model/fdmt-ff-mac-scheduler.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/lte/model/fdmt-ff-mac-scheduler.cc Tue Jun 04 17:20:40 2013 +0200
@@ -29,6 +29,7 @@
#include <ns3/lte-vendor-specific-parameters.h>
#include <ns3/boolean.h>
#include <set>
+#include <cfloat>
NS_LOG_COMPONENT_DEFINE ("FdMtFfMacScheduler");
@@ -1069,6 +1070,11 @@
uint16_t lcActives = LcActivePerFlow ((*itMap).first);
NS_LOG_INFO (this << "Allocate user " << newEl.m_rnti << " rbg " << lcActives);
+ if (lcActives == 0)
+ {
+ // Set to max value, to avoid divide by 0 below
+ lcActives = (uint16_t)65535; // UINT16_MAX;
+ }
uint16_t RgbPerRnti = (*itMap).second.size ();
std::map <uint16_t,SbMeasResult_s>::iterator itCqi;
itCqi = m_a30CqiRxed.find ((*itMap).first);
@@ -1314,7 +1320,7 @@
sinrNum++;
}
}
- double estimatedSinr = sinrSum / (double)sinrNum;
+ double estimatedSinr = (sinrNum > 0) ? (sinrSum / sinrNum) : DBL_MAX;
// store the value
(*itCqi).second.at (rb) = estimatedSinr;
return (estimatedSinr);
--- a/src/lte/model/fdtbfq-ff-mac-scheduler.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/lte/model/fdtbfq-ff-mac-scheduler.cc Tue Jun 04 17:20:40 2013 +0200
@@ -30,6 +30,7 @@
#include <ns3/boolean.h>
#include <ns3/integer.h>
#include <set>
+#include <cfloat>
NS_LOG_COMPONENT_DEFINE ("FdTbfqFfMacScheduler");
@@ -1321,6 +1322,11 @@
uint16_t lcActives = LcActivePerFlow ((*itMap).first);
NS_LOG_INFO (this << "Allocate user " << newEl.m_rnti << " rbg " << lcActives);
+ if (lcActives == 0)
+ {
+ // Set to max value, to avoid divide by 0 below
+ lcActives = (uint16_t)65535; // UINT16_MAX;
+ }
uint16_t RgbPerRnti = (*itMap).second.size ();
std::map <uint16_t,SbMeasResult_s>::iterator itCqi;
itCqi = m_a30CqiRxed.find ((*itMap).first);
@@ -1566,7 +1572,7 @@
sinrNum++;
}
}
- double estimatedSinr = sinrSum / (double)sinrNum;
+ double estimatedSinr = (sinrNum > 0) ? (sinrSum / sinrNum) : DBL_MAX;
// store the value
(*itCqi).second.at (rb) = estimatedSinr;
return (estimatedSinr);
--- a/src/lte/model/lte-enb-phy.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/lte/model/lte-enb-phy.cc Tue Jun 04 17:20:40 2013 +0200
@@ -21,6 +21,7 @@
#include <ns3/object-factory.h>
#include <ns3/log.h>
+#include <cfloat>
#include <cmath>
#include <ns3/simulator.h>
#include <ns3/attribute-accessor-helper.h>
@@ -869,7 +870,8 @@
vsp.m_value = rnti;
ulcqi.m_vendorSpecificList.push_back (vsp);
// call SRS tracing method
- CreateSrsReport (m_srsUeOffset.at (m_currentSrsOffset), srsSum / i);
+ CreateSrsReport (m_srsUeOffset.at (m_currentSrsOffset),
+ (i > 0) ? (srsSum / i) : DBL_MAX);
return (ulcqi);
}
--- a/src/lte/model/lte-ue-phy.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/lte/model/lte-ue-phy.cc Tue Jun 04 17:20:40 2013 +0200
@@ -22,6 +22,7 @@
#include <ns3/object-factory.h>
#include <ns3/log.h>
+#include <cfloat>
#include <cmath>
#include <ns3/simulator.h>
#include <ns3/double.h>
@@ -455,7 +456,7 @@
sum += powerTxW;
rbNum++;
}
- double rsrp = sum / (double)rbNum;
+ double rsrp = (rbNum > 0) ? (sum / rbNum) : DBL_MAX;
// averaged SINR among RBs
sum = 0.0;
rbNum = 0;
@@ -464,7 +465,7 @@
sum += (*it);
rbNum++;
}
- double avSinr = sum / (double)rbNum;
+ double avSinr = (rbNum > 0) ? (sum / rbNum) : DBL_MAX;
NS_LOG_INFO (this << " cellId " << m_cellId << " rnti " << m_rnti << " RSRP " << rsrp << " SINR " << avSinr);
m_reportCurrentCellRsrpSinrTrace (m_cellId, m_rnti, rsrp, avSinr);
--- a/src/lte/model/pf-ff-mac-scheduler.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/lte/model/pf-ff-mac-scheduler.cc Tue Jun 04 17:20:40 2013 +0200
@@ -27,6 +27,7 @@
#include <ns3/pf-ff-mac-scheduler.h>
#include <ns3/lte-vendor-specific-parameters.h>
#include <ns3/boolean.h>
+#include <cfloat>
#include <set>
NS_LOG_COMPONENT_DEFINE ("PfFfMacScheduler");
@@ -1085,6 +1086,11 @@
uint16_t lcActives = LcActivePerFlow ((*itMap).first);
NS_LOG_INFO (this << "Allocate user " << newEl.m_rnti << " rbg " << lcActives);
+ if (lcActives == 0)
+ {
+ // Set to max value, to avoid divide by 0 below
+ lcActives = (uint16_t)65535; // UINT16_MAX;
+ }
uint16_t RgbPerRnti = (*itMap).second.size ();
std::map <uint16_t,SbMeasResult_s>::iterator itCqi;
itCqi = m_a30CqiRxed.find ((*itMap).first);
@@ -1357,7 +1363,7 @@
sinrNum++;
}
}
- double estimatedSinr = sinrSum / (double)sinrNum;
+ double estimatedSinr = (sinrNum > 0) ? (sinrSum / sinrNum) : DBL_MAX;
// store the value
(*itCqi).second.at (rb) = estimatedSinr;
return (estimatedSinr);
--- a/src/lte/model/pss-ff-mac-scheduler.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/lte/model/pss-ff-mac-scheduler.cc Tue Jun 04 17:20:40 2013 +0200
@@ -28,6 +28,7 @@
#include <ns3/pss-ff-mac-scheduler.h>
#include <ns3/lte-vendor-specific-parameters.h>
#include <ns3/boolean.h>
+#include <cfloat>
#include <set>
#include <ns3/string.h>
#include <algorithm>
@@ -1386,6 +1387,11 @@
uint16_t lcActives = LcActivePerFlow ((*itMap).first);
NS_LOG_INFO (this << "Allocate user " << newEl.m_rnti << " rbg " << lcActives);
+ if (lcActives == 0)
+ {
+ // Set to max value, to avoid divide by 0 below
+ lcActives = (uint16_t)65535; // UINT16_MAX;
+ }
uint16_t RgbPerRnti = (*itMap).second.size ();
std::map <uint16_t,SbMeasResult_s>::iterator itCqi;
itCqi = m_a30CqiRxed.find ((*itMap).first);
@@ -1664,7 +1670,7 @@
sinrNum++;
}
}
- double estimatedSinr = sinrSum / (double)sinrNum;
+ double estimatedSinr = (sinrNum > 0) ? (sinrSum / sinrNum) : DBL_MAX;
// store the value
(*itCqi).second.at (rb) = estimatedSinr;
return (estimatedSinr);
--- a/src/lte/model/rr-ff-mac-scheduler.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/lte/model/rr-ff-mac-scheduler.cc Tue Jun 04 17:20:40 2013 +0200
@@ -21,6 +21,7 @@
#include <ns3/log.h>
#include <ns3/pointer.h>
#include <ns3/math.h>
+#include <cfloat>
#include <set>
#include <ns3/lte-amc.h>
@@ -977,7 +978,7 @@
// Divide the resource equally among the active users according to
// Resource allocation type 0 (see sec 7.1.6.1 of 36.213)
- int rbgPerTb = (rbgNum - rbgAllocatedNum) / nTbs;
+ int rbgPerTb = (nTbs > 0) ? ((rbgNum - rbgAllocatedNum) / nTbs) : DBL_MAX;
NS_LOG_INFO (this << " Flows to be transmitted " << nflows << " rbgPerTb " << rbgPerTb);
if (rbgPerTb == 0)
{
--- a/src/lte/model/tdbet-ff-mac-scheduler.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/lte/model/tdbet-ff-mac-scheduler.cc Tue Jun 04 17:20:40 2013 +0200
@@ -29,6 +29,7 @@
#include <ns3/lte-vendor-specific-parameters.h>
#include <ns3/boolean.h>
#include <set>
+#include <cfloat>
NS_LOG_COMPONENT_DEFINE ("TdBetFfMacScheduler");
@@ -1021,6 +1022,11 @@
uint16_t lcActives = LcActivePerFlow ((*itMap).first);
NS_LOG_INFO (this << "Allocate user " << newEl.m_rnti << " rbg " << lcActives);
+ if (lcActives == 0)
+ {
+ // Set to max value, to avoid divide by 0 below
+ lcActives = (uint16_t)65535; // UINT16_MAX;
+ }
uint16_t RgbPerRnti = (*itMap).second.size ();
std::map <uint16_t,uint8_t>::iterator itCqi;
itCqi = m_p10CqiRxed.find ((*itMap).first);
@@ -1257,7 +1263,7 @@
sinrNum++;
}
}
- double estimatedSinr = sinrSum / (double)sinrNum;
+ double estimatedSinr = (sinrNum > 0) ? (sinrSum / sinrNum) : DBL_MAX;
// store the value
(*itCqi).second.at (rb) = estimatedSinr;
return (estimatedSinr);
--- a/src/lte/model/tdmt-ff-mac-scheduler.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/lte/model/tdmt-ff-mac-scheduler.cc Tue Jun 04 17:20:40 2013 +0200
@@ -29,6 +29,7 @@
#include <ns3/lte-vendor-specific-parameters.h>
#include <ns3/boolean.h>
#include <set>
+#include <cfloat>
NS_LOG_COMPONENT_DEFINE ("TdMtFfMacScheduler");
@@ -1048,6 +1049,11 @@
uint16_t lcActives = LcActivePerFlow ((*itMap).first);
NS_LOG_INFO (this << "Allocate user " << newEl.m_rnti << " rbg " << lcActives);
+ if (lcActives == 0)
+ {
+ // Set to max value, to avoid divide by 0 below
+ lcActives = (uint16_t)65535; // UINT16_MAX;
+ }
uint16_t RgbPerRnti = (*itMap).second.size ();
std::map <uint16_t,uint8_t>::iterator itCqi;
itCqi = m_p10CqiRxed.find ((*itMap).first);
@@ -1254,7 +1260,7 @@
sinrNum++;
}
}
- double estimatedSinr = sinrSum / (double)sinrNum;
+ double estimatedSinr = (sinrNum > 0) ? (sinrSum / sinrNum) : DBL_MAX;
// store the value
(*itCqi).second.at (rb) = estimatedSinr;
return (estimatedSinr);
--- a/src/lte/model/tdtbfq-ff-mac-scheduler.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/lte/model/tdtbfq-ff-mac-scheduler.cc Tue Jun 04 17:20:40 2013 +0200
@@ -30,6 +30,7 @@
#include <ns3/boolean.h>
#include <ns3/integer.h>
#include <set>
+#include <cfloat>
NS_LOG_COMPONENT_DEFINE ("TdTbfqFfMacScheduler");
@@ -1096,6 +1097,11 @@
uint16_t lcActives = LcActivePerFlow ((*itMap).first);
NS_LOG_INFO (this << "Allocate user " << newEl.m_rnti << " rbg " << lcActives);
+ if (lcActives == 0)
+ {
+ // Set to max value, to avoid divide by 0 below
+ lcActives = (uint16_t)65535; // UINT16_MAX;
+ }
uint16_t RgbPerRnti = (*itMap).second.size ();
std::map <uint16_t,SbMeasResult_s>::iterator itCqi;
itCqi = m_a30CqiRxed.find ((*itMap).first);
@@ -1352,7 +1358,7 @@
sinrNum++;
}
}
- double estimatedSinr = sinrSum / (double)sinrNum;
+ double estimatedSinr = (sinrNum > 0) ? (sinrSum / sinrNum) : DBL_MAX;
// store the value
(*itCqi).second.at (rb) = estimatedSinr;
return (estimatedSinr);
--- a/src/lte/model/tta-ff-mac-scheduler.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/lte/model/tta-ff-mac-scheduler.cc Tue Jun 04 17:20:40 2013 +0200
@@ -29,6 +29,7 @@
#include <ns3/lte-vendor-specific-parameters.h>
#include <ns3/boolean.h>
#include <set>
+#include <cfloat>
NS_LOG_COMPONENT_DEFINE ("TtaFfMacScheduler");
@@ -1087,6 +1088,11 @@
uint16_t lcActives = LcActivePerFlow ((*itMap).first);
NS_LOG_INFO (this << "Allocate user " << newEl.m_rnti << " rbg " << lcActives);
+ if (lcActives == 0)
+ {
+ // Set to max value, to avoid divide by 0 below
+ lcActives = (uint16_t)65535; // UINT16_MAX;
+ }
uint16_t RgbPerRnti = (*itMap).second.size ();
std::map <uint16_t,SbMeasResult_s>::iterator itCqi;
itCqi = m_a30CqiRxed.find ((*itMap).first);
@@ -1333,7 +1339,7 @@
sinrNum++;
}
}
- double estimatedSinr = sinrSum / (double)sinrNum;
+ double estimatedSinr = (sinrNum > 0) ? (sinrSum / sinrNum) : DBL_MAX;
// store the value
(*itCqi).second.at (rb) = estimatedSinr;
return (estimatedSinr);
--- a/src/lte/test/lte-test-pf-ff-mac-scheduler.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/lte/test/lte-test-pf-ff-mac-scheduler.cc Tue Jun 04 17:20:40 2013 +0200
@@ -85,7 +85,7 @@
// DOWNLINK - DISTANCE 4800 -> MCS 16 -> Itbs 20 (from table 7.1.7.2.1-1 of 36.213)
- // 1 user -> 24 PRB at Itbs 20 -> 903 -> 903000 bytes/sec
+ // 1 user -> 24 PRB at Itbs 15 -> 903 -> 903000 bytes/sec
// 3 users -> 903000 among 3 users -> 301000 bytes/sec
// 6 users -> 903000 among 6 users -> 150500 bytes/sec
// 12 users -> 903000 among 12 users -> 75250 bytes/sec
@@ -104,7 +104,7 @@
AddTestCase (new LenaPfFfMacSchedulerTestCase1 (15,0,4800,60200,49600,errorModel), TestCase::EXTENSIVE);
// DOWNLINK - DISTANCE 6000 -> MCS 14 -> Itbs 13 (from table 7.1.7.2.1-1 of 36.213)
- // 1 user -> 24 PRB at Itbs 15 -> 775 -> 775000 bytes/sec
+ // 1 user -> 24 PRB at Itbs 13 -> 775 -> 775000 bytes/sec
// 3 users -> 775000 among 3 users -> 258000 bytes/sec
// 6 users -> 775000 among 6 users -> 129200 bytes/sec
// 12 users -> 775000 among 12 users -> 64590 bytes/sec
--- a/src/lte/test/lte-test-pss-ff-mac-scheduler.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/lte/test/lte-test-pss-ff-mac-scheduler.cc Tue Jun 04 17:20:40 2013 +0200
@@ -161,8 +161,8 @@
// Traffic1 info
// UDP traffic: payload size = 100 bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 132000 byte/rate
- // Maximum throughput = 4 / ( 1/2196000 + 1/903000 + 1/621000 + 1/421000 ) = 720930 byte/s
- // 132000 * 4 = 528000 < 720930 -> estimated throughput in downlink = 132000 byte/sec
+ // Maximum throughput = 4 / ( 1/2196000 + 1/903000 + 1/775000 + 1/421000 ) = 765051 byte/s
+ // 132000 * 4 = 528000 < 765051 -> estimated throughput in downlink = 132000 byte/sec
std::vector<uint16_t> dist1;
dist1.push_back (0); // User 0 distance --> MCS 28
dist1.push_back (4800); // User 1 distance --> MCS 16
@@ -178,13 +178,13 @@
estThrPssDl1.push_back (132000); // User 1 estimated TTI throughput from PSS
estThrPssDl1.push_back (132000); // User 2 estimated TTI throughput from PSS
estThrPssDl1.push_back (132000); // User 3 estimated TTI throughput from PSS
- AddTestCase (new LenaPssFfMacSchedulerTestCase2 (dist1,estThrPssDl1,packetSize1,1,errorModel), TestCase::EXTENSIVE);
+ AddTestCase (new LenaPssFfMacSchedulerTestCase2 (dist1,estThrPssDl1,packetSize1,1,errorModel), TestCase::QUICK);
// Traffic2 info
// UDP traffic: payload size = 200 bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> 232000 byte/rate
- // Maximum throughput = 4 / ( 1/2196000 + 1/903000 + 1/621000 + 1/421000 ) = 720930 byte/s
- // 232000 * 4 = 928000 > 720930 -> estimated throughput in downlink = 720930 / 4 = 180232 byte/sec
+ // Maximum throughput = 4 / ( 1/2196000 + 1/903000 + 1/775000 + 1/421000 ) = 765051 byte/s
+ // 232000 * 4 = 928000 > 765051 -> estimated throughput in downlink = 765051 / 4 = 191263 byte/sec
std::vector<uint16_t> dist2;
dist2.push_back (0); // User 0 distance --> MCS 28
dist2.push_back (4800); // User 1 distance --> MCS 16
@@ -196,17 +196,17 @@
packetSize2.push_back (200);
packetSize2.push_back (200);
std::vector<uint32_t> estThrPssDl2;
- estThrPssDl2.push_back (180232); // User 0 estimated TTI throughput from PSS
- estThrPssDl2.push_back (180232); // User 1 estimated TTI throughput from PSS
- estThrPssDl2.push_back (180232); // User 2 estimated TTI throughput from PSS
- estThrPssDl2.push_back (180232); // User 3 estimated TTI throughput from PSS
- AddTestCase (new LenaPssFfMacSchedulerTestCase2 (dist2,estThrPssDl2,packetSize2,1,errorModel), TestCase::EXTENSIVE);
+ estThrPssDl2.push_back (191263); // User 0 estimated TTI throughput from PSS
+ estThrPssDl2.push_back (191263); // User 1 estimated TTI throughput from PSS
+ estThrPssDl2.push_back (191263); // User 2 estimated TTI throughput from PSS
+ estThrPssDl2.push_back (191263); // User 3 estimated TTI throughput from PSS
+ AddTestCase (new LenaPssFfMacSchedulerTestCase2 (dist2,estThrPssDl2,packetSize2,1,errorModel), TestCase::QUICK);
// Test Case 3: heterogeneous flow test in PSS
// UDP traffic: payload size = [100,200,300] bytes, interval = 1 ms
// UDP rate in scheduler: (payload + RLC header + PDCP header + IP header + UDP header) * 1000 byte/sec -> [132000, 232000, 332000] byte/rate
- // Maximum throughput = 3 / ( 1/2196000 + 1/903000 + 1/621000 ) = 945450 byte/s
- // 132000 + 232000 + 332000 = 696000 < 945450 -> estimated throughput in downlink = [132000, 232000, 332000] byte/sec
+ // Maximum throughput = 3 / ( 1/2196000 + 1/903000 + 1/775000 ) = 1051482 byte/s
+ // 132000 + 232000 + 332000 = 696000 < 1051482 -> estimated throughput in downlink = [132000, 232000, 332000] byte/sec
std::vector<uint16_t> dist3;
dist3.push_back (0); // User 0 distance --> MCS 28
dist3.push_back (4800); // User 1 distance --> MCS 16
@@ -406,11 +406,11 @@
clientApps.Add (ulClient.Install (ueNodes.Get (u)));
}
- serverApps.Start (Seconds (0.001));
- clientApps.Start (Seconds (0.001));
+ serverApps.Start (Seconds (0.030));
+ clientApps.Start (Seconds (0.030));
- double statsStartTime = 0.001; // need to allow for RRC connection establishment + SRS
- double statsDuration = 1;
+ double statsStartTime = 0.04; // need to allow for RRC connection establishment + SRS
+ double statsDuration = 0.5;
double tolerance = 0.1;
Simulator::Stop (Seconds (statsStartTime + statsDuration - 0.0001));
@@ -647,11 +647,11 @@
clientApps.Add (ulClient.Install (ueNodes.Get (u)));
}
- serverApps.Start (Seconds (0.001));
- clientApps.Start (Seconds (0.001));
+ serverApps.Start (Seconds (0.030));
+ clientApps.Start (Seconds (0.030));
- double statsStartTime = 0.001; // need to allow for RRC connection establishment + SRS
- double statsDuration = 1.0;
+ double statsStartTime = 0.04; // need to allow for RRC connection establishment + SRS
+ double statsDuration = 0.5;
double tolerance = 0.1;
Simulator::Stop (Seconds (statsStartTime + statsDuration - 0.0001));
--- a/src/lte/test/test-lte-epc-e2e-data.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/lte/test/test-lte-epc-e2e-data.cc Tue Jun 04 17:20:40 2013 +0200
@@ -432,7 +432,7 @@
EnbTestData e8;
UeTestData u8;
- BearerTestData f8 (100, 15000, 0.001);
+ BearerTestData f8 (50, 8000, 0.02); // watch out for ns3::LteRlcUm::MaxTxBufferSize
u8.bearers.push_back (f8);
e8.ues.push_back (u8);
std::vector<EnbTestData> v8;
--- a/src/lte/test/test-lte-x2-handover.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/lte/test/test-lte-x2-handover.cc Tue Jun 04 17:20:40 2013 +0200
@@ -239,8 +239,8 @@
if (m_epc)
{
- bool epcDl = true;
- bool epcUl = true;
+ // always true: bool epcDl = true;
+ // always true: bool epcUl = true;
// the rest of this block is copied from lena-dual-stripe
@@ -276,7 +276,7 @@
if (m_useUdp)
{
- if (epcDl)
+ // always true: if (epcDl)
{
UdpClientHelper dlClientHelper (ueIpIfaces.GetAddress (u), dlPort);
clientApps.Add (dlClientHelper.Install (remoteHost));
@@ -287,7 +287,7 @@
serverApps.Add (sinkContainer);
}
- if (epcUl)
+ // always true: if (epcUl)
{
UdpClientHelper ulClientHelper (remoteHostAddr, ulPort);
clientApps.Add (ulClientHelper.Install (ue));
@@ -300,7 +300,7 @@
}
else // use TCP
{
- if (epcDl)
+ // always true: if (epcDl)
{
BulkSendHelper dlClientHelper ("ns3::TcpSocketFactory",
InetSocketAddress (ueIpIfaces.GetAddress (u), dlPort));
@@ -312,7 +312,7 @@
bearerData.dlSink = sinkContainer.Get (0)->GetObject<PacketSink> ();
serverApps.Add (sinkContainer);
}
- if (epcUl)
+ // always true: if (epcUl)
{
BulkSendHelper ulClientHelper ("ns3::TcpSocketFactory",
InetSocketAddress (remoteHostAddr, ulPort));
@@ -327,14 +327,14 @@
} // end if (useUdp)
Ptr<EpcTft> tft = Create<EpcTft> ();
- if (epcDl)
+ // always true: if (epcDl)
{
EpcTft::PacketFilter dlpf;
dlpf.localPortStart = dlPort;
dlpf.localPortEnd = dlPort;
tft->Add (dlpf);
}
- if (epcUl)
+ // always true: if (epcUl)
{
EpcTft::PacketFilter ulpf;
ulpf.remotePortStart = ulPort;
@@ -342,7 +342,7 @@
tft->Add (ulpf);
}
- if (epcDl || epcUl)
+ // always true: if (epcDl || epcUl)
{
EpsBearer bearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT);
m_lteHelper->ActivateDedicatedEpsBearer (ueDevices.Get (u), bearer, tft);
--- a/src/mesh/model/dot11s/ie-dot11s-beacon-timing.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/mesh/model/dot11s/ie-dot11s-beacon-timing.cc Tue Jun 04 17:20:40 2013 +0200
@@ -189,7 +189,7 @@
&& (a.GetBeaconInterval () == b.GetBeaconInterval ()));
}
bool
-IeBeaconTiming::operator== (WifiInformationElement const & a)
+IeBeaconTiming::operator== (WifiInformationElement const & a) const
{
try {
IeBeaconTiming const & aa = dynamic_cast<IeBeaconTiming const &>(a);
--- a/src/mesh/model/dot11s/ie-dot11s-beacon-timing.h Tue Jun 04 16:57:16 2013 +0200
+++ b/src/mesh/model/dot11s/ie-dot11s-beacon-timing.h Tue Jun 04 17:20:40 2013 +0200
@@ -93,7 +93,7 @@
virtual uint8_t DeserializeInformationField (Buffer::Iterator i, uint8_t length);
virtual void Print (std::ostream& os) const;
///\}
- bool operator== (WifiInformationElement const & a);
+ bool operator== (WifiInformationElement const & a) const;
private:
/**
* Converters:
--- a/src/mesh/model/dot11s/peer-link.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/mesh/model/dot11s/peer-link.cc Tue Jun 04 17:20:40 2013 +0200
@@ -578,6 +578,7 @@
{
case CLS_ACPT:
ClearHoldingTimer ();
+ // fall through:
case TOH:
m_state = IDLE;
m_linkStatusCallback (m_interface, m_peerAddress, m_peerMeshPointAddress, HOLDING, IDLE);
--- a/src/mobility/test/ns2-mobility-helper-test-suite.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/mobility/test/ns2-mobility-helper-test-suite.cc Tue Jun 04 17:20:40 2013 +0200
@@ -49,6 +49,8 @@
#include "ns3/config.h"
#include "ns3/ns2-mobility-helper.h"
+NS_LOG_COMPONENT_DEFINE ("ns2-mobility-helper-test-suite");
+
namespace ns3 {
// -----------------------------------------------------------------------------
@@ -227,7 +229,10 @@
void DoTeardown ()
{
Names::Clear ();
- std::remove (m_traceFile.c_str ());
+ if (std::remove (m_traceFile.c_str ()))
+ {
+ NS_LOG_ERROR ("Failed to delete file " << m_traceFile);
+ }
Simulator::Destroy ();
}
--- a/src/netanim/model/animation-interface.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/netanim/model/animation-interface.cc Tue Jun 04 17:20:40 2013 +0200
@@ -153,7 +153,7 @@
NS_LOG_WARN ("Routing protocol object not found");
return;
}
- Ptr<Packet> pkt = 0;
+ Ptr<Packet> pkt = Create<Packet> ();
Ipv4Header header;
header.SetDestination (Ipv4Address (to.c_str ()));
Socket::SocketErrno sockerr;
--- a/src/network/model/address.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/network/model/address.cc Tue Jun 04 17:20:40 2013 +0200
@@ -253,7 +253,7 @@
NS_LOG_FUNCTION_NOARGS ();
std::istringstream iss;
iss.str (v);
- uint32_t retval;
+ uint8_t retval;
iss >> std::hex >> retval >> std::dec;
return retval;
}
--- a/src/network/model/byte-tag-list.h Tue Jun 04 16:57:16 2013 +0200
+++ b/src/network/model/byte-tag-list.h Tue Jun 04 17:20:40 2013 +0200
@@ -31,7 +31,7 @@
/**
* \ingroup packet
*
- * \brief keep track of the tags stored in a packet.
+ * \brief keep track of the byte tags stored in a packet.
*
* This class is mostly private to the Packet implementation and users
* should never have to access it directly.
@@ -40,15 +40,15 @@
* The implementation of this class is a bit tricky so, there are a couple
* of things to keep in mind here:
*
- * - it stores all tags in a single byte buffer: each tag is stored
+ * - It stores all tags in a single byte buffer: each tag is stored
* as 4 32bit integers (TypeId, tag data size, start, end) followed
* by the tag data as generated by Tag::Serialize.
*
- * - the struct ByteTagListData structure which contains the tag byte buffer
+ * - The struct ByteTagListData structure which contains the tag byte buffer
* is shared and, thus, reference-counted. This data structure is unshared
* as-needed to emulate COW semantics.
*
- * - each tag tags a unique set of bytes identified by the pair of offsets
+ * - Each tag tags a unique set of bytes identified by the pair of offsets
* (start,end). These offsets are provided by Buffer::GetCurrentStartOffset
* and Buffer::GetCurrentEndOffset which means that they are relative to
* the start of the 'virtual byte buffer' as explained in the documentation
@@ -59,7 +59,7 @@
* the Packet class calls ByteTagList::AddAtEnd and ByteTagList::AddAtStart to update
* the byte offsets of each tag in the ByteTagList.
*
- * - whenever bytes are removed from the packet byte buffer, the ByteTagList offsets
+ * - Whenever bytes are removed from the packet byte buffer, the ByteTagList offsets
* are never updated because we rely on the fact that they will be updated in
* either the next call to Packet::AddHeader or Packet::AddTrailer or when
* the user iterates the tag list with Packet::GetTagIterator and
--- a/src/network/model/packet-tag-list.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/network/model/packet-tag-list.cc Tue Jun 04 17:20:40 2013 +0200
@@ -17,6 +17,12 @@
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
+
+/**
+\file packet-tag-list.cc
+\brief Implements a linked list of Packet tags, including copy-on-write semantics.
+*/
+
#include "packet-tag-list.h"
#include "tag-buffer.h"
#include "tag.h"
@@ -28,123 +34,228 @@
namespace ns3 {
-#ifdef USE_FREE_LIST
-
-struct PacketTagList::TagData *PacketTagList::g_free = 0;
-uint32_t PacketTagList::g_nfree = 0;
-
-struct PacketTagList::TagData *
-PacketTagList::AllocData (void) const
-{
- NS_LOG_FUNCTION_NOARGS ();
- struct PacketTagList::TagData *retval;
- if (g_free != 0)
- {
- retval = g_free;
- g_free = g_free->m_next;
- g_nfree--;
- }
- else
- {
- retval = new struct PacketTagList::TagData ();
- }
- return retval;
-}
-
-void
-PacketTagList::FreeData (struct TagData *data) const
+bool
+PacketTagList::COWTraverse (Tag & tag, PacketTagList::COWWriter Writer)
{
- NS_LOG_FUNCTION (data);
- if (g_nfree > 1000)
- {
- delete data;
- return;
- }
- g_nfree++;
- data->next = g_free;
- data->tid = TypeId ();
- g_free = data;
-}
-#else
-struct PacketTagList::TagData *
-PacketTagList::AllocData (void) const
-{
- NS_LOG_FUNCTION (this);
- struct PacketTagList::TagData *retval;
- retval = new struct PacketTagList::TagData ();
- return retval;
-}
+ TypeId tid = tag.GetInstanceTypeId ();
+ NS_LOG_FUNCTION (this << tid);
+ NS_LOG_INFO ("looking for " << tid);
-void
-PacketTagList::FreeData (struct TagData *data) const
-{
- NS_LOG_FUNCTION (this << data);
- delete data;
-}
-#endif
-
-bool
-PacketTagList::Remove (Tag &tag)
-{
- NS_LOG_FUNCTION (this << &tag);
- TypeId tid = tag.GetInstanceTypeId ();
- bool found = false;
- for (struct TagData *cur = m_next; cur != 0; cur = cur->next)
- {
- if (cur->tid == tid)
- {
- found = true;
- tag.Deserialize (TagBuffer (cur->data, cur->data+PACKET_TAG_MAX_SIZE));
- }
- }
- if (!found)
+ // trivial case when list is empty
+ if (m_next == 0)
{
return false;
}
- struct TagData *start = 0;
- struct TagData **prevNext = &start;
- for (struct TagData *cur = m_next; cur != 0; cur = cur->next)
+
+ bool found = false;
+
+ struct TagData ** prevNext = &m_next; // previous node's next pointer
+ struct TagData * cur = m_next; // cursor to current node
+ struct TagData * it = 0; // utility
+
+ // Search from the head of the list until we find tid or a merge
+ while (cur != 0)
{
- if (cur->tid == tid)
+ if (cur->count > 1)
+ {
+ // found merge
+ NS_LOG_INFO ("found initial merge before tid");
+ break;
+ }
+ else if (cur->tid == tid)
+ {
+ NS_LOG_INFO ("found tid before initial merge, calling writer");
+ found = (this->*Writer)(tag, true, cur, prevNext);
+ break;
+ }
+ else
{
- /**
- * XXX
- * Note: I believe that we could optimize this to
- * avoid copying each TagData located after the target id
- * and just link the already-copied list to the next tag.
- */
- continue;
+ // no merge or tid found yet, move on
+ prevNext = &cur->next;
+ cur = cur->next;
+ }
+ } // while !found && !cow
+
+ // did we find it or run out of tags?
+ if (cur == 0 || found)
+ {
+ NS_LOG_INFO ("returning after header with found: " << found);
+ return found;
+ }
+
+ // From here on out, we have to copy the list
+ // until we find tid, then link past it
+
+ // Before we do all that work, let's make sure tid really exists
+ for (it = cur; it != 0; it = it->next)
+ {
+ if (it->tid == tid)
+ {
+ break;
}
- struct TagData *copy = AllocData ();
+ }
+ if (it == 0)
+ {
+ // got to end of list without finding tid
+ NS_LOG_INFO ("tid not found after first merge");
+ return found;
+ }
+
+ // At this point cur is a merge, but untested for tid
+ NS_ASSERT (cur != 0);
+ NS_ASSERT (cur->count > 1);
+
+ /*
+ Walk the remainder of the list, copying, until we find tid
+ As we put a copy of the cur node onto our list,
+ we move the merge point down the list.
+
+ Starting position End position
+ T1 is a merge T1.count decremented
+ T2 is a merge
+ T1' is a copy of T1
+
+ other other
+ \ \
+ Prev -> T1 -> T2 -> ... T1 -> T2 -> ...
+ / / /|
+ pNext cur Prev -> T1' --/ |
+ / |
+ pNext cur
+
+ When we reach tid, we link past it, decrement count, and we're done.
+ */
+
+ // Should normally check for null cur pointer,
+ // but since we know tid exists, we'll skip this test
+ while ( /* cur && */ cur->tid != tid)
+ {
+ NS_ASSERT (cur != 0);
+ NS_ASSERT (cur->count > 1);
+ cur->count--; // unmerge cur
+ struct TagData * copy = new struct TagData ();
copy->tid = cur->tid;
copy->count = 1;
- copy->next = 0;
- std::memcpy (copy->data, cur->data, PACKET_TAG_MAX_SIZE);
- *prevNext = copy;
- prevNext = ©->next;
+ memcpy (copy->data, cur->data, TagData::MAX_SIZE);
+ copy->next = cur->next; // merge into tail
+ copy->next->count++; // mark new merge
+ *prevNext = copy; // point prior list at copy
+ prevNext = ©->next; // advance
+ cur = copy->next;
+ }
+ // Sanity check:
+ NS_ASSERT (cur != 0); // cur should be non-zero
+ NS_ASSERT (cur->tid == tid); // cur->tid should be tid
+ NS_ASSERT (cur->count > 1); // cur should be a merge
+
+ // link around tid, removing it from our list
+ found = (this->*Writer)(tag, false, cur, prevNext);
+ return found;
+
+}
+
+bool
+PacketTagList::Remove (Tag & tag)
+{
+ return COWTraverse (tag, &PacketTagList::RemoveWriter);
+}
+
+// COWWriter implementing Remove
+bool
+PacketTagList::RemoveWriter (Tag & tag, bool preMerge,
+ struct PacketTagList::TagData * cur,
+ struct PacketTagList::TagData ** prevNext)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ // found tid
+ bool found = true;
+ tag.Deserialize (TagBuffer (cur->data,
+ cur->data + TagData::MAX_SIZE));
+ *prevNext = cur->next; // link around cur
+
+ if (preMerge)
+ {
+ // found tid before first merge, so delete cur
+ delete cur;
}
- *prevNext = 0;
- RemoveAll ();
- m_next = start;
- return true;
+ else
+ {
+ // cur is always a merge at this point
+ // unmerge cur, since we linked around it already
+ cur->count--;
+ if (cur->next != 0)
+ {
+ // there's a next, so make it a merge
+ cur->next->count++;
+ }
+ }
+ return found;
+}
+
+bool
+PacketTagList::Replace (Tag & tag)
+{
+ bool found = COWTraverse (tag, &PacketTagList::ReplaceWriter);
+ if (!found)
+ {
+ Add (tag);
+ }
+ return found;
+}
+
+// COWWriter implementing Replace
+bool
+PacketTagList::ReplaceWriter (Tag & tag, bool preMerge,
+ struct PacketTagList::TagData * cur,
+ struct PacketTagList::TagData ** prevNext)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ // found tid
+ bool found = true;
+ if (preMerge)
+ {
+ // found tid before first merge, so just rewrite
+ tag.Serialize (TagBuffer (cur->data,
+ cur->data + tag.GetSerializedSize ()));
+ }
+ else
+ {
+ // cur is always a merge at this point
+ // need to copy, replace, and link past cur
+ cur->count--; // unmerge cur
+ struct TagData * copy = new struct TagData ();
+ copy->tid = tag.GetInstanceTypeId ();
+ copy->count = 1;
+ tag.Serialize (TagBuffer (copy->data,
+ copy->data + tag.GetSerializedSize ()));
+ copy->next = cur->next; // merge into tail
+ if (copy->next != 0)
+ {
+ copy->next->count++; // mark new merge
+ }
+ *prevNext = copy; // point prior list at copy
+ }
+ return found;
}
void
PacketTagList::Add (const Tag &tag) const
{
- NS_LOG_FUNCTION (this << &tag);
+ NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ());
// ensure this id was not yet added
for (struct TagData *cur = m_next; cur != 0; cur = cur->next)
{
NS_ASSERT (cur->tid != tag.GetInstanceTypeId ());
}
- struct TagData *head = AllocData ();
+ struct TagData * head = new struct TagData ();
head->count = 1;
head->next = 0;
head->tid = tag.GetInstanceTypeId ();
head->next = m_next;
- NS_ASSERT (tag.GetSerializedSize () <= PACKET_TAG_MAX_SIZE);
- tag.Serialize (TagBuffer (head->data, head->data+tag.GetSerializedSize ()));
+ NS_ASSERT (tag.GetSerializedSize () <= TagData::MAX_SIZE);
+ tag.Serialize (TagBuffer (head->data, head->data + tag.GetSerializedSize ()));
const_cast<PacketTagList *> (this)->m_next = head;
}
@@ -152,14 +263,14 @@
bool
PacketTagList::Peek (Tag &tag) const
{
- NS_LOG_FUNCTION (this << &tag);
+ NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ());
TypeId tid = tag.GetInstanceTypeId ();
for (struct TagData *cur = m_next; cur != 0; cur = cur->next)
{
if (cur->tid == tid)
{
/* found tag */
- tag.Deserialize (TagBuffer (cur->data, cur->data+PACKET_TAG_MAX_SIZE));
+ tag.Deserialize (TagBuffer (cur->data, cur->data + TagData::MAX_SIZE));
return true;
}
}
@@ -173,5 +284,5 @@
return m_next;
}
-} // namespace ns3
+} /* namespace ns3 */
--- a/src/network/model/packet-tag-list.h Tue Jun 04 16:57:16 2013 +0200
+++ b/src/network/model/packet-tag-list.h Tue Jun 04 17:20:40 2013 +0200
@@ -20,6 +20,11 @@
#ifndef PACKET_TAG_LIST_H
#define PACKET_TAG_LIST_H
+/**
+\file packet-tag-list.h
+\brief Defines a linked list of Packet tags, including copy-on-write semantics.
+*/
+
#include <stdint.h>
#include <ostream>
#include "ns3/type-id.h"
@@ -29,44 +34,261 @@
class Tag;
/**
- * \ingroup constants
- * \brief Tag maximum size
- * The maximum size (in bytes) of a Tag is stored
- * in this constant.
+ * \ingroup packet
+ *
+ * \brief List of the packet tags stored in a packet.
+ *
+ * This class is mostly private to the Packet implementation and users
+ * should never have to access it directly.
+ *
+ * \intern
+ *
+ * The implementation of this class is a bit tricky. Refer to this
+ * diagram in the discussion that follows.
+ *
+ * \dot
+ * digraph {
+ * rankdir = "LR";
+ * clusterrank = local;
+ * node [ shape = record, fontname="FreeSans", fontsize="10" ];
+ * oth [ label="<l> Other branch | <n> next | <c> ..." ];
+ * PTL1 [ label="<l> PacketTagList A | <n> m_next" , shape=Mrecord];
+ * PTL2 [ label="<l> PacketTagList B | <n> m_next" , shape=Mrecord];
+ * oth:n -> T7:l ;
+ * PTL2:n -> T6:l ;
+ * PTL1:n -> T5:l ;
+ * T1 [ label="<l> T1 | <n> next | <c> count = 1" ];
+ * T2 [ label="<l> T2 | <n> next | <c> count = 1" ];
+ * T3 [ label="<l> T3 | <n> next | <c> count = 2" ];
+ * T4 [ label="<l> T4 | <n> next | <c> count = 1" ];
+ * T5 [ label="<l> T5 | <n> next | <c> count = 2" ];
+ * T6 [ label="<l> T6 | <n> next | <c> count = 1" ];
+ * T7 [ label="<l> T7 | <n> next | <c> count = 1" ];
+ * NULL [ label="0", shape = ellipse ];
+ * subgraph cluster_list {
+ * penwidth = 0;
+ * T6:n -> T5:l ;
+ * T5:n -> T4:l ;
+ * T4:n -> T3:l ;
+ * T7:n -> T3:l ;
+ * T3:n -> T2:l ;
+ * T2:n -> T1:l ;
+ * T1:n -> NULL ;
+ * };
+ * };
+ * \enddot
+ *
+ * - Tags are stored in serialized form in a tree of TagData
+ * structures. (<tt>T1-T7</tt> in the diagram)
+ *
+ * - Each TagData points (\c next pointers in the diagram)
+ * toward the root of the tree, which is a null pointer.
+ *
+ * - \c count is the number of incoming pointers to this
+ * TagData. Branch points, where branches merge or join, have
+ * <tt>count \> 1</tt> (\c T3, \c T5); successive links along
+ * a branch have <tt>count = 1</tt> (\c T1, \c T2, \c T4, \c T6, \c T7).
+ *
+ * - Each PacketTagList points to a specific TagData,
+ * which is the most recent Tag added to the packet. (<tt>T5-T7</tt>)
+ *
+ * - Conceptually, therefore, each Packet has a PacketTagList which
+ * points to a singly-linked list of TagData.
+ *
+ * \par <b> Copy-on-write </b> is implemented as follows:
+ *
+ * - #Add prepends the new tag to the list (growing that branch of the tree,
+ * as \c T6). This is a constant time operation, and does not affect
+ * any other #PacketTagList's, hence this is a \c const function.
+ *
+ * - Copy constructor (PacketTagList(const PacketTagList & o))
+ * and assignment (#operator=(const PacketTagList & o)
+ * simply join the tree at the same place as the original
+ * PacketTagList \c o, incrementing the \c count.
+ * For assignment, the old branch is deleted, up to
+ * the first branch point, which has its \c count decremented.
+ * (PacketTagList \c B started as a copy of PacketTagList \c A,
+ * before \c T6 was added to \c B).
+ *
+ * - #Remove and #Replace are a little tricky, depending on where the
+ * target tag is found relative to the first branch point:
+ * - \e Target before <em> the first branch point: </em> \n
+ * The target is just dealt with in place (linked around and deleted,
+ * in the case of #Remove; rewritten in the case of #Replace).
+ * - \e Target at or after <em> the first branch point: </em> \n
+ * The portion of the list between the first branch and the target is
+ * shared. This portion is copied before the #Remove or #Replace is
+ * performed.
+ *
+ * \par <b> Memory Management: </b>
+ * \n
+ * Packet tags must serialize to a finite maximum size, see TagData
+ *
+ * This documentation entitles the original author to a free beer.
*/
-#define PACKET_TAG_MAX_SIZE 20
-
class PacketTagList
{
public:
- struct TagData {
- uint8_t data[PACKET_TAG_MAX_SIZE];
- struct TagData *next;
- TypeId tid;
- uint32_t count;
+ /**
+ * Tree node for sharing serialized tags.
+ *
+ * See PacketTagList for a discussion of the data structure.
+ *
+ * See TagData::TagData_e for a discussion of the size limit on
+ * tag serialization.
+ */
+ struct TagData
+ {
+ /**
+ * \brief Packet Tag maximum size
+ *
+ * The maximum size (in bytes) of a Tag is stored
+ * in this constant.
+ *
+ * \intern
+ * Ideally, TagData would be 32 bytes in size, so they require
+ * no padding on 64-bit architectures. (The architecture
+ * affects the size because of the \c #next pointer.)
+ * This would leave 18 bytes for \c #data. However,
+ * ns3:Ipv6PacketInfoTag needs 19 bytes! The current
+ * implementation allows 20 bytes, which gives TagData
+ * a size of 30 bytes on 32-byte machines (which gets
+ * padded with 2 bytes), and 34 bytes on 64-bit machines, which
+ * gets padded to 40 bytes.
+ */
+ enum TagData_e
+ {
+ MAX_SIZE = 20 /**< Size of serialization buffer #data */
};
+ uint8_t data[MAX_SIZE]; /**< Serialization buffer */
+ struct TagData * next; /**< Pointer to next in list */
+ TypeId tid; /**< Type of the tag serialized into #data */
+ uint32_t count; /**< Number of incoming links */
+ }; /* struct TagData */
+
+ /**
+ * Create a new PacketTagList.
+ */
inline PacketTagList ();
+ /**
+ * Copy constructor
+ *
+ * \param [in] o The PacketTagList to copy.
+ *
+ * This makes a light-weight copy by #RemoveAll, then
+ * pointing to the same #struct TagData as \pname{o}.
+ */
inline PacketTagList (PacketTagList const &o);
+ /**
+ * Assignment
+ *
+ * \param [in] o The PacketTagList to copy.
+ *
+ * This makes a light-weight copy by #RemoveAll, then
+ * pointing to the same #struct TagData as \pname{o}.
+ */
inline PacketTagList &operator = (PacketTagList const &o);
+ /**
+ * Destructor
+ *
+ * #RemoveAll's the tags up to the first merge.
+ */
inline ~PacketTagList ();
+ /**
+ * Add a tag to the head of this branch.
+ *
+ * \param [in] tag The tag to add
+ */
void Add (Tag const&tag) const;
+ /**
+ * Remove (the first instance of) tag from the list.
+ *
+ * \param [in,out] tag The tag type to remove. If found,
+ * \pname{tag} is set to the value of the tag found.
+ * \returns True if \pname{tag} is found, false otherwise.
+ */
bool Remove (Tag &tag);
+ /**
+ * Replace the value of a tag.
+ *
+ * \param [in] tag The tag type to replace. To get the old
+ * value of the tag, use #Peek first.
+ * \returns True if \pname{tag} is found, false otherwise.
+ * If \pname{tag} wasn't found, Add is performed instead (so
+ * the list is guaranteed to have the new tag value either way).
+ */
+ bool Replace (Tag &tag);
+ /**
+ * Find a tag and return its value.
+ *
+ * \param [in,out] tag The tag type to find. If found,
+ * \pname{tag} is set to the value of the tag found.
+ * \returns True if \pname{tag} is found, false otherwise.
+ */
bool Peek (Tag &tag) const;
+ /**
+ * Remove all tags from this list (up to the first merge).
+ */
inline void RemoveAll (void);
-
+ /**
+ * \returns pointer to head of tag list
+ */
const struct PacketTagList::TagData *Head (void) const;
private:
+ /**
+ * Typedef of method function pointer for copy-on-write operations
+ *
+ * \param [in] tag The tag type to operate on.
+ * \param [in] preMerge True if \pname{tag} was found before the first merge,
+ * false otherwise.
+ * \param [in] cur Pointer to the tag.
+ * \param [in] prevNext Pointer to the struct TagData.next pointer
+ * pointing to \pname{cur}.
+ * \returns True if operation successful, false otherwise
+ */
+ typedef bool (PacketTagList::*COWWriter)
+ (Tag & tag, bool preMerge,
+ struct TagData * cur, struct TagData ** prevNext);
+ /**
+ * Traverse the list implementing copy-on-write, using \pname{Writer}.
+ *
+ * \param [in] tag The tag type to operate on.
+ * \param [in] Writer The copy-on-write function to use.
+ * \returns True if \pname{tag} found, false otherwise.
+ */
+ bool COWTraverse (Tag & tag, PacketTagList::COWWriter Writer);
+ /**
+ * Copy-on-write implementing Remove.
+ *
+ * \param [in] tag The target tag type to remove.
+ * \param [in] preMerge True if \pname{tag} was found before the first merge,
+ * false otherwise.
+ * \param [in] cur Pointer to the tag.
+ * \param [in] prevNext Pointer to the struct TagData.next pointer
+ * pointing to \pname{cur}.
+ * \returns True, since tag will definitely be removed.
+ */
+ bool RemoveWriter (Tag & tag, bool preMerge,
+ struct TagData * cur, struct TagData ** prevNext);
+ /**
+ * Copy-on-write implementing Replace
+ *
+ * \param [in] tag The target tag type to replace
+ * \param [in] preMerge True if \pname{tag} was found before the first merge,
+ * false otherwise.
+ * \param [in] cur Pointer to the tag
+ * \param [in] prevNext Pointer to the struct TagData.next pointer
+ * pointing to \pname{cur}.
+ * \returns True, since tag value will definitely be replaced.
+ */
+ bool ReplaceWriter (Tag & tag, bool preMerge, struct TagData * cur, struct TagData ** prevNext);
- bool Remove (TypeId tid);
- struct PacketTagList::TagData *AllocData (void) const;
- void FreeData (struct TagData *data) const;
-
- static struct PacketTagList::TagData *g_free;
- static uint32_t g_nfree;
-
+ /**
+ * Pointer to first #struct TagData on the list
+ */
struct TagData *m_next;
};
@@ -118,7 +340,7 @@
PacketTagList::RemoveAll (void)
{
struct TagData *prev = 0;
- for (struct TagData *cur = m_next; cur != 0; cur = cur->next)
+ for (struct TagData *cur = m_next; cur != 0; cur = cur->next)
{
cur->count--;
if (cur->count > 0)
@@ -127,13 +349,13 @@
}
if (prev != 0)
{
- FreeData (prev);
+ delete prev;
}
prev = cur;
}
if (prev != 0)
{
- FreeData (prev);
+ delete prev;
}
m_next = 0;
}
--- a/src/network/model/packet.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/network/model/packet.cc Tue Jun 04 17:20:40 2013 +0200
@@ -38,19 +38,16 @@
uint32_t
ByteTagIterator::Item::GetStart (void) const
{
- NS_LOG_FUNCTION (this);
return m_start;
}
uint32_t
ByteTagIterator::Item::GetEnd (void) const
{
- NS_LOG_FUNCTION (this);
return m_end;
}
void
ByteTagIterator::Item::GetTag (Tag &tag) const
{
- NS_LOG_FUNCTION (this << &tag);
if (tag.GetInstanceTypeId () != GetTypeId ())
{
NS_FATAL_ERROR ("The tag you provided is not of the right type.");
@@ -63,7 +60,6 @@
m_end (end),
m_buffer (buffer)
{
- NS_LOG_FUNCTION (this << tid << start << end << &buffer);
}
bool
ByteTagIterator::HasNext (void) const
@@ -73,7 +69,6 @@
ByteTagIterator::Item
ByteTagIterator::Next (void)
{
- NS_LOG_FUNCTION (this);
ByteTagList::Iterator::Item i = m_current.Next ();
return ByteTagIterator::Item (i.tid,
i.start-m_current.GetOffsetStart (),
@@ -83,25 +78,21 @@
ByteTagIterator::ByteTagIterator (ByteTagList::Iterator i)
: m_current (i)
{
- NS_LOG_FUNCTION (this);
}
PacketTagIterator::PacketTagIterator (const struct PacketTagList::TagData *head)
: m_current (head)
{
- NS_LOG_FUNCTION (this << head);
}
bool
PacketTagIterator::HasNext (void) const
{
- NS_LOG_FUNCTION (this);
return m_current != 0;
}
PacketTagIterator::Item
PacketTagIterator::Next (void)
{
- NS_LOG_FUNCTION (this);
NS_ASSERT (HasNext ());
const struct PacketTagList::TagData *prev = m_current;
m_current = m_current->next;
@@ -111,7 +102,6 @@
PacketTagIterator::Item::Item (const struct PacketTagList::TagData *data)
: m_data (data)
{
- NS_LOG_FUNCTION (this << data);
}
TypeId
PacketTagIterator::Item::GetTypeId (void) const
@@ -121,9 +111,10 @@
void
PacketTagIterator::Item::GetTag (Tag &tag) const
{
- NS_LOG_FUNCTION (this << &tag);
NS_ASSERT (tag.GetInstanceTypeId () == m_data->tid);
- tag.Deserialize (TagBuffer ((uint8_t*)m_data->data, (uint8_t*)m_data->data+PACKET_TAG_MAX_SIZE));
+ tag.Deserialize (TagBuffer ((uint8_t*)m_data->data,
+ (uint8_t*)m_data->data
+ + PacketTagList::TagData::MAX_SIZE));
}
@@ -133,7 +124,6 @@
// we need to invoke the copy constructor directly
// rather than calling Create because the copy constructor
// is private.
- NS_LOG_FUNCTION (this);
return Ptr<Packet> (new Packet (*this), false);
}
@@ -150,7 +140,6 @@
m_metadata (static_cast<uint64_t> (Simulator::GetSystemId ()) << 32 | m_globalUid, 0),
m_nixVector (0)
{
- NS_LOG_FUNCTION (this);
m_globalUid++;
}
@@ -193,7 +182,6 @@
m_metadata (static_cast<uint64_t> (Simulator::GetSystemId ()) << 32 | m_globalUid, size),
m_nixVector (0)
{
- NS_LOG_FUNCTION (this << size);
m_globalUid++;
}
Packet::Packet (uint8_t const *buffer, uint32_t size, bool magic)
@@ -203,7 +191,6 @@
m_metadata (0,0),
m_nixVector (0)
{
- NS_LOG_FUNCTION (this << &buffer << size << magic);
NS_ASSERT (magic);
Deserialize (buffer, size);
}
@@ -221,7 +208,6 @@
m_metadata (static_cast<uint64_t> (Simulator::GetSystemId ()) << 32 | m_globalUid, size),
m_nixVector (0)
{
- NS_LOG_FUNCTION (this << &buffer << size);
m_globalUid++;
m_buffer.AddAtStart (size);
Buffer::Iterator i = m_buffer.Begin ();
@@ -236,7 +222,6 @@
m_metadata (metadata),
m_nixVector (0)
{
- NS_LOG_FUNCTION (this << &buffer << &byteTagList << &packetTagList << &metadata);
}
Ptr<Packet>
@@ -255,14 +240,12 @@
void
Packet::SetNixVector (Ptr<NixVector> nixVector)
{
- NS_LOG_FUNCTION (this << nixVector);
m_nixVector = nixVector;
}
Ptr<NixVector>
Packet::GetNixVector (void) const
{
- NS_LOG_FUNCTION (this);
return m_nixVector;
}
@@ -270,7 +253,7 @@
Packet::AddHeader (const Header &header)
{
uint32_t size = header.GetSerializedSize ();
- NS_LOG_FUNCTION (this << &header);
+ NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << size);
uint32_t orgStart = m_buffer.GetCurrentStartOffset ();
bool resized = m_buffer.AddAtStart (size);
if (resized)
@@ -285,7 +268,7 @@
Packet::RemoveHeader (Header &header)
{
uint32_t deserialized = header.Deserialize (m_buffer.Begin ());
- NS_LOG_FUNCTION (this << &header);
+ NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << deserialized);
m_buffer.RemoveAtStart (deserialized);
m_metadata.RemoveHeader (header, deserialized);
return deserialized;
@@ -294,14 +277,14 @@
Packet::PeekHeader (Header &header) const
{
uint32_t deserialized = header.Deserialize (m_buffer.Begin ());
- NS_LOG_FUNCTION (this << &header);
+ NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << deserialized);
return deserialized;
}
void
Packet::AddTrailer (const Trailer &trailer)
{
uint32_t size = trailer.GetSerializedSize ();
- NS_LOG_FUNCTION (this << &trailer);
+ NS_LOG_FUNCTION (this << trailer.GetInstanceTypeId ().GetName () << size);
uint32_t orgStart = m_buffer.GetCurrentStartOffset ();
bool resized = m_buffer.AddAtEnd (size);
if (resized)
@@ -317,7 +300,7 @@
Packet::RemoveTrailer (Trailer &trailer)
{
uint32_t deserialized = trailer.Deserialize (m_buffer.End ());
- NS_LOG_FUNCTION (this << &trailer);
+ NS_LOG_FUNCTION (this << trailer.GetInstanceTypeId ().GetName () << deserialized);
m_buffer.RemoveAtEnd (deserialized);
m_metadata.RemoveTrailer (trailer, deserialized);
return deserialized;
@@ -326,14 +309,14 @@
Packet::PeekTrailer (Trailer &trailer)
{
uint32_t deserialized = trailer.Deserialize (m_buffer.End ());
- NS_LOG_FUNCTION (this << &trailer);
+ NS_LOG_FUNCTION (this << trailer.GetInstanceTypeId ().GetName () << deserialized);
return deserialized;
}
void
Packet::AddAtEnd (Ptr<const Packet> packet)
{
- NS_LOG_FUNCTION (this << packet);
+ NS_LOG_FUNCTION (this << packet << packet->GetSize ());
uint32_t aStart = m_buffer.GetCurrentStartOffset ();
uint32_t bEnd = packet->m_buffer.GetCurrentEndOffset ();
m_buffer.AddAtEnd (packet->m_buffer);
@@ -397,28 +380,24 @@
uint32_t
Packet::CopyData (uint8_t *buffer, uint32_t size) const
{
- NS_LOG_FUNCTION (this << &buffer << size);
return m_buffer.CopyData (buffer, size);
}
void
Packet::CopyData (std::ostream *os, uint32_t size) const
{
- NS_LOG_FUNCTION (this << &os << size);
return m_buffer.CopyData (os, size);
}
uint64_t
Packet::GetUid (void) const
{
- NS_LOG_FUNCTION (this);
return m_metadata.GetUid ();
}
void
Packet::PrintByteTags (std::ostream &os) const
{
- NS_LOG_FUNCTION (this << &os);
ByteTagIterator i = GetByteTagIterator ();
while (i.HasNext ())
{
@@ -449,7 +428,6 @@
void
Packet::Print (std::ostream &os) const
{
- NS_LOG_FUNCTION (this << &os);
PacketMetadata::ItemIterator i = m_metadata.BeginItem (m_buffer);
while (i.HasNext ())
{
@@ -567,7 +545,6 @@
PacketMetadata::ItemIterator
Packet::BeginItem (void) const
{
- NS_LOG_FUNCTION (this);
return m_metadata.BeginItem (m_buffer);
}
@@ -587,7 +564,6 @@
uint32_t Packet::GetSerializedSize (void) const
{
- NS_LOG_FUNCTION (this);
uint32_t size = 0;
if (m_nixVector)
@@ -631,7 +607,6 @@
uint32_t
Packet::Serialize (uint8_t* buffer, uint32_t maxSize) const
{
- NS_LOG_FUNCTION (this << &buffer << maxSize);
uint32_t* p = reinterpret_cast<uint32_t *> (buffer);
uint32_t size = 0;
@@ -750,7 +725,7 @@
uint32_t
Packet::Deserialize (const uint8_t* buffer, uint32_t size)
{
- NS_LOG_FUNCTION (this << &buffer << size);
+ NS_LOG_FUNCTION (this);
const uint32_t* p = reinterpret_cast<const uint32_t *> (buffer);
@@ -832,7 +807,7 @@
void
Packet::AddByteTag (const Tag &tag) const
{
- NS_LOG_FUNCTION (this << &tag);
+ NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ());
ByteTagList *list = const_cast<ByteTagList *> (&m_byteTagList);
TagBuffer buffer = list->Add (tag.GetInstanceTypeId (), tag.GetSerializedSize (),
m_buffer.GetCurrentStartOffset (),
@@ -842,14 +817,12 @@
ByteTagIterator
Packet::GetByteTagIterator (void) const
{
- NS_LOG_FUNCTION (this);
return ByteTagIterator (m_byteTagList.Begin (m_buffer.GetCurrentStartOffset (), m_buffer.GetCurrentEndOffset ()));
}
bool
Packet::FindFirstMatchingByteTag (Tag &tag) const
{
- NS_LOG_FUNCTION (this << &tag);
TypeId tid = tag.GetInstanceTypeId ();
ByteTagIterator i = GetByteTagIterator ();
while (i.HasNext ())
@@ -867,20 +840,28 @@
void
Packet::AddPacketTag (const Tag &tag) const
{
- NS_LOG_FUNCTION (this << &tag);
+ NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ());
m_packetTagList.Add (tag);
}
+
bool
Packet::RemovePacketTag (Tag &tag)
{
- NS_LOG_FUNCTION (this << &tag);
+ NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ());
bool found = m_packetTagList.Remove (tag);
return found;
}
+bool
+Packet::ReplacePacketTag (Tag &tag)
+{
+ NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ());
+ bool found = m_packetTagList.Replace (tag);
+ return found;
+}
+
bool
Packet::PeekPacketTag (Tag &tag) const
{
- NS_LOG_FUNCTION (this << &tag);
bool found = m_packetTagList.Peek (tag);
return found;
}
@@ -894,7 +875,6 @@
void
Packet::PrintPacketTags (std::ostream &os) const
{
- NS_LOG_FUNCTION (this << &os);
PacketTagIterator i = GetPacketTagIterator ();
while (i.HasNext ())
{
@@ -918,7 +898,6 @@
PacketTagIterator
Packet::GetPacketTagIterator (void) const
{
- NS_LOG_FUNCTION (this);
return PacketTagIterator (m_packetTagList.Head ());
}
--- a/src/network/model/packet.h Tue Jun 04 16:57:16 2013 +0200
+++ b/src/network/model/packet.h Tue Jun 04 17:20:40 2013 +0200
@@ -43,7 +43,7 @@
/**
* \ingroup packet
- * \brief Iterator over the set of tags in a packet
+ * \brief Iterator over the set of byte tags in a packet
*
* This is a java-style iterator.
*/
@@ -51,7 +51,7 @@
{
public:
/**
- * Identifies a tag and a set of bytes within a packet
+ * Identifies a byte tag and a set of bytes within a packet
* to which the tag applies.
*/
class Item
@@ -74,12 +74,12 @@
*/
uint32_t GetEnd (void) const;
/**
+ * Read the requested tag and store it in the user-provided tag instance.
+ *
* \param tag the user tag to which the data should be copied.
*
- * Read the requested tag and store it in the user-provided
- * tag instance. This method will crash if the type of the
- * tag provided by the user does not match the type of
- * the underlying tag.
+ * This method will crash if the type of the tag provided
+ * by the user does not match the type of the underlying tag.
*/
void GetTag (Tag &tag) const;
private:
@@ -106,7 +106,7 @@
/**
* \ingroup packet
- * \brief Iterator over the set of 'packet' tags in a packet
+ * \brief Iterator over the set of packet tags in a packet
*
* This is a java-style iterator.
*/
@@ -114,7 +114,7 @@
{
public:
/**
- * Identifies a tag within a packet.
+ * Identifies a packet tag within a packet.
*/
class Item
{
@@ -124,12 +124,12 @@
*/
TypeId GetTypeId (void) const;
/**
+ * Read the requested tag and store it in the user-provided tag instance.
+ *
* \param tag the user tag to which the data should be copied.
*
- * Read the requested tag and store it in the user-provided
- * tag instance. This method will crash if the type of the
- * tag provided by the user does not match the type of
- * the underlying tag.
+ * This method will crash if the type of the tag provided
+ * by the user does not match the type of the underlying tag.
*/
void GetTag (Tag &tag) const;
private:
@@ -197,8 +197,8 @@
* Implementing a new type of Tag requires roughly the same amount of
* work and this work is described in the ns3::Tag API documentation.
*
- * The performance aspects of the Packet API are discussed in
- * \ref packetperf
+ * The performance aspects copy-on-write semantics of the
+ * Packet API are discussed in \ref packetperf
*/
class Packet : public SimpleRefCount<Packet>
{
@@ -320,7 +320,7 @@
void AddPaddingAtEnd (uint32_t size);
/**
* Remove size bytes from the end of the current packet
- * It is safe to remove more bytes that what is present in
+ * It is safe to remove more bytes than are present in
* the packet.
*
* \param size number of bytes from remove
@@ -328,7 +328,7 @@
void RemoveAtEnd (uint32_t size);
/**
* Remove size bytes from the start of the current packet.
- * It is safe to remove more bytes that what is present in
+ * It is safe to remove more bytes than are present in
* the packet.
*
* \param size number of bytes from remove
@@ -336,18 +336,21 @@
void RemoveAtStart (uint32_t size);
/**
+ * \returns a pointer to the internal buffer of the packet.
+ *
* If you try to change the content of the buffer
* returned by this method, you will die.
* Note that this method is now deprecated and will be removed in
- * the next version of ns-3. If you need to get access to the content
- * of the byte buffer of a packet, you need to call
- * ns3::Packet::CopyData to perform an explicit copy.
+ * a future version of ns-3. To get access to the content
+ * of the byte buffer of a packet, call CopyData"()" to perform
+ * an explicit copy.
*
- * \returns a pointer to the internal buffer of the packet.
*/
uint8_t const *PeekData (void) const NS_DEPRECATED;
/**
+ * Copy the packet contents to a byte buffer.
+ *
* \param buffer a pointer to a byte buffer where the packet data
* should be copied.
* \param size the size of the byte buffer.
@@ -358,6 +361,8 @@
uint32_t CopyData (uint8_t *buffer, uint32_t size) const;
/**
+ * Copy the packet contents to an output stream.
+ *
* \param os pointer to output stream in which we want
* to write the packet data.
* \param size the maximum number of bytes we want to write
@@ -432,30 +437,29 @@
static void EnableChecking (void);
/**
- * For packet serializtion, the total size is checked
+ * \returns number of bytes required for packet
+ * serialization
+ *
+ * For packet serialization, the total size is checked
* in order to determine the size of the buffer
* required for serialization
- *
- * \returns number of bytes required for packet
- * serialization
*/
uint32_t GetSerializedSize (void) const;
- /*
+ /**
+ * Serialize a packet, tags, and metadata into a byte buffer.
+ *
* \param buffer a raw byte buffer to which the packet will be serialized
* \param maxSize the max size of the buffer for bounds checking
*
- * A packet is completely serialized and placed into the raw byte buffer
- *
- * \returns zero if buffer size was too small
+ * \returns one if all data were serialized, zero if buffer size was too small.
*/
uint32_t Serialize (uint8_t* buffer, uint32_t maxSize) const;
/**
- * \param tag the new tag to add to this packet
+ * Tag each byte included in this packet with a new byte tag.
*
- * Tag each byte included in this packet with the
- * new tag.
+ * \param tag the new tag to add to this packet
*
* Note that adding a tag is a const operation which is pretty
* un-intuitive. The rationale is that the content and behavior of
@@ -474,7 +478,7 @@
*/
ByteTagIterator GetByteTagIterator (void) const;
/**
- * \param tag the tag to search in this packet
+ * \param tag the byte tag type to search in this packet
* \returns true if the requested tag type was found, false otherwise.
*
* If the requested tag type is found, it is copied in the user's
@@ -483,44 +487,54 @@
bool FindFirstMatchingByteTag (Tag &tag) const;
/**
- * Remove all the tags stored in this packet.
+ * Remove all byte tags stored in this packet.
*/
void RemoveAllByteTags (void);
/**
* \param os output stream in which the data should be printed.
*
- * Iterate over the tags present in this packet, and
+ * Iterate over the byte tags present in this packet, and
* invoke the Print method of each tag stored in the packet.
*/
void PrintByteTags (std::ostream &os) const;
/**
- * \param tag the tag to store in this packet
+ * Add a packet tag.
*
- * Add a tag to this packet. This method calls the
- * Tag::GetSerializedSize and, then, Tag::Serialize.
+ * \param tag the packet tag type to add.
*
* Note that this method is const, that is, it does not
* modify the state of this packet, which is fairly
- * un-intuitive.
+ * un-intuitive. See AddByteTag"()" discussion.
*/
void AddPacketTag (const Tag &tag) const;
/**
- * \param tag the tag to remove from this packet
+ * Remove a packet tag.
+ *
+ * \param tag the packet tag type to remove from this packet.
+ * The tag parameter is set to the value of the tag found.
* \returns true if the requested tag is found, false
* otherwise.
- *
- * Remove a tag from this packet. This method calls
- * Tag::Deserialize if the tag is found.
*/
bool RemovePacketTag (Tag &tag);
/**
+ * Replace the value of a packet tag.
+ *
+ * \param tag the packet tag type to replace. To get the old
+ * value of the tag, use PeekPacketTag first.
+ * \returns true if the requested tag is found, false otherwise.
+ * If the tag isn't found, Add is performed instead (so
+ * the packet is guaranteed to have the new tag value
+ * either way).
+ */
+ bool ReplacePacketTag (Tag & tag);
+ /**
+ * Search a matching tag and call Tag::Deserialize if it is found.
+ *
* \param tag the tag to search in this packet
* \returns true if the requested tag is found, false
* otherwise.
- *
- * Search a matching tag and call Tag::Deserialize if it is found.
*/
bool PeekPacketTag (Tag &tag) const;
/**
@@ -529,9 +543,9 @@
void RemoveAllPacketTags (void);
/**
- * \param os the stream in which we want to print data.
+ * Print the list of packet tags.
*
- * Print the list of 'packet' tags.
+ * \param os the stream on which to print the tags.
*
* \sa Packet::AddPacketTag, Packet::RemovePacketTag, Packet::PeekPacketTag,
* Packet::RemoveAllPacketTags
@@ -544,13 +558,22 @@
*/
PacketTagIterator GetPacketTagIterator (void) const;
- /* Note: These functions support a temporary solution
+ /**
+ * Set the packet nix-vector.
+ *
+ * Note: This function supports a temporary solution
* to a specific problem in this generic class, i.e.
* how to associate something specific like nix-vector
* with a packet. This design methodology
* should _not_ be followed, and is only here as an
- * impetus to fix this general issue. */
+ * impetus to fix this general issue.
+ */
void SetNixVector (Ptr<NixVector>);
+ /**
+ * Get the packet nix-vector.
+ *
+ * See the comment on SetNixVector
+ */
Ptr<NixVector> GetNixVector (void) const;
private:
@@ -590,6 +613,7 @@
* - ns3::Packet::AddTrailer
* - both versions of ns3::Packet::AddAtEnd
* - ns3::Packet::RemovePacketTag
+ * - ns3::Packet::ReplacePacketTag
*
* Non-dirty operations:
* - ns3::Packet::AddPacketTag
@@ -614,6 +638,10 @@
} // namespace ns3
+/****************************************************
+ * Implementation of inline methods for performance
+ ****************************************************/
+
namespace ns3 {
uint32_t
--- a/src/network/model/tag.h Tue Jun 04 16:57:16 2013 +0200
+++ b/src/network/model/tag.h Tue Jun 04 17:20:40 2013 +0200
@@ -31,7 +31,7 @@
*
* \brief tag a set of bytes in a packet
*
- * New kinds of tags can be created by subclassing this base class.
+ * New kinds of tags can be created by subclassing from this abstract base class.
*/
class Tag : public ObjectBase
{
--- a/src/network/test/packet-test-suite.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/network/test/packet-test-suite.cc Tue Jun 04 17:20:40 2013 +0200
@@ -18,9 +18,15 @@
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "ns3/packet.h"
+#include "ns3/packet-tag-list.h"
#include "ns3/test.h"
+#include "ns3/unused.h"
+#include <limits> // std:numeric_limits
#include <string>
#include <cstdarg>
+#include <iostream>
+#include <iomanip>
+#include <ctime>
using namespace ns3;
@@ -32,8 +38,14 @@
class ATestTagBase : public Tag
{
public:
- ATestTagBase () : m_error (false) {}
+ ATestTagBase () : m_error (false), m_data (0) {}
+ ATestTagBase (uint8_t data) : m_error (false), m_data (data) {}
+ virtual int GetData () const {
+ int result = (int)m_data;
+ return result;
+ }
bool m_error;
+ uint8_t m_data;
};
template <int N>
@@ -54,15 +66,17 @@
return GetTypeId ();
}
virtual uint32_t GetSerializedSize (void) const {
- return N;
+ return N + sizeof(m_data);
}
virtual void Serialize (TagBuffer buf) const {
+ buf.WriteU8 (m_data);
for (uint32_t i = 0; i < N; ++i)
{
buf.WriteU8 (N);
}
}
virtual void Deserialize (TagBuffer buf) {
+ m_data = buf.ReadU8 ();
for (uint32_t i = 0; i < N; ++i)
{
uint8_t v = buf.ReadU8 ();
@@ -73,10 +87,12 @@
}
}
virtual void Print (std::ostream &os) const {
- os << N;
+ os << N << "(" << m_data << ")";
}
ATestTag ()
: ATestTagBase () {}
+ ATestTag (uint8_t data)
+ : ATestTagBase (data) {}
};
class ATestHeaderBase : public Header
@@ -435,6 +451,270 @@
#endif
}
}
+//--------------------------------------
+class PacketTagListTest : public TestCase
+{
+public:
+ PacketTagListTest ();
+ virtual ~PacketTagListTest ();
+private:
+ void DoRun (void);
+ void CheckRef (const PacketTagList & ref,
+ ATestTagBase & t,
+ const char * msg,
+ bool miss = false);
+ void CheckRefList (const PacketTagList & ref,
+ const char * msg,
+ int miss = 0);
+ int RemoveTime (const PacketTagList & ref,
+ ATestTagBase & t,
+ const char * msg = 0);
+ int AddRemoveTime (const bool verbose = false);
+};
+
+PacketTagListTest::PacketTagListTest ()
+ : TestCase ("PacketTagListTest: ")
+{
+}
+
+PacketTagListTest::~PacketTagListTest ()
+{
+}
+
+void
+PacketTagListTest::CheckRef (const PacketTagList & ref,
+ ATestTagBase & t,
+ const char * msg,
+ bool miss)
+{
+ int expect = t.GetData (); // the value we should find
+ bool found = ref.Peek (t); // rewrites t with actual value
+ NS_TEST_EXPECT_MSG_EQ (found, !miss,
+ msg << ": ref contains "
+ << t.GetTypeId ().GetName ());
+ if (found) {
+ NS_TEST_EXPECT_MSG_EQ (t.GetData (), expect,
+ msg << ": ref " << t.GetTypeId ().GetName ()
+ << " = " << expect);
+ }
+}
+
+ // A set of tags with data value 1, to check COW
+#define MAKE_TEST_TAGS \
+ ATestTag<1> t1 (1); \
+ ATestTag<2> t2 (1); \
+ ATestTag<3> t3 (1); \
+ ATestTag<4> t4 (1); \
+ ATestTag<5> t5 (1); \
+ ATestTag<6> t6 (1); \
+ ATestTag<7> t7 (1); \
+ const int tagLast = 7; /* length of ref PacketTagList */ \
+ NS_UNUSED (tagLast) /* silence warnings */
+
+
+
+void
+PacketTagListTest::CheckRefList (const PacketTagList & ptl,
+ const char * msg,
+ int miss /* = 0 */)
+{
+ MAKE_TEST_TAGS ;
+ CheckRef (ptl, t1, msg, miss == 1);
+ CheckRef (ptl, t2, msg, miss == 2);
+ CheckRef (ptl, t3, msg, miss == 3);
+ CheckRef (ptl, t4, msg, miss == 4);
+ CheckRef (ptl, t5, msg, miss == 5);
+ CheckRef (ptl, t6, msg, miss == 6);
+ CheckRef (ptl, t7, msg, miss == 7);
+}
+
+int
+PacketTagListTest::RemoveTime (const PacketTagList & ref,
+ ATestTagBase & t,
+ const char * msg /* = 0 */)
+{
+ const int reps = 10000;
+ std::vector< PacketTagList > ptv(reps, ref);
+ int start = clock ();
+ for (int i = 0; i < reps; ++i) {
+ ptv[i].Remove (t);
+ }
+ int stop = clock ();
+ int delta = stop - start;
+ if (msg) {
+ std::cout << GetName () << "remove time: " << msg << ": " << std::setw (8)
+ << delta << " ticks to remove "
+ << reps << " times"
+ << std::endl;
+ }
+ return delta;
+}
+
+int
+PacketTagListTest::AddRemoveTime (const bool verbose /* = false */)
+{
+ const int reps = 100000;
+ PacketTagList ptl;
+ ATestTag <2> t(2);
+ int start = clock ();
+ for (int i = 0; i < reps; ++i) {
+ ptl.Add (t);
+ ptl.Remove (t);
+ }
+ int stop = clock ();
+ int delta = stop - start;
+ if (verbose) {
+ std::cout << GetName () << "add/remove time: " << std::setw (8)
+ << delta << " ticks to add+remove "
+ << reps << " times"
+ << std::endl;
+ }
+ return delta;
+}
+
+void
+PacketTagListTest::DoRun (void)
+{
+ std::cout << GetName () << "begin" << std::endl;
+
+ MAKE_TEST_TAGS ;
+
+ PacketTagList ref; // empty list
+ ref.Add (t1); // last
+ ref.Add (t2); // post merge
+ ref.Add (t3); // merge successor
+ ref.Add (t4); // merge
+ ref.Add (t5); // merge precursor
+ ref.Add (t6); // pre-merge
+ ref.Add (t7); // first
+
+ { // Peek
+ std::cout << GetName () << "check Peek (missing tag) returns false"
+ << std::endl;;
+ ATestTag<10> t10;
+ NS_TEST_EXPECT_MSG_EQ (ref.Peek (t10), false, "missing tag");
+ }
+
+ { // Copy ctor, assignment
+ std::cout << GetName () << "check copy and assignment" << std::endl;
+ { PacketTagList ptl (ref);
+ CheckRefList (ref, "copy ctor orig");
+ CheckRefList (ptl, "copy ctor copy");
+ }
+ { PacketTagList ptl = ref;
+ CheckRefList (ref, "assignment orig");
+ CheckRefList (ptl, "assignment copy");
+ }
+ }
+
+ { // Removal
+# define RemoveCheck(n) \
+ { PacketTagList p ## n = ref; \
+ p ## n .Remove ( t ## n ); \
+ CheckRefList (ref, "remove " #n " orig"); \
+ CheckRefList (p ## n, "remove " #n " copy", n); \
+ }
+
+ { // Remove single tags from list
+ std::cout << GetName () << "check removal of each tag" << std::endl;
+ RemoveCheck (1);
+ RemoveCheck (2);
+ RemoveCheck (3);
+ RemoveCheck (4);
+ RemoveCheck (5);
+ RemoveCheck (6);
+ RemoveCheck (7);
+ }
+
+ { // Remove in the presence of a merge
+ std::cout << GetName () << "check removal doesn't disturb merge "
+ << std::endl;
+ PacketTagList ptl = ref;
+ ptl.Remove (t7);
+ ptl.Remove (t6);
+ ptl.Remove (t5);
+
+ PacketTagList mrg = ptl; // merged list
+ ATestTag<8> m5 (1);
+ mrg.Add (m5); // ptl and mrg differ
+ ptl.Add (t5);
+ ptl.Add (t6);
+ ptl.Add (t7);
+
+ CheckRefList (ref, "post merge, orig");
+ CheckRefList (ptl, "post merge, long chain");
+ const char * msg = "post merge, short chain";
+ CheckRef (mrg, t1, msg, false);
+ CheckRef (mrg, t2, msg, false);
+ CheckRef (mrg, t3, msg, false);
+ CheckRef (mrg, t4, msg, false);
+ CheckRef (mrg, m5, msg, false);
+ }
+# undef RemoveCheck
+ } // Removal
+
+ { // Replace
+
+ std::cout << GetName () << "check replacing each tag" << std::endl;
+
+# define ReplaceCheck(n) \
+ t ## n .m_data = 2; \
+ { PacketTagList p ## n = ref; \
+ p ## n .Replace ( t ## n ); \
+ CheckRefList (ref, "replace " #n " orig"); \
+ CheckRef (p ## n, t ## n, "replace " #n " copy"); \
+ }
+
+ ReplaceCheck (1);
+ ReplaceCheck (2);
+ ReplaceCheck (3);
+ ReplaceCheck (4);
+ ReplaceCheck (5);
+ ReplaceCheck (6);
+ ReplaceCheck (7);
+ }
+
+ { // Timing
+ std::cout << GetName () << "add+remove timing" << std::endl;
+ int flm = std::numeric_limits<int>::max ();
+ const int nIterations = 100;
+ for (int i = 0; i < nIterations; ++i) {
+ int now = AddRemoveTime ();
+ if (now < flm) flm = now;
+ }
+ std::cout << GetName () << "min add+remove time: "
+ << std::setw (8) << flm << " ticks"
+ << std::endl;
+
+ std::cout << GetName () << "remove timing" << std::endl;
+ // tags numbered from 1, so add one for (unused) entry at 0
+ std::vector <int> rmn (tagLast + 1, std::numeric_limits<int>::max ());
+ for (int i = 0; i < nIterations; ++i) {
+ for (int j = 1; j <= tagLast; ++j) {
+ int now = 0;
+ switch (j) {
+ case 7: now = RemoveTime (ref, t7); break;
+ case 6: now = RemoveTime (ref, t6); break;
+ case 5: now = RemoveTime (ref, t5); break;
+ case 4: now = RemoveTime (ref, t4); break;
+ case 3: now = RemoveTime (ref, t3); break;
+ case 2: now = RemoveTime (ref, t2); break;
+ case 1: now = RemoveTime (ref, t1); break;
+ } // switch
+
+ if (now < rmn[j]) rmn[j] = now;
+ } // for tag j
+ } // for iteration i
+ for (int j = tagLast; j > 0; --j) {
+ std::cout << GetName () << "min remove time: t"
+ << j << ": "
+ << std::setw (8) << rmn[j] << " ticks"
+ << std::endl;
+ }
+ } // Timing
+
+}
+
//-----------------------------------------------------------------------------
class PacketTestSuite : public TestSuite
{
@@ -446,6 +726,7 @@
: TestSuite ("packet", UNIT)
{
AddTestCase (new PacketTest, TestCase::QUICK);
+ AddTestCase (new PacketTagListTest, TestCase::QUICK);
}
static PacketTestSuite g_packetTestSuite;
--- a/src/network/test/pcap-file-test-suite.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/network/test/pcap-file-test-suite.cc Tue Jun 04 17:20:40 2013 +0200
@@ -22,11 +22,14 @@
#include <sstream>
#include <cstring>
+#include "ns3/log.h"
#include "ns3/test.h"
#include "ns3/pcap-file.h"
using namespace ns3;
+NS_LOG_COMPONENT_DEFINE ("pcap-file-test-suite");
+
// ===========================================================================
// Some utility functions for the tests.
// ===========================================================================
@@ -113,7 +116,10 @@
void
WriteModeCreateTestCase::DoTeardown (void)
{
- remove (m_testFilename.c_str ());
+ if (remove (m_testFilename.c_str ()))
+ {
+ NS_LOG_ERROR ("Failed to delete file " << m_testFilename);
+ }
}
void
@@ -225,7 +231,10 @@
void
ReadModeCreateTestCase::DoTeardown (void)
{
- remove (m_testFilename.c_str ());
+ if (remove (m_testFilename.c_str ()))
+ {
+ NS_LOG_ERROR ("Failed to delete file " << m_testFilename);
+ }
}
void
@@ -331,7 +340,10 @@
void
AppendModeCreateTestCase::DoTeardown (void)
{
- remove (m_testFilename.c_str ());
+ if (remove (m_testFilename.c_str ()))
+ {
+ NS_LOG_ERROR ("Failed to delete file " << m_testFilename);
+ }
}
void
@@ -437,7 +449,10 @@
void
FileHeaderTestCase::DoTeardown (void)
{
- remove (m_testFilename.c_str ());
+ if (remove (m_testFilename.c_str ()))
+ {
+ NS_LOG_ERROR ("Failed to delete file " << m_testFilename);
+ }
}
void
@@ -674,7 +689,10 @@
void
RecordHeaderTestCase::DoTeardown (void)
{
- remove (m_testFilename.c_str ());
+ if (remove (m_testFilename.c_str ()))
+ {
+ NS_LOG_ERROR ("Failed to delete file " << m_testFilename);
+ }
}
void
@@ -876,7 +894,8 @@
// starting there in the file. We've tested this all before so we just assume
// it's all right and just seek past it.
//
- std::fseek (p, 24, SEEK_SET);
+ result = std::fseek (p, 24, SEEK_SET);
+ NS_TEST_ASSERT_MSG_EQ (result, 0, "Failed seeking past pcap header");
result = std::fread (&val32, sizeof(val32), 1, p);
NS_TEST_ASSERT_MSG_EQ (result, 1, "Unable to fread() seconds timestamp");
--- a/src/network/utils/mac48-address.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/network/utils/mac48-address.cc Tue Jun 04 17:20:40 2013 +0200
@@ -265,7 +265,7 @@
NS_LOG_FUNCTION (v);
std::istringstream iss;
iss.str (v);
- uint32_t retval;
+ uint8_t retval;
iss >> std::hex >> retval >> std::dec;
return retval;
}
--- a/src/network/utils/packet-socket.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/network/utils/packet-socket.cc Tue Jun 04 17:20:40 2013 +0200
@@ -617,19 +617,20 @@
uint32_t
DeviceNameTag::GetSerializedSize (void) const
{
- uint32_t s = 1 + m_deviceName.size();
- return ( s >= PACKET_TAG_MAX_SIZE)?PACKET_TAG_MAX_SIZE:s;
+ uint32_t s = 1 + m_deviceName.size(); // +1 for name length field
+ s = std::min (s, (uint32_t)PacketTagList::TagData::MAX_SIZE);
+ return s;
}
void
DeviceNameTag::Serialize (TagBuffer i) const
{
const char *n = m_deviceName.c_str();
- uint8_t l = (uint8_t) strlen (n);
+ uint8_t l = (uint8_t) m_deviceName.size ();
- if ( ( 1 + l ) > PACKET_TAG_MAX_SIZE ) l = PACKET_TAG_MAX_SIZE - 1;
+ l = std::min ((uint32_t)l, (uint32_t)PacketTagList::TagData::MAX_SIZE - 1);
i.WriteU8 (l);
- i.Write ( (uint8_t*) n , (uint32_t) l );
+ i.Write ( (uint8_t*) n , (uint32_t) l);
}
void
DeviceNameTag::Deserialize (TagBuffer i)
--- a/src/olsr/model/olsr-routing-protocol.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/olsr/model/olsr-routing-protocol.cc Tue Jun 04 17:20:40 2013 +0200
@@ -2033,7 +2033,9 @@
case OLSR_ASYM_LINK: linkTypeName = "ASYM_LINK"; break;
case OLSR_SYM_LINK: linkTypeName = "SYM_LINK"; break;
case OLSR_LOST_LINK: linkTypeName = "LOST_LINK"; break;
+ /* no default, since lt must be in 0..3, covered above
default: linkTypeName = "(invalid value!)";
+ */
}
const char *neighborTypeName;
@@ -2104,7 +2106,7 @@
}
// Schedules link tuple deletion
- if (created && link_tuple != NULL)
+ if (created)
{
LinkTupleAdded (*link_tuple, hello.willingness);
m_events.Track (Simulator::Schedule (DELAY (std::min (link_tuple->time, link_tuple->symTime)),
--- a/src/spectrum/test/spectrum-ideal-phy-test.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/spectrum/test/spectrum-ideal-phy-test.cc Tue Jun 04 17:20:40 2013 +0200
@@ -202,7 +202,8 @@
{
NS_TEST_ASSERT_MSG_EQ (throughputBps, 0.0, "PHY rate is not achievable but throughput is non-zero");
}
-
+
+ std::clog.unsetf(std::ios_base::floatfield);
Simulator::Destroy ();
}
--- a/src/stats/test/basic-data-calculators-test-suite.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/stats/test/basic-data-calculators-test-suite.cc Tue Jun 04 17:20:40 2013 +0200
@@ -83,14 +83,7 @@
min = multiple;
max = multiple * count;
mean = sum / count;
- if (count == 1)
- {
- variance = 0;
- }
- else
- {
- variance = (count * sqrSum - sum * sum) / (count * (count - 1));
- }
+ variance = 0;
stddev = std::sqrt (variance);
// Test the calculator.
@@ -161,14 +154,7 @@
min = multiple;
max = multiple * count;
mean = sum / count;
- if (count == 1)
- {
- variance = 0;
- }
- else
- {
- variance = (count * sqrSum - sum * sum) / (count * (count - 1));
- }
+ variance = (count * sqrSum - sum * sum) / (count * (count - 1));
stddev = std::sqrt (variance);
// Test the calculator.
@@ -239,14 +225,7 @@
min = multiple;
max = multiple * count;
mean = sum / count;
- if (count == 1)
- {
- variance = 0;
- }
- else
- {
- variance = (count * sqrSum - sum * sum) / (count * (count - 1));
- }
+ variance = (count * sqrSum - sum * sum) / (count * (count - 1));
stddev = std::sqrt (variance);
// Test the calculator.
--- a/src/tools/test/average-test-suite.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/tools/test/average-test-suite.cc Tue Jun 04 17:20:40 2013 +0200
@@ -83,14 +83,7 @@
min = multiple;
max = multiple * count;
mean = sum / count;
- if (count == 1)
- {
- variance = 0;
- }
- else
- {
- variance = (count * sqrSum - sum * sum) / (count * (count - 1));
- }
+ variance = 0;
stddev = std::sqrt (variance);
// Test the calculator.
@@ -159,14 +152,7 @@
min = multiple;
max = multiple * count;
mean = sum / count;
- if (count == 1)
- {
- variance = 0;
- }
- else
- {
- variance = (count * sqrSum - sum * sum) / (count * (count - 1));
- }
+ variance = (count * sqrSum - sum * sum) / (count * (count - 1));
stddev = std::sqrt (variance);
// Test the calculator.
@@ -235,14 +221,7 @@
min = multiple;
max = multiple * count;
mean = sum / count;
- if (count == 1)
- {
- variance = 0;
- }
- else
- {
- variance = (count * sqrSum - sum * sum) / (count * (count - 1));
- }
+ variance = (count * sqrSum - sum * sum) / (count * (count - 1));
stddev = std::sqrt (variance);
// Test the calculator.
--- a/src/topology-read/model/inet-topology-reader.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/topology-read/model/inet-topology-reader.cc Tue Jun 04 17:20:40 2013 +0200
@@ -86,7 +86,7 @@
lineBuffer >> totlink;
NS_LOG_INFO ("Inet topology should have " << totnode << " nodes and " << totlink << " links");
- for (int i = 0; i < totnode; i++)
+ for (int i = 0; i < totnode && !topgen.eof (); i++)
{
getline (topgen,line);
}
--- a/src/uan/model/uan-mac-cw.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/uan/model/uan-mac-cw.cc Tue Jun 04 17:20:40 2013 +0200
@@ -123,7 +123,7 @@
{
case CCABUSY:
NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " MAC " << GetAddress () << " Starting enqueue CCABUSY");
- if (m_txEndEvent.IsRunning () == TX)
+ if (m_txEndEvent.IsRunning ())
{
NS_LOG_DEBUG ("State is TX");
}
--- a/src/uan/model/uan-mac-rc-gw.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/uan/model/uan-mac-rc-gw.cc Tue Jun 04 17:20:40 2013 +0200
@@ -32,6 +32,7 @@
#include "ns3/double.h"
#include "ns3/uinteger.h"
+#include <cfloat>
#include <utility>
#include <set>
#include <map>
@@ -654,7 +655,8 @@
double sum = 0;
for (uint32_t i = 1; i <= n - k + 1; i++)
{
- double p = (double) NchooseK (n - i, k - 1) / NchooseK (n, k);
+ double nChK = NchooseK (n, k);
+ double p = (nChK > 0) ? (NchooseK (n - i, k - 1) / nChK) : DBL_MAX;
sum += p * i;
}
return (uint32_t)(sum + 0.5);
--- a/src/uan/model/uan-prop-model.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/uan/model/uan-prop-model.cc Tue Jun 04 17:20:40 2013 +0200
@@ -64,7 +64,7 @@
std::complex<double> amp;
pdp.m_taps = std::vector<Tap> (ntaps);
- for (uint32_t i = 0; i < ntaps; i++)
+ for (uint32_t i = 0; i < ntaps && !is.eof (); i++)
{
is >> amp >> c1;
if (c1 != '|')
--- a/src/uan/model/uan-tx-mode.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/uan/model/uan-tx-mode.cc Tue Jun 04 17:20:40 2013 +0200
@@ -288,7 +288,7 @@
ml.m_modes.clear ();
ml.m_modes.resize (numModes);
- for (int i = 0; i < numModes; i++)
+ for (int i = 0; i < numModes && !is.eof (); i++)
{
is >> ml.m_modes[i] >> c;
if (c != '|')
--- a/src/wifi/examples/wifi-phy-test.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/wifi/examples/wifi-phy-test.cc Tue Jun 04 17:20:40 2013 +0200
@@ -188,14 +188,16 @@
CollisionExperiment::Receive (Ptr<Packet> p, double snr, WifiMode mode, enum WifiPreamble preamble)
{
FlowIdTag tag;
- p->FindFirstMatchingByteTag (tag);
- if (tag.GetFlowId () == m_flowIdA)
+ if (p->FindFirstMatchingByteTag (tag))
{
- m_output.receivedA++;
- }
- else if (tag.GetFlowId () == m_flowIdB)
- {
- m_output.receivedB++;
+ if (tag.GetFlowId () == m_flowIdA)
+ {
+ m_output.receivedA++;
+ }
+ else if (tag.GetFlowId () == m_flowIdB)
+ {
+ m_output.receivedB++;
+ }
}
}
--- a/src/wifi/model/ctrl-headers.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/wifi/model/ctrl-headers.cc Tue Jun 04 17:20:40 2013 +0200
@@ -67,7 +67,7 @@
CtrlBAckRequestHeader::Print (std::ostream &os) const
{
NS_LOG_FUNCTION (this << &os);
- os << "TID_INFO=" << m_tidInfo << ", StartingSeq=" << std::hex << m_startingSeq;
+ os << "TID_INFO=" << m_tidInfo << ", StartingSeq=" << std::hex << m_startingSeq << std::dec;
}
uint32_t
--- a/src/wifi/model/mgt-headers.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/wifi/model/mgt-headers.cc Tue Jun 04 17:20:40 2013 +0200
@@ -484,42 +484,46 @@
{
case BLOCK_ACK_ADDBA_REQUEST:
retval.blockAck = BLOCK_ACK_ADDBA_REQUEST;
- return retval;
+ break ;
case BLOCK_ACK_ADDBA_RESPONSE:
retval.blockAck = BLOCK_ACK_ADDBA_RESPONSE;
- return retval;
+ break ;
case BLOCK_ACK_DELBA:
retval.blockAck = BLOCK_ACK_DELBA;
- return retval;
+ break ;
}
+ break ;
+
case MESH_PEERING_MGT:
switch (m_actionValue)
{
case PEER_LINK_OPEN:
retval.peerLink = PEER_LINK_OPEN;
- return retval;
+ break ;
case PEER_LINK_CONFIRM:
retval.peerLink = PEER_LINK_CONFIRM;
- return retval;
+ break ;
case PEER_LINK_CLOSE:
retval.peerLink = PEER_LINK_CLOSE;
- return retval;
+ break ;
default:
NS_FATAL_ERROR ("Unknown mesh peering management action code");
retval.peerLink = PEER_LINK_OPEN; /* quiet compiler */
- return retval;
}
+ break ;
+
case MESH_PATH_SELECTION:
switch (m_actionValue)
{
case PATH_SELECTION:
retval.pathSelection = PATH_SELECTION;
- return retval;
+ break ;
default:
NS_FATAL_ERROR ("Unknown mesh path selection action code");
retval.peerLink = PEER_LINK_OPEN; /* quiet compiler */
- return retval;
}
+ break ;
+
case MESH_LINK_METRIC:
// not yet supported
case MESH_INTERWORKING:
@@ -529,8 +533,8 @@
default:
NS_FATAL_ERROR ("Unsupported mesh action");
retval.peerLink = PEER_LINK_OPEN; /* quiet compiler */
- return retval;
}
+ return retval;
}
TypeId
WifiActionHeader::GetTypeId ()
--- a/src/wifi/model/regular-wifi-mac.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/wifi/model/regular-wifi-mac.cc Tue Jun 04 17:20:40 2013 +0200
@@ -512,10 +512,13 @@
default:
NS_FATAL_ERROR ("Unsupported Action field in Block Ack Action frame");
+ return;
}
+
default:
NS_FATAL_ERROR ("Unsupported Action frame received");
+ return;
}
}
NS_FATAL_ERROR ("Don't know how to handle frame (type=" << hdr->GetType ());
--- a/src/wifi/model/wifi-information-element-vector.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/wifi/model/wifi-information-element-vector.cc Tue Jun 04 17:20:40 2013 +0200
@@ -82,7 +82,9 @@
{
Buffer::Iterator i = start;
uint8_t id = i.ReadU8 ();
- uint8_t length = i.ReadU8 ();
+ //unused: uint8_t length = i.ReadU8 ();
+ //but need side effects of read:
+ i.ReadU8 ();
Ptr<WifiInformationElement> newElement;
switch (id)
{
@@ -90,6 +92,7 @@
NS_FATAL_ERROR ("Information element " << (uint16_t) id << " is not implemented");
return 0;
}
+ /* unreachable: b/c switch is guaranteed to return from this function
if (GetSize () + length > m_maxSize)
{
NS_FATAL_ERROR ("Check max size for information element!");
@@ -98,6 +101,7 @@
i.Next (length);
m_elements.push_back (newElement);
return i.GetDistanceFrom (start);
+ */
}
void
WifiInformationElementVector::Print (std::ostream & os) const
--- a/src/wifi/model/wifi-mac-header.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/wifi/model/wifi-mac-header.cc Tue Jun 04 17:20:40 2013 +0200
@@ -221,12 +221,15 @@
case WIFI_MAC_MGT_DEAUTHENTICATION:
m_ctrlType = TYPE_MGT;
m_ctrlSubtype = 12;
+ break;
case WIFI_MAC_MGT_ACTION:
m_ctrlType = TYPE_MGT;
m_ctrlSubtype = 13;
+ break;
case WIFI_MAC_MGT_ACTION_NO_ACK:
m_ctrlType = TYPE_MGT;
m_ctrlSubtype = 14;
+ break;
case WIFI_MAC_MGT_MULTIHOP_ACTION:
m_ctrlType = TYPE_MGT;
m_ctrlSubtype = 15;
@@ -998,10 +1001,12 @@
os << " Duration/ID=" << m_duration << "us"
<< "DA=" << m_addr1 << ", SA=" << m_addr2 << ", BSSID=" << m_addr3
<< ", FragNumber=" << std::hex << (int) m_seqFrag << std::dec << ", SeqNumber=" << m_seqSeq;
+ break;
case WIFI_MAC_MGT_MULTIHOP_ACTION:
os << " Duration/ID=" << m_duration << "us"
<< "RA=" << m_addr1 << ", TA=" << m_addr2 << ", DA=" << m_addr3
<< ", FragNumber=" << std::hex << (int) m_seqFrag << std::dec << ", SeqNumber=" << m_seqSeq;
+ break;
case WIFI_MAC_DATA:
PrintFrameControl (os);
os << " Duration/ID=" << m_duration << "us";
--- a/src/wifi/model/yans-wifi-phy.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/wifi/model/yans-wifi-phy.cc Tue Jun 04 17:20:40 2013 +0200
@@ -109,12 +109,12 @@
MakePointerAccessor (&YansWifiPhy::m_state),
MakePointerChecker<WifiPhyStateHelper> ())
.AddAttribute ("ChannelSwitchDelay",
- "Delay between two short frames transmitted on different frequencies. NOTE: Unused now.",
+ "Delay between two short frames transmitted on different frequencies.",
TimeValue (MicroSeconds (250)),
MakeTimeAccessor (&YansWifiPhy::m_channelSwitchDelay),
MakeTimeChecker ())
.AddAttribute ("ChannelNumber",
- "Channel center frequency = Channel starting frequency + 5 MHz * (nch - 1)",
+ "Channel center frequency = Channel starting frequency + 5 MHz * nch",
UintegerValue (1),
MakeUintegerAccessor (&YansWifiPhy::SetChannelNumber,
&YansWifiPhy::GetChannelNumber),
--- a/src/wifi/model/yans-wifi-phy.h Tue Jun 04 16:57:16 2013 +0200
+++ b/src/wifi/model/yans-wifi-phy.h Tue Jun 04 17:20:40 2013 +0200
@@ -71,7 +71,7 @@
/**
* \brief Set channel number.
*
- * Channel center frequency = Channel starting frequency + 5 MHz * (nch - 1)
+ * Channel center frequency = Channel starting frequency + 5 MHz * nch
*
* where Starting channel frequency is standard-dependent, see SetStandard()
* as defined in IEEE 802.11-2007 17.3.8.3.2.
--- a/src/wimax/model/bs-scheduler-simple.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/wimax/model/bs-scheduler-simple.cc Tue Jun 04 17:20:40 2013 +0200
@@ -297,7 +297,7 @@
serviceFlows = GetBs ()->GetServiceFlowManager ()->GetServiceFlows (ServiceFlow::SF_TYPE_NRTPS);
for (iter2 = serviceFlows.begin (); iter2 != serviceFlows.end (); ++iter2)
{
- serviceFlowRecord = (*iter2)->GetRecord ();
+ //unused: serviceFlowRecord = (*iter2)->GetRecord ();
if ((*iter2)->HasPackets ())
{
NS_LOG_INFO ("Return NRTPS SF: CID = " << (*iter2)->GetCid () << "SFID = " << (*iter2)->GetSfid ());
@@ -309,7 +309,7 @@
serviceFlows = GetBs ()->GetServiceFlowManager ()->GetServiceFlows (ServiceFlow::SF_TYPE_BE);
for (iter2 = serviceFlows.begin (); iter2 != serviceFlows.end (); ++iter2)
{
- serviceFlowRecord = (*iter2)->GetRecord ();
+ //unused: serviceFlowRecord = (*iter2)->GetRecord ();
if ((*iter2)->HasPackets ())
{
NS_LOG_INFO ("Return BE SF: CID = " << (*iter2)->GetCid () << "SFID = " << (*iter2)->GetSfid ());
--- a/src/wimax/model/simple-ofdm-wimax-phy.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/wimax/model/simple-ofdm-wimax-phy.cc Tue Jun 04 17:20:40 2013 +0200
@@ -241,6 +241,7 @@
SimpleOfdmWimaxPhy::Send (SendParams *params)
{
OfdmSendParams *o_params = dynamic_cast<OfdmSendParams*> (params);
+ NS_ASSERT (o_params !=0);
Send (o_params->GetBurst (),
(WimaxPhy::ModulationType) o_params->GetModulationType (),
o_params->GetDirection ());
@@ -284,6 +285,7 @@
}
SimpleOfdmWimaxChannel *channel = dynamic_cast<SimpleOfdmWimaxChannel*> (PeekPointer (GetChannel ()));
+ NS_ASSERT (channel != 0);
if (m_nrRemainingBlocksToSend==1)
{
@@ -585,7 +587,7 @@
SimpleOfdmWimaxPhy::RecreateBuffer ()
{
- bvec buffer (m_blockSize * m_nrBlocks);
+ bvec buffer (m_blockSize * (unsigned long)m_nrBlocks);
bvec block (m_blockSize);
uint32_t i = 0;
for (uint32_t j = 0; j < m_nrBlocks; j++)
@@ -820,51 +822,51 @@
{
uint16_t duration = 0;
duration = (uint16_t)(GetFrameDuration ().GetSeconds () * 10000);
+ uint8_t retval = 0;
switch (duration)
{
case 25:
{
- return FRAME_DURATION_2_POINT_5_MS;
+ retval = FRAME_DURATION_2_POINT_5_MS;
break;
}
case 40:
{
- return FRAME_DURATION_4_MS;
+ retval = FRAME_DURATION_4_MS;
break;
}
case 50:
{
- return FRAME_DURATION_5_MS;
+ retval = FRAME_DURATION_5_MS;
break;
}
case 80:
{
- return FRAME_DURATION_8_MS;
+ retval = FRAME_DURATION_8_MS;
break;
}
case 100:
{
- return FRAME_DURATION_10_MS;
+ retval = FRAME_DURATION_10_MS;
break;
}
case 125:
{
- return FRAME_DURATION_12_POINT_5_MS;
+ retval = FRAME_DURATION_12_POINT_5_MS;
break;
}
case 200:
{
- return FRAME_DURATION_20_MS;
+ retval = FRAME_DURATION_20_MS;
break;
}
default:
{
NS_FATAL_ERROR ("Invalid frame duration = " << duration);
- return 0;
+ retval = 0;
}
}
- NS_FATAL_ERROR ("Invalid frame duration = " << duration);
- return 0;
+ return retval;
}
Time
--- a/src/wimax/model/snr-to-block-error-rate-manager.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/wimax/model/snr-to-block-error-rate-manager.cc Tue Jun 04 17:20:40 2013 +0200
@@ -24,6 +24,7 @@
#include "ns3/snr-to-block-error-rate-record.h"
#include "default-traces.h"
#include "ns3/log.h"
+#include "ns3/assert.h"
#include <fstream>
NS_LOG_COMPONENT_DEFINE ("SNRToBlockErrorRateManager");
@@ -273,6 +274,8 @@
void
SNRToBlockErrorRateManager::SetTraceFilePath (char *traceFilePath)
{
+ NS_ASSERT_MSG (std::strlen (traceFilePath) < TRACE_FILE_PATH_SIZE,
+ "char * traceFilePath too long");
std::strcpy (m_traceFilePath, traceFilePath);
}
--- a/src/wimax/model/snr-to-block-error-rate-manager.h Tue Jun 04 16:57:16 2013 +0200
+++ b/src/wimax/model/snr-to-block-error-rate-manager.h Tue Jun 04 17:20:40 2013 +0200
@@ -94,7 +94,8 @@
void ClearRecords (void);
double m_speed; // in m/s
uint8_t m_activateLoss;
- char m_traceFilePath[1024];
+ static const unsigned int TRACE_FILE_PATH_SIZE = 1024;
+ char m_traceFilePath[TRACE_FILE_PATH_SIZE];
std::vector<SNRToBlockErrorRateRecord *> * m_recordModulation[7];
--- a/src/wimax/model/wimax-tlv.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/src/wimax/model/wimax-tlv.cc Tue Jun 04 17:20:40 2013 +0200
@@ -940,9 +940,9 @@
}
ProtocolTlvValue::~ProtocolTlvValue ()
{
- m_protocol->clear ();
if (m_protocol != 0)
{
+ m_protocol->clear ();
delete m_protocol;
m_protocol = 0;
}
@@ -1013,9 +1013,9 @@
Ipv4AddressTlvValue::~Ipv4AddressTlvValue ()
{
- m_ipv4Addr->clear ();
if (m_ipv4Addr != 0)
{
+ m_ipv4Addr->clear ();
delete m_ipv4Addr;
m_ipv4Addr = 0;
}
--- a/utils/bench-packets.cc Tue Jun 04 16:57:16 2013 +0200
+++ b/utils/bench-packets.cc Tue Jun 04 17:20:40 2013 +0200
@@ -252,7 +252,10 @@
double ps = n;
ps *= 1000;
ps /= deltaMs;
- std::cout << name<<"=" << ps << " packets/s" << std::endl;
+ std::cout << ps << " packets/s"
+ << " (" << deltaMs << " ms elapsed)\t"
+ << name
+ << std::endl;
}
int main (int argc, char *argv[])
@@ -280,11 +283,12 @@
exit (1);
}
std::cout << "Running bench-packets with n=" << n << std::endl;
+ std::cout << "All tests begin by adding UDP and IPv4 headers." << std::endl;
- runBench (&benchA, n, "a");
- runBench (&benchB, n, "b");
- runBench (&benchC, n, "c");
- runBench (&benchD, n, "d");
+ runBench (&benchA, n, "Copy packet, remove headers");
+ runBench (&benchB, n, "Just add headers");
+ runBench (&benchC, n, "Remove by func call");
+ runBench (&benchD, n, "Intermixed add/remove headers and tags");
return 0;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/utils/coverity-report.sh Tue Jun 04 17:20:40 2013 +0200
@@ -0,0 +1,85 @@
+#!/bin/bash
+
+
+# Copyright (c) 2013 Lawrence Livermore National Laboratory
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation;
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Author: Peter D. Barnes, Jr. <pdbarnes@llnl.gov>
+
+#
+# Do a coverity build and submit report
+#
+
+me=`basename $0`
+
+# echo commands and output to a log file
+
+logf=coverity/coverity-build.log
+echo | tee $logf
+
+function say ()
+{
+ echo "$me:" $* | tee -a $logf
+}
+blank ()
+{
+ echo | tee -a $logf
+}
+function doo ()
+{
+ say "$ "$*
+ $* 2>&1 | tee -a $logf
+}
+
+
+
+
+say $(date)
+blank
+
+doo ./waf clean
+blank
+
+doo ./waf configure $NS3CONFIG
+blank
+
+cov=coverity/cov-int
+doo cov-build --dir $cov ./waf build
+blank
+
+tarf=coverity/ns-3.tgz
+doo tar cvzf $tarf -C coverity cov-int
+blank
+
+useremail=$(hg showconfig ui.username | \
+ egrep -o "\b[a-zA-Z0-9.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9.-]+\b")
+
+repoversion="$(basename $(dirname $PWD))@$(hg id -i)"
+
+# curl complains if this contains white space
+description="Coverity-mods"
+
+doo curl \
+ --form file=@$tarf \
+ --form project=ns-3 \
+ --form password=4jk2BVX9 \
+ --form email="$useremail" \
+ --form version="$repoversion" \
+ --form description="$description" \
+ http://scan5.coverity.com/cgi-bin/upload.py
+blank
+
+say $(date)
+blank