Merge tag 'ns-3.39' into unison

ns-3.39 release
This commit is contained in:
F5
2023-11-14 20:52:26 +08:00
1065 changed files with 26463 additions and 31497 deletions

View File

@@ -28,23 +28,29 @@ Checks: >
performance-inefficient-algorithm,
performance-inefficient-vector-operation,
performance-trivially-destructible,
performance-unnecessary-copy-initialization,
readability-braces-around-statements,
readability-container-size-empty,
readability-duplicate-include,
readability-isolate-declaration,
readability-make-member-function-const,
readability-misleading-indentation,
readability-misplaced-array-index,
readability-redundant-control-flow,
readability-redundant-function-ptr-dereference,
readability-redundant-smartptr-get,
readability-redundant-string-cstr,
readability-simplify-boolean-expr,
readability-simplify-subscript-expr,
readability-static-accessed-through-instance,
readability-static-definition-in-anonymous-namespace,
readability-string-compare,
readability-uppercase-literal-suffix,
CheckOptions:
- key: performance-unnecessary-copy-initialization.AllowedTypes
value: Ptr
- key: readability-simplify-boolean-expr.SimplifyDeMorgan
value: false
FormatStyle: "file"
HeaderFilterRegex: ".*(ns|NS).*/(contrib|examples|src|scratch|utils)/*/.*h"
UseColor: true

View File

@@ -1,4 +1,5 @@
[codespell]
skip = .git,.gitlab-ci-local,*.eps,*.pdf,*.css_t,AUTHORS
skip = .git,.gitlab-ci-local,*.eps,*.pdf,*.css_t,AUTHORS,*build*,*.mob
ignore-words = ./utils/codespell-ignored-words
exclude-file = ./utils/codespell-ignored-lines
regex = (?<![a-z])[a-z']+|[A-Z][a-z']*|[a-z]+'[a-z]*|[a-z]+(?=[_-])|[a-z]+(?=[A-Z])|\d+

View File

@@ -31,6 +31,6 @@ indent_size = 4
indent_style = space
indent_size = 2
[*.yml]
[*.{md,rst,yml,yaml}]
indent_style = space
indent_size = 2

View File

@@ -153,18 +153,20 @@ jobs:
- uses: msys2/setup-msys2@v2
- name: Install required msys2/mingw64 packages
run: |
pacman -S --noconfirm unzip
pacman -S --noconfirm tar
pacman -S --noconfirm mingw-w64-x86_64-curl
pacman -S --noconfirm mingw-w64-x86_64-binutils
pacman -S --noconfirm mingw-w64-x86_64-cmake
pacman -S --noconfirm mingw-w64-x86_64-gcc
pacman -S --noconfirm mingw-w64-x86_64-ninja
pacman -S --noconfirm mingw-w64-x86_64-python
pacman -S --noconfirm mingw-w64-x86_64-ccache
pacman -S --noconfirm mingw-w64-x86_64-gsl
pacman -S --noconfirm mingw-w64-x86_64-libxml2
pacman -S --noconfirm mingw-w64-x86_64-lld
pacman -S --noconfirm \
unzip \
tar \
mingw-w64-x86_64-curl \
mingw-w64-x86_64-binutils \
mingw-w64-x86_64-cmake \
mingw-w64-x86_64-gcc \
mingw-w64-x86_64-ninja \
mingw-w64-x86_64-python \
mingw-w64-x86_64-ccache \
mingw-w64-x86_64-gsl \
mingw-w64-x86_64-libxml2 \
mingw-w64-x86_64-lld \
mingw-w64-x86_64-sed
pacman --noconfirm -Scc
- name: Get timestamp
id: time

2
.gitignore vendored
View File

@@ -24,6 +24,8 @@ testpy-output
bindings/python/pybindgen/
venv/
ms_print.*
massif.*
coverity

10
AUTHORS
View File

@@ -7,6 +7,7 @@ Chetan Agrawal (chetanag35@gmail.com)
Rohit Agarwal (mindprince@gmail.com)
Piyush Aggarwal (piyush8311@gmail.com)
Alessandro Aimi (alleaimi95@gmail.com)
German Aizek (germanaizek@yandex.ru)
Zoraze Ali (zoraze.ali@cttc.es)
Eduardo Almeida (enmsa@outlook.pt)
Robert Ammon (ammo6818@vandals.uidaho.edu)
@@ -96,6 +97,7 @@ Nichit Bodhak Goel (nichit93@gmail.com)
Tom Goff (tgoff@tgoff.net)
Mohit Goyal (mohit.bits@gmail.com)
Juan C. Granda (jcgranda@uniovi.es)
Giovanni Grieco (giovanni.grieco@poliba.it)
David Gross (gdavid.devel@gmail.com)
Maja Grubišić (maja.grubisic@live.com)
Rémy Grünblatt (remy@grunblatt.org)
@@ -107,6 +109,7 @@ Daniel Halperin (daniel@halper.in)
Bruno Haick (bghaick@hotmail.com)
Amiraslan Haghrah (amiraslanhaghrah@gmail.com)
Robert Hartung (hartung@ibr.cs.tu-bs.de)
Karsten Heimann
Frank Helbert (frank@ime.usp.br)
Tom Henderson (tomhend@u.washington.edu)
Christopher Hepner (hepner@hs-ulm.de)
@@ -135,6 +138,7 @@ Liu Jian (liujatp@gmail.com)
Sascha Alexander Jopen (jopen@informatik.uni-bonn.de)
Piotr Jurkiewicz (piotr.jerzy.jurkiewicz@gmail.com)
Evgeny Kalishenko (ydginster@gmail.com)
Raghuram Kannan (raghuramkannan40@gmail.com)
Vignesh Kannan (vignesh2496@gmail.com)
Ouassim Karrakchou (okarr102@uottawa.ca)
Tanmay Kathpalia (tanmay.kathpalia@landisgyr.com)
@@ -161,6 +165,7 @@ Emmanuelle Laprise (emmmanuelle.laprise@bluekazoo.ca)
Harsh Lara (harshapplefan@gmail.com)
Mattia Lecci (mattia.lecci@gmail.com)
Robin Lee (xinyashuai1987@163.com)
Juan Leon (juanvleonr@gmail.com)
Kristijan Lenković (k.lenkovic@me.com)
Daniel Lertpratchya (nikkipui@gmail.com)
Brett Levasseur (brettl20@gmail.com)
@@ -198,6 +203,7 @@ Esteban Municio (esteban.municio@urjc.es)
Sidharth Nabar (snabar@uw.edu)
Sharan Naribole (sharan.naribole@gmail.com)
Hemanth Narra (hemanth@ittc.ku.edu)
Carlos Natalino (carlos.natalino@chalmers.se)
Roman Naumann (naumann@informatik.hu-berlin.de)
Mohtashim Nawaz (nawazmohtashim@gmail.com)
Sachin Nayak (sachinn@uw.edu)
@@ -250,11 +256,12 @@ Jakub Rewienski (jrewienski@gmail.com)
Matias Richart (mrichart@fing.edu.uy)
George F. Riley (riley@ece.gatech.edu)
Juergen Rinas (jrinas@gmx.de)
Robert-ML
Sebastian Rohde (sebastian.rohde@tu-dortmund.de)
Karsten Roscher (sfx@rocktale.de)
Ali Rostami (a.rostami@rutgers.edu)
Bill Roome (wdr@bell-labs.com)
David (david.rua@gmail.com)
David Rua (david.rua@gmail.com)
Andrea Sacco (andrea.sacco85@gmail.com)
Richard Sailer (richard_sailer@systemli.org)
Lynne Salameh (l.salameh@cs.ucl.ac.uk)
@@ -312,6 +319,7 @@ Guillaume Vu-Brugier (gvubrugier@gmail.com)
Tom Wambold (tom5760@gmail.com)
Danqi Wang (beyondwdq@gmail.com)
Tinghui Wang (tinghui.wang@wsu.edu)
Yikun Wang (yikunwang6@gmail.com)
Mitch Watrous (watrous@u.washington.edu)
Pierre Wendling (pierre.wendling.4@gmail.com)
Florian Westphal (fw@strlen.de)

View File

@@ -13,6 +13,76 @@ Note that users who upgrade the simulator across versions, or who work directly
This file is a best-effort approach to solving this issue; we will do our best but can guarantee that there will be things that fall through the cracks, unfortunately. If you, as a user, can suggest improvements to this file based on your experience, please contribute a patch or drop us a note on ns-developers mailing list.
Changes from ns-3.38 to ns-3.39
-------------------------------
### New API
* (lr-wpan) Added support for orphan scans. Orphan scans can now be performed using the existing `LrWpanMac::MlmeScanRequest`; This orphan scan use the added orphan notification commands and coordinator realigment commands. Usage is shown in added `lr-wpan-orphan-scan.cc` example and in the `TestOrphanScan` included in `lr-wpan-mac-test.cc`.
* (network) Added `Mac64Address::ConvertToInt`. Converts a Mac64Address object to a uint64_t.
* (network) Added `Mac16Address::ConvertToInt`. Converts a Mac16Address object to a uint16_t.
* (network) Added `Mac16Address::Mac16Address(uint16t addr)` and `Mac16Address::Mac64Address(uint64t addr)` constructors.
* (lr-wpan) Added `LrwpanMac::MlmeGetRequest` function and the corresponding confirm callbacks as well as `LrwpanMac::SetMlmeGetConfirm` function.
* (applications) Added `Tx` and `TxWithAddresses` trace sources in `UdpClient`.
* (spectrum) Added `SpectrumTransmitFilter` class and the ability to add them to `SpectrumChannel` instances.
* (stats) Added `Histogram::Clear` function to clear the histogram contents.
* (wifi) Added `WifiBandwidthFilter` class to allow filtering of out-of-band Wi-Fi signals.
* (flow-monitor) Added `FlowMonitor::ResetAllStats` function to reset the FlowMonitor statistics.
### Changes to existing API
* The spelling of the following files, classes, functions, constants, defines and enumerated values was corrected; this will affect existing users who were using them with the misspelling.
* (dsr) Class `DsrOptionRerrUnsupportHeader` from `dsr-option-header.h` was renamed `DsrOptionRerrUnsupportedHeader`.
* (internet) Enumerated value `IPV6_EXT_AUTHENTIFICATION` from `ipv6-header.h` was renamed `IPV6_EXT_AUTHENTICATION`.
* (lr-wpan) Constant `aMaxBeaconPayloadLenght` from `lr-wpan-constants.h` was renamed `aMaxBeaconPayloadLength`.
* (lte) Enumeration `ControPduType_t` from `lte-rlc-am-header.h` was renamed `ControlPduType_t`.
* (lte) Function `LteUeCphySapProvider::StartInSnycDetection()` from `lte-ue-cphy-sap.h` was renamed `LteUeCphySapProvider::StartInSyncDetection()`.
* (lte) Function `MemberLteUeCphySapProvider::StartInSnycDetection()` from `lte-ue-cphy-sap.h` was renamed `MemberLteUeCphySapProvider::StartInSyncDetection()`.
* (lte) Function `LteUePhy::StartInSnycDetection()` from `lte-ue-phy.h` was renamed `LteUePhy::StartInSyncDetection()`.
* (lte) Function `DoUlInfoListElementHarqFeeback` from `lte-enb-phy-sap.h` and `lte-enb-mac.h` was renamed `DoUlInfoListElementHarqFeedback`.
* (lte) Function `DoDlInfoListElementHarqFeeback` from `lte-enb-phy-sap.h` and `lte-enb-mac.h` was renamed `DoDlInfoListElementHarqFeedback`.
* (mesh) Function `PeerManagementProtocolMac::SetPeerManagerProtcol` from `peer-management-protocol-mac.h` was renamed `PeerManagementProtocolMac::SetPeerManagerProtocol`.
* (network) File `lollipop-comparisions.cc` was renamed `lollipop-comparisons.cc`.
* (network) Attribute `currentTrimedFromStart` from `packet-metadata.h` was renamed `currentTrimmedFromStart`.
* (network) Attribute `currentTrimedFromEnd` from `packet-metadata.h` was renamed `currentTrimmedFromEnd`.
* (sixlowpan) Function `SixLowPanNetDevice::Fragments::GetFraments` from `sixlowpan-net-device.cc` was renamed `SixLowPanNetDevice::Fragments::GetFragments`.
* (wave) Function `OcbWifiMac::CancleTx()` from `ocb-wifi-mac.h` was renamed `OcbWifiMac::CancelTx()`.
* (wifi) Attribute `m_succesMax1` from `aparf-wifi-manager.h` was renamed `m_successMax1`.
* (wifi) Attribute `m_succesMax2` from `aparf-wifi-manager.h` was renamed `m_successMax2`.
* (wifi) Enumerated value `MDAOP_ADVERTISMENT_REQUEST` from `mgmt-headers.h` was renamed `MDAOP_ADVERTISEMENT_REQUEST`.
* (wifi) Enumerated value `MDAOP_ADVERTISMENTS` from `mgmt-headers.h` was renamed `MDAOP_ADVERTISEMENTS`.
* (wifi) Define `IE_BEAMLINK_MAINENANCE` from `wifi-information-element.h` was renamed `IE_BEAMLINK_MAINTENANCE`.
* (wimax) Attribute `m_nrRecivedFecBlocks` from `simple-ofdm-wimax-phy.h` was renamed `m_nrReceivedFecBlocks`.
* (lr-wpan) Updated `LrWpanPhy::PlmeSetAttribute` and `LrWpanPhy::PlmeGetAttribute` (Request and Confirm) to use smart pointers.
* (lr-wpan) Modified `LrWpanPhy::PlmeGetAttributeRequest` to include support for a few attributes (none were supported before the change).
* (lr-wpan) Added `macShortAddress`, `macExtendedAddress` and `macPanId` to the attributes that can be use with MLME-GET and MLME-SET functions.
* (wifi) The QosBlockedDestinations class has been removed and its functionality is now provided via a new framework for blocking/unblocking packets that is based on the queue scheduler.
* (internet) The function signature of `Ipv4RoutingProtocol::RouteInput` and `Ipv6RoutingProtocol::RouteInput` have changed. The `UnicastForwardCallback` (ucb), `MulticastForwardCallback` (mcb), `LocalDeliverCallback` (lcb) and `ErrorCallback` (ecb) should now be passed as const references.
* (olsr) The defines `OLSR_WILL_*` have been replaced by enum `Willingness`.
* (olsr) The defines `OLSR_*_LINK` have been replaced by enum `LinkType`.
* (olsr) The defines `OLSR_*_NEIGH` have been replaced by enum `NeighborType`.
* (wifi) The `WifiCodeRate` typedef was converted to an enum.
* (internet) `InternetStackHelper` can be now used on nodes with an `InternetStack` already installed (it will not install IPv[4,6] twice).
* (lr-wpan) Block the reception of orphan notification commands to devices other than PAN coordinators or coordinators.
* (lr-wpan) Block the reception of broadcast messages in the same device that issues it. This is done in both cases when the src address is either short or extended address.
* (lr-wpan) Adds a new variable flag `m_coor` to the MAC to differentiate between coordinators and PAN coordinators.
* (lte) Add support for DC-GBR. The member `QosBearerType_e` of the structure `LogicalChannelConfigListElement_s` is extended to include DC-GBR resource type. Based on this change, the method **IsGbr** of `EpsBearer`, is renamed to **GetResourceType**. LTE code using this method, is updated according to this change.
* (lte) The `EpsBearer` is extended to include 3GPP Release 18 5QIs.
* (lte) Add PDCP discard timer. If enabled using the attribute `EnablePdcpDiscarding`, in case that the buffering time (head-of-line delay) of a packet is greater than the PDB or a value set by the user, it will perform discarding at the moment of passing the PDCP SDU to RLC.
* (lte) Centralize the constants `MIN_NO_CC` and `MAX_NO_CC`, declared in multiple header files, into the header `lte-common.h`.
* (wave) The Wave module was removed from the codebase due to lack of maintenance
### Changes to build system
### Changed behavior
* (core) The priority of `DEBUG` level logging has been lowered from just below `WARN` level to just below `LOGIC` level.
* (buildings) Calculation of the O2I Low/High Building Penetration Losses based on 3GPP 38.901 7.4.3.1 was missing. These losses are now included in the pathloss calculation when buildings are present.
* (network) The function `Buffer::Allocate` will over-provision `ALLOC_OVER_PROVISION` bytes when allocating buffers for packets. `ALLOC_OVER_PROVISION` is currently set to 100 bytes.
* (wifi) By default, the `SpectrumWifiHelper` now adds a `WifiBandwidthFilter` to discard out-of-band signals before scheduling them on the receiver. This should not affect the simulated behavior of Wi-Fi but may speed up the execution of large Wi-Fi simulations.
* (wifi) Protection mechanisms (e.g., RTS/CTS) are not used if destinations have already received (MU-)RTS in the current TXOP
* (wifi) Protection mechanisms can be used for management frames as well (if needed)
Changes from ns-3.37 to ns-3.38
-------------------------------
@@ -29,6 +99,7 @@ Changes from ns-3.37 to ns-3.38
* (wifi) Added a new attribute **NMaxInflights** to QosTxop to set the maximum number of links on which an MPDU can be simultaneously in-flight.
* (wifi) New API has been introduced to support 802.11be Multi-Link Operations (MLO)
* (wifi) New API has been introduced to support 802.11ax dual NAV, UL MU CS, and MU-RTS/CTS features
* (wifi) Added a new attribute **TrackSignalsFromInactiveInterfaces** to SpectrumWifiPhy to select whether it should track signals from inactive spectrum PHY interfaces.
### Changes to existing API
@@ -39,6 +110,8 @@ Changes from ns-3.37 to ns-3.38
* (lr-wpan) Added file `src/lr-wpan/model/lr-wpan-constants.h` with common constants of the LR-WPAN module.
* (lr-wpan) Removed the functions `LrWpanCsmaCa::GetUnitBackoffPeriod()` and `LrWpanCsmaCa::SetUnitBackoffPeriod()`, and moved the constant `m_aUnitBackoffPeriod` to `src/lr-wpan/model/lr-wpan-constants.h`.
* (lr-wpan) `LrWpanHelper::CreateAssociatedPan` replace `LrWpanHelper::AssociateToPan` and is able to create an associated PAN of the devices with both short addresses (16-bits) and extended addresses (EUI-64 bits).
* (wifi) `SpectrumWifiPhy::SetChannel` has been renamed to `SpectrumWifiPhy::AddChannel` and has one additional parameter (optional) to indicate the frequency range that is covered by the provided spectrum channel. By default, the whole wifi spectrum channel is considered.
* The `WifiSpectrumHelper::SetChannel` functions used for MLO do no longer take a link ID parameter, but instead takes the frequency range covered by the spectrum channel and have been renamed to `WifiSpectrumHelper::AddChannel`. The remaining `WifiSpectrumHelper::SetChannel` functions assume the whole wifi spectrum range is used by the spectrum channel.
### Changes to build system
@@ -400,7 +473,7 @@ Changes from ns-3.29 to ns-3.30
* A new attribute `WifiPhy::PostReceptionErrorModel` has been added to force specific packet drops.
* A new attribute `WifiPhy::PreambleDetectionModel` has been added to decide whether PHY preambles are successfully detected.
* New attributes `QosTxop::AddBaResponseTimeout` and `QosTxop::FailedAddBaTimeout` have been added to set the timeout to wait for an ADDBA response after the ACK to the ADDBA request is received and to set the timeout after a failed BA agreement, respectively.
* A new attribute `QosTxop::UseExpliciteBarAfterMissedBlockAck` has been added to specify whether explicit Block Ack Request should be sent upon missed Block Ack Response.
* A new attribute `QosTxop::UseExplicitBarAfterMissedBlockAck` has been added to specify whether explicit Block Ack Request should be sent upon missed Block Ack Response.
* Added a new trace source `EndOfHePreamble` in WifiPhy for tracing end of preamble (after training fields) for received 802.11ax packets.
* Added a new helper method to SpectrumWifiPhyHelper and YansWifiPhyHelper to set the **frame capture model**.
* Added a new helper method to SpectrumWifiPhyHelper and YansWifiPhyHelper to set the **preamble detection model**.
@@ -587,12 +660,12 @@ Changes from ns-3.26 to ns-3.27
* A new standard value has been added that enables the new 11ax data rates.
* A new 11ax preamble has been added.
* A new attribute was added to configure the guard interval duration for High Efficiency (HE) PHY entities. This attribute can be set using the YansWifiPhyHelper.
* A new information element has been added: HeCapabilities. This information element is added to the MAC frame header if the node is a HE node. This HeCapabilites information element is used to advertise the HE capabilities of the node to other nodes in the network.
* A new information element has been added: HeCapabilities. This information element is added to the MAC frame header if the node is a HE node. This HeCapabilities information element is used to advertise the HE capabilities of the node to other nodes in the network.
* A new class were added for the RRPAA WiFi rate control mechanism.
* Included carrier aggregation feature in LTE module
* LTE model is extended to support carrier aggregation feature according to 3GPP Release 10, for up to 5 component carriers.
* InstallSingleEnbDevice and InstalSingeUeDevice functions of LteHelper are now constructing LteEnbDevice and LteUeDevice according to CA architecture. Each device, UE and eNodeB contains an instance of component carrier manager, and may have several component carrier instances.
* InstallSingleEnbDevice and InstallSingleUeDevice functions of LteHelper are now constructing LteEnbDevice and LteUeDevice according to CA architecture. Each device, UE and eNodeB contains an instance of component carrier manager, and may have several component carrier instances.
* SAP interfaces are extended to include CA message exchange functionality.
* RRC connection procedure is extended to allow RRC connection reconfiguration for the configuration of the secondary carriers.
* RRC measurement reporting is extended to allow measurement reporting from the secondary carriers.
@@ -744,7 +817,7 @@ Changes from ns-3.23 to ns-3.24
* A new helper (VhtWifiMacHelper) was added to set up a Very high throughput (VHT) MAC entity.
* A new standard value has been added that enables the new 11ac data rates.
* A new 11ac preamble has been added.
* A new information element has been added: VhtCapabilities. This information element is added to the MAC frame header if the node is a VHT node. This VhtCapabilites information element is used to advertise the VHT capabilities of the node to other nodes in the network.
* A new information element has been added: VhtCapabilities. This information element is added to the MAC frame header if the node is a VHT node. This VhtCapabilities information element is used to advertise the VHT capabilities of the node to other nodes in the network.
* The ArpCache API was extended to allow the manual removal of ArpCache entries and the addition of permanent (static) entries for IPv4.
* The SimpleChannel in the `network` module now allows per-NetDevice blacklists, in order to do hidden terminal testcases.
@@ -837,7 +910,7 @@ Changes from ns-3.20 to ns-3.21
* New `const double& SpectrumValue::operator[] (size_t index) const`.
* A new TraceSource has been added to TCP sockets: SlowStartThreshold.
* New method CommandLine::AddValue (name, attibutePath) to provide a shorthand argument `name` for the Attribute `path`. This also has the effect of including the help string for the Attribute in the Usage message.
* New method CommandLine::AddValue (name, attributePath) to provide a shorthand argument `name` for the Attribute `path`. This also has the effect of including the help string for the Attribute in the Usage message.
* The GSoC 2014 project in the LTE module has brought some additional APIs:
* a new abstract class LteFfrAlgorithm, which every future implementation of frequency reuse algorithm should inherit from
* a new SAPs: one between MAC Scheduler and FrAlgorithm, one between RRC and FrAlgorithm
@@ -988,7 +1061,7 @@ Changes from ns-3.17 to ns-3.18
* New attributes were added to help the user setup a High Throughput (HT) PHY entity. These attributes can be set using the YansWifiPhyHelper
* A new standard value has been added that enables the new 11n data rates.
* New 11n preambles has been added (Mixed format and greenfield). To be able to change Tx duration according to the preamble used, a new class TxVector has been added to carry the transmission parameters (mode, preamble, stbc,..). Several functions have been updated to allow the passage of TxVector instead of WifiMode in MacLow, WifiRemoteStationManager, WifiPhy, YansWifiPhy,..
* A new information element has been added: HTCapabilities. This information element is added to the MAC frame header if the node is an HT node. This HTCapabilites information element is used to advertise the HT capabilities of the node to other nodes in the network
* A new information element has been added: HTCapabilities. This information element is added to the MAC frame header if the node is an HT node. This HTCapabilities information element is used to advertise the HT capabilities of the node to other nodes in the network
* InternetStackHelper has two new functions:SetIpv4ArpJitter (bool enable) and SetIpv6NsRsJitter (bool enable) to enable/disable the random jitter on the transmission of IPv4 ARP Request and IPv6 NS/RS.
* Bounds on valid time inputs for time attributes can now be enabled. See attribute-test-suite.cc for an example.
* New generic hash function interface provided in the simulation core. Two hash functions are provided: murmur3 (default), and the venerable FNV1a. See the Hash Functions section in the ns-3 manual.
@@ -1057,7 +1130,7 @@ Changes from ns-3.16 to ns-3.17
* New DSR API
* Added PassiveBuffer class to save maintenance packet entry for passive acknowledgment option
* Added FindSourceEntry function in RreqTable class to keep track of route request entry received from same source node
* 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.
* Added NotifyDataReceipt function in DsrRouting class to notify the data receipt of the next hop from link layer. This is used for the link layer acknowledgment.
* New Tag, PacketSocketTag, to carry the destination address of a packet and the packet type
* New Tag, DeviceNameTag, to carry the ns-3 device name from where a packet is coming
* New Error Model, BurstError model, to determine which bursts of packets are errored corresponding to an underlying distribution, burst rate, and burst size
@@ -1091,7 +1164,7 @@ Changes from ns-3.16 to ns-3.17
* LteEnbPhy new methods GetLteEnbCphySapProvider, SetLteEnbCphySapUser, GetDlSpectrumPhy, GetUlSpectrumPhy, CreateSrsReport
* LteEnbPhy methods DoSendMacPdu, DoSetTransmissionMode, DoSetSrsConfigurationIndex, DoGetMacChTtiDelay, DoSendLteControlMessage, AddUePhy, DeleteUePhy made private
* LteEnbPhySapProvider removed methods SetBandwidth, SetTransmissionMode, SetSrsConfigurationIndex, SetCellId
* LteEnbPhySapUser added methods ReceiveRachPreamble, UlInfoListElementHarqFeeback, DlInfoListElementHarqFeeback
* LteEnbPhySapUser added methods ReceiveRachPreamble, UlInfoListElementHarqFeedback, DlInfoListElementHarqFeedback
* LtePdcp added methods (Set/Get)Status
* LtePdcp DoTransmitRrcPdu renamed DoTransmitPdcpSdu
* LteUeRrc new enum State. New methods SetLteUeCphySapProvider, GetLteUeCphySapUser, SetLteUeRrcSapUser, GetLteUeRrcSapProvider, GetState, GetDlEarfcn, GetDlBandwidth, GetUlBandwidth, GetCellId, SetUseRlcSm . GetRnti made const.

View File

@@ -25,6 +25,7 @@ option(NS3_TESTS "Enable tests to be built" OFF)
# fd-net-device options
option(NS3_EMU "Build with emulation support" ON)
option(NS3_TAP "Build with Tap support" ON)
option(NS3_DPDK "Enable fd-net-device DPDK features" OFF)
# maintenance and documentation
option(NS3_CLANG_FORMAT "Enforce cody style with clang-format" OFF)
@@ -93,8 +94,8 @@ option(NS3_WARNINGS_AS_ERRORS
set(NS3_ENABLED_MODULES ""
CACHE STRING "List of modules to enable (e.g. core;network;internet)"
)
set(NS3_DISABLED_MODULES ""
CACHE STRING "List of modules to disable (e.g. lte;wimax;wave)"
set(NS3_DISABLED_MODULES "" CACHE STRING
"List of modules to disable (e.g. lte;wimax)"
)
# Filter in the modules from which examples and tests will be built

View File

@@ -3,8 +3,6 @@
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.10077300.svg)](https://doi.org/10.5281/zenodo.10077300)
[![CI](https://github.com/NASA-NJU/UNISON-for-ns-3/actions/workflows/per_commit.yml/badge.svg)](https://github.com/NASA-NJU/UNISON-for-ns-3/actions/workflows/per_commit.yml)
## Table of Contents
A fast and user-transparent parallel simulator implementation for ns-3.
More information about UNISON can be found in our EuroSys '24 paper (coming soon).

View File

@@ -13,6 +13,66 @@ a [GitLab.com issue tracker](https://gitlab.com/nsnam/ns-3-dev/-/issues) number,
and references prefixed by '!' refer to a
[GitLab.com merge request](https://gitlab.com/nsnam/ns-3-dev/-/merge_requests) number.
Release 3.39
------------
### Availability
This release is available from:
<https://www.nsnam.org/release/ns-allinone-3.39.tar.bz2>
### Supported platforms
This release is intended to work on systems with the following minimal
requirements (Note: not all ns-3 features are available on all systems):
- g++-9 or later, or LLVM/clang++-6 or later
- Python 3.6 or later
- CMake 3.10 or later
- (macOS only) Xcode 11 or later
- (Windows only) Msys2/MinGW64 toolchain or WSL2
Python API requires [Cppyy](https://cppyy.readthedocs.io/en/latest/installation.html). Specifically, avoid Cppyy version 3; stay with version 2.4.2 for this release.
### New user-visible features
- (applications) !1412 - Add Tx and TxWithAddresses trace sources in UdpClient
- (bindings) - Package ns-3 as a pip wheel
- (doc) #876 - Improve dark-mode heading, navigation, and search bars
- (flowmonitor) #901 - Allow to reset the stats
- (lr-wpan) !1399 - Add orphan scan support.
- (lr-wpan) !1402 - Add attributes to MLME-SET and MLME-GET
- (lr-wpan) !1410 - Add Mac16 and Mac64 functions
- (network) !1405 - Add ConvertToInt to Mac64Address
Note: This release has removed the "wave" module from the codebase due to lack of maintenance
and due to lack of relevance to modern vehicular networks which appear to be moving to cellular
V2X solutions. Future users who may wish to use this code should obtain it from an earlier ns-3
release but should also be aware of a number of issues that arose and can be found in the
[ns-3 Issue tracker](https://gitlab.com/nsnam/ns-3-dev/-/issues/?state=all&label_name%5B%5D=module%3A%3Awave); in particular, #249, #879, #872, and #637.
### Bugs fixed
- (build) #881 - Fix scratch targets for file names containing dots
- (core) #902 - Fix vector inversion in the function `AttributeContainerTestSuite::ReverseList()`
- (energy) !1422 - Fix null harvester issue in EnergySource
- (internet) #910 - Release memory when sockets are closed
- (lr-wpan) !1406 - Fixes issues during MAC scan
- (lr-wpan) !1481 - Small fixes in MAC orphan scan
- (lte) #906 - Don't use invalid cell ID
- (propagation) - fix height assignment in 3gpp propagation loss model
- (wifi) #880 - Post-install change in WifiPhy::ChannelSettings does not completely reconfigure Wi-Fi
- (wifi) #862 - sta-wifi-mac.cc cond="!link.bssid.has_value()", High occurrence at higher numbers of STAs per AP in indoor deployment.
- (wifi) - Fix the equality operator of WifiInformationElement
- (wifi) - Make the implementation of the Multi-Link Element compliant with the 11be specs by adding support of inheritance
- (wifi) - Reset intra-BSS NAV when CF-End is an intra-BSS PPDU
- (wifi) - UL MU CS shall be evaluated a SIFS after end of MU-RTS
- (wifi) - Fix crash when changing operating channel after configuration but before initialization
- (wifi) - Fix assert when non-HE STAs receive CTS frames sent using non-HT duplicate following a MU-RTS frame
- (wifi) - Fix OBSS-PD support for 802.11be
- (wifi) #917 - Add missing STA-ID in GetMode() call from YansErrorRateModel
- (wifi) - Fix wifi-rate-adaptation-distance.cc example issues with CCA threshold
Release 3.38
------------
@@ -50,12 +110,17 @@ This release has discontinued support for g++-8 compilers.
- (network) !938 - Added class `TimestampTag` for associating a timestamp with a packet.
- (network) !1163 - Initializing an Ipv[4,6]Address from an invalid string do not raise an exception anymore. Instead the address is marked as not initialized.
- (spectrum) !1046 - Added the TwoRaySpectrumPropagationLossModel fast-fading class, as the outcome of the related GSoC 2022 project titled "A simplified channel and beamforming model for ns-3"
- (spectrum) !1119 - Added a capability to filter signals (with a new SpectrumTransmitFilter) sent on the SpectrumChannel before they are forwarded to receivers on the channel. This is motivated by scalability (reducing inconsequential simulation events).
the TwoRaySpectrumPropagationLossModel fast-fading class, as the outcome of the related GSoC 2022 project titled "A simplified channel and beamforming model for ns-3"
- (wifi) Added support for 802.11be Multi-Link Operations (MLO), STR mode only
- (wifi) Added more fields to the EHT Capabilities information element
- (wifi) Added an initial 802.11be-based example program
- (wifi) Added 802.11ax dual NAV (basic NAV and intra-BSS NAV)
- (wifi) Added 802.11ax Uplink Multi-User Carrier Sense (UL MU CS) mechanism and have it used by non-AP STAs when determining if they can reply to a received Trigger Frame
- (wifi) Added support for 802.11ax MU-RTS/CTS protection
- (wifi) !1119 - Added, by default, a WifiBandwidthFilter to spectrum channels created by the SpectrumWifiHelper, so as to filter out-of-band signals from the receiver.
- (internet) InternetStackHelper can be now used on nodes with an InternetStack already installed (it will not install IPv[4,6] twice).
- (wifi) Added support to attach multiple spectrum channels to a same PHY and the possibility to track signals from multiple RF interfaces
### Bugs fixed

View File

@@ -1 +1 @@
3.38
3.39

View File

@@ -1,5 +1,4 @@
import builtins
from copy import copy
from functools import lru_cache
import glob
import os.path
@@ -11,7 +10,7 @@ DEFAULT_INCLUDE_DIR = sysconfig.get_config_var("INCLUDEDIR")
DEFAULT_LIB_DIR = sysconfig.get_config_var("LIBDIR")
def find_ns3_lock():
def find_ns3_lock() -> str:
# Get the absolute path to this file
path_to_this_init_file = os.path.dirname(os.path.abspath(__file__))
path_to_lock = path_to_this_init_file
@@ -29,12 +28,14 @@ def find_ns3_lock():
if lock_file in os.listdir(path_to_lock):
path_to_lock += os.sep + lock_file
else:
path_to_lock = None
path_to_lock = ""
return path_to_lock
SYSTEM_LIBRARY_DIRECTORIES = (DEFAULT_LIB_DIR,
os.path.dirname(DEFAULT_LIB_DIR)
os.path.dirname(DEFAULT_LIB_DIR),
"/usr/lib64",
"/usr/lib"
)
DYNAMIC_LIBRARY_EXTENSIONS = {"linux": "so",
"win32": "dll",
@@ -81,12 +82,14 @@ def _search_libraries() -> dict:
# Search for the core library in the search paths
libraries = []
for search_path in library_search_paths:
libraries += glob.glob("%s/**/*.%s*" % (search_path, LIBRARY_EXTENSION), recursive=True)
if os.path.exists(search_path):
libraries += glob.glob("%s/**/*.%s*" % (search_path, LIBRARY_EXTENSION), recursive=True)
# Search system library directories (too slow for recursive search)
for search_path in SYSTEM_LIBRARY_DIRECTORIES:
libraries += glob.glob("%s/**/*.%s*" % (search_path, LIBRARY_EXTENSION), recursive=False)
libraries += glob.glob("%s/*.%s*" % (search_path, LIBRARY_EXTENSION), recursive=False)
if os.path.exists(search_path):
libraries += glob.glob("%s/**/*.%s*" % (search_path, LIBRARY_EXTENSION), recursive=False)
libraries += glob.glob("%s/*.%s*" % (search_path, LIBRARY_EXTENSION), recursive=False)
del search_path, library_search_paths
@@ -120,8 +123,35 @@ def search_libraries(library_name: str) -> list:
return matched_libraries
def extract_library_include_dirs(library_name: str, prefix: str) -> list:
library_path = "%s/lib/%s" % (prefix, library_name)
LIBRARY_AND_DEFINES = {
"libgsl": ["HAVE_GSL"],
"libxml2": ["HAVE_LIBXML2"],
"libsqlite3": ["HAVE_SQLITE3"],
"openflow": ["NS3_OPENFLOW", "ENABLE_OPENFLOW"],
"click": ["NS3_CLICK"]
}
def add_library_defines(library_name: str):
has_defines = list(filter(lambda x: x in library_name, LIBRARY_AND_DEFINES.keys()))
defines = ""
if len(has_defines):
for define in LIBRARY_AND_DEFINES[has_defines[0]]:
defines += (f"""
#ifndef {define}
#define {define} 1
#endif
""")
return defines
def extract_linked_libraries(library_name: str, prefix: str) -> tuple:
lib = ""
for variant in ["lib", "lib64"]:
library_path = f"{prefix}/{variant}/{library_name}"
if os.path.exists(library_path):
lib = variant
break
linked_libs = []
# First discover which 3rd-party libraries are used by the current module
try:
@@ -131,10 +161,17 @@ def extract_library_include_dirs(library_name: str, prefix: str) -> list:
print("Failed to extract libraries used by {library} with exception:{exception}"
.format(library=library_path, exception=e))
exit(-1)
return library_path, lib, list(map(lambda x: x.decode("utf-8"), linked_libs))
def extract_library_include_dirs(library_name: str, prefix: str) -> tuple:
library_path, lib, linked_libs = extract_linked_libraries(library_name, prefix)
linked_libs_include_dirs = set()
defines = add_library_defines(library_name)
# Now find these libraries and add a few include paths for them
for linked_library in map(lambda x: x.decode("utf-8"), linked_libs):
for linked_library in linked_libs:
# Skip ns-3 modules
if "libns3" in linked_library:
continue
@@ -148,15 +185,18 @@ def extract_library_include_dirs(library_name: str, prefix: str) -> list:
"Failed to find {library}. Make sure its library directory is in LD_LIBRARY_PATH.".format(
library=linked_library))
# Get path with shortest length
# Get path with the shortest length
linked_library_path = sorted(linked_library_path, key=lambda x: len(x))[0]
# If library is part of the ns-3 build, continue without any new includes
if prefix in linked_library_path:
continue
# Add defines based in linked libraries found
defines += add_library_defines(linked_library)
# If it is part of the system directories, try to find it
system_include_dir = os.path.dirname(linked_library_path).replace("lib", "include")
system_include_dir = os.path.dirname(linked_library_path).replace(lib, "include")
if os.path.exists(system_include_dir):
linked_libs_include_dirs.add(system_include_dir)
@@ -179,134 +219,214 @@ def extract_library_include_dirs(library_name: str, prefix: str) -> list:
inc_path = os.path.join(lib_path, "include")
if os.path.exists(inc_path):
linked_libs_include_dirs.add(inc_path)
return list(linked_libs_include_dirs)
return list(linked_libs_include_dirs), defines
def find_ns3_from_lock_file(lock_file: str) -> (str, list, str):
# Load NS3_ENABLED_MODULES from the lock file inside the build directory
values = {}
# If we find a lock file, load the ns-3 modules from it
# Should be the case when running from the source directory
exec(open(lock_file).read(), {}, values)
suffix = "-" + values["BUILD_PROFILE"] if values["BUILD_PROFILE"] != "release" else ""
modules = [module.replace("ns3-", "") for module in values["NS3_ENABLED_MODULES"]]
prefix = values["out_dir"]
libraries = {os.path.splitext(os.path.basename(x))[0]: x for x in os.listdir(os.path.join(prefix, "lib"))}
version = values["VERSION"]
# Filter out test libraries and incorrect versions
def filter_in_matching_ns3_libraries(libraries_to_filter: dict,
modules_to_filter: list,
version: str,
suffix: str) -> dict:
suffix = [suffix[1:]] if len(suffix) > 1 else []
filtered_in_modules = []
for module in modules_to_filter:
filtered_in_modules += list(filter(lambda x: "-".join([version, module, *suffix]) in x,
libraries_to_filter.keys()))
for library in list(libraries_to_filter.keys()):
if library not in filtered_in_modules:
libraries_to_filter.pop(library)
return libraries_to_filter
libraries = filter_in_matching_ns3_libraries(libraries, modules, version, suffix)
# When we have the lock file, we assemble the correct library names
libraries_to_load = []
for module in modules:
library_name = "libns{version}-{module}{suffix}".format(
version=version,
module=module,
suffix=suffix
)
if library_name not in libraries:
raise Exception("Missing library %s\n" % library_name,
"Build all modules with './ns3 build'"
)
libraries_to_load.append(libraries[library_name])
return prefix, libraries_to_load, version
# Extract version and build suffix (if it exists)
def filter_module_name(library: str) -> str:
library = os.path.splitext(os.path.basename(library))[0]
components = library.split("-")
# Remove version-related prefixes
if "libns3" in components[0]:
components.pop(0)
if "dev" == components[0]:
components.pop(0)
if "rc" in components[0]:
components.pop(0)
# Drop build profile suffix and test libraries
if components[-1] in ["debug", "default", "optimized", "release", "relwithdebinfo", "minsizerel"]:
components.pop(-1)
return "-".join(components)
def extract_version(library: str, module: str) -> str:
library = os.path.basename(library)
return re.findall(r"libns([\d.|rc|\-dev]+)-", library)[0]
def get_newest_version(versions: list) -> str:
versions = list(sorted(versions))
if "dev" in versions[0]:
return versions[0]
# Check if there is a release of a possible candidate
try:
pos = versions.index(os.path.splitext(versions[-1])[0])
except ValueError:
pos = None
# Remove release candidates
if pos is not None:
return versions[pos]
else:
return versions[-1]
def find_ns3_from_search() -> (str, list, str):
libraries = search_libraries("ns3")
if not libraries:
raise Exception("ns-3 libraries were not found.")
# If there is a version with a hash by the end, we have a pip-installed library
pip_libraries = list(filter(lambda x: "python" in x, libraries))
if pip_libraries:
# We drop non-pip libraries
libraries = pip_libraries
# The prefix is the directory with the lib directory
# libns3-dev-core.so/../../
prefix = os.path.dirname(os.path.dirname(libraries[0]))
# Remove test libraries
libraries = list(filter(lambda x: "test" not in x, libraries))
# Filter out module names
modules = set([filter_module_name(library) for library in libraries])
def filter_in_newest_ns3_libraries(libraries_to_filter: list, modules_to_filter: list) -> tuple:
newest_version_found = ""
# Filter out older ns-3 libraries
for module in list(modules_to_filter):
# Filter duplicates of modules, while excluding test libraries
conflicting_libraries = list(filter(lambda x: module == filter_module_name(x), libraries_to_filter))
# Extract versions from conflicting libraries
conflicting_libraries_versions = list(map(lambda x: extract_version(x, module), conflicting_libraries))
# Get the newest version found for that library
newest_version = get_newest_version(conflicting_libraries_versions)
# Check if the version found is the global newest version
if not newest_version_found:
newest_version_found = newest_version
else:
newest_version_found = get_newest_version([newest_version, newest_version_found])
if newest_version != newest_version_found:
raise Exception("Incompatible versions of the ns-3 module '%s' were found: %s != %s."
% (module, newest_version, newest_version_found))
for conflicting_library in list(conflicting_libraries):
if "-".join([newest_version, module]) not in conflicting_library:
libraries.remove(conflicting_library)
conflicting_libraries.remove(conflicting_library)
if len(conflicting_libraries) > 1:
raise Exception("There are multiple build profiles for module '%s'.\nDelete one to continue: %s"
% (module, ", ".join(conflicting_libraries)))
return libraries_to_filter, newest_version_found
# Get library base names
libraries, version = filter_in_newest_ns3_libraries(libraries, list(modules))
return prefix, libraries, version
def load_modules():
lock_file = find_ns3_lock()
libraries_to_load = []
if lock_file:
# Load NS3_ENABLED_MODULES from the lock file inside the build directory
values = {}
# Search for prefix to ns-3 build, modules and respective libraries plus version
ret = find_ns3_from_search() if not lock_file else find_ns3_from_lock_file(lock_file)
# If we find a lock file, load the ns-3 modules from it
# Should be the case when running from the source directory
exec(open(lock_file).read(), {}, values)
suffix = "-" + values["BUILD_PROFILE"] if values["BUILD_PROFILE"] != "release" else ""
modules = [module.replace("ns3-", "") for module in values["NS3_ENABLED_MODULES"]]
prefix = values["out_dir"]
libraries = {os.path.splitext(os.path.basename(x))[0]: x for x in os.listdir(os.path.join(prefix, "lib"))}
version = values["VERSION"]
# Unpack returned values
prefix, libraries, version = ret
prefix = os.path.abspath(prefix)
# Filter out test libraries and incorrect versions
def filter_in_matching_ns3_libraries(libraries_to_filter: dict,
modules_to_filter: list,
version: str,
suffix: str) -> dict:
suffix = [suffix[1:]] if len(suffix) > 1 else []
filtered_in_modules = []
for module in modules_to_filter:
filtered_in_modules += list(filter(lambda x: "-".join([version, module, *suffix]) in x,
libraries_to_filter.keys()))
for library in list(libraries_to_filter.keys()):
if library not in filtered_in_modules:
libraries_to_filter.pop(library)
return libraries_to_filter
# Sort libraries according to their dependencies
def sort_to_dependencies(libraries: list, prefix: str) -> list:
module_dependencies = {}
libraries = list(map(lambda x: os.path.basename(x), libraries))
for ns3_library in libraries:
_, _, linked_libraries = extract_linked_libraries(ns3_library, prefix)
linked_libraries = list(filter(lambda x: "libns3" in x and ns3_library not in x, linked_libraries))
linked_libraries = list(map(lambda x: os.path.basename(x), linked_libraries))
module_dependencies[os.path.basename(ns3_library)] = linked_libraries
libraries = filter_in_matching_ns3_libraries(libraries, modules, version, suffix)
else:
libraries = search_libraries("ns3")
def modules_that_can_be_loaded(module_dependencies, pending_modules, current_modules):
modules = []
for pending_module in pending_modules:
can_be_loaded = True
for dependency in module_dependencies[pending_module]:
if dependency not in current_modules:
can_be_loaded = False
break
if not can_be_loaded:
continue
modules.append(pending_module)
return modules
if not libraries:
raise Exception("ns-3 libraries were not found.")
def dependency_order(module_dependencies, pending_modules, current_modules, step_number=0, steps={}):
if len(pending_modules) == 0:
return steps
if step_number not in steps:
steps[step_number] = []
for module in modules_that_can_be_loaded(module_dependencies, pending_modules, current_modules):
steps[step_number].append(module)
pending_modules.remove(module)
current_modules.append(module)
return dependency_order(module_dependencies, pending_modules, current_modules, step_number + 1, steps)
# The prefix is the directory with the lib directory
# libns3-dev-core.so/../../
prefix = os.path.dirname(os.path.dirname(libraries[0]))
sorted_libraries = []
for step in dependency_order(module_dependencies, list(module_dependencies.keys()), [], 0).values():
sorted_libraries.extend(step)
return sorted_libraries
# Remove test libraries
libraries = list(filter(lambda x: "test" not in x, libraries))
libraries_to_load = sort_to_dependencies(libraries, prefix)
# Extract version and build suffix (if it exists)
def filter_module_name(library):
library = os.path.splitext(os.path.basename(library))[0]
components = library.split("-")
# Extract library base names
libraries_to_load = [os.path.basename(x) for x in libraries_to_load]
# Remove version-related prefixes
if "libns3" in components[0]:
components.pop(0)
if "dev" == components[0]:
components.pop(0)
if "rc" in components[0]:
components.pop(0)
# Drop build profile suffix and test libraries
if components[-1] in ["debug", "default", "optimized", "release", "relwithdebinfo"]:
components.pop(-1)
return "-".join(components)
# Filter out module names
modules = set([filter_module_name(library) for library in libraries])
def extract_version(library: str, module: str) -> str:
library = os.path.basename(library)
return re.findall(r"libns([\d.|rc|\-dev]+)-", library)[0]
def get_newest_version(versions: list) -> str:
versions = list(sorted(versions))
if "dev" in versions[0]:
return versions[0]
# Check if there is a release of a possible candidate
try:
pos = versions.index(os.path.splitext(versions[-1])[0])
except ValueError:
pos = None
# Remove release candidates
if pos is not None:
return versions[pos]
else:
return versions[-1]
def filter_in_newest_ns3_libraries(libraries_to_filter: list, modules_to_filter: list) -> list:
newest_version_found = None
# Filter out older ns-3 libraries
for module in list(modules_to_filter):
# Filter duplicates of modules, while excluding test libraries
conflicting_libraries = list(filter(lambda x: module == filter_module_name(x), libraries_to_filter))
# Extract versions from conflicting libraries
conflicting_libraries_versions = list(map(lambda x: extract_version(x, module), conflicting_libraries))
# Get the newest version found for that library
newest_version = get_newest_version(conflicting_libraries_versions)
# Check if the version found is the global newest version
if not newest_version_found:
newest_version_found = newest_version
else:
newest_version_found = get_newest_version([newest_version, newest_version_found])
if newest_version != newest_version_found:
raise Exception("Incompatible versions of the ns-3 module '%s' were found: %s != %s."
% (module, newest_version, newest_version_found))
for conflicting_library in list(conflicting_libraries):
if "-".join([newest_version, module]) not in conflicting_library:
libraries.remove(conflicting_library)
conflicting_libraries.remove(conflicting_library)
num_libraries -= 1
if len(conflicting_libraries) > 1:
raise Exception("There are multiple build profiles for module '%s'.\nDelete one to continue: %s"
% (module, ", ".join(conflicting_libraries)))
return libraries_to_filter
# Get library base names
libraries = filter_in_newest_ns3_libraries(libraries, modules)
libraries_to_load = list(map(lambda x: os.path.basename(x), libraries))
# Sort modules based on libraries
modules = list(map(lambda x: filter_module_name(x), libraries_to_load))
# Try to import Cppyy and warn the user in case it is not found
try:
@@ -324,35 +444,27 @@ def load_modules():
libcppyy.AddSmartPtrType('Ptr')
# Import ns-3 libraries
prefix = os.path.abspath(prefix)
cppyy.add_library_path("%s/lib" % prefix)
cppyy.add_include_path("%s/include" % prefix)
if lock_file:
# When we have the lock file, we assemble the correct library names
for module in modules:
library_name = "libns{version}-{module}{suffix}".format(
version=version,
module=module,
suffix=suffix
)
if library_name not in libraries:
raise Exception("Missing library %s\n" % library_name,
"Build all modules with './ns3 build'"
)
libraries_to_load.append(libraries[library_name])
for variant in ["lib", "lib64"]:
path_to_lib = f"{prefix}/{variant}"
if not os.path.exists(path_to_lib):
continue
cppyy.add_library_path(path_to_lib)
del variant, path_to_lib
cppyy.add_include_path(f"{prefix}/include")
known_include_dirs = set()
# We then need to include all include directories for dependencies
for library in libraries_to_load:
for linked_lib_include_dir in extract_library_include_dirs(library, prefix):
linked_lib_include_dirs, defines = extract_library_include_dirs(library, prefix)
cppyy.cppexec(defines)
for linked_lib_include_dir in linked_lib_include_dirs:
if linked_lib_include_dir not in known_include_dirs:
known_include_dirs.add(linked_lib_include_dir)
if os.path.isdir(linked_lib_include_dir):
cppyy.add_include_path(linked_lib_include_dir)
for module in modules:
cppyy.include("ns3/%s-module.h" % module)
cppyy.include(f"ns3/{module}-module.h")
# After including all headers, we finally load the modules
for library in libraries_to_load:

View File

@@ -104,7 +104,9 @@ function(build_lib)
)
endif()
if(NOT FILESYSTEM_LIBRARY_IS_LINKED)
if((NOT FILESYSTEM_LIBRARY_IS_LINKED) OR (${GCC} AND ${GCC8}))
# The GCC8 alternative is necessary since when installed alongside newer
# releases, the incorrect shared library can end up being linked.
list(APPEND BLIB_LIBRARIES_TO_LINK -lstdc++fs)
endif()
@@ -144,6 +146,15 @@ function(build_lib)
foreach(library ${BLIB_LIBRARIES_TO_LINK})
remove_lib_prefix("${library}" module_name)
# Ignore the case where the library dependency name match the ns-3 module
# since it is most likely is due to brite, click and openflow collisions.
# All the ns-3 module targets should be prefixed with 'lib' to be
# differentiable.
if("${library}" STREQUAL "${BLIB_LIBNAME}")
list(APPEND non_ns_libraries_to_link ${library})
continue()
endif()
# Check if the module exists in the ns-3 modules list or if it is a
# 3rd-party library
if(${module_name} IN_LIST ns3-all-enabled-modules)
@@ -193,6 +204,20 @@ function(build_lib)
${lib${BLIB_LIBNAME}} ${exported_libraries} ${private_libraries}
)
if(NOT ${XCODE})
# Since linking libraries to object libraries in not allowed in older CMake
# releases, we need to import each of their include directories. Otherwise,
# include directories won't be properly propagated
set(temp)
foreach(target ${ns_libraries_to_link})
list(APPEND temp
"$<TARGET_PROPERTY:${target},INTERFACE_INCLUDE_DIRECTORIES>"
)
endforeach()
target_include_directories(${lib${BLIB_LIBNAME}}-obj PRIVATE ${temp})
unset(temp)
endif()
# set output name of library
set_target_properties(
${lib${BLIB_LIBNAME}}

View File

@@ -36,6 +36,9 @@ option(NS3_ENABLE_SUDO
"Set executables ownership to root and enable the SUID flag" OFF
)
# a flag that controls some aspects related to pip packaging
option(NS3_PIP_PACKAGING "Control aspects related to pip wheel packaging" OFF)
# Replace default CMake messages (logging) with custom colored messages as early
# as possible
include(${PROJECT_SOURCE_DIR}/build-support/3rd-party/colored-messages.cmake)
@@ -71,6 +74,11 @@ if(WIN32)
set(NS3_PRECOMPILE_HEADERS OFF
CACHE BOOL "Precompile module headers to speed up compilation" FORCE
)
# For whatever reason getting M_PI and other math.h definitions from cmath
# requires this definition
# https://docs.microsoft.com/en-us/cpp/c-runtime-library/math-constants?view=vs-2019
add_definitions(/D_USE_MATH_DEFINES)
endif()
set(cat_command cat)
@@ -148,6 +156,25 @@ link_directories(${CMAKE_OUTPUT_DIRECTORY}/lib)
include(GNUInstallDirs)
include(build-support/custom-modules/ns3-cmake-package.cmake)
# Set RPATH not too need LD_LIBRARY_PATH after installing
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib:$ORIGIN/:$ORIGIN/../lib")
# Add the 64 suffix to the library path when manually requested with the
# -DNS3_USE_LIB64=ON flag. May be necessary depending on the target platform.
# This is used to properly build the manylinux pip wheel.
if(${NS3_USE_LIB64})
link_directories(${CMAKE_OUTPUT_DIRECTORY}/lib64)
set(CMAKE_INSTALL_RPATH
"${CMAKE_INSTALL_RPATH}:${CMAKE_INSTALL_PREFIX}/lib64:$ORIGIN/:$ORIGIN/../lib64"
)
endif()
# cmake-format: off
# You are a wizard, Harry!
# source: https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/RPATH-handling
# cmake-format: on
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
if(${XCODE})
# Is that so hard not to break people's CI, AAPL? Why would you output the
# targets to a Debug/Release subfolder? Why?
@@ -202,6 +229,7 @@ if(CLANG)
endif()
set(GCC FALSE)
set(GCC8 FALSE)
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${GNU_MinVersion})
message(
@@ -209,6 +237,12 @@ if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
"GNU ${CMAKE_CXX_COMPILER_VERSION} ${below_minimum_msg} ${GNU_MinVersion}"
)
endif()
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "9.0.0")
# This block is used to identify if GCC8 is being used. In this case, we
# want to explicitly link stdc++fs, which is done in
# ns3-module-macros.cmake.
set(GCC8 TRUE)
endif()
set(GCC TRUE)
add_definitions(-fno-semantic-interposition)
if(${NS3_COLORED_OUTPUT} OR "$ENV{CLICOLOR}")
@@ -222,6 +256,7 @@ unset(below_minimum_msg)
set(CXX_UNSUPPORTED_STANDARDS 98 11 14)
set(CMAKE_CXX_STANDARD_MINIMUM 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(LIB_AS_NEEDED_PRE)
set(LIB_AS_NEEDED_POST)
set(STATIC_LINK_FLAGS -static -static-libstdc++ -static-libgcc)
@@ -308,7 +343,6 @@ macro(clear_global_cached_variables)
unset(ns3-headers-to-module-map CACHE)
unset(ns3-libs CACHE)
unset(ns3-libs-tests CACHE)
unset(ns3-python-bindings-modules CACHE)
mark_as_advanced(
build_profile
build_profile_suffix
@@ -322,7 +356,6 @@ macro(clear_global_cached_variables)
ns3-headers-to-module-map
ns3-libs
ns3-libs-tests
ns3-python-bindings-modules
)
endmacro()
@@ -410,6 +443,8 @@ macro(process_options)
if(${NS3_TESTS} OR ${ns3rc_tests_enabled})
set(ENABLE_TESTS ON)
enable_testing()
else()
list(REMOVE_ITEM libs_to_build test)
endif()
set(profiles_without_suffixes release)
@@ -553,11 +588,11 @@ macro(process_options)
cmake-format
COMMAND
${CMAKE_FORMAT_PROGRAM} -c
${PROJECT_SOURCE_DIR}/build-support/cmake-format.txt -i
${PROJECT_SOURCE_DIR}/build-support/cmake-format.yaml -i
${INTERNAL_CMAKE_FILES}
COMMAND
${CMAKE_FORMAT_PROGRAM} -c
${PROJECT_SOURCE_DIR}/build-support/cmake-format-modules.txt -i
${PROJECT_SOURCE_DIR}/build-support/cmake-format-modules.yaml -i
${MODULES_CMAKE_FILES}
)
unset(MODULES_CMAKE_FILES)
@@ -802,7 +837,7 @@ macro(process_options)
find_package(Python3 COMPONENTS Interpreter Development)
else()
# cmake-format: off
set(Python_ADDITIONAL_VERSIONS 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9)
set(Python_ADDITIONAL_VERSIONS 3.6 3.7 3.8 3.9 3.10 3.11)
# cmake-format: on
find_package(PythonInterp)
find_package(PythonLibs)
@@ -856,10 +891,12 @@ macro(process_options)
)
endif()
else()
message(
${HIGHLIGHTED_STATUS}
"Python: an incompatible version of Python was found, python bindings will be disabled"
)
if(${NS3_PYTHON_BINDINGS})
message(
${HIGHLIGHTED_STATUS}
"Python: an incompatible version of Python was found, python bindings will be disabled"
)
endif()
endif()
set(ENABLE_PYTHON_BINDINGS OFF)
@@ -901,12 +938,16 @@ macro(process_options)
message(
${HIGHLIGHTED_STATUS}
"NS3_BINDINGS_INSTALL_DIR was not set. The python bindings won't be installed with ./ns3 install."
"This setting is meant for packaging and redistribution."
)
message(
${HIGHLIGHTED_STATUS}
"Set NS3_BINDINGS_INSTALL_DIR=\"${SUGGESTED_BINDINGS_INSTALL_DIR}\" to install it to the default location."
)
else()
if(${NS3_BINDINGS_INSTALL_DIR} STREQUAL "INSTALL_PREFIX")
set(NS3_BINDINGS_INSTALL_DIR ${CMAKE_INSTALL_PREFIX})
endif()
install(FILES bindings/python/ns__init__.py
DESTINATION ${NS3_BINDINGS_INSTALL_DIR}/ns RENAME __init__.py
)
@@ -1370,8 +1411,6 @@ macro(process_options)
set(ns3-contrib-libs)
set(lib-ns3-static-objs)
set(ns3-external-libs)
set(ns3-python-bindings ns${NS3_VER}-pybindings${build_profile_suffix})
set(ns3-python-bindings-modules)
foreach(libname ${scanned_modules})
# Create libname of output library of module
@@ -1497,7 +1536,7 @@ macro(process_options)
include(FetchContent)
FetchContent_Declare(
netanim GIT_REPOSITORY https://gitlab.com/nsnam/netanim.git
GIT_TAG netanim-3.108
GIT_TAG netanim-3.109
)
FetchContent_Populate(netanim)
file(COPY build-support/3rd-party/netanim-cmakelists.cmake
@@ -1597,8 +1636,11 @@ function(build_exec)
)
# Resolve nested scratch prefixes without user intervention
if("${CMAKE_CURRENT_SOURCE_DIR}" MATCHES "scratch"
AND "${BEXEC_EXECNAME_PREFIX}" STREQUAL ""
string(REPLACE "${PROJECT_SOURCE_DIR}" "" relative_path
"${CMAKE_CURRENT_SOURCE_DIR}"
)
if("${relative_path}" MATCHES "scratch" AND "${BEXEC_EXECNAME_PREFIX}"
STREQUAL ""
)
get_scratch_prefix(BEXEC_EXECNAME_PREFIX)
endif()
@@ -1946,10 +1988,6 @@ macro(
unset(dependencies)
unset(contrib_dependencies)
endforeach()
if(core IN_LIST ${libs_to_build})
list(APPEND ${libs_to_build} test) # include test module
endif()
endif()
if(${NS3_DISABLED_MODULES} OR ${ns3rc_disabled_modules})

View File

@@ -0,0 +1,11 @@
import os
ns3_path = os.path.dirname(os.path.abspath(os.sep.join([__file__, "../../"])))
for variant in ["lib", "lib64"]:
lib_dir = os.path.abspath(os.path.join(ns3_path, f"build/{variant}"))
if not os.path.exists(lib_dir):
continue
for lib in os.listdir(lib_dir):
if "libns3" in lib:
print(f"--exclude {lib}", end=' ')

View File

@@ -0,0 +1,10 @@
# This is a stub module that loads the actual ns-3
# bindings from ns3.ns
import sys
try:
import ns3.ns
sys.modules['ns'] = ns3.ns
except ModuleNotFoundError as e:
print("Install the ns3 package with pip install ns3.", file=sys.stderr)
exit(-1)

View File

@@ -0,0 +1,11 @@
# This is a stub module that loads the actual visualizer
# from ns3.visualizer
import sys
try:
import ns3.visualizer
except ModuleNotFoundError as e:
print("Install the ns3 package with pip install ns3.", file=sys.stderr)
exit(-1)
from ns3.visualizer import start, register_plugin, set_bounds, add_initialization_hook

View File

@@ -1,16 +0,0 @@
#! /usr/bin/env python3
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
def lp64_to_ilp32(lp64path, ilp32path):
import re
lp64bindings = None
with open(lp64path, "r") as lp64file:
lp64bindings = lp64file.read()
with open(ilp32path, "w") as ilp32file:
ilp32bindings = re.sub("unsigned long(?!( long))", "unsigned long long", lp64bindings)
ilp32file.write(ilp32bindings)
if __name__ == "__main__":
import sys
print(sys.argv)
exit(lp64_to_ilp32(sys.argv[1], sys.argv[2]))

View File

@@ -0,0 +1,6 @@
build_lib(
LIBNAME test-contrib-dependency
SOURCE_FILES contrib-source.cc
HEADER_FILES contrib-header.h
LIBRARIES_TO_LINK ${libcore}
)

View File

@@ -0,0 +1,6 @@
#ifndef NS3_CONTRIB_HEADER_H
#define NS3_CONTRIB_HEADER_H
void testPrint();
#endif // NS3_CONTRIB_HEADER_H

View File

@@ -0,0 +1,9 @@
#include "contrib-header.h"
#include <ns3/simulator.h>
void
testPrint()
{
std::cout << ns3::Simulator::Now() << std::endl;
}

View File

@@ -0,0 +1,8 @@
build_lib(
LIBNAME test-src-dependant-on-contrib
SOURCE_FILES src-source.cc
HEADER_FILES src-header.h
LIBRARIES_TO_LINK ${libcore}
${libtest-contrib-dependency}
)

View File

@@ -0,0 +1,6 @@
build_lib_example(
NAME source-example
SOURCE_FILES source-example.cc
LIBRARIES_TO_LINK
${libtest-src-dependant-on-contrib}
)

View File

@@ -0,0 +1,8 @@
#include <ns3/src-header.h>
int
main()
{
testPrint2();
return 0;
}

View File

@@ -0,0 +1,6 @@
#ifndef NS3_SRC_SOURCE2_H
#define NS3_SRC_SOURCE2_H
void testPrint2();
#endif // NS3_SOURCE_H

View File

@@ -0,0 +1,7 @@
#include <ns3/contrib-header.h>
void
testPrint2()
{
testPrint();
}

View File

@@ -129,6 +129,9 @@ their code and for the GitLab CI/CD pipeline to check if the codebase is well fo
All checks are enabled by default. Users can disable specific checks using the corresponding
flags: ``--no-formatting``, ``--no-whitespace`` and ``--no-tabs``.
Additional information about the formatting issues detected by the script can be enabled
by adding the ``-v, --verbose`` flag.
In addition to checking the files, the script can automatically fix detected issues in-place.
This mode is enabled by adding the ``--fix`` flag.
@@ -148,16 +151,16 @@ For quick-reference, the most used commands are listed below:
.. sourcecode:: console
# Entire codebase (using paths relative to the ns-3 main directory)
./utils/check-style-clang-format.py [--fix] [--no-formatting] [--no-whitespace] [--no-tabs] .
./utils/check-style-clang-format.py [--fix] [--verbose] [--no-formatting] [--no-whitespace] [--no-tabs] .
# Entire codebase (using absolute paths)
/path/to/utils/check-style-clang-format.py [--fix] [--no-formatting] [--no-whitespace] [--no-tabs] /path/to/ns3
/path/to/utils/check-style-clang-format.py [--fix] [--verbose] [--no-formatting] [--no-whitespace] [--no-tabs] /path/to/ns3
# Specific directory
/path/to/utils/check-style-clang-format.py [--fix] [--no-formatting] [--no-whitespace] [--no-tabs] absolute_or_relative/path/to/directory
/path/to/utils/check-style-clang-format.py [--fix] [--verbose] [--no-formatting] [--no-whitespace] [--no-tabs] absolute_or_relative/path/to/directory
# Individual file
/path/to/utils/check-style-clang-format.py [--fix] [--no-formatting] [--no-whitespace] [--no-tabs] absolute_or_relative/path/to/file
/path/to/utils/check-style-clang-format.py [--fix] [--verbose] [--no-formatting] [--no-whitespace] [--no-tabs] absolute_or_relative/path/to/file
Clang-tidy
@@ -752,8 +755,8 @@ For standard headers, use the C++ style of inclusion:
#include <ns3/header.h>
Variables
=========
Variables and constants
=======================
Each variable declaration is on a separate line.
Variables should be declared at the point in the code where they are needed,
@@ -768,6 +771,34 @@ and should be assigned an initial value at the time of declaration.
int x = 0;
int y = 0;
Named constants defined in classes should be declared as ``static constexpr`` instead of
macros, const, or enums. Use of ``static constexpr`` allows a single instance to be
evaluated at compile-time. Declaring the constant in the class enables it to share the scope
of the class.
If the constant is only used in one file, consider declaring the constant in the implementation
file (``*.cc``).
.. sourcecode:: cpp
// Avoid declaring constants as enum
class LteRlcAmHeader : public Header
{
enum ControlPduType_t
{
STATUS_PDU = 000,
};
};
// Prefer to declare them as static constexpr (in class)
class LteRlcAmHeader : public Header
{
static constexpr uint8_t STATUS_PDU{0};
};
// Or as constexpr (in implementation files)
constexpr uint8_t STATUS_PDU{0};
Comments
========
@@ -1096,6 +1127,53 @@ can be rewritten as:
n += 3;
return n;
Boolean Simplifications
=======================
In order to increase readability and performance, avoid unnecessarily complex boolean
expressions in if statements and variable declarations.
For instance, the following code:
.. sourcecode:: cpp
bool IsPositive(int n)
{
if (n > 0)
{
return true;
}
else
{
return false;
}
}
void ProcessNumber(int n)
{
if (IsPositive(n) == true)
{
...
}
}
can be rewritten as:
.. sourcecode:: cpp
bool IsPositive(int n)
{
return n > 0;
}
void ProcessNumber(int n)
{
if (IsPositive(n))
{
...
}
}
Smart pointer boolean comparisons
=================================

View File

@@ -48,9 +48,9 @@ copyright = u'2015, ns-3 project'
# built documents.
#
# The short X.Y version.
version = 'ns-3.38'
version = 'ns-3.39'
# The full version, including alpha/beta/rc tags.
release = 'ns-3.38'
release = 'ns-3.39'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@@ -95,7 +95,6 @@ the previous copyrights from the copyright file! See below for this case.
An example placement of a copyright statement can be found in the file
``src/network/model/packet.h``::
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2005,2006 INRIA
*
@@ -112,7 +111,6 @@ contributor may add a copyright statement that clarifies the new portion
of code that is covered by the new copyright. An example is the program
``src/lte/model/lte-ue-phy.h``::
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2010 TELEMATICS LAB, DEE - Politecnico di Bari
* Copyright (c) 2018 Fraunhofer ESK : RLF extensions

View File

@@ -1881,7 +1881,7 @@ PAPER_TYPE = a4
# If left blank no extra packages will be included.
# This tag requires that the tag GENERATE_LATEX is set to YES.
EXTRA_PACKAGES = amsmath
EXTRA_PACKAGES = amsmath,amssymb
# The LATEX_HEADER tag can be used to specify a user-defined LaTeX header for
# the generated LaTeX document. The header should contain everything until the
@@ -2693,5 +2693,5 @@ GENERATE_LEGEND = YES
DOT_CLEANUP = YES
# Disable dark mode in the generated HTML in Doxygen 1.9.6 or greater.
HTML_COLORSTYLE = LIGHT
# HTML_COLORSTYLE = LIGHT

View File

@@ -48,9 +48,9 @@ copyright = u'2018, ns-3 project'
# built documents.
#
# The short X.Y version.
version = 'ns-3.38'
version = 'ns-3.39'
# The full version, including alpha/beta/rc tags.
release = 'ns-3.38'
release = 'ns-3.39'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@@ -21,8 +21,8 @@ extensions you need; please review the previous chapter if you need more informa
Requirements
************
The minimum supported version of Ubuntu is Ubuntu 16.04 LTS (as long as a modern compiler
version such as g++ version 8 or later is added).
The minimum supported version of Ubuntu is Ubuntu 18.04 LTS (as long as a modern compiler
version such as g++ version 9 or later is added).
+--------------------+---------------------------------------------------------------------+
| **ns-3 Version** | **apt Packages** |
@@ -35,11 +35,8 @@ version such as g++ version 8 or later is added).
+--------------------+---------------------------------------------------------------------+
.. note::
As of January 2022 (ns-3.36 release and later), the minimum g++ version is g++-8.
Older Ubuntu releases (18.04, 16.04) come with an older default g++. On Ubuntu 18.04, this
`StackOverflow answer <https://askubuntu.com/a/1028656>`_ can be followed to install and
prefer g++-8. On older Ubuntu such as 16.04, to use the most recent |ns3|, you must install
g++-8 or g++-9 from the `Ubuntu toolchain <https://launchpad.net/%7Eubuntu-toolchain-r/+archive/ubuntu/test>`_.
As of July 2023 (ns-3.39 release and later), the minimum g++ version is g++-9.
Older ns-3 releases may work with older versions of g++; check the RELEASE_NOTES.
Recommended
***********
@@ -106,9 +103,11 @@ Please see below subsections for Python-related package requirements.
Python bindings
===============
Python requires `Cppyy, <https://cppyy.readthedocs.io/en/latest/installation.html>` and specifically, version 2.4.2 is the latest version known to work with ns-3 at this time.
ns-3.37 and newer::
python3 -m pip install --user cppyy
python3 -m pip install --user cppyy==2.4.2
ns-3.30-3.36 (also requires pybindgen, found in the ``allinone`` directory)::

View File

@@ -51,11 +51,9 @@ choose to use a subset of the available libraries; only the ``core`` library is
|ns3| uses the CMake build system (until release 3.36, the Waf build system was used). It can be
built from command-line or via a code editor program.
Most users write C++ ns-3 programs; Python support is less frequently used and is not officially
maintained as of this writing. As of *ns-3.37*, |ns3| uses `cppyy` to generate runtime Python
bindings. Officially, Python3 support is only lightly maintained, and the `cppyy` support was
contributed by Gabriel Ferreira as a proof-of-concept (hint: the project is seeking a full-time
maintainer to develop this further).
Most users write C++ ns-3 programs; Python support is less frequently used.
As of *ns-3.37*, |ns3| uses `cppyy` to generate runtime Python
bindings, and |ns3| is available in the Pip repositories as of ns-3.39 release.
Many users may be familiar with how software is packaged and installed on Linux and other systems
using package managers. For example, to install a given Linux development library such as

View File

@@ -80,13 +80,13 @@ Download
There are two main options:
1. Download a release tarball. This will unpack to a directory such as ``ns-allinone-3.38``
1. Download a release tarball. This will unpack to a directory such as ``ns-allinone-3.39``
containing |ns3| and some other programs. Below is a command-line download using ``wget``,
but a browser download will also work::
$ wget https://www.nsnam.org/releases/ns-allinone-3.38.tar.bz2
$ tar xfj ns-allinone-3.38.tar.bz2
$ cd ns-allinone-3.38/ns-3.38
$ wget https://www.nsnam.org/releases/ns-allinone-3.39.tar.bz2
$ tar xfj ns-allinone-3.39.tar.bz2
$ cd ns-allinone-3.39/ns-3.39
2. Clone |ns3| from the Git repository. The ``ns-3-allinone`` can be cloned, as well as
``ns-3-dev`` by itself. Below, we illustrate the latter::
@@ -99,7 +99,7 @@ you clone |ns3|, your directory will be named ``ns-3-dev``. By default, Git wil
the |ns3| ``master`` branch, which is a development branch. All |ns3| releases are tagged
in Git, so if you would then like to check out a past release, you can do so as follows::
$ git checkout -b ns-3.38-release ns-3.38
$ git checkout -b ns-3.39-release ns-3.39
In this quick-start, we are omitting download and build instructions for optional |ns3| modules,
the ``NetAnim`` animator, Python bindings, and ``NetSimulyzer``. The
@@ -152,8 +152,8 @@ You should see some output such as below, if successful::
propagation sixlowpan spectrum
stats tap-bridge test (no Python)
topology-read traffic-control uan
virtual-net-device visualizer wave
wifi wimax
virtual-net-device visualizer wifi
wimax
Modules not built (see ns-3 tutorial for explanation):
brite click openflow

View File

@@ -140,7 +140,8 @@ if you are running LTE or NR simulations (which make use of SQLite databases):
Python bindings (ns-3.37 and newer)
===================================
|ns3| Python support now uses `cppyy <https://cppyy.readthedocs.io/en/latest/>`_.
|ns3| Python support now uses `cppyy <https://cppyy.readthedocs.io/en/latest/>`_. Version 2.4.2
is the most recent supported cppyy release; version 3.0.0 is not currently supported.
Using Python bindings (release 3.30 to ns-3.36)
===============================================

View File

@@ -73,9 +73,9 @@ copyright = u'2006-2019'
# built documents.
#
# The short X.Y version.
version = u'ns-3.38'
version = u'ns-3.39'
# The full version, including alpha/beta/rc tags.
release = u'ns-3.38'
release = u'ns-3.39'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@@ -326,20 +326,20 @@ complexity on `Insert()` and `RemoveNext()`, are listed in the
following table. See the individual Scheduler API pages for details on the
complexity of the other API calls.
+-----------------------+-------------------------------------+-------------+--------------+----------+--------------+
| Scheduler Type | Complexity |
+-----------------------+-------------------------------------+-------------+--------------+----------+--------------+
| | | Time | Space |
| `SchedulerImpl` Type | Method +-------------+--------------+----------+--------------+
| | | Insert() | RemoveNext() | Overhead | Per Event |
+=======================+=====================================+=============+==============+==========+==============+
| CalendarScheduler | `<std::list> []` | Constant | Constant | 24 bytes | 16 bytes |
+-----------------------+-------------------------------------+-------------+--------------+----------+--------------+
| HeapScheduler | Heap on `std::vector` | Logarithmic | Logarithmic | 24 bytes | 0 |
+-----------------------+-------------------------------------+-------------+--------------+----------+--------------+
| ListScheduler | `std::list` | Linear | Constant | 24 bytes | 16 bytes |
+-----------------------+-------------------------------------+-------------+--------------+----------+--------------+
| MapScheduler | `st::map` | Logarithmic | Constant | 40 bytes | 32 bytes |
+-----------------------+-------------------------------------+-------------+--------------+----------+--------------+
| PriorityQueueSchduler | `std::priority_queue<,std::vector>` | Logarithimc | Logarithims | 24 bytes | 0 |
+-----------------------+-------------------------------------+-------------+--------------+----------+--------------+
+------------------------+-------------------------------------+-------------+--------------+----------+--------------+
| Scheduler Type | Complexity |
+------------------------+-------------------------------------+-------------+--------------+----------+--------------+
| | | Time | Space |
| `SchedulerImpl` Type | Method +-------------+--------------+----------+--------------+
| | | Insert() | RemoveNext() | Overhead | Per Event |
+========================+=====================================+=============+==============+==========+==============+
| CalendarScheduler | `<std::list> []` | Constant | Constant | 24 bytes | 16 bytes |
+------------------------+-------------------------------------+-------------+--------------+----------+--------------+
| HeapScheduler | Heap on `std::vector` | Logarithmic | Logarithmic | 24 bytes | 0 |
+------------------------+-------------------------------------+-------------+--------------+----------+--------------+
| ListScheduler | `std::list` | Linear | Constant | 24 bytes | 16 bytes |
+------------------------+-------------------------------------+-------------+--------------+----------+--------------+
| MapScheduler | `st::map` | Logarithmic | Constant | 40 bytes | 32 bytes |
+------------------------+-------------------------------------+-------------+--------------+----------+--------------+
| PriorityQueueScheduler | `std::priority_queue<,std::vector>` | Logarithimc | Logarithims | 24 bytes | 0 |
+------------------------+-------------------------------------+-------------+--------------+----------+--------------+

View File

@@ -14,8 +14,8 @@ The |ns3| logging facility can be used to monitor or debug the progress
of simulation programs. Logging output can be enabled by program statements
in your ``main()`` program or by the use of the ``NS_LOG`` environment variable.
Logging statements are not compiled into optimized builds of |ns3|. To use
logging, one must build the (default) debug build of |ns3|.
Logging statements are not compiled into ``optimized`` builds of |ns3|. To use
logging, one must use the ``default`` or ``debug`` build profiles of |ns3|.
The project makes no guarantee about whether logging output will remain
the same over time. Users are cautioned against building simulation output
@@ -29,21 +29,20 @@ Overview
execution events, such as the occurrence of simulation events or the
use of a particular function.
For example, this code snippet is from ``Ipv4L3Protocol::IsDestinationAddress()``::
For example, this code snippet is from ``TcpSocketBase::EnterCwr()`` and informs the user that
the model is reducing the congestion window and changing state::
if (address == iaddr.GetBroadcast())
{
NS_LOG_LOGIC("For me (interface broadcast address)");
return true;
}
NS_LOG_INFO("Enter CWR recovery mode; set cwnd to " << m_tcb->m_cWnd << ", ssthresh to "
<< m_tcb->m_ssThresh << ", recover to "
<< m_recover);
If logging has been enabled for the ``Ipv4L3Protocol`` component at a severity
of ``LOGIC`` or above (see below about log severity), the statement
of ``INFO`` or above (see below about log severity), the statement
will be printed out; otherwise, it will be suppressed.
The logging implementation is enabled in ``debug`` and ``default``
builds, but disabled in all other build profiles,
so has no impact of execution speed.
so that it does not impact the execution speed of more optimized profiles.
You can try the example program `log-example.cc` in `src/core/example`
with various values for the `NS_LOG` environment variable to see the
@@ -138,21 +137,21 @@ Severity and Level Options
Individual messages belong to a single "severity class," set by the macro
creating the message. In the example above,
``NS_LOG_LOGIC(..)`` creates the message in the ``LOG_LOGIC`` severity class.
``NS_LOG_INFO(..)`` creates the message in the ``LOG_INFO`` severity class.
The following severity classes are defined as ``enum`` constants:
================ =====================================
================ =========================================================
Severity Class Meaning
================ =====================================
================ =========================================================
``LOG_NONE`` The default, no logging
``LOG_ERROR`` Serious error messages only
``LOG_WARN`` Warning messages
``LOG_DEBUG`` For use in debugging
``LOG_INFO`` Informational
``LOG_INFO`` Info about the model changing state
``LOG_FUNCTION`` Function tracing
``LOG_LOGIC`` Control flow tracing within functions
================ =====================================
``LOG_LOGIC`` For tracing key decision points or branches in a function
``LOG_DEBUG`` For use in debugging
================ =========================================================
Typically one wants to see messages at a given severity class *and higher*.
This is done by defining inclusive logging "levels":
@@ -162,10 +161,10 @@ Level Meaning
====================== ===========================================
``LOG_LEVEL_ERROR`` Only ``LOG_ERROR`` severity class messages.
``LOG_LEVEL_WARN`` ``LOG_WARN`` and above.
``LOG_LEVEL_DEBUG`` ``LOG_DEBUG`` and above.
``LOG_LEVEL_INFO`` ``LOG_INFO`` and above.
``LOG_LEVEL_FUNCTION`` ``LOG_FUNCTION`` and above.
``LOG_LEVEL_LOGIC`` ``LOG_LOGIC`` and above.
``LOG_LEVEL_DEBUG`` ``LOG_DEBUG`` and above.
``LOG_LEVEL_ALL`` All severity classes.
``LOG_ALL`` Synonym for ``LOG_LEVEL_ALL``
====================== ===========================================
@@ -178,10 +177,10 @@ Class Level
============ =================
``error`` ``level_error``
``warn`` ``level_warn``
``debug`` ``level_debug``
``info`` ``level_info``
``function`` ``level_function``
``logic`` ``level_logic``
``debug`` ``level_debug``
.. | ``level_all``
| ``all``
| ``*``
@@ -193,8 +192,8 @@ For example, ``NS_LOG="*=warn"`` won't output messages with severity ``error``.
``debug`` and above.
Severity classes and levels can be combined with the \`|' operator:
``NS_LOG="*=level_warn|logic"`` will output messages at severity levels
``error``, ``warn`` and ``logic``.
``NS_LOG="*=level_warn|debug"`` will output messages at severity levels
``error``, ``warn`` and ``debug``, but not ``info``, ``function``, or ``logic``.
The ``NS_LOG`` severity level wildcard \`*' and ``all``
are synonyms for ``level_all``.
@@ -265,10 +264,10 @@ class (``|prefix_level``).
Scratch Simulator
[ERROR] error message
[WARN] warn message
[DEBUG] debug message
[INFO] info message
[FUNCT] function message
[LOGIC] logic message
[DEBUG] debug message
Time Prefix
###########
@@ -415,10 +414,10 @@ Logging Macros
``LOG_NONE`` (none needed)
``LOG_ERROR`` ``NS_LOG_ERROR(...);``
``LOG_WARN`` ``NS_LOG_WARN(...);``
``LOG_DEBUG`` ``NS_LOG_DEBUG(...);``
``LOG_INFO`` ``NS_LOG_INFO(...);``
``LOG_FUNCTION`` ``NS_LOG_FUNCTION(...);``
``LOG_LOGIC`` ``NS_LOG_LOGIC(...);``
``LOG_DEBUG`` ``NS_LOG_DEBUG(...);``
================ ==========================
The macros function as output streamers, so anything you can send to
@@ -449,15 +448,21 @@ severity. This macro does not use any of the prefix options. Recall
that logging is only enabled in ``debug``, ``default`` and ``relwithdebinfo``
builds, so this macro will only produce output in the same builds.
The |ns3| model libraries do not typically use the ``NS_LOG_UNCOND(...)`` macro;
it is provided for users for assistance with debugging.
Guidelines
==========
* Start every class method with ``NS_LOG_FUNCTION(this << args...);``
* Start every significant class method with ``NS_LOG_FUNCTION(this << args...);``
This enables easy function call tracing.
* Except: don't log operators or explicit copy constructors,
* Exception 1: don't log operators or explicit copy constructors,
since these will cause infinite recursion and stack overflow.
* Exception 2: For simple methods such as getters, avoid function
logging because it tends to overload the logging output.
* For methods without arguments use the same form:
``NS_LOG_FUNCTION(this);``
@@ -467,26 +472,49 @@ Guidelines
* Without arguments use ``NS_LOG_FUNCTION_NOARGS();``
* Use ``NS_LOG_ERROR`` for serious error conditions that probably
invalidate the simulation execution.
invalidate the simulation execution. Note that in |ns3|, we typically
abort the simulation under such conditions rather than log it as
an error (which might go undetected if the user is not using logging).
The ``NS_ABORT_MSG_IF/UNLESS(cond,msg)`` macros and variants, as well
as the lower-level ``NS_FATAL_ERROR(msg)`` macro, can be used to terminate
the simulation with an error message.
* Use ``NS_LOG_WARN`` for unusual conditions that may be correctable.
* Use ``NS_LOG_WARN`` for unusual conditions that are not considered
invalid. An example might be that some resource has been exhausted
(e.g., the DHCP server has run out of addresses to allocate).
Please give some hints as to the nature of the problem and how
it might be corrected.
* ``NS_LOG_DEBUG`` is usually used in an *ad hoc* way to understand
the execution of a model.
* Use ``NS_LOG_INFO`` for events that cause a state change in the model.
Avoid using it for logging periodic events that are not causing a
state change (e.g., a Wi-Fi beacon is sent, but all nodes are already
associated to the access point). Try to be efficient in using it;
for instance, sending a message is usually an important state change event,
but try to capture this event with one single log message at the ``INFO``
level rather than multiple. If multiple log messages are desired to
fully capture the event and all of its consequences, use ``DEBUG`` level
for the additional messages. The intent of this log level is to allow a
user to examine the normal operation of a model without becoming overwhelmed
by the output.
* Use ``NS_LOG_INFO`` for additional information about the execution,
such as the size of a data structure when adding/removing from it.
* ``NS_LOG_LOGIC`` is used to trace important logic branches or decision points
within a function, without dumping all details of the variable states,
called function return values, individual iterations, etc. It may be useful
to think of it as a less granular level of function logging than ``DEBUG,``
and may not be used by all models (some authors may choose to only use
``DEBUG`` level for full logging).
* Use ``NS_LOG_LOGIC`` to trace important logic branches within a function.
* ``NS_LOG_DEBUG`` is usually used for full voluminous debugging, and contains
much more information than ``NS_LOG_INFO``, such as the detailed execution
logic of functions and the values that variables take within those functions.
* Test that your logging changes do not break the code.
Run some example programs with all log components turned on (e.g.
``NS_LOG="***"``).
* Use an explicit cast for any variable of type uint8_t or int8_t,
e.g., ``NS_LOG_LOGIC("Variable i is " << static_cast<int>(i));``.
* Use a unary operator (preferred) or an explicit cast for any variable of type uint8_t or int8_t,
e.g., ``NS_LOG_DEBUG("Variable i is " << +i);``.
e.g., ``NS_LOG_DEBUG("Variable i is " << static_cast<int>(i));`` or
Without the cast, the integer is interpreted as a char, and the result
will be most likely not in line with the expectations.
This is a well documented C++ 'feature'.

View File

@@ -101,10 +101,25 @@ Here is some example code that is written in Python and that runs |ns3|, which i
Running Python Scripts
**********************
The main prerequisite is to install `cppyy`. Depending on how you may manage
For users that want to change upstream modules in C++ and got a copy of
ns-3 by Git cloning the ns-3-dev repository, or downloaded the
ns3-allinone package, or is using bake, continue to the next section.
`Note: models implemented in Python are not available from C++. If you want
your model to be available for both C++ and Python users, you must implement
it in C++.`
For users that want to exclusively run simulation scenarios and implement
simple modules in python, jump to the `Using the pip wheel`_ section.
Using the bindings from the ns-3 source
=======================================
The main prerequisite is to install `cppyy`, with version no later than 2.4.2.
Depending on how you may manage
Python extensions, the installation instructions may vary, but you can first
check if it installed by seeing if the `cppyy` module can be
successfully imported:
successfully imported and the version is no later than 2.4.2:
.. sourcecode:: bash
@@ -113,6 +128,8 @@ successfully imported:
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cppyy
>>> print("%s" % cppyy.__version)
2.4.2
>>>
If not, you may try to install via `pip` or whatever other manager you are
@@ -120,7 +137,7 @@ using; e.g.:
.. sourcecode:: bash
$ python3 -m pip install --user cppyy
$ python3 -m pip install --user cppyy==2.4.2
First, we need to enable the build of Python bindings:
@@ -135,13 +152,13 @@ To run example programs, there are two ways to use ns3 to take care of this. On
.. sourcecode:: bash
$ ./ns3 shell
$ python3 examples/wireless/mixed-wireless.py
$ python3 examples/wireless/mixed-wired-wireless.py
and the other is to use the 'run' option to ns3:
.. sourcecode:: bash
$ ./ns3 run examples/wireless/mixed-wireless.py
$ ./ns3 run examples/wireless/mixed-wired-wireless.py
Use the ``--no-build`` option to run the program without invoking a project rebuild.
This option may be useful to improve execution time when running the same program
@@ -149,14 +166,14 @@ repeatedly but with different arguments, such as from scripts.
.. sourcecode:: bash
$ ./ns3 run --no-build examples/wireless/mixed-wireless.py
$ ./ns3 run --no-build examples/wireless/mixed-wired-wireless.py
To run a python script under the C debugger:
.. sourcecode:: bash
$ ./ns3 shell
$ gdb --args python3 examples/wireless/mixed-wireless.py
$ gdb --args python3 examples/wireless/mixed-wired-wireless.py
To run your own Python script that calls |ns3| and that has this path, ``/path/to/your/example/my-script.py``, do the following:
@@ -165,6 +182,133 @@ To run your own Python script that calls |ns3| and that has this path, ``/path/t
$ ./ns3 shell
$ python3 /path/to/your/example/my-script.py
Using the pip wheel
===================
Starting from ns-3.38, we provide a pip wheel for Python users using Linux.
.. sourcecode:: bash
$ pip install --user ns3
You can select a specific ns-3 version by specifying the wheel version.
Specifying a nonexistent version will result in an error message listing the available versions.
.. sourcecode:: bash
$ pip install --user ns3==3.37
Defaulting to user installation because normal site-packages is not writeable
ERROR: Could not find a version that satisfies the requirement ns3==3.37 (from versions: 3.37.post415)
ERROR: No matching distribution found for ns3==3.37
You can also specify you want at least a specific version (e.g. which shipped a required feature).
.. sourcecode:: bash
$ pip install --user ns3>=3.37
Defaulting to user installation because normal site-packages is not writeable
Requirement already satisfied: ns3==3.37.post415 in /home/username/.local/lib/python3.10/site-packages (3.37.post415)
Requirement already satisfied: cppyy in /home/username/.local/lib/python3.10/site-packages (from ns3==3.37.post415) (2.4.2)
Requirement already satisfied: cppyy-backend==1.14.10 in /home/username/.local/lib/python3.10/site-packages (from cppyy->ns3==3.37.post415) (1.14.10)
Requirement already satisfied: CPyCppyy==1.12.12 in /home/username/.local/lib/python3.10/site-packages (from cppyy->ns3==3.37.post415) (1.12.12)
Requirement already satisfied: cppyy-cling==6.27.1 in /home/username/.local/lib/python3.10/site-packages (from cppyy->ns3==3.37.post415) (6.27.1)
To check if the pip wheel was installed, use the pip freeze command to list the installed packages,
then grep ns3 to filter the line of interest.
.. sourcecode:: bash
$ pip freeze | grep ns3
ns3==3.37.post415
.. _ns3 wheel: https://pypi.org/project/ns3/#history
The available versions are also listed on the Pypi page for the `ns3 wheel`_.
After installing it, you can start using ns-3 right away. For example, using the following script.
::
from ns import ns
ns.cppyy.cppdef("""
using namespace ns3;
Callback<void,Ptr<const Packet>,const Address&,const Address&>
make_sinktrace_callback(void(*func)(Ptr<Packet>,Address,Address))
{
return MakeCallback(func);
}
""")
# Define the trace callback
def SinkTracer(packet: ns.Packet, src_address: ns.Address, dst_address: ns.Address) -> None:
print(f"At {ns.Simulator.Now().GetSeconds():.0f}s, '{dst_address}' received packet"
f" with {packet.__deref__().GetSerializedSize()} bytes from '{src_address}'")
# Create two nodes
csmaNodes = ns.network.NodeContainer()
csmaNodes.Create(2)
# Connect the two nodes
csma = ns.csma.CsmaHelper()
csma.SetChannelAttribute("DataRate", ns.core.StringValue("100Mbps"))
csma.SetChannelAttribute("Delay", ns.core.TimeValue(ns.core.NanoSeconds(6560)))
csmaDevices = csma.Install(csmaNodes)
# Install the internet stack
stack = ns.internet.InternetStackHelper()
stack.Install(csmaNodes)
# Assign Ipv4 addresses
address = ns.internet.Ipv4AddressHelper()
address.SetBase(ns.network.Ipv4Address("10.1.2.0"), ns.network.Ipv4Mask("255.255.255.0"))
csmaInterfaces = address.Assign(csmaDevices)
# Setup applications
echoServer = ns.applications.UdpEchoServerHelper(9)
serverApps = echoServer.Install(csmaNodes.Get(0))
serverApps.Start(ns.core.Seconds(1.0))
serverApps.Stop(ns.core.Seconds(10.0))
echoClient = ns.applications.UdpEchoClientHelper(csmaInterfaces.GetAddress(0).ConvertTo(), 9)
echoClient.SetAttribute("MaxPackets", ns.core.UintegerValue(10))
echoClient.SetAttribute("Interval", ns.core.TimeValue(ns.core.Seconds(1.0)))
echoClient.SetAttribute("PacketSize", ns.core.UintegerValue(1024))
clientApps = echoClient.Install(csmaNodes.Get(1))
clientApps.Start(ns.core.Seconds(2.0))
clientApps.Stop(ns.core.Seconds(10.0))
# Populate routing tables
ns.internet.Ipv4GlobalRoutingHelper.PopulateRoutingTables()
# Setup the trace callback
sinkTraceCallback = ns.cppyy.gbl.make_sinktrace_callback(SinkTracer)
serverApps.Get(0).__deref__().TraceConnectWithoutContext("RxWithAddresses", sinkTraceCallback);
# Set the simulation duration to 11 seconds
ns.Simulator.Stop(ns.Seconds(11))
# Run the simulator
ns.Simulator.Run()
ns.Simulator.Destroy()
Which should print:
.. sourcecode:: bash
At 2s, '04-07-00:00:00:00:09:00:00' received packet with 60 bytes from '04-07-0a:01:02:02:01:c0:00'
At 3s, '04-07-00:00:00:00:09:00:00' received packet with 60 bytes from '04-07-0a:01:02:02:01:c0:00'
At 4s, '04-07-00:00:00:00:09:00:00' received packet with 60 bytes from '04-07-0a:01:02:02:01:c0:00'
At 5s, '04-07-00:00:00:00:09:00:00' received packet with 60 bytes from '04-07-0a:01:02:02:01:c0:00'
At 6s, '04-07-00:00:00:00:09:00:00' received packet with 60 bytes from '04-07-0a:01:02:02:01:c0:00'
At 7s, '04-07-00:00:00:00:09:00:00' received packet with 60 bytes from '04-07-0a:01:02:02:01:c0:00'
At 8s, '04-07-00:00:00:00:09:00:00' received packet with 60 bytes from '04-07-0a:01:02:02:01:c0:00'
At 9s, '04-07-00:00:00:00:09:00:00' received packet with 60 bytes from '04-07-0a:01:02:02:01:c0:00'
Caveats
*******
@@ -382,6 +526,240 @@ example. There is no structured documentation for the Python bindings
like there is Doxygen for the C++ API, but the Doxygen can be consulted
to understand how the C++ API works.
To inspect what function and classes are available, you can use
the ``dir`` function. Examples below:
.. sourcecode:: bash
>>> print(dir(ns.Simulator))
['Cancel', 'Destroy', 'GetContext', 'GetDelayLeft', 'GetEventCount', 'GetImplementation', 'GetMaximumSimulationTime', 'GetSystemId', 'IsExpired', 'IsFinished', 'NO_CONTEXT', 'Now', 'Remove', 'Run', 'Schedule', 'ScheduleDestroy', 'ScheduleNow', 'ScheduleWithContext', 'SetImplementation', 'SetScheduler', 'Stop', '__add__', '__assign__', '__bool__', '__class__', '__delattr__', '__destruct__', '__dict__', '__dir__', '__dispatch__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__invert__', '__le__', '__lt__', '__module__', '__mul__', '__ne__', '__neg__', '__new__', '__pos__', '__python_owns__', '__radd__', '__reduce__', '__reduce_ex__', '__repr__', '__reshape__', '__rmul__', '__rsub__', '__rtruediv__', '__setattr__', '__sizeof__', '__smartptr__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__weakref__']
>>> print(dir(ns.DefaultSimulatorImpl))
['AggregateObject', 'Cancel', 'Destroy', 'Dispose', 'GetAggregateIterator', 'GetAttribute', 'GetAttributeFailSafe', 'GetContext', 'GetDelayLeft', 'GetEventCount', 'GetInstanceTypeId', 'GetMaximumSimulationTime', 'GetObject', 'GetReferenceCount', 'GetSystemId', 'GetTypeId', 'Initialize', 'IsExpired', 'IsFinished', 'IsInitialized', 'Now', 'PreEventHook', 'Ref', 'Remove', 'Run', 'Schedule', 'ScheduleDestroy', 'ScheduleNow', 'ScheduleWithContext', 'SetAttribute', 'SetAttributeFailSafe', 'SetScheduler', 'Stop', 'TraceConnect', 'TraceConnectWithoutContext', 'TraceDisconnect', 'TraceDisconnectWithoutContext', 'Unref', '__add__', '__assign__', '__bool__', '__class__', '__delattr__', '__destruct__', '__dict__', '__dir__', '__dispatch__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__invert__', '__le__', '__lt__', '__module__', '__mul__', '__ne__', '__neg__', '__new__', '__pos__', '__python_owns__', '__radd__', '__reduce__', '__reduce_ex__', '__repr__', '__reshape__', '__rmul__', '__rsub__', '__rtruediv__', '__setattr__', '__sizeof__', '__smartptr__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__weakref__']
>>> print(dir(ns.Time))
['AUTO', 'As', 'Compare', 'D', 'FS', 'From', 'FromDouble', 'FromInteger', 'GetDays', 'GetDouble', 'GetFemtoSeconds', 'GetHours', 'GetInteger', 'GetMicroSeconds', 'GetMilliSeconds', 'GetMinutes', 'GetNanoSeconds', 'GetPicoSeconds', 'GetResolution', 'GetSeconds', 'GetTimeStep', 'GetYears', 'H', 'IsNegative', 'IsPositive', 'IsStrictlyNegative', 'IsStrictlyPositive', 'IsZero', 'LAST', 'MIN', 'MS', 'Max', 'Min', 'NS', 'PS', 'RoundTo', 'S', 'SetResolution', 'StaticInit', 'To', 'ToDouble', 'ToInteger', 'US', 'Y', '__add__', '__assign__', '__bool__', '__class__', '__delattr__', '__destruct__', '__dict__', '__dir__', '__dispatch__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__invert__', '__le__', '__lt__', '__module__', '__mul__', '__ne__', '__neg__', '__new__', '__pos__', '__python_owns__', '__radd__', '__reduce__', '__reduce_ex__', '__repr__', '__reshape__', '__rmul__', '__rsub__', '__rtruediv__', '__setattr__', '__sizeof__', '__smartptr__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__weakref__']
To get more information about expected arguments, you can use the ``help``
function.
.. sourcecode:: bash
>>> help(ns.DefaultSimulatorImpl)
class DefaultSimulatorImpl(SimulatorImpl)
| Method resolution order:
| DefaultSimulatorImpl
| SimulatorImpl
| Object
| SimpleRefCount<ns3::Object,ns3::ObjectBase,ns3::ObjectDeleter>
| ObjectBase
| cppyy.gbl.CPPInstance
| builtins.object
|
| Methods defined here:
|
| Cancel(...)
| void ns3::DefaultSimulatorImpl::Cancel(const ns3::EventId& id)
|
| Destroy(...)
| void ns3::DefaultSimulatorImpl::Destroy()
|
| GetContext(...)
| unsigned int ns3::DefaultSimulatorImpl::GetContext()
|
| GetDelayLeft(...)
| ns3::Time ns3::DefaultSimulatorImpl::GetDelayLeft(const ns3::EventId& id)
|
| GetEventCount(...)
| unsigned long ns3::DefaultSimulatorImpl::GetEventCount()
|
| GetMaximumSimulationTime(...)
| ns3::Time ns3::DefaultSimulatorImpl::GetMaximumSimulationTime()
|
| GetSystemId(...)
| unsigned int ns3::DefaultSimulatorImpl::GetSystemId()
|
| GetTypeId(...)
| static ns3::TypeId ns3::DefaultSimulatorImpl::GetTypeId()
|
| IsExpired(...)
| bool ns3::DefaultSimulatorImpl::IsExpired(const ns3::EventId& id)
|
| IsFinished(...)
| bool ns3::DefaultSimulatorImpl::IsFinished()
|
| Now(...)
| ns3::Time ns3::DefaultSimulatorImpl::Now()
|
| Remove(...)
| void ns3::DefaultSimulatorImpl::Remove(const ns3::EventId& id)
|
| Run(...)
| void ns3::DefaultSimulatorImpl::Run()
Pip wheel packaging
*******************
This section is meant exclusively for ns-3 maintainers and ns-3
users that want to redistribute their work as wheels for python.
The packaging process is defined in the following GitLab job.
The job is split into blocks explained below.
The manylinux image provides an old glibc compatible with most modern Linux
distributions, resulting on a pip wheel that is compatible across distributions.
.. sourcecode:: yaml
.manylinux-pip-wheel:
image: quay.io/pypa/manylinux_2_28_x86_64
Then we install the required toolchain and dependencies necessary for both
ns-3 (e.g. libxml2, gsl, sqlite, gtk, etc) and for the bindings and packaging
(e.g. setuptools, wheel, auditwheel, cmake-build-extension, cppyy).
.. sourcecode:: yaml
# Install minimal toolchain
- yum install -y libxml2-devel gsl-devel sqlite-devel gtk3-devel boost-devel
# Create Python venv
- $PYTHON -m venv ./venv
- . ./venv/bin/activate
# Upgrade the pip version to reuse the pre-build cppyy
- $PYTHON -m pip install pip --upgrade
- $PYTHON -m pip install setuptools setuptools_scm --upgrade
- $PYTHON -m pip install wheel auditwheel cmake-build-extension cppyy
The project is then configured loading the configuration settings defined
in the ``ns-3-dev/setup.py`` file.
.. sourcecode:: yaml
# Configure and build wheel
- $PYTHON setup.py bdist_wheel build_ext "-DNS3_USE_LIB64=TRUE"
At this point, we have a wheel that only works in the current system,
since external libraries are not shipped.
Auditwheel needs to be called resolve and copy external libraries
that we need to ship along the ns-3 module libraries (e.g. libxml2, sqlite3,
gtk, gsl, etc). However, we need to prevent auditwheel from shipping copies of
the libraries built by the ns-3 project. A list of excluded libraries is generated
by the script ``ns-3-dev/build-support/pip-wheel/auditwheel-exclude-list.py``.
.. sourcecode:: yaml
- export EXCLUDE_INTERNAL_LIBRARIES=`$PYTHON ./build-support/pip-wheel/auditwheel-exclude-list.py`
# Bundle in shared libraries that were not explicitly packaged or depended upon
- $PYTHON -m auditwheel repair ./dist/*whl -L /lib64 $EXCLUDE_INTERNAL_LIBRARIES
At this point, we should have our final wheel ready, but we need to check if it works
before submitting it to Pypi servers.
We first clean the environment and uninstall the packages previously installed.
.. sourcecode:: yaml
# Clean the build directory
- $PYTHON ./ns3 clean
# Clean up the environment
- deactivate
- rm -R ./venv
# Delete toolchain to check if required headers/libraries were really packaged
- yum remove -y libxml2-devel gsl-devel sqlite-devel gtk3-devel boost-devel
Then we can install our newly built wheel and test it.
.. sourcecode:: yaml
# Install wheel
- $PYTHON -m pip install ./wheelhouse/*whl
- $PYTHON -m pip install matplotlib numpy
# Test the bindings
- $PYTHON ./utils/python-unit-tests.py
- $PYTHON ./examples/realtime/realtime-udp-echo.py
- $PYTHON ./examples/routing/simple-routing-ping6.py
- $PYTHON ./examples/tutorial/first.py
- $PYTHON ./examples/tutorial/second.py
- $PYTHON ./examples/tutorial/third.py
- $PYTHON ./examples/wireless/wifi-ap.py
- $PYTHON ./examples/wireless/mixed-wired-wireless.py
- $PYTHON ./src/bridge/examples/csma-bridge.py
- $PYTHON ./src/brite/examples/brite-generic-example.py
- $PYTHON ./src/core/examples/sample-simulator.py
- $PYTHON ./src/core/examples/sample-rng-plot.py --not-blocking
- $PYTHON ./src/click/examples/nsclick-simple-lan.py
- $PYTHON ./src/flow-monitor/examples/wifi-olsr-flowmon.py
- $PYTHON ./src/flow-monitor/examples/flowmon-parse-results.py output.xml
- $PYTHON ./src/openflow/examples/openflow-switch.py
If all programs finish normally, the bindings are working as expected,
and will be saved as an artifact.
.. sourcecode:: yaml
artifacts:
paths:
- wheelhouse/*.whl
One can use ``gitlab-ci-local`` to build the pip wheels locally. After that, the wheels
will be stored in ``.gitlab-ci-local/artifacts/manylinux-pip-wheel-py3Lg10/wheelhouse``
(for Python 3.10).
The wheel names are based on the number of commits since the latest release.
For example, a wheel built 415 after the release 3.37 will be named
``ns3-3.37.post415-cp310-cp310-manylinux_2_28_x86_64.whl``.
The wheel name (``ns3``) is defined in the ``/ns-3-dev/setup.cfg`` file, and that
name should match the build prefix specified in ``/ns-3-dev/setup.py`` file.
The ``cp310-cp310`` indicates that this wheel is compatible from Python 3.10 and up to Python 3.10.
The ``manylinux_2_28`` indicates that this is a manylinux wheel targeting glibc 2.28.
The ``x86_64`` indicates that this is a 64-bit build targeting Intel/AMD processors.
.. _Pypi: https://pypi.org/account/register/
.. _Twine: https://twine.readthedocs.io/en/stable/
After packaging, we can either deploy that wheel locally or upload the wheel to Pypi for general availability.
Local deployment
****************
To deploy a wheel locally, simply share the wheel file across the desired machines.
Then install the wheel and its dependencies running the following command:
.. sourcecode:: bash
$ pip install *.whl
Publishing the pip wheel via Pypi
*********************************
Publishing a pip wheel requires a `Pypi`_ account.
After creating your account, install `Twine`_, an utility to upload the wheel to Pypi.
Then run twine to upload the wheel to the Pypi servers.
.. sourcecode:: bash
$ twine upload .gitlab-ci-local/artifacts/manylinux-pip-wheel-py3Lg10/wheelhouse/*.whl
Enter your Pypi username and password as requested.
Your wheel should be up and running. Give it a try just to make sure.
For the upstream pip wheel, try:
.. sourcecode:: bash
$ pip install ns3
$ python3 -c "from ns import ns; print(ns.Simulator.Now())"
Historical Information
**********************

View File

@@ -423,8 +423,6 @@ We are going to use the aodv module as an example:
.. sourcecode:: python3
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
def build(bld):
module = bld.create_ns3_module('aodv', ['internet', 'wifi'])
module.includes = '.'
@@ -521,8 +519,6 @@ steps. We should have something like the following:
.. sourcecode:: python3
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
def build(bld):
obj = bld.create_ns3_program('aodv',
['wifi', 'internet', 'aodv', 'internet-apps'])

View File

@@ -256,7 +256,7 @@ It is strongly suggested to rebase your branch on top of upstream/master (or mas
This helps reviewing the code changes proposed in the branch. merge it without conflicts, and it increase the speed of the GitLab CI.
GitLab CI (Continuous Integration)
+++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++
GitLab provides a CI (Continuous Integration) feature. Shortly put, after every push the code is built and tests are run in one of the GitLab servers.

View File

@@ -5,7 +5,7 @@
Working with gitlab-ci-local
----------------------------
.. _continuos integration (CI) : https://docs.gitlab.com/ee/ci/
.. _continuous integration (CI) : https://docs.gitlab.com/ee/ci/
.. _pipelines : https://docs.gitlab.com/ee/ci/introduction/index.html#continuous-integration
.. _daily and weekly pipelines : https://gitlab.com/nsnam/ns-3-dev/-/pipeline_schedules
.. _crypto miners abuse : https://about.gitlab.com/blog/2021/05/17/prevent-crypto-mining-abuse/
@@ -15,7 +15,7 @@ Working with gitlab-ci-local
.. _rootless mode : https://docs.docker.com/engine/security/rootless/
The ns-3 project repository is currently hosted in GitLab, which includes
`continuos integration (CI)`_ tools to automate build, tests, packaging and
`continuous integration (CI)`_ tools to automate build, tests, packaging and
distribution of software. The CI works based on jobs, that are defined
on YAML files.

View File

@@ -98,7 +98,6 @@ SOURCES = \
$(SRC)/spectrum/doc/spectrum.rst \
$(SRC)/netanim/doc/animation.rst \
$(SRC)/flow-monitor/doc/flow-monitor.rst \
$(SRC)/wave/doc/wave.rst \
$(SRC)/sixlowpan/doc/sixlowpan.rst \
$(SRC)/lr-wpan/doc/lr-wpan.rst \
@@ -161,6 +160,10 @@ SOURCEFIGS = \
$(SRC)/wifi/doc/source/figures/wifi-11g-p-1500-infrastructure-r-6-min-5-max-50-step-5-throughput.eps \
$(SRC)/wifi/doc/source/figures/default-table-based-error-model-validation.eps \
$(SRC)/wifi/doc/source/figures/error-models-comparison.eps \
$(SRC)/wifi/doc/source/figures/spectrum-wifi-phy-multiple-interfaces.pdf \
$(SRC)/wifi/doc/source/figures/spectrum-wifi-phy-multiple-interfaces.png \
$(SRC)/wifi/doc/source/figures/cca-channel-switching-multiple-interfaces.pdf \
$(SRC)/wifi/doc/source/figures/cca-channel-switching-multiple-interfaces.png \
$(SRC)/wimax/doc/WimaxArchitecture.dia \
$(SRC)/lte/doc/source/figures/epc-ctrl-arch.dia \
$(SRC)/lte/doc/source/figures/epc-data-flow-dl.dia \

View File

@@ -73,9 +73,9 @@ copyright = u'2006-2019'
# built documents.
#
# The short X.Y version.
version = u'ns-3.38'
version = u'ns-3.39'
# The full version, including alpha/beta/rc tags.
release = u'ns-3.38'
release = u'ns-3.39'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@@ -59,6 +59,5 @@ from the ``doc/`` directory of each module. Source file column width is 100 col
topology
traffic-control
uan
wave
wifi
wimax

View File

@@ -74,6 +74,9 @@
<div id="mDocs"
onmouseover="mcancelclosetime()"
onmouseout="mclosetime()">
<a id="ns3_ins"
href="/docs/installation/html/index.html"
>Installation</a><br/>
<a id="ns3_man"
href="/docs/manual/html/index.html"
>Manual</a><br/>

View File

@@ -70,7 +70,7 @@ $extrastylesheet
<div id="mDocs"
onmouseover="mcancelclosetime()"
onmouseout="mclosetime()">
<a id="ns3_man"
<a id="ns3_ins"
href="/docs/installation/html/index.html"
>Installation</a><br/>
<a id="ns3_man"

View File

@@ -61,7 +61,7 @@ div.footer a {
}
div.related {
background-color: {{ theme_relbarbgcolor }};
background-image: linear-gradient(to bottom, white 0%, transparent 80%);
line-height: 30px;
color: {{ theme_relbartextcolor }};
}
@@ -142,9 +142,16 @@ div.sphinxsidebar a {
}
div.sphinxsidebar input {
border: 1px solid {{ theme_sidebarlinkcolor }};
border: 2px solid {{ theme_sidebarlinkcolor }};
font-family: sans-serif;
font-size: 1em;
font-weight: bold;
background: #f0f1e8;
}
div.sphinxsidebar input[type="submit"] {
background: {{ theme_sidebarlinkcolor }};
color: {{theme_sidebartextcolor}};
}
{% if theme_collapsiblesidebar|tobool %}
@@ -196,12 +203,12 @@ div.body h4,
div.body h5,
div.body h6 {
font-family: {{ theme_headfont }};
background-color: {{ theme_headbgcolor }};
font-weight: normal;
color: {{ theme_headtextcolor }};
background-color: transparent;
font-weight: bold;
border-bottom: 1px solid #ccc;
margin: 20px -20px 10px -20px;
padding: 3px 0 3px 10px;
padding: 10px 8px;
border-left: 6px solid #d7d4d2;
}
div.body h1 { margin-top: 0; font-size: 200%; }
@@ -273,7 +280,7 @@ p.admonition-title:after {
pre {
padding: 5px;
background-color: {{ theme_codebgcolor }};
background-color: transparent;
color: {{ theme_codetextcolor }};
line-height: 120%;
border: 1px solid #ac9;

View File

@@ -44,6 +44,7 @@ var ns3_man = ns3_rel + "manual/" + ns3_index;
var ns3_mod = ns3_rel + "models/" + ns3_index;
var ns3_tut = ns3_rel + "tutorial/" + ns3_index;
var ns3_con = ns3_rel + "contributing/" + ns3_index;
var ns3_ins = ns3_rel + "installation/" + ns3_index;
function ns3_write_links() {
document.getElementById("ns3_home1").href = ns3_home;
@@ -52,6 +53,7 @@ function ns3_write_links() {
document.getElementById("ns3_man" ).href = ns3_man;
document.getElementById("ns3_mod" ).href = ns3_mod;
document.getElementById("ns3_con" ).href = ns3_con;
document.getElementById("ns3_ins" ).href = ns3_ins;
document.getElementById("ns3_wiki" ).href = ns3_wiki;
document.getElementById("ns3_api" ).href = ns3_api;
document.getElementById("ns3_bugs" ).href = ns3_bugs;

View File

@@ -10,16 +10,27 @@ dl {
font-size: 12px;
}
/* Dark mode is not supported in Doxygen versions earlier than 1.9.6
/* Dark mode is not supported in Doxygen versions earlier than 1.9.6 */
@media (prefers-color-scheme: dark) {
body,
table,
div,
p,
dl {
dl,
div.body,
div.sphinxsidebar h3,
div.sphinxsidebar h4 ,
div.sphinxsidebar h3 a{
color: ivory;
background:black;
}
} */
div.sphinxsidebar input{
background: #2c2d24;
}
div.related{
background-image: linear-gradient(to bottom, #66696a 0%, transparent 80%);
}
}
a {
color: #91A501;
@@ -27,6 +38,7 @@ a {
}
/* Sphinx headings */
/*
div.body h1,
div.body h2,
div.body h3,
@@ -35,6 +47,7 @@ div.body h5,
div.body h6 {
background-image: url('nav_f.png');
}
*/
/* Sphinx figure captions */
p.caption {
@@ -51,9 +64,11 @@ p.caption {
}
/* Sphinx nav links bar (relbar) */
/*
div.related {
background-image: url('tab_b.png')
}
*/
div.related h3 {
display: none;
@@ -110,8 +125,8 @@ div.sphinxsidebar a {
}
#projecttext {
align: left;
font-color: white;
text-align: left;
color: white;
padding-left: 2em;
width: 250px;
}

View File

@@ -42,7 +42,7 @@ sidebarbtncolor = #D5D5D5
footerbgcolor = #D5D5D5
footertextcolor = #364D7C
codebgcolor = ##FBFCFD
codebgcolor = #FBFCFD
codetextcolor = black
bodyfont = 'Lucida Grande', Verdana, Geneva, Arial, sans-serif

View File

@@ -168,30 +168,8 @@ point-to-point link between two nodes and echo a single packet between the
nodes. Let's take a look at that script line by line, so go ahead and open
``first.cc`` in your favorite editor.
Boilerplate
+++++++++++
The first line in the file is an emacs mode line. This tells emacs about the
formatting conventions (coding style) we use in our source code.
::
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
This is always a somewhat controversial subject, so we might as well get it
out of the way immediately. The |ns3| project, like most large
projects, has adopted a coding style to which all contributed code must
adhere. If you want to contribute your code to the project, you will
eventually have to conform to the |ns3| coding standard as described
in the file ``doc/contributing/source/coding-style.rst`` or shown on the project web page
`here
<https://www.nsnam.org/docs/contributing/html/coding-style.html>`_.
We recommend that you, well, just get used to the look and feel of |ns3|
code and adopt this standard whenever you are working with our code. All of
the development team and contributors have done so with various amounts of
grumbling. The emacs mode line above makes it easier to get the formatting
correct if you use the emacs editor.
Copyright
+++++++++
The |ns3| simulator is licensed using the GNU General Public
License version 2. You will see the appropriate GNU legalese at the head of every file
in the |ns3| distribution. Often you will see a copyright notice for

View File

@@ -71,9 +71,9 @@ copyright = u'2006-2019'
# built documents.
#
# The short X.Y version.
version = u'ns-3.38'
version = u'ns-3.39'
# The full version, including alpha/beta/rc tags.
release = u'ns-3.38'
release = u'ns-3.39'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@@ -57,20 +57,11 @@ emacs, or Eclipse) and, if using the development repositories, an
installation of Git source code control system. Most beginning users
need not concern themselves if their configuration reports some missing
optional features of |ns3|, but for those wishing a full installation,
the project provides a wiki that includes pages with many useful hints
and tips. One such page is the "Installation" page, with install instructions
the project provides an installation guide
for various systems, available at
https://www.nsnam.org/wiki/Installation.
https://www.nsnam.org/docs/installation/html/index.html.
The "Prerequisites" section of this wiki page explains which packages are
required to support common |ns3| options, and also provides the
commands used to install them for common Linux or macOS variants.
You may want to take this opportunity to explore the |ns3| wiki
a bit, or the main web site at https://www.nsnam.org, since there is a
wealth of information there.
As of the most recent |ns3| release (ns-3.38), the following tools
As of the most recent |ns3| release (ns-3.39), the following tools
are needed to get started with |ns3|:
============ ===========================================================
@@ -87,7 +78,8 @@ bunzip2 any recent version (to uncompress an |ns3| release)
To check the default version of Python, type ``python -V``. To check
the default version of g++, type ``g++ -v``. If your installation is
missing or too old, please consult the |ns3| installation wiki for guidance.
missing or too old, please consult the |ns3|
`installation guide <https://www.nsnam.org/docs/installation/html/index.html>`_ for guidance.
From this point forward, we are going to assume that the reader is working in
Linux, macOS, or a Linux emulation environment, and has at least the above
@@ -124,21 +116,21 @@ get a copy of a release by typing the following into your Linux shell
$ cd
$ mkdir workspace
$ cd workspace
$ wget https://www.nsnam.org/release/ns-allinone-3.38.tar.bz2
$ tar xjf ns-allinone-3.38.tar.bz2
$ wget https://www.nsnam.org/release/ns-allinone-3.39.tar.bz2
$ tar xjf ns-allinone-3.39.tar.bz2
Notice the use above of the ``wget`` utility, which is a command-line
tool to fetch objects from the web; if you do not have this installed,
you can use a browser for this step.
Following these steps, if you change into the directory
``ns-allinone-3.38``, you should see a number of files and directories
``ns-allinone-3.39``, you should see a number of files and directories
.. sourcecode:: text
$ cd ns-allinone-3.38
$ cd ns-allinone-3.39
$ ls
bake build.py constants.py netanim-3.109 ns-3.38 README.md util.py
bake build.py constants.py netanim-3.109 ns-3.39 README.md util.py
You are now ready to build the base |ns3| distribution and may skip ahead
to the section on building |ns3|.
@@ -188,7 +180,7 @@ release number:
.. sourcecode:: console
$ python3 download.py -n ns-3.38
$ python3 download.py -n ns-3.39
After this step, the additional repositories of |ns3|, bake, pybindgen,
and netanim will be downloaded to the ``ns-3-allinone`` directory.
@@ -257,9 +249,9 @@ distribution of your choice.
There are a few configuration targets available:
1. ``ns-3.38``: the code corresponding to the release
1. ``ns-3.39``: the code corresponding to the release
2. ``ns-3-dev``: a similar module but using the development code tree
3. ``ns-allinone-3.38``: the module that includes other optional features
3. ``ns-allinone-3.39``: the module that includes other optional features
such as bake build system, netanim animator, and pybindgen
4. ``ns-3-allinone``: similar to the released version of the allinone
module, but for development code.
@@ -276,7 +268,7 @@ code either by inspection of the repository list or by going to the
`"ns-3 Releases"
<https://www.nsnam.org/releases>`_
web page and clicking on the latest release link. We'll proceed in
this tutorial example with ``ns-3.38``.
this tutorial example with ``ns-3.39``.
We are now going to use the bake tool to pull down the various pieces of
|ns3| you will be using. First, we'll say a word about running bake.
@@ -305,7 +297,7 @@ Step into the workspace directory and type the following into your shell:
.. sourcecode:: console
$ ./bake.py configure -e ns-allinone-3.38
$ ./bake.py configure -e ns-allinone-3.39
Next, we'll ask bake to check whether we have enough tools to download
various components. Type:
@@ -352,10 +344,10 @@ should yield something like:
>> Searching for system dependency g++ - OK
>> Searching for system dependency cmake - OK
>> Downloading netanim-3.109 - OK
>> Downloading click-ns-3.38 - OK
>> Downloading click-ns-3.37 - OK
>> Downloading BRITE - OK
>> Downloading openflow-dev - OK
>> Downloading ns-3.38 (target directory:ns-3.38) - OK
>> Downloading ns-3.39 (target directory:ns-3.39) - OK
The above suggests that three sources have been downloaded. Check the
``source`` directory now and type ``ls``; one should see:
@@ -364,7 +356,7 @@ The above suggests that three sources have been downloaded. Check the
$ cd source
$ ls
BRITE click-ns-3.37 netanim-3.109 ns-3.38 openflow-dev
BRITE click-ns-3.37 netanim-3.109 ns-3.39 openflow-dev
You are now ready to build the |ns3| distribution.
@@ -394,7 +386,7 @@ native |ns3| build system, CMake, to be introduced later in this tutorial.
If you downloaded
using a tarball you should have a directory called something like
``ns-allinone-3.38`` under your ``~/workspace`` directory.
``ns-allinone-3.39`` under your ``~/workspace`` directory.
Type the following:
.. sourcecode:: console
@@ -427,7 +419,7 @@ and you should see something like:
.. sourcecode:: text
>> Building netanim-3.109 - OK
>> Building ns-3.38 - OK
>> Building ns-3.39 - OK
There may be failures to build all components, but the build will proceed
anyway if the component is optional.
@@ -604,7 +596,6 @@ output that looks similar to the following:
-- Processing src/traffic-control
-- Processing src/uan
-- Processing src/virtual-net-device
-- Processing src/wave
-- Processing src/wifi
-- Processing src/wimax
-- ---- Summary of optional NS-3 features:
@@ -644,7 +635,7 @@ output that looks similar to the following:
sixlowpan spectrum stats
tap-bridge test topology-read
traffic-control uan virtual-net-device
wave wifi wimax
wifi wimax
Modules that cannot be built:

View File

@@ -64,13 +64,13 @@ Downloading the Latest Release
::
$ tar xjf ns-allinone-3.38.tar.bz2
$ tar xjf ns-allinone-3.39.tar.bz2
3) Change into the |ns3| directory directly; e.g.
::
$ cd ns-allinone-3.38/ns-3.38
$ cd ns-allinone-3.39/ns-3.39
The ns-allinone directory has some additional components but we are skipping
over them here; one can work directly from the |ns3| source code directory.
@@ -92,12 +92,12 @@ only to `cd` into ns-3-dev; the `master` branch is checked out by default.
$ cd ns-3-dev
If instead you want to try the most recent release (version 3.38 as of this
If instead you want to try the most recent release (version 3.39 as of this
writing), you can checkout a branch corresponding to that git tag:
::
$ git checkout -b ns-3.38-branch ns-3.38
$ git checkout -b ns-3.39-branch ns-3.39
Building and testing ns-3
*************************

View File

@@ -84,18 +84,14 @@ neither make directly. We use CMake for these functions.
On macOS, the toolchain used is Xcode. |ns3| users on a Mac are strongly
encouraged to install Xcode and the command-line tools packages from the
Apple App Store, and to look at the |ns3| installation wiki for more
information (https://www.nsnam.org/wiki/Installation).
Apple App Store, and to look at the |ns3| installation guide for more
information (https://www.nsnam.org/docs/installation/html/).
Typically an |ns3| author will work in Linux or a Unix-like environment.
For those running under Windows, there do exist environments
which simulate the Linux environment to various degrees. The |ns3|
project has in the past (but not presently) supported development in the Cygwin environment for
these users. See http://www.cygwin.com/
for details on downloading, and visit the |ns3| wiki for more information
about Cygwin and |ns3|. MinGW is presently not officially supported.
Another alternative to Cygwin is to install a virtual machine environment
such as VMware server and install a Linux virtual machine.
installation guide has information about Windows support
(https://www.nsnam.org/docs/installation/html/windows.html).
Socket Programming
******************

View File

@@ -313,7 +313,6 @@ We have provided some code to implement what is really the simplest
example of tracing that can be assembled. You can find this code in
the tutorial directory as ``fourth.cc``. Let's walk through it::
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* 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
@@ -1390,7 +1389,6 @@ dissecting the congestion window test. Open
``examples/tutorial/fifth.cc`` in your favorite editor. You should
see some familiar looking code::
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* 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

View File

@@ -1,5 +1,4 @@
#! /usr/bin/env python3
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
# A list of C++ examples to run in order to ensure that they remain
# buildable and runnable over time. Each tuple in the list contains

View File

@@ -1,5 +1,4 @@
#! /usr/bin/env python3
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
# A list of C++ examples to run in order to ensure that they remain
# buildable and runnable over time. Each tuple in the list contains

View File

@@ -1,5 +1,4 @@
#! /usr/bin/env python3
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
# A list of C++ examples to run in order to ensure that they remain
# buildable and runnable over time. Each tuple in the list contains

View File

@@ -1,5 +1,4 @@
#! /usr/bin/env python3
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
# A list of C++ examples to run in order to ensure that they remain
# buildable and runnable over time. Each tuple in the list contains

View File

@@ -33,7 +33,6 @@
#include "ns3/applications-module.h"
#include "ns3/core-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-apps-module.h"
#include "ns3/internet-module.h"
#include "ns3/ipv6-routing-table-entry.h"
#include "ns3/ipv6-static-routing-helper.h"

View File

@@ -32,7 +32,6 @@
#include "ns3/applications-module.h"
#include "ns3/core-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-apps-module.h"
#include "ns3/internet-module.h"
#include "ns3/ipv6-routing-table-entry.h"
#include "ns3/ipv6-static-routing-helper.h"

View File

@@ -30,7 +30,6 @@
#include "ns3/applications-module.h"
#include "ns3/core-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-apps-module.h"
#include "ns3/internet-module.h"
#include "ns3/ipv6-routing-table-entry.h"
#include "ns3/ipv6-static-routing-helper.h"

View File

@@ -60,7 +60,7 @@ using namespace ns3;
// ---------- Prototypes ------------------------------------------------------
std::vector<std::vector<bool>> readNxNMatrix(std::string adj_mat_file_name);
std::vector<std::vector<double>> readCordinatesFile(std::string node_coordinates_file_name);
std::vector<std::vector<double>> readCoordinatesFile(std::string node_coordinates_file_name);
void printCoordinateArray(const char* description, std::vector<std::vector<double>> coord_array);
void printMatrix(const char* description, std::vector<std::vector<bool>> array);
@@ -115,7 +115,7 @@ main(int argc, char* argv[])
// ---------- Read Node Coordinates File -----------------------------------
std::vector<std::vector<double>> coord_array;
coord_array = readCordinatesFile(node_coordinates_file_name);
coord_array = readCoordinatesFile(node_coordinates_file_name);
// Optionally display node coordinates file
// printCoordinateArray (node_coordinates_file_name.c_str (),coord_array);
@@ -361,7 +361,7 @@ readNxNMatrix(std::string adj_mat_file_name)
}
std::vector<std::vector<double>>
readCordinatesFile(std::string node_coordinates_file_name)
readCoordinatesFile(std::string node_coordinates_file_name)
{
std::ifstream node_coordinates_file;
node_coordinates_file.open(node_coordinates_file_name, std::ios::in);

View File

@@ -1,5 +1,4 @@
#! /usr/bin/env python3
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
# A list of C++ examples to run in order to ensure that they remain
# buildable and runnable over time. Each tuple in the list contains

View File

@@ -214,7 +214,7 @@ main(int argc, char* argv[])
outputValidated = false;
}
if (outputValidated == false)
if (!outputValidated)
{
std::cerr << "Program internal checking failed; returning with error" << std::endl;
return (1);

View File

@@ -1,5 +1,4 @@
#! /usr/bin/env python3
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
# A list of C++ examples to run in order to ensure that they remain
# buildable and runnable over time. Each tuple in the list contains

View File

@@ -87,6 +87,7 @@ build_example(
${libolsr}
${libinternet}
${libapplications}
${libflow-monitor}
)
build_example(

View File

@@ -1,5 +1,4 @@
#! /usr/bin/env python3
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
# A list of C++ examples to run in order to ensure that they remain
# buildable and runnable over time. Each tuple in the list contains

View File

@@ -69,6 +69,7 @@
#include "ns3/core-module.h"
#include "ns3/dsdv-module.h"
#include "ns3/dsr-module.h"
#include "ns3/flow-monitor-module.h"
#include "ns3/internet-module.h"
#include "ns3/mobility-module.h"
#include "ns3/network-module.h"
@@ -94,20 +95,15 @@ class RoutingExperiment
RoutingExperiment();
/**
* Run the experiment.
* \param nSinks The number of Sink Nodes.
* \param txp The Tx power.
* \param CSVfileName The output CSV filename.
*/
void Run(int nSinks, double txp, std::string CSVfileName);
// static void SetMACParam (ns3::NetDeviceContainer & devices,
// int slotDistance);
void Run();
/**
* Handles the command-line parameters.
* \param argc The argument count.
* \param argv The argument vector.
* \return the CSV filename.
*/
std::string CommandSetup(int argc, char** argv);
void CommandSetup(int argc, char** argv);
private:
/**
@@ -127,25 +123,19 @@ class RoutingExperiment
*/
void CheckThroughput();
uint32_t port; //!< Receiving port number.
uint32_t bytesTotal; //!< Total received bytes.
uint32_t packetsReceived; //!< Total received packets.
uint32_t port{9}; //!< Receiving port number.
uint32_t bytesTotal{0}; //!< Total received bytes.
uint32_t packetsReceived{0}; //!< Total received packets.
std::string m_CSVfileName; //!< CSV filename.
int m_nSinks; //!< Number of sink nodes.
std::string m_protocolName; //!< Protocol name.
double m_txp; //!< Tx power.
bool m_traceMobility; //!< Enavle mobility tracing.
uint32_t m_protocol; //!< Protocol type.
std::string m_CSVfileName{"manet-routing.output.csv"}; //!< CSV filename.
int m_nSinks{10}; //!< Number of sink nodes.
std::string m_protocolName{"AODV"}; //!< Protocol name.
double m_txp{7.5}; //!< Tx power.
bool m_traceMobility{false}; //!< Enable mobility tracing.
bool m_flowMonitor{false}; //!< Enable FlowMonitor.
};
RoutingExperiment::RoutingExperiment()
: port(9),
bytesTotal(0),
packetsReceived(0),
m_CSVfileName("manet-routing.output.csv"),
m_traceMobility(false),
m_protocol(2) // AODV
{
}
@@ -209,25 +199,42 @@ RoutingExperiment::SetupPacketReceive(Ipv4Address addr, Ptr<Node> node)
return sink;
}
std::string
void
RoutingExperiment::CommandSetup(int argc, char** argv)
{
CommandLine cmd(__FILE__);
cmd.AddValue("CSVfileName", "The name of the CSV output file name", m_CSVfileName);
cmd.AddValue("traceMobility", "Enable mobility tracing", m_traceMobility);
cmd.AddValue("protocol", "1=OLSR;2=AODV;3=DSDV;4=DSR", m_protocol);
cmd.AddValue("protocol", "Routing protocol (OLSR, AODV, DSDV, DSR)", m_protocolName);
cmd.AddValue("flowMonitor", "enable FlowMonitor", m_flowMonitor);
cmd.Parse(argc, argv);
return m_CSVfileName;
std::vector<std::string> allowedProtocols{"OLSR", "AODV", "DSDV", "DSR"};
if (std::find(std::begin(allowedProtocols), std::end(allowedProtocols), m_protocolName) ==
std::end(allowedProtocols))
{
NS_FATAL_ERROR("No such protocol:" << m_protocolName);
}
}
int
main(int argc, char* argv[])
{
RoutingExperiment experiment;
std::string CSVfileName = experiment.CommandSetup(argc, argv);
experiment.CommandSetup(argc, argv);
experiment.Run();
return 0;
}
void
RoutingExperiment::Run()
{
Packet::EnablePrinting();
// blank out the last output file and write the column headers
std::ofstream out(CSVfileName);
std::ofstream out(m_CSVfileName);
out << "SimulationSecond,"
<< "ReceiveRate,"
<< "PacketsReceived,"
@@ -236,22 +243,6 @@ main(int argc, char* argv[])
<< "TransmissionPower" << std::endl;
out.close();
int nSinks = 10;
double txp = 7.5;
experiment.Run(nSinks, txp, CSVfileName);
return 0;
}
void
RoutingExperiment::Run(int nSinks, double txp, std::string CSVfileName)
{
Packet::EnablePrinting();
m_nSinks = nSinks;
m_txp = txp;
m_CSVfileName = CSVfileName;
int nWifis = 50;
double TotalTime = 200.0;
@@ -260,7 +251,6 @@ RoutingExperiment::Run(int nSinks, double txp, std::string CSVfileName)
std::string tr_name("manet-routing-compare");
int nodeSpeed = 20; // in m/s
int nodePause = 0; // in s
m_protocolName = "protocol";
Config::SetDefault("ns3::OnOffApplication::PacketSize", StringValue("64"));
Config::SetDefault("ns3::OnOffApplication::DataRate", StringValue(rate));
@@ -289,8 +279,8 @@ RoutingExperiment::Run(int nSinks, double txp, std::string CSVfileName)
"ControlMode",
StringValue(phyMode));
wifiPhy.Set("TxPowerStart", DoubleValue(txp));
wifiPhy.Set("TxPowerEnd", DoubleValue(txp));
wifiPhy.Set("TxPowerStart", DoubleValue(m_txp));
wifiPhy.Set("TxPowerEnd", DoubleValue(m_txp));
wifiMac.SetType("ns3::AdhocWifiMac");
NetDeviceContainer adhocDevices = wifi.Install(wifiPhy, wifiMac, adhocNodes);
@@ -329,36 +319,36 @@ RoutingExperiment::Run(int nSinks, double txp, std::string CSVfileName)
Ipv4ListRoutingHelper list;
InternetStackHelper internet;
switch (m_protocol)
if (m_protocolName == "OLSR")
{
case 1:
list.Add(olsr, 100);
m_protocolName = "OLSR";
break;
case 2:
list.Add(aodv, 100);
m_protocolName = "AODV";
break;
case 3:
list.Add(dsdv, 100);
m_protocolName = "DSDV";
break;
case 4:
m_protocolName = "DSR";
break;
default:
NS_FATAL_ERROR("No such protocol:" << m_protocol);
}
if (m_protocol < 4)
{
internet.SetRoutingHelper(list);
internet.Install(adhocNodes);
}
else if (m_protocol == 4)
else if (m_protocolName == "AODV")
{
list.Add(aodv, 100);
internet.SetRoutingHelper(list);
internet.Install(adhocNodes);
}
else if (m_protocolName == "DSDV")
{
list.Add(dsdv, 100);
internet.SetRoutingHelper(list);
internet.Install(adhocNodes);
}
else if (m_protocolName == "DSR")
{
internet.Install(adhocNodes);
dsrMain.Install(dsr, adhocNodes);
if (m_flowMonitor)
{
NS_FATAL_ERROR("Error: FlowMonitor does not work with DSR. Terminating.");
}
}
else
{
NS_FATAL_ERROR("No such protocol:" << m_protocolName);
}
NS_LOG_INFO("assigning ip address");
@@ -372,7 +362,7 @@ RoutingExperiment::Run(int nSinks, double txp, std::string CSVfileName)
onoff1.SetAttribute("OnTime", StringValue("ns3::ConstantRandomVariable[Constant=1.0]"));
onoff1.SetAttribute("OffTime", StringValue("ns3::ConstantRandomVariable[Constant=0.0]"));
for (int i = 0; i < nSinks; i++)
for (int i = 0; i < m_nSinks; i++)
{
Ptr<Socket> sink = SetupPacketReceive(adhocInterfaces.GetAddress(i), adhocNodes.Get(i));
@@ -380,7 +370,7 @@ RoutingExperiment::Run(int nSinks, double txp, std::string CSVfileName)
onoff1.SetAttribute("Remote", remoteAddress);
Ptr<UniformRandomVariable> var = CreateObject<UniformRandomVariable>();
ApplicationContainer temp = onoff1.Install(adhocNodes.Get(i + nSinks));
ApplicationContainer temp = onoff1.Install(adhocNodes.Get(i + m_nSinks));
temp.Start(Seconds(var->GetValue(100.0, 101.0)));
temp.Stop(Seconds(TotalTime));
}
@@ -411,9 +401,12 @@ RoutingExperiment::Run(int nSinks, double txp, std::string CSVfileName)
AsciiTraceHelper ascii;
MobilityHelper::EnableAsciiAll(ascii.CreateFileStream(tr_name + ".mob"));
// Ptr<FlowMonitor> flowmon;
// FlowMonitorHelper flowmonHelper;
// flowmon = flowmonHelper.InstallAll();
FlowMonitorHelper flowmonHelper;
Ptr<FlowMonitor> flowmon;
if (m_flowMonitor)
{
flowmon = flowmonHelper.InstallAll();
}
NS_LOG_INFO("Run Simulation.");
@@ -422,7 +415,10 @@ RoutingExperiment::Run(int nSinks, double txp, std::string CSVfileName)
Simulator::Stop(Seconds(TotalTime));
Simulator::Run();
// flowmon->SerializeToXmlFile(tr_name + ".flowmon", false, false);
if (m_flowMonitor)
{
flowmon->SerializeToXmlFile(tr_name + ".flowmon", false, false);
}
Simulator::Destroy();
}

View File

@@ -22,7 +22,6 @@
//
// - UDP flows from n0 to n1
#include "ns3/applications-module.h"
#include "ns3/core-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"

View File

@@ -22,7 +22,6 @@
//
// - UDP flows from n0 to n1
#include "ns3/applications-module.h"
#include "ns3/core-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"

View File

@@ -1,5 +1,4 @@
#! /usr/bin/env python3
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
# A list of C++ examples to run in order to ensure that they remain
# buildable and runnable over time. Each tuple in the list contains

View File

@@ -301,8 +301,6 @@ main(int argc, char* argv[])
Time startTime = Seconds(0);
Time stopTime = flowStartupWindow + convergenceTime + measurementWindow;
Time clientStartTime = startTime;
rxS1R1Bytes.reserve(10);
rxS2R2Bytes.reserve(20);
rxS3R1Bytes.reserve(10);
@@ -493,7 +491,7 @@ main(int argc, char* argv[])
AddressValue remoteAddress(InetSocketAddress(ipR2T2[i].GetAddress(0), port));
clientHelper1.SetAttribute("Remote", remoteAddress);
clientApps1.Add(clientHelper1.Install(S2.Get(i)));
clientApps1.Start(i * flowStartupWindow / 20 + clientStartTime + MilliSeconds(i * 5));
clientApps1.Start(i * flowStartupWindow / 20 + startTime + MilliSeconds(i * 5));
clientApps1.Stop(stopTime);
}
@@ -534,13 +532,12 @@ main(int argc, char* argv[])
if (i < 10)
{
clientApps1.Add(clientHelper1.Install(S1.Get(i)));
clientApps1.Start(i * flowStartupWindow / 10 + clientStartTime + MilliSeconds(i * 5));
clientApps1.Start(i * flowStartupWindow / 10 + startTime + MilliSeconds(i * 5));
}
else
{
clientApps1.Add(clientHelper1.Install(S3.Get(i - 10)));
clientApps1.Start((i - 10) * flowStartupWindow / 10 + clientStartTime +
MilliSeconds(i * 5));
clientApps1.Start((i - 10) * flowStartupWindow / 10 + startTime + MilliSeconds(i * 5));
}
clientApps1.Stop(stopTime);

View File

@@ -1,5 +1,4 @@
#! /usr/bin/env python3
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
# A list of C++ examples to run in order to ensure that they remain
# buildable and runnable over time. Each tuple in the list contains

View File

@@ -746,7 +746,7 @@ main(int argc, char* argv[])
firstTcpTypeId = TcpDctcp::GetTypeId();
Config::SetDefault("ns3::CoDelQueueDisc::CeThreshold", TimeValue(ceThreshold));
Config::SetDefault("ns3::FqCoDelQueueDisc::CeThreshold", TimeValue(ceThreshold));
if (queueUseEcn == false)
if (!queueUseEcn)
{
std::cout << "Warning: using DCTCP with queue ECN disabled" << std::endl;
}
@@ -933,7 +933,7 @@ main(int argc, char* argv[])
proto->SetAttribute("SocketType", TypeIdValue(secondTcpTypeId));
}
// InternetStackHelper will install a base TrafficControLayer on the node,
// InternetStackHelper will install a base TrafficControlLayer on the node,
// but the Ipv4AddressHelper below will install the default FqCoDelQueueDisc
// on all single device nodes. The below code overrides the configuration
// that is normally done by the Ipv4AddressHelper::Install() method by

View File

@@ -79,8 +79,8 @@ static std::map<uint32_t, uint32_t> ssThreshValue; //!< SlowSta
static uint32_t
GetNodeIdFromContext(std::string context)
{
std::size_t const n1 = context.find_first_of('/', 1);
std::size_t const n2 = context.find_first_of('/', n1 + 1);
const std::size_t n1 = context.find_first_of('/', 1);
const std::size_t n2 = context.find_first_of('/', n1 + 1);
return std::stoul(context.substr(n1 + 1, n2 - n1 - 1));
}

View File

@@ -1,5 +1,4 @@
#! /usr/bin/env python3
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
# A list of C++ examples to run in order to ensure that they remain
# buildable and runnable over time. Each tuple in the list contains

View File

@@ -1,5 +1,4 @@
#! /usr/bin/env python3
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
# A list of C++ examples to run in order to ensure that they remain
# buildable and runnable over time. Each tuple in the list contains

View File

@@ -125,7 +125,7 @@ main(int argc, char* argv[])
Address anyAddress;
std::string probeType;
std::string tracePath;
if (useV6 == false)
if (!useV6)
{
Ipv4AddressHelper address;
address.SetBase("10.1.1.0", "255.255.255.0");

View File

@@ -74,7 +74,7 @@ main(int argc, char* argv[])
NetDeviceContainer d = csma.Install(n);
NS_LOG_INFO("Assign IP Addresses.");
if (useV6 == false)
if (!useV6)
{
Ipv4AddressHelper ipv4;
ipv4.SetBase("10.1.1.0", "255.255.255.0");

View File

@@ -73,7 +73,7 @@ main(int argc, char* argv[])
NetDeviceContainer d = csma.Install(n);
NS_LOG_INFO("Assign IP Addresses.");
if (useV6 == false)
if (!useV6)
{
Ipv4AddressHelper ipv4;
ipv4.SetBase("10.1.1.0", "255.255.255.0");

View File

@@ -1,5 +1,4 @@
#! /usr/bin/env python3
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
# A list of C++ examples to run in order to ensure that they remain
# buildable and runnable over time. Each tuple in the list contains

View File

@@ -81,7 +81,7 @@ main(int argc, char* argv[])
// We've got the "hardware" in place. Now we need to add IP addresses.
//
NS_LOG_INFO("Assign IP Addresses.");
if (useV6 == false)
if (!useV6)
{
Ipv4AddressHelper ipv4;
ipv4.SetBase("10.1.1.0", "255.255.255.0");

View File

@@ -1,5 +1,4 @@
#! /usr/bin/env python3
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
# A list of C++ examples to run in order to ensure that they remain
# buildable and runnable over time. Each tuple in the list contains
@@ -30,6 +29,9 @@ cpp_examples = [
("wifi-power-adaptation-distance --manager=ns3::ParfWifiManager --outputFileName=parf --steps=5 --stepsSize=10", "True", "True"),
("wifi-power-adaptation-distance --manager=ns3::AparfWifiManager --outputFileName=aparf --steps=5 --stepsSize=10", "True", "False"),
("wifi-power-adaptation-distance --manager=ns3::RrpaaWifiManager --outputFileName=rrpaa --steps=5 --stepsSize=10", "True", "False"),
("wifi-rate-adaptation-distance --standard=802.11a --staManager=ns3::MinstrelWifiManager --apManager=ns3::MinstrelWifiManager --outputFileName=minstrel --stepsSize=50 --stepsTime=0.1", "True", "False"),
("wifi-rate-adaptation-distance --standard=802.11a --staManager=ns3::MinstrelWifiManager --apManager=ns3::MinstrelWifiManager --outputFileName=minstrel --stepsSize=50 --stepsTime=0.1 --STA1_x=-200", "True", "False"),
("wifi-rate-adaptation-distance --staManager=ns3::MinstrelHtWifiManager --apManager=ns3::MinstrelHtWifiManager --outputFileName=minstrelHt --shortGuardInterval=true --channelWidth=40 --stepsSize=50 --stepsTime=0.1", "True", "False"),
("wifi-power-adaptation-interference --simuTime=5", "True", "False"),
("wifi-dsss-validation", "True", "True"),
("wifi-ofdm-validation", "True", "True"),
@@ -58,7 +60,7 @@ cpp_examples = [
("wifi-eht-network --simulationTime=0.1 --frequency=5 --useRts=1 --minExpectedThroughput=6 --maxExpectedThroughput=547", "True", "True"),
("wifi-eht-network --simulationTime=0.1 --frequency=2.4 --useRts=0 --useExtendedBlockAck=1 --frequency2=5 --minExpectedThroughput=12 --maxExpectedThroughput=500", "True", "True"),
("wifi-eht-network --simulationTime=0.1 --frequency=2.4 --useRts=1 --minExpectedThroughput=6 --maxExpectedThroughput=212", "True", "True"),
("wifi-eht-network --simulationTime=0.2 --udp=0 --downlink=1 --useRts=0 --nStations=4 --dlAckType=ACK-SU-FORMAT --enableUlOfdma=1 --enableBsrp=0 --mcs=4 --frequency2=6 --minExpectedThroughput=35 --maxExpectedThroughput=280", "True", "True"),
("wifi-eht-network --simulationTime=0.22 --udp=0 --downlink=1 --useRts=0 --nStations=4 --dlAckType=ACK-SU-FORMAT --enableUlOfdma=1 --enableBsrp=0 --mcs=4 --frequency2=6 --minExpectedThroughput=35 --maxExpectedThroughput=280", "True", "True"),
("wifi-eht-network --simulationTime=0.25 --frequency=2.4 --udp=0 --downlink=1 --useRts=0 --nStations=5 --dlAckType=MU-BAR --enableUlOfdma=1 --enableBsrp=1 --mcs=5 --frequency2=5 --useExtendedBlockAck=1 --minExpectedThroughput=40 --maxExpectedThroughput=100", "True", "True"),
("wifi-eht-network --simulationTime=0.3 --udp=0 --downlink=1 --useRts=1 --nStations=5 --dlAckType=AGGR-MU-BAR --enableUlOfdma=1 --enableBsrp=0 --mcs=6 --muSchedAccessReqInterval=50ms --frequency2=2.4 --minExpectedThroughput=50 --maxExpectedThroughput=140", "True", "True"),
("wifi-eht-network --simulationTime=0.2 --udp=1 --downlink=0 --useRts=0 --nStations=5 --dlAckType=AGGR-MU-BAR --enableUlOfdma=1 --enableBsrp=1 --mcs=5 --muSchedAccessReqInterval=50ms --frequency2=6 --minExpectedThroughput=70 --maxExpectedThroughput=715", "True", "True"),

View File

@@ -414,7 +414,7 @@ main(int argc, char* argv[])
// pcap trace on the application data sink
wifiPhy.EnablePcap("mixed-wireless", appSink->GetId(), 0);
if (useCourseChangeCallback == true)
if (useCourseChangeCallback)
{
Config::Connect("/NodeList/*/$ns3::MobilityModel/CourseChange",
MakeCallback(&CourseChangeCallback));

View File

@@ -91,7 +91,7 @@ def main(argv):
cmd.AddValue("backboneNodes", "number of backbone nodes", backboneNodes)
cmd.AddValue("infraNodes", "number of leaf nodes", infraNodes)
cmd.AddValue("lanNodes", "number of LAN nodes", lanNodes)
cmd.AddValue("stopTime", "simulation stop time(seconds)", stopTime)
cmd.AddValue["double"]("stopTime", "simulation stop time(seconds)", stopTime)
#
# The system global variables and the local values added to the argument

View File

@@ -175,8 +175,7 @@ Experiment::Run(const WifiHelper& wifi,
YansWifiPhyHelper phy = wifiPhy;
phy.SetChannel(wifiChannel.Create());
WifiMacHelper mac = wifiMac;
NetDeviceContainer devices = wifi.Install(phy, mac, c);
NetDeviceContainer devices = wifi.Install(phy, wifiMac, c);
MobilityHelper mobility;
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();

View File

@@ -183,8 +183,7 @@ Experiment::Run(const WifiHelper& wifi,
YansWifiPhyHelper phy = wifiPhy;
phy.SetChannel(wifiChannel.Create());
WifiMacHelper mac = wifiMac;
NetDeviceContainer devices = wifi.Install(phy, mac, c);
NetDeviceContainer devices = wifi.Install(phy, wifiMac, c);
MobilityHelper mobility;
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();

View File

@@ -1,4 +1,3 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2022
*
@@ -244,11 +243,8 @@ main(int argc, char* argv[])
"AGGR-MU-BAR)");
}
double prevThroughput[12];
for (uint32_t l = 0; l < 12; l++)
{
prevThroughput[l] = 0;
}
double prevThroughput[12] = {0};
std::cout << "MCS value"
<< "\t\t"
<< "Channel width"

View File

@@ -167,11 +167,8 @@ main(int argc, char* argv[])
phyModel = "Spectrum";
}
double prevThroughput[12];
for (uint32_t l = 0; l < 12; l++)
{
prevThroughput[l] = 0;
}
double prevThroughput[12] = {0};
std::cout << "MCS value"
<< "\t\t"
<< "Channel width"

View File

@@ -96,11 +96,8 @@ main(int argc, char* argv[])
Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue("0"));
}
double prevThroughput[8];
for (uint32_t l = 0; l < 8; l++)
{
prevThroughput[l] = 0;
}
double prevThroughput[8] = {0};
std::cout << "MCS value"
<< "\t\t"
<< "Channel width"

View File

@@ -505,8 +505,7 @@ Experiment::Run(const WifiHelper& wifi,
YansWifiPhyHelper phy = wifiPhy;
phy.SetChannel(wifiChannel.Create());
WifiMacHelper mac = wifiMac;
NetDeviceContainer devices = wifi.Install(phy, mac, c);
NetDeviceContainer devices = wifi.Install(phy, wifiMac, c);
OlsrHelper olsr;
Ipv4StaticRoutingHelper staticRouting;

View File

@@ -56,6 +56,7 @@
#include "ns3/boolean.h"
#include "ns3/command-line.h"
#include "ns3/config.h"
#include "ns3/double.h"
#include "ns3/gnuplot.h"
#include "ns3/internet-stack-helper.h"
#include "ns3/ipv4-address-helper.h"
@@ -65,6 +66,7 @@
#include "ns3/on-off-helper.h"
#include "ns3/packet-sink-helper.h"
#include "ns3/ssid.h"
#include "ns3/string.h"
#include "ns3/uinteger.h"
#include "ns3/yans-wifi-channel.h"
#include "ns3/yans-wifi-helper.h"
@@ -168,10 +170,16 @@ NodeStatistics::GetDatafile()
return m_output;
}
/**
* Callback for 'Rate' trace source
*
* \param oldRate old MCS rate (bits/sec)
* \param newRate new MCS rate (bits/sec)
*/
void
RateCallback(std::string path, uint64_t rate, Mac48Address dest)
RateCallback(uint64_t oldRate, uint64_t newRate)
{
NS_LOG_INFO((Simulator::Now()).GetSeconds() << " " << dest << " Rate " << rate / 1000000.0);
NS_LOG_INFO("Rate " << newRate / 1000000.0 << " Mbps");
}
int
@@ -194,9 +202,9 @@ main(int argc, char* argv[])
int stepsTime = 1;
CommandLine cmd(__FILE__);
cmd.AddValue("staManager", "PRC Manager of the STA", staManager);
cmd.AddValue("apManager", "PRC Manager of the AP", apManager);
cmd.AddValue("standard", "Wifi Phy Standard", standard);
cmd.AddValue("staManager", "Rate adaptation manager of the STA", staManager);
cmd.AddValue("apManager", "Rate adaptation manager of the AP", apManager);
cmd.AddValue("standard", "Wifi standard (a/b/g/n/ac only)", standard);
cmd.AddValue("shortGuardInterval",
"Enable Short Guard Interval in all stations",
shortGuardInterval);
@@ -215,6 +223,12 @@ main(int argc, char* argv[])
int simuTime = steps * stepsTime;
if (standard != "802.11a" && standard != "802.11b" && standard != "802.11g" &&
standard == "802.11n-2.4GHz" && standard != "802.11n-5GHz" && standard != "802.11ac")
{
NS_FATAL_ERROR("Standard " << standard << " is not supported by this program");
}
// Define the APs
NodeContainer wifiApNodes;
wifiApNodes.Create(1);
@@ -226,6 +240,30 @@ main(int argc, char* argv[])
YansWifiPhyHelper wifiPhy;
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default();
wifiPhy.SetChannel(wifiChannel.Create());
// Channel configuration via ChannelSettings attribute can be performed here
std::string frequencyBand;
if (standard == "802.11b" || standard == "802.11g" || standard == "802.11n-2.4GHz")
{
frequencyBand = "BAND_2_4GHZ";
}
else
{
frequencyBand = "BAND_5GHZ";
}
wifiPhy.Set("ChannelSettings",
StringValue("{0, " + std::to_string(chWidth) + ", " + frequencyBand + ", 0}"));
// By default, the CCA sensitivity is -82 dBm, meaning if the RSS is
// below this value, the receiver will reject the Wi-Fi frame.
// However, we want to allow the rate adaptation to work down to low
// SNR values. To allow this, we need to do three things: 1) disable
// the noise figure (set it to 0 dB) so that the noise level in 20 MHz
// is around -101 dBm, 2) lower the CCA sensitivity to a value that
// disables it (e.g. -110 dBm), and 3) disable the Wi-Fi preamble
// detection model.
wifiPhy.Set("CcaSensitivity", DoubleValue(-110));
wifiPhy.Set("RxNoiseFigure", DoubleValue(0));
wifiPhy.DisablePreambleDetectionModel();
NetDeviceContainer wifiApDevices;
NetDeviceContainer wifiStaDevices;
@@ -296,10 +334,6 @@ main(int argc, char* argv[])
wifiDevices.Add(wifiStaDevices);
wifiDevices.Add(wifiApDevices);
// Set channel width
Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/ChannelWidth",
UintegerValue(chWidth));
// Set guard interval
Config::Set(
"/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/HtConfiguration/ShortGuardIntervalSupported",
@@ -359,9 +393,9 @@ main(int argc, char* argv[])
MakeCallback(&NodeStatistics::RxCallback, &atpCounter));
// Callbacks to print every change of rate
Config::ConnectFailSafe("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/RemoteStationManager/$" +
apManager + "/RateChange",
MakeCallback(RateCallback));
Config::ConnectWithoutContextFailSafe(
"/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/RemoteStationManager/$" + apManager + "/Rate",
MakeCallback(RateCallback));
Simulator::Stop(Seconds(simuTime));
Simulator::Run();

View File

@@ -255,7 +255,7 @@ main(int argc, char* argv[])
InetSocketAddress remote = InetSocketAddress(i.GetAddress(sinkNode, 0), 80);
source->Connect(remote);
if (tracing == true)
if (tracing)
{
AsciiTraceHelper ascii;
wifiPhy.EnableAsciiAll(ascii.CreateFileStream("wifi-simple-adhoc-grid.tr"));

View File

@@ -54,7 +54,7 @@
// time.
//
// Note that, by default, this script configures a network using a
// channel bandwidth of 20 MHz. Changing this value alone (through
// channel width of 20 MHz. Changing this value alone (through
// the --channelWidth argument) without properly adjusting other
// parameters will void the effect of spatial reuse: since energy is
// measured over the 20 MHz primary channel regardless of the channel
@@ -69,11 +69,11 @@
// all these values by 3 dB compared to their defaults.
//
// In addition, consider that adapting the adjustments shown above
// for an 80 MHz bandwidth (using a 6 dB threshold adjustment instead
// for an 80 MHz channel width (using a 6 dB threshold adjustment instead
// of 3 dB) will not produce any changes when enableObssPd is enabled
// or disabled. The cause for this is the insufficient amount of
// traffic that is generated by default in the example: increasing
// the bandwidth shortens the frame durations, and lowers the
// the channel width shortens the frame durations, and lowers the
// collision probability. Collisions between BSSs are a necessary
// condition to see the improvements brought by spatial reuse, and
// thus increasing the amount of generated traffic by setting the
@@ -134,7 +134,7 @@ main(int argc, char* argv[])
double ccaEdTrAp1 = -62; // dBm
double ccaEdTrAp2 = -62; // dBm
double minimumRssi = -82; // dBm
int channelBandwidth = 20; // MHz
int channelWidth = 20; // MHz
uint32_t payloadSize = 1500; // bytes
uint32_t mcs = 0; // MCS value
double interval = 0.001; // seconds
@@ -159,9 +159,7 @@ main(int argc, char* argv[])
cmd.AddValue("minimumRssi",
"Minimum RSSI for the ThresholdPreambleDetectionModel",
minimumRssi);
cmd.AddValue("channelBandwidth",
"Bandwidth of the channel in MHz [20, 40, or 80]",
channelBandwidth);
cmd.AddValue("channelWidth", "Bandwidth of the channel in MHz [20, 40, or 80]", channelWidth);
cmd.AddValue("obssPdThreshold", "Threshold for the OBSS PD Algorithm", obssPdThreshold);
cmd.AddValue("mcs", "The constant MCS value to transmit HE PPDUs", mcs);
cmd.Parse(argc, argv);
@@ -182,7 +180,7 @@ main(int argc, char* argv[])
spectrumPhy.SetChannel(spectrumChannel);
spectrumPhy.SetErrorRateModel("ns3::YansErrorRateModel");
switch (channelBandwidth)
switch (channelWidth)
{
case 20:
spectrumPhy.Set("ChannelSettings", StringValue("{36, 20, BAND_5GHZ, 0}"));
@@ -194,7 +192,7 @@ main(int argc, char* argv[])
spectrumPhy.Set("ChannelSettings", StringValue("{171, 80, BAND_5GHZ, 0}"));
break;
default:
NS_ABORT_MSG("Unrecognized channel bandwidth: " << channelBandwidth);
NS_ABORT_MSG("Unrecognized channel width: " << channelWidth);
break;
}
spectrumPhy.SetPreambleDetectionModel("ns3::ThresholdPreambleDetectionModel",

View File

@@ -90,11 +90,8 @@ main(int argc, char* argv[])
Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue("0"));
}
double prevThroughput[8];
for (uint32_t l = 0; l < 8; l++)
{
prevThroughput[l] = 0;
}
double prevThroughput[8] = {0};
std::cout << "MCS value"
<< "\t\t"
<< "Channel width"

Some files were not shown because too many files have changed in this diff Show More