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  ;
51 
53 {
54  return (MicroSeconds (500000));
55 }
56 
57 TypeId
59 {
60  static TypeId
61  tid =
62  TypeId ("ns3::SubscriberStationNetDevice")
63 
65 
66  .AddConstructor<SubscriberStationNetDevice> ()
67 
68  .AddAttribute ("BasicConnection",
69  "Basic connection",
70  PointerValue (),
71  MakePointerAccessor (&SubscriberStationNetDevice::m_basicConnection),
72  MakePointerChecker<WimaxConnection> ())
73 
74  .AddAttribute ("PrimaryConnection",
75  "Primary connection",
76  PointerValue (),
78  MakePointerChecker<WimaxConnection> ())
79 
80  .AddAttribute ("LostDlMapInterval",
81  "Time since last received DL-MAP message before downlink synchronization is considered lost. Maximum is 600ms",
82  TimeValue (Seconds (0.5)),
85  MakeTimeChecker ())
86 
87  .AddAttribute ("LostUlMapInterval",
88  "Time since last received UL-MAP before uplink synchronization is considered lost, maximum is 600.",
89  TimeValue (MilliSeconds (500)),
92  MakeTimeChecker ())
93 
94  .AddAttribute ("MaxDcdInterval",
95  "Maximum time between transmission of DCD messages. Maximum is 10s",
96  TimeValue (Seconds (10)),
99  MakeTimeChecker ())
100 
101  .AddAttribute ("MaxUcdInterval",
102  "Maximum time between transmission of UCD messages. Maximum is 10s",
103  TimeValue (Seconds (10)),
106  MakeTimeChecker ())
107 
108  .AddAttribute ("IntervalT1",
109  "Wait for DCD timeout. Maximum is 5*maxDcdInterval",
110  TimeValue (Seconds (50)),
113  MakeTimeChecker ())
114 
115  .AddAttribute ("IntervalT2",
116  "Wait for broadcast ranging timeout, i.e., wait for initial ranging opportunity. Maximum is 5*Ranging interval",
117  TimeValue (Seconds (10)),
120  MakeTimeChecker ())
121 
122  .AddAttribute ("IntervalT3",
123  "ranging Response reception timeout following the transmission of a ranging request. Maximum is 200ms",
124  TimeValue (Seconds (0.2)),
127  MakeTimeChecker ())
128 
129  .AddAttribute ("IntervalT7",
130  "wait for DSA/DSC/DSD Response timeout. Maximum is 1s",
131  TimeValue (Seconds (0.1)),
134  MakeTimeChecker ())
135 
136  .AddAttribute ("IntervalT12",
137  "Wait for UCD descriptor.Maximum is 5*MaxUcdInterval",
138  TimeValue (Seconds (10)),
141  MakeTimeChecker ())
142 
143  .AddAttribute ("IntervalT20",
144  "Time the SS searches for preambles on a given channel. Minimum is 2 MAC frames",
145  TimeValue (Seconds (0.5)),
148  MakeTimeChecker ())
149 
150  .AddAttribute ("IntervalT21",
151  "time the SS searches for (decodable) DL-MAP on a given channel",
152  TimeValue (Seconds (10)),
155  MakeTimeChecker ())
156 
157  .AddAttribute ("MaxContentionRangingRetries",
158  "Number of retries on contention Ranging Requests",
159  UintegerValue (16),
162  MakeUintegerChecker<uint8_t> (1, 16))
163 
164  .AddAttribute ("SSScheduler",
165  "The ss scheduler attached to this device.",
166  PointerValue (),
167  MakePointerAccessor (&SubscriberStationNetDevice::GetScheduler,
169  MakePointerChecker<SSScheduler> ())
170 
171  .AddAttribute ("LinkManager",
172  "The ss link manager attached to this device.",
173  PointerValue (),
174  MakePointerAccessor (&SubscriberStationNetDevice::GetLinkManager,
176  MakePointerChecker<SSLinkManager> ())
177 
178  .AddAttribute ("Classifier",
179  "The ss classifier attached to this device.",
180  PointerValue (),
181  MakePointerAccessor (&SubscriberStationNetDevice::GetIpcsClassifier,
183  MakePointerChecker<IpcsClassifier> ())
184 
185  .AddTraceSource ("SSTxDrop",
186  "A packet has been dropped in the MAC layer before being queued for transmission.",
188 
189  .AddTraceSource ("SSPromiscRx",
190  "A packet has been received by this device, has been passed up from the physical layer "
191  "and is being forwarded up the local protocol stack. This is a promiscuous trace,",
193 
194  .AddTraceSource ("SSRx",
195  "A packet has been received by this device, has been passed up from the physical layer "
196  "and is being forwarded up the local protocol stack. This is a non-promiscuous trace,",
198 
199  .AddTraceSource ("SSRxDrop",
200  "A packet has been dropped in the MAC layer after it has been passed up from the physical "
201  "layer.",
203  return tid;
204 }
205 
207 {
208 
210 
211 }
212 
213 void
215 {
216  m_lostDlMapInterval = MilliSeconds (500);
217  m_lostUlMapInterval = MilliSeconds (500);
218  m_maxDcdInterval = Seconds (10);
219  m_maxUcdInterval = Seconds (10);
220  m_intervalT1 = Seconds (5 * m_maxDcdInterval.GetSeconds ());
221  m_intervalT2 = Seconds (5 * 2); // shall be 5 * RangingInterval, if ranging interval=see T2 at page 638) means Initial Ranging Interval=see page 637)
222  m_intervalT3 = MilliSeconds (200);
223  m_intervalT7 = Seconds (0.1); // maximum is 1
224  m_intervalT12 = Seconds (5 * m_maxUcdInterval.GetSeconds ());
225  m_intervalT21 = Seconds (11);
227  m_dcdCount = 0;
228  m_baseStationId = Mac48Address ("00:00:00:00:00:00");
229  m_ucdCount = 0;
231  m_nrDlMapElements = 0;
232  m_nrUlMapElements = 0;
233  m_nrDlMapRecvd = 0;
234  m_nrUlMapRecvd = 0;
235  m_nrDcdRecvd = 0;
236  m_nrUcdRecvd = 0;
240 
241  m_basicConnection = 0;
243 
246  m_classifier = CreateObject<IpcsClassifier> ();
247  m_linkManager = CreateObject<SSLinkManager> (this);
248  m_scheduler = CreateObject<SSScheduler> (this);
249  m_serviceFlowManager = CreateObject<SsServiceFlowManager> (this);
250 }
251 
253 {
255  this->SetNode (node);
256  this->SetPhy (phy);
257 }
258 
260 {
261 }
262 
263 void
265 {
266  delete m_dlBurstProfile;
267  delete m_ulBurstProfile;
268  m_scheduler = 0;
270  m_basicConnection = 0;
272  m_classifier = 0;
273  m_dlBurstProfile = 0;
274  m_ulBurstProfile = 0;
275 
276  m_linkManager = 0;
277 
279 }
280 
281 void
283 {
284  m_lostDlMapInterval = lostDlMapInterval;
285 }
286 
287 Time
289 {
290  return m_lostDlMapInterval;
291 }
292 
293 void
295 {
296  m_lostUlMapInterval = lostUlMapInterval;
297 }
298 
299 Time
301 {
302  return m_lostUlMapInterval;
303 }
304 
305 void
307 {
308  m_maxDcdInterval = maxDcdInterval;
309 }
310 
311 Time
313 {
314  return m_maxDcdInterval;
315 }
316 
317 void
319 {
320  m_maxUcdInterval = maxUcdInterval;
321 }
322 
323 Time
325 {
326  return m_maxUcdInterval;
327 }
328 
329 void
331 {
332  m_intervalT1 = interval;
333 }
334 
335 Time
337 {
338  return m_intervalT1;
339 }
340 
341 void
343 {
344  m_intervalT2 = interval;
345 }
346 
347 Time
349 {
350  return m_intervalT2;
351 }
352 
353 void
355 {
356  m_intervalT3 = interval;
357 }
358 
359 Time
361 {
362  return m_intervalT3;
363 }
364 
365 void
367 {
368  m_intervalT7 = interval;
369 }
370 
371 Time
373 {
374  return m_intervalT7;
375 }
376 
377 void
379 {
380  m_intervalT12 = interval;
381 }
382 
383 Time
385 {
386  return m_intervalT12;
387 }
388 
389 void
391 {
392  m_intervalT20 = interval;
393 }
394 
395 Time
397 {
398  return m_intervalT20;
399 }
400 
401 void
403 {
404  m_intervalT21 = interval;
405 }
406 
407 Time
409 {
410  return m_intervalT21;
411 }
412 
413 void
415 {
416  m_maxContentionRangingRetries = maxContentionRangingRetries;
417 }
418 
419 uint8_t
421 {
423 }
424 
425 void
427 {
428  m_basicConnection = basicConnection;
429 }
430 
433 {
434  return m_basicConnection;
435 }
436 
437 void
439 {
440  m_primaryConnection = primaryConnection;
441 }
442 
445 {
446  return m_primaryConnection;
447 }
448 
449 Cid
451 {
452  return m_basicConnection->GetCid ();
453 }
454 
455 Cid
457 {
458  return m_primaryConnection->GetCid ();
459 }
460 
461 void
463 {
464  m_modulationType = modulationType;
465 }
466 
469 {
470  return m_modulationType;
471 }
472 
473 void
475 {
476  m_areManagementConnectionsAllocated = areManagementConnectionsAllocated;
477 }
478 
479 bool
481 {
483 }
484 
485 void
487 {
488  m_areServiceFlowsAllocated = areServiceFlowsAllocated;
489 }
490 
491 bool
493 {
495 }
496 
499 {
500  return m_scheduler;
501 }
502 
503 void
505 {
506  m_scheduler = scheduler;
507 }
508 
509 bool
511 {
512  return GetServiceFlowManager ()->GetServiceFlows (ServiceFlow::SF_TYPE_ALL).size () > 0;
513 }
514 
517 {
518 
519  return m_classifier;
520 }
521 
522 void
524 {
525  m_classifier = classifier;
526 }
527 
530 {
531  return m_linkManager;
532 }
533 
534 void
536 {
537  m_linkManager = linkManager;
538 }
539 
542 {
543  return m_serviceFlowManager;
544 }
545 
546 void
548 {
549  m_serviceFlowManager = sfm;
550 }
551 
552 void
554 {
556 
557  GetPhy ()->SetPhyParameters ();
558  GetPhy ()->SetDataRates ();
559  m_intervalT20 = Seconds (4 * GetPhy ()->GetFrameDuration ().GetSeconds ());
560 
563 }
564 
565 void
567 {
569 }
570 
571 void
573 {
574  GetServiceFlowManager ()->AddServiceFlow (sf);
575 }
576 
577 void
579 {
580  GetServiceFlowManager ()->AddServiceFlow (sf);
581 }
582 
583 bool
585  const Mac48Address &source,
586  const Mac48Address &dest,
587  uint16_t protocolNumber)
588 {
589  NS_LOG_INFO ("SS (" << source << "):" );
590  NS_LOG_INFO ("\tSending packet..." );
591  NS_LOG_INFO ("\t\tDestination: " << dest );
592  NS_LOG_INFO ("\t\tPacket Size: " << packet->GetSize () );
593  NS_LOG_INFO ("\t\tProtocol: " << protocolNumber );
594 
595  ServiceFlow *serviceFlow = 0;
596 
597  if (IsRegistered ())
598  {
599  NS_LOG_DEBUG ("SS (Basic CID: " << m_basicConnection->GetCid () << ")");
600  }
601  else
602  {
603  NS_LOG_DEBUG ("SS (" << GetMacAddress () << ")");
604  NS_LOG_INFO ("\tCan't send packet! (NotRegitered with the network)");
605  return false;
606  }
607 
608  NS_LOG_DEBUG ("packet to send, size : " << packet->GetSize () << ", destination : " << dest);
609 
610  if (GetServiceFlowManager ()->GetNrServiceFlows () == 0)
611  {
612  NS_LOG_INFO ("\tCan't send packet! (No service Flow)");
613  return false;
614  }
615 
616  if (protocolNumber == 2048)
617  {
618  serviceFlow = m_classifier->Classify (packet, GetServiceFlowManager (), ServiceFlow::SF_DIRECTION_UP);
619  }
620 
621  if ((protocolNumber != 2048) || (serviceFlow == NULL))
622  {
623  serviceFlow = *GetServiceFlowManager ()->GetServiceFlows (ServiceFlow::SF_TYPE_ALL).begin ();
624  NS_LOG_INFO ("\tNo service flows matches...using the default one.");
625  }
626 
627  NS_LOG_INFO ("\tPacket classified in the service flow SFID = " << serviceFlow->GetSfid () << " CID = "
628  << serviceFlow->GetCid ());
629  if (serviceFlow->GetIsEnabled ())
630  {
631  if (!Enqueue (packet, MacHeaderType (), serviceFlow->GetConnection ()))
632  {
633  NS_LOG_INFO ("\tEnqueue ERROR!!" );
634  m_ssTxDropTrace (packet);
635  return false;
636  }
637  else
638  {
639  m_ssTxTrace (packet);
640  }
641  }
642  else
643  {
644  NS_LOG_INFO ("Error!! The Service Flow is not enabled" );
645  m_ssTxDropTrace (packet);
646  return false;
647  }
648 
649  return true;
650 }
651 
652 bool
654  const MacHeaderType &hdrType,
655  Ptr<WimaxConnection> connection)
656 {
657  NS_ASSERT_MSG (connection != 0, "SS: Can not enqueue the packet: the selected connection is nor initialized");
658 
659  GenericMacHeader hdr;
660 
662  {
663  hdr.SetLen (packet->GetSize () + hdr.GetSerializedSize ());
664  hdr.SetCid (connection->GetCid ());
665 
666  }
667 
668  if (connection->GetType () == Cid::TRANSPORT)
669  {
670 
671  if (connection->GetSchedulingType () == ServiceFlow::SF_TYPE_UGS && m_scheduler->GetPollMe ())
672  {
674  "Error while equeuing packet: incorrect header type");
675 
676  GrantManagementSubheader grantMgmntSubhdr;
677  grantMgmntSubhdr.SetPm (true);
678  packet->AddHeader (grantMgmntSubhdr);
679  }
680  }
681  NS_LOG_INFO ("ServiceFlowManager: enqueuing packet" );
682  return connection->Enqueue (packet, hdrType, hdr);
683 }
684 
685 void
687  uint16_t nrSymbols,
688  Ptr<WimaxConnection> connection,
689  MacHeaderType::HeaderType packetType)
690 {
691  WimaxPhy::ModulationType modulationType;
692 
694  {
695  modulationType = WimaxPhy::MODULATION_TYPE_BPSK_12;
696  }
697  else
698  {
699  modulationType = GetBurstProfileManager ()->GetModulationType (uiuc, DIRECTION_UPLINK);
700  }
701  Ptr<PacketBurst> burst = m_scheduler->Schedule (nrSymbols, modulationType, packetType, connection);
702 
703  if (burst->GetNPackets () == 0)
704  {
705  return;
706  }
707 
708  if (IsRegistered ())
709  {
710  NS_LOG_DEBUG ("SS (Basic CID: " << m_basicConnection->GetCid () << ")");
711  }
712  else
713  {
714  NS_LOG_DEBUG ("SS (" << GetMacAddress () << ")");
715  }
716 
717  if (connection->GetType () == Cid::TRANSPORT)
718  {
719  ServiceFlowRecord *record = connection->GetServiceFlow ()->GetRecord ();
720  record->UpdatePktsSent (burst->GetNPackets ());
721  record->UpdateBytesSent (burst->GetSize ());
722 
723  NS_LOG_DEBUG (" sending burst" << ", SFID: " << connection->GetServiceFlow ()->GetSfid () << ", pkts sent: "
724  << record->GetPktsSent () << ", pkts rcvd: " << record->GetPktsRcvd () << ", bytes sent: "
725  << record->GetBytesSent () << ", bytes rcvd: " << record->GetBytesRcvd () );
726 
727  }
728  else
729  {
730 
731  }
732  ForwardDown (burst, modulationType);
733 }
734 
735 void
737 {
738  GenericMacHeader gnrcMacHdr;
739  ManagementMessageType msgType;
740  RngRsp rngrsp;
741  Cid cid;
742  uint32_t pktSize = packet->GetSize ();
743  packet->RemoveHeader (gnrcMacHdr);
744  FragmentationSubheader fragSubhdr;
745  bool fragmentation = false; // it becames true when there is a fragmentation subheader
746 
747  if (gnrcMacHdr.GetHt () == MacHeaderType::HEADER_TYPE_GENERIC)
748  {
749  if (gnrcMacHdr.check_hcs () == false)
750  {
751  // The header is noisy
752  NS_LOG_INFO ("Header HCS ERROR");
753  m_ssRxDropTrace (packet);
754  return;
755  }
756 
757  cid = gnrcMacHdr.GetCid ();
758 
759  // checking for subheaders
760  uint8_t type = gnrcMacHdr.GetType ();
761  if (type)
762  {
763  // Check if there is a fragmentation Subheader
764  uint8_t tmpType = type;
765  if (((tmpType >> 2) & 1) == 1)
766  {
767  // a TRANSPORT packet with fragmentation subheader has been received!
768  fragmentation = true;
769  NS_LOG_INFO ("SS DoReceive -> the packet is a fragment" << std::endl);
770  }
771  }
772 
773  if (cid == GetBroadcastConnection ()->GetCid () && !fragmentation)
774  {
775  packet->RemoveHeader (msgType);
776  switch (msgType.GetType ())
777  {
779  {
781  {
782  Simulator::Cancel (m_linkManager->GetDlMapSyncTimeoutEvent ());
783  }
784 
786  {
788  }
789 
790  m_linkManager->ScheduleScanningRestart (m_lostDlMapInterval, EVENT_LOST_DL_MAP, false, m_lostDlMapEvent);
791 
793  {
795  }
796 
797  m_linkManager->ScheduleScanningRestart (m_intervalT1,
799  false,
801 
803  {
805  }
806 
807  m_linkManager->ScheduleScanningRestart (m_intervalT12,
809  true,
811 
812  DlMap dlmap;
813  packet->RemoveHeader (dlmap);
814  ProcessDlMap (dlmap);
815  break;
816  }
818  {
820  {
822  m_linkManager->ScheduleScanningRestart (m_lostUlMapInterval,
824  true,
826  }
827 
828  UlMap ulmap;
829  packet->RemoveHeader (ulmap);
830 
831  ProcessUlMap (ulmap);
832 
834  {
835  if (m_linkManager->GetRangingIntervalFound ())
836  {
838  {
840  }
841  m_linkManager->PerformBackoff ();
842  }
843  }
844  break;
845  }
847  {
849  {
851  }
852 
854  {
856  m_linkManager->ScheduleScanningRestart (m_intervalT1,
858  false,
860  }
861 
862  Dcd dcd;
863  // number of burst profiles is set to number of DL-MAP IEs after processing DL-MAP, not a very good solution
864  // dcd.SetNrDlBurstProfiles (m_nrDlMapElements);
865  dcd.SetNrDlBurstProfiles (7);
866  packet->RemoveHeader (dcd);
867 
868  ProcessDcd (dcd);
869  break;
870  }
872  {
873  Ucd ucd;
874  // number of burst profiles is set to number of UL-MAP IEs after processing UL-MAP, not a very good solution
875  // ucd.SetNrUlBurstProfiles (m_nrUlMapElements);
876  ucd.SetNrUlBurstProfiles (7);
877  packet->RemoveHeader (ucd);
878 
879  ProcessUcd (ucd);
880 
882  {
884  m_linkManager->ScheduleScanningRestart (m_intervalT12,
886  true,
888  }
889 
891  {
892  /*state indicating that SS has completed scanning, synchronization and parameter acquisition
893  successfully and now waiting for UL-MAP to start initial ranging.*/
895 
896  m_linkManager->ScheduleScanningRestart (m_intervalT2,
898  false,
900  m_linkManager->ScheduleScanningRestart (m_lostUlMapInterval,
902  true,
904  }
905  break;
906  }
907  default:
908  NS_FATAL_ERROR ("Invalid management message type");
909  }
910  }
911  else if (GetInitialRangingConnection () != 0 && cid == GetInitialRangingConnection ()->GetCid () && !fragmentation)
912  {
913  m_traceSSRx (packet, GetMacAddress (), &cid);
914  packet->RemoveHeader (msgType);
915  switch (msgType.GetType ())
916  {
918  // intended for base station, ignore
919  break;
922  "SS: Error while receiving a ranging response message: SS state should be SS_STATE_WAITING_RNG_RSP");
923  packet->RemoveHeader (rngrsp);
924  m_linkManager->PerformRanging (cid, rngrsp);
925  break;
926  default:
927  NS_LOG_ERROR ("Invalid management message type");
928  }
929  }
930  else if (m_basicConnection != 0 && cid == m_basicConnection->GetCid () && !fragmentation)
931  {
932  m_traceSSRx (packet, GetMacAddress (), &cid);
933  packet->RemoveHeader (msgType);
934  switch (msgType.GetType ())
935  {
937  // intended for base station, ignore
938  break;
941  "SS: Error while receiving a ranging response message: SS state should be SS_STATE_WAITING_RNG_RSP");
942  packet->RemoveHeader (rngrsp);
943  m_linkManager->PerformRanging (cid, rngrsp);
944  break;
945  default:
946  NS_LOG_ERROR ("Invalid management message type");
947  }
948  }
949  else if (m_primaryConnection != 0 && cid == m_primaryConnection->GetCid () && !fragmentation)
950  {
951  m_traceSSRx (packet, GetMacAddress (), &cid);
952  packet->RemoveHeader (msgType);
953  switch (msgType.GetType ())
954  {
956  // not yet implemented
957  break;
959  // intended for base station, ignore
960  break;
962  /*from other station as DSA initiation
963  by BS is not supported, ignore*/
964  break;
966  {
967  Simulator::Cancel (GetServiceFlowManager ()->GetDsaRspTimeoutEvent ());
968  DsaRsp dsaRsp;
969  packet->RemoveHeader (dsaRsp);
970  GetServiceFlowManager ()->ProcessDsaRsp (dsaRsp);
971  break;
972  }
974  /*from other station as DSA initiation
975  by BS is not supported, ignore*/
976  break;
977  default:
978  NS_LOG_ERROR ("Invalid management message type");
979  }
980  }
981  else if (GetConnectionManager ()->GetConnection (cid)) // transport connection
982  {
983  ServiceFlow *serviceFlow = GetConnectionManager ()->GetConnection (cid)->GetServiceFlow ();
984  ServiceFlowRecord *record = serviceFlow->GetRecord ();
985 
986  record->UpdatePktsRcvd (1);
987  record->UpdateBytesRcvd (pktSize);
988 
989  // If fragmentation is true, the packet is a fragment.
990  if (!fragmentation)
991  {
992  m_ssRxTrace (packet);
993  ForwardUp (packet, m_baseStationId, GetMacAddress ()); // source shall be BS's address or sender SS's?
994  }
995  else
996  {
997  NS_LOG_INFO ( "FRAG_DEBUG: SS DoReceive, the Packet is a fragment" << std::endl);
998  packet->RemoveHeader (fragSubhdr);
999  uint32_t fc = fragSubhdr.GetFc ();
1000  NS_LOG_INFO ( "\t fragment size = " << packet->GetSize () << std::endl);
1001 
1002  if (fc == 2)
1003  {
1004  // This is the latest fragment.
1005  // Take the fragment queue, defragment a packet and send it to the upper layer
1006  NS_LOG_INFO ( "\t Received the latest fragment" << std::endl);
1007  GetConnectionManager ()->GetConnection (cid)
1008  ->FragmentEnqueue (packet);
1009 
1011  GetConnection (cid)->GetFragmentsQueue ();
1012 
1013  Ptr<Packet> fullPacket = Create<Packet> ();
1014 
1015  // DEFRAGMENTATION
1016  NS_LOG_INFO ( "\t SS PACKET DEFRAGMENTATION" << std::endl);
1017  for (std::list<Ptr<const Packet> >::const_iterator iter = fragmentsQueue.begin ();
1018  iter != fragmentsQueue.end (); ++iter)
1019  {
1020  // Create the whole Packet
1021  fullPacket->AddAtEnd (*iter);
1022  }
1023  GetConnectionManager ()->GetConnection (cid)
1024  ->ClearFragmentsQueue ();
1025  NS_LOG_INFO ( "\t fullPacket size = " << fullPacket->GetSize () << std::endl);
1026 
1027  m_ssRxTrace (fullPacket);
1028  ForwardUp (fullPacket, m_baseStationId, GetMacAddress ()); // source shall be BS's address or sender SS's?
1029  }
1030  else
1031  {
1032  // This is the first or middle fragment.
1033  // Take the fragment queue, store the fragment into the queue
1034  NS_LOG_INFO ( "\t Received the first or the middle fragment" << std::endl);
1035  GetConnectionManager ()->GetConnection (cid)->FragmentEnqueue (packet);
1036  }
1037  }
1038  }
1039  else if (cid.IsMulticast ())
1040  {
1041  m_traceSSRx (packet, GetMacAddress (), &cid);
1042  ForwardUp (packet, m_baseStationId, GetMacAddress ()); // source shall be BS's address or sender SS's?
1043  }
1044  else if (IsPromisc ())
1045  {
1046  NotifyPromiscTrace (packet);
1047  m_ssPromiscRxTrace (packet);
1048 
1049  // not for me, ignore
1050  }
1051  else
1052  {
1053  // not for me drop
1054  }
1055  }
1056  else
1057  {
1058  // from other SS, ignore
1059  }
1060 }
1061 
1062 void
1064 {
1065  m_nrDlMapRecvd++;
1066  m_dcdCount = dlmap.GetDcdCount ();
1067  m_baseStationId = dlmap.GetBaseStationId ();
1068  std::list<OfdmDlMapIe> dlMapElements = dlmap.GetDlMapElements ();
1069 
1070  for (std::list<OfdmDlMapIe>::iterator iter = dlMapElements.begin (); iter != dlMapElements.end (); ++iter)
1071  {
1072  if (iter->GetDiuc () == OfdmDlBurstProfile::DIUC_END_OF_MAP)
1073  {
1074  break;
1075  }
1076 
1077  if (iter->GetCid () == m_basicConnection->GetCid ())
1078  {
1079  /*here the SS shall actually acquire the start time it shall start receiving the burst at. start time is used for power saving
1080  which is not implemented here, furthermore there is no need since the simulator architecture automatically callbacks the receive
1081  function. shall acquire the DIUC (burst profile) as well to decode the burst, again not required again because the callback
1082  mechanism automatically passes it as parameter.*/
1083  }
1084 
1085 #if 0 /* a template for future implementation following */
1086  uint8_t temp = iter->GetDiuc ();
1087  temp = iter->GetPreamblePresent ();
1088  temp = iter->GetStartTime ();
1089 #endif
1090  }
1091 }
1092 
1093 void
1095 {
1096  m_nrUlMapRecvd++;
1097  m_ucdCount = ulmap.GetUcdCount ();
1099  std::list<OfdmUlMapIe> ulMapElements = ulmap.GetUlMapElements ();
1100  m_linkManager->SetRangingIntervalFound (false);
1101 
1102  for (std::list<OfdmUlMapIe>::iterator iter = ulMapElements.begin (); iter != ulMapElements.end (); ++iter)
1103  {
1104  OfdmUlMapIe ulMapIe = *iter;
1105 
1106  if (ulMapIe.GetUiuc () == OfdmUlBurstProfile::UIUC_END_OF_MAP)
1107  {
1108  break;
1109  }
1110 
1111  Cid cid = ulMapIe.GetCid ();
1112 
1113  if (ulMapIe.GetUiuc () == OfdmUlBurstProfile::UIUC_INITIAL_RANGING && cid == GetBroadcastConnection ()->GetCid ())
1114  {
1115  m_linkManager->SetRangingIntervalFound (true);
1116  }
1117 
1118  if (m_areManagementConnectionsAllocated && cid == m_basicConnection->GetCid ())
1119  {
1120 
1121  Time timeToAllocation = GetTimeToAllocation (Seconds (ulMapIe.GetStartTime ()
1122  * GetPhy ()->GetSymbolDuration ().GetSeconds ()));
1123 
1124  if (ulMapIe.GetUiuc () == OfdmUlBurstProfile::UIUC_INITIAL_RANGING) // invited ranging interval
1125 
1126  {
1127 
1128  m_linkManager->IncrementNrInvitedPollsRecvd ();
1130  "SS: Error while processing UL MAP: SS state should be SS_STATE_WAITING_INV_RANG_INTRVL");
1131  Simulator::Schedule (timeToAllocation,
1133  m_linkManager,
1134  ulMapIe.GetUiuc (),
1135  ulMapIe.GetDuration ());
1136  }
1137  else if (ulMapIe.GetUiuc () == OfdmUlBurstProfile::UIUC_REQ_REGION_FULL) // unicast poll
1138 
1139  {
1140 
1141  Simulator::Schedule (timeToAllocation,
1144  ulMapIe.GetUiuc (),
1145  ulMapIe.GetDuration ());
1146  }
1147  else // regular allocation/grant for data, for UGS flows or in response of requests for non-UGS flows
1148 
1149  {
1150 
1151  Ptr<WimaxConnection> connection = NULL;
1152  Simulator::Schedule (timeToAllocation,
1154  this,
1155  ulMapIe.GetUiuc (),
1156  ulMapIe.GetDuration (),
1157  connection,
1159  }
1160  }
1161  else
1162  {
1163  if (ulMapIe.GetUiuc () == OfdmUlBurstProfile::UIUC_INITIAL_RANGING && cid
1164  == GetBroadcastConnection ()->GetCid ()) // regular ranging interval
1165 
1166  {
1168  {
1169  m_linkManager->SetNrRangingTransOpps ((ulMapIe.GetDuration () * GetPhy ()->GetPsPerSymbol ())
1171 
1172  }
1173 
1175  {
1176  m_linkManager->StartContentionResolution ();
1177  }
1178 
1179  }
1180  }
1181  }
1182 }
1183 
1184 void
1186 {
1187  m_nrDcdRecvd++;
1189  {
1190  return; // nothing new in DCD so dont read
1191 
1192  }
1193  SetCurrentDcd (dcd);
1194  OfdmDcdChannelEncodings dcdChnlEncodings = dcd.GetChannelEncodings ();
1195 
1196  // parameters for initial ranging
1197  m_linkManager->SetBsEirp (dcdChnlEncodings.GetBsEirp ());
1198  m_linkManager->SetEirXPIrMax (dcdChnlEncodings.GetEirxPIrMax ());
1199 
1200  GetPhy ()->GetFrameDuration (dcdChnlEncodings.GetFrameDurationCode ());
1201 
1202  std::vector<OfdmDlBurstProfile> dlBurstProfiles = dcd.GetDlBurstProfiles ();
1203 
1204  for (std::vector<OfdmDlBurstProfile>::iterator iter = dlBurstProfiles.begin (); iter != dlBurstProfiles.end (); ++iter)
1205  {
1206  OfdmDlBurstProfile brstProfile = *iter;
1207 
1208  /*NS-2 does this, may be not correct, assumes DIUC/UIUC to
1209  modulation type mapping in DCD/UCD may change over time*/
1210  if (brstProfile.GetFecCodeType () == m_modulationType)
1211  {
1213  m_dlBurstProfile->SetDiuc (brstProfile.GetDiuc ());
1214  }
1215  }
1216 }
1217 
1218 void
1220 {
1221  m_nrUcdRecvd++;
1222  if (!m_linkManager->IsUlChannelUsable ())
1223  {
1224  m_linkManager->StartScanning (EVENT_NONE, false);
1225  return;
1226  }
1227 
1229  {
1230  return; // nothing new in UCD so don't read
1231 
1232  }
1233  SetCurrentUcd (ucd);
1234  m_linkManager->SetRangingCW ((uint8_t) std::pow ((double) 2, (double) ucd.GetRangingBackoffStart ()) - 1); // initializing ranging CW
1235  OfdmUcdChannelEncodings ucdChnlEncodings = ucd.GetChannelEncodings ();
1236 
1237  std::vector<OfdmUlBurstProfile> ulBurstProfiles = ucd.GetUlBurstProfiles ();
1238 
1239  for (std::vector<OfdmUlBurstProfile>::iterator iter = ulBurstProfiles.begin (); iter != ulBurstProfiles.end (); ++iter)
1240  {
1241  OfdmUlBurstProfile brstProfile = *iter;
1242 
1243  /*NS-2 does this, may be not correct, assumes DIUC/UIUC to
1244  modulation type mapping in DCD/UCD may change over time*/
1245  if (brstProfile.GetFecCodeType () == m_modulationType)
1246  {
1248  m_ulBurstProfile->SetUiuc (brstProfile.GetUiuc ());
1249  }
1250  }
1251 }
1252 
1253 /*temporarily assuming registered if ranging is complete,
1254  shall actually consider the registration step also */
1255 bool
1257 {
1258  return GetState () >= SS_STATE_REGISTERED;
1259 }
1260 
1261 Time
1263 {
1264  Time timeAlreadyElapsed = Simulator::Now () - m_frameStartTime;
1265  Time timeToUlSubframe = Seconds (m_allocationStartTime * GetPhy ()->GetPsDuration ().GetSeconds ())
1266  - timeAlreadyElapsed;
1267  return timeToUlSubframe + defferTime;
1268 }
1269 
1270 void
1272 {
1273  if (GetState () == SS_STATE_STOPPED)
1274  {
1275  Simulator::Cancel (eventId); // cancelling this event (already scheduled in function call)
1276  return;
1277  }
1278 
1279  event = eventId;
1280 }
1281 
1282 } // 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:335
void SetTimer(EventId eventId, EventId &event)
keep track of time values and allow control of global simulation resolution
Definition: nstime.h:81
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
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)
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
void SetMaxDcdInterval(Time maxDcdInterval)
Dcd GetCurrentDcd(void) const
void SetAreManagementConnectionsAllocated(bool areManagementConnectionsAllocated)
Ptr< WimaxConnection > GetBroadcastConnection(void) const
uint32_t GetSize(void) const
Definition: packet.h:650
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)
Definition: log.h:298
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:824
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...
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
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:274
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:961
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.
NS_LOG_COMPONENT_DEFINE("SubscriberStationNetDevice")
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:985
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)
Definition: assert.h:86
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)
Definition: log.h:289
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:452
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)
Definition: log.h:271
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:611
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