Merge tag 'ns-3.39' into unison
ns-3.39 release
This commit is contained in:
10
.clang-tidy
10
.clang-tidy
@@ -28,23 +28,29 @@ Checks: >
|
|||||||
performance-inefficient-algorithm,
|
performance-inefficient-algorithm,
|
||||||
performance-inefficient-vector-operation,
|
performance-inefficient-vector-operation,
|
||||||
performance-trivially-destructible,
|
performance-trivially-destructible,
|
||||||
|
performance-unnecessary-copy-initialization,
|
||||||
readability-braces-around-statements,
|
readability-braces-around-statements,
|
||||||
readability-container-size-empty,
|
readability-container-size-empty,
|
||||||
readability-duplicate-include,
|
|
||||||
readability-isolate-declaration,
|
readability-isolate-declaration,
|
||||||
readability-make-member-function-const,
|
readability-make-member-function-const,
|
||||||
readability-misleading-indentation,
|
|
||||||
readability-misplaced-array-index,
|
readability-misplaced-array-index,
|
||||||
readability-redundant-control-flow,
|
readability-redundant-control-flow,
|
||||||
readability-redundant-function-ptr-dereference,
|
readability-redundant-function-ptr-dereference,
|
||||||
readability-redundant-smartptr-get,
|
readability-redundant-smartptr-get,
|
||||||
readability-redundant-string-cstr,
|
readability-redundant-string-cstr,
|
||||||
|
readability-simplify-boolean-expr,
|
||||||
readability-simplify-subscript-expr,
|
readability-simplify-subscript-expr,
|
||||||
readability-static-accessed-through-instance,
|
readability-static-accessed-through-instance,
|
||||||
readability-static-definition-in-anonymous-namespace,
|
readability-static-definition-in-anonymous-namespace,
|
||||||
readability-string-compare,
|
readability-string-compare,
|
||||||
readability-uppercase-literal-suffix,
|
readability-uppercase-literal-suffix,
|
||||||
|
|
||||||
|
CheckOptions:
|
||||||
|
- key: performance-unnecessary-copy-initialization.AllowedTypes
|
||||||
|
value: Ptr
|
||||||
|
- key: readability-simplify-boolean-expr.SimplifyDeMorgan
|
||||||
|
value: false
|
||||||
|
|
||||||
FormatStyle: "file"
|
FormatStyle: "file"
|
||||||
HeaderFilterRegex: ".*(ns|NS).*/(contrib|examples|src|scratch|utils)/*/.*h"
|
HeaderFilterRegex: ".*(ns|NS).*/(contrib|examples|src|scratch|utils)/*/.*h"
|
||||||
UseColor: true
|
UseColor: true
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
[codespell]
|
[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
|
ignore-words = ./utils/codespell-ignored-words
|
||||||
exclude-file = ./utils/codespell-ignored-lines
|
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+
|
||||||
|
|||||||
@@ -31,6 +31,6 @@ indent_size = 4
|
|||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
[*.yml]
|
[*.{md,rst,yml,yaml}]
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|||||||
26
.github/workflows/per_commit.yml
vendored
26
.github/workflows/per_commit.yml
vendored
@@ -153,18 +153,20 @@ jobs:
|
|||||||
- uses: msys2/setup-msys2@v2
|
- uses: msys2/setup-msys2@v2
|
||||||
- name: Install required msys2/mingw64 packages
|
- name: Install required msys2/mingw64 packages
|
||||||
run: |
|
run: |
|
||||||
pacman -S --noconfirm unzip
|
pacman -S --noconfirm \
|
||||||
pacman -S --noconfirm tar
|
unzip \
|
||||||
pacman -S --noconfirm mingw-w64-x86_64-curl
|
tar \
|
||||||
pacman -S --noconfirm mingw-w64-x86_64-binutils
|
mingw-w64-x86_64-curl \
|
||||||
pacman -S --noconfirm mingw-w64-x86_64-cmake
|
mingw-w64-x86_64-binutils \
|
||||||
pacman -S --noconfirm mingw-w64-x86_64-gcc
|
mingw-w64-x86_64-cmake \
|
||||||
pacman -S --noconfirm mingw-w64-x86_64-ninja
|
mingw-w64-x86_64-gcc \
|
||||||
pacman -S --noconfirm mingw-w64-x86_64-python
|
mingw-w64-x86_64-ninja \
|
||||||
pacman -S --noconfirm mingw-w64-x86_64-ccache
|
mingw-w64-x86_64-python \
|
||||||
pacman -S --noconfirm mingw-w64-x86_64-gsl
|
mingw-w64-x86_64-ccache \
|
||||||
pacman -S --noconfirm mingw-w64-x86_64-libxml2
|
mingw-w64-x86_64-gsl \
|
||||||
pacman -S --noconfirm mingw-w64-x86_64-lld
|
mingw-w64-x86_64-libxml2 \
|
||||||
|
mingw-w64-x86_64-lld \
|
||||||
|
mingw-w64-x86_64-sed
|
||||||
pacman --noconfirm -Scc
|
pacman --noconfirm -Scc
|
||||||
- name: Get timestamp
|
- name: Get timestamp
|
||||||
id: time
|
id: time
|
||||||
|
|||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -24,6 +24,8 @@ testpy-output
|
|||||||
|
|
||||||
bindings/python/pybindgen/
|
bindings/python/pybindgen/
|
||||||
|
|
||||||
|
venv/
|
||||||
|
|
||||||
ms_print.*
|
ms_print.*
|
||||||
massif.*
|
massif.*
|
||||||
coverity
|
coverity
|
||||||
|
|||||||
10
AUTHORS
10
AUTHORS
@@ -7,6 +7,7 @@ Chetan Agrawal (chetanag35@gmail.com)
|
|||||||
Rohit Agarwal (mindprince@gmail.com)
|
Rohit Agarwal (mindprince@gmail.com)
|
||||||
Piyush Aggarwal (piyush8311@gmail.com)
|
Piyush Aggarwal (piyush8311@gmail.com)
|
||||||
Alessandro Aimi (alleaimi95@gmail.com)
|
Alessandro Aimi (alleaimi95@gmail.com)
|
||||||
|
German Aizek (germanaizek@yandex.ru)
|
||||||
Zoraze Ali (zoraze.ali@cttc.es)
|
Zoraze Ali (zoraze.ali@cttc.es)
|
||||||
Eduardo Almeida (enmsa@outlook.pt)
|
Eduardo Almeida (enmsa@outlook.pt)
|
||||||
Robert Ammon (ammo6818@vandals.uidaho.edu)
|
Robert Ammon (ammo6818@vandals.uidaho.edu)
|
||||||
@@ -96,6 +97,7 @@ Nichit Bodhak Goel (nichit93@gmail.com)
|
|||||||
Tom Goff (tgoff@tgoff.net)
|
Tom Goff (tgoff@tgoff.net)
|
||||||
Mohit Goyal (mohit.bits@gmail.com)
|
Mohit Goyal (mohit.bits@gmail.com)
|
||||||
Juan C. Granda (jcgranda@uniovi.es)
|
Juan C. Granda (jcgranda@uniovi.es)
|
||||||
|
Giovanni Grieco (giovanni.grieco@poliba.it)
|
||||||
David Gross (gdavid.devel@gmail.com)
|
David Gross (gdavid.devel@gmail.com)
|
||||||
Maja Grubišić (maja.grubisic@live.com)
|
Maja Grubišić (maja.grubisic@live.com)
|
||||||
Rémy Grünblatt (remy@grunblatt.org)
|
Rémy Grünblatt (remy@grunblatt.org)
|
||||||
@@ -107,6 +109,7 @@ Daniel Halperin (daniel@halper.in)
|
|||||||
Bruno Haick (bghaick@hotmail.com)
|
Bruno Haick (bghaick@hotmail.com)
|
||||||
Amiraslan Haghrah (amiraslanhaghrah@gmail.com)
|
Amiraslan Haghrah (amiraslanhaghrah@gmail.com)
|
||||||
Robert Hartung (hartung@ibr.cs.tu-bs.de)
|
Robert Hartung (hartung@ibr.cs.tu-bs.de)
|
||||||
|
Karsten Heimann
|
||||||
Frank Helbert (frank@ime.usp.br)
|
Frank Helbert (frank@ime.usp.br)
|
||||||
Tom Henderson (tomhend@u.washington.edu)
|
Tom Henderson (tomhend@u.washington.edu)
|
||||||
Christopher Hepner (hepner@hs-ulm.de)
|
Christopher Hepner (hepner@hs-ulm.de)
|
||||||
@@ -135,6 +138,7 @@ Liu Jian (liujatp@gmail.com)
|
|||||||
Sascha Alexander Jopen (jopen@informatik.uni-bonn.de)
|
Sascha Alexander Jopen (jopen@informatik.uni-bonn.de)
|
||||||
Piotr Jurkiewicz (piotr.jerzy.jurkiewicz@gmail.com)
|
Piotr Jurkiewicz (piotr.jerzy.jurkiewicz@gmail.com)
|
||||||
Evgeny Kalishenko (ydginster@gmail.com)
|
Evgeny Kalishenko (ydginster@gmail.com)
|
||||||
|
Raghuram Kannan (raghuramkannan40@gmail.com)
|
||||||
Vignesh Kannan (vignesh2496@gmail.com)
|
Vignesh Kannan (vignesh2496@gmail.com)
|
||||||
Ouassim Karrakchou (okarr102@uottawa.ca)
|
Ouassim Karrakchou (okarr102@uottawa.ca)
|
||||||
Tanmay Kathpalia (tanmay.kathpalia@landisgyr.com)
|
Tanmay Kathpalia (tanmay.kathpalia@landisgyr.com)
|
||||||
@@ -161,6 +165,7 @@ Emmanuelle Laprise (emmmanuelle.laprise@bluekazoo.ca)
|
|||||||
Harsh Lara (harshapplefan@gmail.com)
|
Harsh Lara (harshapplefan@gmail.com)
|
||||||
Mattia Lecci (mattia.lecci@gmail.com)
|
Mattia Lecci (mattia.lecci@gmail.com)
|
||||||
Robin Lee (xinyashuai1987@163.com)
|
Robin Lee (xinyashuai1987@163.com)
|
||||||
|
Juan Leon (juanvleonr@gmail.com)
|
||||||
Kristijan Lenković (k.lenkovic@me.com)
|
Kristijan Lenković (k.lenkovic@me.com)
|
||||||
Daniel Lertpratchya (nikkipui@gmail.com)
|
Daniel Lertpratchya (nikkipui@gmail.com)
|
||||||
Brett Levasseur (brettl20@gmail.com)
|
Brett Levasseur (brettl20@gmail.com)
|
||||||
@@ -198,6 +203,7 @@ Esteban Municio (esteban.municio@urjc.es)
|
|||||||
Sidharth Nabar (snabar@uw.edu)
|
Sidharth Nabar (snabar@uw.edu)
|
||||||
Sharan Naribole (sharan.naribole@gmail.com)
|
Sharan Naribole (sharan.naribole@gmail.com)
|
||||||
Hemanth Narra (hemanth@ittc.ku.edu)
|
Hemanth Narra (hemanth@ittc.ku.edu)
|
||||||
|
Carlos Natalino (carlos.natalino@chalmers.se)
|
||||||
Roman Naumann (naumann@informatik.hu-berlin.de)
|
Roman Naumann (naumann@informatik.hu-berlin.de)
|
||||||
Mohtashim Nawaz (nawazmohtashim@gmail.com)
|
Mohtashim Nawaz (nawazmohtashim@gmail.com)
|
||||||
Sachin Nayak (sachinn@uw.edu)
|
Sachin Nayak (sachinn@uw.edu)
|
||||||
@@ -250,11 +256,12 @@ Jakub Rewienski (jrewienski@gmail.com)
|
|||||||
Matias Richart (mrichart@fing.edu.uy)
|
Matias Richart (mrichart@fing.edu.uy)
|
||||||
George F. Riley (riley@ece.gatech.edu)
|
George F. Riley (riley@ece.gatech.edu)
|
||||||
Juergen Rinas (jrinas@gmx.de)
|
Juergen Rinas (jrinas@gmx.de)
|
||||||
|
Robert-ML
|
||||||
Sebastian Rohde (sebastian.rohde@tu-dortmund.de)
|
Sebastian Rohde (sebastian.rohde@tu-dortmund.de)
|
||||||
Karsten Roscher (sfx@rocktale.de)
|
Karsten Roscher (sfx@rocktale.de)
|
||||||
Ali Rostami (a.rostami@rutgers.edu)
|
Ali Rostami (a.rostami@rutgers.edu)
|
||||||
Bill Roome (wdr@bell-labs.com)
|
Bill Roome (wdr@bell-labs.com)
|
||||||
David (david.rua@gmail.com)
|
David Rua (david.rua@gmail.com)
|
||||||
Andrea Sacco (andrea.sacco85@gmail.com)
|
Andrea Sacco (andrea.sacco85@gmail.com)
|
||||||
Richard Sailer (richard_sailer@systemli.org)
|
Richard Sailer (richard_sailer@systemli.org)
|
||||||
Lynne Salameh (l.salameh@cs.ucl.ac.uk)
|
Lynne Salameh (l.salameh@cs.ucl.ac.uk)
|
||||||
@@ -312,6 +319,7 @@ Guillaume Vu-Brugier (gvubrugier@gmail.com)
|
|||||||
Tom Wambold (tom5760@gmail.com)
|
Tom Wambold (tom5760@gmail.com)
|
||||||
Danqi Wang (beyondwdq@gmail.com)
|
Danqi Wang (beyondwdq@gmail.com)
|
||||||
Tinghui Wang (tinghui.wang@wsu.edu)
|
Tinghui Wang (tinghui.wang@wsu.edu)
|
||||||
|
Yikun Wang (yikunwang6@gmail.com)
|
||||||
Mitch Watrous (watrous@u.washington.edu)
|
Mitch Watrous (watrous@u.washington.edu)
|
||||||
Pierre Wendling (pierre.wendling.4@gmail.com)
|
Pierre Wendling (pierre.wendling.4@gmail.com)
|
||||||
Florian Westphal (fw@strlen.de)
|
Florian Westphal (fw@strlen.de)
|
||||||
|
|||||||
89
CHANGES.md
89
CHANGES.md
@@ -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.
|
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
|
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) 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.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) 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
|
### 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) 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) 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).
|
* (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
|
### 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::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.
|
* 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.
|
* 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 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 **frame capture model**.
|
||||||
* Added a new helper method to SpectrumWifiPhyHelper and YansWifiPhyHelper to set the **preamble detection 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 standard value has been added that enables the new 11ax data rates.
|
||||||
* A new 11ax preamble has been added.
|
* 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 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.
|
* A new class were added for the RRPAA WiFi rate control mechanism.
|
||||||
* Included carrier aggregation feature in LTE module
|
* 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.
|
* 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.
|
* 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 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.
|
* 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 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 standard value has been added that enables the new 11ac data rates.
|
||||||
* A new 11ac preamble has been added.
|
* 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 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.
|
* 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`.
|
* New `const double& SpectrumValue::operator[] (size_t index) const`.
|
||||||
* A new TraceSource has been added to TCP sockets: SlowStartThreshold.
|
* 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:
|
* 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 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
|
* 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
|
* 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.
|
* 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,..
|
* 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.
|
* 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.
|
* 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.
|
* 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
|
* New DSR API
|
||||||
* Added PassiveBuffer class to save maintenance packet entry for passive acknowledgment option
|
* 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 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, 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 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
|
* 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 new methods GetLteEnbCphySapProvider, SetLteEnbCphySapUser, GetDlSpectrumPhy, GetUlSpectrumPhy, CreateSrsReport
|
||||||
* LteEnbPhy methods DoSendMacPdu, DoSetTransmissionMode, DoSetSrsConfigurationIndex, DoGetMacChTtiDelay, DoSendLteControlMessage, AddUePhy, DeleteUePhy made private
|
* LteEnbPhy methods DoSendMacPdu, DoSetTransmissionMode, DoSetSrsConfigurationIndex, DoGetMacChTtiDelay, DoSendLteControlMessage, AddUePhy, DeleteUePhy made private
|
||||||
* LteEnbPhySapProvider removed methods SetBandwidth, SetTransmissionMode, SetSrsConfigurationIndex, SetCellId
|
* 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 added methods (Set/Get)Status
|
||||||
* LtePdcp DoTransmitRrcPdu renamed DoTransmitPdcpSdu
|
* LtePdcp DoTransmitRrcPdu renamed DoTransmitPdcpSdu
|
||||||
* LteUeRrc new enum State. New methods SetLteUeCphySapProvider, GetLteUeCphySapUser, SetLteUeRrcSapUser, GetLteUeRrcSapProvider, GetState, GetDlEarfcn, GetDlBandwidth, GetUlBandwidth, GetCellId, SetUseRlcSm . GetRnti made const.
|
* LteUeRrc new enum State. New methods SetLteUeCphySapProvider, GetLteUeCphySapUser, SetLteUeRrcSapUser, GetLteUeRrcSapProvider, GetState, GetDlEarfcn, GetDlBandwidth, GetUlBandwidth, GetCellId, SetUseRlcSm . GetRnti made const.
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ option(NS3_TESTS "Enable tests to be built" OFF)
|
|||||||
# fd-net-device options
|
# fd-net-device options
|
||||||
option(NS3_EMU "Build with emulation support" ON)
|
option(NS3_EMU "Build with emulation support" ON)
|
||||||
option(NS3_TAP "Build with Tap support" ON)
|
option(NS3_TAP "Build with Tap support" ON)
|
||||||
|
option(NS3_DPDK "Enable fd-net-device DPDK features" OFF)
|
||||||
|
|
||||||
# maintenance and documentation
|
# maintenance and documentation
|
||||||
option(NS3_CLANG_FORMAT "Enforce cody style with clang-format" OFF)
|
option(NS3_CLANG_FORMAT "Enforce cody style with clang-format" OFF)
|
||||||
@@ -93,8 +94,8 @@ option(NS3_WARNINGS_AS_ERRORS
|
|||||||
set(NS3_ENABLED_MODULES ""
|
set(NS3_ENABLED_MODULES ""
|
||||||
CACHE STRING "List of modules to enable (e.g. core;network;internet)"
|
CACHE STRING "List of modules to enable (e.g. core;network;internet)"
|
||||||
)
|
)
|
||||||
set(NS3_DISABLED_MODULES ""
|
set(NS3_DISABLED_MODULES "" CACHE STRING
|
||||||
CACHE STRING "List of modules to disable (e.g. lte;wimax;wave)"
|
"List of modules to disable (e.g. lte;wimax)"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Filter in the modules from which examples and tests will be built
|
# Filter in the modules from which examples and tests will be built
|
||||||
|
|||||||
@@ -3,8 +3,6 @@
|
|||||||
[](https://doi.org/10.5281/zenodo.10077300)
|
[](https://doi.org/10.5281/zenodo.10077300)
|
||||||
[](https://github.com/NASA-NJU/UNISON-for-ns-3/actions/workflows/per_commit.yml)
|
[](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.
|
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).
|
More information about UNISON can be found in our EuroSys '24 paper (coming soon).
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
and references prefixed by '!' refer to a
|
||||||
[GitLab.com merge request](https://gitlab.com/nsnam/ns-3-dev/-/merge_requests) number.
|
[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
|
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) !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.
|
- (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) !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 support for 802.11be Multi-Link Operations (MLO), STR mode only
|
||||||
- (wifi) Added more fields to the EHT Capabilities information element
|
- (wifi) Added more fields to the EHT Capabilities information element
|
||||||
- (wifi) Added an initial 802.11be-based example program
|
- (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 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 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) 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
|
### Bugs fixed
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import builtins
|
import builtins
|
||||||
from copy import copy
|
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
import glob
|
import glob
|
||||||
import os.path
|
import os.path
|
||||||
@@ -11,7 +10,7 @@ DEFAULT_INCLUDE_DIR = sysconfig.get_config_var("INCLUDEDIR")
|
|||||||
DEFAULT_LIB_DIR = sysconfig.get_config_var("LIBDIR")
|
DEFAULT_LIB_DIR = sysconfig.get_config_var("LIBDIR")
|
||||||
|
|
||||||
|
|
||||||
def find_ns3_lock():
|
def find_ns3_lock() -> str:
|
||||||
# Get the absolute path to this file
|
# Get the absolute path to this file
|
||||||
path_to_this_init_file = os.path.dirname(os.path.abspath(__file__))
|
path_to_this_init_file = os.path.dirname(os.path.abspath(__file__))
|
||||||
path_to_lock = path_to_this_init_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):
|
if lock_file in os.listdir(path_to_lock):
|
||||||
path_to_lock += os.sep + lock_file
|
path_to_lock += os.sep + lock_file
|
||||||
else:
|
else:
|
||||||
path_to_lock = None
|
path_to_lock = ""
|
||||||
return path_to_lock
|
return path_to_lock
|
||||||
|
|
||||||
|
|
||||||
SYSTEM_LIBRARY_DIRECTORIES = (DEFAULT_LIB_DIR,
|
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",
|
DYNAMIC_LIBRARY_EXTENSIONS = {"linux": "so",
|
||||||
"win32": "dll",
|
"win32": "dll",
|
||||||
@@ -81,12 +82,14 @@ def _search_libraries() -> dict:
|
|||||||
# Search for the core library in the search paths
|
# Search for the core library in the search paths
|
||||||
libraries = []
|
libraries = []
|
||||||
for search_path in library_search_paths:
|
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)
|
# Search system library directories (too slow for recursive search)
|
||||||
for search_path in SYSTEM_LIBRARY_DIRECTORIES:
|
for search_path in SYSTEM_LIBRARY_DIRECTORIES:
|
||||||
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)
|
||||||
|
libraries += glob.glob("%s/*.%s*" % (search_path, LIBRARY_EXTENSION), recursive=False)
|
||||||
|
|
||||||
del search_path, library_search_paths
|
del search_path, library_search_paths
|
||||||
|
|
||||||
@@ -120,8 +123,35 @@ def search_libraries(library_name: str) -> list:
|
|||||||
return matched_libraries
|
return matched_libraries
|
||||||
|
|
||||||
|
|
||||||
def extract_library_include_dirs(library_name: str, prefix: str) -> list:
|
LIBRARY_AND_DEFINES = {
|
||||||
library_path = "%s/lib/%s" % (prefix, library_name)
|
"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 = []
|
linked_libs = []
|
||||||
# First discover which 3rd-party libraries are used by the current module
|
# First discover which 3rd-party libraries are used by the current module
|
||||||
try:
|
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}"
|
print("Failed to extract libraries used by {library} with exception:{exception}"
|
||||||
.format(library=library_path, exception=e))
|
.format(library=library_path, exception=e))
|
||||||
exit(-1)
|
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()
|
linked_libs_include_dirs = set()
|
||||||
|
defines = add_library_defines(library_name)
|
||||||
|
|
||||||
# Now find these libraries and add a few include paths for them
|
# 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
|
# Skip ns-3 modules
|
||||||
if "libns3" in linked_library:
|
if "libns3" in linked_library:
|
||||||
continue
|
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(
|
"Failed to find {library}. Make sure its library directory is in LD_LIBRARY_PATH.".format(
|
||||||
library=linked_library))
|
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]
|
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 library is part of the ns-3 build, continue without any new includes
|
||||||
if prefix in linked_library_path:
|
if prefix in linked_library_path:
|
||||||
continue
|
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
|
# 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):
|
if os.path.exists(system_include_dir):
|
||||||
linked_libs_include_dirs.add(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")
|
inc_path = os.path.join(lib_path, "include")
|
||||||
if os.path.exists(inc_path):
|
if os.path.exists(inc_path):
|
||||||
linked_libs_include_dirs.add(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():
|
def load_modules():
|
||||||
lock_file = find_ns3_lock()
|
lock_file = find_ns3_lock()
|
||||||
libraries_to_load = []
|
libraries_to_load = []
|
||||||
|
|
||||||
if lock_file:
|
# Search for prefix to ns-3 build, modules and respective libraries plus version
|
||||||
# Load NS3_ENABLED_MODULES from the lock file inside the build directory
|
ret = find_ns3_from_search() if not lock_file else find_ns3_from_lock_file(lock_file)
|
||||||
values = {}
|
|
||||||
|
|
||||||
# If we find a lock file, load the ns-3 modules from it
|
# Unpack returned values
|
||||||
# Should be the case when running from the source directory
|
prefix, libraries, version = ret
|
||||||
exec(open(lock_file).read(), {}, values)
|
prefix = os.path.abspath(prefix)
|
||||||
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
|
# Sort libraries according to their dependencies
|
||||||
def filter_in_matching_ns3_libraries(libraries_to_filter: dict,
|
def sort_to_dependencies(libraries: list, prefix: str) -> list:
|
||||||
modules_to_filter: list,
|
module_dependencies = {}
|
||||||
version: str,
|
libraries = list(map(lambda x: os.path.basename(x), libraries))
|
||||||
suffix: str) -> dict:
|
for ns3_library in libraries:
|
||||||
suffix = [suffix[1:]] if len(suffix) > 1 else []
|
_, _, linked_libraries = extract_linked_libraries(ns3_library, prefix)
|
||||||
filtered_in_modules = []
|
linked_libraries = list(filter(lambda x: "libns3" in x and ns3_library not in x, linked_libraries))
|
||||||
for module in modules_to_filter:
|
linked_libraries = list(map(lambda x: os.path.basename(x), linked_libraries))
|
||||||
filtered_in_modules += list(filter(lambda x: "-".join([version, module, *suffix]) in x,
|
module_dependencies[os.path.basename(ns3_library)] = linked_libraries
|
||||||
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)
|
def modules_that_can_be_loaded(module_dependencies, pending_modules, current_modules):
|
||||||
else:
|
modules = []
|
||||||
libraries = search_libraries("ns3")
|
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:
|
def dependency_order(module_dependencies, pending_modules, current_modules, step_number=0, steps={}):
|
||||||
raise Exception("ns-3 libraries were not found.")
|
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
|
sorted_libraries = []
|
||||||
# libns3-dev-core.so/../../
|
for step in dependency_order(module_dependencies, list(module_dependencies.keys()), [], 0).values():
|
||||||
prefix = os.path.dirname(os.path.dirname(libraries[0]))
|
sorted_libraries.extend(step)
|
||||||
|
return sorted_libraries
|
||||||
|
|
||||||
# Remove test libraries
|
libraries_to_load = sort_to_dependencies(libraries, prefix)
|
||||||
libraries = list(filter(lambda x: "test" not in x, libraries))
|
|
||||||
|
|
||||||
# Extract version and build suffix (if it exists)
|
# Extract library base names
|
||||||
def filter_module_name(library):
|
libraries_to_load = [os.path.basename(x) for x in libraries_to_load]
|
||||||
library = os.path.splitext(os.path.basename(library))[0]
|
|
||||||
components = library.split("-")
|
|
||||||
|
|
||||||
# Remove version-related prefixes
|
# Sort modules based on libraries
|
||||||
if "libns3" in components[0]:
|
modules = list(map(lambda x: filter_module_name(x), libraries_to_load))
|
||||||
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))
|
|
||||||
|
|
||||||
# Try to import Cppyy and warn the user in case it is not found
|
# Try to import Cppyy and warn the user in case it is not found
|
||||||
try:
|
try:
|
||||||
@@ -324,35 +444,27 @@ def load_modules():
|
|||||||
libcppyy.AddSmartPtrType('Ptr')
|
libcppyy.AddSmartPtrType('Ptr')
|
||||||
|
|
||||||
# Import ns-3 libraries
|
# Import ns-3 libraries
|
||||||
prefix = os.path.abspath(prefix)
|
for variant in ["lib", "lib64"]:
|
||||||
cppyy.add_library_path("%s/lib" % prefix)
|
path_to_lib = f"{prefix}/{variant}"
|
||||||
cppyy.add_include_path("%s/include" % prefix)
|
if not os.path.exists(path_to_lib):
|
||||||
|
continue
|
||||||
if lock_file:
|
cppyy.add_library_path(path_to_lib)
|
||||||
# When we have the lock file, we assemble the correct library names
|
del variant, path_to_lib
|
||||||
for module in modules:
|
cppyy.add_include_path(f"{prefix}/include")
|
||||||
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])
|
|
||||||
|
|
||||||
known_include_dirs = set()
|
known_include_dirs = set()
|
||||||
# We then need to include all include directories for dependencies
|
# We then need to include all include directories for dependencies
|
||||||
for library in libraries_to_load:
|
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:
|
if linked_lib_include_dir not in known_include_dirs:
|
||||||
known_include_dirs.add(linked_lib_include_dir)
|
known_include_dirs.add(linked_lib_include_dir)
|
||||||
if os.path.isdir(linked_lib_include_dir):
|
if os.path.isdir(linked_lib_include_dir):
|
||||||
cppyy.add_include_path(linked_lib_include_dir)
|
cppyy.add_include_path(linked_lib_include_dir)
|
||||||
|
|
||||||
for module in modules:
|
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
|
# After including all headers, we finally load the modules
|
||||||
for library in libraries_to_load:
|
for library in libraries_to_load:
|
||||||
|
|||||||
@@ -104,7 +104,9 @@ function(build_lib)
|
|||||||
)
|
)
|
||||||
endif()
|
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)
|
list(APPEND BLIB_LIBRARIES_TO_LINK -lstdc++fs)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -144,6 +146,15 @@ function(build_lib)
|
|||||||
foreach(library ${BLIB_LIBRARIES_TO_LINK})
|
foreach(library ${BLIB_LIBRARIES_TO_LINK})
|
||||||
remove_lib_prefix("${library}" module_name)
|
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
|
# Check if the module exists in the ns-3 modules list or if it is a
|
||||||
# 3rd-party library
|
# 3rd-party library
|
||||||
if(${module_name} IN_LIST ns3-all-enabled-modules)
|
if(${module_name} IN_LIST ns3-all-enabled-modules)
|
||||||
@@ -193,6 +204,20 @@ function(build_lib)
|
|||||||
${lib${BLIB_LIBNAME}} ${exported_libraries} ${private_libraries}
|
${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 output name of library
|
||||||
set_target_properties(
|
set_target_properties(
|
||||||
${lib${BLIB_LIBNAME}}
|
${lib${BLIB_LIBNAME}}
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ option(NS3_ENABLE_SUDO
|
|||||||
"Set executables ownership to root and enable the SUID flag" OFF
|
"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
|
# Replace default CMake messages (logging) with custom colored messages as early
|
||||||
# as possible
|
# as possible
|
||||||
include(${PROJECT_SOURCE_DIR}/build-support/3rd-party/colored-messages.cmake)
|
include(${PROJECT_SOURCE_DIR}/build-support/3rd-party/colored-messages.cmake)
|
||||||
@@ -71,6 +74,11 @@ if(WIN32)
|
|||||||
set(NS3_PRECOMPILE_HEADERS OFF
|
set(NS3_PRECOMPILE_HEADERS OFF
|
||||||
CACHE BOOL "Precompile module headers to speed up compilation" FORCE
|
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()
|
endif()
|
||||||
|
|
||||||
set(cat_command cat)
|
set(cat_command cat)
|
||||||
@@ -148,6 +156,25 @@ link_directories(${CMAKE_OUTPUT_DIRECTORY}/lib)
|
|||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
include(build-support/custom-modules/ns3-cmake-package.cmake)
|
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})
|
if(${XCODE})
|
||||||
# Is that so hard not to break people's CI, AAPL? Why would you output the
|
# Is that so hard not to break people's CI, AAPL? Why would you output the
|
||||||
# targets to a Debug/Release subfolder? Why?
|
# targets to a Debug/Release subfolder? Why?
|
||||||
@@ -202,6 +229,7 @@ if(CLANG)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(GCC FALSE)
|
set(GCC FALSE)
|
||||||
|
set(GCC8 FALSE)
|
||||||
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
|
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
|
||||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${GNU_MinVersion})
|
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${GNU_MinVersion})
|
||||||
message(
|
message(
|
||||||
@@ -209,6 +237,12 @@ if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
|
|||||||
"GNU ${CMAKE_CXX_COMPILER_VERSION} ${below_minimum_msg} ${GNU_MinVersion}"
|
"GNU ${CMAKE_CXX_COMPILER_VERSION} ${below_minimum_msg} ${GNU_MinVersion}"
|
||||||
)
|
)
|
||||||
endif()
|
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)
|
set(GCC TRUE)
|
||||||
add_definitions(-fno-semantic-interposition)
|
add_definitions(-fno-semantic-interposition)
|
||||||
if(${NS3_COLORED_OUTPUT} OR "$ENV{CLICOLOR}")
|
if(${NS3_COLORED_OUTPUT} OR "$ENV{CLICOLOR}")
|
||||||
@@ -222,6 +256,7 @@ unset(below_minimum_msg)
|
|||||||
set(CXX_UNSUPPORTED_STANDARDS 98 11 14)
|
set(CXX_UNSUPPORTED_STANDARDS 98 11 14)
|
||||||
set(CMAKE_CXX_STANDARD_MINIMUM 17)
|
set(CMAKE_CXX_STANDARD_MINIMUM 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
set(LIB_AS_NEEDED_PRE)
|
set(LIB_AS_NEEDED_PRE)
|
||||||
set(LIB_AS_NEEDED_POST)
|
set(LIB_AS_NEEDED_POST)
|
||||||
set(STATIC_LINK_FLAGS -static -static-libstdc++ -static-libgcc)
|
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-headers-to-module-map CACHE)
|
||||||
unset(ns3-libs CACHE)
|
unset(ns3-libs CACHE)
|
||||||
unset(ns3-libs-tests CACHE)
|
unset(ns3-libs-tests CACHE)
|
||||||
unset(ns3-python-bindings-modules CACHE)
|
|
||||||
mark_as_advanced(
|
mark_as_advanced(
|
||||||
build_profile
|
build_profile
|
||||||
build_profile_suffix
|
build_profile_suffix
|
||||||
@@ -322,7 +356,6 @@ macro(clear_global_cached_variables)
|
|||||||
ns3-headers-to-module-map
|
ns3-headers-to-module-map
|
||||||
ns3-libs
|
ns3-libs
|
||||||
ns3-libs-tests
|
ns3-libs-tests
|
||||||
ns3-python-bindings-modules
|
|
||||||
)
|
)
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
@@ -410,6 +443,8 @@ macro(process_options)
|
|||||||
if(${NS3_TESTS} OR ${ns3rc_tests_enabled})
|
if(${NS3_TESTS} OR ${ns3rc_tests_enabled})
|
||||||
set(ENABLE_TESTS ON)
|
set(ENABLE_TESTS ON)
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
else()
|
||||||
|
list(REMOVE_ITEM libs_to_build test)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(profiles_without_suffixes release)
|
set(profiles_without_suffixes release)
|
||||||
@@ -553,11 +588,11 @@ macro(process_options)
|
|||||||
cmake-format
|
cmake-format
|
||||||
COMMAND
|
COMMAND
|
||||||
${CMAKE_FORMAT_PROGRAM} -c
|
${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}
|
${INTERNAL_CMAKE_FILES}
|
||||||
COMMAND
|
COMMAND
|
||||||
${CMAKE_FORMAT_PROGRAM} -c
|
${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}
|
${MODULES_CMAKE_FILES}
|
||||||
)
|
)
|
||||||
unset(MODULES_CMAKE_FILES)
|
unset(MODULES_CMAKE_FILES)
|
||||||
@@ -802,7 +837,7 @@ macro(process_options)
|
|||||||
find_package(Python3 COMPONENTS Interpreter Development)
|
find_package(Python3 COMPONENTS Interpreter Development)
|
||||||
else()
|
else()
|
||||||
# cmake-format: off
|
# 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
|
# cmake-format: on
|
||||||
find_package(PythonInterp)
|
find_package(PythonInterp)
|
||||||
find_package(PythonLibs)
|
find_package(PythonLibs)
|
||||||
@@ -856,10 +891,12 @@ macro(process_options)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
message(
|
if(${NS3_PYTHON_BINDINGS})
|
||||||
${HIGHLIGHTED_STATUS}
|
message(
|
||||||
"Python: an incompatible version of Python was found, python bindings will be disabled"
|
${HIGHLIGHTED_STATUS}
|
||||||
)
|
"Python: an incompatible version of Python was found, python bindings will be disabled"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(ENABLE_PYTHON_BINDINGS OFF)
|
set(ENABLE_PYTHON_BINDINGS OFF)
|
||||||
@@ -901,12 +938,16 @@ macro(process_options)
|
|||||||
message(
|
message(
|
||||||
${HIGHLIGHTED_STATUS}
|
${HIGHLIGHTED_STATUS}
|
||||||
"NS3_BINDINGS_INSTALL_DIR was not set. The python bindings won't be installed with ./ns3 install."
|
"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(
|
message(
|
||||||
${HIGHLIGHTED_STATUS}
|
${HIGHLIGHTED_STATUS}
|
||||||
"Set NS3_BINDINGS_INSTALL_DIR=\"${SUGGESTED_BINDINGS_INSTALL_DIR}\" to install it to the default location."
|
"Set NS3_BINDINGS_INSTALL_DIR=\"${SUGGESTED_BINDINGS_INSTALL_DIR}\" to install it to the default location."
|
||||||
)
|
)
|
||||||
else()
|
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
|
install(FILES bindings/python/ns__init__.py
|
||||||
DESTINATION ${NS3_BINDINGS_INSTALL_DIR}/ns RENAME __init__.py
|
DESTINATION ${NS3_BINDINGS_INSTALL_DIR}/ns RENAME __init__.py
|
||||||
)
|
)
|
||||||
@@ -1370,8 +1411,6 @@ macro(process_options)
|
|||||||
set(ns3-contrib-libs)
|
set(ns3-contrib-libs)
|
||||||
set(lib-ns3-static-objs)
|
set(lib-ns3-static-objs)
|
||||||
set(ns3-external-libs)
|
set(ns3-external-libs)
|
||||||
set(ns3-python-bindings ns${NS3_VER}-pybindings${build_profile_suffix})
|
|
||||||
set(ns3-python-bindings-modules)
|
|
||||||
|
|
||||||
foreach(libname ${scanned_modules})
|
foreach(libname ${scanned_modules})
|
||||||
# Create libname of output library of module
|
# Create libname of output library of module
|
||||||
@@ -1497,7 +1536,7 @@ macro(process_options)
|
|||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
netanim GIT_REPOSITORY https://gitlab.com/nsnam/netanim.git
|
netanim GIT_REPOSITORY https://gitlab.com/nsnam/netanim.git
|
||||||
GIT_TAG netanim-3.108
|
GIT_TAG netanim-3.109
|
||||||
)
|
)
|
||||||
FetchContent_Populate(netanim)
|
FetchContent_Populate(netanim)
|
||||||
file(COPY build-support/3rd-party/netanim-cmakelists.cmake
|
file(COPY build-support/3rd-party/netanim-cmakelists.cmake
|
||||||
@@ -1597,8 +1636,11 @@ function(build_exec)
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Resolve nested scratch prefixes without user intervention
|
# Resolve nested scratch prefixes without user intervention
|
||||||
if("${CMAKE_CURRENT_SOURCE_DIR}" MATCHES "scratch"
|
string(REPLACE "${PROJECT_SOURCE_DIR}" "" relative_path
|
||||||
AND "${BEXEC_EXECNAME_PREFIX}" STREQUAL ""
|
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||||
|
)
|
||||||
|
if("${relative_path}" MATCHES "scratch" AND "${BEXEC_EXECNAME_PREFIX}"
|
||||||
|
STREQUAL ""
|
||||||
)
|
)
|
||||||
get_scratch_prefix(BEXEC_EXECNAME_PREFIX)
|
get_scratch_prefix(BEXEC_EXECNAME_PREFIX)
|
||||||
endif()
|
endif()
|
||||||
@@ -1946,10 +1988,6 @@ macro(
|
|||||||
unset(dependencies)
|
unset(dependencies)
|
||||||
unset(contrib_dependencies)
|
unset(contrib_dependencies)
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
if(core IN_LIST ${libs_to_build})
|
|
||||||
list(APPEND ${libs_to_build} test) # include test module
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(${NS3_DISABLED_MODULES} OR ${ns3rc_disabled_modules})
|
if(${NS3_DISABLED_MODULES} OR ${ns3rc_disabled_modules})
|
||||||
|
|||||||
11
build-support/pip-wheel/auditwheel-exclude-list.py
Normal file
11
build-support/pip-wheel/auditwheel-exclude-list.py
Normal 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=' ')
|
||||||
10
build-support/pip-wheel/ns/__init__.py
Normal file
10
build-support/pip-wheel/ns/__init__.py
Normal 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)
|
||||||
11
build-support/pip-wheel/visualizer/__init__.py
Normal file
11
build-support/pip-wheel/visualizer/__init__.py
Normal 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
|
||||||
@@ -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]))
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
build_lib(
|
||||||
|
LIBNAME test-contrib-dependency
|
||||||
|
SOURCE_FILES contrib-source.cc
|
||||||
|
HEADER_FILES contrib-header.h
|
||||||
|
LIBRARIES_TO_LINK ${libcore}
|
||||||
|
)
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef NS3_CONTRIB_HEADER_H
|
||||||
|
#define NS3_CONTRIB_HEADER_H
|
||||||
|
|
||||||
|
void testPrint();
|
||||||
|
|
||||||
|
#endif // NS3_CONTRIB_HEADER_H
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#include "contrib-header.h"
|
||||||
|
|
||||||
|
#include <ns3/simulator.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
testPrint()
|
||||||
|
{
|
||||||
|
std::cout << ns3::Simulator::Now() << std::endl;
|
||||||
|
}
|
||||||
@@ -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}
|
||||||
|
)
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
build_lib_example(
|
||||||
|
NAME source-example
|
||||||
|
SOURCE_FILES source-example.cc
|
||||||
|
LIBRARIES_TO_LINK
|
||||||
|
${libtest-src-dependant-on-contrib}
|
||||||
|
)
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#include <ns3/src-header.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
testPrint2();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef NS3_SRC_SOURCE2_H
|
||||||
|
#define NS3_SRC_SOURCE2_H
|
||||||
|
|
||||||
|
void testPrint2();
|
||||||
|
|
||||||
|
#endif // NS3_SOURCE_H
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#include <ns3/contrib-header.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
testPrint2()
|
||||||
|
{
|
||||||
|
testPrint();
|
||||||
|
}
|
||||||
@@ -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
|
All checks are enabled by default. Users can disable specific checks using the corresponding
|
||||||
flags: ``--no-formatting``, ``--no-whitespace`` and ``--no-tabs``.
|
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.
|
In addition to checking the files, the script can automatically fix detected issues in-place.
|
||||||
This mode is enabled by adding the ``--fix`` flag.
|
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
|
.. sourcecode:: console
|
||||||
|
|
||||||
# Entire codebase (using paths relative to the ns-3 main directory)
|
# 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)
|
# 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
|
# 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
|
# 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
|
Clang-tidy
|
||||||
@@ -752,8 +755,8 @@ For standard headers, use the C++ style of inclusion:
|
|||||||
|
|
||||||
#include <ns3/header.h>
|
#include <ns3/header.h>
|
||||||
|
|
||||||
Variables
|
Variables and constants
|
||||||
=========
|
=======================
|
||||||
|
|
||||||
Each variable declaration is on a separate line.
|
Each variable declaration is on a separate line.
|
||||||
Variables should be declared at the point in the code where they are needed,
|
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 x = 0;
|
||||||
int y = 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
|
Comments
|
||||||
========
|
========
|
||||||
|
|
||||||
@@ -1096,6 +1127,53 @@ can be rewritten as:
|
|||||||
n += 3;
|
n += 3;
|
||||||
return n;
|
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
|
Smart pointer boolean comparisons
|
||||||
=================================
|
=================================
|
||||||
|
|
||||||
|
|||||||
@@ -48,9 +48,9 @@ copyright = u'2015, ns-3 project'
|
|||||||
# built documents.
|
# built documents.
|
||||||
#
|
#
|
||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = 'ns-3.38'
|
version = 'ns-3.39'
|
||||||
# The full version, including alpha/beta/rc tags.
|
# 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
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
|
|||||||
@@ -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
|
An example placement of a copyright statement can be found in the file
|
||||||
``src/network/model/packet.h``::
|
``src/network/model/packet.h``::
|
||||||
|
|
||||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005,2006 INRIA
|
* 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
|
of code that is covered by the new copyright. An example is the program
|
||||||
``src/lte/model/lte-ue-phy.h``::
|
``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) 2010 TELEMATICS LAB, DEE - Politecnico di Bari
|
||||||
* Copyright (c) 2018 Fraunhofer ESK : RLF extensions
|
* Copyright (c) 2018 Fraunhofer ESK : RLF extensions
|
||||||
|
|||||||
@@ -1881,7 +1881,7 @@ PAPER_TYPE = a4
|
|||||||
# If left blank no extra packages will be included.
|
# If left blank no extra packages will be included.
|
||||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
# 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 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
|
# the generated LaTeX document. The header should contain everything until the
|
||||||
@@ -2693,5 +2693,5 @@ GENERATE_LEGEND = YES
|
|||||||
DOT_CLEANUP = YES
|
DOT_CLEANUP = YES
|
||||||
|
|
||||||
# Disable dark mode in the generated HTML in Doxygen 1.9.6 or greater.
|
# Disable dark mode in the generated HTML in Doxygen 1.9.6 or greater.
|
||||||
HTML_COLORSTYLE = LIGHT
|
# HTML_COLORSTYLE = LIGHT
|
||||||
|
|
||||||
|
|||||||
@@ -48,9 +48,9 @@ copyright = u'2018, ns-3 project'
|
|||||||
# built documents.
|
# built documents.
|
||||||
#
|
#
|
||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = 'ns-3.38'
|
version = 'ns-3.39'
|
||||||
# The full version, including alpha/beta/rc tags.
|
# 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
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ extensions you need; please review the previous chapter if you need more informa
|
|||||||
Requirements
|
Requirements
|
||||||
************
|
************
|
||||||
|
|
||||||
The minimum supported version of Ubuntu is Ubuntu 16.04 LTS (as long as a modern compiler
|
The minimum supported version of Ubuntu is Ubuntu 18.04 LTS (as long as a modern compiler
|
||||||
version such as g++ version 8 or later is added).
|
version such as g++ version 9 or later is added).
|
||||||
|
|
||||||
+--------------------+---------------------------------------------------------------------+
|
+--------------------+---------------------------------------------------------------------+
|
||||||
| **ns-3 Version** | **apt Packages** |
|
| **ns-3 Version** | **apt Packages** |
|
||||||
@@ -35,11 +35,8 @@ version such as g++ version 8 or later is added).
|
|||||||
+--------------------+---------------------------------------------------------------------+
|
+--------------------+---------------------------------------------------------------------+
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
As of January 2022 (ns-3.36 release and later), the minimum g++ version is g++-8.
|
As of July 2023 (ns-3.39 release and later), the minimum g++ version is g++-9.
|
||||||
Older Ubuntu releases (18.04, 16.04) come with an older default g++. On Ubuntu 18.04, this
|
Older ns-3 releases may work with older versions of g++; check the RELEASE_NOTES.
|
||||||
`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>`_.
|
|
||||||
|
|
||||||
Recommended
|
Recommended
|
||||||
***********
|
***********
|
||||||
@@ -106,9 +103,11 @@ Please see below subsections for Python-related package requirements.
|
|||||||
Python bindings
|
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::
|
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)::
|
ns-3.30-3.36 (also requires pybindgen, found in the ``allinone`` directory)::
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
|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.
|
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
|
Most users write C++ ns-3 programs; Python support is less frequently used.
|
||||||
maintained as of this writing. As of *ns-3.37*, |ns3| uses `cppyy` to generate runtime Python
|
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
|
bindings, and |ns3| is available in the Pip repositories as of ns-3.39 release.
|
||||||
contributed by Gabriel Ferreira as a proof-of-concept (hint: the project is seeking a full-time
|
|
||||||
maintainer to develop this further).
|
|
||||||
|
|
||||||
Many users may be familiar with how software is packaged and installed on Linux and other systems
|
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
|
using package managers. For example, to install a given Linux development library such as
|
||||||
|
|||||||
@@ -80,13 +80,13 @@ Download
|
|||||||
|
|
||||||
There are two main options:
|
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``,
|
containing |ns3| and some other programs. Below is a command-line download using ``wget``,
|
||||||
but a browser download will also work::
|
but a browser download will also work::
|
||||||
|
|
||||||
$ wget https://www.nsnam.org/releases/ns-allinone-3.38.tar.bz2
|
$ wget https://www.nsnam.org/releases/ns-allinone-3.39.tar.bz2
|
||||||
$ tar xfj ns-allinone-3.38.tar.bz2
|
$ tar xfj ns-allinone-3.39.tar.bz2
|
||||||
$ cd ns-allinone-3.38/ns-3.38
|
$ 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
|
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::
|
``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
|
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::
|
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,
|
In this quick-start, we are omitting download and build instructions for optional |ns3| modules,
|
||||||
the ``NetAnim`` animator, Python bindings, and ``NetSimulyzer``. The
|
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
|
propagation sixlowpan spectrum
|
||||||
stats tap-bridge test (no Python)
|
stats tap-bridge test (no Python)
|
||||||
topology-read traffic-control uan
|
topology-read traffic-control uan
|
||||||
virtual-net-device visualizer wave
|
virtual-net-device visualizer wifi
|
||||||
wifi wimax
|
wimax
|
||||||
|
|
||||||
Modules not built (see ns-3 tutorial for explanation):
|
Modules not built (see ns-3 tutorial for explanation):
|
||||||
brite click openflow
|
brite click openflow
|
||||||
|
|||||||
@@ -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)
|
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)
|
Using Python bindings (release 3.30 to ns-3.36)
|
||||||
===============================================
|
===============================================
|
||||||
|
|||||||
@@ -73,9 +73,9 @@ copyright = u'2006-2019'
|
|||||||
# built documents.
|
# built documents.
|
||||||
#
|
#
|
||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = u'ns-3.38'
|
version = u'ns-3.39'
|
||||||
# The full version, including alpha/beta/rc tags.
|
# 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
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
|
|||||||
@@ -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
|
following table. See the individual Scheduler API pages for details on the
|
||||||
complexity of the other API calls.
|
complexity of the other API calls.
|
||||||
|
|
||||||
+-----------------------+-------------------------------------+-------------+--------------+----------+--------------+
|
+------------------------+-------------------------------------+-------------+--------------+----------+--------------+
|
||||||
| Scheduler Type | Complexity |
|
| Scheduler Type | Complexity |
|
||||||
+-----------------------+-------------------------------------+-------------+--------------+----------+--------------+
|
+------------------------+-------------------------------------+-------------+--------------+----------+--------------+
|
||||||
| | | Time | Space |
|
| | | Time | Space |
|
||||||
| `SchedulerImpl` Type | Method +-------------+--------------+----------+--------------+
|
| `SchedulerImpl` Type | Method +-------------+--------------+----------+--------------+
|
||||||
| | | Insert() | RemoveNext() | Overhead | Per Event |
|
| | | Insert() | RemoveNext() | Overhead | Per Event |
|
||||||
+=======================+=====================================+=============+==============+==========+==============+
|
+========================+=====================================+=============+==============+==========+==============+
|
||||||
| CalendarScheduler | `<std::list> []` | Constant | Constant | 24 bytes | 16 bytes |
|
| CalendarScheduler | `<std::list> []` | Constant | Constant | 24 bytes | 16 bytes |
|
||||||
+-----------------------+-------------------------------------+-------------+--------------+----------+--------------+
|
+------------------------+-------------------------------------+-------------+--------------+----------+--------------+
|
||||||
| HeapScheduler | Heap on `std::vector` | Logarithmic | Logarithmic | 24 bytes | 0 |
|
| HeapScheduler | Heap on `std::vector` | Logarithmic | Logarithmic | 24 bytes | 0 |
|
||||||
+-----------------------+-------------------------------------+-------------+--------------+----------+--------------+
|
+------------------------+-------------------------------------+-------------+--------------+----------+--------------+
|
||||||
| ListScheduler | `std::list` | Linear | Constant | 24 bytes | 16 bytes |
|
| ListScheduler | `std::list` | Linear | Constant | 24 bytes | 16 bytes |
|
||||||
+-----------------------+-------------------------------------+-------------+--------------+----------+--------------+
|
+------------------------+-------------------------------------+-------------+--------------+----------+--------------+
|
||||||
| MapScheduler | `st::map` | Logarithmic | Constant | 40 bytes | 32 bytes |
|
| MapScheduler | `st::map` | Logarithmic | Constant | 40 bytes | 32 bytes |
|
||||||
+-----------------------+-------------------------------------+-------------+--------------+----------+--------------+
|
+------------------------+-------------------------------------+-------------+--------------+----------+--------------+
|
||||||
| PriorityQueueSchduler | `std::priority_queue<,std::vector>` | Logarithimc | Logarithims | 24 bytes | 0 |
|
| PriorityQueueScheduler | `std::priority_queue<,std::vector>` | Logarithimc | Logarithims | 24 bytes | 0 |
|
||||||
+-----------------------+-------------------------------------+-------------+--------------+----------+--------------+
|
+------------------------+-------------------------------------+-------------+--------------+----------+--------------+
|
||||||
|
|||||||
@@ -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
|
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.
|
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 statements are not compiled into ``optimized`` builds of |ns3|. To use
|
||||||
logging, one must build the (default) debug build of |ns3|.
|
logging, one must use the ``default`` or ``debug`` build profiles of |ns3|.
|
||||||
|
|
||||||
The project makes no guarantee about whether logging output will remain
|
The project makes no guarantee about whether logging output will remain
|
||||||
the same over time. Users are cautioned against building simulation output
|
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
|
execution events, such as the occurrence of simulation events or the
|
||||||
use of a particular function.
|
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_INFO("Enter CWR recovery mode; set cwnd to " << m_tcb->m_cWnd << ", ssthresh to "
|
||||||
{
|
<< m_tcb->m_ssThresh << ", recover to "
|
||||||
NS_LOG_LOGIC("For me (interface broadcast address)");
|
<< m_recover);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
If logging has been enabled for the ``Ipv4L3Protocol`` component at a severity
|
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.
|
will be printed out; otherwise, it will be suppressed.
|
||||||
|
|
||||||
The logging implementation is enabled in ``debug`` and ``default``
|
The logging implementation is enabled in ``debug`` and ``default``
|
||||||
builds, but disabled in all other build profiles,
|
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`
|
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
|
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
|
Individual messages belong to a single "severity class," set by the macro
|
||||||
creating the message. In the example above,
|
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:
|
The following severity classes are defined as ``enum`` constants:
|
||||||
|
|
||||||
================ =====================================
|
================ =========================================================
|
||||||
Severity Class Meaning
|
Severity Class Meaning
|
||||||
================ =====================================
|
================ =========================================================
|
||||||
``LOG_NONE`` The default, no logging
|
``LOG_NONE`` The default, no logging
|
||||||
``LOG_ERROR`` Serious error messages only
|
``LOG_ERROR`` Serious error messages only
|
||||||
``LOG_WARN`` Warning messages
|
``LOG_WARN`` Warning messages
|
||||||
``LOG_DEBUG`` For use in debugging
|
``LOG_INFO`` Info about the model changing state
|
||||||
``LOG_INFO`` Informational
|
|
||||||
``LOG_FUNCTION`` Function tracing
|
``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*.
|
Typically one wants to see messages at a given severity class *and higher*.
|
||||||
This is done by defining inclusive logging "levels":
|
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_ERROR`` Only ``LOG_ERROR`` severity class messages.
|
||||||
``LOG_LEVEL_WARN`` ``LOG_WARN`` and above.
|
``LOG_LEVEL_WARN`` ``LOG_WARN`` and above.
|
||||||
``LOG_LEVEL_DEBUG`` ``LOG_DEBUG`` and above.
|
|
||||||
``LOG_LEVEL_INFO`` ``LOG_INFO`` and above.
|
``LOG_LEVEL_INFO`` ``LOG_INFO`` and above.
|
||||||
``LOG_LEVEL_FUNCTION`` ``LOG_FUNCTION`` and above.
|
``LOG_LEVEL_FUNCTION`` ``LOG_FUNCTION`` and above.
|
||||||
``LOG_LEVEL_LOGIC`` ``LOG_LOGIC`` and above.
|
``LOG_LEVEL_LOGIC`` ``LOG_LOGIC`` and above.
|
||||||
|
``LOG_LEVEL_DEBUG`` ``LOG_DEBUG`` and above.
|
||||||
``LOG_LEVEL_ALL`` All severity classes.
|
``LOG_LEVEL_ALL`` All severity classes.
|
||||||
``LOG_ALL`` Synonym for ``LOG_LEVEL_ALL``
|
``LOG_ALL`` Synonym for ``LOG_LEVEL_ALL``
|
||||||
====================== ===========================================
|
====================== ===========================================
|
||||||
@@ -178,10 +177,10 @@ Class Level
|
|||||||
============ =================
|
============ =================
|
||||||
``error`` ``level_error``
|
``error`` ``level_error``
|
||||||
``warn`` ``level_warn``
|
``warn`` ``level_warn``
|
||||||
``debug`` ``level_debug``
|
|
||||||
``info`` ``level_info``
|
``info`` ``level_info``
|
||||||
``function`` ``level_function``
|
``function`` ``level_function``
|
||||||
``logic`` ``level_logic``
|
``logic`` ``level_logic``
|
||||||
|
``debug`` ``level_debug``
|
||||||
.. | ``level_all``
|
.. | ``level_all``
|
||||||
| ``all``
|
| ``all``
|
||||||
| ``*``
|
| ``*``
|
||||||
@@ -193,8 +192,8 @@ For example, ``NS_LOG="*=warn"`` won't output messages with severity ``error``.
|
|||||||
``debug`` and above.
|
``debug`` and above.
|
||||||
|
|
||||||
Severity classes and levels can be combined with the \`|' operator:
|
Severity classes and levels can be combined with the \`|' operator:
|
||||||
``NS_LOG="*=level_warn|logic"`` will output messages at severity levels
|
``NS_LOG="*=level_warn|debug"`` will output messages at severity levels
|
||||||
``error``, ``warn`` and ``logic``.
|
``error``, ``warn`` and ``debug``, but not ``info``, ``function``, or ``logic``.
|
||||||
|
|
||||||
The ``NS_LOG`` severity level wildcard \`*' and ``all``
|
The ``NS_LOG`` severity level wildcard \`*' and ``all``
|
||||||
are synonyms for ``level_all``.
|
are synonyms for ``level_all``.
|
||||||
@@ -265,10 +264,10 @@ class (``|prefix_level``).
|
|||||||
Scratch Simulator
|
Scratch Simulator
|
||||||
[ERROR] error message
|
[ERROR] error message
|
||||||
[WARN] warn message
|
[WARN] warn message
|
||||||
[DEBUG] debug message
|
|
||||||
[INFO] info message
|
[INFO] info message
|
||||||
[FUNCT] function message
|
[FUNCT] function message
|
||||||
[LOGIC] logic message
|
[LOGIC] logic message
|
||||||
|
[DEBUG] debug message
|
||||||
|
|
||||||
Time Prefix
|
Time Prefix
|
||||||
###########
|
###########
|
||||||
@@ -415,10 +414,10 @@ Logging Macros
|
|||||||
``LOG_NONE`` (none needed)
|
``LOG_NONE`` (none needed)
|
||||||
``LOG_ERROR`` ``NS_LOG_ERROR(...);``
|
``LOG_ERROR`` ``NS_LOG_ERROR(...);``
|
||||||
``LOG_WARN`` ``NS_LOG_WARN(...);``
|
``LOG_WARN`` ``NS_LOG_WARN(...);``
|
||||||
``LOG_DEBUG`` ``NS_LOG_DEBUG(...);``
|
|
||||||
``LOG_INFO`` ``NS_LOG_INFO(...);``
|
``LOG_INFO`` ``NS_LOG_INFO(...);``
|
||||||
``LOG_FUNCTION`` ``NS_LOG_FUNCTION(...);``
|
``LOG_FUNCTION`` ``NS_LOG_FUNCTION(...);``
|
||||||
``LOG_LOGIC`` ``NS_LOG_LOGIC(...);``
|
``LOG_LOGIC`` ``NS_LOG_LOGIC(...);``
|
||||||
|
``LOG_DEBUG`` ``NS_LOG_DEBUG(...);``
|
||||||
================ ==========================
|
================ ==========================
|
||||||
|
|
||||||
The macros function as output streamers, so anything you can send to
|
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``
|
that logging is only enabled in ``debug``, ``default`` and ``relwithdebinfo``
|
||||||
builds, so this macro will only produce output in the same builds.
|
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
|
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.
|
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.
|
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:
|
* For methods without arguments use the same form:
|
||||||
``NS_LOG_FUNCTION(this);``
|
``NS_LOG_FUNCTION(this);``
|
||||||
|
|
||||||
@@ -467,26 +472,49 @@ Guidelines
|
|||||||
* Without arguments use ``NS_LOG_FUNCTION_NOARGS();``
|
* Without arguments use ``NS_LOG_FUNCTION_NOARGS();``
|
||||||
|
|
||||||
* Use ``NS_LOG_ERROR`` for serious error conditions that probably
|
* 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
|
Please give some hints as to the nature of the problem and how
|
||||||
it might be corrected.
|
it might be corrected.
|
||||||
|
|
||||||
* ``NS_LOG_DEBUG`` is usually used in an *ad hoc* way to understand
|
* Use ``NS_LOG_INFO`` for events that cause a state change in the model.
|
||||||
the execution of a 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,
|
* ``NS_LOG_LOGIC`` is used to trace important logic branches or decision points
|
||||||
such as the size of a data structure when adding/removing from it.
|
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.
|
* Test that your logging changes do not break the code.
|
||||||
Run some example programs with all log components turned on (e.g.
|
Run some example programs with all log components turned on (e.g.
|
||||||
``NS_LOG="***"``).
|
``NS_LOG="***"``).
|
||||||
|
|
||||||
* Use an explicit cast for any variable of type uint8_t or int8_t,
|
* Use a unary operator (preferred) or 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));``.
|
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
|
Without the cast, the integer is interpreted as a char, and the result
|
||||||
will be most likely not in line with the expectations.
|
will be most likely not in line with the expectations.
|
||||||
This is a well documented C++ 'feature'.
|
This is a well documented C++ 'feature'.
|
||||||
|
|||||||
@@ -101,10 +101,25 @@ Here is some example code that is written in Python and that runs |ns3|, which i
|
|||||||
Running Python Scripts
|
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
|
Python extensions, the installation instructions may vary, but you can first
|
||||||
check if it installed by seeing if the `cppyy` module can be
|
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
|
.. sourcecode:: bash
|
||||||
|
|
||||||
@@ -113,6 +128,8 @@ successfully imported:
|
|||||||
[GCC 9.4.0] on linux
|
[GCC 9.4.0] on linux
|
||||||
Type "help", "copyright", "credits" or "license" for more information.
|
Type "help", "copyright", "credits" or "license" for more information.
|
||||||
>>> import cppyy
|
>>> import cppyy
|
||||||
|
>>> print("%s" % cppyy.__version)
|
||||||
|
2.4.2
|
||||||
>>>
|
>>>
|
||||||
|
|
||||||
If not, you may try to install via `pip` or whatever other manager you are
|
If not, you may try to install via `pip` or whatever other manager you are
|
||||||
@@ -120,7 +137,7 @@ using; e.g.:
|
|||||||
|
|
||||||
.. sourcecode:: bash
|
.. 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:
|
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
|
.. sourcecode:: bash
|
||||||
|
|
||||||
$ ./ns3 shell
|
$ ./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:
|
and the other is to use the 'run' option to ns3:
|
||||||
|
|
||||||
.. sourcecode:: bash
|
.. 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.
|
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
|
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
|
.. 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:
|
To run a python script under the C debugger:
|
||||||
|
|
||||||
.. sourcecode:: bash
|
.. sourcecode:: bash
|
||||||
|
|
||||||
$ ./ns3 shell
|
$ ./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:
|
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
|
$ ./ns3 shell
|
||||||
$ python3 /path/to/your/example/my-script.py
|
$ 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
|
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
|
like there is Doxygen for the C++ API, but the Doxygen can be consulted
|
||||||
to understand how the C++ API works.
|
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
|
Historical Information
|
||||||
**********************
|
**********************
|
||||||
|
|
||||||
|
|||||||
@@ -423,8 +423,6 @@ We are going to use the aodv module as an example:
|
|||||||
|
|
||||||
.. sourcecode:: python3
|
.. sourcecode:: python3
|
||||||
|
|
||||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
|
||||||
|
|
||||||
def build(bld):
|
def build(bld):
|
||||||
module = bld.create_ns3_module('aodv', ['internet', 'wifi'])
|
module = bld.create_ns3_module('aodv', ['internet', 'wifi'])
|
||||||
module.includes = '.'
|
module.includes = '.'
|
||||||
@@ -521,8 +519,6 @@ steps. We should have something like the following:
|
|||||||
|
|
||||||
.. sourcecode:: python3
|
.. sourcecode:: python3
|
||||||
|
|
||||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
|
||||||
|
|
||||||
def build(bld):
|
def build(bld):
|
||||||
obj = bld.create_ns3_program('aodv',
|
obj = bld.create_ns3_program('aodv',
|
||||||
['wifi', 'internet', 'aodv', 'internet-apps'])
|
['wifi', 'internet', 'aodv', 'internet-apps'])
|
||||||
|
|||||||
@@ -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.
|
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 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.
|
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.
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
Working with gitlab-ci-local
|
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
|
.. _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
|
.. _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/
|
.. _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/
|
.. _rootless mode : https://docs.docker.com/engine/security/rootless/
|
||||||
|
|
||||||
The ns-3 project repository is currently hosted in GitLab, which includes
|
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
|
distribution of software. The CI works based on jobs, that are defined
|
||||||
on YAML files.
|
on YAML files.
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,6 @@ SOURCES = \
|
|||||||
$(SRC)/spectrum/doc/spectrum.rst \
|
$(SRC)/spectrum/doc/spectrum.rst \
|
||||||
$(SRC)/netanim/doc/animation.rst \
|
$(SRC)/netanim/doc/animation.rst \
|
||||||
$(SRC)/flow-monitor/doc/flow-monitor.rst \
|
$(SRC)/flow-monitor/doc/flow-monitor.rst \
|
||||||
$(SRC)/wave/doc/wave.rst \
|
|
||||||
$(SRC)/sixlowpan/doc/sixlowpan.rst \
|
$(SRC)/sixlowpan/doc/sixlowpan.rst \
|
||||||
$(SRC)/lr-wpan/doc/lr-wpan.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/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/default-table-based-error-model-validation.eps \
|
||||||
$(SRC)/wifi/doc/source/figures/error-models-comparison.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)/wimax/doc/WimaxArchitecture.dia \
|
||||||
$(SRC)/lte/doc/source/figures/epc-ctrl-arch.dia \
|
$(SRC)/lte/doc/source/figures/epc-ctrl-arch.dia \
|
||||||
$(SRC)/lte/doc/source/figures/epc-data-flow-dl.dia \
|
$(SRC)/lte/doc/source/figures/epc-data-flow-dl.dia \
|
||||||
|
|||||||
@@ -73,9 +73,9 @@ copyright = u'2006-2019'
|
|||||||
# built documents.
|
# built documents.
|
||||||
#
|
#
|
||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = u'ns-3.38'
|
version = u'ns-3.39'
|
||||||
# The full version, including alpha/beta/rc tags.
|
# 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
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
|
|||||||
@@ -59,6 +59,5 @@ from the ``doc/`` directory of each module. Source file column width is 100 col
|
|||||||
topology
|
topology
|
||||||
traffic-control
|
traffic-control
|
||||||
uan
|
uan
|
||||||
wave
|
|
||||||
wifi
|
wifi
|
||||||
wimax
|
wimax
|
||||||
|
|||||||
@@ -74,6 +74,9 @@
|
|||||||
<div id="mDocs"
|
<div id="mDocs"
|
||||||
onmouseover="mcancelclosetime()"
|
onmouseover="mcancelclosetime()"
|
||||||
onmouseout="mclosetime()">
|
onmouseout="mclosetime()">
|
||||||
|
<a id="ns3_ins"
|
||||||
|
href="/docs/installation/html/index.html"
|
||||||
|
>Installation</a><br/>
|
||||||
<a id="ns3_man"
|
<a id="ns3_man"
|
||||||
href="/docs/manual/html/index.html"
|
href="/docs/manual/html/index.html"
|
||||||
>Manual</a><br/>
|
>Manual</a><br/>
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ $extrastylesheet
|
|||||||
<div id="mDocs"
|
<div id="mDocs"
|
||||||
onmouseover="mcancelclosetime()"
|
onmouseover="mcancelclosetime()"
|
||||||
onmouseout="mclosetime()">
|
onmouseout="mclosetime()">
|
||||||
<a id="ns3_man"
|
<a id="ns3_ins"
|
||||||
href="/docs/installation/html/index.html"
|
href="/docs/installation/html/index.html"
|
||||||
>Installation</a><br/>
|
>Installation</a><br/>
|
||||||
<a id="ns3_man"
|
<a id="ns3_man"
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ div.footer a {
|
|||||||
}
|
}
|
||||||
|
|
||||||
div.related {
|
div.related {
|
||||||
background-color: {{ theme_relbarbgcolor }};
|
background-image: linear-gradient(to bottom, white 0%, transparent 80%);
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
color: {{ theme_relbartextcolor }};
|
color: {{ theme_relbartextcolor }};
|
||||||
}
|
}
|
||||||
@@ -142,9 +142,16 @@ div.sphinxsidebar a {
|
|||||||
}
|
}
|
||||||
|
|
||||||
div.sphinxsidebar input {
|
div.sphinxsidebar input {
|
||||||
border: 1px solid {{ theme_sidebarlinkcolor }};
|
border: 2px solid {{ theme_sidebarlinkcolor }};
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
|
font-weight: bold;
|
||||||
|
background: #f0f1e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.sphinxsidebar input[type="submit"] {
|
||||||
|
background: {{ theme_sidebarlinkcolor }};
|
||||||
|
color: {{theme_sidebartextcolor}};
|
||||||
}
|
}
|
||||||
|
|
||||||
{% if theme_collapsiblesidebar|tobool %}
|
{% if theme_collapsiblesidebar|tobool %}
|
||||||
@@ -196,12 +203,12 @@ div.body h4,
|
|||||||
div.body h5,
|
div.body h5,
|
||||||
div.body h6 {
|
div.body h6 {
|
||||||
font-family: {{ theme_headfont }};
|
font-family: {{ theme_headfont }};
|
||||||
background-color: {{ theme_headbgcolor }};
|
background-color: transparent;
|
||||||
font-weight: normal;
|
font-weight: bold;
|
||||||
color: {{ theme_headtextcolor }};
|
|
||||||
border-bottom: 1px solid #ccc;
|
border-bottom: 1px solid #ccc;
|
||||||
margin: 20px -20px 10px -20px;
|
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%; }
|
div.body h1 { margin-top: 0; font-size: 200%; }
|
||||||
@@ -273,7 +280,7 @@ p.admonition-title:after {
|
|||||||
|
|
||||||
pre {
|
pre {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
background-color: {{ theme_codebgcolor }};
|
background-color: transparent;
|
||||||
color: {{ theme_codetextcolor }};
|
color: {{ theme_codetextcolor }};
|
||||||
line-height: 120%;
|
line-height: 120%;
|
||||||
border: 1px solid #ac9;
|
border: 1px solid #ac9;
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ var ns3_man = ns3_rel + "manual/" + ns3_index;
|
|||||||
var ns3_mod = ns3_rel + "models/" + ns3_index;
|
var ns3_mod = ns3_rel + "models/" + ns3_index;
|
||||||
var ns3_tut = ns3_rel + "tutorial/" + ns3_index;
|
var ns3_tut = ns3_rel + "tutorial/" + ns3_index;
|
||||||
var ns3_con = ns3_rel + "contributing/" + ns3_index;
|
var ns3_con = ns3_rel + "contributing/" + ns3_index;
|
||||||
|
var ns3_ins = ns3_rel + "installation/" + ns3_index;
|
||||||
|
|
||||||
function ns3_write_links() {
|
function ns3_write_links() {
|
||||||
document.getElementById("ns3_home1").href = ns3_home;
|
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_man" ).href = ns3_man;
|
||||||
document.getElementById("ns3_mod" ).href = ns3_mod;
|
document.getElementById("ns3_mod" ).href = ns3_mod;
|
||||||
document.getElementById("ns3_con" ).href = ns3_con;
|
document.getElementById("ns3_con" ).href = ns3_con;
|
||||||
|
document.getElementById("ns3_ins" ).href = ns3_ins;
|
||||||
document.getElementById("ns3_wiki" ).href = ns3_wiki;
|
document.getElementById("ns3_wiki" ).href = ns3_wiki;
|
||||||
document.getElementById("ns3_api" ).href = ns3_api;
|
document.getElementById("ns3_api" ).href = ns3_api;
|
||||||
document.getElementById("ns3_bugs" ).href = ns3_bugs;
|
document.getElementById("ns3_bugs" ).href = ns3_bugs;
|
||||||
|
|||||||
@@ -10,16 +10,27 @@ dl {
|
|||||||
font-size: 12px;
|
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) {
|
@media (prefers-color-scheme: dark) {
|
||||||
body,
|
body,
|
||||||
table,
|
table,
|
||||||
div,
|
div,
|
||||||
p,
|
p,
|
||||||
dl {
|
dl,
|
||||||
|
div.body,
|
||||||
|
div.sphinxsidebar h3,
|
||||||
|
div.sphinxsidebar h4 ,
|
||||||
|
div.sphinxsidebar h3 a{
|
||||||
color: ivory;
|
color: ivory;
|
||||||
|
background:black;
|
||||||
}
|
}
|
||||||
} */
|
div.sphinxsidebar input{
|
||||||
|
background: #2c2d24;
|
||||||
|
}
|
||||||
|
div.related{
|
||||||
|
background-image: linear-gradient(to bottom, #66696a 0%, transparent 80%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: #91A501;
|
color: #91A501;
|
||||||
@@ -27,6 +38,7 @@ a {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Sphinx headings */
|
/* Sphinx headings */
|
||||||
|
/*
|
||||||
div.body h1,
|
div.body h1,
|
||||||
div.body h2,
|
div.body h2,
|
||||||
div.body h3,
|
div.body h3,
|
||||||
@@ -35,6 +47,7 @@ div.body h5,
|
|||||||
div.body h6 {
|
div.body h6 {
|
||||||
background-image: url('nav_f.png');
|
background-image: url('nav_f.png');
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/* Sphinx figure captions */
|
/* Sphinx figure captions */
|
||||||
p.caption {
|
p.caption {
|
||||||
@@ -51,9 +64,11 @@ p.caption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Sphinx nav links bar (relbar) */
|
/* Sphinx nav links bar (relbar) */
|
||||||
|
/*
|
||||||
div.related {
|
div.related {
|
||||||
background-image: url('tab_b.png')
|
background-image: url('tab_b.png')
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
div.related h3 {
|
div.related h3 {
|
||||||
display: none;
|
display: none;
|
||||||
@@ -110,8 +125,8 @@ div.sphinxsidebar a {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#projecttext {
|
#projecttext {
|
||||||
align: left;
|
text-align: left;
|
||||||
font-color: white;
|
color: white;
|
||||||
padding-left: 2em;
|
padding-left: 2em;
|
||||||
width: 250px;
|
width: 250px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ sidebarbtncolor = #D5D5D5
|
|||||||
footerbgcolor = #D5D5D5
|
footerbgcolor = #D5D5D5
|
||||||
footertextcolor = #364D7C
|
footertextcolor = #364D7C
|
||||||
|
|
||||||
codebgcolor = ##FBFCFD
|
codebgcolor = #FBFCFD
|
||||||
codetextcolor = black
|
codetextcolor = black
|
||||||
|
|
||||||
bodyfont = 'Lucida Grande', Verdana, Geneva, Arial, sans-serif
|
bodyfont = 'Lucida Grande', Verdana, Geneva, Arial, sans-serif
|
||||||
|
|||||||
@@ -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
|
nodes. Let's take a look at that script line by line, so go ahead and open
|
||||||
``first.cc`` in your favorite editor.
|
``first.cc`` in your favorite editor.
|
||||||
|
|
||||||
Boilerplate
|
Copyright
|
||||||
+++++++++++
|
+++++++++
|
||||||
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.
|
|
||||||
|
|
||||||
The |ns3| simulator is licensed using the GNU General Public
|
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
|
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
|
in the |ns3| distribution. Often you will see a copyright notice for
|
||||||
|
|||||||
@@ -71,9 +71,9 @@ copyright = u'2006-2019'
|
|||||||
# built documents.
|
# built documents.
|
||||||
#
|
#
|
||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = u'ns-3.38'
|
version = u'ns-3.39'
|
||||||
# The full version, including alpha/beta/rc tags.
|
# 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
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
|
|||||||
@@ -57,20 +57,11 @@ emacs, or Eclipse) and, if using the development repositories, an
|
|||||||
installation of Git source code control system. Most beginning users
|
installation of Git source code control system. Most beginning users
|
||||||
need not concern themselves if their configuration reports some missing
|
need not concern themselves if their configuration reports some missing
|
||||||
optional features of |ns3|, but for those wishing a full installation,
|
optional features of |ns3|, but for those wishing a full installation,
|
||||||
the project provides a wiki that includes pages with many useful hints
|
the project provides an installation guide
|
||||||
and tips. One such page is the "Installation" page, with install instructions
|
|
||||||
for various systems, available at
|
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
|
As of the most recent |ns3| release (ns-3.39), the following tools
|
||||||
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
|
|
||||||
are needed to get started with |ns3|:
|
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
|
To check the default version of Python, type ``python -V``. To check
|
||||||
the default version of g++, type ``g++ -v``. If your installation is
|
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
|
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
|
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
|
$ cd
|
||||||
$ mkdir workspace
|
$ mkdir workspace
|
||||||
$ cd workspace
|
$ cd workspace
|
||||||
$ wget https://www.nsnam.org/release/ns-allinone-3.38.tar.bz2
|
$ wget https://www.nsnam.org/release/ns-allinone-3.39.tar.bz2
|
||||||
$ tar xjf ns-allinone-3.38.tar.bz2
|
$ tar xjf ns-allinone-3.39.tar.bz2
|
||||||
|
|
||||||
Notice the use above of the ``wget`` utility, which is a command-line
|
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,
|
tool to fetch objects from the web; if you do not have this installed,
|
||||||
you can use a browser for this step.
|
you can use a browser for this step.
|
||||||
|
|
||||||
Following these steps, if you change into the directory
|
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
|
.. sourcecode:: text
|
||||||
|
|
||||||
$ cd ns-allinone-3.38
|
$ cd ns-allinone-3.39
|
||||||
$ ls
|
$ 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
|
You are now ready to build the base |ns3| distribution and may skip ahead
|
||||||
to the section on building |ns3|.
|
to the section on building |ns3|.
|
||||||
@@ -188,7 +180,7 @@ release number:
|
|||||||
|
|
||||||
.. sourcecode:: console
|
.. 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,
|
After this step, the additional repositories of |ns3|, bake, pybindgen,
|
||||||
and netanim will be downloaded to the ``ns-3-allinone`` directory.
|
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:
|
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
|
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
|
such as bake build system, netanim animator, and pybindgen
|
||||||
4. ``ns-3-allinone``: similar to the released version of the allinone
|
4. ``ns-3-allinone``: similar to the released version of the allinone
|
||||||
module, but for development code.
|
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"
|
`"ns-3 Releases"
|
||||||
<https://www.nsnam.org/releases>`_
|
<https://www.nsnam.org/releases>`_
|
||||||
web page and clicking on the latest release link. We'll proceed in
|
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
|
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.
|
|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
|
.. 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
|
Next, we'll ask bake to check whether we have enough tools to download
|
||||||
various components. Type:
|
various components. Type:
|
||||||
@@ -352,10 +344,10 @@ should yield something like:
|
|||||||
>> Searching for system dependency g++ - OK
|
>> Searching for system dependency g++ - OK
|
||||||
>> Searching for system dependency cmake - OK
|
>> Searching for system dependency cmake - OK
|
||||||
>> Downloading netanim-3.109 - OK
|
>> Downloading netanim-3.109 - OK
|
||||||
>> Downloading click-ns-3.38 - OK
|
>> Downloading click-ns-3.37 - OK
|
||||||
>> Downloading BRITE - OK
|
>> Downloading BRITE - OK
|
||||||
>> Downloading openflow-dev - 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
|
The above suggests that three sources have been downloaded. Check the
|
||||||
``source`` directory now and type ``ls``; one should see:
|
``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
|
$ cd source
|
||||||
$ ls
|
$ 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.
|
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
|
If you downloaded
|
||||||
using a tarball you should have a directory called something like
|
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:
|
Type the following:
|
||||||
|
|
||||||
.. sourcecode:: console
|
.. sourcecode:: console
|
||||||
@@ -427,7 +419,7 @@ and you should see something like:
|
|||||||
.. sourcecode:: text
|
.. sourcecode:: text
|
||||||
|
|
||||||
>> Building netanim-3.109 - OK
|
>> 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
|
There may be failures to build all components, but the build will proceed
|
||||||
anyway if the component is optional.
|
anyway if the component is optional.
|
||||||
@@ -604,7 +596,6 @@ output that looks similar to the following:
|
|||||||
-- Processing src/traffic-control
|
-- Processing src/traffic-control
|
||||||
-- Processing src/uan
|
-- Processing src/uan
|
||||||
-- Processing src/virtual-net-device
|
-- Processing src/virtual-net-device
|
||||||
-- Processing src/wave
|
|
||||||
-- Processing src/wifi
|
-- Processing src/wifi
|
||||||
-- Processing src/wimax
|
-- Processing src/wimax
|
||||||
-- ---- Summary of optional NS-3 features:
|
-- ---- Summary of optional NS-3 features:
|
||||||
@@ -644,7 +635,7 @@ output that looks similar to the following:
|
|||||||
sixlowpan spectrum stats
|
sixlowpan spectrum stats
|
||||||
tap-bridge test topology-read
|
tap-bridge test topology-read
|
||||||
traffic-control uan virtual-net-device
|
traffic-control uan virtual-net-device
|
||||||
wave wifi wimax
|
wifi wimax
|
||||||
|
|
||||||
|
|
||||||
Modules that cannot be built:
|
Modules that cannot be built:
|
||||||
|
|||||||
@@ -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.
|
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
|
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.
|
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
|
$ 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:
|
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
|
Building and testing ns-3
|
||||||
*************************
|
*************************
|
||||||
|
|||||||
@@ -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
|
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
|
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
|
Apple App Store, and to look at the |ns3| installation guide for more
|
||||||
information (https://www.nsnam.org/wiki/Installation).
|
information (https://www.nsnam.org/docs/installation/html/).
|
||||||
|
|
||||||
Typically an |ns3| author will work in Linux or a Unix-like environment.
|
Typically an |ns3| author will work in Linux or a Unix-like environment.
|
||||||
For those running under Windows, there do exist environments
|
For those running under Windows, there do exist environments
|
||||||
which simulate the Linux environment to various degrees. The |ns3|
|
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
|
installation guide has information about Windows support
|
||||||
these users. See http://www.cygwin.com/
|
(https://www.nsnam.org/docs/installation/html/windows.html).
|
||||||
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.
|
|
||||||
|
|
||||||
Socket Programming
|
Socket Programming
|
||||||
******************
|
******************
|
||||||
|
|||||||
@@ -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
|
example of tracing that can be assembled. You can find this code in
|
||||||
the tutorial directory as ``fourth.cc``. Let's walk through it::
|
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
|
* 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
|
* 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
|
``examples/tutorial/fifth.cc`` in your favorite editor. You should
|
||||||
see some familiar looking code::
|
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
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#! /usr/bin/env python3
|
#! /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
|
# 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
|
# buildable and runnable over time. Each tuple in the list contains
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#! /usr/bin/env python3
|
#! /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
|
# 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
|
# buildable and runnable over time. Each tuple in the list contains
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#! /usr/bin/env python3
|
#! /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
|
# 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
|
# buildable and runnable over time. Each tuple in the list contains
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#! /usr/bin/env python3
|
#! /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
|
# 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
|
# buildable and runnable over time. Each tuple in the list contains
|
||||||
|
|||||||
@@ -33,7 +33,6 @@
|
|||||||
#include "ns3/applications-module.h"
|
#include "ns3/applications-module.h"
|
||||||
#include "ns3/core-module.h"
|
#include "ns3/core-module.h"
|
||||||
#include "ns3/csma-module.h"
|
#include "ns3/csma-module.h"
|
||||||
#include "ns3/internet-apps-module.h"
|
|
||||||
#include "ns3/internet-module.h"
|
#include "ns3/internet-module.h"
|
||||||
#include "ns3/ipv6-routing-table-entry.h"
|
#include "ns3/ipv6-routing-table-entry.h"
|
||||||
#include "ns3/ipv6-static-routing-helper.h"
|
#include "ns3/ipv6-static-routing-helper.h"
|
||||||
|
|||||||
@@ -32,7 +32,6 @@
|
|||||||
#include "ns3/applications-module.h"
|
#include "ns3/applications-module.h"
|
||||||
#include "ns3/core-module.h"
|
#include "ns3/core-module.h"
|
||||||
#include "ns3/csma-module.h"
|
#include "ns3/csma-module.h"
|
||||||
#include "ns3/internet-apps-module.h"
|
|
||||||
#include "ns3/internet-module.h"
|
#include "ns3/internet-module.h"
|
||||||
#include "ns3/ipv6-routing-table-entry.h"
|
#include "ns3/ipv6-routing-table-entry.h"
|
||||||
#include "ns3/ipv6-static-routing-helper.h"
|
#include "ns3/ipv6-static-routing-helper.h"
|
||||||
|
|||||||
@@ -30,7 +30,6 @@
|
|||||||
#include "ns3/applications-module.h"
|
#include "ns3/applications-module.h"
|
||||||
#include "ns3/core-module.h"
|
#include "ns3/core-module.h"
|
||||||
#include "ns3/csma-module.h"
|
#include "ns3/csma-module.h"
|
||||||
#include "ns3/internet-apps-module.h"
|
|
||||||
#include "ns3/internet-module.h"
|
#include "ns3/internet-module.h"
|
||||||
#include "ns3/ipv6-routing-table-entry.h"
|
#include "ns3/ipv6-routing-table-entry.h"
|
||||||
#include "ns3/ipv6-static-routing-helper.h"
|
#include "ns3/ipv6-static-routing-helper.h"
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ using namespace ns3;
|
|||||||
// ---------- Prototypes ------------------------------------------------------
|
// ---------- Prototypes ------------------------------------------------------
|
||||||
|
|
||||||
std::vector<std::vector<bool>> readNxNMatrix(std::string adj_mat_file_name);
|
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 printCoordinateArray(const char* description, std::vector<std::vector<double>> coord_array);
|
||||||
void printMatrix(const char* description, std::vector<std::vector<bool>> 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 -----------------------------------
|
// ---------- Read Node Coordinates File -----------------------------------
|
||||||
|
|
||||||
std::vector<std::vector<double>> coord_array;
|
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
|
// Optionally display node coordinates file
|
||||||
// printCoordinateArray (node_coordinates_file_name.c_str (),coord_array);
|
// 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>>
|
std::vector<std::vector<double>>
|
||||||
readCordinatesFile(std::string node_coordinates_file_name)
|
readCoordinatesFile(std::string node_coordinates_file_name)
|
||||||
{
|
{
|
||||||
std::ifstream node_coordinates_file;
|
std::ifstream node_coordinates_file;
|
||||||
node_coordinates_file.open(node_coordinates_file_name, std::ios::in);
|
node_coordinates_file.open(node_coordinates_file_name, std::ios::in);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#! /usr/bin/env python3
|
#! /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
|
# 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
|
# buildable and runnable over time. Each tuple in the list contains
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ main(int argc, char* argv[])
|
|||||||
outputValidated = false;
|
outputValidated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outputValidated == false)
|
if (!outputValidated)
|
||||||
{
|
{
|
||||||
std::cerr << "Program internal checking failed; returning with error" << std::endl;
|
std::cerr << "Program internal checking failed; returning with error" << std::endl;
|
||||||
return (1);
|
return (1);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#! /usr/bin/env python3
|
#! /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
|
# 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
|
# buildable and runnable over time. Each tuple in the list contains
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ build_example(
|
|||||||
${libolsr}
|
${libolsr}
|
||||||
${libinternet}
|
${libinternet}
|
||||||
${libapplications}
|
${libapplications}
|
||||||
|
${libflow-monitor}
|
||||||
)
|
)
|
||||||
|
|
||||||
build_example(
|
build_example(
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#! /usr/bin/env python3
|
#! /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
|
# 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
|
# buildable and runnable over time. Each tuple in the list contains
|
||||||
|
|||||||
@@ -69,6 +69,7 @@
|
|||||||
#include "ns3/core-module.h"
|
#include "ns3/core-module.h"
|
||||||
#include "ns3/dsdv-module.h"
|
#include "ns3/dsdv-module.h"
|
||||||
#include "ns3/dsr-module.h"
|
#include "ns3/dsr-module.h"
|
||||||
|
#include "ns3/flow-monitor-module.h"
|
||||||
#include "ns3/internet-module.h"
|
#include "ns3/internet-module.h"
|
||||||
#include "ns3/mobility-module.h"
|
#include "ns3/mobility-module.h"
|
||||||
#include "ns3/network-module.h"
|
#include "ns3/network-module.h"
|
||||||
@@ -94,20 +95,15 @@ class RoutingExperiment
|
|||||||
RoutingExperiment();
|
RoutingExperiment();
|
||||||
/**
|
/**
|
||||||
* Run the experiment.
|
* 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);
|
void Run();
|
||||||
// static void SetMACParam (ns3::NetDeviceContainer & devices,
|
|
||||||
// int slotDistance);
|
|
||||||
/**
|
/**
|
||||||
* Handles the command-line parameters.
|
* Handles the command-line parameters.
|
||||||
* \param argc The argument count.
|
* \param argc The argument count.
|
||||||
* \param argv The argument vector.
|
* \param argv The argument vector.
|
||||||
* \return the CSV filename.
|
|
||||||
*/
|
*/
|
||||||
std::string CommandSetup(int argc, char** argv);
|
void CommandSetup(int argc, char** argv);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
@@ -127,25 +123,19 @@ class RoutingExperiment
|
|||||||
*/
|
*/
|
||||||
void CheckThroughput();
|
void CheckThroughput();
|
||||||
|
|
||||||
uint32_t port; //!< Receiving port number.
|
uint32_t port{9}; //!< Receiving port number.
|
||||||
uint32_t bytesTotal; //!< Total received bytes.
|
uint32_t bytesTotal{0}; //!< Total received bytes.
|
||||||
uint32_t packetsReceived; //!< Total received packets.
|
uint32_t packetsReceived{0}; //!< Total received packets.
|
||||||
|
|
||||||
std::string m_CSVfileName; //!< CSV filename.
|
std::string m_CSVfileName{"manet-routing.output.csv"}; //!< CSV filename.
|
||||||
int m_nSinks; //!< Number of sink nodes.
|
int m_nSinks{10}; //!< Number of sink nodes.
|
||||||
std::string m_protocolName; //!< Protocol name.
|
std::string m_protocolName{"AODV"}; //!< Protocol name.
|
||||||
double m_txp; //!< Tx power.
|
double m_txp{7.5}; //!< Tx power.
|
||||||
bool m_traceMobility; //!< Enavle mobility tracing.
|
bool m_traceMobility{false}; //!< Enable mobility tracing.
|
||||||
uint32_t m_protocol; //!< Protocol type.
|
bool m_flowMonitor{false}; //!< Enable FlowMonitor.
|
||||||
};
|
};
|
||||||
|
|
||||||
RoutingExperiment::RoutingExperiment()
|
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;
|
return sink;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
void
|
||||||
RoutingExperiment::CommandSetup(int argc, char** argv)
|
RoutingExperiment::CommandSetup(int argc, char** argv)
|
||||||
{
|
{
|
||||||
CommandLine cmd(__FILE__);
|
CommandLine cmd(__FILE__);
|
||||||
cmd.AddValue("CSVfileName", "The name of the CSV output file name", m_CSVfileName);
|
cmd.AddValue("CSVfileName", "The name of the CSV output file name", m_CSVfileName);
|
||||||
cmd.AddValue("traceMobility", "Enable mobility tracing", m_traceMobility);
|
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);
|
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
|
int
|
||||||
main(int argc, char* argv[])
|
main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
RoutingExperiment experiment;
|
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
|
// blank out the last output file and write the column headers
|
||||||
std::ofstream out(CSVfileName);
|
std::ofstream out(m_CSVfileName);
|
||||||
out << "SimulationSecond,"
|
out << "SimulationSecond,"
|
||||||
<< "ReceiveRate,"
|
<< "ReceiveRate,"
|
||||||
<< "PacketsReceived,"
|
<< "PacketsReceived,"
|
||||||
@@ -236,22 +243,6 @@ main(int argc, char* argv[])
|
|||||||
<< "TransmissionPower" << std::endl;
|
<< "TransmissionPower" << std::endl;
|
||||||
out.close();
|
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;
|
int nWifis = 50;
|
||||||
|
|
||||||
double TotalTime = 200.0;
|
double TotalTime = 200.0;
|
||||||
@@ -260,7 +251,6 @@ RoutingExperiment::Run(int nSinks, double txp, std::string CSVfileName)
|
|||||||
std::string tr_name("manet-routing-compare");
|
std::string tr_name("manet-routing-compare");
|
||||||
int nodeSpeed = 20; // in m/s
|
int nodeSpeed = 20; // in m/s
|
||||||
int nodePause = 0; // in s
|
int nodePause = 0; // in s
|
||||||
m_protocolName = "protocol";
|
|
||||||
|
|
||||||
Config::SetDefault("ns3::OnOffApplication::PacketSize", StringValue("64"));
|
Config::SetDefault("ns3::OnOffApplication::PacketSize", StringValue("64"));
|
||||||
Config::SetDefault("ns3::OnOffApplication::DataRate", StringValue(rate));
|
Config::SetDefault("ns3::OnOffApplication::DataRate", StringValue(rate));
|
||||||
@@ -289,8 +279,8 @@ RoutingExperiment::Run(int nSinks, double txp, std::string CSVfileName)
|
|||||||
"ControlMode",
|
"ControlMode",
|
||||||
StringValue(phyMode));
|
StringValue(phyMode));
|
||||||
|
|
||||||
wifiPhy.Set("TxPowerStart", DoubleValue(txp));
|
wifiPhy.Set("TxPowerStart", DoubleValue(m_txp));
|
||||||
wifiPhy.Set("TxPowerEnd", DoubleValue(txp));
|
wifiPhy.Set("TxPowerEnd", DoubleValue(m_txp));
|
||||||
|
|
||||||
wifiMac.SetType("ns3::AdhocWifiMac");
|
wifiMac.SetType("ns3::AdhocWifiMac");
|
||||||
NetDeviceContainer adhocDevices = wifi.Install(wifiPhy, wifiMac, adhocNodes);
|
NetDeviceContainer adhocDevices = wifi.Install(wifiPhy, wifiMac, adhocNodes);
|
||||||
@@ -329,36 +319,36 @@ RoutingExperiment::Run(int nSinks, double txp, std::string CSVfileName)
|
|||||||
Ipv4ListRoutingHelper list;
|
Ipv4ListRoutingHelper list;
|
||||||
InternetStackHelper internet;
|
InternetStackHelper internet;
|
||||||
|
|
||||||
switch (m_protocol)
|
if (m_protocolName == "OLSR")
|
||||||
{
|
{
|
||||||
case 1:
|
|
||||||
list.Add(olsr, 100);
|
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.SetRoutingHelper(list);
|
||||||
internet.Install(adhocNodes);
|
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);
|
internet.Install(adhocNodes);
|
||||||
dsrMain.Install(dsr, 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");
|
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("OnTime", StringValue("ns3::ConstantRandomVariable[Constant=1.0]"));
|
||||||
onoff1.SetAttribute("OffTime", StringValue("ns3::ConstantRandomVariable[Constant=0.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));
|
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);
|
onoff1.SetAttribute("Remote", remoteAddress);
|
||||||
|
|
||||||
Ptr<UniformRandomVariable> var = CreateObject<UniformRandomVariable>();
|
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.Start(Seconds(var->GetValue(100.0, 101.0)));
|
||||||
temp.Stop(Seconds(TotalTime));
|
temp.Stop(Seconds(TotalTime));
|
||||||
}
|
}
|
||||||
@@ -411,9 +401,12 @@ RoutingExperiment::Run(int nSinks, double txp, std::string CSVfileName)
|
|||||||
AsciiTraceHelper ascii;
|
AsciiTraceHelper ascii;
|
||||||
MobilityHelper::EnableAsciiAll(ascii.CreateFileStream(tr_name + ".mob"));
|
MobilityHelper::EnableAsciiAll(ascii.CreateFileStream(tr_name + ".mob"));
|
||||||
|
|
||||||
// Ptr<FlowMonitor> flowmon;
|
FlowMonitorHelper flowmonHelper;
|
||||||
// FlowMonitorHelper flowmonHelper;
|
Ptr<FlowMonitor> flowmon;
|
||||||
// flowmon = flowmonHelper.InstallAll();
|
if (m_flowMonitor)
|
||||||
|
{
|
||||||
|
flowmon = flowmonHelper.InstallAll();
|
||||||
|
}
|
||||||
|
|
||||||
NS_LOG_INFO("Run Simulation.");
|
NS_LOG_INFO("Run Simulation.");
|
||||||
|
|
||||||
@@ -422,7 +415,10 @@ RoutingExperiment::Run(int nSinks, double txp, std::string CSVfileName)
|
|||||||
Simulator::Stop(Seconds(TotalTime));
|
Simulator::Stop(Seconds(TotalTime));
|
||||||
Simulator::Run();
|
Simulator::Run();
|
||||||
|
|
||||||
// flowmon->SerializeToXmlFile(tr_name + ".flowmon", false, false);
|
if (m_flowMonitor)
|
||||||
|
{
|
||||||
|
flowmon->SerializeToXmlFile(tr_name + ".flowmon", false, false);
|
||||||
|
}
|
||||||
|
|
||||||
Simulator::Destroy();
|
Simulator::Destroy();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
//
|
//
|
||||||
// - UDP flows from n0 to n1
|
// - UDP flows from n0 to n1
|
||||||
|
|
||||||
#include "ns3/applications-module.h"
|
|
||||||
#include "ns3/core-module.h"
|
#include "ns3/core-module.h"
|
||||||
#include "ns3/csma-module.h"
|
#include "ns3/csma-module.h"
|
||||||
#include "ns3/internet-module.h"
|
#include "ns3/internet-module.h"
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
//
|
//
|
||||||
// - UDP flows from n0 to n1
|
// - UDP flows from n0 to n1
|
||||||
|
|
||||||
#include "ns3/applications-module.h"
|
|
||||||
#include "ns3/core-module.h"
|
#include "ns3/core-module.h"
|
||||||
#include "ns3/csma-module.h"
|
#include "ns3/csma-module.h"
|
||||||
#include "ns3/internet-module.h"
|
#include "ns3/internet-module.h"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#! /usr/bin/env python3
|
#! /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
|
# 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
|
# buildable and runnable over time. Each tuple in the list contains
|
||||||
|
|||||||
@@ -301,8 +301,6 @@ main(int argc, char* argv[])
|
|||||||
Time startTime = Seconds(0);
|
Time startTime = Seconds(0);
|
||||||
Time stopTime = flowStartupWindow + convergenceTime + measurementWindow;
|
Time stopTime = flowStartupWindow + convergenceTime + measurementWindow;
|
||||||
|
|
||||||
Time clientStartTime = startTime;
|
|
||||||
|
|
||||||
rxS1R1Bytes.reserve(10);
|
rxS1R1Bytes.reserve(10);
|
||||||
rxS2R2Bytes.reserve(20);
|
rxS2R2Bytes.reserve(20);
|
||||||
rxS3R1Bytes.reserve(10);
|
rxS3R1Bytes.reserve(10);
|
||||||
@@ -493,7 +491,7 @@ main(int argc, char* argv[])
|
|||||||
AddressValue remoteAddress(InetSocketAddress(ipR2T2[i].GetAddress(0), port));
|
AddressValue remoteAddress(InetSocketAddress(ipR2T2[i].GetAddress(0), port));
|
||||||
clientHelper1.SetAttribute("Remote", remoteAddress);
|
clientHelper1.SetAttribute("Remote", remoteAddress);
|
||||||
clientApps1.Add(clientHelper1.Install(S2.Get(i)));
|
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);
|
clientApps1.Stop(stopTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -534,13 +532,12 @@ main(int argc, char* argv[])
|
|||||||
if (i < 10)
|
if (i < 10)
|
||||||
{
|
{
|
||||||
clientApps1.Add(clientHelper1.Install(S1.Get(i)));
|
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
|
else
|
||||||
{
|
{
|
||||||
clientApps1.Add(clientHelper1.Install(S3.Get(i - 10)));
|
clientApps1.Add(clientHelper1.Install(S3.Get(i - 10)));
|
||||||
clientApps1.Start((i - 10) * flowStartupWindow / 10 + clientStartTime +
|
clientApps1.Start((i - 10) * flowStartupWindow / 10 + startTime + MilliSeconds(i * 5));
|
||||||
MilliSeconds(i * 5));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clientApps1.Stop(stopTime);
|
clientApps1.Stop(stopTime);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#! /usr/bin/env python3
|
#! /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
|
# 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
|
# buildable and runnable over time. Each tuple in the list contains
|
||||||
|
|||||||
@@ -746,7 +746,7 @@ main(int argc, char* argv[])
|
|||||||
firstTcpTypeId = TcpDctcp::GetTypeId();
|
firstTcpTypeId = TcpDctcp::GetTypeId();
|
||||||
Config::SetDefault("ns3::CoDelQueueDisc::CeThreshold", TimeValue(ceThreshold));
|
Config::SetDefault("ns3::CoDelQueueDisc::CeThreshold", TimeValue(ceThreshold));
|
||||||
Config::SetDefault("ns3::FqCoDelQueueDisc::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;
|
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));
|
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
|
// but the Ipv4AddressHelper below will install the default FqCoDelQueueDisc
|
||||||
// on all single device nodes. The below code overrides the configuration
|
// on all single device nodes. The below code overrides the configuration
|
||||||
// that is normally done by the Ipv4AddressHelper::Install() method by
|
// that is normally done by the Ipv4AddressHelper::Install() method by
|
||||||
|
|||||||
@@ -79,8 +79,8 @@ static std::map<uint32_t, uint32_t> ssThreshValue; //!< SlowSta
|
|||||||
static uint32_t
|
static uint32_t
|
||||||
GetNodeIdFromContext(std::string context)
|
GetNodeIdFromContext(std::string context)
|
||||||
{
|
{
|
||||||
std::size_t const n1 = context.find_first_of('/', 1);
|
const std::size_t n1 = context.find_first_of('/', 1);
|
||||||
std::size_t const n2 = context.find_first_of('/', n1 + 1);
|
const std::size_t n2 = context.find_first_of('/', n1 + 1);
|
||||||
return std::stoul(context.substr(n1 + 1, n2 - n1 - 1));
|
return std::stoul(context.substr(n1 + 1, n2 - n1 - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#! /usr/bin/env python3
|
#! /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
|
# 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
|
# buildable and runnable over time. Each tuple in the list contains
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#! /usr/bin/env python3
|
#! /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
|
# 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
|
# buildable and runnable over time. Each tuple in the list contains
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ main(int argc, char* argv[])
|
|||||||
Address anyAddress;
|
Address anyAddress;
|
||||||
std::string probeType;
|
std::string probeType;
|
||||||
std::string tracePath;
|
std::string tracePath;
|
||||||
if (useV6 == false)
|
if (!useV6)
|
||||||
{
|
{
|
||||||
Ipv4AddressHelper address;
|
Ipv4AddressHelper address;
|
||||||
address.SetBase("10.1.1.0", "255.255.255.0");
|
address.SetBase("10.1.1.0", "255.255.255.0");
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ main(int argc, char* argv[])
|
|||||||
NetDeviceContainer d = csma.Install(n);
|
NetDeviceContainer d = csma.Install(n);
|
||||||
|
|
||||||
NS_LOG_INFO("Assign IP Addresses.");
|
NS_LOG_INFO("Assign IP Addresses.");
|
||||||
if (useV6 == false)
|
if (!useV6)
|
||||||
{
|
{
|
||||||
Ipv4AddressHelper ipv4;
|
Ipv4AddressHelper ipv4;
|
||||||
ipv4.SetBase("10.1.1.0", "255.255.255.0");
|
ipv4.SetBase("10.1.1.0", "255.255.255.0");
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ main(int argc, char* argv[])
|
|||||||
NetDeviceContainer d = csma.Install(n);
|
NetDeviceContainer d = csma.Install(n);
|
||||||
|
|
||||||
NS_LOG_INFO("Assign IP Addresses.");
|
NS_LOG_INFO("Assign IP Addresses.");
|
||||||
if (useV6 == false)
|
if (!useV6)
|
||||||
{
|
{
|
||||||
Ipv4AddressHelper ipv4;
|
Ipv4AddressHelper ipv4;
|
||||||
ipv4.SetBase("10.1.1.0", "255.255.255.0");
|
ipv4.SetBase("10.1.1.0", "255.255.255.0");
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#! /usr/bin/env python3
|
#! /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
|
# 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
|
# buildable and runnable over time. Each tuple in the list contains
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ main(int argc, char* argv[])
|
|||||||
// We've got the "hardware" in place. Now we need to add IP addresses.
|
// We've got the "hardware" in place. Now we need to add IP addresses.
|
||||||
//
|
//
|
||||||
NS_LOG_INFO("Assign IP Addresses.");
|
NS_LOG_INFO("Assign IP Addresses.");
|
||||||
if (useV6 == false)
|
if (!useV6)
|
||||||
{
|
{
|
||||||
Ipv4AddressHelper ipv4;
|
Ipv4AddressHelper ipv4;
|
||||||
ipv4.SetBase("10.1.1.0", "255.255.255.0");
|
ipv4.SetBase("10.1.1.0", "255.255.255.0");
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#! /usr/bin/env python3
|
#! /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
|
# 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
|
# 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::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::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-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-power-adaptation-interference --simuTime=5", "True", "False"),
|
||||||
("wifi-dsss-validation", "True", "True"),
|
("wifi-dsss-validation", "True", "True"),
|
||||||
("wifi-ofdm-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=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=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.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.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.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"),
|
("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"),
|
||||||
|
|||||||
@@ -414,7 +414,7 @@ main(int argc, char* argv[])
|
|||||||
// pcap trace on the application data sink
|
// pcap trace on the application data sink
|
||||||
wifiPhy.EnablePcap("mixed-wireless", appSink->GetId(), 0);
|
wifiPhy.EnablePcap("mixed-wireless", appSink->GetId(), 0);
|
||||||
|
|
||||||
if (useCourseChangeCallback == true)
|
if (useCourseChangeCallback)
|
||||||
{
|
{
|
||||||
Config::Connect("/NodeList/*/$ns3::MobilityModel/CourseChange",
|
Config::Connect("/NodeList/*/$ns3::MobilityModel/CourseChange",
|
||||||
MakeCallback(&CourseChangeCallback));
|
MakeCallback(&CourseChangeCallback));
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ def main(argv):
|
|||||||
cmd.AddValue("backboneNodes", "number of backbone nodes", backboneNodes)
|
cmd.AddValue("backboneNodes", "number of backbone nodes", backboneNodes)
|
||||||
cmd.AddValue("infraNodes", "number of leaf nodes", infraNodes)
|
cmd.AddValue("infraNodes", "number of leaf nodes", infraNodes)
|
||||||
cmd.AddValue("lanNodes", "number of LAN nodes", lanNodes)
|
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
|
# The system global variables and the local values added to the argument
|
||||||
|
|||||||
@@ -175,8 +175,7 @@ Experiment::Run(const WifiHelper& wifi,
|
|||||||
YansWifiPhyHelper phy = wifiPhy;
|
YansWifiPhyHelper phy = wifiPhy;
|
||||||
phy.SetChannel(wifiChannel.Create());
|
phy.SetChannel(wifiChannel.Create());
|
||||||
|
|
||||||
WifiMacHelper mac = wifiMac;
|
NetDeviceContainer devices = wifi.Install(phy, wifiMac, c);
|
||||||
NetDeviceContainer devices = wifi.Install(phy, mac, c);
|
|
||||||
|
|
||||||
MobilityHelper mobility;
|
MobilityHelper mobility;
|
||||||
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
|
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
|
||||||
|
|||||||
@@ -183,8 +183,7 @@ Experiment::Run(const WifiHelper& wifi,
|
|||||||
YansWifiPhyHelper phy = wifiPhy;
|
YansWifiPhyHelper phy = wifiPhy;
|
||||||
phy.SetChannel(wifiChannel.Create());
|
phy.SetChannel(wifiChannel.Create());
|
||||||
|
|
||||||
WifiMacHelper mac = wifiMac;
|
NetDeviceContainer devices = wifi.Install(phy, wifiMac, c);
|
||||||
NetDeviceContainer devices = wifi.Install(phy, mac, c);
|
|
||||||
|
|
||||||
MobilityHelper mobility;
|
MobilityHelper mobility;
|
||||||
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
|
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022
|
* Copyright (c) 2022
|
||||||
*
|
*
|
||||||
@@ -244,11 +243,8 @@ main(int argc, char* argv[])
|
|||||||
"AGGR-MU-BAR)");
|
"AGGR-MU-BAR)");
|
||||||
}
|
}
|
||||||
|
|
||||||
double prevThroughput[12];
|
double prevThroughput[12] = {0};
|
||||||
for (uint32_t l = 0; l < 12; l++)
|
|
||||||
{
|
|
||||||
prevThroughput[l] = 0;
|
|
||||||
}
|
|
||||||
std::cout << "MCS value"
|
std::cout << "MCS value"
|
||||||
<< "\t\t"
|
<< "\t\t"
|
||||||
<< "Channel width"
|
<< "Channel width"
|
||||||
|
|||||||
@@ -167,11 +167,8 @@ main(int argc, char* argv[])
|
|||||||
phyModel = "Spectrum";
|
phyModel = "Spectrum";
|
||||||
}
|
}
|
||||||
|
|
||||||
double prevThroughput[12];
|
double prevThroughput[12] = {0};
|
||||||
for (uint32_t l = 0; l < 12; l++)
|
|
||||||
{
|
|
||||||
prevThroughput[l] = 0;
|
|
||||||
}
|
|
||||||
std::cout << "MCS value"
|
std::cout << "MCS value"
|
||||||
<< "\t\t"
|
<< "\t\t"
|
||||||
<< "Channel width"
|
<< "Channel width"
|
||||||
|
|||||||
@@ -96,11 +96,8 @@ main(int argc, char* argv[])
|
|||||||
Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue("0"));
|
Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue("0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
double prevThroughput[8];
|
double prevThroughput[8] = {0};
|
||||||
for (uint32_t l = 0; l < 8; l++)
|
|
||||||
{
|
|
||||||
prevThroughput[l] = 0;
|
|
||||||
}
|
|
||||||
std::cout << "MCS value"
|
std::cout << "MCS value"
|
||||||
<< "\t\t"
|
<< "\t\t"
|
||||||
<< "Channel width"
|
<< "Channel width"
|
||||||
|
|||||||
@@ -505,8 +505,7 @@ Experiment::Run(const WifiHelper& wifi,
|
|||||||
YansWifiPhyHelper phy = wifiPhy;
|
YansWifiPhyHelper phy = wifiPhy;
|
||||||
phy.SetChannel(wifiChannel.Create());
|
phy.SetChannel(wifiChannel.Create());
|
||||||
|
|
||||||
WifiMacHelper mac = wifiMac;
|
NetDeviceContainer devices = wifi.Install(phy, wifiMac, c);
|
||||||
NetDeviceContainer devices = wifi.Install(phy, mac, c);
|
|
||||||
|
|
||||||
OlsrHelper olsr;
|
OlsrHelper olsr;
|
||||||
Ipv4StaticRoutingHelper staticRouting;
|
Ipv4StaticRoutingHelper staticRouting;
|
||||||
|
|||||||
@@ -56,6 +56,7 @@
|
|||||||
#include "ns3/boolean.h"
|
#include "ns3/boolean.h"
|
||||||
#include "ns3/command-line.h"
|
#include "ns3/command-line.h"
|
||||||
#include "ns3/config.h"
|
#include "ns3/config.h"
|
||||||
|
#include "ns3/double.h"
|
||||||
#include "ns3/gnuplot.h"
|
#include "ns3/gnuplot.h"
|
||||||
#include "ns3/internet-stack-helper.h"
|
#include "ns3/internet-stack-helper.h"
|
||||||
#include "ns3/ipv4-address-helper.h"
|
#include "ns3/ipv4-address-helper.h"
|
||||||
@@ -65,6 +66,7 @@
|
|||||||
#include "ns3/on-off-helper.h"
|
#include "ns3/on-off-helper.h"
|
||||||
#include "ns3/packet-sink-helper.h"
|
#include "ns3/packet-sink-helper.h"
|
||||||
#include "ns3/ssid.h"
|
#include "ns3/ssid.h"
|
||||||
|
#include "ns3/string.h"
|
||||||
#include "ns3/uinteger.h"
|
#include "ns3/uinteger.h"
|
||||||
#include "ns3/yans-wifi-channel.h"
|
#include "ns3/yans-wifi-channel.h"
|
||||||
#include "ns3/yans-wifi-helper.h"
|
#include "ns3/yans-wifi-helper.h"
|
||||||
@@ -168,10 +170,16 @@ NodeStatistics::GetDatafile()
|
|||||||
return m_output;
|
return m_output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for 'Rate' trace source
|
||||||
|
*
|
||||||
|
* \param oldRate old MCS rate (bits/sec)
|
||||||
|
* \param newRate new MCS rate (bits/sec)
|
||||||
|
*/
|
||||||
void
|
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
|
int
|
||||||
@@ -194,9 +202,9 @@ main(int argc, char* argv[])
|
|||||||
int stepsTime = 1;
|
int stepsTime = 1;
|
||||||
|
|
||||||
CommandLine cmd(__FILE__);
|
CommandLine cmd(__FILE__);
|
||||||
cmd.AddValue("staManager", "PRC Manager of the STA", staManager);
|
cmd.AddValue("staManager", "Rate adaptation manager of the STA", staManager);
|
||||||
cmd.AddValue("apManager", "PRC Manager of the AP", apManager);
|
cmd.AddValue("apManager", "Rate adaptation manager of the AP", apManager);
|
||||||
cmd.AddValue("standard", "Wifi Phy Standard", standard);
|
cmd.AddValue("standard", "Wifi standard (a/b/g/n/ac only)", standard);
|
||||||
cmd.AddValue("shortGuardInterval",
|
cmd.AddValue("shortGuardInterval",
|
||||||
"Enable Short Guard Interval in all stations",
|
"Enable Short Guard Interval in all stations",
|
||||||
shortGuardInterval);
|
shortGuardInterval);
|
||||||
@@ -215,6 +223,12 @@ main(int argc, char* argv[])
|
|||||||
|
|
||||||
int simuTime = steps * stepsTime;
|
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
|
// Define the APs
|
||||||
NodeContainer wifiApNodes;
|
NodeContainer wifiApNodes;
|
||||||
wifiApNodes.Create(1);
|
wifiApNodes.Create(1);
|
||||||
@@ -226,6 +240,30 @@ main(int argc, char* argv[])
|
|||||||
YansWifiPhyHelper wifiPhy;
|
YansWifiPhyHelper wifiPhy;
|
||||||
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default();
|
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default();
|
||||||
wifiPhy.SetChannel(wifiChannel.Create());
|
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 wifiApDevices;
|
||||||
NetDeviceContainer wifiStaDevices;
|
NetDeviceContainer wifiStaDevices;
|
||||||
@@ -296,10 +334,6 @@ main(int argc, char* argv[])
|
|||||||
wifiDevices.Add(wifiStaDevices);
|
wifiDevices.Add(wifiStaDevices);
|
||||||
wifiDevices.Add(wifiApDevices);
|
wifiDevices.Add(wifiApDevices);
|
||||||
|
|
||||||
// Set channel width
|
|
||||||
Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/ChannelWidth",
|
|
||||||
UintegerValue(chWidth));
|
|
||||||
|
|
||||||
// Set guard interval
|
// Set guard interval
|
||||||
Config::Set(
|
Config::Set(
|
||||||
"/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/HtConfiguration/ShortGuardIntervalSupported",
|
"/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/HtConfiguration/ShortGuardIntervalSupported",
|
||||||
@@ -359,9 +393,9 @@ main(int argc, char* argv[])
|
|||||||
MakeCallback(&NodeStatistics::RxCallback, &atpCounter));
|
MakeCallback(&NodeStatistics::RxCallback, &atpCounter));
|
||||||
|
|
||||||
// Callbacks to print every change of rate
|
// Callbacks to print every change of rate
|
||||||
Config::ConnectFailSafe("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/RemoteStationManager/$" +
|
Config::ConnectWithoutContextFailSafe(
|
||||||
apManager + "/RateChange",
|
"/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/RemoteStationManager/$" + apManager + "/Rate",
|
||||||
MakeCallback(RateCallback));
|
MakeCallback(RateCallback));
|
||||||
|
|
||||||
Simulator::Stop(Seconds(simuTime));
|
Simulator::Stop(Seconds(simuTime));
|
||||||
Simulator::Run();
|
Simulator::Run();
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ main(int argc, char* argv[])
|
|||||||
InetSocketAddress remote = InetSocketAddress(i.GetAddress(sinkNode, 0), 80);
|
InetSocketAddress remote = InetSocketAddress(i.GetAddress(sinkNode, 0), 80);
|
||||||
source->Connect(remote);
|
source->Connect(remote);
|
||||||
|
|
||||||
if (tracing == true)
|
if (tracing)
|
||||||
{
|
{
|
||||||
AsciiTraceHelper ascii;
|
AsciiTraceHelper ascii;
|
||||||
wifiPhy.EnableAsciiAll(ascii.CreateFileStream("wifi-simple-adhoc-grid.tr"));
|
wifiPhy.EnableAsciiAll(ascii.CreateFileStream("wifi-simple-adhoc-grid.tr"));
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
// time.
|
// time.
|
||||||
//
|
//
|
||||||
// Note that, by default, this script configures a network using a
|
// 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
|
// the --channelWidth argument) without properly adjusting other
|
||||||
// parameters will void the effect of spatial reuse: since energy is
|
// parameters will void the effect of spatial reuse: since energy is
|
||||||
// measured over the 20 MHz primary channel regardless of the channel
|
// 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.
|
// all these values by 3 dB compared to their defaults.
|
||||||
//
|
//
|
||||||
// In addition, consider that adapting the adjustments shown above
|
// 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
|
// of 3 dB) will not produce any changes when enableObssPd is enabled
|
||||||
// or disabled. The cause for this is the insufficient amount of
|
// or disabled. The cause for this is the insufficient amount of
|
||||||
// traffic that is generated by default in the example: increasing
|
// 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
|
// collision probability. Collisions between BSSs are a necessary
|
||||||
// condition to see the improvements brought by spatial reuse, and
|
// condition to see the improvements brought by spatial reuse, and
|
||||||
// thus increasing the amount of generated traffic by setting the
|
// thus increasing the amount of generated traffic by setting the
|
||||||
@@ -134,7 +134,7 @@ main(int argc, char* argv[])
|
|||||||
double ccaEdTrAp1 = -62; // dBm
|
double ccaEdTrAp1 = -62; // dBm
|
||||||
double ccaEdTrAp2 = -62; // dBm
|
double ccaEdTrAp2 = -62; // dBm
|
||||||
double minimumRssi = -82; // dBm
|
double minimumRssi = -82; // dBm
|
||||||
int channelBandwidth = 20; // MHz
|
int channelWidth = 20; // MHz
|
||||||
uint32_t payloadSize = 1500; // bytes
|
uint32_t payloadSize = 1500; // bytes
|
||||||
uint32_t mcs = 0; // MCS value
|
uint32_t mcs = 0; // MCS value
|
||||||
double interval = 0.001; // seconds
|
double interval = 0.001; // seconds
|
||||||
@@ -159,9 +159,7 @@ main(int argc, char* argv[])
|
|||||||
cmd.AddValue("minimumRssi",
|
cmd.AddValue("minimumRssi",
|
||||||
"Minimum RSSI for the ThresholdPreambleDetectionModel",
|
"Minimum RSSI for the ThresholdPreambleDetectionModel",
|
||||||
minimumRssi);
|
minimumRssi);
|
||||||
cmd.AddValue("channelBandwidth",
|
cmd.AddValue("channelWidth", "Bandwidth of the channel in MHz [20, 40, or 80]", channelWidth);
|
||||||
"Bandwidth of the channel in MHz [20, 40, or 80]",
|
|
||||||
channelBandwidth);
|
|
||||||
cmd.AddValue("obssPdThreshold", "Threshold for the OBSS PD Algorithm", obssPdThreshold);
|
cmd.AddValue("obssPdThreshold", "Threshold for the OBSS PD Algorithm", obssPdThreshold);
|
||||||
cmd.AddValue("mcs", "The constant MCS value to transmit HE PPDUs", mcs);
|
cmd.AddValue("mcs", "The constant MCS value to transmit HE PPDUs", mcs);
|
||||||
cmd.Parse(argc, argv);
|
cmd.Parse(argc, argv);
|
||||||
@@ -182,7 +180,7 @@ main(int argc, char* argv[])
|
|||||||
|
|
||||||
spectrumPhy.SetChannel(spectrumChannel);
|
spectrumPhy.SetChannel(spectrumChannel);
|
||||||
spectrumPhy.SetErrorRateModel("ns3::YansErrorRateModel");
|
spectrumPhy.SetErrorRateModel("ns3::YansErrorRateModel");
|
||||||
switch (channelBandwidth)
|
switch (channelWidth)
|
||||||
{
|
{
|
||||||
case 20:
|
case 20:
|
||||||
spectrumPhy.Set("ChannelSettings", StringValue("{36, 20, BAND_5GHZ, 0}"));
|
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}"));
|
spectrumPhy.Set("ChannelSettings", StringValue("{171, 80, BAND_5GHZ, 0}"));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
NS_ABORT_MSG("Unrecognized channel bandwidth: " << channelBandwidth);
|
NS_ABORT_MSG("Unrecognized channel width: " << channelWidth);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
spectrumPhy.SetPreambleDetectionModel("ns3::ThresholdPreambleDetectionModel",
|
spectrumPhy.SetPreambleDetectionModel("ns3::ThresholdPreambleDetectionModel",
|
||||||
|
|||||||
@@ -90,11 +90,8 @@ main(int argc, char* argv[])
|
|||||||
Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue("0"));
|
Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue("0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
double prevThroughput[8];
|
double prevThroughput[8] = {0};
|
||||||
for (uint32_t l = 0; l < 8; l++)
|
|
||||||
{
|
|
||||||
prevThroughput[l] = 0;
|
|
||||||
}
|
|
||||||
std::cout << "MCS value"
|
std::cout << "MCS value"
|
||||||
<< "\t\t"
|
<< "\t\t"
|
||||||
<< "Channel width"
|
<< "Channel width"
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user