A Discrete-Event Network Simulator
API
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 namespace ns3 {
50 
51 NS_LOG_COMPONENT_DEFINE ("BaseStationNetDevice");
52 
53 NS_OBJECT_ENSURE_REGISTERED (BaseStationNetDevice);
54 
56 {
57  static TypeId tid = TypeId ("ns3::BaseStationNetDevice")
58 
60 
61  .AddConstructor<BaseStationNetDevice> ()
62 
63  .AddAttribute ("BSScheduler",
64  "Downlink Scheduler for BS",
65  PointerValue (),
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),
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 (),
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 (),
150  MakePointerChecker<ServiceFlowManager> ())
151 
152  .AddTraceSource ("BSTx",
153  "A packet has been received from higher layers "
154  "and is being processed in preparation "
155  "for queueing for transmission.",
157  "ns3::Packet::TracedCallback")
158 
159  .AddTraceSource ("BSTxDrop",
160  "A packet has been dropped in the MAC layer "
161  "before being queued for transmission.",
163  "ns3::Packet::TracedCallback")
164 
165  .AddTraceSource ("BSPromiscRx",
166  "A packet has been received by this device, "
167  "has been passed up from the physical layer "
168  "and is being forwarded up the local protocol stack. "
169  "This is a promiscuous trace,",
171  "ns3::Packet::TracedCallback")
172 
173  .AddTraceSource ("BSRx",
174  "A packet has been received by this device, "
175  "has been passed up from the physical layer "
176  "and is being forwarded up the local protocol stack. "
177  "This is a non-promiscuous trace,",
179  "ns3::Packet::TracedCallback")
180 
181  .AddTraceSource ("BSRxDrop",
182  "A packet has been dropped in the MAC layer "
183  "after it has been passed up from the physical layer.",
185  "ns3::Packet::TracedCallback");
186  return tid;
187 }
188 
190 {
192 }
193 
194 void
196 {
197 
198  m_initialRangInterval = Seconds (0.05); // maximum is 2
199  m_dcdInterval = Seconds (3); // maximum is 10
200  m_ucdInterval = Seconds (3); // maximum is 10
201  m_intervalT8 = MilliSeconds (50); // maximum is 300 milliseconds
204  m_rangReqOppSize = 8; // 8 symbols = 2 (preamble) + 2 (RNG-REQ) + 4 (round-trip propagation time)
205  m_bwReqOppSize = 2; // 2 symbols = 1 (preamble) + 1 (bandwidth request header)
206  m_nrDlSymbols = 0;
207  m_nrUlSymbols = 0;
208  m_nrDlMapSent = 0;
209  m_nrUlMapSent = 0;
210  m_nrDcdSent = 0;
211  m_nrUcdSent = 0;
216  m_nrDlFrames = 0;
217  m_nrUlFrames = 0;
218  m_nrSsRegistered = 0;
219  m_nrDlAllocations = 0;
220  m_nrUlAllocations = 0;
224  m_rangingOppNumber = 0;
226  m_psDuration = Seconds (0);
228  m_linkManager = CreateObject<BSLinkManager> (this);
229  m_cidFactory = new CidFactory ();
230  m_ssManager = CreateObject<SSManager> ();
231  m_bsClassifier = CreateObject<IpcsClassifier> ();
232  m_serviceFlowManager = CreateObject<BsServiceFlowManager> (this);
233 
234 }
235 
237 {
239  this->SetNode (node);
240  this->SetPhy (phy);
241 }
242 
244  Ptr<WimaxPhy> phy,
245  Ptr<UplinkScheduler> uplinkScheduler,
246  Ptr<BSScheduler> bsScheduler)
247 {
249  this->SetNode (node);
250  this->SetPhy (phy);
251  m_uplinkScheduler = uplinkScheduler;
252  m_scheduler = bsScheduler;
253 }
254 
256 {
257 }
258 
259 void
261 {
262  delete m_cidFactory;
263 
264  m_linkManager = 0;
265  m_ssManager = 0;
266  m_bsClassifier = 0;
268  m_uplinkScheduler = 0;
269  m_cidFactory = 0;
270  m_ssManager = 0;
271  m_uplinkScheduler = 0;
272  m_scheduler = 0;
273 
275 }
276 
277 void
279 {
280  m_bsClassifier = bsc;
281 }
282 
285 {
286  return m_bsClassifier;
287 }
288 
289 void
291 {
292  m_initialRangInterval = initialRangInterval;
293 }
294 
295 Time
297 {
298  return m_initialRangInterval;
299 }
300 
301 void
303 {
304  m_dcdInterval = dcdInterval;
305 }
306 
307 Time
309 {
310  return m_dcdInterval;
311 }
312 
313 void
315 {
316  m_ucdInterval = ucdInterval;
317 }
318 
319 Time
321 {
322  return m_ucdInterval;
323 }
324 
325 void
327 {
328  m_intervalT8 = interval;
329 }
330 
331 Time
333 {
334  return m_intervalT8;
335 }
336 
337 void
339 {
340  m_maxRangCorrectionRetries = maxRangCorrectionRetries;
341 }
342 
343 uint8_t
345 {
347 }
348 
349 void
350 BaseStationNetDevice::SetMaxInvitedRangRetries (uint8_t maxInvitedRangRetries)
351 {
352  m_maxInvitedRangRetries = maxInvitedRangRetries;
353 }
354 
355 uint8_t
357 {
359 }
360 
361 void
363 {
364  m_rangReqOppSize = rangReqOppSize;
365 }
366 
367 uint8_t
369 {
370  return m_rangReqOppSize;
371 }
372 
373 void
375 {
376  m_bwReqOppSize = bwReqOppSize;
377 }
378 
379 uint8_t
381 {
382  return m_bwReqOppSize;
383 }
384 
385 void
387 {
388  m_nrDlSymbols = nrDlSymbols;
389 }
390 
391 uint32_t
393 {
394  return m_nrDlSymbols;
395 }
396 
397 void
399 {
400  m_nrUlSymbols = nrUlSymbols;
401 }
402 
403 uint32_t
405 {
406  return m_nrUlSymbols;
407 }
408 
409 uint32_t
411 {
412  return m_nrDcdSent;
413 }
414 
415 uint32_t
417 {
418  return m_nrUcdSent;
419 }
420 
421 Time
423 {
424  return m_dlSubframeStartTime;
425 }
426 
427 Time
429 {
430  return m_ulSubframeStartTime;
431 }
432 
433 uint8_t
435 {
436  return m_rangingOppNumber;
437 }
438 
441 {
442  return m_ssManager;
443 }
444 
445 void
447 {
448  m_ssManager = ssm;
449 }
450 
453 {
454  return m_serviceFlowManager;
455 }
456 
457 void
459 {
460  m_serviceFlowManager = sfm;
461 }
462 
465 {
466  return m_uplinkScheduler;
467 }
468 
469 void
471 {
472  m_uplinkScheduler = uls;
473 }
474 
477 {
478  return m_linkManager;
479 }
480 
481 void
483 {
484  m_linkManager = lm;
485 }
486 
487 void
489 {
490  m_scheduler = bss;
491 }
494 {
495  return m_scheduler;
496 }
497 
498 Time
500 {
501  return m_psDuration;
502 }
503 
504 Time
506 {
507  return m_symbolDuration;
508 }
509 
510 void
512 {
514  GetConnectionManager ()->SetCidFactory (m_cidFactory);
515  GetPhy ()->SetPhyParameters ();
516  GetPhy ()->SetDataRates ();
517  SetTtg (GetPhy ()->GetTtg ());
518  SetRtg (GetPhy ()->GetRtg ());
519  m_psDuration = GetPhy ()->GetPsDuration ();
520  m_symbolDuration = GetPhy ()->GetSymbolDuration ();
521  GetBandwidthManager ()->SetSubframeRatio ();
522 
524  GetPhy ()->SetSimplex (m_linkManager->SelectDlChannel ());
526 
527  /* shall actually be 2 symbols = 1 (preamble) + 1 (bandwidth request header)*/
528  m_bwReqOppSize = 6;
529  m_uplinkScheduler->InitOnce ();
530 }
531 
532 void
534 {
535 }
536 
537 void
539 {
540  //setting DL/UL subframe allocation for this frame
541  uint32_t symbolsPerFrame = GetPhy ()->GetSymbolsPerFrame ();
542  SetNrDlSymbols ((symbolsPerFrame / 2) - static_cast<uint32_t> (std::ceil (GetTtg ()*m_psDuration.GetSeconds ()/m_symbolDuration.GetSeconds ())));
543  SetNrUlSymbols ((symbolsPerFrame / 2) - static_cast<uint32_t> (std::ceil (GetRtg ()*m_psDuration.GetSeconds ()/m_symbolDuration.GetSeconds ())));
544 
546 
547  NS_LOG_INFO ("----------------------frame" << GetNrFrames () + 1 << "----------------------");
548 
549  StartDlSubFrame ();
550 }
551 
552 void
554 {
555  m_dlSubframeStartTime = Simulator::Now (); // same as m_frameStartTime
556 
557  NS_LOG_DEBUG ("DL frame started : " << m_frameStartTime.GetSeconds ());
558 
559  SetNrFrames (GetNrFrames () + 1);
562  m_uplinkScheduler->Schedule ();
564  m_scheduler->Schedule ();
565  SendBursts ();
568  this);
569 }
570 
571 void
573 {
574  m_nrDlFrames++;
577 }
578 
579 void
581 {
583 
584  NS_LOG_INFO ("UL frame started : " << m_ulSubframeStartTime.GetSeconds ());
585 
591  this);
592 }
593 
594 void
596 {
597  m_nrUlFrames++;
600 }
601 
602 void
604 {
605  StartFrame ();
606 }
607 
608 bool
610  const Mac48Address &source,
611  const Mac48Address &dest,
612  uint16_t protocolNumber)
613 {
614  Ptr<PacketBurst> burst = Create<PacketBurst> ();
615  ServiceFlow *serviceFlow = 0;
616 
617  NS_LOG_INFO ("BS (" << source << "):");
618  NS_LOG_INFO ("\tSending packet...");
619  NS_LOG_INFO ("\t\tDestination: " << dest);
620  NS_LOG_INFO ("\t\tPaket Size: " << packet->GetSize ());
621  NS_LOG_INFO ("\t\tProtocol: " << protocolNumber);
622 
623 
624  if (protocolNumber == 2048)
625  {
626  serviceFlow = m_bsClassifier->Classify (packet, GetServiceFlowManager (), ServiceFlow::SF_DIRECTION_DOWN);
627  }
628 
629  if (protocolNumber != 2048 || serviceFlow == 0)
630  {
631  serviceFlow = *GetServiceFlowManager ()->GetServiceFlows (ServiceFlow::SF_TYPE_ALL).begin ();
632  }
633 
634  if (serviceFlow == 0)
635  {
636  NS_LOG_INFO ("No Service Flow!!");
637  m_bsTxDropTrace (packet);
638  return false;
639  }
640  if (serviceFlow->GetIsEnabled ())
641  {
642  if (!Enqueue (packet, MacHeaderType (), serviceFlow->GetConnection ()))
643  {
644  NS_LOG_INFO ("Enqueue Error!!");
645  m_bsTxDropTrace (packet);
646  return false;
647  }
648  }
649  else
650  {
651  m_bsTxDropTrace (packet);
652  NS_LOG_INFO ("Service Flow is not enabled");
653  return false;
654  }
655  m_bsTxTrace (packet);
656 
657  return true;
658 }
659 
660 bool
662 {
663  NS_ASSERT_MSG (connection != 0,
664  "BS: Can not enqueue packet on the selected connection: the connection is not initialized");
665 
666  GenericMacHeader hdr;
667  hdr.SetLen (packet->GetSize () + hdr.GetSerializedSize ());
668 
669  hdr.SetCid (connection->GetCid ());
670 
671  return connection->Enqueue (packet, hdrType, hdr);
672 }
673 
674 void
676 {
677  GenericMacHeader gnrcMacHdr;
678  BandwidthRequestHeader bwRequestHdr;
679  ManagementMessageType msgType;
680  RngReq rngReq;
681  Cid cid;
682  uint8_t type = 0;
683  GrantManagementSubheader grantMgmntSubhdr;
684  Mac48Address source;
685  LlcSnapHeader llc;
686  Ptr<WimaxConnection> connection = 0;
687  FragmentationSubheader fragSubhdr;
688  bool fragmentation = false; // it becames true when there is a fragmentation subheader
689 
690  packet->RemoveHeader (gnrcMacHdr);
691  if (gnrcMacHdr.GetHt () == MacHeaderType::HEADER_TYPE_GENERIC)
692  {
693  if (gnrcMacHdr.check_hcs () == false)
694  {
695  // The header is noisy
696  m_bsRxDropTrace (packet);
697  NS_LOG_INFO ("Header HCS ERROR");
698  return;
699  }
700 
701  cid = gnrcMacHdr.GetCid ();
702 
703  // checking for subheaders (only grant management subheader is implemented)
704  type = gnrcMacHdr.GetType ();
705  if (type)
706  {
707  // checking 1st bit, see Table 6
708  if (type & 1)
709  {
710  packet->RemoveHeader (grantMgmntSubhdr);
711  }
712  // Check if there is a fragmentation Subheader
713  uint8_t tmpType = type;
714  if (((tmpType >> 2) & 1) == 1)
715  {
716  // a TRANSPORT packet with fragmentation subheader has been received!
717  NS_LOG_INFO ("FRAG_DEBUG: DoReceive -> the packet is a fragment" << std::endl);
718  fragmentation = true;
719  }
720  }
721 
722  if (cid.IsInitialRanging ()) // initial ranging connection
723  {
724  packet->RemoveHeader (msgType);
725  switch (msgType.GetType ())
726  {
728  {
729  packet->RemoveHeader (rngReq);
730  m_linkManager->ProcessRangingRequest (cid, rngReq);
731  break;
732  }
734  // from other base station, ignore
735  break;
736  default:
737  NS_FATAL_ERROR ("Invalid message type");
738  }
739  }
740  else if (m_cidFactory->IsBasic (cid)) // basic management connection
741  {
742  source = m_ssManager->GetMacAddress (cid);
743  m_traceBSRx (packet, source, cid);
744  packet->RemoveHeader (msgType);
745  switch (msgType.GetType ())
746  {
748  {
749  packet->RemoveHeader (rngReq);
750  m_linkManager->ProcessRangingRequest (cid, rngReq);
751  break;
752  }
754  // from other base station, ignore
755  break;
756  default:
757  NS_FATAL_ERROR ("Invalid message type");
758  }
759  }
760  else if (m_cidFactory->IsPrimary (cid)) // primary management connection
761  {
762  source = m_ssManager->GetMacAddress (cid);
763  m_traceBSRx (packet, source, cid);
764  packet->RemoveHeader (msgType);
765  switch (msgType.GetType ())
766  {
768  // not yet implemented
769  break;
771  // from other base station, ignore
772  break;
774  {
775  DsaReq dsaReq;
776  packet->RemoveHeader (dsaReq);
777  GetServiceFlowManager ()->AllocateServiceFlows (dsaReq, cid);
778  break;
779  }
781 
782  /*from other base station, as DSA initiated
783  from BS is not supported, ignore*/
784  break;
786  {
787  Simulator::Cancel (GetServiceFlowManager ()->GetDsaAckTimeoutEvent ());
788  DsaAck dsaAck;
789  packet->RemoveHeader (dsaAck);
790  GetServiceFlowManager ()->ProcessDsaAck (dsaAck, cid);
791  break;
792  }
793  default:
794  NS_FATAL_ERROR ("Invalid message type");
795  }
796  }
797  else if (cid.IsBroadcast ()) // broadcast connection
798  {
799  // from other base station, ignore
800  // or perhaps data packet (using other protocol) for BS, handle later
801  return;
802  }
803  else // transport connection
804  {
805  // If fragmentation is true, the packet is a fragment.
806  Ptr<Packet> C_Packet = packet->Copy ();
807  if (!fragmentation)
808  {
809  C_Packet->RemoveHeader (llc);
810  source = m_ssManager->GetMacAddress (cid);
811  m_bsRxTrace (packet);
812  ForwardUp (packet->Copy (), source, Mac48Address ("ff:ff:ff:ff:ff:ff"));
813  }
814  else
815  {
816  NS_LOG_INFO ( "FRAG_DEBUG: BS DoReceive, the Packet is a fragment" << std::endl);
817  packet->RemoveHeader (fragSubhdr);
818  uint32_t fc = fragSubhdr.GetFc ();
819  NS_LOG_INFO ("\t fragment size = " << packet->GetSize () << std::endl);
820  if (fc == 2)
821  {
822  // This is the latest fragment.
823  // Take the fragment queue, defragment a packet and send it to the upper layer
824  NS_LOG_INFO ("\t Received the latest fragment" << std::endl);
825  GetConnectionManager ()->GetConnection (cid)
826  ->FragmentEnqueue (packet);
828  GetConnection (cid)->GetFragmentsQueue ();
829  Ptr<Packet> fullPacket = Create<Packet> ();
830 
831  // DEFRAGMENTATION
832  NS_LOG_INFO ("\t BS PACKET DEFRAGMENTATION" << std::endl);
833  for (std::list<Ptr<const Packet> >::const_iterator iter = fragmentsQueue.begin ();
834  iter != fragmentsQueue.end (); ++iter)
835  {
836  // Create the whole Packet
837  fullPacket->AddAtEnd (*iter);
838  }
839  GetConnectionManager ()->GetConnection (cid)
840  ->ClearFragmentsQueue ();
841 
842  NS_LOG_INFO ("\t fullPacket size = " << fullPacket->GetSize () << std::endl);
843  source = m_ssManager->GetMacAddress (cid);
844  m_bsRxTrace (fullPacket);
845  ForwardUp (fullPacket->Copy (), source, Mac48Address ("ff:ff:ff:ff:ff:ff"));
846  }
847  else
848  {
849  // This is the first or middle fragment.
850  // Take the fragment queue, store the fragment into the queue
851  NS_LOG_INFO ("\t Received the first or the middle fragment" << std::endl);
852  GetConnectionManager ()->GetConnection (cid)
853  ->FragmentEnqueue (packet);
854  }
855  }
856  }
857  }
858  else
859  {
860  // bandwidth request header
861  packet->AddHeader (gnrcMacHdr);
862  packet->RemoveHeader (bwRequestHdr);
864  "A bandwidth request should be carried by a bandwidth header type");
865  if (bwRequestHdr.check_hcs () == false)
866  {
867  // The header is noisy
868  NS_LOG_INFO ("BS:Header HCS ERROR");
869  return;
870  }
871  cid = bwRequestHdr.GetCid ();
872  source = m_ssManager->GetMacAddress (cid);
873  m_traceBSRx (packet, source, cid);
874  GetBandwidthManager ()->ProcessBandwidthRequest (bwRequestHdr);
875  }
876 
877 }
878 
879 void
881 {
882  Ptr<Packet> dlmap, ulmap;
883  bool sendDcd = false, sendUcd = false, updateDcd = false, updateUcd = false;
884 
885  uint16_t currentNrSsRegistered = m_ssManager->GetNRegisteredSSs ();
886 
887  if (m_nrSsRegistered == currentNrSsRegistered)
888  {
889  m_uplinkScheduler->GetChannelDescriptorsToUpdate (updateDcd, updateUcd, sendDcd, sendUcd);
890  }
891  else
892  {
893  sendDcd = sendUcd = true;
894  }
895 
896  m_nrSsRegistered = currentNrSsRegistered;
897 
898  /*either DCD and UCD must be created first because CCC is set during their
899  creation, or CCC must be calculated first so that it could be set during
900  creation of DL-MAP and UL-MAP and then set duirng creation of DCD and UCD*/
901 
902  if (sendDcd)
903  {
904  m_dcdConfigChangeCount += 1 % 256;
905  }
906 
907  if (sendUcd)
908  {
909  m_ucdConfigChangeCount += 1 % 256;
910  }
911 
912  dlmap = CreateDlMap ();
914  m_nrDlMapSent++;
915 
916  ulmap = CreateUlMap ();
918  m_nrUlMapSent++;
919 
920  CreateDescriptorMessages (sendDcd, sendUcd);
921 }
922 
923 void
925 {
926  Ptr<Packet> dcd, ucd;
927 
928  if (sendDcd)
929  {
930  dcd = CreateDcd ();
932  m_nrDcdSent++;
934  }
935  else
936  {
938  }
939 
940  if (sendUcd)
941  {
942  ucd = CreateUcd ();
944  m_nrUcdSent++;
946  }
947  else
948  {
950  }
951 }
952 
953 /*
954  Sends bursts in the downlink subframe. i.e., creates the downlink subframe. The first burst
955  is broadcast burst with MAC management messages. The rest of the bursts contain data packets.
956  */
957 void
959 {
960  Time txTime = Seconds (0);
961  std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > pair;
963  std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > > *downlinkBursts = m_scheduler->GetDownlinkBursts ();
964  Ptr<PacketBurst> burst;
965  OfdmDlMapIe *dlMapIe;
966  Cid cid;
967 
968  while (downlinkBursts->size ())
969  {
970  pair = downlinkBursts->front ();
971  burst = pair.second;
972  dlMapIe = pair.first;
973  cid = dlMapIe->GetCid ();
974  uint8_t diuc = dlMapIe->GetDiuc ();
975 
976  if (cid != GetInitialRangingConnection ()->GetCid () && cid != GetBroadcastConnection ()->GetCid ())
977  {
978  if (m_serviceFlowManager->GetServiceFlow (cid) != 0)
979  {
980  modulationType = GetBurstProfileManager ()->GetModulationType (diuc, WimaxNetDevice::DIRECTION_DOWNLINK);
981  }
982  else
983  {
984  modulationType = GetBurstProfileManager ()->GetModulationType (diuc, WimaxNetDevice::DIRECTION_DOWNLINK);
985  }
986  }
987  else
988  {
989  modulationType = WimaxPhy::MODULATION_TYPE_BPSK_12;
990  }
991 
992  Simulator::Schedule (txTime, &WimaxNetDevice::ForwardDown, this, burst, modulationType);
993  txTime += GetPhy ()->GetTransmissionTime (burst->GetSize (), modulationType);
994  downlinkBursts->pop_front ();
995  delete dlMapIe;
996  }
997 }
998 
1001 {
1002  m_nrDlAllocations = 0;
1003 
1004  DlMap dlmap;
1006  dlmap.SetBaseStationId (GetMacAddress ());
1007 
1008  std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > > *downlinkBursts = m_scheduler->GetDownlinkBursts ();
1009 
1010  for (std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > >::iterator iter = downlinkBursts->begin (); iter
1011  != downlinkBursts->end (); ++iter)
1012  {
1013  iter->first->SetPreamblePresent (0);
1014  iter->first->SetStartTime (0);
1015  dlmap.AddDlMapElement (*(iter->first));
1016  }
1017 
1018  OfdmDlMapIe dlMapIeEnd;
1019 
1020  dlMapIeEnd.SetCid (Cid::InitialRanging ());
1022  dlMapIeEnd.SetPreamblePresent (0);
1023  dlMapIeEnd.SetStartTime (0);
1024 
1025  dlmap.AddDlMapElement (dlMapIeEnd);
1026  m_nrDlAllocations = downlinkBursts->size ();
1027 
1028  Ptr<Packet> p = Create<Packet> ();
1029  p->AddHeader (dlmap);
1031  return p;
1032 }
1033 
1036 {
1037  Dcd dcd;
1038  OfdmDcdChannelEncodings chnlEncodings;
1039 
1040  chnlEncodings.SetBsEirp (0);
1041  chnlEncodings.SetEirxPIrMax (0);
1042  chnlEncodings.SetFrequency (GetPhy ()->GetFrequency ());
1043  chnlEncodings.SetChannelNr (0);
1044  chnlEncodings.SetTtg (GetTtg ());
1045  chnlEncodings.SetRtg (GetRtg ());
1046  chnlEncodings.SetBaseStationId (GetMacAddress ());
1047  chnlEncodings.SetFrameDurationCode (GetPhy ()->GetFrameDurationCode ());
1048  chnlEncodings.SetFrameNumber (GetNrFrames ());
1049 
1051  dcd.SetChannelEncodings (chnlEncodings);
1052 
1053  SetDlBurstProfiles (&dcd);
1054  SetCurrentDcd (dcd);
1055 
1056  Ptr<Packet> p = Create<Packet> ();
1057  p->AddHeader (dcd);
1059  return p;
1060 }
1061 
1064 {
1066  m_rangingOppNumber = 0;
1067  m_nrUlAllocations = 0;
1068 
1069  UlMap ulmap;
1071  ulmap.SetAllocationStartTime (m_uplinkScheduler->CalculateAllocationStartTime ());
1072 
1073  std::list<OfdmUlMapIe> uplinkAllocations = m_uplinkScheduler->GetUplinkAllocations ();
1074 
1075  for (std::list<OfdmUlMapIe>::iterator iter = uplinkAllocations.begin (); iter != uplinkAllocations.end (); ++iter)
1076  {
1077  ulmap.AddUlMapElement (*iter);
1078  }
1079 
1080  m_nrUlAllocations = uplinkAllocations.size ();
1081 
1082  Ptr<Packet> p = Create<Packet> ();
1083  p->AddHeader (ulmap);
1085  return p;
1086 }
1087 
1090 {
1091  Ucd ucd;
1093  ucd.SetRangingBackoffStart (3); // setting to 7. i.e., 2^3 = 8 -> 0-7
1094  ucd.SetRangingBackoffEnd (6); // setting to 63. i.e., 2^6 = 64 -> 0-63
1095  ucd.SetRequestBackoffStart (3);
1096  ucd.SetRequestBackoffEnd (6);
1097 
1098  OfdmUcdChannelEncodings chnlEncodings;
1099 
1100  chnlEncodings.SetBwReqOppSize (m_bwReqOppSize * GetPhy ()->GetPsPerSymbol ());
1101  chnlEncodings.SetRangReqOppSize (m_rangReqOppSize * GetPhy ()->GetPsPerSymbol ());
1102 
1103  chnlEncodings.SetFrequency (GetPhy ()->GetFrequency ());
1104  chnlEncodings.SetSbchnlReqRegionFullParams (0);
1105  chnlEncodings.SetSbchnlFocContCodes (0);
1106 
1107  ucd.SetChannelEncodings (chnlEncodings);
1108 
1109  SetUlBurstProfiles (&ucd);
1110  SetCurrentUcd (ucd);
1111 
1112  Ptr<Packet> p = Create<Packet> ();
1113  p->AddHeader (ucd);
1115  return p;
1116 }
1117 
1118 void
1120 {
1121  for (int i = 0; i < GetBurstProfileManager ()->GetNrBurstProfilesToDefine (); ++i)
1122  {
1123  OfdmDlBurstProfile brstProfile;
1124  brstProfile.SetType (0);
1125  brstProfile.SetLength (0);
1126  brstProfile.SetDiuc (i + 1); // DIUC will be between 1-11, see Table 237
1127  brstProfile.SetFecCodeType (i);
1128  dcd->AddDlBurstProfile (brstProfile);
1129  }
1130 }
1131 
1132 void
1134 {
1135  for (int i = 0; i < GetBurstProfileManager ()->GetNrBurstProfilesToDefine (); ++i)
1136  {
1137  OfdmUlBurstProfile brstProfile;
1138  brstProfile.SetType (0);
1139  brstProfile.SetLength (0);
1140  // UIUC will be between 5-12, see Table 246. UIUC 1 (initial ranging) is not included
1141  brstProfile.SetUiuc (i + 5);
1142  brstProfile.SetFecCodeType (i);
1143 
1144  ucd->AddUlBurstProfile (brstProfile);
1145  }
1146 }
1147 
1150 {
1151  Ptr<WimaxConnection> connection = 0;
1152  if (cid.IsInitialRanging ())
1153  {
1154  return GetInitialRangingConnection ();
1155  }
1156  else if (cid.IsBroadcast ())
1157  {
1158  connection = GetBroadcastConnection ();
1159  }
1160  else
1161  {
1162  connection = GetConnectionManager ()->GetConnection (cid);
1163  }
1164 
1165  NS_ASSERT_MSG (connection != 0, "BS: Invalid connection=0");
1166  return connection;
1167 }
1168 
1169 void
1171 {
1172  uint16_t symbolsToAllocation = 0;
1173  std::list<OfdmUlMapIe> uplinkAllocations = m_uplinkScheduler->GetUplinkAllocations ();
1174  for (std::list<OfdmUlMapIe>::iterator iter = uplinkAllocations.begin (); iter != uplinkAllocations.end (); ++iter)
1175  {
1176  OfdmUlMapIe uplinkAllocation = *iter;
1177 
1178  if (uplinkAllocation.GetUiuc () == OfdmUlBurstProfile::UIUC_END_OF_MAP)
1179  {
1180  break;
1181  }
1182 
1183  symbolsToAllocation = uplinkAllocation.GetStartTime ();
1184  MarkUplinkAllocationStart (Seconds (symbolsToAllocation * m_symbolDuration.GetSeconds ()));
1185  MarkUplinkAllocationEnd (Seconds ((symbolsToAllocation + uplinkAllocation.GetDuration ())
1186  * m_symbolDuration.GetSeconds ()), uplinkAllocation.GetCid (), uplinkAllocation.GetUiuc ());
1187  }
1188 }
1189 
1190 void
1192 {
1194 }
1195 
1196 void
1197 BaseStationNetDevice::MarkUplinkAllocationEnd (Time allocationEndTime, Cid cid, uint8_t uiuc)
1198 {
1199  Simulator::Schedule (allocationEndTime, &BaseStationNetDevice::UplinkAllocationEnd, this, cid, uiuc);
1200 }
1201 
1202 void
1204 {
1206 
1207  NS_LOG_DEBUG ("--UL allocation " << (uint32_t) m_ulAllocationNumber << " started : "
1208  << Simulator::Now ().GetSeconds ());
1209 
1210 }
1211 
1212 void
1214 {
1215  NS_LOG_DEBUG ("--UL allocation " << (uint32_t) m_ulAllocationNumber << " ended : " << Simulator::Now ().GetSeconds ());
1216 
1217  if (m_cidFactory->IsBasic (cid))
1218  {
1219  m_linkManager->VerifyInvitedRanging (cid, uiuc);
1220  }
1221 }
1222 
1223 void
1225 {
1226  Simulator::Schedule (rangingOppStartTime, &BaseStationNetDevice::RangingOppStart, this);
1227 }
1228 
1229 void
1231 {
1233 
1234  NS_LOG_DEBUG ("Ranging TO " << (uint32_t) m_rangingOppNumber << ": " << Simulator::Now ().GetSeconds ());
1235 }
1236 
1237 } // 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)
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:95
void SetUcdCount(uint8_t ucdCount)
Time GetIntervalT8(void) const
void SetNrDlSymbols(uint32_t dlSymbols)
Introspection did not find any typical Config paths.
Introspection did not find any typical Config paths.
Definition: mac-messages.h:430
uint16_t GetRtg(void) const
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
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)
Introspection did not find any typical Config paths.
Definition: mac-messages.h:41
void SetRangingBackoffEnd(uint8_t rangingBackoffEnd)
Introspection did not find any typical Config paths.
Definition: mac-messages.h:476
void SetLinkManager(Ptr< BSLinkManager > linkManager)
void ForwardUp(Ptr< Packet > packet, const Mac48Address &source, const Mac48Address &dest)
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:867
Ptr< WimaxConnection > GetBroadcastConnection(void) const
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:766
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)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
bool IsBroadcast(void) const
Definition: cid.cc:56
#define NS_FATAL_ERROR(msg)
Fatal error handling.
Definition: fatal-error.h:100
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:311
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:819
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)
void SetStartTime(uint16_t startTime)
uint8_t GetType(void) const
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:439
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
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:327
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.
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: pointer.h:210
uint16_t GetTtg(void) const
Cid GetCid(void) const
void SetSbchnlFocContCodes(uint8_t sbchnlFocContCodes)
void SetCurrentDcd(Dcd dcd)
void SetRangReqOppSize(uint8_t rangReqOppSize)
AttributeValue implementation for Time.
Definition: nstime.h:921
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:44
void SetDcdCount(uint8_t dcdCount)
void SetUiuc(uint8_t uiuc)
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)
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)
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)
Destructor implementation.
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
performs a COW copy of the packet.
Definition: packet.cc:122
void SetChannelEncodings(OfdmDcdChannelEncodings channelEncodings)
uint8_t GetBwReqOppSize(void) const
Hold together all Wimax-related objects in a NetDevice.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint16_t GetDuration(void) const
Hold objects of type Ptr.
Definition: pointer.h:36
this class implements the bandwidth-request mac Header as described by IEEE Standard for Local and me...
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:43
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:980
std::list< Ptr< const Packet > > FragmentsQueue
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:922
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:223
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)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:84
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)
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)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
Ptr< SSManager > GetSSManager(void) const
void SetRequestBackoffEnd(uint8_t requestBackoffEnd)
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:859
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)
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)
Destructor implementation.
uint8_t GetHt(void) const
void SetNrUlSymbols(uint32_t ulSymbols)
virtual void SetNode(Ptr< Node > node)
Introspection did not find any typical Config paths.
Definition: mac-messages.h:262
bool IsPrimary(Cid cid) const
Definition: cid-factory.cc:105
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
void AddUlMapElement(OfdmUlMapIe ulMapElement)
a unique identifier for an interface.
Definition: type-id.h:51
TypeId SetParent(TypeId tid)
Definition: type-id.cc:631
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)