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 "ns3/simulator.h"
24 #include "ns3/drop-tail-queue.h"
25 #include "ns3/node.h"
26 #include "bs-uplink-scheduler.h"
27 #include "bs-net-device.h"
28 #include "wimax-phy.h"
29 #include "ns3/packet-burst.h"
30 #include "ss-record.h"
31 #include "bs-scheduler.h"
32 #include "wimax-mac-queue.h"
33 #include "burst-profile-manager.h"
34 #include "ss-manager.h"
35 #include "ns3/trace-source-accessor.h"
36 #include "ns3/pointer.h"
37 #include "ns3/enum.h"
38 #include "ns3/uinteger.h"
39 #include "service-flow.h"
40 #include "service-flow-manager.h"
41 #include "connection-manager.h"
42 #include "bs-link-manager.h"
43 #include "bandwidth-manager.h"
44 #include "ns3/ipv4-address.h"
45 #include "ns3/llc-snap-header.h"
46 
47 NS_LOG_COMPONENT_DEFINE ("BaseStationNetDevice");
48 
49 namespace ns3 {
50 
51 NS_OBJECT_ENSURE_REGISTERED (BaseStationNetDevice);
52 
54 {
55  static TypeId tid = TypeId ("ns3::BaseStationNetDevice")
56 
58 
59  .AddConstructor<BaseStationNetDevice> ()
60 
61  .AddAttribute ("BSScheduler",
62  "Downlink Scheduler for BS",
63  PointerValue (),
64  MakePointerAccessor (&BaseStationNetDevice::m_scheduler),
65  MakePointerChecker<BSScheduler> ())
66 
67  .AddAttribute ("InitialRangInterval",
68  "Time between Initial Ranging regions assigned by the BS. Maximum is 2s",
69  TimeValue (Seconds (0.05)),
72  MakeTimeChecker ())
73 
74  .AddAttribute ("DcdInterval",
75  "Time between transmission of DCD messages. Maximum value is 10s.",
76  TimeValue (Seconds (3)),
78  MakeTimeChecker ())
79 
80  .AddAttribute ("UcdInterval",
81  "Time between transmission of UCD messages. Maximum value is 10s.",
82  TimeValue (Seconds (3)),
84  MakeTimeChecker ())
85 
86  .AddAttribute ("IntervalT8",
87  "Wait for DSA/DSC Acknowledge timeout. Maximum 300ms.",
88  TimeValue (Seconds (0.05)),
90  MakeTimeChecker ())
91 
92  .AddAttribute ("RangReqOppSize",
93  "The ranging opportunity size in symbols",
94  UintegerValue (8),
95  MakeUintegerAccessor (&BaseStationNetDevice::GetRangReqOppSize,
97  MakeUintegerChecker<uint8_t> (1, 256))
98 
99  .AddAttribute ("BwReqOppSize",
100  "The bandwidth request opportunity size in symbols",
101  UintegerValue (2),
103  MakeUintegerChecker<uint8_t> (1, 256))
104 
105  .AddAttribute ("MaxRangCorrectionRetries",
106  "Number of retries on contention Ranging Requests",
107  UintegerValue (16),
110  MakeUintegerChecker<uint8_t> (1, 16))
111 
112  .AddAttribute ("SSManager",
113  "The ss manager attached to this device.",
114  PointerValue (),
116  MakePointerChecker<SSManager> ())
117 
118  .AddAttribute ("Scheduler",
119  "The BS scheduler attached to this device.",
120  PointerValue (),
122  MakePointerChecker<BSScheduler> ())
123 
124  .AddAttribute ("LinkManager",
125  "The link manager attached to this device.",
126  PointerValue (),
128  MakePointerChecker<BSLinkManager> ())
129 
130  .AddAttribute ("UplinkScheduler",
131  "The uplink scheduler attached to this device.",
132  PointerValue (),
133  MakePointerAccessor (&BaseStationNetDevice::GetUplinkScheduler,
135  MakePointerChecker<UplinkScheduler> ())
136 
137  .AddAttribute ("BsIpcsPacketClassifier",
138  "The uplink IP packet classifier attached to this device.",
139  PointerValue (),
141  MakePointerChecker<IpcsClassifier> ())
142 
143  .AddAttribute ("ServiceFlowManager",
144  "The service flow manager attached to this device.",
145  PointerValue (),
146  MakePointerAccessor (&BaseStationNetDevice::GetServiceFlowManager,
148  MakePointerChecker<ServiceFlowManager> ())
149 
150  .AddTraceSource ("BSTx", "A packet has been received from higher layers and is being processed in preparation for "
151  "queueing for transmission.", MakeTraceSourceAccessor (&BaseStationNetDevice::m_bsTxTrace))
152 
153  .AddTraceSource ("BSTxDrop",
154  "A packet has been dropped in the MAC layer before being queued for transmission.",
156 
157  .AddTraceSource ("BSPromiscRx",
158  "A packet has been received by this device, has been passed up from the physical layer "
159  "and is being forwarded up the local protocol stack. This is a promiscuous trace,",
161 
162  .AddTraceSource ("BSRx",
163  "A packet has been received by this device, has been passed up from the physical layer "
164  "and is being forwarded up the local protocol stack. This is a non-promiscuous trace,",
166 
167  .AddTraceSource ("BSRxDrop",
168  "A packet has been dropped in the MAC layer after it has been passed up from the physical "
169  "layer.",
171  return tid;
172 }
173 
175 {
177 }
178 
179 void
181 {
182 
183  m_initialRangInterval = Seconds (0.05); // maximum is 2
184  m_dcdInterval = Seconds (3); // maximum is 10
185  m_ucdInterval = Seconds (3); // maximum is 10
186  m_intervalT8 = MilliSeconds (50); // maximum is 300 milliseconds
189  m_rangReqOppSize = 8; // 8 symbols = 2 (preamble) + 2 (RNG-REQ) + 4 (round-trip propagation time)
190  m_bwReqOppSize = 2; // 2 symbols = 1 (preamble) + 1 (bandwidth request header)
191  m_nrDlSymbols = 0;
192  m_nrUlSymbols = 0;
193  m_nrDlMapSent = 0;
194  m_nrUlMapSent = 0;
195  m_nrDcdSent = 0;
196  m_nrUcdSent = 0;
201  m_nrDlFrames = 0;
202  m_nrUlFrames = 0;
203  m_nrSsRegistered = 0;
204  m_nrDlAllocations = 0;
205  m_nrUlAllocations = 0;
209  m_rangingOppNumber = 0;
211  m_psDuration = Seconds (0);
213  m_linkManager = CreateObject<BSLinkManager> (this);
214  m_cidFactory = new CidFactory ();
215  m_ssManager = CreateObject<SSManager> ();
216  m_bsClassifier = CreateObject<IpcsClassifier> ();
217  m_serviceFlowManager = CreateObject<BsServiceFlowManager> (this);
218 
219 }
220 
222 {
224  this->SetNode (node);
225  this->SetPhy (phy);
226 }
227 
229  Ptr<WimaxPhy> phy,
230  Ptr<UplinkScheduler> uplinkScheduler,
231  Ptr<BSScheduler> bsScheduler)
232 {
234  this->SetNode (node);
235  this->SetPhy (phy);
236  m_uplinkScheduler = uplinkScheduler;
237  m_scheduler = bsScheduler;
238 }
239 
241 {
242 }
243 
244 void
246 {
247  delete m_cidFactory;
248 
249  m_linkManager = 0;
250  m_ssManager = 0;
251  m_bsClassifier = 0;
253  m_uplinkScheduler = 0;
254  m_cidFactory = 0;
255  m_ssManager = 0;
256  m_uplinkScheduler = 0;
257  m_scheduler = 0;
258 
260 }
261 
262 void
264 {
265  m_bsClassifier = bsc;
266 }
267 
270 {
271  return m_bsClassifier;
272 }
273 
274 void
276 {
277  m_initialRangInterval = initialRangInterval;
278 }
279 
280 Time
282 {
283  return m_initialRangInterval;
284 }
285 
286 void
288 {
289  m_dcdInterval = dcdInterval;
290 }
291 
292 Time
294 {
295  return m_dcdInterval;
296 }
297 
298 void
300 {
301  m_ucdInterval = ucdInterval;
302 }
303 
304 Time
306 {
307  return m_ucdInterval;
308 }
309 
310 void
312 {
313  m_intervalT8 = interval;
314 }
315 
316 Time
318 {
319  return m_intervalT8;
320 }
321 
322 void
324 {
325  m_maxRangCorrectionRetries = maxRangCorrectionRetries;
326 }
327 
328 uint8_t
330 {
332 }
333 
334 void
335 BaseStationNetDevice::SetMaxInvitedRangRetries (uint8_t maxInvitedRangRetries)
336 {
337  m_maxInvitedRangRetries = maxInvitedRangRetries;
338 }
339 
340 uint8_t
342 {
344 }
345 
346 void
348 {
349  m_rangReqOppSize = rangReqOppSize;
350 }
351 
352 uint8_t
354 {
355  return m_rangReqOppSize;
356 }
357 
358 void
360 {
361  m_bwReqOppSize = bwReqOppSize;
362 }
363 
364 uint8_t
366 {
367  return m_bwReqOppSize;
368 }
369 
370 void
372 {
373  m_nrDlSymbols = nrDlSymbols;
374 }
375 
376 uint32_t
378 {
379  return m_nrDlSymbols;
380 }
381 
382 void
384 {
385  m_nrUlSymbols = nrUlSymbols;
386 }
387 
388 uint32_t
390 {
391  return m_nrUlSymbols;
392 }
393 
394 uint32_t
396 {
397  return m_nrDcdSent;
398 }
399 
400 uint32_t
402 {
403  return m_nrUcdSent;
404 }
405 
406 Time
408 {
409  return m_dlSubframeStartTime;
410 }
411 
412 Time
414 {
415  return m_ulSubframeStartTime;
416 }
417 
418 uint8_t
420 {
421  return m_rangingOppNumber;
422 }
423 
426 {
427  return m_ssManager;
428 }
429 
430 void
432 {
433  m_ssManager = ssm;
434 }
435 
438 {
439  return m_serviceFlowManager;
440 }
441 
442 void
444 {
445  m_serviceFlowManager = sfm;
446 }
447 
450 {
451  return m_uplinkScheduler;
452 }
453 
454 void
456 {
457  m_uplinkScheduler = uls;
458 }
459 
462 {
463  return m_linkManager;
464 }
465 
466 void
468 {
469  m_linkManager = lm;
470 }
471 
472 void
474 {
475  m_scheduler = bss;
476 }
479 {
480  return m_scheduler;
481 }
482 
483 Time
485 {
486  return m_psDuration;
487 }
488 
489 Time
491 {
492  return m_symbolDuration;
493 }
494 
495 void
497 {
500  GetPhy ()->SetPhyParameters ();
501  GetPhy ()->SetDataRates ();
502  SetTtg (GetPhy ()->GetTtg ());
503  SetRtg (GetPhy ()->GetRtg ());
507 
511 
512  /* shall actually be 2 symbols = 1 (preamble) + 1 (bandwidth request header)*/
513  m_bwReqOppSize = 6;
515 }
516 
517 void
519 {
520 }
521 
522 void
524 {
525  //setting DL/UL subframe allocation for this frame
526  uint32_t symbolsPerFrame = GetPhy ()->GetSymbolsPerFrame ();
527  SetNrDlSymbols ((symbolsPerFrame / 2) - static_cast<uint32_t> (ceil (GetTtg ()*m_psDuration.GetSeconds ()/m_symbolDuration.GetSeconds ())));
528  SetNrUlSymbols ((symbolsPerFrame / 2) - static_cast<uint32_t> (ceil (GetRtg ()*m_psDuration.GetSeconds ()/m_symbolDuration.GetSeconds ())));
529 
531 
532  NS_LOG_INFO ("----------------------frame" << GetNrFrames () + 1 << "----------------------");
533 
534  StartDlSubFrame ();
535 }
536 
537 void
539 {
540  m_dlSubframeStartTime = Simulator::Now (); // same as m_frameStartTime
541 
542  NS_LOG_DEBUG ("DL frame started : " << m_frameStartTime.GetSeconds ());
543 
544  SetNrFrames (GetNrFrames () + 1);
549  m_scheduler->Schedule ();
550  SendBursts ();
553  this);
554 }
555 
556 void
558 {
559  m_nrDlFrames++;
562 }
563 
564 void
566 {
568 
569  NS_LOG_INFO ("UL frame started : " << m_ulSubframeStartTime.GetSeconds ());
570 
576  this);
577 }
578 
579 void
581 {
582  m_nrUlFrames++;
585 }
586 
587 void
589 {
590  StartFrame ();
591 }
592 
593 bool
595  const Mac48Address &source,
596  const Mac48Address &dest,
597  uint16_t protocolNumber)
598 {
599  Ptr<PacketBurst> burst = Create<PacketBurst> ();
600  ServiceFlow *serviceFlow = 0;
601 
602  NS_LOG_INFO ("BS (" << source << "):");
603  NS_LOG_INFO ("\tSending packet...");
604  NS_LOG_INFO ("\t\tDestination: " << dest);
605  NS_LOG_INFO ("\t\tPaket Size: " << packet->GetSize ());
606  NS_LOG_INFO ("\t\tProtocol: " << protocolNumber);
607 
608 
609  if (protocolNumber == 2048)
610  {
612  }
613 
614  if (protocolNumber != 2048 || serviceFlow == 0)
615  {
616  serviceFlow = *GetServiceFlowManager ()->GetServiceFlows (ServiceFlow::SF_TYPE_ALL).begin ();
617  }
618 
619  if (serviceFlow == 0)
620  {
621  NS_LOG_INFO ("No Service Flow!!");
622  m_bsTxDropTrace (packet);
623  return false;
624  }
625  if (serviceFlow->GetIsEnabled ())
626  {
627  if (!Enqueue (packet, MacHeaderType (), serviceFlow->GetConnection ()))
628  {
629  NS_LOG_INFO ("Enqueue Error!!");
630  m_bsTxDropTrace (packet);
631  return false;
632  }
633  }
634  else
635  {
636  m_bsTxDropTrace (packet);
637  NS_LOG_INFO ("Service Flow is not enabled");
638  return false;
639  }
640  m_bsTxTrace (packet);
641 
642  return true;
643 }
644 
645 bool
647 {
648  NS_ASSERT_MSG (connection != 0,
649  "BS: Can not enqueue packet on the selected connection: the connection is not initialized");
650 
651  GenericMacHeader hdr;
652  hdr.SetLen (packet->GetSize () + hdr.GetSerializedSize ());
653 
654  hdr.SetCid (connection->GetCid ());
655 
656  return connection->Enqueue (packet, hdrType, hdr);
657 }
658 
659 void
661 {
662  GenericMacHeader gnrcMacHdr;
663  BandwidthRequestHeader bwRequestHdr;
664  ManagementMessageType msgType;
665  RngReq rngReq;
666  Cid cid;
667  uint8_t type = 0;
668  GrantManagementSubheader grantMgmntSubhdr;
669  Mac48Address source;
670  LlcSnapHeader llc;
671  Ptr<WimaxConnection> connection = 0;
672  FragmentationSubheader fragSubhdr;
673  bool fragmentation = false; // it becames true when there is a fragmentation subheader
674 
675  packet->RemoveHeader (gnrcMacHdr);
676  if (gnrcMacHdr.GetHt () == MacHeaderType::HEADER_TYPE_GENERIC)
677  {
678  if (gnrcMacHdr.check_hcs () == false)
679  {
680  // The header is noisy
681  m_bsRxDropTrace (packet);
682  NS_LOG_INFO ("Header HCS ERROR");
683  return;
684  }
685 
686  cid = gnrcMacHdr.GetCid ();
687 
688  // checking for subheaders (only grant management subheader is implemented)
689  type = gnrcMacHdr.GetType ();
690  if (type)
691  {
692  // checking 1st bit, see Table 6
693  if (type & 1)
694  {
695  packet->RemoveHeader (grantMgmntSubhdr);
696  }
697  // Check if there is a fragmentation Subheader
698  uint8_t tmpType = type;
699  if (((tmpType >> 2) & 1) == 1)
700  {
701  // a TRANSPORT packet with fragmentation subheader has been received!
702  NS_LOG_INFO ("FRAG_DEBUG: DoReceive -> the packet is a fragment" << std::endl);
703  fragmentation = true;
704  }
705  }
706 
707  if (cid.IsInitialRanging ()) // initial ranging connection
708  {
709  packet->RemoveHeader (msgType);
710  switch (msgType.GetType ())
711  {
713  {
714  packet->RemoveHeader (rngReq);
715  m_linkManager->ProcessRangingRequest (cid, rngReq);
716  break;
717  }
719  // from other base station, ignore
720  break;
721  default:
722  NS_FATAL_ERROR ("Invalid message type");
723  }
724  }
725  else if (m_cidFactory->IsBasic (cid)) // basic management connection
726  {
727  source = m_ssManager->GetMacAddress (cid);
728  m_traceBSRx (packet, source, cid);
729  packet->RemoveHeader (msgType);
730  switch (msgType.GetType ())
731  {
733  {
734  packet->RemoveHeader (rngReq);
735  m_linkManager->ProcessRangingRequest (cid, rngReq);
736  break;
737  }
739  // from other base station, ignore
740  break;
741  default:
742  NS_FATAL_ERROR ("Invalid message type");
743  }
744  }
745  else if (m_cidFactory->IsPrimary (cid)) // primary management connection
746  {
747  source = m_ssManager->GetMacAddress (cid);
748  m_traceBSRx (packet, source, cid);
749  packet->RemoveHeader (msgType);
750  switch (msgType.GetType ())
751  {
753  // not yet implemented
754  break;
756  // from other base station, ignore
757  break;
759  {
760  DsaReq dsaReq;
761  packet->RemoveHeader (dsaReq);
763  break;
764  }
766 
767  /*from other base station, as DSA initiated
768  from BS is not supported, ignore*/
769  break;
771  {
772  Simulator::Cancel (GetServiceFlowManager ()->GetDsaAckTimeoutEvent ());
773  DsaAck dsaAck;
774  packet->RemoveHeader (dsaAck);
775  GetServiceFlowManager ()->ProcessDsaAck (dsaAck, cid);
776  break;
777  }
778  default:
779  NS_FATAL_ERROR ("Invalid message type");
780  }
781  }
782  else if (cid.IsBroadcast ()) // broadcast connection
783  {
784  // from other base station, ignore
785  // or perhaps data packet (using other protocol) for BS, handle later
786  return;
787  }
788  else // transport connection
789  {
790  // If fragmentation is true, the packet is a fragment.
791  Ptr<Packet> C_Packet = packet->Copy ();
792  if (!fragmentation)
793  {
794  C_Packet->RemoveHeader (llc);
795  source = m_ssManager->GetMacAddress (cid);
796  m_bsRxTrace (packet);
797  ForwardUp (packet->Copy (), source, Mac48Address ("ff:ff:ff:ff:ff:ff"));
798  }
799  else
800  {
801  NS_LOG_INFO ( "FRAG_DEBUG: BS DoReceive, the Packet is a fragment" << std::endl);
802  packet->RemoveHeader (fragSubhdr);
803  uint32_t fc = fragSubhdr.GetFc ();
804  NS_LOG_INFO ("\t fragment size = " << packet->GetSize () << std::endl);
805  if (fc == 2)
806  {
807  // This is the latest fragment.
808  // Take the fragment queue, defragment a packet and send it to the upper layer
809  NS_LOG_INFO ("\t Received the latest fragment" << std::endl);
811  ->FragmentEnqueue (packet);
814  Ptr<Packet> fullPacket = Create<Packet> ();
815 
816  // DEFRAGMENTATION
817  NS_LOG_INFO ("\t BS PACKET DEFRAGMENTATION" << std::endl);
818  for (std::list<Ptr<const Packet> >::const_iterator iter = fragmentsQueue.begin ();
819  iter != fragmentsQueue.end (); ++iter)
820  {
821  // Create the whole Packet
822  fullPacket->AddAtEnd (*iter);
823  }
825  ->ClearFragmentsQueue ();
826 
827  NS_LOG_INFO ("\t fullPacket size = " << fullPacket->GetSize () << std::endl);
828  source = m_ssManager->GetMacAddress (cid);
829  m_bsRxTrace (fullPacket);
830  ForwardUp (fullPacket->Copy (), source, Mac48Address ("ff:ff:ff:ff:ff:ff"));
831  }
832  else
833  {
834  // This is the first or middle fragment.
835  // Take the fragment queue, store the fragment into the queue
836  NS_LOG_INFO ("\t Received the first or the middle fragment" << std::endl);
838  ->FragmentEnqueue (packet);
839  }
840  }
841  }
842  }
843  else
844  {
845  // bandwidth request header
846  packet->AddHeader (gnrcMacHdr);
847  packet->RemoveHeader (bwRequestHdr);
849  "A bandwidth request should be carried by a bandwidth header type");
850  if (bwRequestHdr.check_hcs () == false)
851  {
852  // The header is noisy
853  NS_LOG_INFO ("BS:Header HCS ERROR");
854  return;
855  }
856  cid = bwRequestHdr.GetCid ();
857  source = m_ssManager->GetMacAddress (cid);
858  m_traceBSRx (packet, source, cid);
859  GetBandwidthManager ()->ProcessBandwidthRequest (bwRequestHdr);
860  }
861 
862 }
863 
864 void
866 {
867  Ptr<Packet> dlmap, ulmap;
868  bool sendDcd = false, sendUcd = false, updateDcd = false, updateUcd = false;
869 
870  uint16_t currentNrSsRegistered = m_ssManager->GetNRegisteredSSs ();
871 
872  if (m_nrSsRegistered == currentNrSsRegistered)
873  {
874  m_uplinkScheduler->GetChannelDescriptorsToUpdate (updateDcd, updateUcd, sendDcd, sendUcd);
875  }
876  else
877  {
878  sendDcd = sendUcd = true;
879  }
880 
881  m_nrSsRegistered = currentNrSsRegistered;
882 
883  /*either DCD and UCD must be created first because CCC is set during their
884  creation, or CCC must be calculated first so that it could be set during
885  creation of DL-MAP and UL-MAP and then set duirng creation of DCD and UCD*/
886 
887  if (sendDcd)
888  {
889  m_dcdConfigChangeCount += 1 % 256;
890  }
891 
892  if (sendUcd)
893  {
894  m_ucdConfigChangeCount += 1 % 256;
895  }
896 
897  dlmap = CreateDlMap ();
899  m_nrDlMapSent++;
900 
901  ulmap = CreateUlMap ();
903  m_nrUlMapSent++;
904 
905  CreateDescriptorMessages (sendDcd, sendUcd);
906 }
907 
908 void
910 {
911  Ptr<Packet> dcd, ucd;
912 
913  if (sendDcd)
914  {
915  dcd = CreateDcd ();
917  m_nrDcdSent++;
919  }
920  else
921  {
923  }
924 
925  if (sendUcd)
926  {
927  ucd = CreateUcd ();
929  m_nrUcdSent++;
931  }
932  else
933  {
935  }
936 }
937 
938 /*
939  Sends bursts in the downlink subframe. i.e., creates the downlink subframe. The first burst
940  is broadcast burst with MAC management messages. The rest of the bursts contain data packets.
941  */
942 void
944 {
945  Time txTime = Seconds (0);
946  std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > pair;
948  std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > > *downlinkBursts = m_scheduler->GetDownlinkBursts ();
949  Ptr<PacketBurst> burst;
950  OfdmDlMapIe *dlMapIe;
951  Cid cid;
952 
953  while (downlinkBursts->size ())
954  {
955  pair = downlinkBursts->front ();
956  burst = pair.second;
957  dlMapIe = pair.first;
958  cid = dlMapIe->GetCid ();
959  uint8_t diuc = dlMapIe->GetDiuc ();
960 
961  if (cid != GetInitialRangingConnection ()->GetCid () && cid != GetBroadcastConnection ()->GetCid ())
962  {
963  if (m_serviceFlowManager->GetServiceFlow (cid) != 0)
964  {
966  }
967  else
968  {
970  }
971  }
972  else
973  {
974  modulationType = WimaxPhy::MODULATION_TYPE_BPSK_12;
975  }
976 
977  Simulator::Schedule (txTime, &WimaxNetDevice::ForwardDown, this, burst, modulationType);
978  txTime += GetPhy ()->GetTransmissionTime (burst->GetSize (), modulationType);
979  downlinkBursts->pop_front ();
980  delete dlMapIe;
981  }
982 }
983 
986 {
987  m_nrDlAllocations = 0;
988 
989  DlMap dlmap;
991  dlmap.SetBaseStationId (GetMacAddress ());
992 
993  std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > > *downlinkBursts = m_scheduler->GetDownlinkBursts ();
994 
995  for (std::list<std::pair<OfdmDlMapIe*, Ptr<PacketBurst> > >::iterator iter = downlinkBursts->begin (); iter
996  != downlinkBursts->end (); ++iter)
997  {
998  iter->first->SetPreamblePresent (0);
999  iter->first->SetStartTime (0);
1000  dlmap.AddDlMapElement (*(iter->first));
1001  }
1002 
1003  OfdmDlMapIe dlMapIeEnd;
1004 
1005  dlMapIeEnd.SetCid (Cid::InitialRanging ());
1007  dlMapIeEnd.SetPreamblePresent (0);
1008  dlMapIeEnd.SetStartTime (0);
1009 
1010  dlmap.AddDlMapElement (dlMapIeEnd);
1011  m_nrDlAllocations = downlinkBursts->size ();
1012 
1013  Ptr<Packet> p = Create<Packet> ();
1014  p->AddHeader (dlmap);
1016  return p;
1017 }
1018 
1021 {
1022  Dcd dcd;
1023  OfdmDcdChannelEncodings chnlEncodings;
1024 
1025  chnlEncodings.SetBsEirp (0);
1026  chnlEncodings.SetEirxPIrMax (0);
1027  chnlEncodings.SetFrequency (GetPhy ()->GetFrequency ());
1028  chnlEncodings.SetChannelNr (0);
1029  chnlEncodings.SetTtg (GetTtg ());
1030  chnlEncodings.SetRtg (GetRtg ());
1031  chnlEncodings.SetBaseStationId (GetMacAddress ());
1032  chnlEncodings.SetFrameDurationCode (GetPhy ()->GetFrameDurationCode ());
1033  chnlEncodings.SetFrameNumber (GetNrFrames ());
1034 
1036  dcd.SetChannelEncodings (chnlEncodings);
1037 
1038  SetDlBurstProfiles (&dcd);
1039  SetCurrentDcd (dcd);
1040 
1041  Ptr<Packet> p = Create<Packet> ();
1042  p->AddHeader (dcd);
1044  return p;
1045 }
1046 
1049 {
1051  m_rangingOppNumber = 0;
1052  m_nrUlAllocations = 0;
1053 
1054  UlMap ulmap;
1057 
1058  std::list<OfdmUlMapIe> uplinkAllocations = m_uplinkScheduler->GetUplinkAllocations ();
1059 
1060  for (std::list<OfdmUlMapIe>::iterator iter = uplinkAllocations.begin (); iter != uplinkAllocations.end (); ++iter)
1061  {
1062  ulmap.AddUlMapElement (*iter);
1063  }
1064 
1065  m_nrUlAllocations = uplinkAllocations.size ();
1066 
1067  Ptr<Packet> p = Create<Packet> ();
1068  p->AddHeader (ulmap);
1070  return p;
1071 }
1072 
1075 {
1076  Ucd ucd;
1078  ucd.SetRangingBackoffStart (3); // setting to 7. i.e., 2^3 = 8 -> 0-7
1079  ucd.SetRangingBackoffEnd (6); // setting to 63. i.e., 2^6 = 64 -> 0-63
1080  ucd.SetRequestBackoffStart (3);
1081  ucd.SetRequestBackoffEnd (6);
1082 
1083  OfdmUcdChannelEncodings chnlEncodings;
1084 
1085  chnlEncodings.SetBwReqOppSize (m_bwReqOppSize * GetPhy ()->GetPsPerSymbol ());
1086  chnlEncodings.SetRangReqOppSize (m_rangReqOppSize * GetPhy ()->GetPsPerSymbol ());
1087 
1088  chnlEncodings.SetFrequency (GetPhy ()->GetFrequency ());
1089  chnlEncodings.SetSbchnlReqRegionFullParams (0);
1090  chnlEncodings.SetSbchnlFocContCodes (0);
1091 
1092  ucd.SetChannelEncodings (chnlEncodings);
1093 
1094  SetUlBurstProfiles (&ucd);
1095  SetCurrentUcd (ucd);
1096 
1097  Ptr<Packet> p = Create<Packet> ();
1098  p->AddHeader (ucd);
1100  return p;
1101 }
1102 
1103 void
1105 {
1106  for (int i = 0; i < GetBurstProfileManager ()->GetNrBurstProfilesToDefine (); ++i)
1107  {
1108  OfdmDlBurstProfile brstProfile;
1109  brstProfile.SetType (0);
1110  brstProfile.SetLength (0);
1111  brstProfile.SetDiuc (i + 1); // DIUC will be between 1-11, see Table 237
1112  brstProfile.SetFecCodeType (i);
1113  dcd->AddDlBurstProfile (brstProfile);
1114  }
1115 }
1116 
1117 void
1119 {
1120  for (int i = 0; i < GetBurstProfileManager ()->GetNrBurstProfilesToDefine (); ++i)
1121  {
1122  OfdmUlBurstProfile brstProfile;
1123  brstProfile.SetType (0);
1124  brstProfile.SetLength (0);
1125  // UIUC will be between 5-12, see Table 246. UIUC 1 (initial ranging) is not included
1126  brstProfile.SetUiuc (i + 5);
1127  brstProfile.SetFecCodeType (i);
1128 
1129  ucd->AddUlBurstProfile (brstProfile);
1130  }
1131 }
1132 
1135 {
1136  Ptr<WimaxConnection> connection = 0;
1137  if (cid.IsInitialRanging ())
1138  {
1139  return GetInitialRangingConnection ();
1140  }
1141  else if (cid.IsBroadcast ())
1142  {
1143  connection = GetBroadcastConnection ();
1144  }
1145  else
1146  {
1147  connection = GetConnectionManager ()->GetConnection (cid);
1148  }
1149 
1150  NS_ASSERT_MSG (connection != 0, "BS: Invalid connection=0");
1151  return connection;
1152 }
1153 
1154 void
1156 {
1157  uint16_t symbolsToAllocation = 0;
1158  std::list<OfdmUlMapIe> uplinkAllocations = m_uplinkScheduler->GetUplinkAllocations ();
1159  for (std::list<OfdmUlMapIe>::iterator iter = uplinkAllocations.begin (); iter != uplinkAllocations.end (); ++iter)
1160  {
1161  OfdmUlMapIe uplinkAllocation = *iter;
1162 
1163  if (uplinkAllocation.GetUiuc () == OfdmUlBurstProfile::UIUC_END_OF_MAP)
1164  {
1165  break;
1166  }
1167 
1168  symbolsToAllocation = uplinkAllocation.GetStartTime ();
1169  MarkUplinkAllocationStart (Seconds (symbolsToAllocation * m_symbolDuration.GetSeconds ()));
1170  MarkUplinkAllocationEnd (Seconds ((symbolsToAllocation + uplinkAllocation.GetDuration ())
1171  * m_symbolDuration.GetSeconds ()), uplinkAllocation.GetCid (), uplinkAllocation.GetUiuc ());
1172  }
1173 }
1174 
1175 void
1177 {
1179 }
1180 
1181 void
1182 BaseStationNetDevice::MarkUplinkAllocationEnd (Time allocationEndTime, Cid cid, uint8_t uiuc)
1183 {
1184  Simulator::Schedule (allocationEndTime, &BaseStationNetDevice::UplinkAllocationEnd, this, cid, uiuc);
1185 }
1186 
1187 void
1189 {
1191 
1192  NS_LOG_DEBUG ("--UL allocation " << (uint32_t) m_ulAllocationNumber << " started : "
1193  << Simulator::Now ().GetSeconds ());
1194 
1195 }
1196 
1197 void
1199 {
1200  NS_LOG_DEBUG ("--UL allocation " << (uint32_t) m_ulAllocationNumber << " ended : " << Simulator::Now ().GetSeconds ());
1201 
1202  if (m_cidFactory->IsBasic (cid))
1203  {
1204  m_linkManager->VerifyInvitedRanging (cid, uiuc);
1205  }
1206 }
1207 
1208 void
1210 {
1211  Simulator::Schedule (rangingOppStartTime, &BaseStationNetDevice::RangingOppStart, this);
1212 }
1213 
1214 void
1216 {
1218 
1219  NS_LOG_DEBUG ("Ranging TO " << (uint32_t) m_rangingOppNumber << ": " << Simulator::Now ().GetSeconds ());
1220 }
1221 
1222 } // namespace ns3