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  .SetGroupName("Wimax")
62 
63  .AddConstructor<BaseStationNetDevice> ()
64 
65  .AddAttribute ("BSScheduler",
66  "Downlink Scheduler for BS",
67  PointerValue (),
69  MakePointerChecker<BSScheduler> ())
70 
71  .AddAttribute ("InitialRangInterval",
72  "Time between Initial Ranging regions assigned by the BS. Maximum is 2s",
73  TimeValue (Seconds (0.05)),
76  MakeTimeChecker ())
77 
78  .AddAttribute ("DcdInterval",
79  "Time between transmission of DCD messages. Maximum value is 10s.",
80  TimeValue (Seconds (3)),
82  MakeTimeChecker ())
83 
84  .AddAttribute ("UcdInterval",
85  "Time between transmission of UCD messages. Maximum value is 10s.",
86  TimeValue (Seconds (3)),
88  MakeTimeChecker ())
89 
90  .AddAttribute ("IntervalT8",
91  "Wait for DSA/DSC Acknowledge timeout. Maximum 300ms.",
92  TimeValue (Seconds (0.05)),
94  MakeTimeChecker ())
95 
96  .AddAttribute ("RangReqOppSize",
97  "The ranging opportunity size in symbols",
98  UintegerValue (8),
101  MakeUintegerChecker<uint8_t> (1, 256))
102 
103  .AddAttribute ("BwReqOppSize",
104  "The bandwidth request opportunity size in symbols",
105  UintegerValue (2),
107  MakeUintegerChecker<uint8_t> (1, 256))
108 
109  .AddAttribute ("MaxRangCorrectionRetries",
110  "Number of retries on contention Ranging Requests",
111  UintegerValue (16),
114  MakeUintegerChecker<uint8_t> (1, 16))
115 
116  .AddAttribute ("SSManager",
117  "The ss manager attached to this device.",
118  PointerValue (),
120  MakePointerChecker<SSManager> ())
121 
122  .AddAttribute ("Scheduler",
123  "The BS scheduler attached to this device.",
124  PointerValue (),
126  MakePointerChecker<BSScheduler> ())
127 
128  .AddAttribute ("LinkManager",
129  "The link manager attached to this device.",
130  PointerValue (),
132  MakePointerChecker<BSLinkManager> ())
133 
134  .AddAttribute ("UplinkScheduler",
135  "The uplink scheduler attached to this device.",
136  PointerValue (),
139  MakePointerChecker<UplinkScheduler> ())
140 
141  .AddAttribute ("BsIpcsPacketClassifier",
142  "The uplink IP packet classifier attached to this device.",
143  PointerValue (),
145  MakePointerChecker<IpcsClassifier> ())
146 
147  .AddAttribute ("ServiceFlowManager",
148  "The service flow manager attached to this device.",
149  PointerValue (),
152  MakePointerChecker<ServiceFlowManager> ())
153 
154  .AddTraceSource ("BSTx",
155  "A packet has been received from higher layers "
156  "and is being processed in preparation "
157  "for queueing for transmission.",
159  "ns3::Packet::TracedCallback")
160 
161  .AddTraceSource ("BSTxDrop",
162  "A packet has been dropped in the MAC layer "
163  "before being queued for transmission.",
165  "ns3::Packet::TracedCallback")
166 
167  .AddTraceSource ("BSPromiscRx",
168  "A packet has been received by this device, "
169  "has been passed up from the physical layer "
170  "and is being forwarded up the local protocol stack. "
171  "This is a promiscuous trace,",
173  "ns3::Packet::TracedCallback")
174 
175  .AddTraceSource ("BSRx",
176  "A packet has been received by this device, "
177  "has been passed up from the physical layer "
178  "and is being forwarded up the local protocol stack. "
179  "This is a non-promiscuous trace,",
181  "ns3::Packet::TracedCallback")
182 
183  .AddTraceSource ("BSRxDrop",
184  "A packet has been dropped in the MAC layer "
185  "after it has been passed up from the physical layer.",
187  "ns3::Packet::TracedCallback");
188  return tid;
189 }
190 
192 {
194 }
195 
196 void
198 {
199 
200  m_initialRangInterval = Seconds (0.05); // maximum is 2
201  m_dcdInterval = Seconds (3); // maximum is 10
202  m_ucdInterval = Seconds (3); // maximum is 10
203  m_intervalT8 = MilliSeconds (50); // maximum is 300 milliseconds
206  m_rangReqOppSize = 8; // 8 symbols = 2 (preamble) + 2 (RNG-REQ) + 4 (round-trip propagation time)
207  m_bwReqOppSize = 2; // 2 symbols = 1 (preamble) + 1 (bandwidth request header)
208  m_nrDlSymbols = 0;
209  m_nrUlSymbols = 0;
210  m_nrDlMapSent = 0;
211  m_nrUlMapSent = 0;
212  m_nrDcdSent = 0;
213  m_nrUcdSent = 0;
218  m_nrDlFrames = 0;
219  m_nrUlFrames = 0;
220  m_nrSsRegistered = 0;
221  m_nrDlAllocations = 0;
222  m_nrUlAllocations = 0;
226  m_rangingOppNumber = 0;
228  m_psDuration = Seconds (0);
230  m_linkManager = CreateObject<BSLinkManager> (this);
231  m_cidFactory = new CidFactory ();
232  m_ssManager = CreateObject<SSManager> ();
233  m_bsClassifier = CreateObject<IpcsClassifier> ();
234  m_serviceFlowManager = CreateObject<BsServiceFlowManager> (this);
235 
236 }
237 
239 {
241  this->SetNode (node);
242  this->SetPhy (phy);
243 }
244 
247  Ptr<UplinkScheduler> uplinkScheduler,
248  Ptr<BSScheduler> bsScheduler)
249 {
251  this->SetNode (node);
252  this->SetPhy (phy);
253  m_uplinkScheduler = uplinkScheduler;
254  m_scheduler = bsScheduler;
255 }
256 
258 {
259 }
260 
261 void
263 {
264  delete m_cidFactory;
265 
266  m_linkManager = 0;
267  m_ssManager = 0;
268  m_bsClassifier = 0;
270  m_uplinkScheduler = 0;
271  m_cidFactory = 0;
272  m_ssManager = 0;
273  m_uplinkScheduler = 0;
274  m_scheduler = 0;
275 
277 }
278 
279 void
281 {
282  m_bsClassifier = bsc;
283 }
284 
287 {
288  return m_bsClassifier;
289 }
290 
291 void
293 {
294  m_initialRangInterval = initialRangInterval;
295 }
296 
297 Time
299 {
300  return m_initialRangInterval;
301 }
302 
303 void
305 {
306  m_dcdInterval = dcdInterval;
307 }
308 
309 Time
311 {
312  return m_dcdInterval;
313 }
314 
315 void
317 {
318  m_ucdInterval = ucdInterval;
319 }
320 
321 Time
323 {
324  return m_ucdInterval;
325 }
326 
327 void
329 {
330  m_intervalT8 = interval;
331 }
332 
333 Time
335 {
336  return m_intervalT8;
337 }
338 
339 void
341 {
342  m_maxRangCorrectionRetries = maxRangCorrectionRetries;
343 }
344 
345 uint8_t
347 {
349 }
350 
351 void
352 BaseStationNetDevice::SetMaxInvitedRangRetries (uint8_t maxInvitedRangRetries)
353 {
354  m_maxInvitedRangRetries = maxInvitedRangRetries;
355 }
356 
357 uint8_t
359 {
361 }
362 
363 void
365 {
366  m_rangReqOppSize = rangReqOppSize;
367 }
368 
369 uint8_t
371 {
372  return m_rangReqOppSize;
373 }
374 
375 void
377 {
378  m_bwReqOppSize = bwReqOppSize;
379 }
380 
381 uint8_t
383 {
384  return m_bwReqOppSize;
385 }
386 
387 void
389 {
390  m_nrDlSymbols = nrDlSymbols;
391 }
392 
393 uint32_t
395 {
396  return m_nrDlSymbols;
397 }
398 
399 void
401 {
402  m_nrUlSymbols = nrUlSymbols;
403 }
404 
405 uint32_t
407 {
408  return m_nrUlSymbols;
409 }
410 
411 uint32_t
413 {
414  return m_nrDcdSent;
415 }
416 
417 uint32_t
419 {
420  return m_nrUcdSent;
421 }
422 
423 Time
425 {
426  return m_dlSubframeStartTime;
427 }
428 
429 Time
431 {
432  return m_ulSubframeStartTime;
433 }
434 
435 uint8_t
437 {
438  return m_rangingOppNumber;
439 }
440 
443 {
444  return m_ssManager;
445 }
446 
447 void
449 {
450  m_ssManager = ssm;
451 }
452 
455 {
456  return m_serviceFlowManager;
457 }
458 
459 void
461 {
462  m_serviceFlowManager = sfm;
463 }
464 
467 {
468  return m_uplinkScheduler;
469 }
470 
471 void
473 {
474  m_uplinkScheduler = uls;
475 }
476 
479 {
480  return m_linkManager;
481 }
482 
483 void
485 {
486  m_linkManager = lm;
487 }
488 
489 void
491 {
492  m_scheduler = bss;
493 }
496 {
497  return m_scheduler;
498 }
499 
500 Time
502 {
503  return m_psDuration;
504 }
505 
506 Time
508 {
509  return m_symbolDuration;
510 }
511 
512 void
514 {
516  GetConnectionManager ()->SetCidFactory (m_cidFactory);
517  GetPhy ()->SetPhyParameters ();
518  GetPhy ()->SetDataRates ();
519  SetTtg (GetPhy ()->GetTtg ());
520  SetRtg (GetPhy ()->GetRtg ());
521  m_psDuration = GetPhy ()->GetPsDuration ();
522  m_symbolDuration = GetPhy ()->GetSymbolDuration ();
523  GetBandwidthManager ()->SetSubframeRatio ();
524 
526  GetPhy ()->SetSimplex (m_linkManager->SelectDlChannel ());
528 
529  /* shall actually be 2 symbols = 1 (preamble) + 1 (bandwidth request header)*/
530  m_bwReqOppSize = 6;
531  m_uplinkScheduler->InitOnce ();
532 }
533 
534 void
536 {
537 }
538 
539 void
541 {
542  //setting DL/UL subframe allocation for this frame
543  uint32_t symbolsPerFrame = GetPhy ()->GetSymbolsPerFrame ();
544  SetNrDlSymbols ((symbolsPerFrame / 2) - static_cast<uint32_t> (std::ceil (GetTtg ()*m_psDuration.GetSeconds ()/m_symbolDuration.GetSeconds ())));
545  SetNrUlSymbols ((symbolsPerFrame / 2) - static_cast<uint32_t> (std::ceil (GetRtg ()*m_psDuration.GetSeconds ()/m_symbolDuration.GetSeconds ())));
546 
548 
549  NS_LOG_INFO ("----------------------frame" << GetNrFrames () + 1 << "----------------------");
550 
551  StartDlSubFrame ();
552 }
553 
554 void
556 {
557  m_dlSubframeStartTime = Simulator::Now (); // same as m_frameStartTime
558 
559  NS_LOG_DEBUG ("DL frame started : " << m_frameStartTime.GetSeconds ());
560 
561  SetNrFrames (GetNrFrames () + 1);
564  m_uplinkScheduler->Schedule ();
566  m_scheduler->Schedule ();
567  SendBursts ();
570  this);
571 }
572 
573 void
575 {
576  m_nrDlFrames++;
579 }
580 
581 void
583 {
585 
586  NS_LOG_INFO ("UL frame started : " << m_ulSubframeStartTime.GetSeconds ());
587 
593  this);
594 }
595 
596 void
598 {
599  m_nrUlFrames++;
602 }
603 
604 void
606 {
607  StartFrame ();
608 }
609 
610 bool
612  const Mac48Address &source,
613  const Mac48Address &dest,
614  uint16_t protocolNumber)
615 {
616  Ptr<PacketBurst> burst = Create<PacketBurst> ();
617  ServiceFlow *serviceFlow = 0;
618 
619  NS_LOG_INFO ("BS (" << source << "):");
620  NS_LOG_INFO ("\tSending packet...");
621  NS_LOG_INFO ("\t\tDestination: " << dest);
622  NS_LOG_INFO ("\t\tPaket Size: " << packet->GetSize ());
623  NS_LOG_INFO ("\t\tProtocol: " << protocolNumber);
624 
625 
626  if (protocolNumber == 2048)
627  {
628  serviceFlow = m_bsClassifier->Classify (packet, GetServiceFlowManager (), ServiceFlow::SF_DIRECTION_DOWN);
629  }
630 
631  if (protocolNumber != 2048 || serviceFlow == 0)
632  {
633  serviceFlow = *GetServiceFlowManager ()->GetServiceFlows (ServiceFlow::SF_TYPE_ALL).begin ();
634  }
635 
636  if (serviceFlow == 0)
637  {
638  NS_LOG_INFO ("No Service Flow!!");
639  m_bsTxDropTrace (packet);
640  return false;
641  }
642  if (serviceFlow->GetIsEnabled ())
643  {
644  if (!Enqueue (packet, MacHeaderType (), serviceFlow->GetConnection ()))
645  {
646  NS_LOG_INFO ("Enqueue Error!!");
647  m_bsTxDropTrace (packet);
648  return false;
649  }
650  }
651  else
652  {
653  m_bsTxDropTrace (packet);
654  NS_LOG_INFO ("Service Flow is not enabled");
655  return false;
656  }
657  m_bsTxTrace (packet);
658 
659  return true;
660 }
661 
662 bool
664 {
665  NS_ASSERT_MSG (connection != 0,
666  "BS: Can not enqueue packet on the selected connection: the connection is not initialized");
667 
668  GenericMacHeader hdr;
669  hdr.SetLen (packet->GetSize () + hdr.GetSerializedSize ());
670 
671  hdr.SetCid (connection->GetCid ());
672 
673  return connection->Enqueue (packet, hdrType, hdr);
674 }
675 
676 void
678 {
679  GenericMacHeader gnrcMacHdr;
680  BandwidthRequestHeader bwRequestHdr;
681  ManagementMessageType msgType;
682  RngReq rngReq;
683  Cid cid;
684  uint8_t type = 0;
685  GrantManagementSubheader grantMgmntSubhdr;
686  Mac48Address source;
687  LlcSnapHeader llc;
688  Ptr<WimaxConnection> connection = 0;
689  FragmentationSubheader fragSubhdr;
690  bool fragmentation = false; // it becames true when there is a fragmentation subheader
691 
692  packet->RemoveHeader (gnrcMacHdr);
693  if (gnrcMacHdr.GetHt () == MacHeaderType::HEADER_TYPE_GENERIC)
694  {
695  if (gnrcMacHdr.check_hcs () == false)
696  {
697  // The header is noisy
698  m_bsRxDropTrace (packet);
699  NS_LOG_INFO ("Header HCS ERROR");
700  return;
701  }
702 
703  cid = gnrcMacHdr.GetCid ();
704 
705  // checking for subheaders (only grant management subheader is implemented)
706  type = gnrcMacHdr.GetType ();
707  if (type)
708  {
709  // checking 1st bit, see Table 6
710  if (type & 1)
711  {
712  packet->RemoveHeader (grantMgmntSubhdr);
713  }
714  // Check if there is a fragmentation Subheader
715  uint8_t tmpType = type;
716  if (((tmpType >> 2) & 1) == 1)
717  {
718  // a TRANSPORT packet with fragmentation subheader has been received!
719  NS_LOG_INFO ("FRAG_DEBUG: DoReceive -> the packet is a fragment" << std::endl);
720  fragmentation = true;
721  }
722  }
723 
724  if (cid.IsInitialRanging ()) // initial ranging connection
725  {
726  packet->RemoveHeader (msgType);
727  switch (msgType.GetType ())
728  {
730  {
731  packet->RemoveHeader (rngReq);
732  m_linkManager->ProcessRangingRequest (cid, rngReq);
733  break;
734  }
736  // from other base station, ignore
737  break;
738  default:
739  NS_FATAL_ERROR ("Invalid message type");
740  }
741  }
742  else if (m_cidFactory->IsBasic (cid)) // basic management connection
743  {
744  source = m_ssManager->GetMacAddress (cid);
745  m_traceBSRx (packet, source, cid);
746  packet->RemoveHeader (msgType);
747  switch (msgType.GetType ())
748  {
750  {
751  packet->RemoveHeader (rngReq);
752  m_linkManager->ProcessRangingRequest (cid, rngReq);
753  break;
754  }
756  // from other base station, ignore
757  break;
758  default:
759  NS_FATAL_ERROR ("Invalid message type");
760  }
761  }
762  else if (m_cidFactory->IsPrimary (cid)) // primary management connection
763  {
764  source = m_ssManager->GetMacAddress (cid);
765  m_traceBSRx (packet, source, cid);
766  packet->RemoveHeader (msgType);
767  switch (msgType.GetType ())
768  {
770  // not yet implemented
771  break;
773  // from other base station, ignore
774  break;
776  {
777  DsaReq dsaReq;
778  packet->RemoveHeader (dsaReq);
779  GetServiceFlowManager ()->AllocateServiceFlows (dsaReq, cid);
780  break;
781  }
783 
784  /*from other base station, as DSA initiated
785  from BS is not supported, ignore*/
786  break;
788  {
789  Simulator::Cancel (GetServiceFlowManager ()->GetDsaAckTimeoutEvent ());
790  DsaAck dsaAck;
791  packet->RemoveHeader (dsaAck);
792  GetServiceFlowManager ()->ProcessDsaAck (dsaAck, cid);
793  break;
794  }
795  default:
796  NS_FATAL_ERROR ("Invalid message type");
797  }
798  }
799  else if (cid.IsBroadcast ()) // broadcast connection
800  {
801  // from other base station, ignore
802  // or perhaps data packet (using other protocol) for BS, handle later
803  return;
804  }
805  else // transport connection
806  {
807  // If fragmentation is true, the packet is a fragment.
808  Ptr<Packet> C_Packet = packet->Copy ();
809  if (!fragmentation)
810  {
811  C_Packet->RemoveHeader (llc);
812  source = m_ssManager->GetMacAddress (cid);
813  m_bsRxTrace (packet);
814  ForwardUp (packet->Copy (), source, Mac48Address ("ff:ff:ff:ff:ff:ff"));
815  }
816  else
817  {
818  NS_LOG_INFO ( "FRAG_DEBUG: BS DoReceive, the Packet is a fragment" << std::endl);
819  packet->RemoveHeader (fragSubhdr);
820  uint32_t fc = fragSubhdr.GetFc ();
821  NS_LOG_INFO ("\t fragment size = " << packet->GetSize () << std::endl);
822  if (fc == 2)
823  {
824  // This is the latest fragment.
825  // Take the fragment queue, defragment a packet and send it to the upper layer
826  NS_LOG_INFO ("\t Received the latest fragment" << std::endl);
827  GetConnectionManager ()->GetConnection (cid)
828  ->FragmentEnqueue (packet);
830  GetConnection (cid)->GetFragmentsQueue ();
831  Ptr<Packet> fullPacket = Create<Packet> ();
832 
833  // DEFRAGMENTATION
834  NS_LOG_INFO ("\t BS PACKET DEFRAGMENTATION" << std::endl);
835  for (std::list<Ptr<const Packet> >::const_iterator iter = fragmentsQueue.begin ();
836  iter != fragmentsQueue.end (); ++iter)
837  {
838  // Create the whole Packet
839  fullPacket->AddAtEnd (*iter);
840  }
841  GetConnectionManager ()->GetConnection (cid)
842  ->ClearFragmentsQueue ();
843 
844  NS_LOG_INFO ("\t fullPacket size = " << fullPacket->GetSize () << std::endl);
845  source = m_ssManager->GetMacAddress (cid);
846  m_bsRxTrace (fullPacket);
847  ForwardUp (fullPacket->Copy (), source, Mac48Address ("ff:ff:ff:ff:ff:ff"));
848  }
849  else
850  {
851  // This is the first or middle fragment.
852  // Take the fragment queue, store the fragment into the queue
853  NS_LOG_INFO ("\t Received the first or the middle fragment" << std::endl);
854  GetConnectionManager ()->GetConnection (cid)
855  ->FragmentEnqueue (packet);
856  }
857  }
858  }
859  }
860  else
861  {
862  // bandwidth request header
863  packet->AddHeader (gnrcMacHdr);
864  packet->RemoveHeader (bwRequestHdr);
866  "A bandwidth request should be carried by a bandwidth header type");
867  if (bwRequestHdr.check_hcs () == false)
868  {
869  // The header is noisy
870  NS_LOG_INFO ("BS:Header HCS ERROR");
871  return;
872  }
873  cid = bwRequestHdr.GetCid ();
874  source = m_ssManager->GetMacAddress (cid);
875  m_traceBSRx (packet, source, cid);
876  GetBandwidthManager ()->ProcessBandwidthRequest (bwRequestHdr);
877  }
878 
879 }
880 
881 void
883 {
884  Ptr<Packet> dlmap, ulmap;
885  bool sendDcd = false, sendUcd = false, updateDcd = false, updateUcd = false;
886 
887  uint16_t currentNrSsRegistered = m_ssManager->GetNRegisteredSSs ();
888 
889  if (m_nrSsRegistered == currentNrSsRegistered)
890  {
891  m_uplinkScheduler->GetChannelDescriptorsToUpdate (updateDcd, updateUcd, sendDcd, sendUcd);
892  }
893  else
894  {
895  sendDcd = sendUcd = true;
896  }
897 
898  m_nrSsRegistered = currentNrSsRegistered;
899 
900  /*either DCD and UCD must be created first because CCC is set during their
901  creation, or CCC must be calculated first so that it could be set during
902  creation of DL-MAP and UL-MAP and then set duirng creation of DCD and UCD*/
903 
904  if (sendDcd)
905  {
906  m_dcdConfigChangeCount += 1 % 256;
907  }
908 
909  if (sendUcd)
910  {
911  m_ucdConfigChangeCount += 1 % 256;
912  }
913 
914  dlmap = CreateDlMap ();
916  m_nrDlMapSent++;
917 
918  ulmap = CreateUlMap ();
920  m_nrUlMapSent++;
921 
922  CreateDescriptorMessages (sendDcd, sendUcd);
923 }
924 
925 void
927 {
928  Ptr<Packet> dcd, ucd;
929 
930  if (sendDcd)
931  {
932  dcd = CreateDcd ();
934  m_nrDcdSent++;
936  }
937  else
938  {
940  }
941 
942  if (sendUcd)
943  {
944  ucd = CreateUcd ();
946  m_nrUcdSent++;
948  }
949  else
950  {
952  }
953 }
954 
955 /*
956  Sends bursts in the downlink subframe. i.e., creates the downlink subframe. The first burst
957  is broadcast burst with MAC management messages. The rest of the bursts contain data packets.
958  */
959 void
961 {
962  Time txTime = Seconds (0);
963  std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > pair;
965  std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > > *downlinkBursts = m_scheduler->GetDownlinkBursts ();
966  Ptr<PacketBurst> burst;
967  OfdmDlMapIe *dlMapIe;
968  Cid cid;
969 
970  while (downlinkBursts->size ())
971  {
972  pair = downlinkBursts->front ();
973  burst = pair.second;
974  dlMapIe = pair.first;
975  cid = dlMapIe->GetCid ();
976  uint8_t diuc = dlMapIe->GetDiuc ();
977 
978  if (cid != GetInitialRangingConnection ()->GetCid () && cid != GetBroadcastConnection ()->GetCid ())
979  {
980  if (m_serviceFlowManager->GetServiceFlow (cid) != 0)
981  {
982  modulationType = GetBurstProfileManager ()->GetModulationType (diuc, WimaxNetDevice::DIRECTION_DOWNLINK);
983  }
984  else
985  {
986  modulationType = GetBurstProfileManager ()->GetModulationType (diuc, WimaxNetDevice::DIRECTION_DOWNLINK);
987  }
988  }
989  else
990  {
991  modulationType = WimaxPhy::MODULATION_TYPE_BPSK_12;
992  }
993 
994  Simulator::Schedule (txTime, &WimaxNetDevice::ForwardDown, this, burst, modulationType);
995  txTime += GetPhy ()->GetTransmissionTime (burst->GetSize (), modulationType);
996  downlinkBursts->pop_front ();
997  delete dlMapIe;
998  }
999 }
1000 
1003 {
1004  m_nrDlAllocations = 0;
1005 
1006  DlMap dlmap;
1008  dlmap.SetBaseStationId (GetMacAddress ());
1009 
1010  std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > > *downlinkBursts = m_scheduler->GetDownlinkBursts ();
1011 
1012  for (std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > >::iterator iter = downlinkBursts->begin (); iter
1013  != downlinkBursts->end (); ++iter)
1014  {
1015  iter->first->SetPreamblePresent (0);
1016  iter->first->SetStartTime (0);
1017  dlmap.AddDlMapElement (*(iter->first));
1018  }
1019 
1020  OfdmDlMapIe dlMapIeEnd;
1021 
1022  dlMapIeEnd.SetCid (Cid::InitialRanging ());
1024  dlMapIeEnd.SetPreamblePresent (0);
1025  dlMapIeEnd.SetStartTime (0);
1026 
1027  dlmap.AddDlMapElement (dlMapIeEnd);
1028  m_nrDlAllocations = downlinkBursts->size ();
1029 
1030  Ptr<Packet> p = Create<Packet> ();
1031  p->AddHeader (dlmap);
1033  return p;
1034 }
1035 
1038 {
1039  Dcd dcd;
1040  OfdmDcdChannelEncodings chnlEncodings;
1041 
1042  chnlEncodings.SetBsEirp (0);
1043  chnlEncodings.SetEirxPIrMax (0);
1044  chnlEncodings.SetFrequency (GetPhy ()->GetFrequency ());
1045  chnlEncodings.SetChannelNr (0);
1046  chnlEncodings.SetTtg (GetTtg ());
1047  chnlEncodings.SetRtg (GetRtg ());
1048  chnlEncodings.SetBaseStationId (GetMacAddress ());
1049  chnlEncodings.SetFrameDurationCode (GetPhy ()->GetFrameDurationCode ());
1050  chnlEncodings.SetFrameNumber (GetNrFrames ());
1051 
1053  dcd.SetChannelEncodings (chnlEncodings);
1054 
1055  SetDlBurstProfiles (&dcd);
1056  SetCurrentDcd (dcd);
1057 
1058  Ptr<Packet> p = Create<Packet> ();
1059  p->AddHeader (dcd);
1061  return p;
1062 }
1063 
1066 {
1068  m_rangingOppNumber = 0;
1069  m_nrUlAllocations = 0;
1070 
1071  UlMap ulmap;
1073  ulmap.SetAllocationStartTime (m_uplinkScheduler->CalculateAllocationStartTime ());
1074 
1075  std::list<OfdmUlMapIe> uplinkAllocations = m_uplinkScheduler->GetUplinkAllocations ();
1076 
1077  for (std::list<OfdmUlMapIe>::iterator iter = uplinkAllocations.begin (); iter != uplinkAllocations.end (); ++iter)
1078  {
1079  ulmap.AddUlMapElement (*iter);
1080  }
1081 
1082  m_nrUlAllocations = uplinkAllocations.size ();
1083 
1084  Ptr<Packet> p = Create<Packet> ();
1085  p->AddHeader (ulmap);
1087  return p;
1088 }
1089 
1092 {
1093  Ucd ucd;
1095  ucd.SetRangingBackoffStart (3); // setting to 7. i.e., 2^3 = 8 -> 0-7
1096  ucd.SetRangingBackoffEnd (6); // setting to 63. i.e., 2^6 = 64 -> 0-63
1097  ucd.SetRequestBackoffStart (3);
1098  ucd.SetRequestBackoffEnd (6);
1099 
1100  OfdmUcdChannelEncodings chnlEncodings;
1101 
1102  chnlEncodings.SetBwReqOppSize (m_bwReqOppSize * GetPhy ()->GetPsPerSymbol ());
1103  chnlEncodings.SetRangReqOppSize (m_rangReqOppSize * GetPhy ()->GetPsPerSymbol ());
1104 
1105  chnlEncodings.SetFrequency (GetPhy ()->GetFrequency ());
1106  chnlEncodings.SetSbchnlReqRegionFullParams (0);
1107  chnlEncodings.SetSbchnlFocContCodes (0);
1108 
1109  ucd.SetChannelEncodings (chnlEncodings);
1110 
1111  SetUlBurstProfiles (&ucd);
1112  SetCurrentUcd (ucd);
1113 
1114  Ptr<Packet> p = Create<Packet> ();
1115  p->AddHeader (ucd);
1117  return p;
1118 }
1119 
1120 void
1122 {
1123  for (int i = 0; i < GetBurstProfileManager ()->GetNrBurstProfilesToDefine (); ++i)
1124  {
1125  OfdmDlBurstProfile brstProfile;
1126  brstProfile.SetType (0);
1127  brstProfile.SetLength (0);
1128  brstProfile.SetDiuc (i + 1); // DIUC will be between 1-11, see Table 237
1129  brstProfile.SetFecCodeType (i);
1130  dcd->AddDlBurstProfile (brstProfile);
1131  }
1132 }
1133 
1134 void
1136 {
1137  for (int i = 0; i < GetBurstProfileManager ()->GetNrBurstProfilesToDefine (); ++i)
1138  {
1139  OfdmUlBurstProfile brstProfile;
1140  brstProfile.SetType (0);
1141  brstProfile.SetLength (0);
1142  // UIUC will be between 5-12, see Table 246. UIUC 1 (initial ranging) is not included
1143  brstProfile.SetUiuc (i + 5);
1144  brstProfile.SetFecCodeType (i);
1145 
1146  ucd->AddUlBurstProfile (brstProfile);
1147  }
1148 }
1149 
1152 {
1153  Ptr<WimaxConnection> connection = 0;
1154  if (cid.IsInitialRanging ())
1155  {
1156  return GetInitialRangingConnection ();
1157  }
1158  else if (cid.IsBroadcast ())
1159  {
1160  connection = GetBroadcastConnection ();
1161  }
1162  else
1163  {
1164  connection = GetConnectionManager ()->GetConnection (cid);
1165  }
1166 
1167  NS_ASSERT_MSG (connection != 0, "BS: Invalid connection=0");
1168  return connection;
1169 }
1170 
1171 void
1173 {
1174  uint16_t symbolsToAllocation = 0;
1175  std::list<OfdmUlMapIe> uplinkAllocations = m_uplinkScheduler->GetUplinkAllocations ();
1176  for (std::list<OfdmUlMapIe>::iterator iter = uplinkAllocations.begin (); iter != uplinkAllocations.end (); ++iter)
1177  {
1178  OfdmUlMapIe uplinkAllocation = *iter;
1179 
1180  if (uplinkAllocation.GetUiuc () == OfdmUlBurstProfile::UIUC_END_OF_MAP)
1181  {
1182  break;
1183  }
1184 
1185  symbolsToAllocation = uplinkAllocation.GetStartTime ();
1186  MarkUplinkAllocationStart (Seconds (symbolsToAllocation * m_symbolDuration.GetSeconds ()));
1187  MarkUplinkAllocationEnd (Seconds ((symbolsToAllocation + uplinkAllocation.GetDuration ())
1188  * m_symbolDuration.GetSeconds ()), uplinkAllocation.GetCid (), uplinkAllocation.GetUiuc ());
1189  }
1190 }
1191 
1192 void
1194 {
1196 }
1197 
1198 void
1199 BaseStationNetDevice::MarkUplinkAllocationEnd (Time allocationEndTime, Cid cid, uint8_t uiuc)
1200 {
1201  Simulator::Schedule (allocationEndTime, &BaseStationNetDevice::UplinkAllocationEnd, this, cid, uiuc);
1202 }
1203 
1204 void
1206 {
1208 
1209  NS_LOG_DEBUG ("--UL allocation " << (uint32_t) m_ulAllocationNumber << " started : "
1210  << Simulator::Now ().GetSeconds ());
1211 
1212 }
1213 
1214 void
1216 {
1217  NS_LOG_DEBUG ("--UL allocation " << (uint32_t) m_ulAllocationNumber << " ended : " << Simulator::Now ().GetSeconds ());
1218 
1219  if (m_cidFactory->IsBasic (cid))
1220  {
1221  m_linkManager->VerifyInvitedRanging (cid, uiuc);
1222  }
1223 }
1224 
1225 void
1227 {
1228  Simulator::Schedule (rangingOppStartTime, &BaseStationNetDevice::RangingOppStart, this);
1229 }
1230 
1231 void
1233 {
1235 
1236  NS_LOG_DEBUG ("Ranging TO " << (uint32_t) m_rangingOppNumber << ": " << Simulator::Now ().GetSeconds ());
1237 }
1238 
1239 } // 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:102
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:903
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:792
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)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
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:321
void SetBSScheduler(Ptr< BSScheduler > bsSchedule)
Ptr< ConnectionManager > GetConnectionManager(void) const
uint8_t GetRangReqOppSize(void) const
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:446
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:341
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:313
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.
tuple phy
Definition: third.py:86
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:220
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1238
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:957
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:1401
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:958
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:224
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:90
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:895
void CreateDefaultConnections(void)
Creates the initial ranging and broadcast connections.
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:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:904
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:257
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)