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 
48 bool
50 {
51  return a.GetAsInt () < b.GetAsInt ();
52 }
53 
54 
56  : UanMac (),
57  m_state (IDLE),
58  m_currentRateNum (0),
59  m_cleared (false)
60 {
61  UanHeaderCommon ch;
62  UanHeaderRcRts rts;
63  UanHeaderRcCts cts;
64  UanHeaderRcAck ack;
66 
71 
72  NS_LOG_DEBUG ("Gateway initialized");
73 }
74 
76 {
77 }
78 
79 void
81 {
82  if (m_cleared)
83  {
84  return;
85  }
86  m_cleared = true;
87  if (m_phy)
88  {
89  m_phy->Clear ();
90  m_phy = 0;
91  }
92  m_propDelay.clear ();
93  std::map<UanAddress, AckData>::iterator it = m_ackData.begin ();
94  for (; it != m_ackData.end (); it++)
95  {
96  it->second.rxFrames.clear ();
97  }
98  m_ackData.clear ();
99  m_requests.clear ();
100  m_sortedRes.clear ();
101 }
102 
103 void
105 {
106  Clear ();
108 }
109 TypeId
111 {
112  static TypeId tid = TypeId ("ns3::UanMacRcGw")
113  .SetParent<UanMac> ()
114  .AddConstructor<UanMacRcGw> ()
115  .AddAttribute ("MaxReservations",
116  "Maximum number of reservations to accept per cycle",
117  UintegerValue (10),
118  MakeUintegerAccessor (&UanMacRcGw::m_maxRes),
119  MakeUintegerChecker<uint32_t> ())
120  .AddAttribute ("NumberOfRates",
121  "Number of rates per Phy layer",
122  UintegerValue (1023),
123  MakeUintegerAccessor (&UanMacRcGw::m_numRates),
124  MakeUintegerChecker<uint32_t> ())
125  .AddAttribute ("MaxPropDelay",
126  "Maximum propagation delay between gateway and non-gateway nodes",
127  TimeValue (Seconds (2)),
128  MakeTimeAccessor (&UanMacRcGw::m_maxDelta),
129  MakeTimeChecker ())
130  .AddAttribute ("SIFS",
131  "Spacing between frames to account for timing error and processing delay",
132  TimeValue (Seconds (0.2)),
133  MakeTimeAccessor (&UanMacRcGw::m_sifs),
134  MakeTimeChecker ())
135  .AddAttribute ("NumberOfNodes",
136  "Number of non-gateway nodes in this gateway's neighborhood",
137  UintegerValue (10),
138  MakeUintegerAccessor (&UanMacRcGw::m_numNodes),
139  MakeUintegerChecker<uint32_t> ())
140  .AddAttribute ("MinRetryRate",
141  "Smallest allowed RTS retry rate",
142  DoubleValue (0.01),
143  MakeDoubleAccessor (&UanMacRcGw::m_minRetryRate),
144  MakeDoubleChecker<double> ())
145  .AddAttribute ("RetryStep",
146  "Retry rate increment",
147  DoubleValue (0.01),
148  MakeDoubleAccessor (&UanMacRcGw::m_retryStep),
149  MakeDoubleChecker<double> ())
150  .AddAttribute ("TotalRate",
151  "Total available channel rate in bps (for a single channel, without splitting reservation channel)",
152  UintegerValue (4096),
153  MakeUintegerAccessor (&UanMacRcGw::m_totalRate),
154  MakeUintegerChecker<uint32_t> ())
155  .AddAttribute ("RateStep",
156  "Increments available for rate assignment in bps",
157  UintegerValue (4),
158  MakeUintegerAccessor (&UanMacRcGw::m_rateStep),
159  MakeUintegerChecker<uint32_t> ())
160  .AddAttribute ("FrameSize",
161  "Size of data frames in bytes",
162  UintegerValue (1000),
163  MakeUintegerAccessor (&UanMacRcGw::m_frameSize),
164  MakeUintegerChecker<uint32_t> ())
165  .AddTraceSource ("RX",
166  "A packet was destined for and received at this MAC layer",
168  .AddTraceSource ("Cycle",
169  "Trace cycle statistics",
171 
172  ;
173 
174  return tid;
175 }
176 
177 Address
179 {
180  return m_address;
181 }
182 
183 void
185 {
186  m_address = addr;
187 }
188 
189 bool
190 UanMacRcGw::Enqueue (Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
191 {
192  NS_LOG_WARN ("RCMAC Gateway transmission to acoustic nodes is not yet implemented");
193  return false;
194 }
195 
196 void
198 {
199  m_forwardUpCb = cb;
200 }
201 
202 void
204 {
205  m_phy = phy;
206  phy->SetReceiveOkCallback (MakeCallback (&UanMacRcGw::ReceivePacket, this));
207  phy->SetReceiveErrorCallback (MakeCallback (&UanMacRcGw::ReceiveError, this));
208 }
209 
210 void
212 {
213 }
214 
215 Address
217 {
218  return UanAddress::GetBroadcast ();
219 }
220 
221 void
223 {
224  UanHeaderCommon ch;
225  pkt->PeekHeader (ch);
226 
227  if (ch.GetDest () == m_address || ch.GetDest () == UanAddress::GetBroadcast ())
228  {
229  m_rxLogger (pkt, mode);
230  }
231  else
232  {
233  return;
234  }
235 
236  pkt->RemoveHeader (ch);
237 
238  switch (ch.GetType ())
239  {
240  case UanMacRc::TYPE_DATA:
241  {
242  UanHeaderRcData dh;
243  pkt->RemoveHeader (dh);
244  m_propDelay[ch.GetSrc ()] = dh.GetPropDelay ();
245  if (m_ackData.find (ch.GetSrc ()) == m_ackData.end ())
246  {
247  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GATEWAY Received unexpected data packet");
248  }
249  else
250  {
251  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GW Received data packet from " << ch.GetSrc () << " length = " << pkt->GetSize ());
252  m_ackData[ch.GetSrc ()].rxFrames.insert (dh.GetFrameNo ());
253  }
254  m_forwardUpCb (pkt, ch.GetSrc ());
255  }
256  break;
258  case UanMacRc::TYPE_RTS:
259  if (m_state == CTSING)
260  {
261  return;
262  }
263 
264  {
265  UanHeaderRcRts rh;
266  pkt->RemoveHeader (rh);
267 
268  if (m_requests.find (ch.GetSrc ()) == m_requests.end ())
269  {
270  Request req;
271  req.numFrames = rh.GetNoFrames ();
272  req.rxTime = Simulator::Now ();
273  req.frameNo = rh.GetFrameNo ();
274  req.retryNo = rh.GetRetryNo ();
275  req.length = rh.GetLength ();
276  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GW storing reservation from " << ch.GetSrc () << " with length " << req.length);
277  m_requests.insert (std::make_pair (ch.GetSrc (), req));
278  std::map<UanAddress, Time>::iterator it = m_propDelay.find (ch.GetSrc ());
279  if (it == m_propDelay.end ())
280  {
281  m_sortedRes.insert (std::make_pair (m_maxDelta, ch.GetSrc ()));
282  }
283  else
284  {
285  m_sortedRes.insert (std::make_pair ( (*it).second, ch.GetSrc ()));
286  }
287  }
288  }
289  if (m_state == IDLE)
290  {
291  StartCycle ();
292  }
293  break;
294  case UanMacRc::TYPE_CTS:
295  NS_FATAL_ERROR ("Received CTS at GW. Currently only support single GW network!");
296  break;
297  case UanMacRc::TYPE_ACK:
298  NS_FATAL_ERROR ("Received ACK at GW. Currently only support single GW network!");
299  break;
300  default:
301  NS_FATAL_ERROR ("Received unknown packet at GW!");
302  }
303 }
304 
305 void
307 {
308  uint32_t numRts = m_sortedRes.size ();
309 
310  if (numRts)
311  {
312  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Simulator starting non-empty cycle");
313  }
314  else
315  {
316  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Simulator starting EMPTY cycle");
317  }
318 
319  // Calculate dataRate
320  uint32_t totalBytes = 0;
321  uint32_t totalFrames = 0;
322  double pDelay = 0;
323  if (numRts > 0)
324  {
325  std::map<UanAddress, Request>::iterator rit = m_requests.begin ();
326  for (; rit != m_requests.end (); rit++)
327  {
328  totalBytes += (*rit).second.length;
329  totalFrames += (*rit).second.numFrames;
330  }
331  pDelay = 2 * m_sortedRes.begin ()->first.GetSeconds ();
332  }
333 
334 
335  double minRate = m_phy->GetMode (m_numRates).GetDataRateBps ();
336 
337  uint32_t optA = m_maxRes;
338  if (m_maxRes == 0)
339  {
340  optA = FindOptA ();
341  }
342  double thAlpha = ComputeAlpha (totalFrames, totalBytes, m_numNodes, optA, pDelay / 2.0);
343 
344  double thCtlRate = m_totalRate * thAlpha;
345 
346  double temprate = (thCtlRate - minRate) / ((double) m_rateStep) + 0.5;
347  m_currentRateNum = (uint32_t) temprate;
349  {
351  }
352 
353  NS_LOG_DEBUG ("Found theoretical alpha: " << thAlpha << " Found associated rate = " << thCtlRate << " Giving rate number: " << temprate);
354  double thX = thAlpha * m_totalRate / (2.0 * m_numNodes * m_rtsSize * 8.0);
355 
356  double dataRate = m_phy->GetMode (m_currentRateNum).GetDataRateBps ();
357 
358 
359  if (thX < m_minRetryRate)
360  {
361  NS_LOG_WARN ("Gateway found optimum RTS retry rate is below minimum");
362  m_currentRetryRate = 0;
363  }
364  else
365  {
366  m_currentRetryRate = (uint16_t)((thX - m_minRetryRate) / m_retryStep + 0.5);
367  }
368 
369  double actualX = m_currentRetryRate * m_retryStep + m_minRetryRate;
370 
371  uint32_t ctlRate = m_phy->GetMode (m_currentRateNum + m_numRates).GetDataRateBps ();
372 
373 
374  double winSize = (double)(totalBytes) * 8.0 / dataRate + m_sifs.GetSeconds () * totalFrames + pDelay;
375  if (numRts == 0)
376  {
377  winSize = (optA * std::exp (1.0) + 0.5) * 2.0 * 8.0 * m_rtsSize / (thAlpha * m_totalRate) + 2 * m_maxDelta.GetSeconds ();
378  }
379  double effWinSize = winSize - m_rtsSize * 8 / ctlRate - 2 * m_maxDelta.GetSeconds ();
380 
381 
382  // Before fast CTS/ACK(below)
383  double cycleSeconds = winSize + (totalFrames + 1.0) * m_sifs.GetSeconds () + m_ctsSizeG * 8.0 / dataRate + (m_ctsSizeN + m_ackSize) * 8.0 * numRts / dataRate;
384 
385  Time ctsTxTimeG = Seconds (m_ctsSizeG * 8.0 / dataRate);
386  Time ctsTxTimeTotal = Seconds (m_ctsSizeN * 8.0 * numRts / dataRate) + ctsTxTimeG;
387  if (numRts == 0)
388  {
390  ctsg.SetWindowTime (Seconds (effWinSize));
393  ctsg.SetTxTimeStamp (Simulator::Now ());
394 
396  Ptr<Packet> p = Create<Packet> ();
397  p->AddHeader (ctsg);
398  p->AddHeader (ch);
400 
401 
402  Simulator::Schedule (Seconds (cycleSeconds), &UanMacRcGw::StartCycle, this);
403  m_state = INCYCLE;
404  m_cycleLogger (Simulator::Now (), Seconds (0), numRts, totalBytes, effWinSize, ctlRate, actualX);
405  return;
406  }
407 
408  Time nextEarliest = ctsTxTimeTotal + m_sifs;
409 
410  m_state = CTSING;
411  Simulator::Schedule (nextEarliest, &UanMacRcGw::CycleStarted, this);
412 
413  std::set<std::pair<Time, UanAddress> >::iterator it = m_sortedRes.begin ();
414  Time minPdelay = (*it).first;
415  Ptr<Packet> cts = Create<Packet> ();
416 
417  for (; it != m_sortedRes.end (); it++)
418  {
419  Request req = m_requests[(*it).second];
420  Time pdelay = (*it).first;
421 
422  AckData newData;
423  newData.expFrames = req.numFrames;
424  newData.frameNo = req.frameNo;
425  UanAddress dest = (*it).second;
426  m_ackData.insert (std::make_pair (dest, newData));
427 
428  Time earliestArr = ctsTxTimeTotal + pdelay + pdelay + m_sifs;
429  Time arrivalTime = std::max (earliestArr, nextEarliest);
430  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 ());
431  nextEarliest = arrivalTime + Seconds (req.length * 8.0 / dataRate) + Seconds (m_sifs.GetSeconds () * req.numFrames);
432 
433  UanHeaderRcCts ctsh;
434  ctsh.SetAddress (dest);
435  ctsh.SetRtsTimeStamp (req.rxTime);
436  ctsh.SetFrameNo (req.frameNo);
437  ctsh.SetRetryNo (req.retryNo);
438  ctsh.SetDelayToTx (arrivalTime);
439  cts->AddHeader (ctsh);
440 
441  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");
442  }
443 
447  ctsg.SetWindowTime (Seconds (effWinSize));
448  ctsg.SetTxTimeStamp (Simulator::Now ());
449  UanHeaderCommon ch;
451  ch.SetSrc (m_address);
453  cts->AddHeader (ctsg);
454  cts->AddHeader (ch);
456 
457  m_requests.clear ();
458  m_sortedRes.clear ();
459  Simulator::Schedule (nextEarliest, &UanMacRcGw::EndCycle, this);
460 
461 
462  m_cycleLogger (Simulator::Now (), minPdelay, numRts, totalBytes, cycleSeconds, ctlRate, actualX);
463 }
464 
465 void
467 {
468  m_state = INCYCLE;
469 }
470 void
472 {
473 
474  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GW Ending cycle");
475 
476  Time nextAck = Seconds (0);
477 
478  Time ackTime = Seconds (m_ackSize * 8.0 / m_phy->GetMode (m_currentRateNum).GetDataRateBps ());
479 
480  std::map<UanAddress, AckData>::iterator it = m_ackData.begin ();
481  for (; it != m_ackData.end (); it++)
482  {
483  UanAddress dest = (*it).first;
484  AckData &data = (*it).second;
485 
486  std::list<uint32_t> toNack;
487  for (uint32_t i = 0; i < data.expFrames; i++)
488  {
489  if (data.rxFrames.find (i) == data.rxFrames.end ())
490  {
491  toNack.push_back (i);
492  }
493  }
494  UanHeaderCommon ch;
495  ch.SetDest (dest);
496  ch.SetSrc (m_address);
498  UanHeaderRcAck ah;
499  ah.SetFrameNo (data.frameNo);
500  std::list<uint32_t>::iterator nit = toNack.begin ();
501  for (; nit != toNack.end (); nit++)
502  {
503  ah.AddNackedFrame (*nit);
504  }
505 
506  Ptr<Packet> ack = Create<Packet> ();
507  ack->AddHeader (ah);
508  ack->AddHeader (ch);
510  nextAck = nextAck + ackTime + m_sifs;
511  }
512  m_ackData.clear ();
514 
515 }
516 void
518 {
519  UanHeaderCommon ch;
520  pkt->PeekHeader (ch);
521  std::string type;
522  switch (ch.GetType ())
523  {
524  case UanMacRc::TYPE_DATA:
525  type = "DATA";
526  break;
527  case UanMacRc::TYPE_RTS:
528  type = "RTS";
529  break;
530  case UanMacRc::TYPE_CTS:
531  type = "CTS";
532  break;
533  case UanMacRc::TYPE_ACK:
534  type = "ACK";
535  break;
537  type = "GWPING";
538  break;
539  default:
540  type = "UNKNOWN";
541  break;
542  }
543  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GW sending " << type << " packet with size " << pkt->GetSize () << " to " << ch.GetDest () << " at rate " << rate);
544  m_phy->SendPacket (pkt, rate);
545 }
546 
547 
548 double
549 UanMacRcGw::ComputeAlpha (uint32_t totalFrames, uint32_t totalBytes, uint32_t n, uint32_t a, double deltaK)
550 {
551 
552  double alpha;
553  double lrae = m_rtsSize * 8.0 * a * std::exp (1.0);
554  if (totalFrames == 0)
555  {
556 
557  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)) ) /
558  (2 * lrae + 8.0 * m_rtsSize - 8.0 * m_ctsSizeG);
559  }
560  else
561  {
562  double w = totalBytes * 8.0 + totalFrames*m_sifs.GetSeconds () * m_totalRate;
563  double v = m_rtsSize * 8.0 + 2 * lrae;
564  double u = (2 * m_maxDelta.GetSeconds () - 2 * deltaK) * m_totalRate;
565 
566  double gamma = (w - u + v) / (2 * (u - totalFrames * m_sifs.GetSeconds () * m_totalRate));
567 
568  alpha = -gamma + std::sqrt (gamma * gamma + v / (u - totalFrames * m_sifs.GetSeconds () * m_totalRate));
569 
570  if (alpha < 0 || alpha > 1)
571  {
572  alpha = -gamma - std::sqrt (gamma * gamma + v / (u - totalFrames * m_sifs.GetSeconds () * m_totalRate));
573  }
574  }
575  NS_ASSERT_MSG (alpha > 0 && alpha < 1, "Error computing alpha. Alpha out of valid range!");
576  return alpha;
577 }
578 
579 std::vector<double>
581 {
582  uint32_t n = m_numNodes;
583  std::vector<double> pds;
584  std::map<UanAddress, Time>::iterator pdit = m_propDelay.begin ();
585 
586  for (; pdit != m_propDelay.end (); pdit++)
587  {
588  pds.push_back (pdit->second.GetSeconds ());
589  }
590  while (pds.size () < m_numNodes)
591  {
592  pds.push_back (m_maxDelta.GetSeconds ());
593  }
594 
595  std::sort (pds.begin (), pds.end ());
596  // Find expected min. prop. delay for k nodes
597  std::vector<double> exppdk;
598  exppdk.push_back (m_maxDelta.GetSeconds ());
599  for (uint32_t k = 1; k <= n; k++)
600  {
601  uint32_t ind = CompExpMinIndex (n,k) - 1;
602  exppdk.push_back (pds[ind]);
603  }
604  return exppdk;
605 }
606 
607 double
608 UanMacRcGw::ComputeExpS (uint32_t a, uint32_t ld, std::vector<double> exppdk)
609 {
610  UanHeaderCommon ch;
611  uint32_t lh = ch.GetSerializedSize ();
612 
613  uint32_t n = m_numNodes;
614  double expk = n * (1 - std::exp (-((double) a) / (double) n));
615  NS_LOG_DEBUG ("expk = " << expk);
616 
617  // Compute expected data per cycle
618  double expdata = 8 * ld * expk;
619 
620  // Compute expected time per cycle
621  double alpha0 = ComputeAlpha (0,0,n,a,exppdk[0]);
622  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);
623  double exptime = ComputePiK (a,n,0) * c0;
624  double expp = 0;
625  for (uint32_t i = 1; i <= n; i++)
626  {
627  expp += ComputePiK (a,n,i) * exppdk[i - 1];
628  }
629 
630  exptime += ComputeExpBOverA (n,a,ld + lh,exppdk) + expk * 2 * m_sifs.GetSeconds () + m_sifs.GetSeconds () + 2 * expp;
631  double s = (1.0 / m_totalRate) * expdata / exptime;
632 
633  return s;
634 }
635 
636 double
637 UanMacRcGw::ComputeExpS (uint32_t a, uint32_t ld)
638 {
639  return ComputeExpS (a, ld, GetExpPdk ());
640 }
641 
642 uint32_t
643 UanMacRcGw::CompExpMinIndex (uint32_t n, uint32_t k)
644 {
645  double sum = 0;
646  for (uint32_t i = 1; i <= n - k + 1; i++)
647  {
648  double nChK = NchooseK (n, k);
649  double p = (nChK > 0) ? (NchooseK (n - i, k - 1) / nChK) : DBL_MAX;
650  sum += p * i;
651  }
652  return (uint32_t)(sum + 0.5);
653 }
654 
655 double
656 UanMacRcGw::ComputePiK (uint32_t a, uint32_t n, uint32_t k)
657 {
658  double nck = (double) NchooseK (n, k);
659  return nck * std::pow ( (std::exp ( (double) a / (double) n) - 1.0), (double) k) * std::exp (-( (double) a));
660 }
661 
662 double
663 UanMacRcGw::ComputeExpBOverA (uint32_t n, uint32_t a, uint32_t ldlh, std::vector<double> deltaK)
664 {
665 
666  double sum = 0;
667  uint32_t lt = 8 * (m_ctsSizeN + ldlh + m_ackSize);
668  for (uint32_t k = 1; k <= n; k++)
669  {
670  double num = 8.0 * m_ctsSizeG + k * lt;
671  double denom = (1.0 - ComputeAlpha (k, k * ldlh, n, a, deltaK[k])) * m_totalRate;
672  double pik = ComputePiK (a, n, k);
673  double term = pik * num / denom;
674 
675  sum += term;
676  }
677 
678  return sum;
679 }
680 
681 uint64_t
682 UanMacRcGw::NchooseK (uint32_t n, uint32_t k)
683 {
684  if (k > n)
685  {
686  return 0;
687  }
688 
689  if (k > n / 2)
690  {
691  k = n - k;
692  }
693 
694  double accum = 1;
695  for (uint32_t i = 1; i <= k; i++)
696  {
697  accum = accum * (n - k + i) / i;
698  }
699 
700  return (uint64_t)(accum + 0.5);
701 
702 }
703 
704 uint32_t
706 {
707  double tput = 0;
708  uint32_t a = 1;
709  while (1)
710  {
711 
712  double newtput = ComputeExpS (a, m_frameSize);
713  if (newtput < tput)
714  {
715  a--;
716  break;
717  }
718  else
719  {
720  tput = newtput;
721  a++;
722  }
723  }
724  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GW: Found optimum a = " << a);
725  return a;
726 }
727 
728 int64_t
730 {
731  NS_LOG_FUNCTION (this << stream);
732  return 0;
733 }
734 
735 } // namespace ns3
std::set< std::pair< Time, UanAddress > > m_sortedRes
uint32_t RemoveHeader(Header &header)
Definition: packet.cc:268
Time GetPropDelay(void) const
keep track of time values and allow control of global simulation resolution
Definition: nstime.h:81
virtual void AttachPhy(Ptr< UanPhy > phy)
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
Cycle broadcast information for.
void SetRateNum(uint16_t rate)
uint32_t CompExpMinIndex(uint32_t n, uint32_t k)
virtual uint32_t GetSerializedSize(void) const
Callback template class.
Definition: callback.h:920
TracedCallback< Time, Time, uint32_t, uint32_t, double, uint32_t, double > m_cycleLogger
uint32_t m_ctsSizeG
Header used for ACK packets by protocol ns3::UanMacRc.
int64_t AssignStreams(int64_t stream)
void SetAddress(UanAddress addr)
uint32_t m_numRates
std::map< UanAddress, Time > m_propDelay
uint32_t GetSize(void) const
Definition: packet.h:650
uint16_t m_currentRetryRate
virtual void DoDispose(void)
Definition: object.cc:335
bool operator<(const Room &a, const Room &b)
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:824
virtual void Clear(void)
virtual Address GetBroadcast(void) const
uint8_t GetType(void) const
Callback< void, Ptr< Packet >, const UanAddress & > m_forwardUpCb
virtual ~UanMacRcGw()
uint8_t GetFrameNo(void) const
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
a polymophic address class
Definition: address.h:86
std::vector< double > GetExpPdk(void)
void ReceiveError(Ptr< Packet > pkt, double sinr)
double GetSeconds(void) const
Definition: nstime.h:266
double ComputeExpS(uint32_t a, uint32_t ld, std::vector< double > exppdk)
void SendPacket(Ptr< Packet > pkt, uint32_t rate)
Virtual base class for all UAN MAC protocols.
Definition: uan-mac.h:47
virtual Address GetAddress(void)
uint64_t NchooseK(uint32_t n, uint32_t k)
hold objects of type ns3::Time
Definition: nstime.h:828
virtual uint32_t GetSerializedSize(void) const
Hold an unsigned integer type.
Definition: uinteger.h:46
void SetSrc(UanAddress src)
uint8_t data[writeSize]
Ptr< SampleEmitter > s
uint32_t m_numNodes
NS_OBJECT_ENSURE_REGISTERED(AntennaModel)
Abstraction of packet modulation information.
Definition: uan-tx-mode.h:36
void ReceivePacket(Ptr< Packet > pkt, double sinr, UanTxMode mode)
virtual void DoDispose()
uint32_t m_rateStep
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1238
virtual void SetAddress(UanAddress addr)
TracedCallback< Ptr< const Packet >, UanTxMode > m_rxLogger
uint32_t m_currentRateNum
void SetDest(UanAddress dest)
void AddNackedFrame(uint8_t frame)
uint8_t GetRetryNo(void) const
static UanAddress GetBroadcast(void)
Definition: uan-address.cc:92
uint32_t FindOptA(void)
uint8_t GetFrameNo(void) const
uint32_t PeekHeader(Header &header) const
Definition: packet.cc:277
uint8_t GetAsInt(void) const
Definition: uan-address.cc:63
uint32_t m_ctsSizeN
static TypeId GetTypeId(void)
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
UanAddress GetDest(void) const
static Time Now(void)
Definition: simulator.cc:180
void SetTxTimeStamp(Time timeStamp)
std::map< UanAddress, Request > m_requests
uint8_t GetNoFrames(void) const
Ptr< UanPhy > m_phy
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
uint32_t m_frameSize
uint32_t m_totalRate
void StartCycle(void)
#define NS_LOG_WARN(msg)
Definition: log.h:246
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
void SetFrameNo(uint8_t frameNo)
void CycleStarted(void)
double ComputePiK(uint32_t a, uint32_t n, uint32_t k)
uint32_t m_rtsSize
virtual uint32_t GetSerializedSize(void) const
void SetType(uint8_t type)
void EndCycle(void)
NS_LOG_COMPONENT_DEFINE("UanMacRcGw")
UanAddress GetSrc(void) const
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range. Both limits are inclusive.
Definition: time.cc:404
std::map< UanAddress, AckData > m_ackData
UanAddress m_address
virtual bool Enqueue(Ptr< Packet > pkt, const Address &dest, uint16_t protocolNumber)
double ComputeAlpha(uint32_t totalFrames, uint32_t totalBytes, uint32_t n, uint32_t a, double deltaK)
void SetRetryRate(uint16_t rate)
Hold an floating point type.
Definition: double.h:41
virtual uint32_t GetSerializedSize(void) const
std::set< uint8_t > rxFrames
a unique identifier for an interface.
Definition: type-id.h:49
uint32_t m_ackSize
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)
void AddHeader(const Header &header)
Definition: packet.cc:253
Extra data header information.
Definition: uan-header-rc.h:41
uint16_t GetLength(void) const
virtual void SetForwardUpCb(Callback< void, Ptr< Packet >, const UanAddress & > cb)