Loading...
Searching...
No Matches
satellite-point-to-point-isl-net-device.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2007, 2008 University of Washington
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * (Based on point-to-point network device)
19 * Author: Andre Aguas March 2020
20 * Simon 2020
21 * Adapted to SNS-3 by: Bastien Tauran <bastien.tauran@viveris.fr>
22 *
23 */
24
26
29
30#include "ns3/drop-tail-queue.h"
31#include "ns3/error-model.h"
32#include "ns3/llc-snap-header.h"
33#include "ns3/log.h"
34#include "ns3/mac48-address.h"
35#include "ns3/pointer.h"
36#include "ns3/ppp-header.h"
37#include "ns3/simulator.h"
38#include "ns3/uinteger.h"
39
40#include <cstddef>
41
42NS_LOG_COMPONENT_DEFINE("PointToPointIslNetDevice");
43
44namespace ns3
45{
46
47NS_OBJECT_ENSURE_REGISTERED(PointToPointIslNetDevice);
48
49TypeId
51{
52 static TypeId tid =
53 TypeId("ns3::PointToPointIslNetDevice")
54 .SetParent<NetDevice>()
55 .AddConstructor<PointToPointIslNetDevice>()
56 .AddAttribute("ReceiveErrorModel",
57 "The receiver error model used to simulate packet loss",
58 PointerValue(),
60 MakePointerChecker<ErrorModel>())
61 .AddAttribute("InterframeGap",
62 "The time to wait between packet (frame) transmissions",
63 TimeValue(Seconds(0.0)),
65 MakeTimeChecker())
66 .AddTraceSource(
67 "PacketDropRateTrace",
68 "A packet has been dropped or not",
70 "ns3::SatTypedefs::PacketDropRateTrace");
71 return tid;
72}
73
76 m_channel(0),
77 m_linkUp(false),
79{
80 NS_LOG_FUNCTION(this);
81}
82
84{
85 NS_LOG_FUNCTION(this);
86}
87
88void
89PointToPointIslNetDevice::AddHeader(Ptr<Packet> p, uint16_t protocolNumber)
90{
91 NS_LOG_FUNCTION(this << p << protocolNumber);
92 PppHeader ppp;
93 ppp.SetProtocol(EtherToPpp(protocolNumber));
94 p->AddHeader(ppp);
95}
96
97bool
98PointToPointIslNetDevice::ProcessHeader(Ptr<Packet> p, uint16_t& param)
99{
100 NS_LOG_FUNCTION(this << p << param);
101 PppHeader ppp;
102 p->RemoveHeader(ppp);
103 param = PppToEther(ppp.GetProtocol());
104 return true;
105}
106
107void
109{
110 NS_LOG_FUNCTION(this);
111 m_node = 0;
112 m_channel = 0;
114 m_currentPkt = 0;
115 m_queue = 0;
116 NetDevice::DoDispose();
117}
118
119void
121{
122 NS_LOG_FUNCTION(this);
123 m_dataRate = bps;
124}
125
126void
128{
129 NS_LOG_FUNCTION(this << t.GetSeconds());
131}
132
133bool
135{
136 NS_LOG_FUNCTION(this << p);
137 NS_LOG_LOGIC("UID is " << p->GetUid() << ")");
138
139 //
140 // This function is called to start the process of transmitting a packet.
141 // We need to tell the channel that we've started wiggling the wire and
142 // schedule an event that will be executed when the transmission is complete.
143 //
144 NS_ASSERT_MSG(m_txMachineState == READY, "Must be READY to transmit");
146 m_currentPkt = p;
147
148 Time txTime = m_dataRate.CalculateBytesTxTime(p->GetSize());
149 Time txCompleteTime = txTime + m_tInterframeGap;
150
151 NS_LOG_LOGIC("Schedule TransmitCompleteEvent in " << txCompleteTime.GetSeconds() << "sec");
152 Simulator::Schedule(txCompleteTime, &PointToPointIslNetDevice::TransmitComplete, this);
153
154 bool result = m_channel->TransmitStart(p, this, m_destinationNode, txTime);
155 return result;
156}
157
158void
160{
161 NS_LOG_FUNCTION(this);
162
163 //
164 // This function is called to when we're all done transmitting a packet.
165 // We try and pull another packet off of the transmit queue. If the queue
166 // is empty, we are done, otherwise we need to start transmitting the
167 // next packet.
168 //
169 NS_ASSERT_MSG(m_txMachineState == BUSY, "Must be BUSY if transmitting");
171
172 NS_ASSERT_MSG(m_currentPkt != nullptr,
173 "PointToPointIslNetDevice::TransmitComplete(): m_currentPkt zero");
174
175 m_currentPkt = nullptr;
176
177 Ptr<Packet> p = m_queue->Dequeue();
178 if (p == nullptr)
179 {
180 NS_LOG_LOGIC("No pending packets in device queue after tx complete");
181 return;
182 }
183
184 TransmitStart(p);
185}
186
187bool
188PointToPointIslNetDevice::Attach(Ptr<PointToPointIslChannel> ch)
189{
190 NS_LOG_FUNCTION(this << &ch);
191
192 m_channel = ch;
193
194 m_channel->Attach(this);
195
196 //
197 // This device is up whenever it is attached to a channel. A better plan
198 // would be to have the link come up when both devices are attached, but this
199 // is not done for now.
200 //
201 NotifyLinkUp();
202 return true;
203}
204
205void
207{
208 NS_LOG_FUNCTION(this << q);
209 m_queue = q;
210}
211
212void
214{
215 NS_LOG_FUNCTION(this << em);
217}
218
219void
221{
222 NS_LOG_FUNCTION(this << packet);
223 uint16_t protocol = 0;
224
225 if (!m_receiveErrorModel || !m_receiveErrorModel->IsCorrupt(packet))
226 {
227 //
228 // Strip off the point-to-point protocol header and forward this packet
229 // up the protocol stack. Since this is a simple point-to-point link,
230 // there is no difference in what the promisc callback sees and what the
231 // normal receive callback sees.
232 //
233 ProcessHeader(packet, protocol);
234
235 if (!m_promiscCallback.IsNull())
236 {
238 packet,
239 protocol,
240 GetRemote(),
241 GetAddress(),
242 NetDevice::PACKET_HOST);
243 }
244
245 // m_rxCallback (this, packet, protocol, GetRemote ());
246 SatGroundStationAddressTag groundStationAddressTag;
247 if (!packet->PeekPacketTag(groundStationAddressTag))
248 {
249 NS_FATAL_ERROR("SatGroundStationAddressTag not found");
250 }
251
252 m_orbiterNetDevice->ReceiveFromIsl(packet,
253 groundStationAddressTag.GetGroundStationAddress());
254 }
255}
256
257void
258PointToPointIslNetDevice::SetOrbiterNetDevice(Ptr<SatOrbiterNetDevice> orbiterNetDevice)
259{
260 NS_LOG_FUNCTION(this);
261
262 m_orbiterNetDevice = orbiterNetDevice;
263}
264
265Ptr<DropTailQueue<Packet>>
267{
268 NS_LOG_FUNCTION(this);
269 return m_queue;
270}
271
272void
274{
275 NS_LOG_FUNCTION(this);
276 m_linkUp = true;
277}
278
279void
281{
282 NS_LOG_FUNCTION(this);
283 m_ifIndex = index;
284}
285
286uint32_t
288{
289 return m_ifIndex;
290}
291
292Ptr<Channel>
294{
295 return m_channel;
296}
297
298//
299// This is a point-to-point device, so we really don't need any kind of address
300// information. However, the base class NetDevice wants us to define the
301// methods to get and set the address. Rather than be rude and assert, we let
302// clients get and set the address, but simply ignore them.
303
304void
306{
307 NS_LOG_FUNCTION(this << address);
308 m_address = Mac48Address::ConvertFrom(address);
309}
310
311Address
313{
314 return m_address;
315}
316
317void
319{
320 NS_LOG_FUNCTION(this << node);
321 m_destinationNode = node;
322}
323
324Ptr<Node>
329
330bool
332{
333 NS_LOG_FUNCTION(this);
334 return m_linkUp;
335}
336
337void
339{
340 NS_LOG_FUNCTION(this);
341}
342
343//
344// This is a point-to-point device, so every transmission is a broadcast to
345// all of the devices on the network.
346//
347bool
349{
350 NS_LOG_FUNCTION(this);
351 return true;
352}
353
354//
355// We don't really need any addressing information since this is a
356// point-to-point device. The base class NetDevice wants us to return a
357// broadcast address, so we make up something reasonable.
358//
359Address
361{
362 NS_LOG_FUNCTION(this);
363 return Mac48Address("ff:ff:ff:ff:ff:ff");
364}
365
366bool
368{
369 NS_LOG_FUNCTION(this);
370 return true;
371}
372
373Address
374PointToPointIslNetDevice::GetMulticast(Ipv4Address multicastGroup) const
375{
376 NS_LOG_FUNCTION(this);
377 return Mac48Address("01:00:5e:00:00:00");
378}
379
380Address
382{
383 NS_LOG_FUNCTION(this << addr);
384 return Mac48Address("33:33:00:00:00:00");
385}
386
387bool
389{
390 NS_LOG_FUNCTION(this);
391 return true;
392}
393
394bool
396{
397 NS_LOG_FUNCTION(this);
398 return false;
399}
400
401bool
402PointToPointIslNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
403{
404 NS_LOG_FUNCTION(this << packet << dest << protocolNumber);
405 NS_LOG_LOGIC("p=" << packet << ", dest=" << &dest);
406 NS_LOG_LOGIC("UID is " << packet->GetUid());
407
408 // If IsLinkUp() is false it means there is no channel to send any packet
409 // over so we just return an error.
410 if (IsLinkUp() == false)
411 {
412 return false;
413 }
414
415 AddHeader(packet, protocolNumber);
416
417 NS_ASSERT(m_queue != nullptr);
418
419 if (m_queue->Enqueue(packet))
420 {
421 // Packet is enqued
423
424 // If the channel is ready for transition we send the packet right now
425 if (m_txMachineState == READY)
426 {
427 packet = m_queue->Dequeue();
428 bool ret = TransmitStart(packet);
429 return ret;
430 }
431 return true;
432 }
433
434 // Packet is dropped
436
437 return false;
438}
439
440bool
442 const Address& source,
443 const Address& dest,
444 uint16_t protocolNumber)
445{
446 NS_LOG_FUNCTION(this << packet << source << dest << protocolNumber);
447 return false;
448}
449
450Ptr<Node>
452{
453 return m_node;
454}
455
456void
458{
459 NS_LOG_FUNCTION(this);
460 m_node = node;
461}
462
463bool
465{
466 NS_LOG_FUNCTION(this);
467 return false;
468}
469
470void
472{
473 m_rxCallback = cb;
474}
475
476void
477PointToPointIslNetDevice::SetPromiscReceiveCallback(NetDevice::PromiscReceiveCallback cb)
478{
480}
481
482bool
484{
485 NS_LOG_FUNCTION(this);
486 return false;
487}
488
489Address
491{
492 NS_LOG_FUNCTION(this);
493 NS_ASSERT(m_channel->GetNDevices() == 2);
494 for (std::size_t i = 0; i < m_channel->GetNDevices(); ++i)
495 {
496 Ptr<NetDevice> tmp = m_channel->GetDevice(i);
497 if (tmp != this)
498 {
499 return tmp->GetAddress();
500 }
501 }
502 NS_ASSERT(false);
503 // quiet compiler.
504 return Address();
505}
506
507bool
509{
510 NS_LOG_FUNCTION(this << mtu);
511 m_mtu = mtu;
512 return true;
513}
514
515uint16_t
517{
518 NS_LOG_FUNCTION(this);
519 return m_mtu;
520}
521
522uint16_t
524{
525 NS_LOG_FUNCTION_NOARGS();
526 switch (proto)
527 {
528 case 0x0021:
529 return 0x0800; // IPv4
530 case 0x0057:
531 return 0x86DD; // IPv6
532 default:
533 NS_ASSERT_MSG(false, "PPP Protocol number not defined!");
534 }
535 return 0;
536}
537
538uint16_t
540{
541 NS_LOG_FUNCTION_NOARGS();
542 switch (proto)
543 {
544 case 0x0800:
545 return 0x0021; // IPv4
546 case 0x86DD:
547 return 0x0057; // IPv6
548 default:
549 NS_ASSERT_MSG(false, "PPP Protocol number not defined!");
550 }
551 return 0;
552}
553
554} // namespace ns3
@ READY
The transmitter is ready to begin transmission of a packet.
@ BUSY
The transmitter is busy transmitting a packet.
Ptr< DropTailQueue< Packet > > m_queue
The Queue which this PointToPointIslNetDevice uses as a packet source.
void SetReceiveErrorModel(Ptr< ErrorModel > em)
Attach a receive ErrorModel to the PointToPointIslNetDevice.
NetDevice::ReceiveCallback m_rxCallback
Receive callback.
bool TransmitStart(Ptr< Packet > p)
Start Sending a Packet Down the Wire.
virtual bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber)
void NotifyLinkUp(void)
Make the link up and running.
void SetInterframeGap(Time t)
Set the interframe gap used to separate packets.
Mac48Address m_address
Mac48Address of this NetDevice.
void Receive(Ptr< Packet > p)
Receive a packet from a connected PointToPointIslChannel.
Ptr< Packet > m_currentPkt
Current packet processed.
PointToPointIslNetDevice()
Construct a PointToPointIslNetDevice.
bool ProcessHeader(Ptr< Packet > p, uint16_t &param)
Removes, from a packet of data, all headers and trailers that relate to the protocol implemented by t...
void AddHeader(Ptr< Packet > p, uint16_t protocolNumber)
Adds the necessary headers and trailers to a packet of data in order to respect the protocol implemen...
NetDevice::PromiscReceiveCallback m_promiscCallback
Receive callback.
bool m_linkUp
Identify if the link is up or not.
void SetQueue(Ptr< DropTailQueue< Packet > > queue)
Attach a queue to the PointToPointIslNetDevice.
virtual void SetReceiveCallback(NetDevice::ReceiveCallback cb)
void SetDataRate(DataRate bps)
Set the Data Rate used for transmission of packets.
Ptr< DropTailQueue< Packet > > GetQueue(void) const
Get a copy of the attached Queue.
virtual void AddLinkChangeCallback(Callback< void > callback)
virtual void SetPromiscReceiveCallback(PromiscReceiveCallback cb)
TracedCallback< uint32_t, Ptr< Node >, Ptr< Node >, bool > m_packetDropRateTrace
Traced callback for drop rate in queue.
Ptr< Node > m_node
Node owning this NetDevice.
virtual ~PointToPointIslNetDevice()
Destroy a PointToPointIslNetDevice.
TxMachineState m_txMachineState
The state of the Net Device transmit state machine.
Time m_tInterframeGap
The interframe gap that the Net Device uses to throttle packet transmission.
DataRate m_dataRate
The data rate that the Net Device uses to simulate packet transmission timing.
static uint16_t EtherToPpp(uint16_t protocol)
Ethernet to PPP protocol number mapping.
Ptr< SatOrbiterNetDevice > m_orbiterNetDevice
Satellite Orbiter Net Device associated to this instance.
virtual Address GetMulticast(Ipv4Address multicastGroup) const
void TransmitComplete(void)
Stop Sending a Packet Down the Wire and Begin the Interframe Gap.
void SetOrbiterNetDevice(Ptr< SatOrbiterNetDevice > orbiterNetDevice)
Set the associated OrbiterNetDevice.
static uint16_t PppToEther(uint16_t protocol)
PPP to Ethernet protocol number mapping.
uint32_t m_mtu
The Maximum Transmission Unit.
virtual void DoDispose(void)
Dispose of the object.
Ptr< Node > m_destinationNode
Node at the other end of the p2pIslLink.
Ptr< PointToPointIslChannel > m_channel
The PointToPointIslChannel to which this PointToPointIslNetDevice has been attached.
bool Attach(Ptr< PointToPointIslChannel > ch)
Attach the device to a channel.
virtual bool SendFrom(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)
Ptr< ErrorModel > m_receiveErrorModel
Error model for receive packet events.
Tag to store ground station destination address.
Mac48Address GetGroundStationAddress(void) const
Get the ground station MAC address.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.