A Discrete-Event Network Simulator
API
uan-mac-rc-gw.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 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  * Author: Leonard Tracy <lentracy@gmail.com>
19  */
20 
21 #include "uan-mac-rc-gw.h"
22 #include "uan-mac-rc.h"
23 #include "uan-header-common.h"
24 #include "uan-header-rc.h"
25 #include "uan-phy.h"
26 #include "uan-tx-mode.h"
27 
28 #include "ns3/assert.h"
29 #include "ns3/log.h"
30 #include "ns3/trace-source-accessor.h"
31 #include "ns3/nstime.h"
32 #include "ns3/double.h"
33 #include "ns3/uinteger.h"
34 
35 #include <cfloat>
36 #include <utility>
37 #include <set>
38 #include <map>
39 #include <vector>
40 #include <algorithm>
41 
42 namespace ns3 {
43 
44 NS_LOG_COMPONENT_DEFINE ("UanMacRcGw");
45 
46 NS_OBJECT_ENSURE_REGISTERED (UanMacRcGw);
47 
49  : UanMac (),
50  m_state (IDLE),
51  m_currentRateNum (0),
52  m_cleared (false)
53 {
54  UanHeaderCommon ch;
55  UanHeaderRcRts rts;
56  UanHeaderRcCts cts;
57  UanHeaderRcAck ack;
59 
64 
65  NS_LOG_DEBUG ("Gateway initialized");
66 }
67 
69 {
70 }
71 
72 void
74 {
75  if (m_cleared)
76  {
77  return;
78  }
79  m_cleared = true;
80  if (m_phy)
81  {
82  m_phy->Clear ();
83  m_phy = 0;
84  }
85  m_propDelay.clear ();
86  std::map<Mac8Address, AckData>::iterator it = m_ackData.begin ();
87  for (; it != m_ackData.end (); it++)
88  {
89  it->second.rxFrames.clear ();
90  }
91  m_ackData.clear ();
92  m_requests.clear ();
93  m_sortedRes.clear ();
94 }
95 
96 void
98 {
99  Clear ();
101 }
102 TypeId
104 {
105  static TypeId tid = TypeId ("ns3::UanMacRcGw")
106  .SetParent<UanMac> ()
107  .SetGroupName ("Uan")
108  .AddConstructor<UanMacRcGw> ()
109  .AddAttribute ("MaxReservations",
110  "Maximum number of reservations to accept per cycle.",
111  UintegerValue (10),
113  MakeUintegerChecker<uint32_t> ())
114  .AddAttribute ("NumberOfRates",
115  "Number of rates per Phy layer.",
116  UintegerValue (1023),
118  MakeUintegerChecker<uint32_t> ())
119  .AddAttribute ("MaxPropDelay",
120  "Maximum propagation delay between gateway and non-gateway nodes.",
121  TimeValue (Seconds (2)),
123  MakeTimeChecker ())
124  .AddAttribute ("SIFS",
125  "Spacing between frames to account for timing error and processing delay.",
126  TimeValue (Seconds (0.2)),
128  MakeTimeChecker ())
129  .AddAttribute ("NumberOfNodes",
130  "Number of non-gateway nodes in this gateway's neighborhood.",
131  UintegerValue (10),
133  MakeUintegerChecker<uint32_t> ())
134  .AddAttribute ("MinRetryRate",
135  "Smallest allowed RTS retry rate.",
136  DoubleValue (0.01),
138  MakeDoubleChecker<double> ())
139  .AddAttribute ("RetryStep",
140  "Retry rate increment.",
141  DoubleValue (0.01),
143  MakeDoubleChecker<double> ())
144  .AddAttribute ("TotalRate",
145  "Total available channel rate in bps (for a single channel, without splitting reservation channel).",
146  UintegerValue (4096),
148  MakeUintegerChecker<uint32_t> ())
149  .AddAttribute ("RateStep",
150  "Increments available for rate assignment in bps.",
151  UintegerValue (4),
153  MakeUintegerChecker<uint32_t> ())
154  .AddAttribute ("FrameSize",
155  "Size of data frames in bytes.",
156  UintegerValue (1000),
158  MakeUintegerChecker<uint32_t> ())
159  .AddTraceSource ("RX",
160  "A packet was destined for and received at this MAC layer.",
162  "ns3::UanMac::PacketModeTracedCallback")
163  .AddTraceSource ("Cycle",
164  "Trace cycle statistics.",
166  "ns3::UanMacRcGw::CycleCallback")
167 
168  ;
169 
170  return tid;
171 }
172 
173 bool
175  [[maybe_unused]] uint16_t protocolNumber,
176  [[maybe_unused]] const Address &dest)
177 {
178  NS_LOG_WARN ("RCMAC Gateway transmission to acoustic nodes is not yet implemented");
179  return false;
180 }
181 
182 void
184 {
185  m_forwardUpCb = cb;
186 }
187 
188 void
190 {
191  m_phy = phy;
192  phy->SetReceiveOkCallback (MakeCallback (&UanMacRcGw::ReceivePacket, this));
193  phy->SetReceiveErrorCallback (MakeCallback (&UanMacRcGw::ReceiveError, this));
194 }
195 
196 void
197 UanMacRcGw::ReceiveError (Ptr<Packet> pkt, [[maybe_unused]] double sinr)
198 {
199 }
200 
201 void
202 UanMacRcGw::ReceivePacket (Ptr<Packet> pkt, [[maybe_unused]] double sinr, UanTxMode mode)
203 {
204  UanHeaderCommon ch;
205  pkt->PeekHeader (ch);
206 
208  {
209  m_rxLogger (pkt, mode);
210  }
211  else
212  {
213  return;
214  }
215 
216  pkt->RemoveHeader (ch);
217 
218  switch (ch.GetType ())
219  {
220  case UanMacRc::TYPE_DATA:
221  {
222  UanHeaderRcData dh;
223  pkt->RemoveHeader (dh);
224  m_propDelay[ch.GetSrc ()] = dh.GetPropDelay ();
225  if (m_ackData.find (ch.GetSrc ()) == m_ackData.end ())
226  {
227  NS_LOG_DEBUG (Now ().As (Time::S) << " GATEWAY Received unexpected data packet");
228  }
229  else
230  {
231  NS_LOG_DEBUG (Now ().As (Time::S) << " GW Received data packet from " << ch.GetSrc () << " length = " << pkt->GetSize ());
232  m_ackData[ch.GetSrc ()].rxFrames.insert (dh.GetFrameNo ());
233  }
234  m_forwardUpCb (pkt, ch.GetProtocolNumber (), ch.GetSrc ());
235  }
236  break;
238  case UanMacRc::TYPE_RTS:
239  if (m_state == CTSING)
240  {
241  return;
242  }
243 
244  {
245  UanHeaderRcRts rh;
246  pkt->RemoveHeader (rh);
247 
248  if (m_requests.find (ch.GetSrc ()) == m_requests.end ())
249  {
250  Request req;
251  req.numFrames = rh.GetNoFrames ();
252  req.rxTime = Simulator::Now ();
253  req.frameNo = rh.GetFrameNo ();
254  req.retryNo = rh.GetRetryNo ();
255  req.length = rh.GetLength ();
256  NS_LOG_DEBUG (Now ().As (Time::S) << " GW storing reservation from " << ch.GetSrc () << " with length " << req.length);
257  m_requests.insert (std::make_pair (ch.GetSrc (), req));
258  std::map<Mac8Address, Time>::iterator it = m_propDelay.find (ch.GetSrc ());
259  if (it == m_propDelay.end ())
260  {
261  m_sortedRes.insert (std::make_pair (m_maxDelta, ch.GetSrc ()));
262  }
263  else
264  {
265  m_sortedRes.insert (std::make_pair ( (*it).second, ch.GetSrc ()));
266  }
267  }
268  }
269  if (m_state == IDLE)
270  {
271  StartCycle ();
272  }
273  break;
274  case UanMacRc::TYPE_CTS:
275  NS_FATAL_ERROR ("Received CTS at GW. Currently only support single GW network!");
276  break;
277  case UanMacRc::TYPE_ACK:
278  NS_FATAL_ERROR ("Received ACK at GW. Currently only support single GW network!");
279  break;
280  default:
281  NS_FATAL_ERROR ("Received unknown packet at GW!");
282  }
283 }
284 
285 void
287 {
288  uint32_t numRts = static_cast<uint32_t> (m_sortedRes.size ());
289 
290  if (numRts)
291  {
292  NS_LOG_DEBUG (Now ().As (Time::S) << " Simulator starting non-empty cycle");
293  }
294  else
295  {
296  NS_LOG_DEBUG (Now ().As (Time::S) << " Simulator starting EMPTY cycle");
297  }
298 
299  // Calculate dataRate
300  uint32_t totalBytes = 0;
301  uint32_t totalFrames = 0;
302  Time pDelay = Seconds (0);
303  if (numRts > 0)
304  {
305  std::map<Mac8Address, Request>::iterator rit = m_requests.begin ();
306  for (; rit != m_requests.end (); rit++)
307  {
308  totalBytes += (*rit).second.length;
309  totalFrames += (*rit).second.numFrames;
310  }
311  pDelay = 2 * m_sortedRes.begin ()->first;
312  }
313 
314 
315  double minRate = m_phy->GetMode (m_numRates).GetDataRateBps ();
316 
317  uint32_t optA = m_maxRes;
318  if (m_maxRes == 0)
319  {
320  optA = FindOptA ();
321  }
322  double thAlpha = ComputeAlpha (totalFrames, totalBytes, m_numNodes, optA, (pDelay / 2.0).GetSeconds ());
323 
324  double thCtlRate = m_totalRate * thAlpha;
325 
326  double temprate = (thCtlRate - minRate) / ((double) m_rateStep) + 0.5;
327  m_currentRateNum = (uint32_t) temprate;
329  {
331  }
332 
333  NS_LOG_DEBUG ("Found theoretical alpha: " << thAlpha << " Found associated rate = " << thCtlRate << " Giving rate number: " << temprate);
334  double thX = thAlpha * m_totalRate / (2.0 * m_numNodes * m_rtsSize * 8.0);
335 
336  double dataRate = m_phy->GetMode (m_currentRateNum).GetDataRateBps ();
337 
338 
339  if (thX < m_minRetryRate)
340  {
341  NS_LOG_WARN ("Gateway found optimum RTS retry rate is below minimum");
342  m_currentRetryRate = 0;
343  }
344  else
345  {
346  m_currentRetryRate = (uint16_t)((thX - m_minRetryRate) / m_retryStep + 0.5);
347  }
348 
349  double actualX = m_currentRetryRate * m_retryStep + m_minRetryRate;
350 
351  uint32_t ctlRate = m_phy->GetMode (m_currentRateNum + m_numRates).GetDataRateBps ();
352 
353 
354  Time winSize = Seconds (totalBytes * 8.0 / dataRate) + m_sifs * totalFrames + pDelay;
355  if (numRts == 0)
356  {
357  winSize = Seconds ((optA * std::exp (1.0) + 0.5) * 2.0 * 8.0 * m_rtsSize / (thAlpha * m_totalRate)) + (2 * m_maxDelta);
358  }
359  Time effWinSize = winSize - Seconds (m_rtsSize * 8.0 / ctlRate) - (2 * m_maxDelta);
360 
361  // Before fast CTS/ACK(below)
362  Time ctsTxTimeG = Seconds (m_ctsSizeG * 8.0 / dataRate);
363  Time cycleSeconds = winSize + ((totalFrames + 1.0) * m_sifs) +
364  ctsTxTimeG + Seconds ((m_ctsSizeN + m_ackSize) * 8.0 / dataRate);
365 
366 
367  Time ctsTxTimeTotal = Seconds (m_ctsSizeN * 8.0 * numRts / dataRate) + ctsTxTimeG;
368  if (numRts == 0)
369  {
371  ctsg.SetWindowTime (effWinSize);
372  ctsg.SetRateNum (static_cast<uint16_t> (m_currentRateNum));
374  ctsg.SetTxTimeStamp (Simulator::Now ());
375 
376  UanHeaderCommon ch;
380  ch.SetProtocolNumber (0);
381 
382  Ptr<Packet> p = Create<Packet> ();
383  p->AddHeader (ctsg);
384  p->AddHeader (ch);
386 
387 
388  Simulator::Schedule (cycleSeconds, &UanMacRcGw::StartCycle, this);
389  m_state = INCYCLE;
390  m_cycleLogger (Simulator::Now (), Seconds (0), numRts, totalBytes, effWinSize.GetSeconds (), ctlRate, actualX);
391  return;
392  }
393 
394  Time nextEarliest = ctsTxTimeTotal + m_sifs;
395 
396  m_state = CTSING;
397  Simulator::Schedule (nextEarliest, &UanMacRcGw::CycleStarted, this);
398 
399  std::set<std::pair<Time, Mac8Address> >::iterator it = m_sortedRes.begin ();
400  Time minPdelay = (*it).first;
401  Ptr<Packet> cts = Create<Packet> ();
402 
403  for (; it != m_sortedRes.end (); it++)
404  {
405  Request req = m_requests[(*it).second];
406  Time pdelay = (*it).first;
407 
408  AckData newData;
409  newData.expFrames = req.numFrames;
410  newData.frameNo = req.frameNo;
411  Mac8Address dest = (*it).second;
412  m_ackData.insert (std::make_pair (dest, newData));
413 
414  Time earliestArr = ctsTxTimeTotal + pdelay + pdelay + m_sifs;
415  Time arrivalTime = std::max (earliestArr, nextEarliest);
416  NS_LOG_DEBUG (Now ().As (Time::S) << " GW: Scheduling request for prop. delay " << pdelay.As (Time::S) << " for " << (*it).second << " Earliest possible arrival=" << earliestArr.As (Time::S) << " Next arrival time=" << nextEarliest.As (Time::S));
417  nextEarliest = arrivalTime + Seconds (req.length * 8.0 / dataRate) + m_sifs * req.numFrames;
418 
419  UanHeaderRcCts ctsh;
420  ctsh.SetAddress (dest);
421  ctsh.SetRtsTimeStamp (req.rxTime);
422  ctsh.SetFrameNo (req.frameNo);
423  ctsh.SetRetryNo (req.retryNo);
424  ctsh.SetDelayToTx (arrivalTime);
425  cts->AddHeader (ctsh);
426 
427  NS_LOG_DEBUG (Now ().As (Time::S) <<
428  " GW Scheduling reception for " << (uint32_t) req.numFrames <<
429  " frames at " << (Simulator::Now () + arrivalTime).As (Time::S) << " (delaytiltx of " << arrivalTime.As (Time::S) << ") Total length is " << req.length << " with txtime " << req.length * 8 / dataRate << " seconds");
430  }
431 
433  ctsg.SetRateNum (static_cast<uint16_t> (m_currentRateNum));
435  ctsg.SetWindowTime (effWinSize);
436  ctsg.SetTxTimeStamp (Simulator::Now ());
437  UanHeaderCommon ch;
441  cts->AddHeader (ctsg);
442  cts->AddHeader (ch);
444 
445  m_requests.clear ();
446  m_sortedRes.clear ();
447  Simulator::Schedule (nextEarliest, &UanMacRcGw::EndCycle, this);
448 
449 
450  m_cycleLogger (Simulator::Now (), minPdelay, numRts, totalBytes, cycleSeconds.GetSeconds (), ctlRate, actualX);
451 }
452 
453 void
455 {
456  m_state = INCYCLE;
457 }
458 void
460 {
461 
462  NS_LOG_DEBUG (Now ().As (Time::S) << " GW Ending cycle");
463 
464  Time nextAck = Seconds (0);
465 
466  Time ackTime = Seconds (m_ackSize * 8.0 / m_phy->GetMode (m_currentRateNum).GetDataRateBps ());
467 
468  std::map<Mac8Address, AckData>::iterator it = m_ackData.begin ();
469  for (; it != m_ackData.end (); it++)
470  {
471  Mac8Address dest = (*it).first;
472  AckData &data = (*it).second;
473 
474  std::list<uint32_t> toNack;
475  for (uint8_t i = 0; i < data.expFrames; i++)
476  {
477  if (data.rxFrames.find (i) == data.rxFrames.end ())
478  {
479  toNack.push_back (i);
480  }
481  }
482  UanHeaderCommon ch;
483  ch.SetDest (dest);
486  UanHeaderRcAck ah;
487  ah.SetFrameNo (data.frameNo);
488  std::list<uint32_t>::iterator nit = toNack.begin ();
489  for (; nit != toNack.end (); nit++)
490  {
491  ah.AddNackedFrame (static_cast<uint8_t> (*nit));
492  }
493 
494  Ptr<Packet> ack = Create<Packet> ();
495  ack->AddHeader (ah);
496  ack->AddHeader (ch);
498  nextAck = nextAck + ackTime + m_sifs;
499  }
500  m_ackData.clear ();
502 
503 }
504 void
506 {
507  UanHeaderCommon ch;
508  pkt->PeekHeader (ch);
509  std::string type;
510  switch (ch.GetType ())
511  {
512  case UanMacRc::TYPE_DATA:
513  type = "DATA";
514  break;
515  case UanMacRc::TYPE_RTS:
516  type = "RTS";
517  break;
518  case UanMacRc::TYPE_CTS:
519  type = "CTS";
520  break;
521  case UanMacRc::TYPE_ACK:
522  type = "ACK";
523  break;
525  type = "GWPING";
526  break;
527  default:
528  type = "UNKNOWN";
529  break;
530  }
531  NS_LOG_DEBUG (Now ().As (Time::S) << " GW sending " << type << " packet with size " << pkt->GetSize () << " to " << ch.GetDest () << " at rate " << rate);
532  m_phy->SendPacket (pkt, rate);
533 }
534 
535 
536 double
537 UanMacRcGw::ComputeAlpha (uint32_t totalFrames, uint32_t totalBytes,
538  [[maybe_unused]] uint32_t n, uint32_t a, double deltaK)
539 {
540  double alpha;
541  double lrae = m_rtsSize * 8.0 * a * std::exp (1.0);
542  if (totalFrames == 0)
543  {
544 
545  alpha = (2.0 * lrae + 8.0 * m_rtsSize - std::sqrt (m_ctsSizeG * 8.0 * 8.0 * m_rtsSize + 2 * 8.0 * m_ctsSizeG * 8.0 * m_rtsSize * a * std::exp (1.0)) ) /
546  (2 * lrae + 8.0 * m_rtsSize - 8.0 * m_ctsSizeG);
547  }
548  else
549  {
550  double w = totalBytes * 8.0 + totalFrames*m_sifs.GetSeconds () * m_totalRate;
551  double v = m_rtsSize * 8.0 + 2 * lrae;
552  double u = (2 * m_maxDelta.GetSeconds () - 2 * deltaK) * m_totalRate;
553 
554  double gamma = (w - u + v) / (2 * (u - totalFrames * m_sifs.GetSeconds () * m_totalRate));
555 
556  alpha = -gamma + std::sqrt (gamma * gamma + v / (u - totalFrames * m_sifs.GetSeconds () * m_totalRate));
557 
558  if (alpha < 0 || alpha > 1)
559  {
560  alpha = -gamma - std::sqrt (gamma * gamma + v / (u - totalFrames * m_sifs.GetSeconds () * m_totalRate));
561  }
562  }
563  NS_ASSERT_MSG (alpha > 0 && alpha < 1, "Error computing alpha. Alpha out of valid range!");
564  return alpha;
565 }
566 
567 std::vector<double>
569 {
570  uint32_t n = m_numNodes;
571  std::vector<double> pds;
572  std::map<Mac8Address, Time>::iterator pdit = m_propDelay.begin ();
573 
574  for (; pdit != m_propDelay.end (); pdit++)
575  {
576  pds.push_back (pdit->second.GetSeconds ());
577  }
578  while (pds.size () < m_numNodes)
579  {
580  pds.push_back (m_maxDelta.GetSeconds ());
581  }
582 
583  std::sort (pds.begin (), pds.end ());
584  // Find expected min. prop. delay for k nodes
585  std::vector<double> exppdk;
586  exppdk.push_back (m_maxDelta.GetSeconds ());
587  for (uint32_t k = 1; k <= n; k++)
588  {
589  uint32_t ind = CompExpMinIndex (n,k) - 1;
590  exppdk.push_back (pds[ind]);
591  }
592  return exppdk;
593 }
594 
595 double
596 UanMacRcGw::ComputeExpS (uint32_t a, uint32_t ld, std::vector<double> exppdk)
597 {
598  UanHeaderCommon ch;
599  uint32_t lh = ch.GetSerializedSize ();
600 
601  uint32_t n = m_numNodes;
602  double expk = n * (1 - std::exp (-((double) a) / (double) n));
603  NS_LOG_DEBUG ("expk = " << expk);
604 
605  // Compute expected data per cycle
606  double expdata = 8 * ld * expk;
607 
608  // Compute expected time per cycle
609  double alpha0 = ComputeAlpha (0,0,n,a,exppdk[0]);
610  double c0 = 8.0 * m_ctsSizeG / ( m_totalRate * (1 - alpha0)) + 2 * m_maxDelta.GetSeconds () + (a * std::exp (1.0) + 0.5) * 2 * m_rtsSize * 8.0 / (alpha0 * m_totalRate);
611  double exptime = ComputePiK (a,n,0) * c0;
612  double expp = 0;
613  for (uint32_t i = 1; i <= n; i++)
614  {
615  expp += ComputePiK (a,n,i) * exppdk[i - 1];
616  }
617 
618  exptime += ComputeExpBOverA (n,a,ld + lh,exppdk) + expk * 2 * m_sifs.GetSeconds () + m_sifs.GetSeconds () + 2 * expp;
619  double s = (1.0 / m_totalRate) * expdata / exptime;
620 
621  return s;
622 }
623 
624 double
625 UanMacRcGw::ComputeExpS (uint32_t a, uint32_t ld)
626 {
627  return ComputeExpS (a, ld, GetExpPdk ());
628 }
629 
630 uint32_t
631 UanMacRcGw::CompExpMinIndex (uint32_t n, uint32_t k)
632 {
633  double sum = 0;
634  for (uint32_t i = 1; i <= n - k + 1; i++)
635  {
636  double nChK = static_cast<double> (NchooseK (n, k));
637  double p = (nChK > 0) ? (static_cast<double> (NchooseK (n - i, k - 1)) / nChK) : DBL_MAX;
638  sum += p * i;
639  }
640  return (uint32_t)(sum + 0.5);
641 }
642 
643 double
644 UanMacRcGw::ComputePiK (uint32_t a, uint32_t n, uint32_t k)
645 {
646  double nck = (double) NchooseK (n, k);
647  return nck * std::pow ( (std::exp ( (double) a / (double) n) - 1.0), (double) k) * std::exp (-( (double) a));
648 }
649 
650 double
651 UanMacRcGw::ComputeExpBOverA (uint32_t n, uint32_t a, uint32_t ldlh, std::vector<double> deltaK)
652 {
653 
654  double sum = 0;
655  uint32_t lt = 8 * (m_ctsSizeN + ldlh + m_ackSize);
656  for (uint32_t k = 1; k <= n; k++)
657  {
658  double num = 8.0 * m_ctsSizeG + k * lt;
659  double denom = (1.0 - ComputeAlpha (k, k * ldlh, n, a, deltaK[k])) * m_totalRate;
660  double pik = ComputePiK (a, n, k);
661  double term = pik * num / denom;
662 
663  sum += term;
664  }
665 
666  return sum;
667 }
668 
669 uint64_t
670 UanMacRcGw::NchooseK (uint32_t n, uint32_t k)
671 {
672  if (k > n)
673  {
674  return 0;
675  }
676 
677  if (k > n / 2)
678  {
679  k = n - k;
680  }
681 
682  double accum = 1;
683  for (uint32_t i = 1; i <= k; i++)
684  {
685  accum = accum * (n - k + i) / i;
686  }
687 
688  return (uint64_t)(accum + 0.5);
689 
690 }
691 
692 uint32_t
694 {
695  double tput = 0;
696  uint32_t a = 1;
697  while (1)
698  {
699 
700  double newtput = ComputeExpS (a, m_frameSize);
701  if (newtput < tput)
702  {
703  a--;
704  break;
705  }
706  else
707  {
708  tput = newtput;
709  a++;
710  }
711  }
712  NS_LOG_DEBUG (Now ().As (Time::S) << " GW: Found optimum a = " << a);
713  return a;
714 }
715 
716 int64_t
718 {
719  NS_LOG_FUNCTION (this << stream);
720  return 0;
721 }
722 
723 } // namespace ns3
#define max(a, b)
Definition: 80211b.c:43
a polymophic address class
Definition: address.h:91
Callback template class.
Definition: callback.h:1279
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:41
A class used for addressing MAC8 MAC's.
Definition: mac8-address.h:43
static Mac8Address GetBroadcast(void)
Get the broadcast address (255).
Definition: mac8-address.cc:87
static Mac8Address ConvertFrom(const Address &address)
Convert a generic address to a Mac8Address.
Definition: mac8-address.cc:54
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:290
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:379
@ S
second
Definition: nstime.h:114
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:418
AttributeValue implementation for Time.
Definition: nstime.h:1308
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
Common packet header fields.
void SetSrc(Mac8Address src)
Set the source address.
uint8_t GetType(void) const
Get the header type value.
virtual uint32_t GetSerializedSize(void) const
Mac8Address GetSrc(void) const
Get the source address.
Mac8Address GetDest(void) const
Get the destination address.
void SetProtocolNumber(uint16_t protocolNumber)
Set the packet type.
void SetDest(Mac8Address dest)
Set the destination address.
void SetType(uint8_t type)
Set the header type.
uint16_t GetProtocolNumber(void) const
Get the packet type value.
Header used for ACK packets by protocol UanMacRc.
virtual uint32_t GetSerializedSize(void) const
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.
virtual uint32_t GetSerializedSize(void) const
void SetWindowTime(Time t)
Set the window time (time duration following blocking time to allow RTS transmissions).
void SetRtsTimeStamp(Time timeStamp)
Set the timestamp for RTS reception.
void SetFrameNo(uint8_t frameNo)
Set the RTS frame number being cleared.
virtual uint32_t GetSerializedSize(void) const
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:42
Time GetPropDelay(void) const
Get the propagation delay found in handshaking.
uint8_t GetFrameNo(void) const
Get the frame number of the reservation being transmitted.
uint8_t GetFrameNo(void) const
Get the frame number.
uint8_t GetNoFrames(void) const
Get the number of data frames in the reservation.
uint8_t GetRetryNo(void) const
Get the retry number of this RTS packet.
uint16_t GetLength(void) const
Get the total number of bytes in the reservation, including headers.
virtual uint32_t GetSerializedSize(void) const
Virtual base class for all UAN MAC protocols.
Definition: uan-mac.h:50
virtual Address GetAddress(void)
Get the MAC Address.
Definition: uan-mac.cc:55
Gateway side of RC-MAC.
Definition: uan-mac-rc-gw.h:58
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.
virtual bool Enqueue(Ptr< Packet > pkt, uint16_t protocolNumber, const Address &dest)
Enqueue packet to be transmitted.
void SendPacket(Ptr< Packet > pkt, uint32_t rate)
Send packet on PHY.
virtual void DoDispose()
Destructor implementation.
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.
virtual void Clear(void)
Clears all pointer references.
double m_minRetryRate
Smallest allowed RTS retry rate.
uint16_t m_currentRetryRate
Retry rate number for current cycle.
virtual void SetForwardUpCb(Callback< void, Ptr< Packet >, uint16_t, const Mac8Address & > cb)
Set the callback to forward packets up to higher layers.
uint32_t m_ctsSizeN
Size of UanHeaderRcCts.
UanMacRcGw()
Constructor.
static TypeId GetTypeId(void)
Register this type.
uint32_t m_rateStep
Increments available for rate assignment in bps.
std::map< Mac8Address, AckData > m_ackData
AckData for each node.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
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.
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.
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:98
@ INCYCLE
Cycling through nodes.
Definition: uan-mac-rc-gw.h:97
@ IDLE
Initial idle state.
Definition: uan-mac-rc-gw.h:96
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.
void CycleStarted(void)
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.
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.
void StartCycle(void)
Cycle through pending requests.
uint32_t FindOptA(void)
Compute the optimum maximum number of reservations to accept per cycle.
std::map< Mac8Address, Request > m_requests
Request for each node.
double m_retryStep
Retry rate increment.
virtual void AttachPhy(Ptr< UanPhy > phy)
Attach PHY layer to this MAC.
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.
std::vector< double > GetExpPdk(void)
Get the expected propagation delay to each node.
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.
TracedCallback< Ptr< const Packet >, UanTxMode > m_rxLogger
A packet was destined for and received at this MAC layer.
void EndCycle(void)
End cycle by scheduling pending ACKs.
virtual ~UanMacRcGw()
Dummy destructor, see DoDispose.
@ 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:42
Hold an unsigned integer type.
Definition: uinteger.h:44
#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:88
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: double.h:42
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: nstime.h:1309
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: uinteger.h:45
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#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:265
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
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.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:522
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
@ IDLE
Channel is IDLE, no packet is being transmitted.
Definition: csma-channel.h:75
float alpha
Plot alpha value (transparency)
phy
Definition: third.py:93
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.