blob: a8565fb000140cc0eed56116107261565914fd0a [file] [log] [blame]
Spyridon Mastorakis5ea33222016-12-07 14:33:53 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Eric Newberry8821d3e2018-07-04 16:42:01 -04002/*
3 * Copyright (c) 2011-2018 Regents of the University of California.
Spyridon Mastorakis5ea33222016-12-07 14:33:53 -08004 *
5 * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
6 * contributors.
7 *
8 * ndnSIM is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * ndnSIM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * ndnSIM, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 **/
19
20#include "ndn-net-device-transport.hpp"
21
22#include "../helper/ndn-stack-helper.hpp"
23#include "ndn-block-header.hpp"
24#include "../utils/ndn-ns3-packet-tag.hpp"
25
26#include <ndn-cxx/encoding/block.hpp>
27#include <ndn-cxx/interest.hpp>
28#include <ndn-cxx/data.hpp>
29
Eric Newberry8821d3e2018-07-04 16:42:01 -040030#include "ns3/queue.h"
31
Spyridon Mastorakis5ea33222016-12-07 14:33:53 -080032NS_LOG_COMPONENT_DEFINE("ndn.NetDeviceTransport");
33
34namespace ns3 {
35namespace ndn {
36
37NetDeviceTransport::NetDeviceTransport(Ptr<Node> node,
38 const Ptr<NetDevice>& netDevice,
39 const std::string& localUri,
40 const std::string& remoteUri,
41 ::ndn::nfd::FaceScope scope,
42 ::ndn::nfd::FacePersistency persistency,
43 ::ndn::nfd::LinkType linkType)
44 : m_netDevice(netDevice)
45 , m_node(node)
46{
47 this->setLocalUri(FaceUri(localUri));
48 this->setRemoteUri(FaceUri(remoteUri));
49 this->setScope(scope);
50 this->setPersistency(persistency);
51 this->setLinkType(linkType);
Spyridon Mastorakiscb9be5c2018-02-20 11:22:27 -080052 this->setMtu(m_netDevice->GetMtu()); // Use the MTU of the netDevice
Spyridon Mastorakis5ea33222016-12-07 14:33:53 -080053
Eric Newberry8821d3e2018-07-04 16:42:01 -040054 // Get send queue capacity for congestion marking
55 PointerValue txQueueAttribute;
56 if (m_netDevice->GetAttributeFailSafe("TxQueue", txQueueAttribute)) {
57 Ptr<ns3::QueueBase> txQueue = txQueueAttribute.Get<ns3::QueueBase>();
58 // must be put into bytes mode queue
Alexander Afanasyev77f84c62018-10-08 13:37:42 -040059
60 auto size = txQueue->GetMaxSize();
61 if (size.GetUnit() == BYTES) {
62 this->setSendQueueCapacity(size.GetValue());
63 }
64 else {
65 // don't know the exact size in bytes, guessing based on "standard" packet size
66 this->setSendQueueCapacity(size.GetValue() * 1500);
67 }
Eric Newberry8821d3e2018-07-04 16:42:01 -040068 }
69
Spyridon Mastorakis5ea33222016-12-07 14:33:53 -080070 NS_LOG_FUNCTION(this << "Creating an ndnSIM transport instance for netDevice with URI"
71 << this->getLocalUri());
72
73 NS_ASSERT_MSG(m_netDevice != 0, "NetDeviceFace needs to be assigned a valid NetDevice");
74
75 m_node->RegisterProtocolHandler(MakeCallback(&NetDeviceTransport::receiveFromNetDevice, this),
76 L3Protocol::ETHERNET_FRAME_TYPE, m_netDevice,
77 true /*promiscuous mode*/);
78}
79
80NetDeviceTransport::~NetDeviceTransport()
81{
82 NS_LOG_FUNCTION_NOARGS();
83}
84
Eric Newberry8821d3e2018-07-04 16:42:01 -040085ssize_t
86NetDeviceTransport::getSendQueueLength()
87{
88 PointerValue txQueueAttribute;
89 if (m_netDevice->GetAttributeFailSafe("TxQueue", txQueueAttribute)) {
90 Ptr<ns3::QueueBase> txQueue = txQueueAttribute.Get<ns3::QueueBase>();
91 return txQueue->GetNBytes();
92 }
93 else {
94 return nfd::face::QUEUE_UNSUPPORTED;
95 }
96}
97
Spyridon Mastorakis5ea33222016-12-07 14:33:53 -080098void
Spyridon Mastorakis5ea33222016-12-07 14:33:53 -080099NetDeviceTransport::doClose()
100{
101 NS_LOG_FUNCTION(this << "Closing transport for netDevice with URI"
102 << this->getLocalUri());
103
104 // set the state of the transport to "CLOSED"
105 this->setState(nfd::face::TransportState::CLOSED);
106}
107
108void
109NetDeviceTransport::doSend(Packet&& packet)
110{
111 NS_LOG_FUNCTION(this << "Sending packet from netDevice with URI"
112 << this->getLocalUri());
113
114 // convert NFD packet to NS3 packet
115 BlockHeader header(packet);
116
117 Ptr<ns3::Packet> ns3Packet = Create<ns3::Packet>();
118 ns3Packet->AddHeader(header);
119
120 // send the NS3 packet
121 m_netDevice->Send(ns3Packet, m_netDevice->GetBroadcast(),
122 L3Protocol::ETHERNET_FRAME_TYPE);
123}
124
125// callback
126void
127NetDeviceTransport::receiveFromNetDevice(Ptr<NetDevice> device,
128 Ptr<const ns3::Packet> p,
129 uint16_t protocol,
130 const Address& from, const Address& to,
131 NetDevice::PacketType packetType)
132{
133 NS_LOG_FUNCTION(device << p << protocol << from << to << packetType);
134
135 // Convert NS3 packet to NFD packet
136 Ptr<ns3::Packet> packet = p->Copy();
137
138 BlockHeader header;
139 packet->RemoveHeader(header);
140
141 auto nfdPacket = Packet(std::move(header.getBlock()));
142
143 this->receive(std::move(nfdPacket));
144}
145
146Ptr<NetDevice>
147NetDeviceTransport::GetNetDevice() const
148{
149 return m_netDevice;
150}
151
152} // namespace ndn
153} // namespace ns3