A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
uan-mac-rc-gw.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009 University of Washington
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Leonard Tracy <lentracy@gmail.com>
18 */
19
20#include "uan-mac-rc-gw.h"
21
22#include "uan-header-common.h"
23#include "uan-header-rc.h"
24#include "uan-mac-rc.h"
25#include "uan-phy.h"
26#include "uan-tx-mode.h"
27
28#include "ns3/assert.h"
29#include "ns3/double.h"
30#include "ns3/log.h"
31#include "ns3/nstime.h"
32#include "ns3/trace-source-accessor.h"
33#include "ns3/uinteger.h"
34
35#include <algorithm>
36#include <cfloat>
37#include <map>
38#include <set>
39#include <utility>
40#include <vector>
41
42namespace ns3
43{
44
45NS_LOG_COMPONENT_DEFINE("UanMacRcGw");
46
48
50 : UanMac(),
51 m_state(IDLE),
52 m_currentRateNum(0),
53 m_cleared(false)
54{
60
65
66 NS_LOG_DEBUG("Gateway initialized");
67}
68
70{
71}
72
73void
75{
76 if (m_cleared)
77 {
78 return;
79 }
80 m_cleared = true;
81 if (m_phy)
82 {
83 m_phy->Clear();
84 m_phy = nullptr;
85 }
86 m_propDelay.clear();
87 auto it = m_ackData.begin();
88 for (; it != m_ackData.end(); it++)
89 {
90 it->second.rxFrames.clear();
91 }
92 m_ackData.clear();
93 m_requests.clear();
94 m_sortedRes.clear();
95}
96
97void
99{
100 Clear();
102}
103
104TypeId
106{
107 static TypeId tid =
108 TypeId("ns3::UanMacRcGw")
109 .SetParent<UanMac>()
110 .SetGroupName("Uan")
111 .AddConstructor<UanMacRcGw>()
112 .AddAttribute("MaxReservations",
113 "Maximum number of reservations to accept per cycle.",
114 UintegerValue(10),
116 MakeUintegerChecker<uint32_t>())
117 .AddAttribute("NumberOfRates",
118 "Number of rates per Phy layer.",
119 UintegerValue(1023),
121 MakeUintegerChecker<uint32_t>())
122 .AddAttribute("MaxPropDelay",
123 "Maximum propagation delay between gateway and non-gateway nodes.",
124 TimeValue(Seconds(2)),
127 .AddAttribute(
128 "SIFS",
129 "Spacing between frames to account for timing error and processing delay.",
130 TimeValue(Seconds(0.2)),
133 .AddAttribute("NumberOfNodes",
134 "Number of non-gateway nodes in this gateway's neighborhood.",
135 UintegerValue(10),
137 MakeUintegerChecker<uint32_t>())
138 .AddAttribute("MinRetryRate",
139 "Smallest allowed RTS retry rate.",
140 DoubleValue(0.01),
142 MakeDoubleChecker<double>())
143 .AddAttribute("RetryStep",
144 "Retry rate increment.",
145 DoubleValue(0.01),
147 MakeDoubleChecker<double>())
148 .AddAttribute("TotalRate",
149 "Total available channel rate in bps (for a single channel, without "
150 "splitting reservation channel).",
151 UintegerValue(4096),
153 MakeUintegerChecker<uint32_t>())
154 .AddAttribute("RateStep",
155 "Increments available for rate assignment in bps.",
156 UintegerValue(4),
158 MakeUintegerChecker<uint32_t>())
159 .AddAttribute("FrameSize",
160 "Size of data frames in bytes.",
161 UintegerValue(1000),
163 MakeUintegerChecker<uint32_t>())
164 .AddTraceSource("RX",
165 "A packet was destined for and received at this MAC layer.",
167 "ns3::UanMac::PacketModeTracedCallback")
168 .AddTraceSource("Cycle",
169 "Trace cycle statistics.",
171 "ns3::UanMacRcGw::CycleCallback")
172
173 ;
174
175 return tid;
176}
177
178bool
180 uint16_t /* protocolNumber */,
181 const Address& /* dest */)
182{
183 NS_LOG_WARN("RCMAC Gateway transmission to acoustic nodes is not yet implemented");
184 return false;
185}
186
187void
189{
190 m_forwardUpCb = cb;
191}
192
193void
195{
196 m_phy = phy;
197 phy->SetReceiveOkCallback(MakeCallback(&UanMacRcGw::ReceivePacket, this));
198 phy->SetReceiveErrorCallback(MakeCallback(&UanMacRcGw::ReceiveError, this));
199}
200
201void
202UanMacRcGw::ReceiveError(Ptr<Packet> /* pkt */, double /* sinr */)
203{
204}
205
206void
208{
210 pkt->PeekHeader(ch);
211
214 {
215 m_rxLogger(pkt, mode);
216 }
217 else
218 {
219 return;
220 }
221
222 pkt->RemoveHeader(ch);
223
224 switch (ch.GetType())
225 {
226 case UanMacRc::TYPE_DATA: {
228 pkt->RemoveHeader(dh);
229 m_propDelay[ch.GetSrc()] = dh.GetPropDelay();
230 if (m_ackData.find(ch.GetSrc()) == m_ackData.end())
231 {
232 NS_LOG_DEBUG(Now().As(Time::S) << " GATEWAY Received unexpected data packet");
233 }
234 else
235 {
236 NS_LOG_DEBUG(Now().As(Time::S) << " GW Received data packet from " << ch.GetSrc()
237 << " length = " << pkt->GetSize());
238 m_ackData[ch.GetSrc()].rxFrames.insert(dh.GetFrameNo());
239 }
240 m_forwardUpCb(pkt, ch.GetProtocolNumber(), ch.GetSrc());
241 }
242 break;
245 if (m_state == CTSING)
246 {
247 return;
248 }
249
250 {
252 pkt->RemoveHeader(rh);
253
254 if (m_requests.find(ch.GetSrc()) == m_requests.end())
255 {
256 Request req;
257 req.numFrames = rh.GetNoFrames();
258 req.rxTime = Simulator::Now();
259 req.frameNo = rh.GetFrameNo();
260 req.retryNo = rh.GetRetryNo();
261 req.length = rh.GetLength();
262 NS_LOG_DEBUG(Now().As(Time::S) << " GW storing reservation from " << ch.GetSrc()
263 << " with length " << req.length);
264 m_requests.insert(std::make_pair(ch.GetSrc(), req));
265 auto it = m_propDelay.find(ch.GetSrc());
266 if (it == m_propDelay.end())
267 {
268 m_sortedRes.insert(std::make_pair(m_maxDelta, ch.GetSrc()));
269 }
270 else
271 {
272 m_sortedRes.insert(std::make_pair((*it).second, ch.GetSrc()));
273 }
274 }
275 }
276 if (m_state == IDLE)
277 {
278 StartCycle();
279 }
280 break;
282 NS_FATAL_ERROR("Received CTS at GW. Currently only support single GW network!");
283 break;
285 NS_FATAL_ERROR("Received ACK at GW. Currently only support single GW network!");
286 break;
287 default:
288 NS_FATAL_ERROR("Received unknown packet at GW!");
289 }
290}
291
292void
294{
295 auto numRts = static_cast<uint32_t>(m_sortedRes.size());
296
297 if (numRts)
298 {
299 NS_LOG_DEBUG(Now().As(Time::S) << " Simulator starting non-empty cycle");
300 }
301 else
302 {
303 NS_LOG_DEBUG(Now().As(Time::S) << " Simulator starting EMPTY cycle");
304 }
305
306 // Calculate dataRate
307 uint32_t totalBytes = 0;
308 uint32_t totalFrames = 0;
309 Time pDelay = Seconds(0);
310 if (numRts > 0)
311 {
312 auto rit = m_requests.begin();
313 for (; rit != m_requests.end(); rit++)
314 {
315 totalBytes += (*rit).second.length;
316 totalFrames += (*rit).second.numFrames;
317 }
318 pDelay = 2 * m_sortedRes.begin()->first;
319 }
320
321 double minRate = m_phy->GetMode(m_numRates).GetDataRateBps();
322
323 uint32_t optA = m_maxRes;
324 if (m_maxRes == 0)
325 {
326 optA = FindOptA();
327 }
328 double thAlpha =
329 ComputeAlpha(totalFrames, totalBytes, m_numNodes, optA, (pDelay / 2.0).GetSeconds());
330
331 double thCtlRate = m_totalRate * thAlpha;
332
333 double temprate = (thCtlRate - minRate) / ((double)m_rateStep) + 0.5;
334 m_currentRateNum = (uint32_t)temprate;
336 {
338 }
339
340 NS_LOG_DEBUG("Found theoretical alpha: " << thAlpha << " Found associated rate = " << thCtlRate
341 << " Giving rate number: " << temprate);
342 double thX = thAlpha * m_totalRate / (2.0 * m_numNodes * m_rtsSize * 8.0);
343
344 double dataRate = m_phy->GetMode(m_currentRateNum).GetDataRateBps();
345
346 if (thX < m_minRetryRate)
347 {
348 NS_LOG_WARN("Gateway found optimum RTS retry rate is below minimum");
350 }
351 else
352 {
353 m_currentRetryRate = (uint16_t)((thX - m_minRetryRate) / m_retryStep + 0.5);
354 }
355
356 double actualX = m_currentRetryRate * m_retryStep + m_minRetryRate;
357
358 uint32_t ctlRate = m_phy->GetMode(m_currentRateNum + m_numRates).GetDataRateBps();
359
360 Time winSize = Seconds(totalBytes * 8.0 / dataRate) + m_sifs * totalFrames + pDelay;
361 if (numRts == 0)
362 {
363 winSize = Seconds((optA * std::exp(1.0) + 0.5) * 2.0 * 8.0 * m_rtsSize /
364 (thAlpha * m_totalRate)) +
365 (2 * m_maxDelta);
366 }
367 Time effWinSize = winSize - Seconds(m_rtsSize * 8.0 / ctlRate) - (2 * m_maxDelta);
368
369 // Before fast CTS/ACK(below)
370 Time ctsTxTimeG = Seconds(m_ctsSizeG * 8.0 / dataRate);
371 Time cycleSeconds = winSize + ((totalFrames + 1.0) * m_sifs) + ctsTxTimeG +
372 Seconds((m_ctsSizeN + m_ackSize) * 8.0 / dataRate);
373
374 Time ctsTxTimeTotal = Seconds(m_ctsSizeN * 8.0 * numRts / dataRate) + ctsTxTimeG;
375 if (numRts == 0)
376 {
378 ctsg.SetWindowTime(effWinSize);
379 ctsg.SetRateNum(static_cast<uint16_t>(m_currentRateNum));
382
387 ch.SetProtocolNumber(0);
388
389 Ptr<Packet> p = Create<Packet>();
390 p->AddHeader(ctsg);
391 p->AddHeader(ch);
393
394 Simulator::Schedule(cycleSeconds, &UanMacRcGw::StartCycle, this);
397 Seconds(0),
398 numRts,
399 totalBytes,
400 effWinSize.GetSeconds(),
401 ctlRate,
402 actualX);
403 return;
404 }
405
406 Time nextEarliest = ctsTxTimeTotal + m_sifs;
407
408 m_state = CTSING;
409 Simulator::Schedule(nextEarliest, &UanMacRcGw::CycleStarted, this);
410
411 auto it = m_sortedRes.begin();
412 Time minPdelay = (*it).first;
413 Ptr<Packet> cts = Create<Packet>();
414
415 for (; it != m_sortedRes.end(); it++)
416 {
417 Request req = m_requests[(*it).second];
418 Time pdelay = (*it).first;
419
420 AckData newData;
421 newData.expFrames = req.numFrames;
422 newData.frameNo = req.frameNo;
423 Mac8Address dest = (*it).second;
424 m_ackData.insert(std::make_pair(dest, newData));
425
426 Time earliestArr = ctsTxTimeTotal + pdelay + pdelay + m_sifs;
427 Time arrivalTime = std::max(earliestArr, nextEarliest);
429 << " GW: Scheduling request for prop. delay " << pdelay.As(Time::S) << " for "
430 << (*it).second << " Earliest possible arrival=" << earliestArr.As(Time::S)
431 << " Next arrival time=" << nextEarliest.As(Time::S));
432 nextEarliest = arrivalTime + Seconds(req.length * 8.0 / dataRate) + m_sifs * req.numFrames;
433
434 UanHeaderRcCts ctsh;
435 ctsh.SetAddress(dest);
436 ctsh.SetRtsTimeStamp(req.rxTime);
437 ctsh.SetFrameNo(req.frameNo);
438 ctsh.SetRetryNo(req.retryNo);
439 ctsh.SetDelayToTx(arrivalTime);
440 cts->AddHeader(ctsh);
441
443 << " GW Scheduling reception for " << (uint32_t)req.numFrames << " frames at "
444 << (Simulator::Now() + arrivalTime).As(Time::S) << " (delaytiltx of "
445 << arrivalTime.As(Time::S) << ") Total length is " << req.length
446 << " with txtime " << req.length * 8 / dataRate << " seconds");
447 }
448
450 ctsg.SetRateNum(static_cast<uint16_t>(m_currentRateNum));
452 ctsg.SetWindowTime(effWinSize);
458 cts->AddHeader(ctsg);
459 cts->AddHeader(ch);
461
462 m_requests.clear();
463 m_sortedRes.clear();
464 Simulator::Schedule(nextEarliest, &UanMacRcGw::EndCycle, this);
465
467 minPdelay,
468 numRts,
469 totalBytes,
470 cycleSeconds.GetSeconds(),
471 ctlRate,
472 actualX);
473}
474
475void
477{
479}
480
481void
483{
484 NS_LOG_DEBUG(Now().As(Time::S) << " GW Ending cycle");
485
486 Time nextAck = Seconds(0);
487
488 Time ackTime = Seconds(m_ackSize * 8.0 / m_phy->GetMode(m_currentRateNum).GetDataRateBps());
489
490 auto it = m_ackData.begin();
491 for (; it != m_ackData.end(); it++)
492 {
493 Mac8Address dest = (*it).first;
494 AckData& data = (*it).second;
495
496 std::list<uint32_t> toNack;
497 for (uint8_t i = 0; i < data.expFrames; i++)
498 {
499 if (data.rxFrames.find(i) == data.rxFrames.end())
500 {
501 toNack.push_back(i);
502 }
503 }
505 ch.SetDest(dest);
509 ah.SetFrameNo(data.frameNo);
510 auto nit = toNack.begin();
511 for (; nit != toNack.end(); nit++)
512 {
513 ah.AddNackedFrame(static_cast<uint8_t>(*nit));
514 }
515
516 Ptr<Packet> ack = Create<Packet>();
517 ack->AddHeader(ah);
518 ack->AddHeader(ch);
520 nextAck = nextAck + ackTime + m_sifs;
521 }
522 m_ackData.clear();
524}
525
526void
528{
530 pkt->PeekHeader(ch);
531 std::string type;
532 switch (ch.GetType())
533 {
535 type = "DATA";
536 break;
538 type = "RTS";
539 break;
541 type = "CTS";
542 break;
544 type = "ACK";
545 break;
547 type = "GWPING";
548 break;
549 default:
550 type = "UNKNOWN";
551 break;
552 }
554 << " GW sending " << type << " packet with size " << pkt->GetSize() << " to "
555 << ch.GetDest() << " at rate " << rate);
556 m_phy->SendPacket(pkt, rate);
557}
558
559double
561 uint32_t totalBytes,
562 uint32_t /* n */,
563 uint32_t a,
564 double deltaK)
565{
566 double alpha;
567 double lrae = m_rtsSize * 8.0 * a * std::exp(1.0);
568 if (totalFrames == 0)
569 {
570 alpha = (2.0 * lrae + 8.0 * m_rtsSize -
571 std::sqrt(m_ctsSizeG * 8.0 * 8.0 * m_rtsSize +
572 2 * 8.0 * m_ctsSizeG * 8.0 * m_rtsSize * a * std::exp(1.0))) /
573 (2 * lrae + 8.0 * m_rtsSize - 8.0 * m_ctsSizeG);
574 }
575 else
576 {
577 double w = totalBytes * 8.0 + totalFrames * m_sifs.GetSeconds() * m_totalRate;
578 double v = m_rtsSize * 8.0 + 2 * lrae;
579 double u = (2 * m_maxDelta.GetSeconds() - 2 * deltaK) * m_totalRate;
580
581 double gamma = (w - u + v) / (2 * (u - totalFrames * m_sifs.GetSeconds() * m_totalRate));
582
583 alpha = -gamma + std::sqrt(gamma * gamma +
584 v / (u - totalFrames * m_sifs.GetSeconds() * m_totalRate));
585
586 if (alpha < 0 || alpha > 1)
587 {
588 alpha = -gamma - std::sqrt(gamma * gamma +
589 v / (u - totalFrames * m_sifs.GetSeconds() * m_totalRate));
590 }
591 }
592 NS_ASSERT_MSG(alpha > 0 && alpha < 1, "Error computing alpha. Alpha out of valid range!");
593 return alpha;
594}
595
596std::vector<double>
598{
600 std::vector<double> pds;
601 auto pdit = m_propDelay.begin();
602
603 for (; pdit != m_propDelay.end(); pdit++)
604 {
605 pds.push_back(pdit->second.GetSeconds());
606 }
607 while (pds.size() < m_numNodes)
608 {
609 pds.push_back(m_maxDelta.GetSeconds());
610 }
611
612 std::sort(pds.begin(), pds.end());
613 // Find expected min. prop. delay for k nodes
614 std::vector<double> exppdk;
615 exppdk.push_back(m_maxDelta.GetSeconds());
616 for (uint32_t k = 1; k <= n; k++)
617 {
618 uint32_t ind = CompExpMinIndex(n, k) - 1;
619 exppdk.push_back(pds[ind]);
620 }
621 return exppdk;
622}
623
624double
625UanMacRcGw::ComputeExpS(uint32_t a, uint32_t ld, std::vector<double> exppdk)
626{
628 uint32_t lh = ch.GetSerializedSize();
629
631 double expk = n * (1 - std::exp(-((double)a) / (double)n));
632 NS_LOG_DEBUG("expk = " << expk);
633
634 // Compute expected data per cycle
635 double expdata = 8 * ld * expk;
636
637 // Compute expected time per cycle
638 double alpha0 = ComputeAlpha(0, 0, n, a, exppdk[0]);
639 double c0 = 8.0 * m_ctsSizeG / (m_totalRate * (1 - alpha0)) + 2 * m_maxDelta.GetSeconds() +
640 (a * std::exp(1.0) + 0.5) * 2 * m_rtsSize * 8.0 / (alpha0 * m_totalRate);
641 double exptime = ComputePiK(a, n, 0) * c0;
642 double expp = 0;
643 for (uint32_t i = 1; i <= n; i++)
644 {
645 expp += ComputePiK(a, n, i) * exppdk[i - 1];
646 }
647
648 exptime += ComputeExpBOverA(n, a, ld + lh, exppdk) + expk * 2 * m_sifs.GetSeconds() +
649 m_sifs.GetSeconds() + 2 * expp;
650 double s = (1.0 / m_totalRate) * expdata / exptime;
651
652 return s;
653}
654
655double
657{
658 return ComputeExpS(a, ld, GetExpPdk());
659}
660
663{
664 double sum = 0;
665 for (uint32_t i = 1; i <= n - k + 1; i++)
666 {
667 auto nChK = static_cast<double>(NchooseK(n, k));
668 double p = (nChK > 0) ? (static_cast<double>(NchooseK(n - i, k - 1)) / nChK) : DBL_MAX;
669 sum += p * i;
670 }
671 return (uint32_t)(sum + 0.5);
672}
673
674double
676{
677 auto nck = (double)NchooseK(n, k);
678 return nck * std::pow((std::exp((double)a / (double)n) - 1.0), (double)k) *
679 std::exp(-((double)a));
680}
681
682double
683UanMacRcGw::ComputeExpBOverA(uint32_t n, uint32_t a, uint32_t ldlh, std::vector<double> deltaK)
684{
685 double sum = 0;
686 uint32_t lt = 8 * (m_ctsSizeN + ldlh + m_ackSize);
687 for (uint32_t k = 1; k <= n; k++)
688 {
689 double num = 8.0 * m_ctsSizeG + k * lt;
690 double denom = (1.0 - ComputeAlpha(k, k * ldlh, n, a, deltaK[k])) * m_totalRate;
691 double pik = ComputePiK(a, n, k);
692 double term = pik * num / denom;
693
694 sum += term;
695 }
696
697 return sum;
698}
699
700uint64_t
702{
703 if (k > n)
704 {
705 return 0;
706 }
707
708 if (k > n / 2)
709 {
710 k = n - k;
711 }
712
713 double accum = 1;
714 for (uint32_t i = 1; i <= k; i++)
715 {
716 accum = accum * (n - k + i) / i;
717 }
718
719 return (uint64_t)(accum + 0.5);
720}
721
724{
725 double tput = 0;
726 uint32_t a = 1;
727 while (true)
728 {
729 double newtput = ComputeExpS(a, m_frameSize);
730 if (newtput < tput)
731 {
732 a--;
733 break;
734 }
735 else
736 {
737 tput = newtput;
738 a++;
739 }
740 }
741 NS_LOG_DEBUG(Now().As(Time::S) << " GW: Found optimum a = " << a);
742 return a;
743}
744
745int64_t
747{
748 NS_LOG_FUNCTION(this << stream);
749 return 0;
750}
751
752} // namespace ns3
a polymophic address class
Definition: address.h:101
Callback template class.
Definition: callback.h:438
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
A class used for addressing MAC8 MAC's.
Definition: mac8-address.h:44
static Mac8Address GetBroadcast()
Get the broadcast address (255).
Definition: mac8-address.cc:88
static Mac8Address ConvertFrom(const Address &address)
Convert a generic address to a Mac8Address.
Definition: mac8-address.cc:56
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:444
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:415
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:403
@ S
second
Definition: nstime.h:116
AttributeValue implementation for Time.
Definition: nstime.h:1406
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
Common packet header fields.
void SetSrc(Mac8Address src)
Set the source address.
uint32_t GetSerializedSize() const override
uint8_t GetType() const
Get the header type value.
Mac8Address GetDest() const
Get the destination address.
void SetProtocolNumber(uint16_t protocolNumber)
Set the packet type.
Mac8Address GetSrc() const
Get the source address.
void SetDest(Mac8Address dest)
Set the destination address.
void SetType(uint8_t type)
Set the header type.
uint16_t GetProtocolNumber() const
Get the packet type value.
Header used for ACK packets by protocol UanMacRc.
uint32_t GetSerializedSize() const override
void AddNackedFrame(uint8_t frame)
NACK a frame.
void SetFrameNo(uint8_t frameNo)
Set the frame number of the reservation being acknowledged.
Cycle broadcast information.
void SetRateNum(uint16_t rate)
Set the rate number corresponding to data rate of current cycle.
void SetRetryRate(uint16_t rate)
Set the retry rate number for the current cycle.
void SetTxTimeStamp(Time timeStamp)
Set the CTS timestamp.
void SetWindowTime(Time t)
Set the window time (time duration following blocking time to allow RTS transmissions).
uint32_t GetSerializedSize() const override
void SetRtsTimeStamp(Time timeStamp)
Set the timestamp for RTS reception.
void SetFrameNo(uint8_t frameNo)
Set the RTS frame number being cleared.
uint32_t GetSerializedSize() const override
void SetDelayToTx(Time delay)
Set the time delay from CTS transmission to first data frame arrival.
void SetRetryNo(uint8_t no)
Set the retry number of the RTS frame being cleared.
void SetAddress(Mac8Address addr)
Set the destination address, for scheduling info.
Extra data header information.
Definition: uan-header-rc.h:41
uint8_t GetFrameNo() const
Get the frame number of the reservation being transmitted.
Time GetPropDelay() const
Get the propagation delay found in handshaking.
uint8_t GetFrameNo() const
Get the frame number.
uint16_t GetLength() const
Get the total number of bytes in the reservation, including headers.
uint8_t GetNoFrames() const
Get the number of data frames in the reservation.
uint32_t GetSerializedSize() const override
uint8_t GetRetryNo() const
Get the retry number of this RTS packet.
Virtual base class for all UAN MAC protocols.
Definition: uan-mac.h:46
virtual Address GetAddress()
Get the MAC Address.
Definition: uan-mac.cc:52
Gateway side of RC-MAC.
Definition: uan-mac-rc-gw.h:55
uint32_t m_numNodes
Number of non-gateway nodes in this gateway's neighborhood.
void ReceiveError(Ptr< Packet > pkt, double sinr)
PHY receive error callback.
void SendPacket(Ptr< Packet > pkt, uint32_t rate)
Send packet on PHY.
uint32_t m_maxRes
Maximum number of reservations to accept per cycle.
double ComputeAlpha(uint32_t totalFrames, uint32_t totalBytes, uint32_t n, uint32_t a, double deltaK)
Compute alpha parameter.
double m_minRetryRate
Smallest allowed RTS retry rate.
void Clear() override
Clears all pointer references.
uint16_t m_currentRetryRate
Retry rate number for current cycle.
~UanMacRcGw() override
Dummy destructor, see DoDispose.
uint32_t m_ctsSizeN
Size of UanHeaderRcCts.
UanMacRcGw()
Constructor.
TracedCallback< Ptr< const Packet >, UanTxMode > m_rxLogger
A packet was destined for and received at this MAC layer.
void EndCycle()
End cycle by scheduling pending ACKs.
uint32_t m_rateStep
Increments available for rate assignment in bps.
uint32_t FindOptA()
Compute the optimum maximum number of reservations to accept per cycle.
std::map< Mac8Address, AckData > m_ackData
AckData for each node.
void StartCycle()
Cycle through pending requests.
TracedCallback< Time, Time, uint32_t, uint32_t, double, uint32_t, double > m_cycleLogger
A packet was destined for and received at this MAC layer.
std::set< std::pair< Time, Mac8Address > > m_sortedRes
Queued request times.
void AttachPhy(Ptr< UanPhy > phy) override
Attach PHY layer to this MAC.
Time m_maxDelta
Maximum propagation delay between gateway and non-gateway nodes .
double ComputeExpS(uint32_t a, uint32_t ld, std::vector< double > exppdk)
Throughput for a reservations with framesize ld, given expected delays exppdk.
Time m_sifs
Spacing between frames to account for timing error and processing delay.
void DoDispose() override
Destructor implementation.
static TypeId GetTypeId()
Register this type.
bool m_cleared
Flag when we've been cleared.
uint32_t m_ctsSizeG
Size of UanHeaderCommon and UanHeaderRcCtsGlobal.
Ptr< UanPhy > m_phy
PHY layer attached to this MAC.
@ CTSING
Sending CTS.
Definition: uan-mac-rc-gw.h:99
@ INCYCLE
Cycling through nodes.
Definition: uan-mac-rc-gw.h:98
@ IDLE
Initial idle state.
Definition: uan-mac-rc-gw.h:97
uint32_t m_frameSize
Size of data frames in bytes.
uint64_t NchooseK(uint32_t n, uint32_t k)
Binomial coefficient.
uint32_t m_numRates
Number of rates per Phy layer.
bool Enqueue(Ptr< Packet > pkt, uint16_t protocolNumber, const Address &dest) override
Enqueue packet to be transmitted.
int64_t AssignStreams(int64_t stream) override
Assign a fixed random variable stream number to the random variables used by this model.
void CycleStarted()
Set state to INCYCLE.
void ReceivePacket(Ptr< Packet > pkt, double sinr, UanTxMode mode)
PHY receive ok callback.
Callback< void, Ptr< Packet >, uint16_t, const Mac8Address & > m_forwardUpCb
Forwarding up callback.
uint32_t m_currentRateNum
Rate number corresponding to data rate of current cycle.
double ComputePiK(uint32_t a, uint32_t n, uint32_t k)
Numeric function.
std::vector< double > GetExpPdk()
Get the expected propagation delay to each node.
uint32_t m_totalRate
Total available channel rate in bps (for a single channel, without splitting reservation channel).
uint32_t m_rtsSize
Size of UanHeaderCommon and UanHeaderRcRts.
State m_state
Gateway processing state.
std::map< Mac8Address, Request > m_requests
Request for each node.
double m_retryStep
Retry rate increment.
double ComputeExpBOverA(uint32_t n, uint32_t a, uint32_t ldlh, std::vector< double > deltaK)
Numeric function.
std::map< Mac8Address, Time > m_propDelay
Propagation delay to each node.
void SetForwardUpCb(Callback< void, Ptr< Packet >, uint16_t, const Mac8Address & > cb) override
Set the callback to forward packets up to higher layers.
uint32_t m_ackSize
Size of UanHeaderCommon and UanHeaderRcAck.
uint32_t CompExpMinIndex(uint32_t n, uint32_t k)
Index to the k'th expected delay among n nodes.
@ TYPE_RTS
RTS.
Definition: uan-mac-rc.h:170
@ TYPE_DATA
Data.
Definition: uan-mac-rc.h:168
@ TYPE_ACK
ACK.
Definition: uan-mac-rc.h:172
@ TYPE_CTS
CTS.
Definition: uan-mac-rc.h:171
@ TYPE_GWPING
Gateway ping.
Definition: uan-mac-rc.h:169
Abstraction of packet modulation information.
Definition: uan-tx-mode.h:43
Hold an unsigned integer type.
Definition: uinteger.h:45
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition: nstime.h:1427
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1407
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:305
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:706
@ IDLE
Channel is IDLE, no packet is being transmitted.
Definition: csma-channel.h:76
uint8_t data[writeSize]
uint8_t expFrames
Expected number of frames.
uint8_t frameNo
Frame number being ACK'ed.
Reservation request.
uint8_t retryNo
Retry number.
uint16_t length
Request header length.
uint8_t frameNo
Current frame number.
uint8_t numFrames
Number of frames.
Time rxTime
Time request received.