A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
bs-net-device.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007,2008,2009 INRIA, UDcast
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  * Authors: Jahanzeb Farooq <jahanzeb.farooq@sophia.inria.fr>
19  * Mohamed Amine Ismail <amine.ismail@sophia.inria.fr>
20  * <amine.ismail@UDcast.com>
21  */
22 
23 #include <cmath>
24 
25 #include "ns3/simulator.h"
26 #include "ns3/drop-tail-queue.h"
27 #include "ns3/node.h"
28 #include "bs-uplink-scheduler.h"
29 #include "bs-net-device.h"
30 #include "wimax-phy.h"
31 #include "ns3/packet-burst.h"
32 #include "ss-record.h"
33 #include "bs-scheduler.h"
34 #include "wimax-mac-queue.h"
35 #include "burst-profile-manager.h"
36 #include "ss-manager.h"
37 #include "ns3/trace-source-accessor.h"
38 #include "ns3/pointer.h"
39 #include "ns3/enum.h"
40 #include "ns3/uinteger.h"
41 #include "service-flow.h"
42 #include "service-flow-manager.h"
43 #include "connection-manager.h"
44 #include "bs-link-manager.h"
45 #include "bandwidth-manager.h"
46 #include "ns3/ipv4-address.h"
47 #include "ns3/llc-snap-header.h"
48 
49 NS_LOG_COMPONENT_DEFINE ("BaseStationNetDevice");
50 
51 namespace ns3 {
52 
53 NS_OBJECT_ENSURE_REGISTERED (BaseStationNetDevice);
54 
55 TypeId BaseStationNetDevice::GetTypeId (void)
56 {
57  static TypeId tid = TypeId ("ns3::BaseStationNetDevice")
58 
59  .SetParent<WimaxNetDevice> ()
60 
61  .AddConstructor<BaseStationNetDevice> ()
62 
63  .AddAttribute ("BSScheduler",
64  "Downlink Scheduler for BS",
65  PointerValue (),
66  MakePointerAccessor (&BaseStationNetDevice::m_scheduler),
67  MakePointerChecker<BSScheduler> ())
68 
69  .AddAttribute ("InitialRangInterval",
70  "Time between Initial Ranging regions assigned by the BS. Maximum is 2s",
71  TimeValue (Seconds (0.05)),
74  MakeTimeChecker ())
75 
76  .AddAttribute ("DcdInterval",
77  "Time between transmission of DCD messages. Maximum value is 10s.",
78  TimeValue (Seconds (3)),
80  MakeTimeChecker ())
81 
82  .AddAttribute ("UcdInterval",
83  "Time between transmission of UCD messages. Maximum value is 10s.",
84  TimeValue (Seconds (3)),
86  MakeTimeChecker ())
87 
88  .AddAttribute ("IntervalT8",
89  "Wait for DSA/DSC Acknowledge timeout. Maximum 300ms.",
90  TimeValue (Seconds (0.05)),
92  MakeTimeChecker ())
93 
94  .AddAttribute ("RangReqOppSize",
95  "The ranging opportunity size in symbols",
96  UintegerValue (8),
97  MakeUintegerAccessor (&BaseStationNetDevice::GetRangReqOppSize,
99  MakeUintegerChecker<uint8_t> (1, 256))
100 
101  .AddAttribute ("BwReqOppSize",
102  "The bandwidth request opportunity size in symbols",
103  UintegerValue (2),
105  MakeUintegerChecker<uint8_t> (1, 256))
106 
107  .AddAttribute ("MaxRangCorrectionRetries",
108  "Number of retries on contention Ranging Requests",
109  UintegerValue (16),
112  MakeUintegerChecker<uint8_t> (1, 16))
113 
114  .AddAttribute ("SSManager",
115  "The ss manager attached to this device.",
116  PointerValue (),
118  MakePointerChecker<SSManager> ())
119 
120  .AddAttribute ("Scheduler",
121  "The BS scheduler attached to this device.",
122  PointerValue (),
124  MakePointerChecker<BSScheduler> ())
125 
126  .AddAttribute ("LinkManager",
127  "The link manager attached to this device.",
128  PointerValue (),
130  MakePointerChecker<BSLinkManager> ())
131 
132  .AddAttribute ("UplinkScheduler",
133  "The uplink scheduler attached to this device.",
134  PointerValue (),
135  MakePointerAccessor (&BaseStationNetDevice::GetUplinkScheduler,
137  MakePointerChecker<UplinkScheduler> ())
138 
139  .AddAttribute ("BsIpcsPacketClassifier",
140  "The uplink IP packet classifier attached to this device.",
141  PointerValue (),
143  MakePointerChecker<IpcsClassifier> ())
144 
145  .AddAttribute ("ServiceFlowManager",
146  "The service flow manager attached to this device.",
147  PointerValue (),
148  MakePointerAccessor (&BaseStationNetDevice::GetServiceFlowManager,
149  &BaseStationNetDevice::SetServiceFlowManager),
150  MakePointerChecker<ServiceFlowManager> ())
151 
152  .AddTraceSource ("BSTx", "A packet has been received from higher layers and is being processed in preparation for "
153  "queueing for transmission.", MakeTraceSourceAccessor (&BaseStationNetDevice::m_bsTxTrace))
154 
155  .AddTraceSource ("BSTxDrop",
156  "A packet has been dropped in the MAC layer before being queued for transmission.",
158 
159  .AddTraceSource ("BSPromiscRx",
160  "A packet has been received by this device, has been passed up from the physical layer "
161  "and is being forwarded up the local protocol stack. This is a promiscuous trace,",
163 
164  .AddTraceSource ("BSRx",
165  "A packet has been received by this device, has been passed up from the physical layer "
166  "and is being forwarded up the local protocol stack. This is a non-promiscuous trace,",
168 
169  .AddTraceSource ("BSRxDrop",
170  "A packet has been dropped in the MAC layer after it has been passed up from the physical "
171  "layer.",
173  return tid;
174 }
175 
176 BaseStationNetDevice::BaseStationNetDevice (void)
177 {
179 }
180 
181 void
183 {
184 
185  m_initialRangInterval = Seconds (0.05); // maximum is 2
186  m_dcdInterval = Seconds (3); // maximum is 10
187  m_ucdInterval = Seconds (3); // maximum is 10
188  m_intervalT8 = MilliSeconds (50); // maximum is 300 milliseconds
189  m_maxRangCorrectionRetries = 16;
190  m_maxInvitedRangRetries = 16;
191  m_rangReqOppSize = 8; // 8 symbols = 2 (preamble) + 2 (RNG-REQ) + 4 (round-trip propagation time)
192  m_bwReqOppSize = 2; // 2 symbols = 1 (preamble) + 1 (bandwidth request header)
193  m_nrDlSymbols = 0;
194  m_nrUlSymbols = 0;
195  m_nrDlMapSent = 0;
196  m_nrUlMapSent = 0;
197  m_nrDcdSent = 0;
198  m_nrUcdSent = 0;
199  m_dcdConfigChangeCount = 0;
200  m_ucdConfigChangeCount = 0;
201  m_framesSinceLastDcd = 0;
202  m_framesSinceLastUcd = 0;
203  m_nrDlFrames = 0;
204  m_nrUlFrames = 0;
205  m_nrSsRegistered = 0;
206  m_nrDlAllocations = 0;
207  m_nrUlAllocations = 0;
208  m_dlSubframeStartTime = Seconds (0);
209  m_ulSubframeStartTime = Seconds (0);
210  m_ulAllocationNumber = 0;
211  m_rangingOppNumber = 0;
212  m_allocationStartTime = 0;
213  m_psDuration = Seconds (0);
214  m_symbolDuration = Seconds (0);
215  m_linkManager = CreateObject<BSLinkManager> (this);
216  m_cidFactory = new CidFactory ();
217  m_ssManager = CreateObject<SSManager> ();
218  m_bsClassifier = CreateObject<IpcsClassifier> ();
219  m_serviceFlowManager = CreateObject<BsServiceFlowManager> (this);
220 
221 }
222 
223 BaseStationNetDevice::BaseStationNetDevice (Ptr<Node> node, Ptr<WimaxPhy> phy)
224 {
226  this->SetNode (node);
227  this->SetPhy (phy);
228 }
229 
230 BaseStationNetDevice::BaseStationNetDevice (Ptr<Node> node,
231  Ptr<WimaxPhy> phy,
232  Ptr<UplinkScheduler> uplinkScheduler,
233  Ptr<BSScheduler> bsScheduler)
234 {
236  this->SetNode (node);
237  this->SetPhy (phy);
238  m_uplinkScheduler = uplinkScheduler;
239  m_scheduler = bsScheduler;
240 }
241 
242 BaseStationNetDevice::~BaseStationNetDevice (void)
243 {
244 }
245 
246 void
248 {
249  delete m_cidFactory;
250 
251  m_linkManager = 0;
252  m_ssManager = 0;
253  m_bsClassifier = 0;
254  m_serviceFlowManager = 0;
255  m_uplinkScheduler = 0;
256  m_cidFactory = 0;
257  m_ssManager = 0;
258  m_uplinkScheduler = 0;
259  m_scheduler = 0;
260 
262 }
263 
264 void
266 {
267  m_bsClassifier = bsc;
268 }
269 
272 {
273  return m_bsClassifier;
274 }
275 
276 void
278 {
279  m_initialRangInterval = initialRangInterval;
280 }
281 
282 Time
284 {
285  return m_initialRangInterval;
286 }
287 
288 void
290 {
291  m_dcdInterval = dcdInterval;
292 }
293 
294 Time
296 {
297  return m_dcdInterval;
298 }
299 
300 void
302 {
303  m_ucdInterval = ucdInterval;
304 }
305 
306 Time
308 {
309  return m_ucdInterval;
310 }
311 
312 void
314 {
315  m_intervalT8 = interval;
316 }
317 
318 Time
320 {
321  return m_intervalT8;
322 }
323 
324 void
326 {
327  m_maxRangCorrectionRetries = maxRangCorrectionRetries;
328 }
329 
330 uint8_t
332 {
333  return m_maxRangCorrectionRetries;
334 }
335 
336 void
337 BaseStationNetDevice::SetMaxInvitedRangRetries (uint8_t maxInvitedRangRetries)
338 {
339  m_maxInvitedRangRetries = maxInvitedRangRetries;
340 }
341 
342 uint8_t
344 {
345  return m_maxInvitedRangRetries;
346 }
347 
348 void
350 {
351  m_rangReqOppSize = rangReqOppSize;
352 }
353 
354 uint8_t
356 {
357  return m_rangReqOppSize;
358 }
359 
360 void
362 {
363  m_bwReqOppSize = bwReqOppSize;
364 }
365 
366 uint8_t
368 {
369  return m_bwReqOppSize;
370 }
371 
372 void
374 {
375  m_nrDlSymbols = nrDlSymbols;
376 }
377 
378 uint32_t
380 {
381  return m_nrDlSymbols;
382 }
383 
384 void
386 {
387  m_nrUlSymbols = nrUlSymbols;
388 }
389 
390 uint32_t
392 {
393  return m_nrUlSymbols;
394 }
395 
396 uint32_t
398 {
399  return m_nrDcdSent;
400 }
401 
402 uint32_t
404 {
405  return m_nrUcdSent;
406 }
407 
408 Time
409 BaseStationNetDevice::GetDlSubframeStartTime (void) const
410 {
411  return m_dlSubframeStartTime;
412 }
413 
414 Time
415 BaseStationNetDevice::GetUlSubframeStartTime (void) const
416 {
417  return m_ulSubframeStartTime;
418 }
419 
420 uint8_t
421 BaseStationNetDevice::GetRangingOppNumber (void) const
422 {
423  return m_rangingOppNumber;
424 }
425 
426 Ptr<SSManager>
428 {
429  return m_ssManager;
430 }
431 
432 void
434 {
435  m_ssManager = ssm;
436 }
437 
439 BaseStationNetDevice::GetServiceFlowManager (void) const
440 {
441  return m_serviceFlowManager;
442 }
443 
444 void
445 BaseStationNetDevice::SetServiceFlowManager (Ptr<BsServiceFlowManager> sfm)
446 {
447  m_serviceFlowManager = sfm;
448 }
449 
450 Ptr<UplinkScheduler>
452 {
453  return m_uplinkScheduler;
454 }
455 
456 void
458 {
459  m_uplinkScheduler = uls;
460 }
461 
464 {
465  return m_linkManager;
466 }
467 
468 void
470 {
471  m_linkManager = lm;
472 }
473 
474 void
476 {
477  m_scheduler = bss;
478 }
481 {
482  return m_scheduler;
483 }
484 
485 Time
486 BaseStationNetDevice::GetPsDuration (void) const
487 {
488  return m_psDuration;
489 }
490 
491 Time
492 BaseStationNetDevice::GetSymbolDuration (void) const
493 {
494  return m_symbolDuration;
495 }
496 
497 void
498 BaseStationNetDevice::Start (void)
499 {
500  SetReceiveCallback ();
501  GetConnectionManager ()->SetCidFactory (m_cidFactory);
502  GetPhy ()->SetPhyParameters ();
503  GetPhy ()->SetDataRates ();
504  SetTtg (GetPhy ()->GetTtg ());
505  SetRtg (GetPhy ()->GetRtg ());
506  m_psDuration = GetPhy ()->GetPsDuration ();
507  m_symbolDuration = GetPhy ()->GetSymbolDuration ();
508  GetBandwidthManager ()->SetSubframeRatio ();
509 
510  CreateDefaultConnections ();
511  GetPhy ()->SetSimplex (m_linkManager->SelectDlChannel ());
512  Simulator::ScheduleNow (&BaseStationNetDevice::StartFrame, this);
513 
514  /* shall actually be 2 symbols = 1 (preamble) + 1 (bandwidth request header)*/
515  m_bwReqOppSize = 6;
516  m_uplinkScheduler->InitOnce ();
517 }
518 
519 void
520 BaseStationNetDevice::Stop (void)
521 {
522 }
523 
524 void
525 BaseStationNetDevice::StartFrame (void)
526 {
527  //setting DL/UL subframe allocation for this frame
528  uint32_t symbolsPerFrame = GetPhy ()->GetSymbolsPerFrame ();
529  SetNrDlSymbols ((symbolsPerFrame / 2) - static_cast<uint32_t> (std::ceil (GetTtg ()*m_psDuration.GetSeconds ()/m_symbolDuration.GetSeconds ())));
530  SetNrUlSymbols ((symbolsPerFrame / 2) - static_cast<uint32_t> (std::ceil (GetRtg ()*m_psDuration.GetSeconds ()/m_symbolDuration.GetSeconds ())));
531 
532  m_frameStartTime = Simulator::Now ();
533 
534  NS_LOG_INFO ("----------------------frame" << GetNrFrames () + 1 << "----------------------");
535 
536  StartDlSubFrame ();
537 }
538 
539 void
540 BaseStationNetDevice::StartDlSubFrame (void)
541 {
542  m_dlSubframeStartTime = Simulator::Now (); // same as m_frameStartTime
543 
544  NS_LOG_DEBUG ("DL frame started : " << m_frameStartTime.GetSeconds ());
545 
546  SetNrFrames (GetNrFrames () + 1);
547  SetState (BS_STATE_DL_SUB_FRAME);
548  m_direction = DIRECTION_DOWNLINK;
549  m_uplinkScheduler->Schedule ();
551  m_scheduler->Schedule ();
552  SendBursts ();
553  Simulator::Schedule (Seconds (m_nrDlSymbols * m_symbolDuration.GetSeconds ()),
554  &BaseStationNetDevice::EndDlSubFrame,
555  this);
556 }
557 
558 void
559 BaseStationNetDevice::EndDlSubFrame (void)
560 {
561  m_nrDlFrames++;
562  SetState (BS_STATE_TTG);
563  Simulator::Schedule (Seconds (GetTtg () * m_psDuration.GetSeconds ()), &BaseStationNetDevice::StartUlSubFrame, this);
564 }
565 
566 void
567 BaseStationNetDevice::StartUlSubFrame (void)
568 {
569  m_ulSubframeStartTime = Simulator::Now ();
570 
571  NS_LOG_INFO ("UL frame started : " << m_ulSubframeStartTime.GetSeconds ());
572 
573  SetState (BS_STATE_UL_SUB_FRAME);
574  m_direction = DIRECTION_UPLINK;
575  MarkUplinkAllocations ();
576  Simulator::Schedule (Seconds (m_nrUlSymbols * m_symbolDuration.GetSeconds ()),
577  &BaseStationNetDevice::EndUlSubFrame,
578  this);
579 }
580 
581 void
582 BaseStationNetDevice::EndUlSubFrame (void)
583 {
584  m_nrUlFrames++;
585  SetState (BS_STATE_RTG);
586  Simulator::Schedule (Seconds (GetRtg () * m_psDuration.GetSeconds ()), &BaseStationNetDevice::EndFrame, this);
587 }
588 
589 void
590 BaseStationNetDevice::EndFrame (void)
591 {
592  StartFrame ();
593 }
594 
595 bool
596 BaseStationNetDevice::DoSend (Ptr<Packet> packet,
597  const Mac48Address &source,
598  const Mac48Address &dest,
599  uint16_t protocolNumber)
600 {
601  Ptr<PacketBurst> burst = Create<PacketBurst> ();
602  ServiceFlow *serviceFlow = 0;
603 
604  NS_LOG_INFO ("BS (" << source << "):");
605  NS_LOG_INFO ("\tSending packet...");
606  NS_LOG_INFO ("\t\tDestination: " << dest);
607  NS_LOG_INFO ("\t\tPaket Size: " << packet->GetSize ());
608  NS_LOG_INFO ("\t\tProtocol: " << protocolNumber);
609 
610 
611  if (protocolNumber == 2048)
612  {
613  serviceFlow = m_bsClassifier->Classify (packet, GetServiceFlowManager (), ServiceFlow::SF_DIRECTION_DOWN);
614  }
615 
616  if (protocolNumber != 2048 || serviceFlow == 0)
617  {
618  serviceFlow = *GetServiceFlowManager ()->GetServiceFlows (ServiceFlow::SF_TYPE_ALL).begin ();
619  }
620 
621  if (serviceFlow == 0)
622  {
623  NS_LOG_INFO ("No Service Flow!!");
624  m_bsTxDropTrace (packet);
625  return false;
626  }
627  if (serviceFlow->GetIsEnabled ())
628  {
629  if (!Enqueue (packet, MacHeaderType (), serviceFlow->GetConnection ()))
630  {
631  NS_LOG_INFO ("Enqueue Error!!");
632  m_bsTxDropTrace (packet);
633  return false;
634  }
635  }
636  else
637  {
638  m_bsTxDropTrace (packet);
639  NS_LOG_INFO ("Service Flow is not enabled");
640  return false;
641  }
642  m_bsTxTrace (packet);
643 
644  return true;
645 }
646 
647 bool
649 {
650  NS_ASSERT_MSG (connection != 0,
651  "BS: Can not enqueue packet on the selected connection: the connection is not initialized");
652 
653  GenericMacHeader hdr;
654  hdr.SetLen (packet->GetSize () + hdr.GetSerializedSize ());
655 
656  hdr.SetCid (connection->GetCid ());
657 
658  return connection->Enqueue (packet, hdrType, hdr);
659 }
660 
661 void
662 BaseStationNetDevice::DoReceive (Ptr<Packet> packet)
663 {
664  GenericMacHeader gnrcMacHdr;
665  BandwidthRequestHeader bwRequestHdr;
666  ManagementMessageType msgType;
667  RngReq rngReq;
668  Cid cid;
669  uint8_t type = 0;
670  GrantManagementSubheader grantMgmntSubhdr;
671  Mac48Address source;
672  LlcSnapHeader llc;
673  Ptr<WimaxConnection> connection = 0;
674  FragmentationSubheader fragSubhdr;
675  bool fragmentation = false; // it becames true when there is a fragmentation subheader
676 
677  packet->RemoveHeader (gnrcMacHdr);
678  if (gnrcMacHdr.GetHt () == MacHeaderType::HEADER_TYPE_GENERIC)
679  {
680  if (gnrcMacHdr.check_hcs () == false)
681  {
682  // The header is noisy
683  m_bsRxDropTrace (packet);
684  NS_LOG_INFO ("Header HCS ERROR");
685  return;
686  }
687 
688  cid = gnrcMacHdr.GetCid ();
689 
690  // checking for subheaders (only grant management subheader is implemented)
691  type = gnrcMacHdr.GetType ();
692  if (type)
693  {
694  // checking 1st bit, see Table 6
695  if (type & 1)
696  {
697  packet->RemoveHeader (grantMgmntSubhdr);
698  }
699  // Check if there is a fragmentation Subheader
700  uint8_t tmpType = type;
701  if (((tmpType >> 2) & 1) == 1)
702  {
703  // a TRANSPORT packet with fragmentation subheader has been received!
704  NS_LOG_INFO ("FRAG_DEBUG: DoReceive -> the packet is a fragment" << std::endl);
705  fragmentation = true;
706  }
707  }
708 
709  if (cid.IsInitialRanging ()) // initial ranging connection
710  {
711  packet->RemoveHeader (msgType);
712  switch (msgType.GetType ())
713  {
714  case ManagementMessageType::MESSAGE_TYPE_RNG_REQ:
715  {
716  packet->RemoveHeader (rngReq);
717  m_linkManager->ProcessRangingRequest (cid, rngReq);
718  break;
719  }
720  case ManagementMessageType::MESSAGE_TYPE_RNG_RSP:
721  // from other base station, ignore
722  break;
723  default:
724  NS_FATAL_ERROR ("Invalid message type");
725  }
726  }
727  else if (m_cidFactory->IsBasic (cid)) // basic management connection
728  {
729  source = m_ssManager->GetMacAddress (cid);
730  m_traceBSRx (packet, source, cid);
731  packet->RemoveHeader (msgType);
732  switch (msgType.GetType ())
733  {
734  case ManagementMessageType::MESSAGE_TYPE_RNG_REQ:
735  {
736  packet->RemoveHeader (rngReq);
737  m_linkManager->ProcessRangingRequest (cid, rngReq);
738  break;
739  }
740  case ManagementMessageType::MESSAGE_TYPE_RNG_RSP:
741  // from other base station, ignore
742  break;
743  default:
744  NS_FATAL_ERROR ("Invalid message type");
745  }
746  }
747  else if (m_cidFactory->IsPrimary (cid)) // primary management connection
748  {
749  source = m_ssManager->GetMacAddress (cid);
750  m_traceBSRx (packet, source, cid);
751  packet->RemoveHeader (msgType);
752  switch (msgType.GetType ())
753  {
754  case ManagementMessageType::MESSAGE_TYPE_REG_REQ:
755  // not yet implemented
756  break;
757  case ManagementMessageType::MESSAGE_TYPE_REG_RSP:
758  // from other base station, ignore
759  break;
760  case ManagementMessageType::MESSAGE_TYPE_DSA_REQ:
761  {
762  DsaReq dsaReq;
763  packet->RemoveHeader (dsaReq);
764  GetServiceFlowManager ()->AllocateServiceFlows (dsaReq, cid);
765  break;
766  }
767  case ManagementMessageType::MESSAGE_TYPE_DSA_RSP:
768 
769  /*from other base station, as DSA initiated
770  from BS is not supported, ignore*/
771  break;
772  case ManagementMessageType::MESSAGE_TYPE_DSA_ACK:
773  {
774  Simulator::Cancel (GetServiceFlowManager ()->GetDsaAckTimeoutEvent ());
775  DsaAck dsaAck;
776  packet->RemoveHeader (dsaAck);
777  GetServiceFlowManager ()->ProcessDsaAck (dsaAck, cid);
778  break;
779  }
780  default:
781  NS_FATAL_ERROR ("Invalid message type");
782  }
783  }
784  else if (cid.IsBroadcast ()) // broadcast connection
785  {
786  // from other base station, ignore
787  // or perhaps data packet (using other protocol) for BS, handle later
788  return;
789  }
790  else // transport connection
791  {
792  // If fragmentation is true, the packet is a fragment.
793  Ptr<Packet> C_Packet = packet->Copy ();
794  if (!fragmentation)
795  {
796  C_Packet->RemoveHeader (llc);
797  source = m_ssManager->GetMacAddress (cid);
798  m_bsRxTrace (packet);
799  ForwardUp (packet->Copy (), source, Mac48Address ("ff:ff:ff:ff:ff:ff"));
800  }
801  else
802  {
803  NS_LOG_INFO ( "FRAG_DEBUG: BS DoReceive, the Packet is a fragment" << std::endl);
804  packet->RemoveHeader (fragSubhdr);
805  uint32_t fc = fragSubhdr.GetFc ();
806  NS_LOG_INFO ("\t fragment size = " << packet->GetSize () << std::endl);
807  if (fc == 2)
808  {
809  // This is the latest fragment.
810  // Take the fragment queue, defragment a packet and send it to the upper layer
811  NS_LOG_INFO ("\t Received the latest fragment" << std::endl);
812  GetConnectionManager ()->GetConnection (cid)
813  ->FragmentEnqueue (packet);
814  WimaxConnection::FragmentsQueue fragmentsQueue = GetConnectionManager ()->
815  GetConnection (cid)->GetFragmentsQueue ();
816  Ptr<Packet> fullPacket = Create<Packet> ();
817 
818  // DEFRAGMENTATION
819  NS_LOG_INFO ("\t BS PACKET DEFRAGMENTATION" << std::endl);
820  for (std::list<Ptr<const Packet> >::const_iterator iter = fragmentsQueue.begin ();
821  iter != fragmentsQueue.end (); ++iter)
822  {
823  // Create the whole Packet
824  fullPacket->AddAtEnd (*iter);
825  }
826  GetConnectionManager ()->GetConnection (cid)
827  ->ClearFragmentsQueue ();
828 
829  NS_LOG_INFO ("\t fullPacket size = " << fullPacket->GetSize () << std::endl);
830  source = m_ssManager->GetMacAddress (cid);
831  m_bsRxTrace (fullPacket);
832  ForwardUp (fullPacket->Copy (), source, Mac48Address ("ff:ff:ff:ff:ff:ff"));
833  }
834  else
835  {
836  // This is the first or middle fragment.
837  // Take the fragment queue, store the fragment into the queue
838  NS_LOG_INFO ("\t Received the first or the middle fragment" << std::endl);
839  GetConnectionManager ()->GetConnection (cid)
840  ->FragmentEnqueue (packet);
841  }
842  }
843  }
844  }
845  else
846  {
847  // bandwidth request header
848  packet->AddHeader (gnrcMacHdr);
849  packet->RemoveHeader (bwRequestHdr);
850  NS_ASSERT_MSG (bwRequestHdr.GetHt () == MacHeaderType::HEADER_TYPE_BANDWIDTH,
851  "A bandwidth request should be carried by a bandwidth header type");
852  if (bwRequestHdr.check_hcs () == false)
853  {
854  // The header is noisy
855  NS_LOG_INFO ("BS:Header HCS ERROR");
856  return;
857  }
858  cid = bwRequestHdr.GetCid ();
859  source = m_ssManager->GetMacAddress (cid);
860  m_traceBSRx (packet, source, cid);
861  GetBandwidthManager ()->ProcessBandwidthRequest (bwRequestHdr);
862  }
863 
864 }
865 
866 void
868 {
869  Ptr<Packet> dlmap, ulmap;
870  bool sendDcd = false, sendUcd = false, updateDcd = false, updateUcd = false;
871 
872  uint16_t currentNrSsRegistered = m_ssManager->GetNRegisteredSSs ();
873 
874  if (m_nrSsRegistered == currentNrSsRegistered)
875  {
876  m_uplinkScheduler->GetChannelDescriptorsToUpdate (updateDcd, updateUcd, sendDcd, sendUcd);
877  }
878  else
879  {
880  sendDcd = sendUcd = true;
881  }
882 
883  m_nrSsRegistered = currentNrSsRegistered;
884 
885  /*either DCD and UCD must be created first because CCC is set during their
886  creation, or CCC must be calculated first so that it could be set during
887  creation of DL-MAP and UL-MAP and then set duirng creation of DCD and UCD*/
888 
889  if (sendDcd)
890  {
891  m_dcdConfigChangeCount += 1 % 256;
892  }
893 
894  if (sendUcd)
895  {
896  m_ucdConfigChangeCount += 1 % 256;
897  }
898 
899  dlmap = CreateDlMap ();
901  m_nrDlMapSent++;
902 
903  ulmap = CreateUlMap ();
905  m_nrUlMapSent++;
906 
907  CreateDescriptorMessages (sendDcd, sendUcd);
908 }
909 
910 void
912 {
913  Ptr<Packet> dcd, ucd;
914 
915  if (sendDcd)
916  {
917  dcd = CreateDcd ();
919  m_nrDcdSent++;
920  m_framesSinceLastDcd = 0;
921  }
922  else
923  {
924  m_framesSinceLastDcd++;
925  }
926 
927  if (sendUcd)
928  {
929  ucd = CreateUcd ();
931  m_nrUcdSent++;
932  m_framesSinceLastUcd = 0;
933  }
934  else
935  {
936  m_framesSinceLastUcd++;
937  }
938 }
939 
940 /*
941  Sends bursts in the downlink subframe. i.e., creates the downlink subframe. The first burst
942  is broadcast burst with MAC management messages. The rest of the bursts contain data packets.
943  */
944 void
945 BaseStationNetDevice::SendBursts (void)
946 {
947  Time txTime = Seconds (0);
948  std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > pair;
949  WimaxPhy::ModulationType modulationType = WimaxPhy::MODULATION_TYPE_BPSK_12;
950  std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > > *downlinkBursts = m_scheduler->GetDownlinkBursts ();
951  Ptr<PacketBurst> burst;
952  OfdmDlMapIe *dlMapIe;
953  Cid cid;
954 
955  while (downlinkBursts->size ())
956  {
957  pair = downlinkBursts->front ();
958  burst = pair.second;
959  dlMapIe = pair.first;
960  cid = dlMapIe->GetCid ();
961  uint8_t diuc = dlMapIe->GetDiuc ();
962 
963  if (cid != GetInitialRangingConnection ()->GetCid () && cid != GetBroadcastConnection ()->GetCid ())
964  {
965  if (m_serviceFlowManager->GetServiceFlow (cid) != 0)
966  {
967  modulationType = GetBurstProfileManager ()->GetModulationType (diuc, WimaxNetDevice::DIRECTION_DOWNLINK);
968  }
969  else
970  {
971  modulationType = GetBurstProfileManager ()->GetModulationType (diuc, WimaxNetDevice::DIRECTION_DOWNLINK);
972  }
973  }
974  else
975  {
976  modulationType = WimaxPhy::MODULATION_TYPE_BPSK_12;
977  }
978 
979  Simulator::Schedule (txTime, &WimaxNetDevice::ForwardDown, this, burst, modulationType);
980  txTime += GetPhy ()->GetTransmissionTime (burst->GetSize (), modulationType);
981  downlinkBursts->pop_front ();
982  delete dlMapIe;
983  }
984 }
985 
986 Ptr<Packet>
987 BaseStationNetDevice::CreateDlMap (void)
988 {
989  m_nrDlAllocations = 0;
990 
991  DlMap dlmap;
992  dlmap.SetDcdCount (m_dcdConfigChangeCount);
993  dlmap.SetBaseStationId (GetMacAddress ());
994 
995  std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > > *downlinkBursts = m_scheduler->GetDownlinkBursts ();
996 
997  for (std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > >::iterator iter = downlinkBursts->begin (); iter
998  != downlinkBursts->end (); ++iter)
999  {
1000  iter->first->SetPreamblePresent (0);
1001  iter->first->SetStartTime (0);
1002  dlmap.AddDlMapElement (*(iter->first));
1003  }
1004 
1005  OfdmDlMapIe dlMapIeEnd;
1006 
1007  dlMapIeEnd.SetCid (Cid::InitialRanging ());
1008  dlMapIeEnd.SetDiuc (OfdmDlBurstProfile::DIUC_END_OF_MAP);
1009  dlMapIeEnd.SetPreamblePresent (0);
1010  dlMapIeEnd.SetStartTime (0);
1011 
1012  dlmap.AddDlMapElement (dlMapIeEnd);
1013  m_nrDlAllocations = downlinkBursts->size ();
1014 
1015  Ptr<Packet> p = Create<Packet> ();
1016  p->AddHeader (dlmap);
1017  p->AddHeader (ManagementMessageType (ManagementMessageType::MESSAGE_TYPE_DL_MAP));
1018  return p;
1019 }
1020 
1021 Ptr<Packet>
1022 BaseStationNetDevice::CreateDcd (void)
1023 {
1024  Dcd dcd;
1025  OfdmDcdChannelEncodings chnlEncodings;
1026 
1027  chnlEncodings.SetBsEirp (0);
1028  chnlEncodings.SetEirxPIrMax (0);
1029  chnlEncodings.SetFrequency (GetPhy ()->GetFrequency ());
1030  chnlEncodings.SetChannelNr (0);
1031  chnlEncodings.SetTtg (GetTtg ());
1032  chnlEncodings.SetRtg (GetRtg ());
1033  chnlEncodings.SetBaseStationId (GetMacAddress ());
1034  chnlEncodings.SetFrameDurationCode (GetPhy ()->GetFrameDurationCode ());
1035  chnlEncodings.SetFrameNumber (GetNrFrames ());
1036 
1037  dcd.SetConfigurationChangeCount (m_dcdConfigChangeCount);
1038  dcd.SetChannelEncodings (chnlEncodings);
1039 
1040  SetDlBurstProfiles (&dcd);
1041  SetCurrentDcd (dcd);
1042 
1043  Ptr<Packet> p = Create<Packet> ();
1044  p->AddHeader (dcd);
1045  p->AddHeader (ManagementMessageType (ManagementMessageType::MESSAGE_TYPE_DCD));
1046  return p;
1047 }
1048 
1049 Ptr<Packet>
1050 BaseStationNetDevice::CreateUlMap (void)
1051 {
1052  m_ulAllocationNumber = 0;
1053  m_rangingOppNumber = 0;
1054  m_nrUlAllocations = 0;
1055 
1056  UlMap ulmap;
1057  ulmap.SetUcdCount (m_ucdConfigChangeCount);
1058  ulmap.SetAllocationStartTime (m_uplinkScheduler->CalculateAllocationStartTime ());
1059 
1060  std::list<OfdmUlMapIe> uplinkAllocations = m_uplinkScheduler->GetUplinkAllocations ();
1061 
1062  for (std::list<OfdmUlMapIe>::iterator iter = uplinkAllocations.begin (); iter != uplinkAllocations.end (); ++iter)
1063  {
1064  ulmap.AddUlMapElement (*iter);
1065  }
1066 
1067  m_nrUlAllocations = uplinkAllocations.size ();
1068 
1069  Ptr<Packet> p = Create<Packet> ();
1070  p->AddHeader (ulmap);
1071  p->AddHeader (ManagementMessageType (ManagementMessageType::MESSAGE_TYPE_UL_MAP));
1072  return p;
1073 }
1074 
1075 Ptr<Packet>
1076 BaseStationNetDevice::CreateUcd (void)
1077 {
1078  Ucd ucd;
1079  ucd.SetConfigurationChangeCount (m_ucdConfigChangeCount);
1080  ucd.SetRangingBackoffStart (3); // setting to 7. i.e., 2^3 = 8 -> 0-7
1081  ucd.SetRangingBackoffEnd (6); // setting to 63. i.e., 2^6 = 64 -> 0-63
1082  ucd.SetRequestBackoffStart (3);
1083  ucd.SetRequestBackoffEnd (6);
1084 
1085  OfdmUcdChannelEncodings chnlEncodings;
1086 
1087  chnlEncodings.SetBwReqOppSize (m_bwReqOppSize * GetPhy ()->GetPsPerSymbol ());
1088  chnlEncodings.SetRangReqOppSize (m_rangReqOppSize * GetPhy ()->GetPsPerSymbol ());
1089 
1090  chnlEncodings.SetFrequency (GetPhy ()->GetFrequency ());
1091  chnlEncodings.SetSbchnlReqRegionFullParams (0);
1092  chnlEncodings.SetSbchnlFocContCodes (0);
1093 
1094  ucd.SetChannelEncodings (chnlEncodings);
1095 
1096  SetUlBurstProfiles (&ucd);
1097  SetCurrentUcd (ucd);
1098 
1099  Ptr<Packet> p = Create<Packet> ();
1100  p->AddHeader (ucd);
1101  p->AddHeader (ManagementMessageType (ManagementMessageType::MESSAGE_TYPE_UCD));
1102  return p;
1103 }
1104 
1105 void
1106 BaseStationNetDevice::SetDlBurstProfiles (Dcd *dcd)
1107 {
1108  for (int i = 0; i < GetBurstProfileManager ()->GetNrBurstProfilesToDefine (); ++i)
1109  {
1110  OfdmDlBurstProfile brstProfile;
1111  brstProfile.SetType (0);
1112  brstProfile.SetLength (0);
1113  brstProfile.SetDiuc (i + 1); // DIUC will be between 1-11, see Table 237
1114  brstProfile.SetFecCodeType (i);
1115  dcd->AddDlBurstProfile (brstProfile);
1116  }
1117 }
1118 
1119 void
1120 BaseStationNetDevice::SetUlBurstProfiles (Ucd *ucd)
1121 {
1122  for (int i = 0; i < GetBurstProfileManager ()->GetNrBurstProfilesToDefine (); ++i)
1123  {
1124  OfdmUlBurstProfile brstProfile;
1125  brstProfile.SetType (0);
1126  brstProfile.SetLength (0);
1127  // UIUC will be between 5-12, see Table 246. UIUC 1 (initial ranging) is not included
1128  brstProfile.SetUiuc (i + 5);
1129  brstProfile.SetFecCodeType (i);
1130 
1131  ucd->AddUlBurstProfile (brstProfile);
1132  }
1133 }
1134 
1135 Ptr<WimaxConnection>
1136 BaseStationNetDevice::GetConnection (Cid cid)
1137 {
1138  Ptr<WimaxConnection> connection = 0;
1139  if (cid.IsInitialRanging ())
1140  {
1141  return GetInitialRangingConnection ();
1142  }
1143  else if (cid.IsBroadcast ())
1144  {
1145  connection = GetBroadcastConnection ();
1146  }
1147  else
1148  {
1149  connection = GetConnectionManager ()->GetConnection (cid);
1150  }
1151 
1152  NS_ASSERT_MSG (connection != 0, "BS: Invalid connection=0");
1153  return connection;
1154 }
1155 
1156 void
1157 BaseStationNetDevice::MarkUplinkAllocations (void)
1158 {
1159  uint16_t symbolsToAllocation = 0;
1160  std::list<OfdmUlMapIe> uplinkAllocations = m_uplinkScheduler->GetUplinkAllocations ();
1161  for (std::list<OfdmUlMapIe>::iterator iter = uplinkAllocations.begin (); iter != uplinkAllocations.end (); ++iter)
1162  {
1163  OfdmUlMapIe uplinkAllocation = *iter;
1164 
1165  if (uplinkAllocation.GetUiuc () == OfdmUlBurstProfile::UIUC_END_OF_MAP)
1166  {
1167  break;
1168  }
1169 
1170  symbolsToAllocation = uplinkAllocation.GetStartTime ();
1171  MarkUplinkAllocationStart (Seconds (symbolsToAllocation * m_symbolDuration.GetSeconds ()));
1172  MarkUplinkAllocationEnd (Seconds ((symbolsToAllocation + uplinkAllocation.GetDuration ())
1173  * m_symbolDuration.GetSeconds ()), uplinkAllocation.GetCid (), uplinkAllocation.GetUiuc ());
1174  }
1175 }
1176 
1177 void
1178 BaseStationNetDevice::MarkUplinkAllocationStart (Time allocationStartTime)
1179 {
1180  Simulator::Schedule (allocationStartTime, &BaseStationNetDevice::UplinkAllocationStart, this);
1181 }
1182 
1183 void
1184 BaseStationNetDevice::MarkUplinkAllocationEnd (Time allocationEndTime, Cid cid, uint8_t uiuc)
1185 {
1186  Simulator::Schedule (allocationEndTime, &BaseStationNetDevice::UplinkAllocationEnd, this, cid, uiuc);
1187 }
1188 
1189 void
1190 BaseStationNetDevice::UplinkAllocationStart (void)
1191 {
1192  m_ulAllocationNumber++;
1193 
1194  NS_LOG_DEBUG ("--UL allocation " << (uint32_t) m_ulAllocationNumber << " started : "
1195  << Simulator::Now ().GetSeconds ());
1196 
1197 }
1198 
1199 void
1200 BaseStationNetDevice::UplinkAllocationEnd (Cid cid, uint8_t uiuc)
1201 {
1202  NS_LOG_DEBUG ("--UL allocation " << (uint32_t) m_ulAllocationNumber << " ended : " << Simulator::Now ().GetSeconds ());
1203 
1204  if (m_cidFactory->IsBasic (cid))
1205  {
1206  m_linkManager->VerifyInvitedRanging (cid, uiuc);
1207  }
1208 }
1209 
1210 void
1211 BaseStationNetDevice::MarkRangingOppStart (Time rangingOppStartTime)
1212 {
1213  Simulator::Schedule (rangingOppStartTime, &BaseStationNetDevice::RangingOppStart, this);
1214 }
1215 
1216 void
1217 BaseStationNetDevice::RangingOppStart (void)
1218 {
1219  m_rangingOppNumber++;
1220 
1221  NS_LOG_DEBUG ("Ranging TO " << (uint32_t) m_rangingOppNumber << ": " << Simulator::Now ().GetSeconds ());
1222 }
1223 
1224 } // namespace ns3
void SetUcdInterval(Time ucdInterval)
uint32_t RemoveHeader(Header &header)
Definition: packet.cc:285
void SetRtg(uint16_t rtg)
keep track of time unit.
Definition: nstime.h:149
Time GetIntervalT8(void) const
void SetNrDlSymbols(uint32_t dlSymbols)
uint16_t GetRtg(void) const
uint32_t GetNrDcdSent(void) const
void SetLinkManager(Ptr< BSLinkManager > linkManager)
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
Ptr< WimaxConnection > GetBroadcastConnection(void) const
uint32_t GetSize(void) const
Definition: packet.h:620
Ptr< BSScheduler > GetBSScheduler(void) const
TracedCallback< Ptr< const Packet > > m_bsRxTrace
uint8_t GetMaxRangingCorrectionRetries(void) const
#define NS_LOG_INFO(msg)
Definition: log.h:264
bool IsBroadcast(void) const
Definition: cid.cc:56
static void Cancel(const EventId &id)
Definition: simulator.cc:267
void SetBSScheduler(Ptr< BSScheduler > bsSchedule)
Ptr< ConnectionManager > GetConnectionManager(void) const
uint8_t GetRangReqOppSize(void) const
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
void SetMaxInvitedRangRetries(uint8_t maxInvitedRangRetries)
void SetIntervalT8(Time interval)
void SetBsClassifier(Ptr< IpcsClassifier > classifier)
this class implements the Generic mac Header as described by IEEE Standard for Local and metropolitan...
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
Time GetDcdInterval(void) const
double GetSeconds(void) const
Definition: nstime.h:262
uint32_t GetSerializedSize(void) const
uint8_t GetMaxInvitedRangRetries(void) const
TracedCallback< Ptr< const Packet > > m_bsRxDropTrace
bool Enqueue(Ptr< Packet > packet, const MacHeaderType &hdrType, Ptr< WimaxConnection > connection)
Enqueue a packet into a connection queue.
uint16_t GetTtg(void) const
void SetRangReqOppSize(uint8_t rangReqOppSize)
void SetTtg(uint16_t ttg)
TracedCallback< Ptr< const Packet > > m_bsTxDropTrace
Time GetInitialRangingInterval(void) const
static Cid InitialRanging(void)
Definition: cid.cc:82
bool IsInitialRanging(void) const
Definition: cid.cc:66
Ptr< UplinkScheduler > GetUplinkScheduler(void) const
void SetInitialRangingInterval(Time initialRangInterval)
Ptr< IpcsClassifier > GetBsClassifier(void) const
Ptr< WimaxConnection > GetInitialRangingConnection(void) const
Ptr< BandwidthManager > GetBandwidthManager(void) const
Mac48Address GetMacAddress(void) const
Represents the HT (Header Type) field of generic MAC and bandwidth request headers.
virtual void DoDispose(void)
Ptr< Packet > Copy(void) const
Definition: packet.cc:131
uint8_t GetBwReqOppSize(void) const
this class implements the bandwidth-request mac Header as described by IEEE Standard for Local and me...
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Definition: cid.h:35
an EUI-48 address
Definition: mac48-address.h:41
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Definition: simulator.h:981
static Time Now(void)
Definition: simulator.cc:179
void SetDcdInterval(Time dcdInterval)
TracedCallback< Ptr< const Packet > > m_bsPromiscRxTrace
void SetPhy(Ptr< WimaxPhy > phy)
void CreateMapMessages(void)
creates the MAC management messages DL-MAP and UL-MAP
TracedCallback< Ptr< const Packet > > m_bsTxTrace
void SetUplinkScheduler(Ptr< UplinkScheduler > ulScheduler)
uint32_t GetNrDlSymbols(void) const
this class implements the fragmentation sub-header as described by IEEE Standard for Local and metrop...
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
void CreateDescriptorMessages(bool sendDcd, bool senUcd)
creates the channel descriptor MAC management messages DCD and UCD
Ptr< BurstProfileManager > GetBurstProfileManager(void) const
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
uint32_t GetNrUlSymbols(void) const
void SetMaxRangingCorrectionRetries(uint8_t maxRangCorrectionRetries)
Ptr< BSLinkManager > GetLinkManager(void) const
Ptr< WimaxPhy > GetPhy(void) const
Time GetUcdInterval(void) const
void SetBwReqOppSize(uint8_t bwReqOppSize)
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
Ptr< SSManager > GetSSManager(void) const
void SetSSManager(Ptr< SSManager > ssManager)
Time MilliSeconds(uint64_t ms)
create ns3::Time instances in units of milliseconds.
Definition: nstime.h:601
void InitBaseStationNetDevice(void)
initializes the BS net device and sets its parameters to the default values
void SetNrUlSymbols(uint32_t ulSymbols)
virtual void SetNode(Ptr< Node > node)
uint32_t GetNrUcdSent(void) const
void AddHeader(const Header &header)
Definition: packet.cc:270
Header for the LLC/SNAP encapsulation.