diff --git a/.jenkins.d/01-deps.sh b/.jenkins.d/01-deps.sh
index 43c81f8b2..db2d80879 100755
--- a/.jenkins.d/01-deps.sh
+++ b/.jenkins.d/01-deps.sh
@@ -20,6 +20,6 @@ if has Ubuntu $NODE_LABELS; then
sudo apt-get -qq install build-essential pkg-config libboost-all-dev \
libcrypto++-dev libsqlite3-dev libssl-dev
sudo apt-get install -qq -y python-setuptools python-dev python-pygraphviz python-kiwi
- sudo apt-get install -qq -y python-pygoocanvas python-gnome2
- sudo apt-get install -qq -y python-rsvg ipython
+ # sudo apt-get install -qq -y python-pygoocanvas python-gnome2
+ # sudo apt-get install -qq -y python-rsvg ipython
fi
diff --git a/apps/ndn-consumer-pcon.cpp b/apps/ndn-consumer-pcon.cpp
new file mode 100644
index 000000000..22427407c
--- /dev/null
+++ b/apps/ndn-consumer-pcon.cpp
@@ -0,0 +1,346 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011-2018 Regents of the University of California.
+ *
+ * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
+ * contributors.
+ *
+ * ndnSIM is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndnSIM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndnSIM, e.g., in COPYING.md file. If not, see .
+ **/
+
+#include "ndn-consumer-pcon.hpp"
+
+NS_LOG_COMPONENT_DEFINE("ndn.ConsumerPcon");
+
+namespace ns3 {
+namespace ndn {
+
+NS_OBJECT_ENSURE_REGISTERED(ConsumerPcon);
+
+constexpr double ConsumerPcon::CUBIC_C;
+constexpr uint32_t ConsumerPcon::BIC_MAX_INCREMENT;
+constexpr uint32_t ConsumerPcon::BIC_LOW_WINDOW;
+
+TypeId
+ConsumerPcon::GetTypeId()
+{
+ static TypeId tid =
+ TypeId("ns3::ndn::ConsumerPcon")
+ .SetGroupName("Ndn")
+ .SetParent()
+ .AddConstructor()
+
+ .AddAttribute("CcAlgorithm",
+ "Specify which window adaptation algorithm to use (AIMD, BIC, or CUBIC)",
+ EnumValue(CcAlgorithm::AIMD),
+ MakeEnumAccessor(&ConsumerPcon::m_ccAlgorithm),
+ MakeEnumChecker(CcAlgorithm::AIMD, "AIMD", CcAlgorithm::BIC, "BIC",
+ CcAlgorithm::CUBIC, "CUBIC"))
+
+ .AddAttribute("Beta",
+ "TCP Multiplicative Decrease factor",
+ DoubleValue(0.5),
+ MakeDoubleAccessor(&ConsumerPcon::m_beta),
+ MakeDoubleChecker())
+
+ .AddAttribute("CubicBeta",
+ "TCP CUBIC Multiplicative Decrease factor",
+ DoubleValue(0.8),
+ MakeDoubleAccessor(&ConsumerPcon::m_cubicBeta),
+ MakeDoubleChecker())
+
+ .AddAttribute("AddRttSuppress",
+ "Minimum number of RTTs (1 + this factor) between window decreases",
+ DoubleValue(0.5), // This default value was chosen after manual testing
+ MakeDoubleAccessor(&ConsumerPcon::m_addRttSuppress),
+ MakeDoubleChecker())
+
+ .AddAttribute("ReactToCongestionMarks",
+ "If true, process received congestion marks",
+ BooleanValue(true),
+ MakeBooleanAccessor(&ConsumerPcon::m_reactToCongestionMarks),
+ MakeBooleanChecker())
+
+ .AddAttribute("UseCwa",
+ "If true, use Conservative Window Adaptation",
+ BooleanValue(true),
+ MakeBooleanAccessor(&ConsumerPcon::m_useCwa),
+ MakeBooleanChecker())
+
+ .AddAttribute("UseCubicFastConvergence",
+ "If true, use TCP CUBIC Fast Convergence",
+ BooleanValue(false),
+ MakeBooleanAccessor(&ConsumerPcon::m_useCubicFastConv),
+ MakeBooleanChecker());
+
+ return tid;
+}
+
+ConsumerPcon::ConsumerPcon()
+ : m_ssthresh(std::numeric_limits::max())
+ , m_highData(0)
+ , m_recPoint(0.0)
+ , m_cubicWmax(0)
+ , m_cubicLastWmax(0)
+ , m_cubicLastDecrease(time::steady_clock::now())
+ , m_bicMinWin(0)
+ , m_bicMaxWin(std::numeric_limits::max())
+ , m_bicTargetWin(0)
+ , m_bicSsCwnd(0)
+ , m_bicSsTarget(0)
+ , m_isBicSs(false)
+{
+}
+
+void
+ConsumerPcon::OnData(shared_ptr data)
+{
+ Consumer::OnData(data);
+
+ uint64_t sequenceNum = data->getName().get(-1).toSequenceNumber();
+
+ // Set highest received Data to sequence number
+ if (m_highData < sequenceNum) {
+ m_highData = sequenceNum;
+ }
+
+ if (data->getCongestionMark() > 0) {
+ if (m_reactToCongestionMarks) {
+ NS_LOG_DEBUG("Received congestion mark: " << data->getCongestionMark());
+ WindowDecrease();
+ }
+ else {
+ NS_LOG_DEBUG("Ignored received congestion mark: " << data->getCongestionMark());
+ }
+ }
+ else {
+ WindowIncrease();
+ }
+
+ if (m_inFlight > static_cast(0)) {
+ m_inFlight--;
+ }
+
+ NS_LOG_DEBUG("Window: " << m_window << ", InFlight: " << m_inFlight);
+
+ ScheduleNextPacket();
+}
+
+void
+ConsumerPcon::OnTimeout(uint32_t sequenceNum)
+{
+ WindowDecrease();
+
+ if (m_inFlight > static_cast(0)) {
+ m_inFlight--;
+ }
+
+ NS_LOG_DEBUG("Window: " << m_window << ", InFlight: " << m_inFlight);
+
+ Consumer::OnTimeout(sequenceNum);
+}
+
+void
+ConsumerPcon::WindowIncrease()
+{
+ if (m_ccAlgorithm == CcAlgorithm::AIMD) {
+ if (m_window < m_ssthresh) {
+ m_window += 1.0;
+ }
+ else {
+ m_window += (1.0 / m_window);
+ }
+ }
+ else if (m_ccAlgorithm == CcAlgorithm::CUBIC) {
+ CubicIncrease();
+ }
+ else if (m_ccAlgorithm == CcAlgorithm::BIC) {
+ BicIncrease();
+ }
+ else {
+ BOOST_ASSERT_MSG(false, "Unknown CC Algorithm");
+ }
+ NS_LOG_DEBUG("Window size increased to " << m_window);
+}
+
+void
+ConsumerPcon::WindowDecrease()
+{
+ if (!m_useCwa || m_highData > m_recPoint) {
+ const double diff = m_seq - m_highData;
+ BOOST_ASSERT(diff > 0);
+
+ m_recPoint = m_seq + (m_addRttSuppress * diff);
+
+ if (m_ccAlgorithm == CcAlgorithm::AIMD) {
+ // Normal TCP Decrease:
+ m_ssthresh = m_window * m_beta;
+ m_window = m_ssthresh;
+ }
+ else if (m_ccAlgorithm == CcAlgorithm::CUBIC) {
+ CubicDecrease();
+ }
+ else if (m_ccAlgorithm == CcAlgorithm::BIC) {
+ BicDecrease();
+ }
+ else {
+ BOOST_ASSERT_MSG(false, "Unknown CC Algorithm");
+ }
+
+ // Window size cannot be reduced below initial size
+ if (m_window < m_initialWindow) {
+ m_window = m_initialWindow;
+ }
+
+ NS_LOG_DEBUG("Window size decreased to " << m_window);
+ }
+ else {
+ NS_LOG_DEBUG("Window decrease suppressed, HighData: " << m_highData << ", RecPoint: " << m_recPoint);
+ }
+}
+
+
+void
+ConsumerPcon::BicIncrease()
+{
+ if (m_window < BIC_LOW_WINDOW) {
+ // Normal TCP AIMD behavior
+ if (m_window < m_ssthresh) {
+ m_window = m_window + 1;
+ }
+ else {
+ m_window = m_window + 1.0 / m_window;
+ }
+ }
+ else if (!m_isBicSs) {
+ // Binary increase
+ if (m_bicTargetWin - m_window < BIC_MAX_INCREMENT) { // Binary search
+ m_window += (m_bicTargetWin - m_window) / m_window;
+ }
+ else {
+ m_window += BIC_MAX_INCREMENT / m_window; // Additive increase
+ }
+ // FIX for equal double values.
+ if (m_window + 0.00001 < m_bicMaxWin) {
+ m_bicMinWin = m_window;
+ m_bicTargetWin = (m_bicMaxWin + m_bicMinWin) / 2;
+ }
+ else {
+ m_isBicSs = true;
+ m_bicSsCwnd = 1;
+ m_bicSsTarget = m_window + 1.0;
+ m_bicMaxWin = std::numeric_limits::max();
+ }
+ }
+ else {
+ // BIC slow start
+ m_window += m_bicSsCwnd / m_window;
+ if (m_window >= m_bicSsTarget) {
+ m_bicSsCwnd = 2 * m_bicSsCwnd;
+ m_bicSsTarget = m_window + m_bicSsCwnd;
+ }
+ if (m_bicSsCwnd >= BIC_MAX_INCREMENT) {
+ m_isBicSs = false;
+ }
+ }
+}
+
+void
+ConsumerPcon::BicDecrease()
+{
+ // BIC Decrease
+ if (m_window >= BIC_LOW_WINDOW) {
+ auto prev_max = m_bicMaxWin;
+ m_bicMaxWin = m_window;
+ m_window = m_window * m_cubicBeta;
+ m_bicMinWin = m_window;
+ if (prev_max > m_bicMaxWin) {
+ // Fast Convergence
+ m_bicMaxWin = (m_bicMaxWin + m_bicMinWin) / 2;
+ }
+ m_bicTargetWin = (m_bicMaxWin + m_bicMinWin) / 2;
+ }
+ else {
+ // Normal TCP Decrease:
+ m_ssthresh = m_window * m_cubicBeta;
+ m_window = m_ssthresh;
+ }
+}
+
+
+void
+ConsumerPcon::CubicIncrease()
+{
+ // 1. Time since last congestion event in Seconds
+ const double t = time::duration_cast(
+ time::steady_clock::now() - m_cubicLastDecrease).count() / 1e6;
+
+ // 2. Time it takes to increase the window to cubic_wmax
+ // K = cubic_root(W_max*(1-beta_cubic)/C) (Eq. 2)
+ const double k = std::cbrt(m_cubicWmax * (1 - m_cubicBeta) / CUBIC_C);
+
+ // 3. Target: W_cubic(t) = C*(t-K)^3 + W_max (Eq. 1)
+ const double w_cubic = CUBIC_C * std::pow(t - k, 3) + m_cubicWmax;
+
+ // 4. Estimate of Reno Increase (Currently Disabled)
+ // const double rtt = m_rtt->GetCurrentEstimate().GetSeconds();
+ // const double w_est = m_cubic_wmax*m_beta + (3*(1-m_beta)/(1+m_beta)) * (t/rtt);
+ constexpr double w_est = 0.0;
+
+ // Actual adaptation
+ if (m_window < m_ssthresh) {
+ m_window += 1.0;
+ }
+ else {
+ BOOST_ASSERT(m_cubicWmax > 0);
+
+ double cubic_increment = std::max(w_cubic, w_est) - m_window;
+ // Cubic increment must be positive:
+ // Note: This change is not part of the RFC, but I added it to improve performance.
+ if (cubic_increment < 0) {
+ cubic_increment = 0.0;
+ }
+ m_window += cubic_increment / m_window;
+ }
+}
+
+
+void
+ConsumerPcon::CubicDecrease()
+{
+ // This implementation is ported from https://datatracker.ietf.org/doc/rfc8312/
+
+ const double FAST_CONV_DIFF = 1.0; // In percent
+
+ // A flow remembers the last value of W_max,
+ // before it updates W_max for the current congestion event.
+
+ // Current w_max < last_wmax
+ if (m_useCubicFastConv && m_window < m_cubicLastWmax * (1 - FAST_CONV_DIFF / 100)) {
+ m_cubicLastWmax = m_window;
+ m_cubicWmax = m_window * (1.0 + m_cubicBeta) / 2.0;
+ }
+ else {
+ // Save old cwnd as w_max:
+ m_cubicLastWmax = m_window;
+ m_cubicWmax = m_window;
+ }
+
+ m_ssthresh = m_window * m_cubicBeta;
+ m_ssthresh = std::max(m_ssthresh, m_initialWindow);
+ m_window = m_ssthresh;
+
+ m_cubicLastDecrease = time::steady_clock::now();
+}
+
+} // namespace ndn
+} // namespace ns3
diff --git a/apps/ndn-consumer-pcon.hpp b/apps/ndn-consumer-pcon.hpp
new file mode 100644
index 000000000..080e675c6
--- /dev/null
+++ b/apps/ndn-consumer-pcon.hpp
@@ -0,0 +1,117 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011-2018 Regents of the University of California.
+ *
+ * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
+ * contributors.
+ *
+ * ndnSIM is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndnSIM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndnSIM, e.g., in COPYING.md file. If not, see .
+ **/
+
+#ifndef NDN_CONSUMER_PCON_H
+#define NDN_CONSUMER_PCON_H
+
+#include "ns3/ndnSIM/model/ndn-common.hpp"
+
+#include "ndn-consumer-window.hpp"
+
+namespace ns3 {
+namespace ndn {
+
+enum CcAlgorithm {
+ AIMD,
+ BIC,
+ CUBIC
+};
+
+/**
+ * @ingroup ndn-apps
+ * \brief NDN consumer application with more advanced congestion control options
+ *
+ * This app uses the algorithms from "A Practical Congestion Control Scheme for Named
+ * Data Networking" (https://dl.acm.org/citation.cfm?id=2984369).
+ *
+ * It implements slow start, conservative window adaptation (RFC 6675),
+ * and 3 different TCP algorithms: AIMD, BIC, and CUBIC (RFC 8312).
+ */
+class ConsumerPcon : public ConsumerWindow {
+public:
+ static TypeId
+ GetTypeId();
+
+ ConsumerPcon();
+
+ virtual void
+ OnData(shared_ptr data) override;
+
+ virtual void
+ OnTimeout(uint32_t sequenceNum) override;
+
+private:
+ void
+ WindowIncrease();
+
+ void
+ WindowDecrease();
+
+ void
+ CubicIncrease();
+
+ void
+ CubicDecrease();
+
+ void
+ BicIncrease();
+
+ void
+ BicDecrease();
+
+private:
+ CcAlgorithm m_ccAlgorithm;
+ double m_beta;
+ double m_addRttSuppress;
+ bool m_reactToCongestionMarks;
+ bool m_useCwa;
+
+ double m_ssthresh;
+ uint32_t m_highData;
+ double m_recPoint;
+
+ // TCP CUBIC Parameters //
+ static constexpr double CUBIC_C = 0.4;
+ bool m_useCubicFastConv;
+ double m_cubicBeta;
+
+ double m_cubicWmax;
+ double m_cubicLastWmax;
+ time::steady_clock::TimePoint m_cubicLastDecrease;
+
+ // TCP BIC Parameters //
+ //! Regular TCP behavior (including slow start) until this window size
+ static constexpr uint32_t BIC_LOW_WINDOW = 14;
+
+ //! Sets the maximum (linear) increase of TCP BIC. Should be between 8 and 64.
+ static constexpr uint32_t BIC_MAX_INCREMENT = 16;
+
+ // BIC variables:
+ double m_bicMinWin; //!< last minimum cwnd
+ double m_bicMaxWin; //!< last maximum cwnd
+ double m_bicTargetWin;
+ double m_bicSsCwnd;
+ double m_bicSsTarget;
+ bool m_isBicSs; //!< whether we are currently in the BIC slow start phase
+};
+
+} // namespace ndn
+} // namespace ns3
+
+#endif // NDN_CONSUMER_PCON_H
diff --git a/apps/ndn-consumer-window.hpp b/apps/ndn-consumer-window.hpp
index 4e76c5096..c298e1711 100644
--- a/apps/ndn-consumer-window.hpp
+++ b/apps/ndn-consumer-window.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2011-2015 Regents of the University of California.
+/*
+ * Copyright (c) 2011-2018 Regents of the University of California.
*
* This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
* contributors.
@@ -33,7 +33,7 @@ namespace ndn {
* \brief Ndn application for sending out Interest packets (window-based)
*
* !!! ATTENTION !!! This is highly experimental and relies on experimental features of the
- *simulator.
+ * simulator.
* Behavior may be unpredictable if used incorrectly.
*/
class ConsumerWindow : public Consumer {
@@ -57,7 +57,7 @@ class ConsumerWindow : public Consumer {
WillSendOutInterest(uint32_t sequenceNumber);
public:
- typedef void (*WindowTraceCallback)(uint32_t);
+ typedef std::function WindowTraceCallback;
protected:
/**
@@ -92,18 +92,18 @@ class ConsumerWindow : public Consumer {
void
SetSeqMax(uint32_t seqMax);
-private:
+protected:
uint32_t m_payloadSize; // expected payload size
double m_maxSize; // max size to request
uint32_t m_initialWindow;
bool m_setInitialWindowOnTimeout;
- TracedValue m_window;
+ TracedValue m_window;
TracedValue m_inFlight;
};
} // namespace ndn
} // namespace ns3
-#endif
+#endif // NDN_CONSUMER_WINDOW_H
diff --git a/docs/source/applications.rst b/docs/source/applications.rst
index 8bb508da1..51911468a 100644
--- a/docs/source/applications.rst
+++ b/docs/source/applications.rst
@@ -130,7 +130,7 @@ This applications has the following attributes:
ConsumerWindow
^^^^^^^^^^^^^^^^^^
-:ndnsim:`ConsumerWindow` is an application generating a variable rate Interest traffic. It implements a simple sliding-window-based Interest generation mechanism.
+:ndnsim:`ConsumerWindow` is an application generating a variable-rate Interest traffic. It implements a simple sliding-window-based Interest generation mechanism.
.. code-block:: c++
@@ -163,6 +163,67 @@ This applications has the following attributes:
If ``Size`` is set to -1, Interests will be requested till the end of the simulation.
+ConsumerPcon
+^^^^^^^^^^^^^^^^
+
+:ndnsim:`ConsumerPcon` is an application generating variable-rate Interest traffic. It implements a window-based rate control that adjusts window size using the PCON congestion control mechanism developed by K. Schneider et al. (https://named-data.net/publications/practical_congestion_control_scheme/). It is derived from :ndnsim:`ConsumerWindow`.
+
+.. code-block:: c++
+
+ // Create application using the app helper
+ AppHelper consumerHelper("ns3::ndn::ConsumerPcon");
+
+The application has the same attributes as :ndnsim:`ConsumerWindow`, in addition to the following:
+
+* ``CcAlgorithm``
+
+ .. note::
+ default: ``AIMD``
+
+ Which window adaptation algorithm to use (AIMD, BIC, or CUBIC)
+
+* ``Beta``
+
+ .. note::
+ default: ``0.5``
+
+ TCP Multiplicative Decrease factor
+
+* ``CubicBeta``
+
+ .. note::
+ default: ``0.8``
+
+ TCP CUBIC Multiplicative Decrease factor
+
+* ``AddRttSupress``
+
+ .. note::
+ default: ``0.5``
+
+ Minimum number of RTTs (1 + this factor) between window decreases
+
+* ``ReactToCongestionMarks``
+
+ .. note::
+ default: ``true``
+
+ If true, process received congestion marks; otherwise, ignore them
+
+* ``UseCwa``
+
+ .. note::
+ default: ``true``
+
+ If true, use Conservative Window Adaptation
+
+* ``UseCubicFastConvergence``
+
+ .. note::
+ default: ``true``
+
+ If true, use TCP CUBIC Fast Convergence
+
Producer
^^^^^^^^^^^^
diff --git a/examples/ndn-grid.py b/examples/ndn-grid.py
index c13c405c7..11d5f045c 100644
--- a/examples/ndn-grid.py
+++ b/examples/ndn-grid.py
@@ -51,7 +51,7 @@
Config.SetDefault("ns3::PointToPointNetDevice::DataRate", StringValue("10Mbps"))
Config.SetDefault("ns3::PointToPointChannel::Delay", StringValue("10ms"))
-Config::SetDefault("ns3::QueueBase::MaxPackets", UintegerValue(20))
+Config.SetDefault("ns3::QueueBase::MaxPackets", UintegerValue(20))
import sys; cmd = CommandLine(); cmd.Parse(sys.argv);
diff --git a/examples/ndn-simple.py b/examples/ndn-simple.py
index 108406a06..62ae4ca0f 100644
--- a/examples/ndn-simple.py
+++ b/examples/ndn-simple.py
@@ -47,7 +47,7 @@
# Set default parameters for PointToPoint links and channels
Config.SetDefault("ns3::PointToPointNetDevice::DataRate", StringValue("10Mbps"))
Config.SetDefault("ns3::PointToPointChannel::Delay", StringValue("10ms"))
-Config::SetDefault("ns3::QueueBase::MaxPackets", UintegerValue(20))
+Config.SetDefault("ns3::QueueBase::MaxPackets", UintegerValue(20))
# Read optional command-line parameters (e.g., enable visualizer with ./waf --pyrun=<> --visualize
import sys; cmd = CommandLine(); cmd.Parse(sys.argv);
diff --git a/model/ndn-net-device-transport.cpp b/model/ndn-net-device-transport.cpp
index 32abaa6e0..17880d279 100644
--- a/model/ndn-net-device-transport.cpp
+++ b/model/ndn-net-device-transport.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2011-2016 Regents of the University of California.
+/*
+ * Copyright (c) 2011-2018 Regents of the University of California.
*
* This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
* contributors.
@@ -27,6 +27,8 @@
#include
#include
+#include "ns3/queue.h"
+
NS_LOG_COMPONENT_DEFINE("ndn.NetDeviceTransport");
namespace ns3 {
@@ -49,6 +51,14 @@ NetDeviceTransport::NetDeviceTransport(Ptr node,
this->setLinkType(linkType);
this->setMtu(m_netDevice->GetMtu()); // Use the MTU of the netDevice
+ // Get send queue capacity for congestion marking
+ PointerValue txQueueAttribute;
+ if (m_netDevice->GetAttributeFailSafe("TxQueue", txQueueAttribute)) {
+ Ptr txQueue = txQueueAttribute.Get();
+ // must be put into bytes mode queue
+ this->setSendQueueCapacity(txQueue->GetMaxBytes());
+ }
+
NS_LOG_FUNCTION(this << "Creating an ndnSIM transport instance for netDevice with URI"
<< this->getLocalUri());
@@ -64,6 +74,19 @@ NetDeviceTransport::~NetDeviceTransport()
NS_LOG_FUNCTION_NOARGS();
}
+ssize_t
+NetDeviceTransport::getSendQueueLength()
+{
+ PointerValue txQueueAttribute;
+ if (m_netDevice->GetAttributeFailSafe("TxQueue", txQueueAttribute)) {
+ Ptr txQueue = txQueueAttribute.Get();
+ return txQueue->GetNBytes();
+ }
+ else {
+ return nfd::face::QUEUE_UNSUPPORTED;
+ }
+}
+
void
NetDeviceTransport::doClose()
{
diff --git a/model/ndn-net-device-transport.hpp b/model/ndn-net-device-transport.hpp
index 09a08ed55..e68382d74 100644
--- a/model/ndn-net-device-transport.hpp
+++ b/model/ndn-net-device-transport.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2011-2016 Regents of the University of California.
+/*
+ * Copyright (c) 2011-2018 Regents of the University of California.
*
* This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
* contributors.
@@ -54,6 +54,9 @@ class NetDeviceTransport : public nfd::face::Transport
Ptr
GetNetDevice() const;
+ virtual ssize_t
+ getSendQueueLength() final;
+
private:
virtual void
doClose() override;