Loading...
Searching...
No Matches
satellite-request-manager.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2013 Magister Solutions Ltd.
4 * Copyright (c) 2018 CNES
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation;
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * Author: Jani Puttonen <jani.puttonen@magister.fi>
20 * Author: Mathias Ettinger <mettinger@toulouse.viveris.com>
21 */
22
24
26#include "satellite-enums.h"
27#include "satellite-utils.h"
28
29#include "ns3/boolean.h"
30#include "ns3/double.h"
31#include "ns3/enum.h"
32#include "ns3/log.h"
33#include "ns3/nstime.h"
34#include "ns3/simulator.h"
35
36#include <algorithm>
37#include <cmath>
38#include <deque>
39#include <sstream>
40#include <utility>
41#include <vector>
42
43NS_LOG_COMPONENT_DEFINE("SatRequestManager");
44
45namespace ns3
46{
47
48NS_OBJECT_ENSURE_REGISTERED(SatRequestManager);
49
50const uint32_t SatRequestManager::m_rbdcScalingFactors[4] = {1, 4, 16, 64};
51const uint32_t SatRequestManager::m_vbdcScalingFactors[4] = {1, 8, 64, 512};
52
54 : m_gwAddress(),
56 m_lastCno(NAN),
57 m_llsConf(),
58 m_evaluationInterval(Seconds(0.1)),
59 m_cnoReportInterval(Seconds(0.0)),
60 m_gainValueK(1.0),
61 m_rttEstimate(MilliSeconds(560)),
67 m_lastVbdcCrSent(Seconds(0)),
68 m_superFrameDuration(Seconds(0)),
70 m_numValues(256),
74{
75 NS_LOG_FUNCTION(this);
76}
77
81
82void
83SatRequestManager::Initialize(Ptr<SatLowerLayerServiceConf> llsConf, Time superFrameDuration)
84{
85 NS_LOG_FUNCTION(this << superFrameDuration.GetSeconds());
86
87 m_llsConf = llsConf;
88
90 std::vector<std::deque<std::pair<Time, uint32_t>>>(m_llsConf->GetDaServiceCount(),
91 std::deque<std::pair<Time, uint32_t>>());
92 m_pendingVbdcBytes = std::vector<uint32_t>(m_llsConf->GetDaServiceCount(), 0);
93 m_assignedDaResourcesBytes = std::vector<uint32_t>(m_llsConf->GetDaServiceCount(), 0);
94 m_previousEvaluationTime = std::vector<Time>(m_llsConf->GetDaServiceCount(), Seconds(0.0));
95
96 // Superframe duration
97 m_superFrameDuration = superFrameDuration;
98
99 // Start the request manager evaluation cycle
100 Simulator::ScheduleWithContext(m_nodeInfo->GetNodeId(),
103 this);
104
105 // Start the C/N0 report cycle
107 Simulator::Schedule(m_cnoReportInterval, &SatRequestManager::SendCnoReport, this);
108}
109
110TypeId
112{
113 static TypeId tid =
114 TypeId("ns3::SatRequestManager")
115 .SetParent<Object>()
116 .AddConstructor<SatRequestManager>()
117 .AddAttribute("EvaluationInterval",
118 "Evaluation interval time",
119 TimeValue(Seconds(0.1)),
121 MakeTimeChecker())
122 .AddAttribute("CnoReportInterval",
123 "C/NO report interval time",
124 TimeValue(Seconds(1.1)),
126 MakeTimeChecker())
127 .AddAttribute("RttEstimate",
128 "Round trip time estimate for request manager",
129 TimeValue(MilliSeconds(560)),
130 MakeTimeAccessor(&SatRequestManager::m_rttEstimate),
131 MakeTimeChecker())
132 .AddAttribute("OverEstimationFactor",
133 "Over-estimation due to RLE and FPDU overhead.",
134 DoubleValue(1.1),
136 MakeDoubleChecker<double_t>())
137 .AddAttribute("EnableOnDemandEvaluation",
138 "Enable on-demand resource evaluation.",
139 BooleanValue(false),
141 MakeBooleanChecker())
142 .AddAttribute("GainValueK",
143 "Gain value K for RBDC calculation.",
144 DoubleValue(1.0),
145 MakeDoubleAccessor(&SatRequestManager::m_gainValueK),
146 MakeDoubleChecker<double_t>())
147 .AddAttribute("RbdcCapacityRequestAlgorithm",
148 "Algorithm to calculate RBDC capacity requests.",
149 EnumValue(SatEnums::CR_RBDC_LEGACY),
150 MakeEnumAccessor<SatEnums::RbdcCapacityRequestAlgorithm_t>(
152 MakeEnumChecker(SatEnums::CR_RBDC_LEGACY, "Legacy"))
153 .AddAttribute("VbdcCapacityRequestAlgorithm",
154 "Algorithm to calculate VBDC capacity requests.",
155 EnumValue(SatEnums::CR_VBDC_LEGACY),
156 MakeEnumAccessor<SatEnums::VbdcCapacityRequestAlgorithm_t>(
158 MakeEnumChecker(SatEnums::CR_VBDC_LEGACY, "Legacy"))
159 .AddTraceSource("CrTrace",
160 "Capacity request trace",
161 MakeTraceSourceAccessor(&SatRequestManager::m_crTrace),
162 "ns3::SatRequestManager::CapacityRequestTraceCallback")
163 .AddTraceSource("CrTraceLog",
164 "Capacity request trace log",
165 MakeTraceSourceAccessor(&SatRequestManager::m_crTraceLog),
166 "ns3::SatRequestManager::CapacityRequestTraceLogCallback")
167 .AddTraceSource("RbdcTrace",
168 "Trace for all sent RBDC capacity requests.",
169 MakeTraceSourceAccessor(&SatRequestManager::m_rbdcTrace),
170 "ns3::SatRequestManager::RbdcTraceCallback")
171 .AddTraceSource("VbdcTrace",
172 "Trace for all sent VBDC capacity requests.",
173 MakeTraceSourceAccessor(&SatRequestManager::m_vbdcTrace),
174 "ns3::SatRequestManager::VbdcTraceCallback")
175 .AddTraceSource("AvbdcTrace",
176 "Trace for all sent AVBDC capacity requests.",
177 MakeTraceSourceAccessor(&SatRequestManager::m_aVbdcTrace),
178 "ns3::SatRequestManager::AvbdcTraceCallback");
179 return tid;
180}
181
182void
184{
185 NS_LOG_FUNCTION(this);
186
187 for (CallbackContainer_t::iterator it = m_queueCallbacks.begin(); it != m_queueCallbacks.end();
188 ++it)
189 {
190 it->second.Nullify();
191 }
192 m_queueCallbacks.clear();
193
194 m_ctrlCallback.Nullify();
195
198
199 m_llsConf = nullptr;
200
201 Object::DoDispose();
202}
203
204void
206{
207 NS_LOG_FUNCTION(this << event << (uint32_t)(rcIndex));
208
209 if (event == SatQueue::FIRST_BUFFERED_PKT)
210 {
211 NS_LOG_INFO("FIRST_BUFFERED_PKT event received from queue: " << (uint32_t)(rcIndex));
212
214 {
215 NS_LOG_INFO("Do on-demand CR evaluation for RC index: " << (uint32_t)(rcIndex));
216 DoEvaluation();
217 }
218 }
219 // Other queue events not handled here
220}
221
222void
224{
225 NS_LOG_FUNCTION(this);
226
227 DoEvaluation();
228
229 // Schedule next evaluation interval
231}
232
233void
235{
236 NS_LOG_FUNCTION(this);
237
238 NS_LOG_INFO("---Start request manager evaluation---");
239
240 // Check whether the ctrl msg transmission is possible
241 bool ctrlMsgTxPossible = m_ctrlMsgTxPossibleCallback();
242
243 // The request manager evaluation is not done, if there is no
244 // possibility to send the CR. Instead, we just we wait for the next
245 // evaluation interval.
246 if (ctrlMsgTxPossible)
247 {
248 // Update the VBDC counters based on received TBTP
249 // resources
251
252 // Check whether we should update the VBDC request
253 // with AVBDC.
255
256 Ptr<SatCrMessage> crMsg = CreateObject<SatCrMessage>();
257
258 // Go through the RC indices
259 for (uint8_t rc = 0; rc < m_llsConf->GetDaServiceCount(); ++rc)
260 {
261 if (m_queueCallbacks.find(rc) != m_queueCallbacks.end())
262 {
263 // Get statistics for LLC/SatQueue
264 struct SatQueue::QueueStats_t stats = m_queueCallbacks.at(rc)(true);
265
266 NS_LOG_INFO("Evaluating the needs for RC: " << (uint32_t)(rc));
267 NS_LOG_INFO("RC: " << (uint32_t)(rc)
268 << " incoming rate: " << stats.m_incomingRateKbps << " kbps");
269 NS_LOG_INFO("RC: " << (uint32_t)(rc)
270 << " outgoing rate: " << stats.m_outgoingRateKbps << " kbps");
271 NS_LOG_INFO("RC: " << (uint32_t)(rc) << " volume in: " << stats.m_volumeInBytes
272 << " bytes");
273 NS_LOG_INFO("RC: " << (uint32_t)(rc) << " volume out: " << stats.m_volumeOutBytes
274 << " bytes");
275 NS_LOG_INFO("RC: " << (uint32_t)(rc)
276 << " total queue size: " << stats.m_queueSizeBytes << " bytes");
277
278 // RBDC only
279 if (m_llsConf->GetDaRbdcAllowed(rc) && !m_llsConf->GetDaVolumeAllowed(rc))
280 {
281 NS_LOG_INFO("Evaluating RBDC needs for RC: " << (uint32_t)(rc));
282 uint32_t rbdcRateKbps = DoRbdc(rc, stats);
283
284 NS_LOG_INFO("Requested RBDC rate for RC: " << (uint32_t)(rc) << " is "
285 << rbdcRateKbps << " kbps");
286
287 if (rbdcRateKbps > 0)
288 {
289 // Add control element only if UT needs some rate
290 crMsg->AddControlElement(rc, SatEnums::DA_RBDC, rbdcRateKbps);
291
292 std::stringstream ss;
293 ss << Simulator::Now().GetSeconds() << ", " << m_nodeInfo->GetNodeId()
294 << ", " << static_cast<uint32_t>(rc) << ", "
296 << rbdcRateKbps << ", " << stats.m_queueSizeBytes;
297 m_crTraceLog(ss.str());
298 m_rbdcTrace(rbdcRateKbps);
299 }
300 }
301
302 // VBDC only
303 else if (m_llsConf->GetDaVolumeAllowed(rc) && !m_llsConf->GetDaRbdcAllowed(rc))
304 {
305 NS_LOG_INFO("Evaluation VBDC for RC: " << (uint32_t)(rc));
306
307 uint32_t vbdcBytes(0);
308
309 SatEnums::SatCapacityAllocationCategory_t cac = DoVbdc(rc, stats, vbdcBytes);
310
311 vbdcBytes *= m_headerOffsetVbcd;
312
313 if (vbdcBytes > 0)
314 {
315 // Add control element only if UT needs some bytes
316 crMsg->AddControlElement(rc, cac, vbdcBytes);
317
318 // Update the time when VBDC CR is sent
319 m_lastVbdcCrSent = Simulator::Now();
320
321 std::stringstream ss;
322 ss << Simulator::Now().GetSeconds() << ", " << m_nodeInfo->GetNodeId()
323 << ", " << static_cast<uint32_t>(rc) << ", "
324 << SatEnums::GetCapacityAllocationCategory(cac) << ", " << vbdcBytes
325 << ", " << stats.m_queueSizeBytes;
326 m_crTraceLog(ss.str());
327
328 if (cac == SatEnums::DA_AVBDC)
329 {
330 m_aVbdcTrace(vbdcBytes);
331 }
332 else
333 {
334 m_vbdcTrace(vbdcBytes);
335 }
336 }
337
338 NS_LOG_INFO("Requested VBDC volume for RC: " << (uint32_t)(rc) << " is "
339 << vbdcBytes
340 << " Bytes with CAC: " << cac);
341 }
342
343 // RBDC + VBDC
344 else if (m_llsConf->GetDaRbdcAllowed(rc) && m_llsConf->GetDaVolumeAllowed(rc))
345 {
346 NS_LOG_INFO("Evaluation RBDC+VBDC for RC: " << (uint32_t)(rc));
347
352 NS_FATAL_ERROR(
353 "Simultaneous RBDC and VBDC for one RC is not currently supported!");
354 }
355 // No dynamic DA configured
356 else
357 {
358 NS_LOG_INFO("RBDC nor VBDC was configured for RC: " << (uint32_t)(rc));
359 }
360
361 // Update evaluation time
362 m_previousEvaluationTime.at(rc) = Simulator::Now();
363 }
364 }
365
366 // If CR has some valid elements
367 if (crMsg->IsNotEmpty())
368 {
369 NS_LOG_INFO("Send CR");
370
371 SendCapacityRequest(crMsg);
372 }
373
375 }
376 else
377 {
378 NS_LOG_INFO("No transmission possibility, thus skipping CR evaluation!");
379 }
380
381 NS_LOG_INFO("---End request manager evaluation---");
382}
383
384void
386{
387 NS_LOG_FUNCTION(this << (uint32_t)(rcIndex) << &cb);
388 m_queueCallbacks.insert(std::make_pair(rcIndex, cb));
389}
390
391void
393{
394 NS_LOG_FUNCTION(this << &cb);
395 m_ctrlCallback = cb;
396}
397
398void
404
405void
411
412void
414{
415 NS_LOG_FUNCTION(this << address);
416 m_gwAddress = address;
417}
418
419void
420SatRequestManager::SetNodeInfo(Ptr<SatNodeInfo> nodeInfo)
421{
422 NS_LOG_FUNCTION(this);
423
424 m_nodeInfo = nodeInfo;
425}
426
427void
429 uint32_t beamId,
430 Address sourceMac,
431 Address /*gwId*/,
432 double cno,
433 bool isSatelliteMac)
434{
435 NS_LOG_FUNCTION(this << satId << beamId << cno);
436
437 NS_LOG_INFO("C/No updated to request manager: " << cno);
438
439 if (isSatelliteMac)
440 {
441 m_lastSatelliteCno = cno;
442 m_satAddress = Mac48Address::ConvertFrom(sourceMac);
443 }
444 else
445 {
446 m_lastCno = cno;
447 }
448}
449
450uint32_t
452{
453 NS_LOG_FUNCTION(this);
454
456 {
458 return DoRbdcLegacy(rc, stats);
459 }
460 default: {
461 NS_FATAL_ERROR("SatRequestManager::DoRbdc - Invalid RBDC algorithm!");
462 }
463 }
464
465 NS_FATAL_ERROR("SatRequestManager::DoRbdc - Invalid RBDC algorithm!");
466 return 0;
467}
468
469uint32_t
471{
472 NS_LOG_FUNCTION(this << (uint32_t)(rc));
473
474 // Duration from last evaluation time
475 Time duration = Simulator::Now() - m_previousEvaluationTime.at(rc);
476
477 // Calculate the raw RBDC request
478 // double gainValueK = 1.0 / (2.0 * duration.GetSeconds ());
479
480 // This round kbits
481 double inRateKbps = m_overEstimationFactor * stats.m_incomingRateKbps;
482 double thisRbdcInKbits = inRateKbps * duration.GetSeconds();
483 double previousRbdcInKbits = GetPendingRbdcSumKbps(rc) * duration.GetSeconds();
484 double queueSizeInKbits = SatConstVariables::BITS_PER_BYTE * stats.m_queueSizeBytes /
486
487 double queueOccupancy =
488 std::max(0.0,
489 m_gainValueK * (queueSizeInKbits - thisRbdcInKbits - previousRbdcInKbits) /
490 duration.GetSeconds());
491
492 double reqRbdcKbps = inRateKbps + queueOccupancy;
493
494 NS_LOG_INFO("queueSizeInKbits: " << queueSizeInKbits << " thisRbdcInKbits: " << thisRbdcInKbits
495 << " previousRbdcInKbits " << previousRbdcInKbits);
496 NS_LOG_INFO("gainValueK: " << m_gainValueK);
497 NS_LOG_INFO("In rate: " << inRateKbps << " queueOccupancy: " << queueOccupancy);
498
499 // If CRA enabled, substract the CRA bitrate from the calculated RBDC bitrate
500 if (m_llsConf->GetDaConstantAssignmentProvided(rc))
501 {
502 // If CRA is sufficient, no RBDC needed
503 if (reqRbdcKbps <= m_llsConf->GetDaConstantServiceRateInKbps(rc))
504 {
505 reqRbdcKbps = 0.0;
506 }
507 // Else reduce the CRA from RBDC request
508 else
509 {
510 reqRbdcKbps -= m_llsConf->GetDaConstantServiceRateInKbps(rc);
511 }
512
513 if (m_llsConf->GetDaConstantServiceRateInKbps(rc) >
514 m_llsConf->GetDaMaximumServiceRateInKbps(rc))
515 {
516 NS_FATAL_ERROR("SatRequestManager::DoRbdcLegacy - configured CRA is bigger than "
517 "maximum RBDC for RC: "
518 << uint32_t(rc));
519 }
520
521 // CRA + RBDC is too much
522 if ((m_llsConf->GetDaConstantServiceRateInKbps(rc) + reqRbdcKbps) >
523 m_llsConf->GetDaMaximumServiceRateInKbps(rc))
524 {
525 reqRbdcKbps = m_llsConf->GetDaMaximumServiceRateInKbps(rc) -
526 m_llsConf->GetDaConstantServiceRateInKbps(rc);
527 }
528 }
529 // CRA is disabled, but check that RBDC request is not by itself going over max service rate.
530 else if (reqRbdcKbps > m_llsConf->GetDaMaximumServiceRateInKbps(rc))
531 {
532 reqRbdcKbps = m_llsConf->GetDaMaximumServiceRateInKbps(rc);
533 }
534
535 NS_LOG_INFO("RBDC bitrate after CRA as been taken off: " << reqRbdcKbps << " kbps");
536
537 uint32_t crRbdcKbps = GetQuantizedRbdcValue(rc, reqRbdcKbps);
538
539 NS_LOG_INFO("Quantized RBDC bitrate: " << crRbdcKbps << " kbps");
540
541 UpdatePendingRbdcCounters(rc, crRbdcKbps);
542
543 return crRbdcKbps;
544}
545
547SatRequestManager::DoVbdc(uint8_t rc, const SatQueue::QueueStats_t& stats, uint32_t& rcVbdcBytes)
548{
549 NS_LOG_FUNCTION(this);
550
552 {
554 return DoVbdcLegacy(rc, stats, rcVbdcBytes);
555 }
556 default: {
557 NS_FATAL_ERROR("SatRequestManager::DoVbdc - Invalid VBDC algorithm!");
558 }
559 }
560
561 NS_FATAL_ERROR("SatRequestManager::DoVbdc - Invalid VBDC algorithm!");
563}
564
567 const SatQueue::QueueStats_t& stats,
568 uint32_t& rcVbdcBytes)
569{
570 NS_LOG_FUNCTION(this << (uint32_t)(rc));
571
572 uint32_t vbdcBytes(0);
573
575
576 if (m_forcedAvbdcUpdate == true)
577 {
578 cac = SatEnums::DA_AVBDC;
579 vbdcBytes = GetAvbdcBytes(rc, stats);
580 }
581 else
582 {
583 // If there is volume in, there is no need to ask for additional resources
584 if (stats.m_volumeInBytes > 0)
585 {
586 NS_LOG_INFO("VBDC volume in for RC: " << (uint32_t)(rc) << ": " << stats.m_volumeInBytes
587 << " Bytes");
588
589 // If we assume that we have received all requested resources,
590 // send AVBDC request with total queue size.
591 if (m_pendingVbdcBytes.at(rc) == 0)
592 {
593 cac = SatEnums::DA_AVBDC;
594 vbdcBytes = GetAvbdcBytes(rc, stats);
595 }
596 else
597 {
598 cac = SatEnums::DA_VBDC;
599 vbdcBytes = GetVbdcBytes(rc, stats);
600 }
601 }
602 }
603 // Return the VBDC as referenced uint32_t
604 rcVbdcBytes = vbdcBytes;
605
606 return cac;
607}
608
609uint32_t
611{
612 NS_LOG_FUNCTION(this << (uint32_t)(rc));
613
614 Reset(rc);
615
616 uint32_t craBytes(0);
617 uint32_t vbdcBytes = m_overEstimationFactor * stats.m_queueSizeBytes;
618
619 // If CRA enabled, substract the CRA Bytes from VBDC
620 if (m_llsConf->GetDaConstantAssignmentProvided(rc))
621 {
622 NS_LOG_INFO("CRA is enabled together with VBDC for RC: " << (uint32_t)(rc));
623
624 // Duration from last evaluation time
625 Time duration = Simulator::Now() - m_previousEvaluationTime.at(rc);
626
627 // Calculate how much bytes would be given to this RC index with configured CRA
628 craBytes =
630 m_llsConf->GetDaConstantServiceRateInKbps(rc) * duration.GetSeconds()) /
632 }
633
634 // If there is still need for Bytes after CRA
635 if (craBytes < vbdcBytes)
636 {
637 vbdcBytes -= craBytes;
638 vbdcBytes = GetQuantizedVbdcValue(rc, vbdcBytes);
639
640 // Update the pending counters
641 m_pendingVbdcBytes.at(rc) = vbdcBytes;
642
643 NS_LOG_INFO("Pending VBDC bytes: " << (uint32_t)(rc) << ": " << m_pendingVbdcBytes.at(rc)
644 << " Bytes");
645 }
646 else
647 {
648 vbdcBytes = 0;
649 }
650
651 return vbdcBytes;
652}
653
654uint32_t
656{
657 NS_LOG_FUNCTION(this << (uint32_t)(rc));
658
659 uint32_t craBytes(0);
660 uint32_t vbdcBytes = m_overEstimationFactor * stats.m_volumeInBytes;
661
662 // If CRA enabled, substract the CRA Bytes from VBDC
663 if (m_llsConf->GetDaConstantAssignmentProvided(rc))
664 {
665 NS_LOG_INFO("CRA is enabled together with VBDC for RC: " << (uint32_t)(rc));
666
667 // Duration from last evaluation time
668 Time duration = Simulator::Now() - m_previousEvaluationTime.at(rc);
669
670 // Calculate how much bytes would be given to this RC index with configured CRA
671 craBytes =
673 m_llsConf->GetDaConstantServiceRateInKbps(rc) * duration.GetSeconds()) /
675 }
676
677 // If there is still need for Bytes after CRA
678 if (craBytes < vbdcBytes)
679 {
680 vbdcBytes -= craBytes;
681
682 NS_LOG_INFO("VBDC volume after CRA for RC: " << (uint32_t)(rc) << ": " << vbdcBytes
683 << " Bytes");
684
685 vbdcBytes = GetQuantizedVbdcValue(rc, vbdcBytes);
686 m_pendingVbdcBytes.at(rc) = m_pendingVbdcBytes.at(rc) + vbdcBytes;
687
688 NS_LOG_INFO("Pending VBDC bytes: " << (uint32_t)(rc) << ": " << m_pendingVbdcBytes.at(rc)
689 << " Bytes");
690 NS_LOG_INFO("VBDC volume after pending: " << (uint32_t)(rc) << ": " << vbdcBytes
691 << " Bytes");
692 }
693 else
694 {
695 vbdcBytes = 0;
696 }
697
698 return vbdcBytes;
699}
700
701void
703{
704 NS_LOG_FUNCTION(this);
705
706 // Volume backlog shall expire at the NCC?
707 // Last sent CR + backlog persistence duration is smaller than now
708 if ((m_lastVbdcCrSent + (m_llsConf->GetVolumeBacklogPersistence() - 1) * m_superFrameDuration) <
709 Simulator::Now())
710 {
711 // Go through all RC indeces
712 for (std::vector<uint32_t>::iterator it = m_pendingVbdcBytes.begin();
713 it != m_pendingVbdcBytes.end();
714 ++it)
715 {
716 // Check if UT is still in need for resources
717 if (*it > 0)
718 {
719 // Volume backlog is about to expire, and we still have buffered data,
720 // send forced AVBDC
721 m_forcedAvbdcUpdate = true;
722 return;
723 }
724 }
725 }
726
727 // No need to send forced AVBDC
728 m_forcedAvbdcUpdate = false;
729 return;
730}
731
732uint32_t
734{
735 NS_LOG_FUNCTION(this << (uint32_t)(rc));
736
738
739 uint32_t value(0);
740 std::deque<std::pair<Time, uint32_t>> cont = m_pendingRbdcRequestsKbps.at(rc);
741
742 for (std::deque<std::pair<Time, uint32_t>>::const_iterator it = cont.begin(); it != cont.end();
743 ++it)
744 {
745 // Add the kbps
746 value += (*it).second;
747 }
748
749 NS_LOG_INFO("Pending RBDC sum for RC: " << (uint32_t)(rc) << " is " << value);
750
751 return value;
752}
753
754void
756{
757 NS_LOG_FUNCTION(this << (uint32_t)(rc) << kbps);
758
759 if (kbps > 0)
760 {
761 Time now = Simulator::Now();
762 std::pair<Time, uint32_t> item = std::make_pair(now, kbps);
763 m_pendingRbdcRequestsKbps.at(rc).push_back(item);
764 }
765}
766
767void
769{
770 NS_LOG_FUNCTION(this << (uint32_t)(rc));
771
772 std::deque<std::pair<Time, uint32_t>>& cont = m_pendingRbdcRequestsKbps.at(rc);
773 std::deque<std::pair<Time, uint32_t>>::const_iterator it = cont.begin();
774
775 while (it != cont.end())
776 {
777 if ((*it).first < (Simulator::Now() - m_rttEstimate))
778 {
779 cont.pop_front();
780 it = cont.begin();
781 }
782 else
783 {
784 break;
785 }
786 }
787}
788
789void
791{
792 NS_LOG_FUNCTION(this);
793
794 for (uint8_t rc = 0; rc < m_llsConf->GetDaServiceCount(); rc++)
795 {
797 }
798}
799
800void
802{
803 NS_LOG_FUNCTION(this << (uint32_t)(rc));
804
805 /*
806 * m_pendingVbdcBytes is updated with requested bytes and reduce by allocated
807 * bytes via TBTP. This information comes from UT MAC.
808 * m_assignedDaResources holds the amount of resources allocated during the previous
809 * superframe.
810 */
811
813 {
816 }
817 else
818 {
819 m_pendingVbdcBytes.at(rc) = 0;
821 }
822}
823
824void
826{
827 NS_LOG_FUNCTION(this);
828
829 // Cancel the C/No report event
830 m_cnoReportEvent.Cancel();
831
832 if (!m_ctrlCallback.IsNull())
833 {
834 NS_LOG_INFO("Send C/N0 report to GW: " << m_gwAddress);
835
836 m_crTrace(Simulator::Now(), m_nodeInfo->GetMacAddress(), crMsg);
837
838 crMsg->SetCnoEstimate(m_lastCno);
840
841 m_lastCno = NAN;
842 }
843 else
844 {
845 NS_FATAL_ERROR("Unable to send capacity request, since the Ctrl callback is NULL!");
846 }
847
848 // Re-schedule the C/No report event
850 Simulator::Schedule(m_cnoReportInterval, &SatRequestManager::SendCnoReport, this);
851}
852
853void
855{
856 NS_LOG_FUNCTION(this);
857
858 if (!m_ctrlCallback.IsNull())
859 {
860 // Check if we have the possiblity to send a ctrl msg
861 bool ctrlMsgTxPossible = m_ctrlMsgTxPossibleCallback();
862
863 if (ctrlMsgTxPossible && m_lastCno != NAN)
864 {
865 NS_LOG_INFO("Send C/No report to GW: " << m_gwAddress);
866
867 Ptr<SatCnoReportMessage> cnoReport = CreateObject<SatCnoReportMessage>();
868
869 cnoReport->SetCnoEstimate(m_lastCno);
870 m_ctrlCallback(cnoReport, m_gwAddress);
871
872 m_lastCno = NAN;
873 }
874
875 if (ctrlMsgTxPossible && m_lastSatelliteCno != NAN)
876 {
877 NS_LOG_INFO("Send C/No report to SAT user: " << m_satAddress);
878 Ptr<SatCnoReportMessage> cnoReport = CreateObject<SatCnoReportMessage>();
879
880 cnoReport->SetCnoEstimate(m_lastSatelliteCno);
881 m_ctrlCallback(cnoReport, m_satAddress);
882
883 m_lastSatelliteCno = NAN;
884 }
885 }
886
888 Simulator::Schedule(m_cnoReportInterval, &SatRequestManager::SendCnoReport, this);
889}
890
891void
892SatRequestManager::SendHandoverRecommendation(uint32_t satId, uint32_t beamId)
893{
894 NS_LOG_FUNCTION(this << beamId);
895
896 // Check if we have the possiblity to send a ctrl msg
898 {
899 NS_LOG_INFO("Send handover recommendation to GW: " << m_gwAddress);
900
901 Ptr<SatHandoverRecommendationMessage> hoRecommendation =
902 CreateObject<SatHandoverRecommendationMessage>();
903 hoRecommendation->SetRecommendedBeamId(beamId);
904 hoRecommendation->SetRecommendedSatId(satId);
905
906 m_ctrlCallback(hoRecommendation, m_gwAddress);
907 }
908}
909
910void
912{
913 NS_LOG_FUNCTION(this);
914
915 // Check if we have the possiblity to send a logon msg
916 // TODO add new callback
918 {
919 NS_LOG_INFO("Send logon message to GW: " << m_gwAddress);
920
921 Ptr<SatLogonMessage> logonMessage = CreateObject<SatLogonMessage>();
922 m_ctrlCallback(logonMessage, m_gwAddress);
923 }
924}
925
926void
928{
929 m_headerOffsetVbcd = headerOffsetVbcd;
930}
931
932void
933SatRequestManager::AssignedDaResources(uint8_t rcIndex, uint32_t bytes)
934{
935 NS_LOG_FUNCTION(this << (uint32_t)(rcIndex) << bytes);
936
937 NS_LOG_INFO("TBTP resources assigned for RC: " << (uint32_t)(rcIndex) << " bytes: " << bytes);
938
939 m_assignedDaResourcesBytes.at(rcIndex) = m_assignedDaResourcesBytes.at(rcIndex) + bytes;
940}
941
942void
944{
945 NS_LOG_FUNCTION(this);
946
947 for (uint32_t i = 0; i < m_llsConf->GetDaServiceCount(); ++i)
948 {
950 }
951}
952
953void
955{
956 NS_LOG_FUNCTION(this << (uint32_t)(rc));
957
959 m_pendingVbdcBytes.at(rc) = 0;
960}
961
962uint16_t
963SatRequestManager::GetQuantizedRbdcValue(uint8_t index, uint16_t reqRbdcKbps) const
964{
965 NS_LOG_FUNCTION(this << (uint32_t)(index) << reqRbdcKbps);
966
967 uint32_t maxRbdc = m_llsConf->GetDaMaximumServiceRateInKbps(index);
968 uint32_t quantValue(0);
969
970 // Maximum configured RBDC rate
971 if (reqRbdcKbps > maxRbdc)
972 {
973 return maxRbdc;
974 }
975
976 // Else quantize based on the predefined scaling factors from the specification
977 for (uint32_t i = 0; i < 4; i++)
978 {
979 // If the value can be represented with this scaling value
980 if (reqRbdcKbps <= m_rbdcScalingFactors[i] * m_numValues)
981 {
982 quantValue = (uint16_t)(ceil(reqRbdcKbps / (double)(m_rbdcScalingFactors[i])) *
984 return quantValue;
985 }
986 }
987
988 NS_FATAL_ERROR("Quantized value for RBDC not calculated!");
989
990 return quantValue;
991}
992
993uint16_t
994SatRequestManager::GetQuantizedVbdcValue(uint8_t index, uint16_t reqVbdcBytes) const
995{
996 NS_LOG_FUNCTION(this << (uint32_t)(index) << reqVbdcBytes);
997
998 uint32_t maxBacklogBytes =
999 SatConstVariables::BYTES_IN_KBYTE * m_llsConf->GetDaMaximumBacklogInKbytes(index);
1000 uint32_t quantValue(0);
1001
1002 // If maximum backlog reached
1003 if (reqVbdcBytes > maxBacklogBytes)
1004 {
1005 return maxBacklogBytes;
1006 }
1007
1008 // Else quantize based on the predefined scaling factors from the specification
1009 for (uint32_t i = 0; i < 4; ++i)
1010 {
1011 // If the value can be represented with this scaling value
1012 if (reqVbdcBytes <= m_vbdcScalingFactors[i] * m_numValues)
1013 {
1014 quantValue = (uint16_t)(ceil(reqVbdcBytes / (double)(m_vbdcScalingFactors[i])) *
1016 return quantValue;
1017 }
1018 }
1019
1020 NS_FATAL_ERROR("Quantized value for VBDC not calculated!");
1021
1022 return quantValue;
1023}
1024
1025} // namespace ns3
SatEnums class is for simplifying the use of enumerators in the satellite module.
SatCapacityAllocationCategory_t
Definition for different types of Capacity Request (CR) messages.
static std::string GetCapacityAllocationCategory(SatCapacityAllocationCategory_t cac)
SatRequestManager analyzes periodically or on-a-need-basis UT's buffer status for different RC indice...
Time m_superFrameDuration
Superframe duration used for updating the volume backlog persistence.
double m_overEstimationFactor
Over-estimation factor used for estimating a bit more resources than there are in the buffers.
SatEnums::RbdcCapacityRequestAlgorithm_t m_rbdcCapacityRequestAlgorithm
The RBDC capacity algorithm to use.
SatEnums::SatCapacityAllocationCategory_t DoVbdcLegacy(uint8_t rc, const SatQueue::QueueStats_t &stats, uint32_t &rcVbdcBytes)
Legacy algorithm to do VBDC calculation for a RC.
void Reset(uint8_t rc)
Reset RC index counters.
SendCtrlCallback m_ctrlCallback
Callback to send control messages.
PendingRbdcRequestsContainer_t m_pendingRbdcRequestsKbps
Key = RC index Value -> Key = Time when the request was sent Value -> Value = Requested bitrate or by...
void AssignedDaResources(uint8_t rcIndex, uint32_t bytes)
Sat UT MAC informs that certain amount of resources have been received in TBTP.
TracedCallback< uint32_t > m_aVbdcTrace
double m_lastSatelliteCno
The last received user link C/N0 information from lower layer in linear format.
void SetLogonMsgTxPossibleCallback(SatRequestManager::LogonMsgTxPossibleCallback cb)
Set the callback to check the possibility of sending a control message.
TracedCallback< std::string > m_crTraceLog
Trace callback used for CR tracing.
void SendLogonMessage()
Send a logon message to the gateway.
Ptr< SatLowerLayerServiceConf > m_llsConf
Lower layer services conf pointer, which holds the configurations for RCs and capacity allocation cat...
static TypeId GetTypeId(void)
inherited from Object
void ReceiveQueueEvent(SatQueue::QueueEvent_t event, uint8_t rcIndex)
Receive a queue event.
void RemoveOldEntriesFromPendingRbdcContainer(uint8_t rc)
Clean-up the pending RBDC container from old samples.
void Initialize(Ptr< SatLowerLayerServiceConf > llsConf, Time superFrameDuration)
Mac48Address m_gwAddress
GW address.
uint32_t GetVbdcBytes(uint8_t rc, const SatQueue::QueueStats_t &stats)
Calculate the needed VBDC bytes for a RC.
LogonMsgTxPossibleCallback m_logonMsgTxPossibleCallback
Callback to check from MAC if a logon msg may be transmitted in the near future.
uint16_t GetQuantizedRbdcValue(uint8_t index, uint16_t reqRbdcKbps) const
The RBDC value is signalled with 8 bits, which means that to be able to signal larger than 256 values...
void UpdatePendingRbdcCounters(uint8_t rc, uint32_t kbps)
Update the pending RBDC counters with new request information.
Callback< SatQueue::QueueStats_t, bool > QueueCallback
Callback to fetch queue statistics.
SatEnums::VbdcCapacityRequestAlgorithm_t m_vbdcCapacityRequestAlgorithm
The VBDC capacity algorithm to use.
void UpdatePendingVbdcCounters()
Update pending VBDC counters for all RCs.
Ptr< SatNodeInfo > m_nodeInfo
Node information.
virtual ~SatRequestManager()
Destructor for SatRequestManager.
uint32_t GetPendingRbdcSumKbps(uint8_t rc)
Calculate the pending RBDC requests related to a specific RC.
Callback< bool > CtrlMsgTxPossibleCallback
Callback to check whether control msg transmission is possible.
void DoPeriodicalEvaluation()
Periodically check the buffer status and whether a new CR is needed to be sent.
void SetCtrlMsgTxPossibleCallback(SatRequestManager::CtrlMsgTxPossibleCallback cb)
Set the callback to check the possibility of sending a control message.
SatEnums::SatCapacityAllocationCategory_t DoVbdc(uint8_t rc, const SatQueue::QueueStats_t &stats, uint32_t &rcVbdcBytes)
Do VBDC calculation for a RC.
static const uint32_t m_rbdcScalingFactors[4]
std::vector< uint32_t > m_pendingVbdcBytes
Pending VBDC counter for each RC index.
Mac48Address m_satAddress
SAT address.
void SetNodeInfo(Ptr< SatNodeInfo > nodeInfo)
Set the node info of this UT.
virtual void DoDispose()
Dispose of this class instance.
TracedCallback< uint32_t > m_rbdcTrace
Traced callbacks for all sent RBDC and VBDC capacity requests.
void SendCnoReport()
Send the C/N0 report message via txCallback to SatNetDevice.
void ResetAssignedResources()
Reset the assigned resources counter.
uint32_t GetAvbdcBytes(uint8_t rc, const SatQueue::QueueStats_t &stats)
Calculate the needed AVBDC bytes for a RC.
uint16_t GetQuantizedVbdcValue(uint8_t index, uint16_t reqVbdcBytes) const
The RBDC value is signalled with 8 bits, which means that to be able to signal larger than 256 values...
double m_gainValueK
Gain value K for the RBDC calculation.
Callback< bool, Ptr< SatControlMessage >, const Address & > SendCtrlCallback
Control message sending callback.
void DoEvaluation()
Do evaluation of the buffer status and decide whether or not to send CRs.
uint32_t DoRbdcLegacy(uint8_t rc, const SatQueue::QueueStats_t &stats)
Legacy algorithm to do RBDC calculation for a RC.
void AddQueueCallback(uint8_t rcIndex, SatRequestManager::QueueCallback cb)
Add a callback to fetch queue statistics.
EventId m_cnoReportEvent
Event id for the C/NO report.
uint32_t DoRbdc(uint8_t rc, const SatQueue::QueueStats_t &stats)
Do RBDC calculation for a RC.
static const uint32_t m_vbdcScalingFactors[4]
Time m_rttEstimate
Round trip time estimate.
TracedCallback< Time, Mac48Address, Ptr< SatCrMessage > > m_crTrace
Trace callback used for CR tracing.
TracedCallback< uint32_t > m_vbdcTrace
std::vector< uint32_t > m_assignedDaResourcesBytes
Dedicated assignments received within the previous superframe.
Time m_lastVbdcCrSent
Time when the last CR including VBDC request was sent.
double m_lastCno
The last received on E2E C/N0 information from lower layer in linear format.
Time m_cnoReportInterval
Interval to send C/N0 report.
void SetGwAddress(Mac48Address address)
Set the GW address needed for CR transmission.
bool m_forcedAvbdcUpdate
Flag indicating that UT should send a forced AVBDC request, since the volume backlog persistence shal...
void SendCapacityRequest(Ptr< SatCrMessage > crMsg)
Send the capacity request control msg via txCallback to SatNetDevice.
Time m_evaluationInterval
Interval to do the periodical CR evaluation.
double m_headerOffsetVbcd
Additional VBDC to add to take into account E2E header in regenerative LINK or NETWORK,...
bool m_enableOnDemandEvaluation
Enable on demand / ad hoc CR evaluation.
void CheckForVolumeBacklogPersistence()
Check whether VBDC volume backlog persistence shall expire and whether UT should update request by AV...
void SetHeaderOffsetVbdc(double headerOffsetVbcd)
Update the value of header offset.
CtrlMsgTxPossibleCallback m_ctrlMsgTxPossibleCallback
Callback to check from MAC if a control msg may be transmitted in the near future.
SatRequestManager()
Default constructor.
void CnoUpdated(uint32_t satId, uint32_t beamId, Address sourceMac, Address gwId, double cno, bool isSatelliteMac)
Update C/N0 information from lower layer.
void SetCtrlMsgCallback(SatRequestManager::SendCtrlCallback cb)
Set the control message sending callback.
CallbackContainer_t m_queueCallbacks
The queue enque/deque rate getter callback.
void SendHandoverRecommendation(uint32_t satId, uint32_t beamId)
Send a handover recommendation message to the gateway.
std::vector< Time > m_previousEvaluationTime
Time when CR evaluation was previously done.
Callback< bool > LogonMsgTxPossibleCallback
Callback to check whether logon msg transmission is possible.
constexpr uint32_t BITS_IN_KBIT
Number of bits consisting a kilobit.
constexpr uint32_t BITS_PER_BYTE
Number of bits in a byte.
constexpr uint32_t BYTES_IN_KBYTE
Number of bytes consisting a kilobyte.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.
QueueStats_t definition for passing queue related statistics to any interested modules.