A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 NS_LOG_COMPONENT_DEFINE ("UanMacRcGw");
43 
44 namespace ns3 {
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<UanAddress, 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  .AddConstructor<UanMacRcGw> ()
108  .AddAttribute ("MaxReservations",
109  "Maximum number of reservations to accept per cycle.",
110  UintegerValue (10),
111  MakeUintegerAccessor (&UanMacRcGw::m_maxRes),
112  MakeUintegerChecker<uint32_t> ())
113  .AddAttribute ("NumberOfRates",
114  "Number of rates per Phy layer.",
115  UintegerValue (1023),
116  MakeUintegerAccessor (&UanMacRcGw::m_numRates),
117  MakeUintegerChecker<uint32_t> ())
118  .AddAttribute ("MaxPropDelay",
119  "Maximum propagation delay between gateway and non-gateway nodes.",
120  TimeValue (Seconds (2)),
121  MakeTimeAccessor (&UanMacRcGw::m_maxDelta),
122  MakeTimeChecker ())
123  .AddAttribute ("SIFS",
124  "Spacing between frames to account for timing error and processing delay.",
125  TimeValue (Seconds (0.2)),
126  MakeTimeAccessor (&UanMacRcGw::m_sifs),
127  MakeTimeChecker ())
128  .AddAttribute ("NumberOfNodes",
129  "Number of non-gateway nodes in this gateway's neighborhood.",
130  UintegerValue (10),
131  MakeUintegerAccessor (&UanMacRcGw::m_numNodes),
132  MakeUintegerChecker<uint32_t> ())
133  .AddAttribute ("MinRetryRate",
134  "Smallest allowed RTS retry rate.",
135  DoubleValue (0.01),
136  MakeDoubleAccessor (&UanMacRcGw::m_minRetryRate),
137  MakeDoubleChecker<double> ())
138  .AddAttribute ("RetryStep",
139  "Retry rate increment.",
140  DoubleValue (0.01),
141  MakeDoubleAccessor (&UanMacRcGw::m_retryStep),
142  MakeDoubleChecker<double> ())
143  .AddAttribute ("TotalRate",
144  "Total available channel rate in bps (for a single channel, without splitting reservation channel).",
145  UintegerValue (4096),
146  MakeUintegerAccessor (&UanMacRcGw::m_totalRate),
147  MakeUintegerChecker<uint32_t> ())
148  .AddAttribute ("RateStep",
149  "Increments available for rate assignment in bps.",
150  UintegerValue (4),
151  MakeUintegerAccessor (&UanMacRcGw::m_rateStep),
152  MakeUintegerChecker<uint32_t> ())
153  .AddAttribute ("FrameSize",
154  "Size of data frames in bytes.",
155  UintegerValue (1000),
156  MakeUintegerAccessor (&UanMacRcGw::m_frameSize),
157  MakeUintegerChecker<uint32_t> ())
158  .AddTraceSource ("RX",
159  "A packet was destined for and received at this MAC layer.",
161  .AddTraceSource ("Cycle",
162  "Trace cycle statistics.",
164 
165  ;
166 
167  return tid;
168 }
169 
170 Address
172 {
173  return m_address;
174 }
175 
176 void
178 {
179  m_address = addr;
180 }
181 
182 bool
183 UanMacRcGw::Enqueue (Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
184 {
185  NS_LOG_WARN ("RCMAC Gateway transmission to acoustic nodes is not yet implemented");
186  return false;
187 }
188 
189 void
191 {
192  m_forwardUpCb = cb;
193 }
194 
195 void
197 {
198  m_phy = phy;
199  phy->SetReceiveOkCallback (MakeCallback (&UanMacRcGw::ReceivePacket, this));
200  phy->SetReceiveErrorCallback (MakeCallback (&UanMacRcGw::ReceiveError, this));
201 }
202 
203 void
205 {
206 }
207 
208 Address
210 {
211  return UanAddress::GetBroadcast ();
212 }
213 
214 void
216 {
217  UanHeaderCommon ch;
218  pkt->PeekHeader (ch);
219 
220  if (ch.GetDest () == m_address || ch.GetDest () == UanAddress::GetBroadcast ())
221  {
222  m_rxLogger (pkt, mode);
223  }
224  else
225  {
226  return;
227  }
228 
229  pkt->RemoveHeader (ch);
230 
231  switch (ch.GetType ())
232  {
233  case UanMacRc::TYPE_DATA:
234  {
235  UanHeaderRcData dh;
236  pkt->RemoveHeader (dh);
237  m_propDelay[ch.GetSrc ()] = dh.GetPropDelay ();
238  if (m_ackData.find (ch.GetSrc ()) == m_ackData.end ())
239  {
240  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GATEWAY Received unexpected data packet");
241  }
242  else
243  {
244  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GW Received data packet from " << ch.GetSrc () << " length = " << pkt->GetSize ());
245  m_ackData[ch.GetSrc ()].rxFrames.insert (dh.GetFrameNo ());
246  }
247  m_forwardUpCb (pkt, ch.GetSrc ());
248  }
249  break;
251  case UanMacRc::TYPE_RTS:
252  if (m_state == CTSING)
253  {
254  return;
255  }
256 
257  {
258  UanHeaderRcRts rh;
259  pkt->RemoveHeader (rh);
260 
261  if (m_requests.find (ch.GetSrc ()) == m_requests.end ())
262  {
263  Request req;
264  req.numFrames = rh.GetNoFrames ();
265  req.rxTime = Simulator::Now ();
266  req.frameNo = rh.GetFrameNo ();
267  req.retryNo = rh.GetRetryNo ();
268  req.length = rh.GetLength ();
269  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GW storing reservation from " << ch.GetSrc () << " with length " << req.length);
270  m_requests.insert (std::make_pair (ch.GetSrc (), req));
271  std::map<UanAddress, Time>::iterator it = m_propDelay.find (ch.GetSrc ());
272  if (it == m_propDelay.end ())
273  {
274  m_sortedRes.insert (std::make_pair (m_maxDelta, ch.GetSrc ()));
275  }
276  else
277  {
278  m_sortedRes.insert (std::make_pair ( (*it).second, ch.GetSrc ()));
279  }
280  }
281  }
282  if (m_state == IDLE)
283  {
284  StartCycle ();
285  }
286  break;
287  case UanMacRc::TYPE_CTS:
288  NS_FATAL_ERROR ("Received CTS at GW. Currently only support single GW network!");
289  break;
290  case UanMacRc::TYPE_ACK:
291  NS_FATAL_ERROR ("Received ACK at GW. Currently only support single GW network!");
292  break;
293  default:
294  NS_FATAL_ERROR ("Received unknown packet at GW!");
295  }
296 }
297 
298 void
300 {
301  uint32_t numRts = m_sortedRes.size ();
302 
303  if (numRts)
304  {
305  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Simulator starting non-empty cycle");
306  }
307  else
308  {
309  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Simulator starting EMPTY cycle");
310  }
311 
312  // Calculate dataRate
313  uint32_t totalBytes = 0;
314  uint32_t totalFrames = 0;
315  double pDelay = 0;
316  if (numRts > 0)
317  {
318  std::map<UanAddress, Request>::iterator rit = m_requests.begin ();
319  for (; rit != m_requests.end (); rit++)
320  {
321  totalBytes += (*rit).second.length;
322  totalFrames += (*rit).second.numFrames;
323  }
324  pDelay = 2 * m_sortedRes.begin ()->first.GetSeconds ();
325  }
326 
327 
328  double minRate = m_phy->GetMode (m_numRates).GetDataRateBps ();
329 
330  uint32_t optA = m_maxRes;
331  if (m_maxRes == 0)
332  {
333  optA = FindOptA ();
334  }
335  double thAlpha = ComputeAlpha (totalFrames, totalBytes, m_numNodes, optA, pDelay / 2.0);
336 
337  double thCtlRate = m_totalRate * thAlpha;
338 
339  double temprate = (thCtlRate - minRate) / ((double) m_rateStep) + 0.5;
340  m_currentRateNum = (uint32_t) temprate;
342  {
344  }
345 
346  NS_LOG_DEBUG ("Found theoretical alpha: " << thAlpha << " Found associated rate = " << thCtlRate << " Giving rate number: " << temprate);
347  double thX = thAlpha * m_totalRate / (2.0 * m_numNodes * m_rtsSize * 8.0);
348 
349  double dataRate = m_phy->GetMode (m_currentRateNum).GetDataRateBps ();
350 
351 
352  if (thX < m_minRetryRate)
353  {
354  NS_LOG_WARN ("Gateway found optimum RTS retry rate is below minimum");
355  m_currentRetryRate = 0;
356  }
357  else
358  {
359  m_currentRetryRate = (uint16_t)((thX - m_minRetryRate) / m_retryStep + 0.5);
360  }
361 
362  double actualX = m_currentRetryRate * m_retryStep + m_minRetryRate;
363 
364  uint32_t ctlRate = m_phy->GetMode (m_currentRateNum + m_numRates).GetDataRateBps ();
365 
366 
367  double winSize = (double)(totalBytes) * 8.0 / dataRate + m_sifs.GetSeconds () * totalFrames + pDelay;
368  if (numRts == 0)
369  {
370  winSize = (optA * std::exp (1.0) + 0.5) * 2.0 * 8.0 * m_rtsSize / (thAlpha * m_totalRate) + 2 * m_maxDelta.GetSeconds ();
371  }
372  double effWinSize = winSize - m_rtsSize * 8 / ctlRate - 2 * m_maxDelta.GetSeconds ();
373 
374 
375  // Before fast CTS/ACK(below)
376  double cycleSeconds = winSize + (totalFrames + 1.0) * m_sifs.GetSeconds () + m_ctsSizeG * 8.0 / dataRate + (m_ctsSizeN + m_ackSize) * 8.0 * numRts / dataRate;
377 
378  Time ctsTxTimeG = Seconds (m_ctsSizeG * 8.0 / dataRate);
379  Time ctsTxTimeTotal = Seconds (m_ctsSizeN * 8.0 * numRts / dataRate) + ctsTxTimeG;
380  if (numRts == 0)
381  {
383  ctsg.SetWindowTime (Seconds (effWinSize));
386  ctsg.SetTxTimeStamp (Simulator::Now ());
387 
389  Ptr<Packet> p = Create<Packet> ();
390  p->AddHeader (ctsg);
391  p->AddHeader (ch);
393 
394 
395  Simulator::Schedule (Seconds (cycleSeconds), &UanMacRcGw::StartCycle, this);
396  m_state = INCYCLE;
397  m_cycleLogger (Simulator::Now (), Seconds (0), numRts, totalBytes, effWinSize, ctlRate, actualX);
398  return;
399  }
400 
401  Time nextEarliest = ctsTxTimeTotal + m_sifs;
402 
403  m_state = CTSING;
404  Simulator::Schedule (nextEarliest, &UanMacRcGw::CycleStarted, this);
405 
406  std::set<std::pair<Time, UanAddress> >::iterator it = m_sortedRes.begin ();
407  Time minPdelay = (*it).first;
408  Ptr<Packet> cts = Create<Packet> ();
409 
410  for (; it != m_sortedRes.end (); it++)
411  {
412  Request req = m_requests[(*it).second];
413  Time pdelay = (*it).first;
414 
415  AckData newData;
416  newData.expFrames = req.numFrames;
417  newData.frameNo = req.frameNo;
418  UanAddress dest = (*it).second;
419  m_ackData.insert (std::make_pair (dest, newData));
420 
421  Time earliestArr = ctsTxTimeTotal + pdelay + pdelay + m_sifs;
422  Time arrivalTime = std::max (earliestArr, nextEarliest);
423  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GW: Scheduling request for prop. delay " << pdelay.GetSeconds () << " for " << (*it).second << " Earliest possible arrival=" << earliestArr.GetSeconds () << " Next arrival time=" << nextEarliest.GetSeconds ());
424  nextEarliest = arrivalTime + Seconds (req.length * 8.0 / dataRate) + Seconds (m_sifs.GetSeconds () * req.numFrames);
425 
426  UanHeaderRcCts ctsh;
427  ctsh.SetAddress (dest);
428  ctsh.SetRtsTimeStamp (req.rxTime);
429  ctsh.SetFrameNo (req.frameNo);
430  ctsh.SetRetryNo (req.retryNo);
431  ctsh.SetDelayToTx (arrivalTime);
432  cts->AddHeader (ctsh);
433 
434  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GW Scheduling reception for " << (uint32_t) req.numFrames << " frames at " << (Simulator::Now () + arrivalTime).GetSeconds () << " (delaytiltx of " << arrivalTime.GetSeconds () << ") Total length is " << req.length << " with txtime " << req.length * 8 / dataRate << " seconds");
435  }
436 
440  ctsg.SetWindowTime (Seconds (effWinSize));
441  ctsg.SetTxTimeStamp (Simulator::Now ());
442  UanHeaderCommon ch;
444  ch.SetSrc (m_address);
446  cts->AddHeader (ctsg);
447  cts->AddHeader (ch);
449 
450  m_requests.clear ();
451  m_sortedRes.clear ();
452  Simulator::Schedule (nextEarliest, &UanMacRcGw::EndCycle, this);
453 
454 
455  m_cycleLogger (Simulator::Now (), minPdelay, numRts, totalBytes, cycleSeconds, ctlRate, actualX);
456 }
457 
458 void
460 {
461  m_state = INCYCLE;
462 }
463 void
465 {
466 
467  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GW Ending cycle");
468 
469  Time nextAck = Seconds (0);
470 
471  Time ackTime = Seconds (m_ackSize * 8.0 / m_phy->GetMode (m_currentRateNum).GetDataRateBps ());
472 
473  std::map<UanAddress, AckData>::iterator it = m_ackData.begin ();
474  for (; it != m_ackData.end (); it++)
475  {
476  UanAddress dest = (*it).first;
477  AckData &data = (*it).second;
478 
479  std::list<uint32_t> toNack;
480  for (uint32_t i = 0; i < data.expFrames; i++)
481  {
482  if (data.rxFrames.find (i) == data.rxFrames.end ())
483  {
484  toNack.push_back (i);
485  }
486  }
487  UanHeaderCommon ch;
488  ch.SetDest (dest);
489  ch.SetSrc (m_address);
491  UanHeaderRcAck ah;
492  ah.SetFrameNo (data.frameNo);
493  std::list<uint32_t>::iterator nit = toNack.begin ();
494  for (; nit != toNack.end (); nit++)
495  {
496  ah.AddNackedFrame (*nit);
497  }
498 
499  Ptr<Packet> ack = Create<Packet> ();
500  ack->AddHeader (ah);
501  ack->AddHeader (ch);
503  nextAck = nextAck + ackTime + m_sifs;
504  }
505  m_ackData.clear ();
507 
508 }
509 void
511 {
512  UanHeaderCommon ch;
513  pkt->PeekHeader (ch);
514  std::string type;
515  switch (ch.GetType ())
516  {
517  case UanMacRc::TYPE_DATA:
518  type = "DATA";
519  break;
520  case UanMacRc::TYPE_RTS:
521  type = "RTS";
522  break;
523  case UanMacRc::TYPE_CTS:
524  type = "CTS";
525  break;
526  case UanMacRc::TYPE_ACK:
527  type = "ACK";
528  break;
530  type = "GWPING";
531  break;
532  default:
533  type = "UNKNOWN";
534  break;
535  }
536  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GW sending " << type << " packet with size " << pkt->GetSize () << " to " << ch.GetDest () << " at rate " << rate);
537  m_phy->SendPacket (pkt, rate);
538 }
539 
540 
541 double
542 UanMacRcGw::ComputeAlpha (uint32_t totalFrames, uint32_t totalBytes, uint32_t n, uint32_t a, double deltaK)
543 {
544 
545  double alpha;
546  double lrae = m_rtsSize * 8.0 * a * std::exp (1.0);
547  if (totalFrames == 0)
548  {
549 
550  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)) ) /
551  (2 * lrae + 8.0 * m_rtsSize - 8.0 * m_ctsSizeG);
552  }
553  else
554  {
555  double w = totalBytes * 8.0 + totalFrames*m_sifs.GetSeconds () * m_totalRate;
556  double v = m_rtsSize * 8.0 + 2 * lrae;
557  double u = (2 * m_maxDelta.GetSeconds () - 2 * deltaK) * m_totalRate;
558 
559  double gamma = (w - u + v) / (2 * (u - totalFrames * m_sifs.GetSeconds () * m_totalRate));
560 
561  alpha = -gamma + std::sqrt (gamma * gamma + v / (u - totalFrames * m_sifs.GetSeconds () * m_totalRate));
562 
563  if (alpha < 0 || alpha > 1)
564  {
565  alpha = -gamma - std::sqrt (gamma * gamma + v / (u - totalFrames * m_sifs.GetSeconds () * m_totalRate));
566  }
567  }
568  NS_ASSERT_MSG (alpha > 0 && alpha < 1, "Error computing alpha. Alpha out of valid range!");
569  return alpha;
570 }
571 
572 std::vector<double>
574 {
575  uint32_t n = m_numNodes;
576  std::vector<double> pds;
577  std::map<UanAddress, Time>::iterator pdit = m_propDelay.begin ();
578 
579  for (; pdit != m_propDelay.end (); pdit++)
580  {
581  pds.push_back (pdit->second.GetSeconds ());
582  }
583  while (pds.size () < m_numNodes)
584  {
585  pds.push_back (m_maxDelta.GetSeconds ());
586  }
587 
588  std::sort (pds.begin (), pds.end ());
589  // Find expected min. prop. delay for k nodes
590  std::vector<double> exppdk;
591  exppdk.push_back (m_maxDelta.GetSeconds ());
592  for (uint32_t k = 1; k <= n; k++)
593  {
594  uint32_t ind = CompExpMinIndex (n,k) - 1;
595  exppdk.push_back (pds[ind]);
596  }
597  return exppdk;
598 }
599 
600 double
601 UanMacRcGw::ComputeExpS (uint32_t a, uint32_t ld, std::vector<double> exppdk)
602 {
603  UanHeaderCommon ch;
604  uint32_t lh = ch.GetSerializedSize ();
605 
606  uint32_t n = m_numNodes;
607  double expk = n * (1 - std::exp (-((double) a) / (double) n));
608  NS_LOG_DEBUG ("expk = " << expk);
609 
610  // Compute expected data per cycle
611  double expdata = 8 * ld * expk;
612 
613  // Compute expected time per cycle
614  double alpha0 = ComputeAlpha (0,0,n,a,exppdk[0]);
615  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);
616  double exptime = ComputePiK (a,n,0) * c0;
617  double expp = 0;
618  for (uint32_t i = 1; i <= n; i++)
619  {
620  expp += ComputePiK (a,n,i) * exppdk[i - 1];
621  }
622 
623  exptime += ComputeExpBOverA (n,a,ld + lh,exppdk) + expk * 2 * m_sifs.GetSeconds () + m_sifs.GetSeconds () + 2 * expp;
624  double s = (1.0 / m_totalRate) * expdata / exptime;
625 
626  return s;
627 }
628 
629 double
630 UanMacRcGw::ComputeExpS (uint32_t a, uint32_t ld)
631 {
632  return ComputeExpS (a, ld, GetExpPdk ());
633 }
634 
635 uint32_t
636 UanMacRcGw::CompExpMinIndex (uint32_t n, uint32_t k)
637 {
638  double sum = 0;
639  for (uint32_t i = 1; i <= n - k + 1; i++)
640  {
641  double nChK = NchooseK (n, k);
642  double p = (nChK > 0) ? (NchooseK (n - i, k - 1) / nChK) : DBL_MAX;
643  sum += p * i;
644  }
645  return (uint32_t)(sum + 0.5);
646 }
647 
648 double
649 UanMacRcGw::ComputePiK (uint32_t a, uint32_t n, uint32_t k)
650 {
651  double nck = (double) NchooseK (n, k);
652  return nck * std::pow ( (std::exp ( (double) a / (double) n) - 1.0), (double) k) * std::exp (-( (double) a));
653 }
654 
655 double
656 UanMacRcGw::ComputeExpBOverA (uint32_t n, uint32_t a, uint32_t ldlh, std::vector<double> deltaK)
657 {
658 
659  double sum = 0;
660  uint32_t lt = 8 * (m_ctsSizeN + ldlh + m_ackSize);
661  for (uint32_t k = 1; k <= n; k++)
662  {
663  double num = 8.0 * m_ctsSizeG + k * lt;
664  double denom = (1.0 - ComputeAlpha (k, k * ldlh, n, a, deltaK[k])) * m_totalRate;
665  double pik = ComputePiK (a, n, k);
666  double term = pik * num / denom;
667 
668  sum += term;
669  }
670 
671  return sum;
672 }
673 
674 uint64_t
675 UanMacRcGw::NchooseK (uint32_t n, uint32_t k)
676 {
677  if (k > n)
678  {
679  return 0;
680  }
681 
682  if (k > n / 2)
683  {
684  k = n - k;
685  }
686 
687  double accum = 1;
688  for (uint32_t i = 1; i <= k; i++)
689  {
690  accum = accum * (n - k + i) / i;
691  }
692 
693  return (uint64_t)(accum + 0.5);
694 
695 }
696 
697 uint32_t
699 {
700  double tput = 0;
701  uint32_t a = 1;
702  while (1)
703  {
704 
705  double newtput = ComputeExpS (a, m_frameSize);
706  if (newtput < tput)
707  {
708  a--;
709  break;
710  }
711  else
712  {
713  tput = newtput;
714  a++;
715  }
716  }
717  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GW: Found optimum a = " << a);
718  return a;
719 }
720 
721 int64_t
723 {
724  NS_LOG_FUNCTION (this << stream);
725  return 0;
726 }
727 
728 } // namespace ns3
std::set< std::pair< Time, UanAddress > > m_sortedRes
Queued request times.
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
Time GetPropDelay(void) const
Get the propagation delay found in handshaking.
double m_retryStep
Retry rate increment.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:79
virtual void AttachPhy(Ptr< UanPhy > phy)
Attach PHY layer to this MAC.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Time rxTime
Time request received.
Definition: uan-mac-rc-gw.h:98
Cycle broadcast information.
void SetRateNum(uint16_t rate)
Set the rate number corresponding to data rate of current cycle.
uint32_t CompExpMinIndex(uint32_t n, uint32_t k)
Index to the k'th expected delay among n nodes.
virtual uint32_t GetSerializedSize(void) const
Callback template class.
Definition: callback.h:924
TracedCallback< Time, Time, uint32_t, uint32_t, double, uint32_t, double > m_cycleLogger
A packet was destined for and received at this MAC layer.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
uint32_t m_ctsSizeG
Size of UanHeaderCommon and UanHeaderRcCtsGlobal.
Header used for ACK packets by protocol UanMacRc.
bool m_cleared
Flag when we've been cleared.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
void SetAddress(UanAddress addr)
Set the destination address, for scheduling info.
uint32_t m_numRates
Number of rates per Phy layer.
Time m_sifs
Spacing between frames to account for timing error and processing delay.
Channel is IDLE, no packet is being transmitted.
Definition: csma-channel.h:62
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
std::map< UanAddress, Time > m_propDelay
Propagation delay to each node.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:744
uint16_t m_currentRetryRate
Retry rate number for current cycle.
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: object.cc:335
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:95
double m_minRetryRate
Smallest allowed RTS retry rate.
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:825
virtual void Clear(void)
Clears all pointer references.
virtual Address GetBroadcast(void) const
Get the broadcast address.
State m_state
Gateway processing state.
Definition: uan-mac-rc-gw.h:86
uint8_t GetType(void) const
Get the header type value.
void SetWindowTime(Time t)
Set the window time (time duration following blocking time to allow RTS transmissions).
Callback< void, Ptr< Packet >, const UanAddress & > m_forwardUpCb
Forwarding up callback.
virtual ~UanMacRcGw()
Dummy destructor, see DoDispose.
uint8_t GetFrameNo(void) const
Get the frame number.
a polymophic address class
Definition: address.h:86
uint8_t numFrames
Number of frames.
Definition: uan-mac-rc-gw.h:94
std::vector< double > GetExpPdk(void)
Get the expected propagation delay to each node.
void ReceiveError(Ptr< Packet > pkt, double sinr)
PHY receive error callback.
double GetSeconds(void) const
Definition: nstime.h:272
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.
void SendPacket(Ptr< Packet > pkt, uint32_t rate)
Send packet on PHY.
Virtual base class for all UAN MAC protocols.
Definition: uan-mac.h:47
virtual Address GetAddress(void)
Get the MAC Address.
uint64_t NchooseK(uint32_t n, uint32_t k)
Binomial coefficient.
hold objects of type ns3::Time
Definition: nstime.h:1008
A class used for addressing UAN MAC's.
Definition: uan-address.h:40
virtual uint32_t GetSerializedSize(void) const
Hold an unsigned integer type.
Definition: uinteger.h:46
void SetSrc(UanAddress src)
Set the source address.
uint8_t data[writeSize]
Ptr< SampleEmitter > s
uint32_t m_numNodes
Number of non-gateway nodes in this gateway's neighborhood.
Abstraction of packet modulation information.
Definition: uan-tx-mode.h:41
void ReceivePacket(Ptr< Packet > pkt, double sinr, UanTxMode mode)
PHY recieve ok callback.
uint8_t frameNo
Current frame number.
Definition: uan-mac-rc-gw.h:95
virtual void DoDispose()
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
uint32_t m_rateStep
Increments available for rate assignment in bps.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1242
virtual void SetAddress(UanAddress addr)
Set the address.
uint16_t length
Request header length.
Definition: uan-mac-rc-gw.h:97
TracedCallback< Ptr< const Packet >, UanTxMode > m_rxLogger
A packet was destined for and received at this MAC layer.
uint32_t m_currentRateNum
Rate number corresponding to data rate of current cycle.
void SetDest(UanAddress dest)
Set the destination address.
void AddNackedFrame(uint8_t frame)
NACK a frame.
uint8_t GetRetryNo(void) const
Get the retry number of this RTS packet.
static UanAddress GetBroadcast(void)
Get the broadcast address (255).
Definition: uan-address.cc:92
uint32_t FindOptA(void)
Compute the optimum maximum number of reservations to accept per cycle.
uint8_t expFrames
Expected number of frames.
uint8_t GetFrameNo(void) const
Get the frame number of the reservation being transmitted.
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:277
uint32_t m_ctsSizeN
Size of UanHeaderRcCts.
static TypeId GetTypeId(void)
Register this type.
Common packet header fields.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
UanAddress GetDest(void) const
Get the destination address.
Reservation request.
Definition: uan-mac-rc-gw.h:92
Cycling through nodes.
Definition: uan-mac-rc-gw.h:83
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
void SetTxTimeStamp(Time timeStamp)
Set the CTS timestamp.
uint8_t frameNo
Frame number being ACK'ed.
std::map< UanAddress, Request > m_requests
Request for each node.
uint8_t GetNoFrames(void) const
Get the number of data frames in the reservation.
Ptr< UanPhy > m_phy
PHY layer attached to this MAC.
#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:84
uint32_t m_frameSize
Size of data frames in bytes.
uint32_t m_totalRate
Total available channel rate in bps (for a single channel, without splitting reservation channel)...
void StartCycle(void)
Cycle through pending requests.
UanMacRcGw()
Constructor.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:203
uint32_t m_maxRes
Maximum number of reservations to accept per cycle.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:213
void SetFrameNo(uint8_t frameNo)
Set the frame number of the reservation being acknowledged.
void CycleStarted(void)
Set state to INCYCLE.
double ComputePiK(uint32_t a, uint32_t n, uint32_t k)
Numeric function.
uint32_t m_rtsSize
Size of UanHeaderCommon and UanHeaderRcRts.
virtual uint32_t GetSerializedSize(void) const
void SetType(uint8_t type)
Set the header type.
void EndCycle(void)
End cycle by scheduling pending ACKs.
UanAddress GetSrc(void) const
Get the source address.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:441
std::map< UanAddress, AckData > m_ackData
AckData for each node.
UanAddress m_address
The MAC address.
uint8_t retryNo
Retry number.
Definition: uan-mac-rc-gw.h:96
Initial idle state.
Definition: uan-mac-rc-gw.h:82
virtual bool Enqueue(Ptr< Packet > pkt, const Address &dest, uint16_t protocolNumber)
Enqueue packet to be transmitted.
double ComputeAlpha(uint32_t totalFrames, uint32_t totalBytes, uint32_t n, uint32_t a, double deltaK)
Compute alpha parameter.
void SetRetryRate(uint16_t rate)
Set the retry rate number for the current cycle.
Hold a floating point type.
Definition: double.h:41
virtual uint32_t GetSerializedSize(void) const
std::set< uint8_t > rxFrames
Received frames.
Packet ACK data.
a unique identifier for an interface.
Definition: type-id.h:49
uint32_t m_ackSize
Size of UanHeaderCommon and UanHeaderRcAck.
virtual uint32_t GetSerializedSize(void) const
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
double ComputeExpBOverA(uint32_t n, uint32_t a, uint32_t ldlh, std::vector< double > deltaK)
Numeric function.
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:253
Extra data header information.
Definition: uan-header-rc.h:41
uint16_t GetLength(void) const
Get the total number of bytes in the reservation, including headers.
virtual void SetForwardUpCb(Callback< void, Ptr< Packet >, const UanAddress & > cb)
Set the callback to forward packets up to higher layers.