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
174 UanMacRcGw::Enqueue (Ptr<Packet> packet, uint16_t protocolNumber, const Address &dest)
175 {
176  NS_UNUSED (dest);
177  NS_UNUSED (protocolNumber);
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
198 {
199  NS_UNUSED (sinr);
200 }
201 
202 void
204 {
205  NS_UNUSED (sinr);
206  UanHeaderCommon ch;
207  pkt->PeekHeader (ch);
208 
209  if (ch.GetDest () == m_address || ch.GetDest () == Mac8Address::GetBroadcast ())
210  {
211  m_rxLogger (pkt, mode);
212  }
213  else
214  {
215  return;
216  }
217 
218  pkt->RemoveHeader (ch);
219 
220  switch (ch.GetType ())
221  {
222  case UanMacRc::TYPE_DATA:
223  {
224  UanHeaderRcData dh;
225  pkt->RemoveHeader (dh);
226  m_propDelay[ch.GetSrc ()] = dh.GetPropDelay ();
227  if (m_ackData.find (ch.GetSrc ()) == m_ackData.end ())
228  {
229  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GATEWAY Received unexpected data packet");
230  }
231  else
232  {
233  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GW Received data packet from " << ch.GetSrc () << " length = " << pkt->GetSize ());
234  m_ackData[ch.GetSrc ()].rxFrames.insert (dh.GetFrameNo ());
235  }
236  m_forwardUpCb (pkt, ch.GetProtocolNumber (), ch.GetSrc ());
237  }
238  break;
240  case UanMacRc::TYPE_RTS:
241  if (m_state == CTSING)
242  {
243  return;
244  }
245 
246  {
247  UanHeaderRcRts rh;
248  pkt->RemoveHeader (rh);
249 
250  if (m_requests.find (ch.GetSrc ()) == m_requests.end ())
251  {
252  Request req;
253  req.numFrames = rh.GetNoFrames ();
254  req.rxTime = Simulator::Now ();
255  req.frameNo = rh.GetFrameNo ();
256  req.retryNo = rh.GetRetryNo ();
257  req.length = rh.GetLength ();
258  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GW storing reservation from " << ch.GetSrc () << " with length " << req.length);
259  m_requests.insert (std::make_pair (ch.GetSrc (), req));
260  std::map<Mac8Address, Time>::iterator it = m_propDelay.find (ch.GetSrc ());
261  if (it == m_propDelay.end ())
262  {
263  m_sortedRes.insert (std::make_pair (m_maxDelta, ch.GetSrc ()));
264  }
265  else
266  {
267  m_sortedRes.insert (std::make_pair ( (*it).second, ch.GetSrc ()));
268  }
269  }
270  }
271  if (m_state == IDLE)
272  {
273  StartCycle ();
274  }
275  break;
276  case UanMacRc::TYPE_CTS:
277  NS_FATAL_ERROR ("Received CTS at GW. Currently only support single GW network!");
278  break;
279  case UanMacRc::TYPE_ACK:
280  NS_FATAL_ERROR ("Received ACK at GW. Currently only support single GW network!");
281  break;
282  default:
283  NS_FATAL_ERROR ("Received unknown packet at GW!");
284  }
285 }
286 
287 void
289 {
290  uint32_t numRts = static_cast<uint32_t> (m_sortedRes.size ());
291 
292  if (numRts)
293  {
294  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Simulator starting non-empty cycle");
295  }
296  else
297  {
298  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Simulator starting EMPTY cycle");
299  }
300 
301  // Calculate dataRate
302  uint32_t totalBytes = 0;
303  uint32_t totalFrames = 0;
304  double pDelay = 0;
305  if (numRts > 0)
306  {
307  std::map<Mac8Address, Request>::iterator rit = m_requests.begin ();
308  for (; rit != m_requests.end (); rit++)
309  {
310  totalBytes += (*rit).second.length;
311  totalFrames += (*rit).second.numFrames;
312  }
313  pDelay = 2 * m_sortedRes.begin ()->first.GetSeconds ();
314  }
315 
316 
317  double minRate = m_phy->GetMode (m_numRates).GetDataRateBps ();
318 
319  uint32_t optA = m_maxRes;
320  if (m_maxRes == 0)
321  {
322  optA = FindOptA ();
323  }
324  double thAlpha = ComputeAlpha (totalFrames, totalBytes, m_numNodes, optA, pDelay / 2.0);
325 
326  double thCtlRate = m_totalRate * thAlpha;
327 
328  double temprate = (thCtlRate - minRate) / ((double) m_rateStep) + 0.5;
329  m_currentRateNum = (uint32_t) temprate;
331  {
333  }
334 
335  NS_LOG_DEBUG ("Found theoretical alpha: " << thAlpha << " Found associated rate = " << thCtlRate << " Giving rate number: " << temprate);
336  double thX = thAlpha * m_totalRate / (2.0 * m_numNodes * m_rtsSize * 8.0);
337 
338  double dataRate = m_phy->GetMode (m_currentRateNum).GetDataRateBps ();
339 
340 
341  if (thX < m_minRetryRate)
342  {
343  NS_LOG_WARN ("Gateway found optimum RTS retry rate is below minimum");
344  m_currentRetryRate = 0;
345  }
346  else
347  {
348  m_currentRetryRate = (uint16_t)((thX - m_minRetryRate) / m_retryStep + 0.5);
349  }
350 
351  double actualX = m_currentRetryRate * m_retryStep + m_minRetryRate;
352 
353  uint32_t ctlRate = m_phy->GetMode (m_currentRateNum + m_numRates).GetDataRateBps ();
354 
355 
356  double winSize = (double)(totalBytes) * 8.0 / dataRate + m_sifs.GetSeconds () * totalFrames + pDelay;
357  if (numRts == 0)
358  {
359  winSize = (optA * std::exp (1.0) + 0.5) * 2.0 * 8.0 * m_rtsSize / (thAlpha * m_totalRate) + 2 * m_maxDelta.GetSeconds ();
360  }
361  double effWinSize = winSize - m_rtsSize * 8 / ctlRate - 2 * m_maxDelta.GetSeconds ();
362 
363 
364  // Before fast CTS/ACK(below)
365  double cycleSeconds = winSize + (totalFrames + 1.0) * m_sifs.GetSeconds () + m_ctsSizeG * 8.0 / dataRate + (m_ctsSizeN + m_ackSize) * 8.0 * numRts / dataRate;
366 
367  Time ctsTxTimeG = Seconds (m_ctsSizeG * 8.0 / dataRate);
368  Time ctsTxTimeTotal = Seconds (m_ctsSizeN * 8.0 * numRts / dataRate) + ctsTxTimeG;
369  if (numRts == 0)
370  {
372  ctsg.SetWindowTime (Seconds (effWinSize));
373  ctsg.SetRateNum (static_cast<uint16_t> (m_currentRateNum));
375  ctsg.SetTxTimeStamp (Simulator::Now ());
376 
378  Ptr<Packet> p = Create<Packet> ();
379  p->AddHeader (ctsg);
380  p->AddHeader (ch);
382 
383 
384  Simulator::Schedule (Seconds (cycleSeconds), &UanMacRcGw::StartCycle, this);
385  m_state = INCYCLE;
386  m_cycleLogger (Simulator::Now (), Seconds (0), numRts, totalBytes, effWinSize, ctlRate, actualX);
387  return;
388  }
389 
390  Time nextEarliest = ctsTxTimeTotal + m_sifs;
391 
392  m_state = CTSING;
393  Simulator::Schedule (nextEarliest, &UanMacRcGw::CycleStarted, this);
394 
395  std::set<std::pair<Time, Mac8Address> >::iterator it = m_sortedRes.begin ();
396  Time minPdelay = (*it).first;
397  Ptr<Packet> cts = Create<Packet> ();
398 
399  for (; it != m_sortedRes.end (); it++)
400  {
401  Request req = m_requests[(*it).second];
402  Time pdelay = (*it).first;
403 
404  AckData newData;
405  newData.expFrames = req.numFrames;
406  newData.frameNo = req.frameNo;
407  Mac8Address dest = (*it).second;
408  m_ackData.insert (std::make_pair (dest, newData));
409 
410  Time earliestArr = ctsTxTimeTotal + pdelay + pdelay + m_sifs;
411  Time arrivalTime = std::max (earliestArr, nextEarliest);
412  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 ());
413  nextEarliest = arrivalTime + Seconds (req.length * 8.0 / dataRate) + Seconds (m_sifs.GetSeconds () * req.numFrames);
414 
415  UanHeaderRcCts ctsh;
416  ctsh.SetAddress (dest);
417  ctsh.SetRtsTimeStamp (req.rxTime);
418  ctsh.SetFrameNo (req.frameNo);
419  ctsh.SetRetryNo (req.retryNo);
420  ctsh.SetDelayToTx (arrivalTime);
421  cts->AddHeader (ctsh);
422 
423  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () <<
424  " GW Scheduling reception for " << (uint32_t) req.numFrames <<
425  " frames at " << (Simulator::Now () + arrivalTime).GetSeconds () << " (delaytiltx of " << arrivalTime.GetSeconds () << ") Total length is " << req.length << " with txtime " << req.length * 8 / dataRate << " seconds");
426  }
427 
429  ctsg.SetRateNum (static_cast<uint16_t> (m_currentRateNum));
430  ctsg.SetRetryRate (m_currentRetryRate);
431  ctsg.SetWindowTime (Seconds (effWinSize));
432  ctsg.SetTxTimeStamp (Simulator::Now ());
433  UanHeaderCommon ch;
435  ch.SetSrc (m_address);
437  cts->AddHeader (ctsg);
438  cts->AddHeader (ch);
440 
441  m_requests.clear ();
442  m_sortedRes.clear ();
443  Simulator::Schedule (nextEarliest, &UanMacRcGw::EndCycle, this);
444 
445 
446  m_cycleLogger (Simulator::Now (), minPdelay, numRts, totalBytes, cycleSeconds, ctlRate, actualX);
447 }
448 
449 void
451 {
452  m_state = INCYCLE;
453 }
454 void
456 {
457 
458  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GW Ending cycle");
459 
460  Time nextAck = Seconds (0);
461 
462  Time ackTime = Seconds (m_ackSize * 8.0 / m_phy->GetMode (m_currentRateNum).GetDataRateBps ());
463 
464  std::map<Mac8Address, AckData>::iterator it = m_ackData.begin ();
465  for (; it != m_ackData.end (); it++)
466  {
467  Mac8Address dest = (*it).first;
468  AckData &data = (*it).second;
469 
470  std::list<uint32_t> toNack;
471  for (uint8_t i = 0; i < data.expFrames; i++)
472  {
473  if (data.rxFrames.find (i) == data.rxFrames.end ())
474  {
475  toNack.push_back (i);
476  }
477  }
478  UanHeaderCommon ch;
479  ch.SetDest (dest);
480  ch.SetSrc (m_address);
482  UanHeaderRcAck ah;
483  ah.SetFrameNo (data.frameNo);
484  std::list<uint32_t>::iterator nit = toNack.begin ();
485  for (; nit != toNack.end (); nit++)
486  {
487  ah.AddNackedFrame (static_cast<uint8_t> (*nit));
488  }
489 
490  Ptr<Packet> ack = Create<Packet> ();
491  ack->AddHeader (ah);
492  ack->AddHeader (ch);
494  nextAck = nextAck + ackTime + m_sifs;
495  }
496  m_ackData.clear ();
498 
499 }
500 void
502 {
503  UanHeaderCommon ch;
504  pkt->PeekHeader (ch);
505  std::string type;
506  switch (ch.GetType ())
507  {
508  case UanMacRc::TYPE_DATA:
509  type = "DATA";
510  break;
511  case UanMacRc::TYPE_RTS:
512  type = "RTS";
513  break;
514  case UanMacRc::TYPE_CTS:
515  type = "CTS";
516  break;
517  case UanMacRc::TYPE_ACK:
518  type = "ACK";
519  break;
521  type = "GWPING";
522  break;
523  default:
524  type = "UNKNOWN";
525  break;
526  }
527  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GW sending " << type << " packet with size " << pkt->GetSize () << " to " << ch.GetDest () << " at rate " << rate);
528  m_phy->SendPacket (pkt, rate);
529 }
530 
531 
532 double
533 UanMacRcGw::ComputeAlpha (uint32_t totalFrames, uint32_t totalBytes, uint32_t n, uint32_t a, double deltaK)
534 {
535  NS_UNUSED (n);
536  double alpha;
537  double lrae = m_rtsSize * 8.0 * a * std::exp (1.0);
538  if (totalFrames == 0)
539  {
540 
541  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)) ) /
542  (2 * lrae + 8.0 * m_rtsSize - 8.0 * m_ctsSizeG);
543  }
544  else
545  {
546  double w = totalBytes * 8.0 + totalFrames*m_sifs.GetSeconds () * m_totalRate;
547  double v = m_rtsSize * 8.0 + 2 * lrae;
548  double u = (2 * m_maxDelta.GetSeconds () - 2 * deltaK) * m_totalRate;
549 
550  double gamma = (w - u + v) / (2 * (u - totalFrames * m_sifs.GetSeconds () * m_totalRate));
551 
552  alpha = -gamma + std::sqrt (gamma * gamma + v / (u - totalFrames * m_sifs.GetSeconds () * m_totalRate));
553 
554  if (alpha < 0 || alpha > 1)
555  {
556  alpha = -gamma - std::sqrt (gamma * gamma + v / (u - totalFrames * m_sifs.GetSeconds () * m_totalRate));
557  }
558  }
559  NS_ASSERT_MSG (alpha > 0 && alpha < 1, "Error computing alpha. Alpha out of valid range!");
560  return alpha;
561 }
562 
563 std::vector<double>
565 {
566  uint32_t n = m_numNodes;
567  std::vector<double> pds;
568  std::map<Mac8Address, Time>::iterator pdit = m_propDelay.begin ();
569 
570  for (; pdit != m_propDelay.end (); pdit++)
571  {
572  pds.push_back (pdit->second.GetSeconds ());
573  }
574  while (pds.size () < m_numNodes)
575  {
576  pds.push_back (m_maxDelta.GetSeconds ());
577  }
578 
579  std::sort (pds.begin (), pds.end ());
580  // Find expected min. prop. delay for k nodes
581  std::vector<double> exppdk;
582  exppdk.push_back (m_maxDelta.GetSeconds ());
583  for (uint32_t k = 1; k <= n; k++)
584  {
585  uint32_t ind = CompExpMinIndex (n,k) - 1;
586  exppdk.push_back (pds[ind]);
587  }
588  return exppdk;
589 }
590 
591 double
592 UanMacRcGw::ComputeExpS (uint32_t a, uint32_t ld, std::vector<double> exppdk)
593 {
594  UanHeaderCommon ch;
595  uint32_t lh = ch.GetSerializedSize ();
596 
597  uint32_t n = m_numNodes;
598  double expk = n * (1 - std::exp (-((double) a) / (double) n));
599  NS_LOG_DEBUG ("expk = " << expk);
600 
601  // Compute expected data per cycle
602  double expdata = 8 * ld * expk;
603 
604  // Compute expected time per cycle
605  double alpha0 = ComputeAlpha (0,0,n,a,exppdk[0]);
606  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);
607  double exptime = ComputePiK (a,n,0) * c0;
608  double expp = 0;
609  for (uint32_t i = 1; i <= n; i++)
610  {
611  expp += ComputePiK (a,n,i) * exppdk[i - 1];
612  }
613 
614  exptime += ComputeExpBOverA (n,a,ld + lh,exppdk) + expk * 2 * m_sifs.GetSeconds () + m_sifs.GetSeconds () + 2 * expp;
615  double s = (1.0 / m_totalRate) * expdata / exptime;
616 
617  return s;
618 }
619 
620 double
621 UanMacRcGw::ComputeExpS (uint32_t a, uint32_t ld)
622 {
623  return ComputeExpS (a, ld, GetExpPdk ());
624 }
625 
626 uint32_t
627 UanMacRcGw::CompExpMinIndex (uint32_t n, uint32_t k)
628 {
629  double sum = 0;
630  for (uint32_t i = 1; i <= n - k + 1; i++)
631  {
632  double nChK = static_cast<double> (NchooseK (n, k));
633  double p = (nChK > 0) ? (static_cast<double> (NchooseK (n - i, k - 1)) / nChK) : DBL_MAX;
634  sum += p * i;
635  }
636  return (uint32_t)(sum + 0.5);
637 }
638 
639 double
640 UanMacRcGw::ComputePiK (uint32_t a, uint32_t n, uint32_t k)
641 {
642  double nck = (double) NchooseK (n, k);
643  return nck * std::pow ( (std::exp ( (double) a / (double) n) - 1.0), (double) k) * std::exp (-( (double) a));
644 }
645 
646 double
647 UanMacRcGw::ComputeExpBOverA (uint32_t n, uint32_t a, uint32_t ldlh, std::vector<double> deltaK)
648 {
649 
650  double sum = 0;
651  uint32_t lt = 8 * (m_ctsSizeN + ldlh + m_ackSize);
652  for (uint32_t k = 1; k <= n; k++)
653  {
654  double num = 8.0 * m_ctsSizeG + k * lt;
655  double denom = (1.0 - ComputeAlpha (k, k * ldlh, n, a, deltaK[k])) * m_totalRate;
656  double pik = ComputePiK (a, n, k);
657  double term = pik * num / denom;
658 
659  sum += term;
660  }
661 
662  return sum;
663 }
664 
665 uint64_t
666 UanMacRcGw::NchooseK (uint32_t n, uint32_t k)
667 {
668  if (k > n)
669  {
670  return 0;
671  }
672 
673  if (k > n / 2)
674  {
675  k = n - k;
676  }
677 
678  double accum = 1;
679  for (uint32_t i = 1; i <= k; i++)
680  {
681  accum = accum * (n - k + i) / i;
682  }
683 
684  return (uint64_t)(accum + 0.5);
685 
686 }
687 
688 uint32_t
690 {
691  double tput = 0;
692  uint32_t a = 1;
693  while (1)
694  {
695 
696  double newtput = ComputeExpS (a, m_frameSize);
697  if (newtput < tput)
698  {
699  a--;
700  break;
701  }
702  else
703  {
704  tput = newtput;
705  a++;
706  }
707  }
708  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GW: Found optimum a = " << a);
709  return a;
710 }
711 
712 int64_t
714 {
715  NS_LOG_FUNCTION (this << stream);
716  return 0;
717 }
718 
719 } // namespace ns3
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
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:102
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.
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&#39;th expected delay among n nodes.
virtual uint32_t GetSerializedSize(void) const
Callback template class.
Definition: callback.h:1176
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 an Object subclass with the TypeId system.
Definition: object-base.h:45
void SetSrc(Mac8Address src)
Set the source address.
uint32_t m_ctsSizeG
Size of UanHeaderCommon and UanHeaderRcCtsGlobal.
Header used for ACK packets by protocol UanMacRc.
bool m_cleared
Flag when we&#39;ve been cleared.
std::map< Mac8Address, Request > m_requests
Request for each node.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
std::set< std::pair< Time, Mac8Address > > m_sortedRes
Queued request times.
Gateway side of RC-MAC.
Definition: uan-mac-rc-gw.h:57
uint32_t m_numRates
Number of rates per Phy layer.
std::map< Mac8Address, Time > m_propDelay
Propagation delay to each node.
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:75
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:831
#define NS_UNUSED(x)
Mark a local variable as unused.
Definition: unused.h:36
uint16_t m_currentRetryRate
Retry rate number for current cycle.
static Mac8Address GetBroadcast(void)
Get the broadcast address (255).
Definition: mac8-address.cc:87
Mac8Address GetSrc(void) const
Get the source address.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
double m_minRetryRate
Smallest allowed RTS retry rate.
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
virtual void Clear(void)
Clears all pointer references.
State m_state
Gateway processing state.
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).
virtual ~UanMacRcGw()
Dummy destructor, see DoDispose.
uint8_t GetFrameNo(void) const
Get the frame number.
a polymophic address class
Definition: address.h:90
uint8_t numFrames
Number of frames.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
phy
Definition: third.py:86
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:446
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
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:355
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.
std::map< Mac8Address, AckData > m_ackData
AckData for each node.
void SendPacket(Ptr< Packet > pkt, uint32_t rate)
Send packet on PHY.
NS_ASSERT_MSG(false,"Ipv4AddressGenerator::MaskToIndex(): Impossible")
Virtual base class for all UAN MAC protocols.
Definition: uan-mac.h:49
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1381
#define max(a, b)
Definition: 80211b.c:43
uint64_t NchooseK(uint32_t n, uint32_t k)
Binomial coefficient.
virtual bool Enqueue(Ptr< Packet > pkt, uint16_t protocolNumber, const Address &dest)
Enqueue packet to be transmitted.
AttributeValue implementation for Time.
Definition: nstime.h:1069
virtual uint32_t GetSerializedSize(void) const
Hold an unsigned integer type.
Definition: uinteger.h:44
uint8_t data[writeSize]
void SetAddress(Mac8Address addr)
Set the destination address, for scheduling info.
uint32_t m_numNodes
Number of non-gateway nodes in this gateway&#39;s neighborhood.
Abstraction of packet modulation information.
Definition: uan-tx-mode.h:41
void ReceivePacket(Ptr< Packet > pkt, double sinr, UanTxMode mode)
PHY receive ok callback.
A class used for addressing MAC8 MAC&#39;s.
Definition: mac8-address.h:42
uint8_t frameNo
Current frame number.
virtual void DoDispose()
Destructor implementation.
uint32_t m_rateStep
Increments available for rate assignment in bps.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
uint16_t length
Request header length.
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 AddNackedFrame(uint8_t frame)
NACK a frame.
uint8_t GetRetryNo(void) const
Get the retry number of this RTS packet.
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:290
uint32_t m_ctsSizeN
Size of UanHeaderRcCts.
static TypeId GetTypeId(void)
Register this type.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Common packet header fields.
Reservation request.
Cycling through nodes.
Definition: uan-mac-rc-gw.h:97
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:1070
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:249
void SetTxTimeStamp(Time timeStamp)
Set the CTS timestamp.
uint8_t frameNo
Frame number being ACK&#39;ed.
uint8_t GetNoFrames(void) const
Get the number of data frames in the reservation.
Ptr< UanPhy > m_phy
PHY layer attached to this MAC.
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
uint32_t m_frameSize
Size of data frames in bytes.
uint16_t GetProtocolNumber(void) const
Get the packet type value.
uint32_t m_totalRate
Total available channel rate in bps (for a single channel, without splitting reservation channel)...
Callback< void, Ptr< Packet >, uint16_t, const Mac8Address & > m_forwardUpCb
Forwarding up callback.
void StartCycle(void)
Cycle through pending requests.
Mac8Address m_address
The MAC address.
UanMacRcGw()
Constructor.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:262
uint32_t m_maxRes
Maximum number of reservations to accept per cycle.
void SetDest(Mac8Address dest)
Set the destination address.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:270
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1007
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.
Mac8Address GetDest(void) const
Get the destination address.
uint8_t retryNo
Retry number.
Initial idle state.
Definition: uan-mac-rc-gw.h:96
virtual void SetForwardUpCb(Callback< void, Ptr< Packet >, uint16_t, const Mac8Address & > cb)
Set the callback to forward packets up to higher layers.
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.
This class can be used to hold variables of floating point type such as &#39;double&#39; or &#39;float&#39;...
Definition: double.h:41
virtual uint32_t GetSerializedSize(void) const
std::set< uint8_t > rxFrames
Received frames.
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
Packet ACK data.
a unique identifier for an interface.
Definition: type-id.h:58
uint32_t m_ackSize
Size of UanHeaderCommon and UanHeaderRcAck.
virtual uint32_t GetSerializedSize(void) const
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:915
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:256
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.