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