A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
bs-net-device.cc
Go to the documentation of this file.
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 
57 {
58  static TypeId tid = TypeId ("ns3::BaseStationNetDevice")
59 
61 
62  .AddConstructor<BaseStationNetDevice> ()
63 
64  .AddAttribute ("BSScheduler",
65  "Downlink Scheduler for BS",
66  PointerValue (),
67  MakePointerAccessor (&BaseStationNetDevice::m_scheduler),
68  MakePointerChecker<BSScheduler> ())
69 
70  .AddAttribute ("InitialRangInterval",
71  "Time between Initial Ranging regions assigned by the BS. Maximum is 2s",
72  TimeValue (Seconds (0.05)),
75  MakeTimeChecker ())
76 
77  .AddAttribute ("DcdInterval",
78  "Time between transmission of DCD messages. Maximum value is 10s.",
79  TimeValue (Seconds (3)),
81  MakeTimeChecker ())
82 
83  .AddAttribute ("UcdInterval",
84  "Time between transmission of UCD messages. Maximum value is 10s.",
85  TimeValue (Seconds (3)),
87  MakeTimeChecker ())
88 
89  .AddAttribute ("IntervalT8",
90  "Wait for DSA/DSC Acknowledge timeout. Maximum 300ms.",
91  TimeValue (Seconds (0.05)),
93  MakeTimeChecker ())
94 
95  .AddAttribute ("RangReqOppSize",
96  "The ranging opportunity size in symbols",
97  UintegerValue (8),
98  MakeUintegerAccessor (&BaseStationNetDevice::GetRangReqOppSize,
100  MakeUintegerChecker<uint8_t> (1, 256))
101 
102  .AddAttribute ("BwReqOppSize",
103  "The bandwidth request opportunity size in symbols",
104  UintegerValue (2),
106  MakeUintegerChecker<uint8_t> (1, 256))
107 
108  .AddAttribute ("MaxRangCorrectionRetries",
109  "Number of retries on contention Ranging Requests",
110  UintegerValue (16),
113  MakeUintegerChecker<uint8_t> (1, 16))
114 
115  .AddAttribute ("SSManager",
116  "The ss manager attached to this device.",
117  PointerValue (),
119  MakePointerChecker<SSManager> ())
120 
121  .AddAttribute ("Scheduler",
122  "The BS scheduler attached to this device.",
123  PointerValue (),
125  MakePointerChecker<BSScheduler> ())
126 
127  .AddAttribute ("LinkManager",
128  "The link manager attached to this device.",
129  PointerValue (),
131  MakePointerChecker<BSLinkManager> ())
132 
133  .AddAttribute ("UplinkScheduler",
134  "The uplink scheduler attached to this device.",
135  PointerValue (),
136  MakePointerAccessor (&BaseStationNetDevice::GetUplinkScheduler,
138  MakePointerChecker<UplinkScheduler> ())
139 
140  .AddAttribute ("BsIpcsPacketClassifier",
141  "The uplink IP packet classifier attached to this device.",
142  PointerValue (),
144  MakePointerChecker<IpcsClassifier> ())
145 
146  .AddAttribute ("ServiceFlowManager",
147  "The service flow manager attached to this device.",
148  PointerValue (),
149  MakePointerAccessor (&BaseStationNetDevice::GetServiceFlowManager,
151  MakePointerChecker<ServiceFlowManager> ())
152 
153  .AddTraceSource ("BSTx", "A packet has been received from higher layers and is being processed in preparation for "
154  "queueing for transmission.", MakeTraceSourceAccessor (&BaseStationNetDevice::m_bsTxTrace))
155 
156  .AddTraceSource ("BSTxDrop",
157  "A packet has been dropped in the MAC layer before being queued for transmission.",
159 
160  .AddTraceSource ("BSPromiscRx",
161  "A packet has been received by this device, has been passed up from the physical layer "
162  "and is being forwarded up the local protocol stack. This is a promiscuous trace,",
164 
165  .AddTraceSource ("BSRx",
166  "A packet has been received by this device, has been passed up from the physical layer "
167  "and is being forwarded up the local protocol stack. This is a non-promiscuous trace,",
169 
170  .AddTraceSource ("BSRxDrop",
171  "A packet has been dropped in the MAC layer after it has been passed up from the physical "
172  "layer.",
174  return tid;
175 }
176 
178 {
180 }
181 
182 void
184 {
185 
186  m_initialRangInterval = Seconds (0.05); // maximum is 2
187  m_dcdInterval = Seconds (3); // maximum is 10
188  m_ucdInterval = Seconds (3); // maximum is 10
189  m_intervalT8 = MilliSeconds (50); // maximum is 300 milliseconds
192  m_rangReqOppSize = 8; // 8 symbols = 2 (preamble) + 2 (RNG-REQ) + 4 (round-trip propagation time)
193  m_bwReqOppSize = 2; // 2 symbols = 1 (preamble) + 1 (bandwidth request header)
194  m_nrDlSymbols = 0;
195  m_nrUlSymbols = 0;
196  m_nrDlMapSent = 0;
197  m_nrUlMapSent = 0;
198  m_nrDcdSent = 0;
199  m_nrUcdSent = 0;
204  m_nrDlFrames = 0;
205  m_nrUlFrames = 0;
206  m_nrSsRegistered = 0;
207  m_nrDlAllocations = 0;
208  m_nrUlAllocations = 0;
209  m_dlSubframeStartTime = Seconds (0);
210  m_ulSubframeStartTime = Seconds (0);
212  m_rangingOppNumber = 0;
214  m_psDuration = Seconds (0);
215  m_symbolDuration = Seconds (0);
216  m_linkManager = CreateObject<BSLinkManager> (this);
217  m_cidFactory = new CidFactory ();
218  m_ssManager = CreateObject<SSManager> ();
219  m_bsClassifier = CreateObject<IpcsClassifier> ();
220  m_serviceFlowManager = CreateObject<BsServiceFlowManager> (this);
221 
222 }
223 
225 {
227  this->SetNode (node);
228  this->SetPhy (phy);
229 }
230 
232  Ptr<WimaxPhy> phy,
233  Ptr<UplinkScheduler> uplinkScheduler,
234  Ptr<BSScheduler> bsScheduler)
235 {
237  this->SetNode (node);
238  this->SetPhy (phy);
239  m_uplinkScheduler = uplinkScheduler;
240  m_scheduler = bsScheduler;
241 }
242 
244 {
245 }
246 
247 void
249 {
250  delete m_cidFactory;
251 
252  m_linkManager = 0;
253  m_ssManager = 0;
254  m_bsClassifier = 0;
256  m_uplinkScheduler = 0;
257  m_cidFactory = 0;
258  m_ssManager = 0;
259  m_uplinkScheduler = 0;
260  m_scheduler = 0;
261 
263 }
264 
265 void
267 {
268  m_bsClassifier = bsc;
269 }
270 
273 {
274  return m_bsClassifier;
275 }
276 
277 void
279 {
280  m_initialRangInterval = initialRangInterval;
281 }
282 
283 Time
285 {
286  return m_initialRangInterval;
287 }
288 
289 void
291 {
292  m_dcdInterval = dcdInterval;
293 }
294 
295 Time
297 {
298  return m_dcdInterval;
299 }
300 
301 void
303 {
304  m_ucdInterval = ucdInterval;
305 }
306 
307 Time
309 {
310  return m_ucdInterval;
311 }
312 
313 void
315 {
316  m_intervalT8 = interval;
317 }
318 
319 Time
321 {
322  return m_intervalT8;
323 }
324 
325 void
327 {
328  m_maxRangCorrectionRetries = maxRangCorrectionRetries;
329 }
330 
331 uint8_t
333 {
335 }
336 
337 void
338 BaseStationNetDevice::SetMaxInvitedRangRetries (uint8_t maxInvitedRangRetries)
339 {
340  m_maxInvitedRangRetries = maxInvitedRangRetries;
341 }
342 
343 uint8_t
345 {
347 }
348 
349 void
351 {
352  m_rangReqOppSize = rangReqOppSize;
353 }
354 
355 uint8_t
357 {
358  return m_rangReqOppSize;
359 }
360 
361 void
363 {
364  m_bwReqOppSize = bwReqOppSize;
365 }
366 
367 uint8_t
369 {
370  return m_bwReqOppSize;
371 }
372 
373 void
375 {
376  m_nrDlSymbols = nrDlSymbols;
377 }
378 
379 uint32_t
381 {
382  return m_nrDlSymbols;
383 }
384 
385 void
387 {
388  m_nrUlSymbols = nrUlSymbols;
389 }
390 
391 uint32_t
393 {
394  return m_nrUlSymbols;
395 }
396 
397 uint32_t
399 {
400  return m_nrDcdSent;
401 }
402 
403 uint32_t
405 {
406  return m_nrUcdSent;
407 }
408 
409 Time
411 {
412  return m_dlSubframeStartTime;
413 }
414 
415 Time
417 {
418  return m_ulSubframeStartTime;
419 }
420 
421 uint8_t
423 {
424  return m_rangingOppNumber;
425 }
426 
429 {
430  return m_ssManager;
431 }
432 
433 void
435 {
436  m_ssManager = ssm;
437 }
438 
441 {
442  return m_serviceFlowManager;
443 }
444 
445 void
447 {
448  m_serviceFlowManager = sfm;
449 }
450 
453 {
454  return m_uplinkScheduler;
455 }
456 
457 void
459 {
460  m_uplinkScheduler = uls;
461 }
462 
465 {
466  return m_linkManager;
467 }
468 
469 void
471 {
472  m_linkManager = lm;
473 }
474 
475 void
477 {
478  m_scheduler = bss;
479 }
482 {
483  return m_scheduler;
484 }
485 
486 Time
488 {
489  return m_psDuration;
490 }
491 
492 Time
494 {
495  return m_symbolDuration;
496 }
497 
498 void
500 {
502  GetConnectionManager ()->SetCidFactory (m_cidFactory);
503  GetPhy ()->SetPhyParameters ();
504  GetPhy ()->SetDataRates ();
505  SetTtg (GetPhy ()->GetTtg ());
506  SetRtg (GetPhy ()->GetRtg ());
507  m_psDuration = GetPhy ()->GetPsDuration ();
508  m_symbolDuration = GetPhy ()->GetSymbolDuration ();
509  GetBandwidthManager ()->SetSubframeRatio ();
510 
512  GetPhy ()->SetSimplex (m_linkManager->SelectDlChannel ());
514 
515  /* shall actually be 2 symbols = 1 (preamble) + 1 (bandwidth request header)*/
516  m_bwReqOppSize = 6;
517  m_uplinkScheduler->InitOnce ();
518 }
519 
520 void
522 {
523 }
524 
525 void
527 {
528  //setting DL/UL subframe allocation for this frame
529  uint32_t symbolsPerFrame = GetPhy ()->GetSymbolsPerFrame ();
530  SetNrDlSymbols ((symbolsPerFrame / 2) - static_cast<uint32_t> (std::ceil (GetTtg ()*m_psDuration.GetSeconds ()/m_symbolDuration.GetSeconds ())));
531  SetNrUlSymbols ((symbolsPerFrame / 2) - static_cast<uint32_t> (std::ceil (GetRtg ()*m_psDuration.GetSeconds ()/m_symbolDuration.GetSeconds ())));
532 
534 
535  NS_LOG_INFO ("----------------------frame" << GetNrFrames () + 1 << "----------------------");
536 
537  StartDlSubFrame ();
538 }
539 
540 void
542 {
543  m_dlSubframeStartTime = Simulator::Now (); // same as m_frameStartTime
544 
545  NS_LOG_DEBUG ("DL frame started : " << m_frameStartTime.GetSeconds ());
546 
547  SetNrFrames (GetNrFrames () + 1);
550  m_uplinkScheduler->Schedule ();
552  m_scheduler->Schedule ();
553  SendBursts ();
556  this);
557 }
558 
559 void
561 {
562  m_nrDlFrames++;
565 }
566 
567 void
569 {
571 
572  NS_LOG_INFO ("UL frame started : " << m_ulSubframeStartTime.GetSeconds ());
573 
579  this);
580 }
581 
582 void
584 {
585  m_nrUlFrames++;
588 }
589 
590 void
592 {
593  StartFrame ();
594 }
595 
596 bool
598  const Mac48Address &source,
599  const Mac48Address &dest,
600  uint16_t protocolNumber)
601 {
602  Ptr<PacketBurst> burst = Create<PacketBurst> ();
603  ServiceFlow *serviceFlow = 0;
604 
605  NS_LOG_INFO ("BS (" << source << "):");
606  NS_LOG_INFO ("\tSending packet...");
607  NS_LOG_INFO ("\t\tDestination: " << dest);
608  NS_LOG_INFO ("\t\tPaket Size: " << packet->GetSize ());
609  NS_LOG_INFO ("\t\tProtocol: " << protocolNumber);
610 
611 
612  if (protocolNumber == 2048)
613  {
614  serviceFlow = m_bsClassifier->Classify (packet, GetServiceFlowManager (), ServiceFlow::SF_DIRECTION_DOWN);
615  }
616 
617  if (protocolNumber != 2048 || serviceFlow == 0)
618  {
619  serviceFlow = *GetServiceFlowManager ()->GetServiceFlows (ServiceFlow::SF_TYPE_ALL).begin ();
620  }
621 
622  if (serviceFlow == 0)
623  {
624  NS_LOG_INFO ("No Service Flow!!");
625  m_bsTxDropTrace (packet);
626  return false;
627  }
628  if (serviceFlow->GetIsEnabled ())
629  {
630  if (!Enqueue (packet, MacHeaderType (), serviceFlow->GetConnection ()))
631  {
632  NS_LOG_INFO ("Enqueue Error!!");
633  m_bsTxDropTrace (packet);
634  return false;
635  }
636  }
637  else
638  {
639  m_bsTxDropTrace (packet);
640  NS_LOG_INFO ("Service Flow is not enabled");
641  return false;
642  }
643  m_bsTxTrace (packet);
644 
645  return true;
646 }
647 
648 bool
650 {
651  NS_ASSERT_MSG (connection != 0,
652  "BS: Can not enqueue packet on the selected connection: the connection is not initialized");
653 
654  GenericMacHeader hdr;
655  hdr.SetLen (packet->GetSize () + hdr.GetSerializedSize ());
656 
657  hdr.SetCid (connection->GetCid ());
658 
659  return connection->Enqueue (packet, hdrType, hdr);
660 }
661 
662 void
664 {
665  GenericMacHeader gnrcMacHdr;
666  BandwidthRequestHeader bwRequestHdr;
667  ManagementMessageType msgType;
668  RngReq rngReq;
669  Cid cid;
670  uint8_t type = 0;
671  GrantManagementSubheader grantMgmntSubhdr;
672  Mac48Address source;
673  LlcSnapHeader llc;
674  Ptr<WimaxConnection> connection = 0;
675  FragmentationSubheader fragSubhdr;
676  bool fragmentation = false; // it becames true when there is a fragmentation subheader
677 
678  packet->RemoveHeader (gnrcMacHdr);
679  if (gnrcMacHdr.GetHt () == MacHeaderType::HEADER_TYPE_GENERIC)
680  {
681  if (gnrcMacHdr.check_hcs () == false)
682  {
683  // The header is noisy
684  m_bsRxDropTrace (packet);
685  NS_LOG_INFO ("Header HCS ERROR");
686  return;
687  }
688 
689  cid = gnrcMacHdr.GetCid ();
690 
691  // checking for subheaders (only grant management subheader is implemented)
692  type = gnrcMacHdr.GetType ();
693  if (type)
694  {
695  // checking 1st bit, see Table 6
696  if (type & 1)
697  {
698  packet->RemoveHeader (grantMgmntSubhdr);
699  }
700  // Check if there is a fragmentation Subheader
701  uint8_t tmpType = type;
702  if (((tmpType >> 2) & 1) == 1)
703  {
704  // a TRANSPORT packet with fragmentation subheader has been received!
705  NS_LOG_INFO ("FRAG_DEBUG: DoReceive -> the packet is a fragment" << std::endl);
706  fragmentation = true;
707  }
708  }
709 
710  if (cid.IsInitialRanging ()) // initial ranging connection
711  {
712  packet->RemoveHeader (msgType);
713  switch (msgType.GetType ())
714  {
716  {
717  packet->RemoveHeader (rngReq);
718  m_linkManager->ProcessRangingRequest (cid, rngReq);
719  break;
720  }
722  // from other base station, ignore
723  break;
724  default:
725  NS_FATAL_ERROR ("Invalid message type");
726  }
727  }
728  else if (m_cidFactory->IsBasic (cid)) // basic management connection
729  {
730  source = m_ssManager->GetMacAddress (cid);
731  m_traceBSRx (packet, source, cid);
732  packet->RemoveHeader (msgType);
733  switch (msgType.GetType ())
734  {
736  {
737  packet->RemoveHeader (rngReq);
738  m_linkManager->ProcessRangingRequest (cid, rngReq);
739  break;
740  }
742  // from other base station, ignore
743  break;
744  default:
745  NS_FATAL_ERROR ("Invalid message type");
746  }
747  }
748  else if (m_cidFactory->IsPrimary (cid)) // primary management connection
749  {
750  source = m_ssManager->GetMacAddress (cid);
751  m_traceBSRx (packet, source, cid);
752  packet->RemoveHeader (msgType);
753  switch (msgType.GetType ())
754  {
756  // not yet implemented
757  break;
759  // from other base station, ignore
760  break;
762  {
763  DsaReq dsaReq;
764  packet->RemoveHeader (dsaReq);
765  GetServiceFlowManager ()->AllocateServiceFlows (dsaReq, cid);
766  break;
767  }
769 
770  /*from other base station, as DSA initiated
771  from BS is not supported, ignore*/
772  break;
774  {
775  Simulator::Cancel (GetServiceFlowManager ()->GetDsaAckTimeoutEvent ());
776  DsaAck dsaAck;
777  packet->RemoveHeader (dsaAck);
778  GetServiceFlowManager ()->ProcessDsaAck (dsaAck, cid);
779  break;
780  }
781  default:
782  NS_FATAL_ERROR ("Invalid message type");
783  }
784  }
785  else if (cid.IsBroadcast ()) // broadcast connection
786  {
787  // from other base station, ignore
788  // or perhaps data packet (using other protocol) for BS, handle later
789  return;
790  }
791  else // transport connection
792  {
793  // If fragmentation is true, the packet is a fragment.
794  Ptr<Packet> C_Packet = packet->Copy ();
795  if (!fragmentation)
796  {
797  C_Packet->RemoveHeader (llc);
798  source = m_ssManager->GetMacAddress (cid);
799  m_bsRxTrace (packet);
800  ForwardUp (packet->Copy (), source, Mac48Address ("ff:ff:ff:ff:ff:ff"));
801  }
802  else
803  {
804  NS_LOG_INFO ( "FRAG_DEBUG: BS DoReceive, the Packet is a fragment" << std::endl);
805  packet->RemoveHeader (fragSubhdr);
806  uint32_t fc = fragSubhdr.GetFc ();
807  NS_LOG_INFO ("\t fragment size = " << packet->GetSize () << std::endl);
808  if (fc == 2)
809  {
810  // This is the latest fragment.
811  // Take the fragment queue, defragment a packet and send it to the upper layer
812  NS_LOG_INFO ("\t Received the latest fragment" << std::endl);
813  GetConnectionManager ()->GetConnection (cid)
814  ->FragmentEnqueue (packet);
816  GetConnection (cid)->GetFragmentsQueue ();
817  Ptr<Packet> fullPacket = Create<Packet> ();
818 
819  // DEFRAGMENTATION
820  NS_LOG_INFO ("\t BS PACKET DEFRAGMENTATION" << std::endl);
821  for (std::list<Ptr<const Packet> >::const_iterator iter = fragmentsQueue.begin ();
822  iter != fragmentsQueue.end (); ++iter)
823  {
824  // Create the whole Packet
825  fullPacket->AddAtEnd (*iter);
826  }
827  GetConnectionManager ()->GetConnection (cid)
828  ->ClearFragmentsQueue ();
829 
830  NS_LOG_INFO ("\t fullPacket size = " << fullPacket->GetSize () << std::endl);
831  source = m_ssManager->GetMacAddress (cid);
832  m_bsRxTrace (fullPacket);
833  ForwardUp (fullPacket->Copy (), source, Mac48Address ("ff:ff:ff:ff:ff:ff"));
834  }
835  else
836  {
837  // This is the first or middle fragment.
838  // Take the fragment queue, store the fragment into the queue
839  NS_LOG_INFO ("\t Received the first or the middle fragment" << std::endl);
840  GetConnectionManager ()->GetConnection (cid)
841  ->FragmentEnqueue (packet);
842  }
843  }
844  }
845  }
846  else
847  {
848  // bandwidth request header
849  packet->AddHeader (gnrcMacHdr);
850  packet->RemoveHeader (bwRequestHdr);
852  "A bandwidth request should be carried by a bandwidth header type");
853  if (bwRequestHdr.check_hcs () == false)
854  {
855  // The header is noisy
856  NS_LOG_INFO ("BS:Header HCS ERROR");
857  return;
858  }
859  cid = bwRequestHdr.GetCid ();
860  source = m_ssManager->GetMacAddress (cid);
861  m_traceBSRx (packet, source, cid);
862  GetBandwidthManager ()->ProcessBandwidthRequest (bwRequestHdr);
863  }
864 
865 }
866 
867 void
869 {
870  Ptr<Packet> dlmap, ulmap;
871  bool sendDcd = false, sendUcd = false, updateDcd = false, updateUcd = false;
872 
873  uint16_t currentNrSsRegistered = m_ssManager->GetNRegisteredSSs ();
874 
875  if (m_nrSsRegistered == currentNrSsRegistered)
876  {
877  m_uplinkScheduler->GetChannelDescriptorsToUpdate (updateDcd, updateUcd, sendDcd, sendUcd);
878  }
879  else
880  {
881  sendDcd = sendUcd = true;
882  }
883 
884  m_nrSsRegistered = currentNrSsRegistered;
885 
886  /*either DCD and UCD must be created first because CCC is set during their
887  creation, or CCC must be calculated first so that it could be set during
888  creation of DL-MAP and UL-MAP and then set duirng creation of DCD and UCD*/
889 
890  if (sendDcd)
891  {
892  m_dcdConfigChangeCount += 1 % 256;
893  }
894 
895  if (sendUcd)
896  {
897  m_ucdConfigChangeCount += 1 % 256;
898  }
899 
900  dlmap = CreateDlMap ();
902  m_nrDlMapSent++;
903 
904  ulmap = CreateUlMap ();
906  m_nrUlMapSent++;
907 
908  CreateDescriptorMessages (sendDcd, sendUcd);
909 }
910 
911 void
913 {
914  Ptr<Packet> dcd, ucd;
915 
916  if (sendDcd)
917  {
918  dcd = CreateDcd ();
920  m_nrDcdSent++;
922  }
923  else
924  {
926  }
927 
928  if (sendUcd)
929  {
930  ucd = CreateUcd ();
932  m_nrUcdSent++;
934  }
935  else
936  {
938  }
939 }
940 
941 /*
942  Sends bursts in the downlink subframe. i.e., creates the downlink subframe. The first burst
943  is broadcast burst with MAC management messages. The rest of the bursts contain data packets.
944  */
945 void
947 {
948  Time txTime = Seconds (0);
949  std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > pair;
951  std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > > *downlinkBursts = m_scheduler->GetDownlinkBursts ();
952  Ptr<PacketBurst> burst;
953  OfdmDlMapIe *dlMapIe;
954  Cid cid;
955 
956  while (downlinkBursts->size ())
957  {
958  pair = downlinkBursts->front ();
959  burst = pair.second;
960  dlMapIe = pair.first;
961  cid = dlMapIe->GetCid ();
962  uint8_t diuc = dlMapIe->GetDiuc ();
963 
964  if (cid != GetInitialRangingConnection ()->GetCid () && cid != GetBroadcastConnection ()->GetCid ())
965  {
966  if (m_serviceFlowManager->GetServiceFlow (cid) != 0)
967  {
968  modulationType = GetBurstProfileManager ()->GetModulationType (diuc, WimaxNetDevice::DIRECTION_DOWNLINK);
969  }
970  else
971  {
972  modulationType = GetBurstProfileManager ()->GetModulationType (diuc, WimaxNetDevice::DIRECTION_DOWNLINK);
973  }
974  }
975  else
976  {
977  modulationType = WimaxPhy::MODULATION_TYPE_BPSK_12;
978  }
979 
980  Simulator::Schedule (txTime, &WimaxNetDevice::ForwardDown, this, burst, modulationType);
981  txTime += GetPhy ()->GetTransmissionTime (burst->GetSize (), modulationType);
982  downlinkBursts->pop_front ();
983  delete dlMapIe;
984  }
985 }
986 
989 {
990  m_nrDlAllocations = 0;
991 
992  DlMap dlmap;
994  dlmap.SetBaseStationId (GetMacAddress ());
995 
996  std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > > *downlinkBursts = m_scheduler->GetDownlinkBursts ();
997 
998  for (std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > >::iterator iter = downlinkBursts->begin (); iter
999  != downlinkBursts->end (); ++iter)
1000  {
1001  iter->first->SetPreamblePresent (0);
1002  iter->first->SetStartTime (0);
1003  dlmap.AddDlMapElement (*(iter->first));
1004  }
1005 
1006  OfdmDlMapIe dlMapIeEnd;
1007 
1008  dlMapIeEnd.SetCid (Cid::InitialRanging ());
1010  dlMapIeEnd.SetPreamblePresent (0);
1011  dlMapIeEnd.SetStartTime (0);
1012 
1013  dlmap.AddDlMapElement (dlMapIeEnd);
1014  m_nrDlAllocations = downlinkBursts->size ();
1015 
1016  Ptr<Packet> p = Create<Packet> ();
1017  p->AddHeader (dlmap);
1019  return p;
1020 }
1021 
1024 {
1025  Dcd dcd;
1026  OfdmDcdChannelEncodings chnlEncodings;
1027 
1028  chnlEncodings.SetBsEirp (0);
1029  chnlEncodings.SetEirxPIrMax (0);
1030  chnlEncodings.SetFrequency (GetPhy ()->GetFrequency ());
1031  chnlEncodings.SetChannelNr (0);
1032  chnlEncodings.SetTtg (GetTtg ());
1033  chnlEncodings.SetRtg (GetRtg ());
1034  chnlEncodings.SetBaseStationId (GetMacAddress ());
1035  chnlEncodings.SetFrameDurationCode (GetPhy ()->GetFrameDurationCode ());
1036  chnlEncodings.SetFrameNumber (GetNrFrames ());
1037 
1039  dcd.SetChannelEncodings (chnlEncodings);
1040 
1041  SetDlBurstProfiles (&dcd);
1042  SetCurrentDcd (dcd);
1043 
1044  Ptr<Packet> p = Create<Packet> ();
1045  p->AddHeader (dcd);
1047  return p;
1048 }
1049 
1052 {
1054  m_rangingOppNumber = 0;
1055  m_nrUlAllocations = 0;
1056 
1057  UlMap ulmap;
1059  ulmap.SetAllocationStartTime (m_uplinkScheduler->CalculateAllocationStartTime ());
1060 
1061  std::list<OfdmUlMapIe> uplinkAllocations = m_uplinkScheduler->GetUplinkAllocations ();
1062 
1063  for (std::list<OfdmUlMapIe>::iterator iter = uplinkAllocations.begin (); iter != uplinkAllocations.end (); ++iter)
1064  {
1065  ulmap.AddUlMapElement (*iter);
1066  }
1067 
1068  m_nrUlAllocations = uplinkAllocations.size ();
1069 
1070  Ptr<Packet> p = Create<Packet> ();
1071  p->AddHeader (ulmap);
1073  return p;
1074 }
1075 
1078 {
1079  Ucd ucd;
1081  ucd.SetRangingBackoffStart (3); // setting to 7. i.e., 2^3 = 8 -> 0-7
1082  ucd.SetRangingBackoffEnd (6); // setting to 63. i.e., 2^6 = 64 -> 0-63
1083  ucd.SetRequestBackoffStart (3);
1084  ucd.SetRequestBackoffEnd (6);
1085 
1086  OfdmUcdChannelEncodings chnlEncodings;
1087 
1088  chnlEncodings.SetBwReqOppSize (m_bwReqOppSize * GetPhy ()->GetPsPerSymbol ());
1089  chnlEncodings.SetRangReqOppSize (m_rangReqOppSize * GetPhy ()->GetPsPerSymbol ());
1090 
1091  chnlEncodings.SetFrequency (GetPhy ()->GetFrequency ());
1092  chnlEncodings.SetSbchnlReqRegionFullParams (0);
1093  chnlEncodings.SetSbchnlFocContCodes (0);
1094 
1095  ucd.SetChannelEncodings (chnlEncodings);
1096 
1097  SetUlBurstProfiles (&ucd);
1098  SetCurrentUcd (ucd);
1099 
1100  Ptr<Packet> p = Create<Packet> ();
1101  p->AddHeader (ucd);
1103  return p;
1104 }
1105 
1106 void
1108 {
1109  for (int i = 0; i < GetBurstProfileManager ()->GetNrBurstProfilesToDefine (); ++i)
1110  {
1111  OfdmDlBurstProfile brstProfile;
1112  brstProfile.SetType (0);
1113  brstProfile.SetLength (0);
1114  brstProfile.SetDiuc (i + 1); // DIUC will be between 1-11, see Table 237
1115  brstProfile.SetFecCodeType (i);
1116  dcd->AddDlBurstProfile (brstProfile);
1117  }
1118 }
1119 
1120 void
1122 {
1123  for (int i = 0; i < GetBurstProfileManager ()->GetNrBurstProfilesToDefine (); ++i)
1124  {
1125  OfdmUlBurstProfile brstProfile;
1126  brstProfile.SetType (0);
1127  brstProfile.SetLength (0);
1128  // UIUC will be between 5-12, see Table 246. UIUC 1 (initial ranging) is not included
1129  brstProfile.SetUiuc (i + 5);
1130  brstProfile.SetFecCodeType (i);
1131 
1132  ucd->AddUlBurstProfile (brstProfile);
1133  }
1134 }
1135 
1138 {
1139  Ptr<WimaxConnection> connection = 0;
1140  if (cid.IsInitialRanging ())
1141  {
1142  return GetInitialRangingConnection ();
1143  }
1144  else if (cid.IsBroadcast ())
1145  {
1146  connection = GetBroadcastConnection ();
1147  }
1148  else
1149  {
1150  connection = GetConnectionManager ()->GetConnection (cid);
1151  }
1152 
1153  NS_ASSERT_MSG (connection != 0, "BS: Invalid connection=0");
1154  return connection;
1155 }
1156 
1157 void
1159 {
1160  uint16_t symbolsToAllocation = 0;
1161  std::list<OfdmUlMapIe> uplinkAllocations = m_uplinkScheduler->GetUplinkAllocations ();
1162  for (std::list<OfdmUlMapIe>::iterator iter = uplinkAllocations.begin (); iter != uplinkAllocations.end (); ++iter)
1163  {
1164  OfdmUlMapIe uplinkAllocation = *iter;
1165 
1166  if (uplinkAllocation.GetUiuc () == OfdmUlBurstProfile::UIUC_END_OF_MAP)
1167  {
1168  break;
1169  }
1170 
1171  symbolsToAllocation = uplinkAllocation.GetStartTime ();
1172  MarkUplinkAllocationStart (Seconds (symbolsToAllocation * m_symbolDuration.GetSeconds ()));
1173  MarkUplinkAllocationEnd (Seconds ((symbolsToAllocation + uplinkAllocation.GetDuration ())
1174  * m_symbolDuration.GetSeconds ()), uplinkAllocation.GetCid (), uplinkAllocation.GetUiuc ());
1175  }
1176 }
1177 
1178 void
1180 {
1182 }
1183 
1184 void
1185 BaseStationNetDevice::MarkUplinkAllocationEnd (Time allocationEndTime, Cid cid, uint8_t uiuc)
1186 {
1187  Simulator::Schedule (allocationEndTime, &BaseStationNetDevice::UplinkAllocationEnd, this, cid, uiuc);
1188 }
1189 
1190 void
1192 {
1194 
1195  NS_LOG_DEBUG ("--UL allocation " << (uint32_t) m_ulAllocationNumber << " started : "
1196  << Simulator::Now ().GetSeconds ());
1197 
1198 }
1199 
1200 void
1202 {
1203  NS_LOG_DEBUG ("--UL allocation " << (uint32_t) m_ulAllocationNumber << " ended : " << Simulator::Now ().GetSeconds ());
1204 
1205  if (m_cidFactory->IsBasic (cid))
1206  {
1207  m_linkManager->VerifyInvitedRanging (cid, uiuc);
1208  }
1209 }
1210 
1211 void
1213 {
1214  Simulator::Schedule (rangingOppStartTime, &BaseStationNetDevice::RangingOppStart, this);
1215 }
1216 
1217 void
1219 {
1221 
1222  NS_LOG_DEBUG ("Ranging TO " << (uint32_t) m_rangingOppNumber << ": " << Simulator::Now ().GetSeconds ());
1223 }
1224 
1225 } // namespace ns3
void SetUcdInterval(Time ucdInterval)
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
void SetRtg(uint16_t rtg)
keep track of time values and allow control of global simulation resolution
Definition: nstime.h:81
void SetUcdCount(uint8_t ucdCount)
Time GetIntervalT8(void) const
void SetNrDlSymbols(uint32_t dlSymbols)
Doxygen introspection did not find any typical Config paths.
Doxygen introspection did not find any typical Config paths.
Definition: mac-messages.h:412
uint16_t GetRtg(void) const
void SetEirxPIrMax(uint16_t rss_ir_max)
uint32_t GetNrDcdSent(void) const
void SetLength(uint8_t length)
void MarkRangingOppStart(Time rangingOppStartTime)
void SetBsEirp(uint16_t bs_eirp)
Doxygen introspection did not find any typical Config paths.
Definition: mac-messages.h:41
void SetRangingBackoffEnd(uint8_t rangingBackoffEnd)
Doxygen introspection did not find any typical Config paths.
Definition: mac-messages.h:458
void SetLinkManager(Ptr< BSLinkManager > linkManager)
void ForwardUp(Ptr< Packet > packet, const Mac48Address &source, const Mac48Address &dest)
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
Ptr< WimaxConnection > GetBroadcastConnection(void) const
uint32_t GetSize(void) const
Definition: packet.h:650
Ptr< BSScheduler > GetBSScheduler(void) const
Cid GetCid(void) const
TracedCallback< Ptr< const Packet > > m_bsRxTrace
The trace source fired for packets successfully received by the device immediately before being forwa...
uint8_t GetMaxRangingCorrectionRetries(void) const
#define NS_LOG_INFO(msg)
Definition: log.h:298
bool IsBroadcast(void) const
Definition: cid.cc:56
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
Definition: simulator.cc:268
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)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:824
uint8_t GetType(void) const
Definition: mac-messages.cc:56
Ptr< Packet > CreateUcd(void)
void SetChannelNr(uint8_t channelNr)
void SetMaxInvitedRangRetries(uint8_t maxInvitedRangRetries)
void SetIntervalT8(Time interval)
void SetBsClassifier(Ptr< IpcsClassifier > classifier)
void SetType(uint8_t type)
void SetLength(uint8_t length)
void UplinkAllocationEnd(Cid cid, uint8_t uiuc)
bool IsBasic(Cid cid) const
Definition: cid-factory.cc:111
void SetDiuc(uint8_t diuc)
this class implements the Generic mac Header as described by IEEE Standard for Local and metropolitan...
void SetChannelEncodings(OfdmUcdChannelEncodings channelEncodings)
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
void SetStartTime(uint16_t startTime)
uint8_t GetType(void) const
void SetPreamblePresent(uint8_t preamblePresent)
void SetFrameDurationCode(uint8_t frameDurationCode)
uint8_t GetFc(void) const
uint32_t GetNrFrames(void) const
Time GetDcdInterval(void) const
void SetSbchnlReqRegionFullParams(uint8_t sbchnlReqRegionFullParams)
void SetBaseStationId(Mac48Address baseStationID)
double GetSeconds(void) const
Definition: nstime.h:274
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:317
void SetRequestBackoffStart(uint8_t requestBackoffStart)
Ptr< Packet > CreateUlMap(void)
uint32_t GetSerializedSize(void) const
void MarkUplinkAllocationStart(Time allocationStartTime)
uint8_t GetMaxInvitedRangRetries(void) const
TracedCallback< Ptr< const Packet > > m_bsRxDropTrace
The trace source fired when packets coming into the "top" of the device are dropped at the MAC layer ...
void SetDiuc(uint8_t diuc)
bool Enqueue(Ptr< Packet > packet, const MacHeaderType &hdrType, Ptr< WimaxConnection > connection)
Enqueue a packet into a connection queue.
uint16_t GetTtg(void) const
Cid GetCid(void) const
void SetSbchnlFocContCodes(uint8_t sbchnlFocContCodes)
void SetCurrentDcd(Dcd dcd)
void SetRangReqOppSize(uint8_t rangReqOppSize)
hold objects of type ns3::Time
Definition: nstime.h:961
void SetTtg(uint16_t ttg)
TracedCallback< Ptr< const Packet > > m_bsTxDropTrace
The trace source fired when packets coming into the "top" of the device are dropped at the MAC layer ...
Time GetInitialRangingInterval(void) const
void SetFecCodeType(uint8_t fecCodeType)
static Cid InitialRanging(void)
Definition: cid.cc:82
Time GetSymbolDuration(void) const
Hold an unsigned integer type.
Definition: uinteger.h:46
void SetDcdCount(uint8_t dcdCount)
void SetUiuc(uint8_t uiuc)
Doxygen introspection did not find any typical Config paths.
void SetAllocationStartTime(uint32_t allocationStartTime)
bool IsInitialRanging(void) const
Definition: cid.cc:66
static TypeId GetTypeId(void)
void SetRangingBackoffStart(uint8_t rangingBackoffStart)
Time GetPsDuration(void) const
Ptr< UplinkScheduler > GetUplinkScheduler(void) const
void SetInitialRangingInterval(Time initialRangInterval)
Doxygen introspection did not find any typical Config paths.
uint8_t GetHt(void) const
Ptr< IpcsClassifier > GetBsClassifier(void) const
Ptr< WimaxConnection > GetInitialRangingConnection(void) const
Ptr< BandwidthManager > GetBandwidthManager(void) const
Ptr< BSLinkManager > m_linkManager
void SetBwReqOppSize(uint16_t bwReqOppSize)
void AddUlBurstProfile(OfdmUlBurstProfile ulBurstProfile)
Doxygen introspection did not find any typical Config paths.
Mac48Address GetMacAddress(void) const
Represents the HT (Header Type) field of generic MAC and bandwidth request headers.
Ptr< IpcsClassifier > m_bsClassifier
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Ptr< Packet > CreateDlMap(void)
void SetFrameNumber(uint32_t frameNumber)
#define list
Ptr< BsServiceFlowManager > GetServiceFlowManager(void) const
uint8_t GetUiuc(void) const
Ptr< Packet > Copy(void) const
Definition: packet.cc:122
void SetChannelEncodings(OfdmDcdChannelEncodings channelEncodings)
uint8_t GetBwReqOppSize(void) const
Hold together all Wimax-related objects in a NetDevice.
uint16_t GetDuration(void) const
hold objects of type Ptr
Definition: pointer.h:33
this class implements the bandwidth-request mac Header as described by IEEE Standard for Local and me...
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
void SetFrequency(uint32_t frequency)
TracedCallback< Ptr< const Packet >, Mac48Address, Cid > m_traceBSRx
Definition: cid.h:35
void AddDlBurstProfile(OfdmDlBurstProfile dlBurstProfile)
uint8_t GetRangingOppNumber(void) const
an EUI-48 address
Definition: mac48-address.h:41
void SetRangReqOppSize(uint16_t rangReqOppSize)
Ptr< BSScheduler > m_scheduler
This class implements service flows as described by the IEEE-802.16 standard.
Definition: service-flow.h:39
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Schedule an event to expire Now.
Definition: simulator.h:985
std::list< Ptr< const Packet > > FragmentsQueue
NS_LOG_COMPONENT_DEFINE("BaseStationNetDevice")
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
void SetDcdInterval(Time dcdInterval)
TracedCallback< Ptr< const Packet > > m_bsPromiscRxTrace
The trace source fired for packets successfully received by the device immediately before being forwa...
void SetPhy(Ptr< WimaxPhy > phy)
void CreateMapMessages(void)
creates the MAC management messages DL-MAP and UL-MAP
bool DoSend(Ptr< Packet > packet, const Mac48Address &source, const Mac48Address &dest, uint16_t protocolNumber)
TracedCallback< Ptr< const Packet > > m_bsTxTrace
The trace source fired when packets come into the "top" of the device at the L3/L2 transition...
Ptr< SSManager > m_ssManager
Cid GetCid(void) const
void SetUplinkScheduler(Ptr< UplinkScheduler > ulScheduler)
uint32_t GetNrDlSymbols(void) const
void DoReceive(Ptr< Packet > packet)
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
void SetDlBurstProfiles(Dcd *dcd)
Ptr< BurstProfileManager > GetBurstProfileManager(void) const
void SetFrequency(uint32_t frequency)
void SetNrFrames(uint32_t nrFrames)
uint32_t GetNrUlSymbols(void) const
void SetMaxRangingCorrectionRetries(uint8_t maxRangCorrectionRetries)
void SetConfigurationChangeCount(uint8_t ucdCount)
void SetCurrentUcd(Ucd ucd)
Doxygen introspection did not find any typical Config paths.
void ForwardDown(Ptr< PacketBurst > burst, WimaxPhy::ModulationType modulationType)
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:289
Ptr< SSManager > GetSSManager(void) const
void SetRequestBackoffEnd(uint8_t requestBackoffEnd)
void CreateDefaultConnections(void)
void MarkUplinkAllocationEnd(Time allocationEndTime, Cid cid, uint8_t uiuc)
Ptr< BsServiceFlowManager > m_serviceFlowManager
Ptr< UplinkScheduler > m_uplinkScheduler
void SetUlBurstProfiles(Ucd *ucd)
Ptr< WimaxConnection > GetConnection(Cid cid)
void SetSSManager(Ptr< SSManager > ssManager)
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:452
uint8_t GetDiuc(void) const
Time GetDlSubframeStartTime(void) const
void SetBaseStationId(Mac48Address baseStationId)
void SetState(uint8_t state)
void SetCid(Cid cid)
void InitBaseStationNetDevice(void)
initializes the BS net device and sets its parameters to the default values
void AddDlMapElement(OfdmDlMapIe dlMapElement)
void SetServiceFlowManager(Ptr< BsServiceFlowManager >)
bool check_hcs(void) const
This class is used exclusively by the BS to allocate CIDs to new connections.
Definition: cid-factory.h:45
void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
uint8_t GetHt(void) const
void SetNrUlSymbols(uint32_t ulSymbols)
virtual void SetNode(Ptr< Node > node)
Doxygen introspection did not find any typical Config paths.
Definition: mac-messages.h:262
bool IsPrimary(Cid cid) const
Definition: cid-factory.cc:105
void AddUlMapElement(OfdmUlMapIe ulMapElement)
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
Time GetUlSubframeStartTime(void) const
static Time m_frameStartTime
uint16_t GetStartTime(void) const
void SetConfigurationChangeCount(uint8_t configurationChangeCount)
uint32_t GetNrUcdSent(void) const
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:253
void SetFecCodeType(uint8_t fecCodeType)
Header for the LLC/SNAP encapsulation.
void SetLen(uint16_t len)
static uint8_t m_direction
void SetType(uint8_t type)
Ptr< Packet > CreateDcd(void)