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