A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ss-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 "ss-net-device.h"
27 #include "wimax-phy.h"
28 #include "ns3/packet-burst.h"
29 #include <algorithm>
30 #include "dl-mac-messages.h"
31 #include "ul-mac-messages.h"
32 #include "ss-scheduler.h"
33 #include "wimax-mac-queue.h"
34 #include "ns3/trace-source-accessor.h"
35 #include "ns3/pointer.h"
36 #include "ns3/enum.h"
37 #include "service-flow.h"
38 #include "service-flow-record.h"
39 #include "service-flow-manager.h"
40 #include "connection-manager.h"
41 #include "burst-profile-manager.h"
42 #include "ss-link-manager.h"
43 #include "bandwidth-manager.h"
44 
45 NS_LOG_COMPONENT_DEFINE ("SubscriberStationNetDevice");
46 
47 namespace ns3 {
48 
49 NS_OBJECT_ENSURE_REGISTERED (SubscriberStationNetDevice);
50 
52 {
53  return (MicroSeconds (500000));
54 }
55 
56 TypeId
58 {
59  static TypeId
60  tid =
61  TypeId ("ns3::SubscriberStationNetDevice")
62 
64 
65  .AddConstructor<SubscriberStationNetDevice> ()
66 
67  .AddAttribute ("BasicConnection",
68  "Basic connection",
69  PointerValue (),
70  MakePointerAccessor (&SubscriberStationNetDevice::m_basicConnection),
71  MakePointerChecker<WimaxConnection> ())
72 
73  .AddAttribute ("PrimaryConnection",
74  "Primary connection",
75  PointerValue (),
77  MakePointerChecker<WimaxConnection> ())
78 
79  .AddAttribute ("LostDlMapInterval",
80  "Time since last received DL-MAP message before downlink synchronization is considered lost. Maximum is 600ms",
81  TimeValue (Seconds (0.5)),
84  MakeTimeChecker ())
85 
86  .AddAttribute ("LostUlMapInterval",
87  "Time since last received UL-MAP before uplink synchronization is considered lost, maximum is 600.",
88  TimeValue (MilliSeconds (500)),
91  MakeTimeChecker ())
92 
93  .AddAttribute ("MaxDcdInterval",
94  "Maximum time between transmission of DCD messages. Maximum is 10s",
95  TimeValue (Seconds (10)),
98  MakeTimeChecker ())
99 
100  .AddAttribute ("MaxUcdInterval",
101  "Maximum time between transmission of UCD messages. Maximum is 10s",
102  TimeValue (Seconds (10)),
105  MakeTimeChecker ())
106 
107  .AddAttribute ("IntervalT1",
108  "Wait for DCD timeout. Maximum is 5*maxDcdInterval",
109  TimeValue (Seconds (50)),
112  MakeTimeChecker ())
113 
114  .AddAttribute ("IntervalT2",
115  "Wait for broadcast ranging timeout, i.e., wait for initial ranging opportunity. Maximum is 5*Ranging interval",
116  TimeValue (Seconds (10)),
119  MakeTimeChecker ())
120 
121  .AddAttribute ("IntervalT3",
122  "ranging Response reception timeout following the transmission of a ranging request. Maximum is 200ms",
123  TimeValue (Seconds (0.2)),
126  MakeTimeChecker ())
127 
128  .AddAttribute ("IntervalT7",
129  "wait for DSA/DSC/DSD Response timeout. Maximum is 1s",
130  TimeValue (Seconds (0.1)),
133  MakeTimeChecker ())
134 
135  .AddAttribute ("IntervalT12",
136  "Wait for UCD descriptor.Maximum is 5*MaxUcdInterval",
137  TimeValue (Seconds (10)),
140  MakeTimeChecker ())
141 
142  .AddAttribute ("IntervalT20",
143  "Time the SS searches for preambles on a given channel. Minimum is 2 MAC frames",
144  TimeValue (Seconds (0.5)),
147  MakeTimeChecker ())
148 
149  .AddAttribute ("IntervalT21",
150  "time the SS searches for (decodable) DL-MAP on a given channel",
151  TimeValue (Seconds (10)),
154  MakeTimeChecker ())
155 
156  .AddAttribute ("MaxContentionRangingRetries",
157  "Number of retries on contention Ranging Requests",
158  UintegerValue (16),
161  MakeUintegerChecker<uint8_t> (1, 16))
162 
163  .AddAttribute ("SSScheduler",
164  "The ss scheduler attached to this device.",
165  PointerValue (),
166  MakePointerAccessor (&SubscriberStationNetDevice::GetScheduler,
168  MakePointerChecker<SSScheduler> ())
169 
170  .AddAttribute ("LinkManager",
171  "The ss link manager attached to this device.",
172  PointerValue (),
173  MakePointerAccessor (&SubscriberStationNetDevice::GetLinkManager,
175  MakePointerChecker<SSLinkManager> ())
176 
177  .AddAttribute ("Classifier",
178  "The ss classifier attached to this device.",
179  PointerValue (),
180  MakePointerAccessor (&SubscriberStationNetDevice::GetIpcsClassifier,
182  MakePointerChecker<IpcsClassifier> ())
183 
184  .AddTraceSource ("SSTxDrop",
185  "A packet has been dropped in the MAC layer before being queued for transmission.",
187 
188  .AddTraceSource ("SSPromiscRx",
189  "A packet has been received by this device, has been passed up from the physical layer "
190  "and is being forwarded up the local protocol stack. This is a promiscuous trace,",
192 
193  .AddTraceSource ("SSRx",
194  "A packet has been received by this device, has been passed up from the physical layer "
195  "and is being forwarded up the local protocol stack. This is a non-promiscuous trace,",
197 
198  .AddTraceSource ("SSRxDrop",
199  "A packet has been dropped in the MAC layer after it has been passed up from the physical "
200  "layer.",
202  return tid;
203 }
204 
206 {
207 
209 
210 }
211 
212 void
214 {
215  m_lostDlMapInterval = MilliSeconds (500);
216  m_lostUlMapInterval = MilliSeconds (500);
217  m_maxDcdInterval = Seconds (10);
218  m_maxUcdInterval = Seconds (10);
219  m_intervalT1 = Seconds (5 * m_maxDcdInterval.GetSeconds ());
220  m_intervalT2 = Seconds (5 * 2); // shall be 5 * RangingInterval, if ranging interval=see T2 at page 638) means Initial Ranging Interval=see page 637)
221  m_intervalT3 = MilliSeconds (200);
222  m_intervalT7 = Seconds (0.1); // maximum is 1
223  m_intervalT12 = Seconds (5 * m_maxUcdInterval.GetSeconds ());
224  m_intervalT21 = Seconds (11);
226  m_dcdCount = 0;
227  m_baseStationId = Mac48Address ("00:00:00:00:00:00");
228  m_ucdCount = 0;
230  m_nrDlMapElements = 0;
231  m_nrUlMapElements = 0;
232  m_nrDlMapRecvd = 0;
233  m_nrUlMapRecvd = 0;
234  m_nrDcdRecvd = 0;
235  m_nrUcdRecvd = 0;
239 
240  m_basicConnection = 0;
242 
245  m_classifier = CreateObject<IpcsClassifier> ();
246  m_linkManager = CreateObject<SSLinkManager> (this);
247  m_scheduler = CreateObject<SSScheduler> (this);
248  m_serviceFlowManager = CreateObject<SsServiceFlowManager> (this);
249 }
250 
252 {
254  this->SetNode (node);
255  this->SetPhy (phy);
256 }
257 
259 {
260 }
261 
262 void
264 {
265  delete m_dlBurstProfile;
266  delete m_ulBurstProfile;
267  m_scheduler = 0;
269  m_basicConnection = 0;
271  m_classifier = 0;
272  m_dlBurstProfile = 0;
273  m_ulBurstProfile = 0;
274 
275  m_linkManager = 0;
276 
278 }
279 
280 void
282 {
283  m_lostDlMapInterval = lostDlMapInterval;
284 }
285 
286 Time
288 {
289  return m_lostDlMapInterval;
290 }
291 
292 void
294 {
295  m_lostUlMapInterval = lostUlMapInterval;
296 }
297 
298 Time
300 {
301  return m_lostUlMapInterval;
302 }
303 
304 void
306 {
307  m_maxDcdInterval = maxDcdInterval;
308 }
309 
310 Time
312 {
313  return m_maxDcdInterval;
314 }
315 
316 void
318 {
319  m_maxUcdInterval = maxUcdInterval;
320 }
321 
322 Time
324 {
325  return m_maxUcdInterval;
326 }
327 
328 void
330 {
331  m_intervalT1 = interval;
332 }
333 
334 Time
336 {
337  return m_intervalT1;
338 }
339 
340 void
342 {
343  m_intervalT2 = interval;
344 }
345 
346 Time
348 {
349  return m_intervalT2;
350 }
351 
352 void
354 {
355  m_intervalT3 = interval;
356 }
357 
358 Time
360 {
361  return m_intervalT3;
362 }
363 
364 void
366 {
367  m_intervalT7 = interval;
368 }
369 
370 Time
372 {
373  return m_intervalT7;
374 }
375 
376 void
378 {
379  m_intervalT12 = interval;
380 }
381 
382 Time
384 {
385  return m_intervalT12;
386 }
387 
388 void
390 {
391  m_intervalT20 = interval;
392 }
393 
394 Time
396 {
397  return m_intervalT20;
398 }
399 
400 void
402 {
403  m_intervalT21 = interval;
404 }
405 
406 Time
408 {
409  return m_intervalT21;
410 }
411 
412 void
414 {
415  m_maxContentionRangingRetries = maxContentionRangingRetries;
416 }
417 
418 uint8_t
420 {
422 }
423 
424 void
426 {
427  m_basicConnection = basicConnection;
428 }
429 
432 {
433  return m_basicConnection;
434 }
435 
436 void
438 {
439  m_primaryConnection = primaryConnection;
440 }
441 
444 {
445  return m_primaryConnection;
446 }
447 
448 Cid
450 {
451  return m_basicConnection->GetCid ();
452 }
453 
454 Cid
456 {
457  return m_primaryConnection->GetCid ();
458 }
459 
460 void
462 {
463  m_modulationType = modulationType;
464 }
465 
468 {
469  return m_modulationType;
470 }
471 
472 void
474 {
475  m_areManagementConnectionsAllocated = areManagementConnectionsAllocated;
476 }
477 
478 bool
480 {
482 }
483 
484 void
486 {
487  m_areServiceFlowsAllocated = areServiceFlowsAllocated;
488 }
489 
490 bool
492 {
494 }
495 
498 {
499  return m_scheduler;
500 }
501 
502 void
504 {
505  m_scheduler = scheduler;
506 }
507 
508 bool
510 {
511  return GetServiceFlowManager ()->GetServiceFlows (ServiceFlow::SF_TYPE_ALL).size () > 0;
512 }
513 
516 {
517 
518  return m_classifier;
519 }
520 
521 void
523 {
524  m_classifier = classifier;
525 }
526 
529 {
530  return m_linkManager;
531 }
532 
533 void
535 {
536  m_linkManager = linkManager;
537 }
538 
541 {
542  return m_serviceFlowManager;
543 }
544 
545 void
547 {
548  m_serviceFlowManager = sfm;
549 }
550 
551 void
553 {
555 
556  GetPhy ()->SetPhyParameters ();
557  GetPhy ()->SetDataRates ();
558  m_intervalT20 = Seconds (4 * GetPhy ()->GetFrameDuration ().GetSeconds ());
559 
562 }
563 
564 void
566 {
568 }
569 
570 void
572 {
573  GetServiceFlowManager ()->AddServiceFlow (sf);
574 }
575 
576 void
578 {
579  GetServiceFlowManager ()->AddServiceFlow (sf);
580 }
581 
582 bool
584  const Mac48Address &source,
585  const Mac48Address &dest,
586  uint16_t protocolNumber)
587 {
588  NS_LOG_INFO ("SS (" << source << "):" );
589  NS_LOG_INFO ("\tSending packet..." );
590  NS_LOG_INFO ("\t\tDestination: " << dest );
591  NS_LOG_INFO ("\t\tPacket Size: " << packet->GetSize () );
592  NS_LOG_INFO ("\t\tProtocol: " << protocolNumber );
593 
594  ServiceFlow *serviceFlow = 0;
595 
596  if (IsRegistered ())
597  {
598  NS_LOG_DEBUG ("SS (Basic CID: " << m_basicConnection->GetCid () << ")");
599  }
600  else
601  {
602  NS_LOG_DEBUG ("SS (" << GetMacAddress () << ")");
603  NS_LOG_INFO ("\tCan't send packet! (NotRegitered with the network)");
604  return false;
605  }
606 
607  NS_LOG_DEBUG ("packet to send, size : " << packet->GetSize () << ", destination : " << dest);
608 
609  if (GetServiceFlowManager ()->GetNrServiceFlows () == 0)
610  {
611  NS_LOG_INFO ("\tCan't send packet! (No service Flow)");
612  return false;
613  }
614 
615  if (protocolNumber == 2048)
616  {
617  serviceFlow = m_classifier->Classify (packet, GetServiceFlowManager (), ServiceFlow::SF_DIRECTION_UP);
618  }
619 
620  if ((protocolNumber != 2048) || (serviceFlow == NULL))
621  {
622  serviceFlow = *GetServiceFlowManager ()->GetServiceFlows (ServiceFlow::SF_TYPE_ALL).begin ();
623  NS_LOG_INFO ("\tNo service flows matches...using the default one.");
624  }
625 
626  NS_LOG_INFO ("\tPacket classified in the service flow SFID = " << serviceFlow->GetSfid () << " CID = "
627  << serviceFlow->GetCid ());
628  if (serviceFlow->GetIsEnabled ())
629  {
630  if (!Enqueue (packet, MacHeaderType (), serviceFlow->GetConnection ()))
631  {
632  NS_LOG_INFO ("\tEnqueue ERROR!!" );
633  m_ssTxDropTrace (packet);
634  return false;
635  }
636  else
637  {
638  m_ssTxTrace (packet);
639  }
640  }
641  else
642  {
643  NS_LOG_INFO ("Error!! The Service Flow is not enabled" );
644  m_ssTxDropTrace (packet);
645  return false;
646  }
647 
648  return true;
649 }
650 
651 bool
653  const MacHeaderType &hdrType,
654  Ptr<WimaxConnection> connection)
655 {
656  NS_ASSERT_MSG (connection != 0, "SS: Can not enqueue the packet: the selected connection is nor initialized");
657 
658  GenericMacHeader hdr;
659 
661  {
662  hdr.SetLen (packet->GetSize () + hdr.GetSerializedSize ());
663  hdr.SetCid (connection->GetCid ());
664 
665  }
666 
667  if (connection->GetType () == Cid::TRANSPORT)
668  {
669 
670  if (connection->GetSchedulingType () == ServiceFlow::SF_TYPE_UGS && m_scheduler->GetPollMe ())
671  {
673  "Error while equeuing packet: incorrect header type");
674 
675  GrantManagementSubheader grantMgmntSubhdr;
676  grantMgmntSubhdr.SetPm (true);
677  packet->AddHeader (grantMgmntSubhdr);
678  }
679  }
680  NS_LOG_INFO ("ServiceFlowManager: enqueuing packet" );
681  return connection->Enqueue (packet, hdrType, hdr);
682 }
683 
684 void
686  uint16_t nrSymbols,
687  Ptr<WimaxConnection> connection,
688  MacHeaderType::HeaderType packetType)
689 {
690  WimaxPhy::ModulationType modulationType;
691 
693  {
694  modulationType = WimaxPhy::MODULATION_TYPE_BPSK_12;
695  }
696  else
697  {
698  modulationType = GetBurstProfileManager ()->GetModulationType (uiuc, DIRECTION_UPLINK);
699  }
700  Ptr<PacketBurst> burst = m_scheduler->Schedule (nrSymbols, modulationType, packetType, connection);
701 
702  if (burst->GetNPackets () == 0)
703  {
704  return;
705  }
706 
707  if (IsRegistered ())
708  {
709  NS_LOG_DEBUG ("SS (Basic CID: " << m_basicConnection->GetCid () << ")");
710  }
711  else
712  {
713  NS_LOG_DEBUG ("SS (" << GetMacAddress () << ")");
714  }
715 
716  if (connection->GetType () == Cid::TRANSPORT)
717  {
718  ServiceFlowRecord *record = connection->GetServiceFlow ()->GetRecord ();
719  record->UpdatePktsSent (burst->GetNPackets ());
720  record->UpdateBytesSent (burst->GetSize ());
721 
722  NS_LOG_DEBUG (" sending burst" << ", SFID: " << connection->GetServiceFlow ()->GetSfid () << ", pkts sent: "
723  << record->GetPktsSent () << ", pkts rcvd: " << record->GetPktsRcvd () << ", bytes sent: "
724  << record->GetBytesSent () << ", bytes rcvd: " << record->GetBytesRcvd () );
725 
726  }
727  else
728  {
729 
730  }
731  ForwardDown (burst, modulationType);
732 }
733 
734 void
736 {
737  GenericMacHeader gnrcMacHdr;
738  ManagementMessageType msgType;
739  RngRsp rngrsp;
740  Cid cid;
741  uint32_t pktSize = packet->GetSize ();
742  packet->RemoveHeader (gnrcMacHdr);
743  FragmentationSubheader fragSubhdr;
744  bool fragmentation = false; // it becames true when there is a fragmentation subheader
745 
746  if (gnrcMacHdr.GetHt () == MacHeaderType::HEADER_TYPE_GENERIC)
747  {
748  if (gnrcMacHdr.check_hcs () == false)
749  {
750  // The header is noisy
751  NS_LOG_INFO ("Header HCS ERROR");
752  m_ssRxDropTrace (packet);
753  return;
754  }
755 
756  cid = gnrcMacHdr.GetCid ();
757 
758  // checking for subheaders
759  uint8_t type = gnrcMacHdr.GetType ();
760  if (type)
761  {
762  // Check if there is a fragmentation Subheader
763  uint8_t tmpType = type;
764  if (((tmpType >> 2) & 1) == 1)
765  {
766  // a TRANSPORT packet with fragmentation subheader has been received!
767  fragmentation = true;
768  NS_LOG_INFO ("SS DoReceive -> the packet is a fragment" << std::endl);
769  }
770  }
771 
772  if (cid == GetBroadcastConnection ()->GetCid () && !fragmentation)
773  {
774  packet->RemoveHeader (msgType);
775  switch (msgType.GetType ())
776  {
778  {
780  {
781  Simulator::Cancel (m_linkManager->GetDlMapSyncTimeoutEvent ());
782  }
783 
785  {
787  }
788 
789  m_linkManager->ScheduleScanningRestart (m_lostDlMapInterval, EVENT_LOST_DL_MAP, false, m_lostDlMapEvent);
790 
792  {
794  }
795 
796  m_linkManager->ScheduleScanningRestart (m_intervalT1,
798  false,
800 
802  {
804  }
805 
806  m_linkManager->ScheduleScanningRestart (m_intervalT12,
808  true,
810 
811  DlMap dlmap;
812  packet->RemoveHeader (dlmap);
813  ProcessDlMap (dlmap);
814  break;
815  }
817  {
819  {
821  m_linkManager->ScheduleScanningRestart (m_lostUlMapInterval,
823  true,
825  }
826 
827  UlMap ulmap;
828  packet->RemoveHeader (ulmap);
829 
830  ProcessUlMap (ulmap);
831 
833  {
834  if (m_linkManager->GetRangingIntervalFound ())
835  {
837  {
839  }
840  m_linkManager->PerformBackoff ();
841  }
842  }
843  break;
844  }
846  {
848  {
850  }
851 
853  {
855  m_linkManager->ScheduleScanningRestart (m_intervalT1,
857  false,
859  }
860 
861  Dcd dcd;
862  // number of burst profiles is set to number of DL-MAP IEs after processing DL-MAP, not a very good solution
863  // dcd.SetNrDlBurstProfiles (m_nrDlMapElements);
864  dcd.SetNrDlBurstProfiles (7);
865  packet->RemoveHeader (dcd);
866 
867  ProcessDcd (dcd);
868  break;
869  }
871  {
872  Ucd ucd;
873  // number of burst profiles is set to number of UL-MAP IEs after processing UL-MAP, not a very good solution
874  // ucd.SetNrUlBurstProfiles (m_nrUlMapElements);
875  ucd.SetNrUlBurstProfiles (7);
876  packet->RemoveHeader (ucd);
877 
878  ProcessUcd (ucd);
879 
881  {
883  m_linkManager->ScheduleScanningRestart (m_intervalT12,
885  true,
887  }
888 
890  {
891  /*state indicating that SS has completed scanning, synchronization and parameter acquisition
892  successfully and now waiting for UL-MAP to start initial ranging.*/
894 
895  m_linkManager->ScheduleScanningRestart (m_intervalT2,
897  false,
899  m_linkManager->ScheduleScanningRestart (m_lostUlMapInterval,
901  true,
903  }
904  break;
905  }
906  default:
907  NS_FATAL_ERROR ("Invalid management message type");
908  }
909  }
910  else if (GetInitialRangingConnection () != 0 && cid == GetInitialRangingConnection ()->GetCid () && !fragmentation)
911  {
912  m_traceSSRx (packet, GetMacAddress (), &cid);
913  packet->RemoveHeader (msgType);
914  switch (msgType.GetType ())
915  {
917  // intended for base station, ignore
918  break;
921  "SS: Error while receiving a ranging response message: SS state should be SS_STATE_WAITING_RNG_RSP");
922  packet->RemoveHeader (rngrsp);
923  m_linkManager->PerformRanging (cid, rngrsp);
924  break;
925  default:
926  NS_LOG_ERROR ("Invalid management message type");
927  }
928  }
929  else if (m_basicConnection != 0 && cid == m_basicConnection->GetCid () && !fragmentation)
930  {
931  m_traceSSRx (packet, GetMacAddress (), &cid);
932  packet->RemoveHeader (msgType);
933  switch (msgType.GetType ())
934  {
936  // intended for base station, ignore
937  break;
940  "SS: Error while receiving a ranging response message: SS state should be SS_STATE_WAITING_RNG_RSP");
941  packet->RemoveHeader (rngrsp);
942  m_linkManager->PerformRanging (cid, rngrsp);
943  break;
944  default:
945  NS_LOG_ERROR ("Invalid management message type");
946  }
947  }
948  else if (m_primaryConnection != 0 && cid == m_primaryConnection->GetCid () && !fragmentation)
949  {
950  m_traceSSRx (packet, GetMacAddress (), &cid);
951  packet->RemoveHeader (msgType);
952  switch (msgType.GetType ())
953  {
955  // not yet implemented
956  break;
958  // intended for base station, ignore
959  break;
961  /*from other station as DSA initiation
962  by BS is not supported, ignore*/
963  break;
965  {
966  Simulator::Cancel (GetServiceFlowManager ()->GetDsaRspTimeoutEvent ());
967  DsaRsp dsaRsp;
968  packet->RemoveHeader (dsaRsp);
969  GetServiceFlowManager ()->ProcessDsaRsp (dsaRsp);
970  break;
971  }
973  /*from other station as DSA initiation
974  by BS is not supported, ignore*/
975  break;
976  default:
977  NS_LOG_ERROR ("Invalid management message type");
978  }
979  }
980  else if (GetConnectionManager ()->GetConnection (cid)) // transport connection
981  {
982  ServiceFlow *serviceFlow = GetConnectionManager ()->GetConnection (cid)->GetServiceFlow ();
983  ServiceFlowRecord *record = serviceFlow->GetRecord ();
984 
985  record->UpdatePktsRcvd (1);
986  record->UpdateBytesRcvd (pktSize);
987 
988  // If fragmentation is true, the packet is a fragment.
989  if (!fragmentation)
990  {
991  m_ssRxTrace (packet);
992  ForwardUp (packet, m_baseStationId, GetMacAddress ()); // source shall be BS's address or sender SS's?
993  }
994  else
995  {
996  NS_LOG_INFO ( "FRAG_DEBUG: SS DoReceive, the Packet is a fragment" << std::endl);
997  packet->RemoveHeader (fragSubhdr);
998  uint32_t fc = fragSubhdr.GetFc ();
999  NS_LOG_INFO ( "\t fragment size = " << packet->GetSize () << std::endl);
1000 
1001  if (fc == 2)
1002  {
1003  // This is the latest fragment.
1004  // Take the fragment queue, defragment a packet and send it to the upper layer
1005  NS_LOG_INFO ( "\t Received the latest fragment" << std::endl);
1006  GetConnectionManager ()->GetConnection (cid)
1007  ->FragmentEnqueue (packet);
1008 
1010  GetConnection (cid)->GetFragmentsQueue ();
1011 
1012  Ptr<Packet> fullPacket = Create<Packet> ();
1013 
1014  // DEFRAGMENTATION
1015  NS_LOG_INFO ( "\t SS PACKET DEFRAGMENTATION" << std::endl);
1016  for (std::list<Ptr<const Packet> >::const_iterator iter = fragmentsQueue.begin ();
1017  iter != fragmentsQueue.end (); ++iter)
1018  {
1019  // Create the whole Packet
1020  fullPacket->AddAtEnd (*iter);
1021  }
1022  GetConnectionManager ()->GetConnection (cid)
1023  ->ClearFragmentsQueue ();
1024  NS_LOG_INFO ( "\t fullPacket size = " << fullPacket->GetSize () << std::endl);
1025 
1026  m_ssRxTrace (fullPacket);
1027  ForwardUp (fullPacket, m_baseStationId, GetMacAddress ()); // source shall be BS's address or sender SS's?
1028  }
1029  else
1030  {
1031  // This is the first or middle fragment.
1032  // Take the fragment queue, store the fragment into the queue
1033  NS_LOG_INFO ( "\t Received the first or the middle fragment" << std::endl);
1034  GetConnectionManager ()->GetConnection (cid)->FragmentEnqueue (packet);
1035  }
1036  }
1037  }
1038  else if (cid.IsMulticast ())
1039  {
1040  m_traceSSRx (packet, GetMacAddress (), &cid);
1041  ForwardUp (packet, m_baseStationId, GetMacAddress ()); // source shall be BS's address or sender SS's?
1042  }
1043  else if (IsPromisc ())
1044  {
1045  NotifyPromiscTrace (packet);
1046  m_ssPromiscRxTrace (packet);
1047 
1048  // not for me, ignore
1049  }
1050  else
1051  {
1052  // not for me drop
1053  }
1054  }
1055  else
1056  {
1057  // from other SS, ignore
1058  }
1059 }
1060 
1061 void
1063 {
1064  m_nrDlMapRecvd++;
1065  m_dcdCount = dlmap.GetDcdCount ();
1066  m_baseStationId = dlmap.GetBaseStationId ();
1067  std::list<OfdmDlMapIe> dlMapElements = dlmap.GetDlMapElements ();
1068 
1069  for (std::list<OfdmDlMapIe>::iterator iter = dlMapElements.begin (); iter != dlMapElements.end (); ++iter)
1070  {
1071  if (iter->GetDiuc () == OfdmDlBurstProfile::DIUC_END_OF_MAP)
1072  {
1073  break;
1074  }
1075 
1076  if (iter->GetCid () == m_basicConnection->GetCid ())
1077  {
1078  /*here the SS shall actually acquire the start time it shall start receiving the burst at. start time is used for power saving
1079  which is not implemented here, furthermore there is no need since the simulator architecture automatically callbacks the receive
1080  function. shall acquire the DIUC (burst profile) as well to decode the burst, again not required again because the callback
1081  mechanism automatically passes it as parameter.*/
1082  }
1083 
1084 #if 0 /* a template for future implementation following */
1085  uint8_t temp = iter->GetDiuc ();
1086  temp = iter->GetPreamblePresent ();
1087  temp = iter->GetStartTime ();
1088 #endif
1089  }
1090 }
1091 
1092 void
1094 {
1095  m_nrUlMapRecvd++;
1096  m_ucdCount = ulmap.GetUcdCount ();
1098  std::list<OfdmUlMapIe> ulMapElements = ulmap.GetUlMapElements ();
1099  m_linkManager->SetRangingIntervalFound (false);
1100 
1101  for (std::list<OfdmUlMapIe>::iterator iter = ulMapElements.begin (); iter != ulMapElements.end (); ++iter)
1102  {
1103  OfdmUlMapIe ulMapIe = *iter;
1104 
1105  if (ulMapIe.GetUiuc () == OfdmUlBurstProfile::UIUC_END_OF_MAP)
1106  {
1107  break;
1108  }
1109 
1110  Cid cid = ulMapIe.GetCid ();
1111 
1112  if (ulMapIe.GetUiuc () == OfdmUlBurstProfile::UIUC_INITIAL_RANGING && cid == GetBroadcastConnection ()->GetCid ())
1113  {
1114  m_linkManager->SetRangingIntervalFound (true);
1115  }
1116 
1117  if (m_areManagementConnectionsAllocated && cid == m_basicConnection->GetCid ())
1118  {
1119 
1120  Time timeToAllocation = GetTimeToAllocation (Seconds (ulMapIe.GetStartTime ()
1121  * GetPhy ()->GetSymbolDuration ().GetSeconds ()));
1122 
1123  if (ulMapIe.GetUiuc () == OfdmUlBurstProfile::UIUC_INITIAL_RANGING) // invited ranging interval
1124 
1125  {
1126 
1127  m_linkManager->IncrementNrInvitedPollsRecvd ();
1129  "SS: Error while processing UL MAP: SS state should be SS_STATE_WAITING_INV_RANG_INTRVL");
1130  Simulator::Schedule (timeToAllocation,
1132  m_linkManager,
1133  ulMapIe.GetUiuc (),
1134  ulMapIe.GetDuration ());
1135  }
1136  else if (ulMapIe.GetUiuc () == OfdmUlBurstProfile::UIUC_REQ_REGION_FULL) // unicast poll
1137 
1138  {
1139 
1140  Simulator::Schedule (timeToAllocation,
1143  ulMapIe.GetUiuc (),
1144  ulMapIe.GetDuration ());
1145  }
1146  else // regular allocation/grant for data, for UGS flows or in response of requests for non-UGS flows
1147 
1148  {
1149 
1150  Ptr<WimaxConnection> connection = NULL;
1151  Simulator::Schedule (timeToAllocation,
1153  this,
1154  ulMapIe.GetUiuc (),
1155  ulMapIe.GetDuration (),
1156  connection,
1158  }
1159  }
1160  else
1161  {
1162  if (ulMapIe.GetUiuc () == OfdmUlBurstProfile::UIUC_INITIAL_RANGING && cid
1163  == GetBroadcastConnection ()->GetCid ()) // regular ranging interval
1164 
1165  {
1167  {
1168  m_linkManager->SetNrRangingTransOpps ((ulMapIe.GetDuration () * GetPhy ()->GetPsPerSymbol ())
1170 
1171  }
1172 
1174  {
1175  m_linkManager->StartContentionResolution ();
1176  }
1177 
1178  }
1179  }
1180  }
1181 }
1182 
1183 void
1185 {
1186  m_nrDcdRecvd++;
1188  {
1189  return; // nothing new in DCD so dont read
1190 
1191  }
1192  SetCurrentDcd (dcd);
1193  OfdmDcdChannelEncodings dcdChnlEncodings = dcd.GetChannelEncodings ();
1194 
1195  // parameters for initial ranging
1196  m_linkManager->SetBsEirp (dcdChnlEncodings.GetBsEirp ());
1197  m_linkManager->SetEirXPIrMax (dcdChnlEncodings.GetEirxPIrMax ());
1198 
1199  GetPhy ()->GetFrameDuration (dcdChnlEncodings.GetFrameDurationCode ());
1200 
1201  std::vector<OfdmDlBurstProfile> dlBurstProfiles = dcd.GetDlBurstProfiles ();
1202 
1203  for (std::vector<OfdmDlBurstProfile>::iterator iter = dlBurstProfiles.begin (); iter != dlBurstProfiles.end (); ++iter)
1204  {
1205  OfdmDlBurstProfile brstProfile = *iter;
1206 
1207  /*NS-2 does this, may be not correct, assumes DIUC/UIUC to
1208  modulation type mapping in DCD/UCD may change over time*/
1209  if (brstProfile.GetFecCodeType () == m_modulationType)
1210  {
1212  m_dlBurstProfile->SetDiuc (brstProfile.GetDiuc ());
1213  }
1214  }
1215 }
1216 
1217 void
1219 {
1220  m_nrUcdRecvd++;
1221  if (!m_linkManager->IsUlChannelUsable ())
1222  {
1223  m_linkManager->StartScanning (EVENT_NONE, false);
1224  return;
1225  }
1226 
1228  {
1229  return; // nothing new in UCD so don't read
1230 
1231  }
1232  SetCurrentUcd (ucd);
1233  m_linkManager->SetRangingCW ((uint8_t) std::pow ((double) 2, (double) ucd.GetRangingBackoffStart ()) - 1); // initializing ranging CW
1234  OfdmUcdChannelEncodings ucdChnlEncodings = ucd.GetChannelEncodings ();
1235 
1236  std::vector<OfdmUlBurstProfile> ulBurstProfiles = ucd.GetUlBurstProfiles ();
1237 
1238  for (std::vector<OfdmUlBurstProfile>::iterator iter = ulBurstProfiles.begin (); iter != ulBurstProfiles.end (); ++iter)
1239  {
1240  OfdmUlBurstProfile brstProfile = *iter;
1241 
1242  /*NS-2 does this, may be not correct, assumes DIUC/UIUC to
1243  modulation type mapping in DCD/UCD may change over time*/
1244  if (brstProfile.GetFecCodeType () == m_modulationType)
1245  {
1247  m_ulBurstProfile->SetUiuc (brstProfile.GetUiuc ());
1248  }
1249  }
1250 }
1251 
1252 /*temporarily assuming registered if ranging is complete,
1253  shall actually consider the registration step also */
1254 bool
1256 {
1257  return GetState () >= SS_STATE_REGISTERED;
1258 }
1259 
1260 Time
1262 {
1263  Time timeAlreadyElapsed = Simulator::Now () - m_frameStartTime;
1264  Time timeToUlSubframe = Seconds (m_allocationStartTime * GetPhy ()->GetPsDuration ().GetSeconds ())
1265  - timeAlreadyElapsed;
1266  return timeToUlSubframe + defferTime;
1267 }
1268 
1269 void
1271 {
1272  if (GetState () == SS_STATE_STOPPED)
1273  {
1274  Simulator::Cancel (eventId); // cancelling this event (already scheduled in function call)
1275  return;
1276  }
1277 
1278  event = eventId;
1279 }
1280 
1281 } // namespace ns`
void SendBandwidthRequest(uint8_t uiuc, uint16_t allocationSize)
uint8_t GetFecCodeType(void) const
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
HeaderType
this class implements the mac header type field.
OfdmDcdChannelEncodings GetChannelEncodings(void) const
void SetIntervalT3(Time interval3)
Doxygen introspection did not find any typical Config paths.
Definition: mac-messages.h:344
void SetTimer(EventId eventId, EventId &event)
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:79
bool GetIsEnabled(void) const
void SetIntervalT1(Time interval1)
Time GetIntervalT2(void) const
returns the wait for broadcast ranging timeout, i.e., wait for initial ranging opportunity ...
static Time GetDefaultLostDlMapInterval()
Doxygen introspection did not find any typical Config paths.
void SetLostDlMapInterval(Time lostDlMapInterval)
void ProcessUcd(const Ucd &ucd)
Time GetMaxUcdInterval(void) const
returns the maximum time between transmission of UCD messages
void ProcessDcd(const Dcd &dcd)
void SetIntervalT21(Time interval21)
Ptr< WimaxConnection > m_basicConnection
Doxygen introspection did not find any typical Config paths.
Definition: mac-messages.h:97
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
Ptr< WimaxConnection > m_primaryConnection
uint8_t GetFrameDurationCode(void) const
std::list< OfdmDlMapIe > GetDlMapElements(void) const
Doxygen introspection did not find any typical Config paths.
Definition: mac-messages.h:41
uint8_t GetConfigurationChangeCount(void) const
this class implements a structure to manage some parameters and statistics related to a service flow ...
void SetIntervalT2(Time interval2)
void SetModulationType(WimaxPhy::ModulationType modulationType)
Set the most efficient modulation and coding scheme (MCS) supported by the device.
bool GetAreManagementConnectionsAllocated(void) const
uint32_t GetBytesRcvd(void) const
void ProcessDlMap(const DlMap &dlmap)
bool IsMulticast(void) const
Definition: cid.cc:51
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
void SetMaxDcdInterval(Time maxDcdInterval)
Dcd GetCurrentDcd(void) const
void SetAreManagementConnectionsAllocated(bool areManagementConnectionsAllocated)
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
Time GetIntervalT7(void) const
returns the wait for DSA/DSC/DSD Response timeout
void SetLostUlMapInterval(Time lostUlMapInterval)
uint32_t GetSfid(void) const
Cid GetCid(void) const
uint8_t GetConfigurationChangeCount(void) const
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:223
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:95
Time GetLostUlMapInterval(void) const
returns the time since last received UL-MAP before uplink synchronization is considered lost ...
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 SetScheduler(Ptr< SSScheduler > ssScheduler)
bool IsRunning(void) const
This method is syntactic sugar for the ns3::Simulator::isExpired method.
Definition: event-id.cc:59
void SetMaxUcdInterval(Time maxUcdInterval)
Ptr< ConnectionManager > GetConnectionManager(void) const
Time GetIntervalT12(void) const
returns the wait for UCD descriptor timeout
Ptr< IpcsClassifier > GetIpcsClassifier() 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
TracedCallback< Ptr< const Packet > > m_ssPromiscRxTrace
The trace source fired for packets successfully received by the device immediately before being forwa...
uint8_t GetDcdCount(void) const
Ptr< SSScheduler > m_scheduler
void ProcessUlMap(const UlMap &ulmap)
Ptr< WimaxConnection > GetConnection(void) const
uint16_t GetRangReqOppSize(void) const
void SetDiuc(uint8_t diuc)
this class implements the Generic mac Header as described by IEEE Standard for Local and metropolitan...
uint8_t GetType(void) const
Ptr< SSScheduler > GetScheduler(void) const
uint8_t GetFc(void) const
void SetNrUlBurstProfiles(uint8_t nrUlBurstProfiles)
void DoReceive(Ptr< Packet > packet)
TracedCallback< Ptr< const Packet > > m_ssRxTrace
The trace source fired for packets successfully received by the device immediately before being forwa...
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 SetNrDlBurstProfiles(uint8_t nrDlBurstProfiles)
uint32_t GetSerializedSize(void) const
void SetIntervalT20(Time interval20)
void SetMaxContentionRangingRetries(uint8_t maxContentionRangingRetries)
Cid GetCid(void) const
void SetCurrentDcd(Dcd dcd)
hold objects of type ns3::Time
Definition: nstime.h:1008
void SetIntervalT12(Time interval12)
void SetFecCodeType(uint8_t fecCodeType)
bool DoSend(Ptr< Packet > packet, const Mac48Address &source, const Mac48Address &dest, uint16_t protocolNumber)
Hold an unsigned integer type.
Definition: uinteger.h:46
OfdmUcdChannelEncodings GetChannelEncodings(void) const
bool Enqueue(Ptr< Packet > packet, const MacHeaderType &hdrType, Ptr< WimaxConnection > connection)
Enqueue a packet into a connection queue.
void SetUiuc(uint8_t uiuc)
TracedCallback< Ptr< const Packet > > m_ssTxDropTrace
The trace source fired when packets coming into the "top" of the device are dropped at the MAC layer ...
Time GetTimeToAllocation(Time defferTime)
Doxygen introspection did not find any typical Config paths.
uint8_t GetRangingBackoffStart(void) const
Ptr< SsServiceFlowManager > m_serviceFlowManager
uint8_t GetFecCodeType(void) const
Doxygen introspection did not find any typical Config paths.
uint8_t GetHt(void) const
std::list< OfdmUlMapIe > GetUlMapElements(void) const
Ptr< WimaxConnection > GetInitialRangingConnection(void) const
Ptr< BandwidthManager > GetBandwidthManager(void) const
Ptr< SSLinkManager > GetLinkManager(void) const
TracedCallback< Ptr< const Packet > > m_ssTxTrace
The trace source fired when packets come into the "top" of the device at the L3/L2 transition...
uint8_t GetUiuc(void) const
Doxygen introspection did not find any typical Config paths.
void SendBurst(uint8_t uiuc, uint16_t nrSymbols, Ptr< WimaxConnection > connection, MacHeaderType::HeaderType packetType=MacHeaderType::HEADER_TYPE_GENERIC)
Sends a burst on the uplink frame.
Mac48Address GetMacAddress(void) const
Represents the HT (Header Type) field of generic MAC and bandwidth request headers.
TracedCallback< Ptr< const Packet > > m_ssRxDropTrace
The trace source fired when packets coming into the "top" of the device are dropped at the MAC layer ...
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
#define list
void UpdatePktsRcvd(uint32_t pktsRcvd)
update the number of received packets by adding pktsRcvd
uint8_t GetUiuc(void) const
uint16_t GetEirxPIrMax(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
uint16_t GetBsEirp(void) const
static TypeId GetTypeId(void)
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Definition: cid.h:35
void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
WimaxPhy::ModulationType GetModulationType(void) const
returns the most efficient modulation and coding scheme (MCS) supported by the device ...
uint32_t GetPktsRcvd(void) const
uint8_t GetUcdCount(void) const
Ucd GetCurrentUcd(void) const
an EUI-48 address
Definition: mac48-address.h:41
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
Ptr< SSLinkManager > m_linkManager
void SetBasicConnection(Ptr< WimaxConnection > basicConnection)
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
void SetPhy(Ptr< WimaxPhy > phy)
Mac48Address GetBaseStationId(void) const
ServiceFlowRecord * GetRecord(void) const
Ptr< WimaxConnection > GetBasicConnection(void) const
void SetAreServiceFlowsAllocated(bool areServiceFlowsAllocated)
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 NotifyPromiscTrace(Ptr< Packet > p)
Ptr< BurstProfileManager > GetBurstProfileManager(void) const
Time GetIntervalT21(void) const
returns the time the SS searches for (decodable) DL-MAP on a given channel
void SetLinkManager(Ptr< SSLinkManager >)
sets the link manager to be used
an identifier for simulation events.
Definition: event-id.h:46
std::vector< OfdmDlBurstProfile > GetDlBurstProfiles(void) const
std::vector< OfdmUlBurstProfile > GetUlBurstProfiles(void) const
void SetCurrentUcd(Ucd ucd)
Time GetIntervalT1(void) const
returns the wait for DCD timeout
Doxygen introspection did not find any typical Config paths.
void ForwardDown(Ptr< PacketBurst > burst, WimaxPhy::ModulationType modulationType)
Ptr< WimaxPhy > GetPhy(void) const
Time GetMaxDcdInterval(void) const
returns the maximum time between transmission of DCD messages
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:213
void SetIntervalT7(Time interval7)
uint8_t GetType(void) const
void CreateDefaultConnections(void)
uint32_t GetAllocationStartTime(void) const
uint32_t GetBytesSent(void) const
OfdmDlBurstProfile * m_dlBurstProfile
Time GetLostDlMapInterval(void) const
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:441
Time GetIntervalT20(void) const
returns the Time the SS searches for preambles on a given channel
void SetState(uint8_t state)
void SetServiceFlowManager(Ptr< SsServiceFlowManager >)
Sets the service flow manager to be installed on the device.
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:193
uint8_t GetDiuc(void) const
Ptr< IpcsClassifier > m_classifier
void InitSubscriberStationNetDevice(void)
initializes the net device and sets the parameters to the default values
bool check_hcs(void) const
WimaxPhy::ModulationType m_modulationType
void UpdateBytesSent(uint32_t bytesSent)
update the number of sent bytes by adding bytesSent
virtual void SetNode(Ptr< Node > node)
OfdmUlBurstProfile * m_ulBurstProfile
void SetIpcsPacketClassifier(Ptr< IpcsClassifier >)
Sets the packet classifier to be used.
Ptr< SsServiceFlowManager > GetServiceFlowManager(void) const
void AddServiceFlow(ServiceFlow *sf)
adds a new service flow
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
TracedCallback< Ptr< const Packet >, Mac48Address, Cid * > m_traceSSRx
static Time m_frameStartTime
uint16_t GetStartTime(void) const
void SetPrimaryConnection(Ptr< WimaxConnection > primaryConnection)
uint8_t GetMaxContentionRangingRetries(void) const
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:253
uint8_t GetState(void) const
void SetFecCodeType(uint8_t fecCodeType)
Ptr< WimaxConnection > GetPrimaryConnection(void) const
returns the primary connection currently usde
void SetLen(uint16_t len)
uint16_t GetCid(void) const
bool GetAreServiceFlowsAllocated(void) const
void UpdatePktsSent(uint32_t pktsSent)
update the number of sent packets by adding pktsSent
Time GetIntervalT3(void) const
returns the ranging Response reception timeout following the transmission of a ranging request ...
uint32_t GetPktsSent(void) const
void UpdateBytesRcvd(uint32_t bytesRcvd)
update the number of received bytes by adding bytesRcvd