A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ss-link-manager.cc
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 "ss-link-manager.h"
24 #include <stdint.h>
25 #include "ns3/node.h"
26 #include "ns3/packet.h"
27 #include "ns3/simulator.h"
28 #include "ns3/log.h"
29 #include "ns3/pointer.h"
30 #include "ns3/enum.h"
31 #include "burst-profile-manager.h"
32 #include "service-flow-manager.h"
33 
34 NS_LOG_COMPONENT_DEFINE ("SSLinkManager");
35 
36 namespace ns3 {
37 
38 NS_OBJECT_ENSURE_REGISTERED (SSLinkManager);
39 
40 TypeId SSLinkManager::GetTypeId (void)
41 {
42  static TypeId tid = TypeId ("ns3::SSLinkManager")
43  .SetParent<Object> ();
44  return tid;
45 }
46 
47 SSLinkManager::SSLinkManager (Ptr<SubscriberStationNetDevice> ss)
48  : m_ss (ss),
49  m_rangingStatus (WimaxNetDevice::RANGING_STATUS_EXPIRED),
50  m_bsEirp (65535),
51  m_eirXPIrMax (65535),
52  m_pTxIrMax (0),
53  m_initRangOppNumber (0),
54  m_contentionRangingRetries (0),
55  m_rngReqFrameNumber (0),
56  m_dlChnlNr (0),
57  m_frequency (0),
58  m_rangingIntervalFound (false),
59  m_nrRngReqsSent (0),
60  m_nrRngRspsRecvd (0),
61  m_nrInvitedPollsRecvd (0),
62  m_rangingCW (0),
63  m_rangingBO (0),
64  m_nrRangingTransOpps (0),
65  m_isBackoffSet (false),
66  m_rangingAnomalies (0)
67 {
68 
69 }
70 
71 SSLinkManager::~SSLinkManager (void)
72 {
73  m_ss = 0;
74 }
75 
76 
77 void
79 {
80  m_ss = 0;
81 }
82 
83 void
84 SSLinkManager::SetBsEirp (uint16_t bs_eirp)
85 {
86  m_bsEirp = bs_eirp;
87 }
88 
89 void
90 SSLinkManager::SetEirXPIrMax (uint16_t eir_x_p_ir_max)
91 {
92  m_eirXPIrMax = eir_x_p_ir_max;
93 }
94 
95 void
96 SSLinkManager::SetRangingIntervalFound (bool rangingIntervalFound)
97 {
98  m_rangingIntervalFound = rangingIntervalFound;
99 }
100 
101 bool
102 SSLinkManager::GetRangingIntervalFound (void) const
103 {
104  return m_rangingIntervalFound;
105 }
106 
107 void
108 SSLinkManager::SetNrRangingTransOpps (uint8_t nrRangingTransOpps)
109 {
110  m_nrRangingTransOpps = nrRangingTransOpps;
111 }
112 
113 void
114 SSLinkManager::SetRangingCW (uint8_t rangingCW)
115 {
116  m_rangingCW = rangingCW;
117 }
118 
119 void
120 SSLinkManager::IncrementNrInvitedPollsRecvd (void)
121 {
122  m_nrInvitedPollsRecvd++;
123 }
124 
125 EventId
126 SSLinkManager::GetDlMapSyncTimeoutEvent (void)
127 {
128  return m_dlMapSyncTimeoutEvent;
129 }
130 
131 void
132 SSLinkManager::StartScanning (
133  SubscriberStationNetDevice::EventType type, bool deleteParameters)
134 {
135  // temp parameter "type" just to check on expiry of which event the function was called
136 
137  if (deleteParameters)
138  {
139  DeleteUplinkParameters ();
140  }
141 
142  NS_ASSERT_MSG (!m_ss->IsRegistered (),
143  "Subscriber Station: Error while scanning: Already registered with a BS");
144 
145  if (m_ss->GetState () != SubscriberStationNetDevice::SS_STATE_IDLE)
146  {
147  m_dlChnlNr++;
148  }
149 
150  // using max number of channel according to according to Section 8.5.1 of IEEE 802.16-2004 standard.
151  if (m_dlChnlNr >= 200)
152  {
153  m_dlChnlNr = 0;
154  }
155 
156  uint64_t dlChannel = m_ss->GetChannel (m_dlChnlNr);
157 
158  m_ss->SetState (SubscriberStationNetDevice::SS_STATE_SCANNING);
159  m_ss->GetPhy ()->StartScanning (dlChannel, m_ss->GetIntervalT20 (),
160  MakeCallback (&SSLinkManager::EndScanning, this));
161 }
162 
163 void
164 SSLinkManager::EndScanning (bool status, uint64_t frequency)
165 {
166  if (status)
167  {
168  StartSynchronizing ();
169  m_frequency = frequency;
170  }
171  else
172  {
173  StartScanning (SubscriberStationNetDevice::EVENT_NONE, false);
174  }
175 }
176 
177 void
178 SSLinkManager::StartSynchronizing (void)
179 {
180  m_ss->SetState (SubscriberStationNetDevice::SS_STATE_SYNCHRONIZING);
181  m_ss->SetTimer (Simulator::Schedule (m_ss->GetIntervalT21 (),
182  &SSLinkManager::StartScanning, this,
183  SubscriberStationNetDevice::EVENT_DL_MAP_SYNC_TIMEOUT, false),
184  m_dlMapSyncTimeoutEvent);
185 }
186 
187 void
188 SSLinkManager::SendRangingRequest (uint8_t uiuc, uint16_t allocationSize)
189 {
190  NS_ASSERT_MSG (
191  m_ss->GetState ()
192  == SubscriberStationNetDevice::SS_STATE_WAITING_REG_RANG_INTRVL
193  || m_ss->GetState ()
194  == SubscriberStationNetDevice::SS_STATE_WAITING_INV_RANG_INTRVL,
195  "SS: Error while sending a ranging request: the ss state should be SS_STATE_WAITING_REG_RANG_INTRVL or SS_STATE_WAITING_INV_RANG_INTRVL");
196 
197  if (m_nrRngReqsSent == 0) // sending the first time
198  {
199  m_pTxIrMax = CalculateMaxIRSignalStrength ();
200  m_rngreq.SetReqDlBurstProfile (
201  m_ss->GetBurstProfileManager ()->GetBurstProfileToRequest ());
202  m_rngreq.SetMacAddress (m_ss->GetMacAddress ());
203  }
204  else
205  {
206  m_pTxIrMax++;
207  if (m_nrRngRspsRecvd > 0)
208  {
209  m_rngreq.SetRangingAnomalies (m_rangingAnomalies);
210  }
211  }
212 
213  Ptr<Packet> packet = Create<Packet> ();
214  Ptr<PacketBurst> burst = Create<PacketBurst> ();
215 
216  packet->AddHeader (m_rngreq);
217  packet->AddHeader (ManagementMessageType (
218  ManagementMessageType::MESSAGE_TYPE_RNG_REQ));
219 
220  Ptr<WimaxConnection> connection;
221 
222  if (m_rangingStatus == WimaxNetDevice::RANGING_STATUS_CONTINUE)
223  {
224  connection = m_ss->GetBasicConnection ();
225  }
226  else // have been assigned BCID, means currently adjusting parameters
227  {
228  connection = m_ss->GetInitialRangingConnection ();
229  }
230 
231  m_ss->Enqueue (packet, MacHeaderType (), connection);
232 
233  m_ss->SetState (SubscriberStationNetDevice::SS_STATE_WAITING_RNG_RSP);
234  m_ss->SetTimer (Simulator::Schedule (m_ss->GetIntervalT3 (),
235  &SSLinkManager::StartContentionResolution, this), m_waitForRngRspEvent);
236  m_nrRngReqsSent++;
237 
238  NS_ASSERT_MSG (allocationSize
239  == m_ss->GetCurrentUcd ().GetChannelEncodings ().GetRangReqOppSize ()
240  / m_ss->GetPhy ()->GetPsPerSymbol (),
241  "SS: Error while sending a ranging request: the allocation size is not correct");
242 
243  // will work even if connection is not passed (i.e. null is passed) as scheduler will automatically select the same connection
244  m_ss->SendBurst (uiuc, allocationSize, connection);
245 }
246 
247 void
248 SSLinkManager::StartContentionResolution (void)
249 {
250  NS_ASSERT_MSG (
251  m_ss->GetState ()
252  == SubscriberStationNetDevice::SS_STATE_WAITING_RNG_RSP
253  || m_ss->GetState ()
254  == SubscriberStationNetDevice::SS_STATE_WAITING_REG_RANG_INTRVL
255  || m_ss->GetState ()
256  == SubscriberStationNetDevice::SS_STATE_ADJUSTING_PARAMETERS,
257  "SS: Can not start connection resolution: The SS state should be SS_STATE_WAITING_RNG_RSP or SS_STATE_WAITING_REG_RANG_INTRVL or SS_STATE_ADJUSTING_PARAMETERS");
258 
259  if (m_ss->GetState ()
260  == SubscriberStationNetDevice::SS_STATE_WAITING_RNG_RSP)
261  {
262  m_ss->SetState (
263  SubscriberStationNetDevice::SS_STATE_WAITING_REG_RANG_INTRVL);
264  IncreaseRangingRequestCW ();
265  m_contentionRangingRetries++;
266  }
267  else if (m_ss->GetState ()
268  == SubscriberStationNetDevice::SS_STATE_ADJUSTING_PARAMETERS)
269  {
270  m_ss->SetState (
271  SubscriberStationNetDevice::SS_STATE_WAITING_REG_RANG_INTRVL);
272  }
273 
274  if (m_contentionRangingRetries == m_ss->GetMaxContentionRangingRetries ())
275  {
276  StartScanning (SubscriberStationNetDevice::EVENT_NONE, false);
277  }
278  else
279  {
280  if (!m_isBackoffSet)
281  {
282  SelectRandomBackoff ();
283  }
284  }
285 }
286 
287 void
288 SSLinkManager::PerformBackoff (void)
289 {
290  Time defferTime = Seconds (0);
291  Time timeToAllocation = Seconds (0);
292  uint16_t nrPsPerRangOpp =
293  m_ss->GetCurrentUcd ().GetChannelEncodings ().GetRangReqOppSize ();
294  uint16_t oppSize =
295  m_ss->GetCurrentUcd ().GetChannelEncodings ().GetRangReqOppSize ()
296  / m_ss->GetPhy ()->GetPsPerSymbol ();
297 
298  for (uint8_t deferTOs = 0; deferTOs < m_nrRangingTransOpps; deferTOs++)
299  {
300  if (m_rangingBO == 0)
301  {
302  defferTime = Seconds (deferTOs * nrPsPerRangOpp
303  * m_ss->GetPhy ()->GetPsDuration ().GetSeconds ());
304  timeToAllocation = m_ss->GetTimeToAllocation (defferTime);
305 
306  Simulator::Schedule (timeToAllocation,
307  &SSLinkManager::SendRangingRequest, this,
308  OfdmUlBurstProfile::UIUC_INITIAL_RANGING, oppSize);
309 
310  m_rngReqFrameNumber = m_ss->GetNrFrames ();
311  m_initRangOppNumber = deferTOs + 1;
312 
313  m_isBackoffSet = false;
314  break;
315  }
316  m_rangingBO--;
317  }
318 }
319 
320 void
321 SSLinkManager::SelectRandomBackoff (void)
322 {
323  NS_ASSERT_MSG (m_rangingCW != 0 && m_rangingBO == 0,
324  "be sure that CW has been set and BO is not already set"); // ensuring CW has been set and BO is not already set
325 
326  m_rangingBO = (rand () % m_rangingCW);
327  m_isBackoffSet = true;
328 }
329 
330 void
331 SSLinkManager::IncreaseRangingRequestCW (void)
332 {
333  m_rangingCW = std::min (uint8_t ((m_rangingCW * 2 + 1) - 1),
334  m_ss->GetCurrentUcd ().GetRangingBackoffEnd ());
335 }
336 
337 void
338 SSLinkManager::ResetRangingRequestCW (void)
339 {
340  m_rangingCW = (uint8_t) std::pow ((double) 2,
341  (double) m_ss->GetCurrentUcd ().GetRangingBackoffStart ()) - 1;
342 }
343 
344 void
345 SSLinkManager::PerformRanging (Cid cid,
346  RngRsp rngrsp)
347 {
348  // need to distinguish initial ranging or periodic ranging
349 
350  if (cid == m_ss->GetInitialRangingConnection ()->GetCid ())
351  {
352  if (rngrsp.GetFrameNumber () == m_rngReqFrameNumber
353  && rngrsp.GetInitRangOppNumber () == m_initRangOppNumber)
354  {
355  Simulator::Cancel (m_waitForRngRspEvent);
356  m_nrRngRspsRecvd++;
357 
358  // RNG-REQ was undecodable
359  ResetRangingRequestCW ();
360  AdjustRangingParameters (rngrsp);
361  m_ss->SetState (
362  SubscriberStationNetDevice::SS_STATE_ADJUSTING_PARAMETERS);
363  return;
364  }
365 
366  if (m_ss->GetAddress () != rngrsp.GetMacAddress ())
367  {
368  return;
369  }
370 
371  m_ss->SetBasicConnection (CreateObject<WimaxConnection> (rngrsp.GetBasicCid (),
372  Cid::BASIC));
373 
374  m_ss->SetPrimaryConnection (CreateObject<WimaxConnection> (rngrsp.GetPrimaryCid (),
375  Cid::PRIMARY));
376  m_ss->SetAreManagementConnectionsAllocated (true);
377  }
378  else
379  {
380  // either periodic ranging or an additional RNG-RSP during initial ranging
381  }
382 
383  m_nrRngRspsRecvd++;
384  if (m_waitForRngRspEvent.IsRunning ())
385  {
386  Simulator::Cancel (m_waitForRngRspEvent);
387  }
388 
389  m_rangingStatus = (WimaxNetDevice::RangingStatus) rngrsp.GetRangStatus ();
390 
391  NS_ASSERT_MSG (
392  m_rangingStatus == WimaxNetDevice::RANGING_STATUS_CONTINUE
393  || m_rangingStatus == WimaxNetDevice::RANGING_STATUS_ABORT
394  || m_rangingStatus == WimaxNetDevice::RANGING_STATUS_SUCCESS,
395  "SS: Can not perform ranging: the ranging status should be RANGING_STATUS_CONTINUE or RANGING_STATUS_ABORT or RANGING_STATUS_SUCCESS");
396 
397  if (m_rangingStatus == WimaxNetDevice::RANGING_STATUS_ABORT)
398  {
399  if (rngrsp.GetDlFreqOverride ())
400  {
401  // code to move to new channel/frequency goes here
402  }
403  // deassigning basic and primary CIDs
404  m_ss->SetBasicConnection (0);
405  m_ss->SetPrimaryConnection (0);
406  m_ss->SetAreManagementConnectionsAllocated (false);
407  }
408  else
409  {
410  AdjustRangingParameters (rngrsp);
411 
412  if (m_rangingStatus == WimaxNetDevice::RANGING_STATUS_SUCCESS)
413  {
414 
415  m_ss->SetState (SubscriberStationNetDevice::SS_STATE_REGISTERED);
416  // initiate service flows
417  if (m_ss->HasServiceFlows () && !m_ss->GetAreServiceFlowsAllocated ())
418  {
419  m_ss->GetServiceFlowManager ()->InitiateServiceFlows ();
420  }
421 
422  NegotiateBasicCapabilities ();
423  }
424  else
425  {
426 
427  m_ss->SetState (
428  SubscriberStationNetDevice::SS_STATE_WAITING_INV_RANG_INTRVL);
429  // wait for invited ranging interval assigned to its Basic CID
430  }
431  }
432 }
433 
434 void
435 SSLinkManager::DeleteUplinkParameters (void)
436 {
437  m_ss->SetCurrentUcd (Ucd ());
438 }
439 
440 bool
441 SSLinkManager::IsUlChannelUsable (void)
442 {
443  // dont know how to check if usable, see Figure 58.
444  return true; // temporarily assuming usable
445 }
446 
447 void
448 SSLinkManager::AdjustRangingParameters (const RngRsp &rngrsp)
449 {
450 #if 0 /* a template for future implementation following */
451  bool successful = true;
452  uint8_t temp = rngrsp.GetTimingAdjust ();
453  temp = rngrsp.GetPowerLevelAdjust ();
454  temp = rngrsp.GetOffsetFreqAdjust ();
455 
456  // code for adjusting parameters goes here
457 
458  if (!successful)
459  {
460  // code for setting ranging anomalies goes here
461  }
462 #endif
463 }
464 
465 void
466 SSLinkManager::NegotiateBasicCapabilities (void)
467 {
468  // code to nagotiate basic capabilites goes here, ignored until very advanced stages
469 }
470 
471 uint16_t
472 SSLinkManager::CalculateMaxIRSignalStrength (void)
473 {
474  // SS obtains RSSI measurement from the OFDM downlink preambles using a complex formula, page 486
475  uint16_t rss = 1;
476 
477  if (m_bsEirp == 65535 || m_eirXPIrMax == 65535)
478  {
479  return GetMinTransmitPowerLevel ();
480  }
481  else
482  {
483  return m_eirXPIrMax + m_bsEirp - rss;
484  }
485 
486  return 0;
487 }
488 
489 uint16_t
490 SSLinkManager::GetMinTransmitPowerLevel (void)
491 {
492  // code to calculate minimum transmit power level of the SS, see page 189 of ammendment
493  return 10; // temp
494 }
495 
496 void
497 SSLinkManager::ScheduleScanningRestart (Time interval,
498  SubscriberStationNetDevice::EventType eventType,
499  bool deleteUlParameters, EventId &eventId)
500 {
501  m_ss->SetTimer (Simulator::Schedule (interval, &SSLinkManager::StartScanning,
502  this, eventType, deleteUlParameters), eventId);
503 }
504 
505 } // namespace ns3
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
static void Cancel(const EventId &id)
Definition: simulator.cc:267
bool IsRunning(void) const
Definition: event-id.cc:59
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:502
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586