A Discrete-Event Network Simulator
API
cqa-ff-mac-scheduler.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
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: Biljana Bojovic <bbojovic@cttc.es>, Nicola Baldo<nbaldo@cttc.es>.
19  *
20  * Note:
21  * Implementation is using many common scheduler functionalities in its
22  * original version implemented by Marco Miozzo<mmiozzo@cttc.es> in
23  * Proportional Fair and Round Robin schedulers implementations.
24  */
25 
26 #include <ns3/log.h>
27 #include <ns3/pointer.h>
28 #include <ns3/math.h>
29 
30 #include <ns3/simulator.h>
31 #include <ns3/lte-amc.h>
32 #include <ns3/cqa-ff-mac-scheduler.h>
33 #include <ns3/ff-mac-common.h>
34 #include <ns3/lte-vendor-specific-parameters.h>
35 #include <ns3/boolean.h>
36 #include <cfloat>
37 #include <set>
38 #include <stdexcept>
39 #include <ns3/integer.h>
40 #include <ns3/string.h>
41 
42 namespace ns3 {
43 
44 NS_LOG_COMPONENT_DEFINE ("CqaFfMacScheduler");
45 
47 static const int CqaType0AllocationRbg[4] = {
48  10, // RGB size 1
49  26, // RGB size 2
50  63, // RGB size 3
51  110 // RGB size 4
52 }; // see table 7.1.6.1-1 of 36.213
53 
54 
55 NS_OBJECT_ENSURE_REGISTERED (CqaFfMacScheduler);
56 
57 
60 {
62  uint8_t cqi_value_for_lc;
63 };
64 
65 
72 bool CQIValueDescComparator (uint8_t key1, uint8_t key2)
73 {
74  return key1>key2;
75 }
76 
83 bool CqaGroupDescComparator (int key1, int key2)
84 {
85  return key1>key2;
86 }
87 
89 typedef uint8_t CQI_value;
91 typedef int RBG_index;
93 typedef int HOL_group;
94 
96 typedef std::map<CQI_value,LteFlowId_t,bool(*)(uint8_t,uint8_t)> t_map_CQIToUE; //sorted
98 typedef std::map<RBG_index,t_map_CQIToUE> t_map_RBGToCQIsSorted;
100 typedef std::map<HOL_group,t_map_RBGToCQIsSorted> t_map_HOLGroupToRBGs;
101 
103 typedef std::map<CQI_value,LteFlowId_t,bool(*)(uint8_t,uint8_t)>::iterator t_it_CQIToUE; //sorted
105 typedef std::map<RBG_index,t_map_CQIToUE>::iterator t_it_RBGToCQIsSorted;
107 typedef std::map<HOL_group,t_map_RBGToCQIsSorted>::iterator t_it_HOLGroupToRBGs;
108 
110 typedef std::multimap<HOL_group,std::set<LteFlowId_t>,bool(*)(int,int)> t_map_HOLgroupToUEs;
112 typedef std::map<HOL_group,std::set<LteFlowId_t> >::iterator t_it_HOLgroupToUEs;
113 
114 //typedef std::map<RBG_index,CQI_value> map_RBG_to_CQI;
115 //typedef std::map<LteFlowId_t,map_RBG_to_CQI> map_flowId_to_CQI_map;
116 
117 
124 bool CqaKeyDescComparator (uint16_t key1, uint16_t key2)
125 {
126  return key1>key2;
127 }
128 
129 
131  : m_cschedSapUser (0),
132  m_schedSapUser (0),
133  m_timeWindow (99.0),
134  m_nextRntiUl (0)
135 {
136  m_amc = CreateObject <LteAmc> ();
139  m_ffrSapProvider = 0;
141 }
142 
144 {
145  NS_LOG_FUNCTION (this);
146 }
147 
148 void
150 {
151  NS_LOG_FUNCTION (this);
153  m_dlHarqProcessesTimer.clear ();
155  m_dlInfoListBuffered.clear ();
156  m_ulHarqCurrentProcessId.clear ();
157  m_ulHarqProcessesStatus.clear ();
159  delete m_cschedSapProvider;
160  delete m_schedSapProvider;
161  delete m_ffrSapUser;
162 }
163 
164 TypeId
166 {
167  static TypeId tid = TypeId ("ns3::CqaFfMacScheduler")
169  .SetGroupName("Lte")
170  .AddConstructor<CqaFfMacScheduler>()
171  .AddAttribute ("CqiTimerThreshold",
172  "The number of TTIs a CQI is valid (default 1000 - 1 sec.)",
173  UintegerValue (1000),
175  MakeUintegerChecker<uint32_t> ())
176  .AddAttribute ("CqaMetric",
177  "CqaFfMacScheduler metric type that can be: CqaFf, CqaPf",
178  StringValue ("CqaFf"),
181  .AddAttribute ("HarqEnabled",
182  "Activate/Deactivate the HARQ [by default is active].",
183  BooleanValue (true),
186  .AddAttribute ("UlGrantMcs",
187  "The MCS of the UL grant, must be [0..15] (default 0)",
188  UintegerValue (0),
190  MakeUintegerChecker<uint8_t> ())
191  ;
192  return tid;
193 }
194 
195 
196 
197 void
199 {
200  m_cschedSapUser = s;
201 }
202 
203 void
205 {
206  m_schedSapUser = s;
207 }
208 
211 {
212  return m_cschedSapProvider;
213 }
214 
217 {
218  return m_schedSapProvider;
219 }
220 
221 void
223 {
224  m_ffrSapProvider = s;
225 }
226 
229 {
230  return m_ffrSapUser;
231 }
232 
233 void
235 {
236  NS_LOG_FUNCTION (this);
237  // Read the subset of parameters used
238  m_cschedCellConfig = params;
241  cnf.m_result = SUCCESS;
243  return;
244 }
245 
246 void
248 {
249  NS_LOG_FUNCTION (this << " RNTI " << params.m_rnti << " txMode " << (uint16_t)params.m_transmissionMode);
250  std::map <uint16_t,uint8_t>::iterator it = m_uesTxMode.find (params.m_rnti);
251  if (it == m_uesTxMode.end ())
252  {
253  m_uesTxMode.insert (std::pair <uint16_t, uint8_t> (params.m_rnti, params.m_transmissionMode));
254  // generate HARQ buffers
255  m_dlHarqCurrentProcessId.insert (std::pair <uint16_t,uint8_t > (params.m_rnti, 0));
256  DlHarqProcessesStatus_t dlHarqPrcStatus;
257  dlHarqPrcStatus.resize (8,0);
258  m_dlHarqProcessesStatus.insert (std::pair <uint16_t, DlHarqProcessesStatus_t> (params.m_rnti, dlHarqPrcStatus));
259  DlHarqProcessesTimer_t dlHarqProcessesTimer;
260  dlHarqProcessesTimer.resize (8,0);
261  m_dlHarqProcessesTimer.insert (std::pair <uint16_t, DlHarqProcessesTimer_t> (params.m_rnti, dlHarqProcessesTimer));
262  DlHarqProcessesDciBuffer_t dlHarqdci;
263  dlHarqdci.resize (8);
264  m_dlHarqProcessesDciBuffer.insert (std::pair <uint16_t, DlHarqProcessesDciBuffer_t> (params.m_rnti, dlHarqdci));
265  DlHarqRlcPduListBuffer_t dlHarqRlcPdu;
266  dlHarqRlcPdu.resize (2);
267  dlHarqRlcPdu.at (0).resize (8);
268  dlHarqRlcPdu.at (1).resize (8);
269  m_dlHarqProcessesRlcPduListBuffer.insert (std::pair <uint16_t, DlHarqRlcPduListBuffer_t> (params.m_rnti, dlHarqRlcPdu));
270  m_ulHarqCurrentProcessId.insert (std::pair <uint16_t,uint8_t > (params.m_rnti, 0));
271  UlHarqProcessesStatus_t ulHarqPrcStatus;
272  ulHarqPrcStatus.resize (8,0);
273  m_ulHarqProcessesStatus.insert (std::pair <uint16_t, UlHarqProcessesStatus_t> (params.m_rnti, ulHarqPrcStatus));
274  UlHarqProcessesDciBuffer_t ulHarqdci;
275  ulHarqdci.resize (8);
276  m_ulHarqProcessesDciBuffer.insert (std::pair <uint16_t, UlHarqProcessesDciBuffer_t> (params.m_rnti, ulHarqdci));
277  }
278  else
279  {
280  (*it).second = params.m_transmissionMode;
281  }
282  return;
283 }
284 
285 void
287 {
288  NS_LOG_FUNCTION (this << " New LC, rnti: " << params.m_rnti);
289 
290  NS_LOG_FUNCTION ("LC configuration. Number of LCs:"<<params.m_logicalChannelConfigList.size ());
291 
292  // m_reconfigureFlat indicates if this is a reconfiguration or new UE is added, table 4.1.5 in LTE MAC scheduler specification
293  if (params.m_reconfigureFlag)
294  {
295  std::vector <struct LogicalChannelConfigListElement_s>::const_iterator lcit;
296 
297  for(lcit = params.m_logicalChannelConfigList.begin (); lcit!= params.m_logicalChannelConfigList.end (); lcit++)
298  {
299  LteFlowId_t flowid = LteFlowId_t (params.m_rnti,lcit->m_logicalChannelIdentity);
300 
302  {
303  NS_LOG_ERROR ("UE logical channels can not be reconfigured because it was not configured before.");
304  }
305  else
306  {
307  m_ueLogicalChannelsConfigList.find (flowid)->second = *lcit;
308  }
309  }
310 
311  } // else new UE is added
312  else
313  {
314  std::vector <struct LogicalChannelConfigListElement_s>::const_iterator lcit;
315 
316  for (lcit = params.m_logicalChannelConfigList.begin (); lcit != params.m_logicalChannelConfigList.end (); lcit++)
317  {
318  LteFlowId_t flowId = LteFlowId_t (params.m_rnti,lcit->m_logicalChannelIdentity);
319  m_ueLogicalChannelsConfigList.insert (std::pair<LteFlowId_t, LogicalChannelConfigListElement_s>(flowId,*lcit));
320  }
321  }
322 
323 
324  std::map <uint16_t, CqasFlowPerf_t>::iterator it;
325 
326  for (uint16_t i = 0; i < params.m_logicalChannelConfigList.size (); i++)
327  {
328  it = m_flowStatsDl.find (params.m_rnti);
329 
330  if (it == m_flowStatsDl.end ())
331  {
332  double tbrDlInBytes = params.m_logicalChannelConfigList.at (i).m_eRabGuaranteedBitrateDl / 8; // byte/s
333  double tbrUlInBytes = params.m_logicalChannelConfigList.at (i).m_eRabGuaranteedBitrateUl / 8; // byte/s
334 
335  CqasFlowPerf_t flowStatsDl;
336  flowStatsDl.flowStart = Simulator::Now ();
337  flowStatsDl.totalBytesTransmitted = 0;
338  flowStatsDl.lastTtiBytesTransmitted = 0;
339  flowStatsDl.lastAveragedThroughput = 1;
340  flowStatsDl.secondLastAveragedThroughput = 1;
341  flowStatsDl.targetThroughput = tbrDlInBytes;
342  m_flowStatsDl.insert (std::pair<uint16_t, CqasFlowPerf_t> (params.m_rnti, flowStatsDl));
343  CqasFlowPerf_t flowStatsUl;
344  flowStatsUl.flowStart = Simulator::Now ();
345  flowStatsUl.totalBytesTransmitted = 0;
346  flowStatsUl.lastTtiBytesTransmitted = 0;
347  flowStatsUl.lastAveragedThroughput = 1;
348  flowStatsUl.secondLastAveragedThroughput = 1;
349  flowStatsUl.targetThroughput = tbrUlInBytes;
350  m_flowStatsUl.insert (std::pair<uint16_t, CqasFlowPerf_t> (params.m_rnti, flowStatsUl));
351  }
352  else
353  {
354  // update GBR from UeManager::SetupDataRadioBearer ()
355  double tbrDlInBytes = params.m_logicalChannelConfigList.at (i).m_eRabGuaranteedBitrateDl / 8; // byte/s
356  double tbrUlInBytes = params.m_logicalChannelConfigList.at (i).m_eRabGuaranteedBitrateUl / 8; // byte/s
357  m_flowStatsDl[(*it).first].targetThroughput = tbrDlInBytes;
358  m_flowStatsUl[(*it).first].targetThroughput = tbrUlInBytes;
359 
360  }
361  }
362 
363  return;
364 }
365 
366 void
368 {
369  NS_LOG_FUNCTION (this);
370  std::vector <uint8_t>::const_iterator it;
371 
372  for (it = params.m_logicalChannelIdentity.begin (); it != params.m_logicalChannelIdentity.end (); it++)
373  {
374  LteFlowId_t flowId = LteFlowId_t (params.m_rnti, *it);
375 
376  // find the logical channel with the same Logical Channel Identity in the current list, release it
378  {
379  m_ueLogicalChannelsConfigList.erase (flowId);
380  }
381  else
382  {
383  NS_FATAL_ERROR ("Logical channels cannot be released because it can not be found in the list of active LCs");
384  }
385  }
386 
387  for (uint16_t i = 0; i < params.m_logicalChannelIdentity.size (); i++)
388  {
389  std::map<LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it = m_rlcBufferReq.begin ();
390  std::map<LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator temp;
391  while (it!=m_rlcBufferReq.end ())
392  {
393  if (((*it).first.m_rnti == params.m_rnti) && ((*it).first.m_lcId == params.m_logicalChannelIdentity.at (i)))
394  {
395  temp = it;
396  it++;
397  m_rlcBufferReq.erase (temp);
398  }
399  else
400  {
401  it++;
402  }
403  }
404  }
405  return;
406 }
407 
408 void
410 {
411  NS_LOG_FUNCTION (this);
412 
413  for (int i=0; i < MAX_LC_LIST; i++)
414  {
415  LteFlowId_t flowId = LteFlowId_t (params.m_rnti,i);
416  // find the logical channel with the same Logical Channel Identity in the current list, release it
418  {
419  m_ueLogicalChannelsConfigList.erase (flowId);
420  }
421  }
422 
423  m_uesTxMode.erase (params.m_rnti);
424  m_dlHarqCurrentProcessId.erase (params.m_rnti);
425  m_dlHarqProcessesStatus.erase (params.m_rnti);
426  m_dlHarqProcessesTimer.erase (params.m_rnti);
427  m_dlHarqProcessesDciBuffer.erase (params.m_rnti);
429  m_ulHarqCurrentProcessId.erase (params.m_rnti);
430  m_ulHarqProcessesStatus.erase (params.m_rnti);
431  m_ulHarqProcessesDciBuffer.erase (params.m_rnti);
432  m_flowStatsDl.erase (params.m_rnti);
433  m_flowStatsUl.erase (params.m_rnti);
434  m_ceBsrRxed.erase (params.m_rnti);
435  std::map<LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it = m_rlcBufferReq.begin ();
436  std::map<LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator temp;
437  while (it!=m_rlcBufferReq.end ())
438  {
439  if ((*it).first.m_rnti == params.m_rnti)
440  {
441  temp = it;
442  it++;
443  m_rlcBufferReq.erase (temp);
444  }
445  else
446  {
447  it++;
448  }
449  }
450  if (m_nextRntiUl == params.m_rnti)
451  {
452  m_nextRntiUl = 0;
453  }
454 
455  return;
456 }
457 
458 
459 void
461 {
462  NS_LOG_FUNCTION (this << params.m_rnti << (uint32_t) params.m_logicalChannelIdentity);
463  // API generated by RLC for updating RLC parameters on a LC (tx and retx queues)
464 
465  std::map <LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it;
466 
467  LteFlowId_t flow (params.m_rnti, params.m_logicalChannelIdentity);
468 
469  it = m_rlcBufferReq.find (flow);
470 
471  if (it == m_rlcBufferReq.end ())
472  {
473  m_rlcBufferReq.insert (std::pair <LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters> (flow, params));
474  }
475  else
476  {
477  (*it).second = params;
478  }
479 
480  return;
481 }
482 
483 void
485 {
486  NS_LOG_FUNCTION (this);
487  NS_FATAL_ERROR ("method not implemented");
488  return;
489 }
490 
491 void
493 {
494  NS_LOG_FUNCTION (this);
495  NS_FATAL_ERROR ("method not implemented");
496  return;
497 }
498 
499 int
501 {
502  for (int i = 0; i < 4; i++)
503  {
504  if (dlbandwidth < CqaType0AllocationRbg[i])
505  {
506  return (i + 1);
507  }
508  }
509 
510  return (-1);
511 }
512 
513 
514 unsigned int
516 {
517  std::map <LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it;
518  unsigned int lcActive = 0;
519  for (it = m_rlcBufferReq.begin (); it != m_rlcBufferReq.end (); it++)
520  {
521  if (((*it).first.m_rnti == rnti) && (((*it).second.m_rlcTransmissionQueueSize > 0)
522  || ((*it).second.m_rlcRetransmissionQueueSize > 0)
523  || ((*it).second.m_rlcStatusPduSize > 0) ))
524  {
525  lcActive++;
526  }
527  if ((*it).first.m_rnti > rnti)
528  {
529  break;
530  }
531  }
532  return (lcActive);
533 
534 }
535 
536 
537 uint8_t
539 {
540  NS_LOG_FUNCTION (this << rnti);
541 
542  std::map <uint16_t, uint8_t>::iterator it = m_dlHarqCurrentProcessId.find (rnti);
543  if (it == m_dlHarqCurrentProcessId.end ())
544  {
545  NS_FATAL_ERROR ("No Process Id found for this RNTI " << rnti);
546  }
547  std::map <uint16_t, DlHarqProcessesStatus_t>::iterator itStat = m_dlHarqProcessesStatus.find (rnti);
548  if (itStat == m_dlHarqProcessesStatus.end ())
549  {
550  NS_FATAL_ERROR ("No Process Id Statusfound for this RNTI " << rnti);
551  }
552  uint8_t i = (*it).second;
553  do
554  {
555  i = (i + 1) % HARQ_PROC_NUM;
556  }
557  while ( ((*itStat).second.at (i) != 0)&&(i != (*it).second));
558  if ((*itStat).second.at (i) == 0)
559  {
560  return (true);
561  }
562  else
563  {
564  return (false); // return a not valid harq proc id
565  }
566 }
567 
568 
569 
570 uint8_t
572 {
573  NS_LOG_FUNCTION (this << rnti);
574 
575  if (m_harqOn == false)
576  {
577  return (0);
578  }
579 
580 
581  std::map <uint16_t, uint8_t>::iterator it = m_dlHarqCurrentProcessId.find (rnti);
582  if (it == m_dlHarqCurrentProcessId.end ())
583  {
584  NS_FATAL_ERROR ("No Process Id found for this RNTI " << rnti);
585  }
586  std::map <uint16_t, DlHarqProcessesStatus_t>::iterator itStat = m_dlHarqProcessesStatus.find (rnti);
587  if (itStat == m_dlHarqProcessesStatus.end ())
588  {
589  NS_FATAL_ERROR ("No Process Id Statusfound for this RNTI " << rnti);
590  }
591  uint8_t i = (*it).second;
592  do
593  {
594  i = (i + 1) % HARQ_PROC_NUM;
595  }
596  while ( ((*itStat).second.at (i) != 0)&&(i != (*it).second));
597  if ((*itStat).second.at (i) == 0)
598  {
599  (*it).second = i;
600  (*itStat).second.at (i) = 1;
601  }
602  else
603  {
604  NS_FATAL_ERROR ("No HARQ process available for RNTI " << rnti << " check before update with HarqProcessAvailability");
605  }
606 
607  return ((*it).second);
608 }
609 
610 
611 void
613 {
614  NS_LOG_FUNCTION (this);
615 
616  std::map <uint16_t, DlHarqProcessesTimer_t>::iterator itTimers;
617  for (itTimers = m_dlHarqProcessesTimer.begin (); itTimers != m_dlHarqProcessesTimer.end (); itTimers++)
618  {
619  for (uint16_t i = 0; i < HARQ_PROC_NUM; i++)
620  {
621  if ((*itTimers).second.at (i) == HARQ_DL_TIMEOUT)
622  {
623  // reset HARQ process
624 
625  NS_LOG_DEBUG (this << " Reset HARQ proc " << i << " for RNTI " << (*itTimers).first);
626  std::map <uint16_t, DlHarqProcessesStatus_t>::iterator itStat = m_dlHarqProcessesStatus.find ((*itTimers).first);
627  if (itStat == m_dlHarqProcessesStatus.end ())
628  {
629  NS_FATAL_ERROR ("No Process Id Status found for this RNTI " << (*itTimers).first);
630  }
631  (*itStat).second.at (i) = 0;
632  (*itTimers).second.at (i) = 0;
633  }
634  else
635  {
636  (*itTimers).second.at (i)++;
637  }
638  }
639  }
640 
641 }
642 
643 
644 void
646 {
647  NS_LOG_FUNCTION (this << " Frame no. " << (params.m_sfnSf >> 4) << " subframe no. " << (0xF & params.m_sfnSf));
648  // API generated by RLC for triggering the scheduling of a DL subframe
649  // evaluate the relative channel quality indicator for each UE per each RBG
650  // (since we are using allocation type 0 the small unit of allocation is RBG)
651  // Resource allocation type 0 (see sec 7.1.6.1 of 36.213)
652 
653  RefreshDlCqiMaps ();
654 
656  int numberOfRBGs = m_cschedCellConfig.m_dlBandwidth / rbgSize;
657  std::map <uint16_t, std::multimap <uint8_t, qos_rb_and_CQI_assigned_to_lc> > allocationMapPerRntiPerLCId;
658  std::map <uint16_t, std::multimap <uint8_t, qos_rb_and_CQI_assigned_to_lc> >::iterator itMap;
659  allocationMapPerRntiPerLCId.clear ();
660  bool(*key_function_pointer_groups)(int,int) = CqaGroupDescComparator;
661  t_map_HOLgroupToUEs map_GBRHOLgroupToUE (key_function_pointer_groups);
662  t_map_HOLgroupToUEs map_nonGBRHOLgroupToUE (key_function_pointer_groups);
663  int grouping_parameter = 1000;
664  double tolerance = 1.1;
665  std::map<LteFlowId_t,int> UEtoHOL;
666  std::vector <bool> rbgMap; // global RBGs map
667  uint16_t rbgAllocatedNum = 0;
668  std::set <uint16_t> rntiAllocated;
669  rbgMap.resize (m_cschedCellConfig.m_dlBandwidth / rbgSize, false);
670 
671  rbgMap = m_ffrSapProvider->GetAvailableDlRbg ();
672  for (std::vector<bool>::iterator it = rbgMap.begin (); it != rbgMap.end (); it++)
673  {
674  if ((*it) == true )
675  {
676  rbgAllocatedNum++;
677  }
678  }
679 
681 
682  // update UL HARQ proc id
683  std::map <uint16_t, uint8_t>::iterator itProcId;
684  for (itProcId = m_ulHarqCurrentProcessId.begin (); itProcId != m_ulHarqCurrentProcessId.end (); itProcId++)
685  {
686  (*itProcId).second = ((*itProcId).second + 1) % HARQ_PROC_NUM;
687  }
688 
689 
690  // RACH Allocation
691  uint16_t rbAllocatedNum = 0;
692  std::vector <bool> ulRbMap;
693  ulRbMap.resize (m_cschedCellConfig.m_ulBandwidth, false);
694  ulRbMap = m_ffrSapProvider->GetAvailableUlRbg ();
695  uint8_t maxContinuousUlBandwidth = 0;
696  uint8_t tmpMinBandwidth = 0;
697  uint16_t ffrRbStartOffset = 0;
698  uint16_t tmpFfrRbStartOffset = 0;
699  uint16_t index = 0;
700 
701  for (std::vector<bool>::iterator it = ulRbMap.begin (); it != ulRbMap.end (); it++)
702  {
703  if ((*it) == true )
704  {
705  rbAllocatedNum++;
706  if (tmpMinBandwidth > maxContinuousUlBandwidth)
707  {
708  maxContinuousUlBandwidth = tmpMinBandwidth;
709  ffrRbStartOffset = tmpFfrRbStartOffset;
710  }
711  tmpMinBandwidth = 0;
712  }
713  else
714  {
715  if (tmpMinBandwidth == 0)
716  {
717  tmpFfrRbStartOffset = index;
718  }
719  tmpMinBandwidth++;
720  }
721  index++;
722  }
723 
724  if (tmpMinBandwidth > maxContinuousUlBandwidth)
725  {
726  maxContinuousUlBandwidth = tmpMinBandwidth;
727  ffrRbStartOffset = tmpFfrRbStartOffset;
728  }
729 
731  uint16_t rbStart = 0;
732  rbStart = ffrRbStartOffset;
733  std::vector <struct RachListElement_s>::iterator itRach;
734  for (itRach = m_rachList.begin (); itRach != m_rachList.end (); itRach++)
735  {
736  NS_ASSERT_MSG (m_amc->GetUlTbSizeFromMcs (m_ulGrantMcs, m_cschedCellConfig.m_ulBandwidth) > (*itRach).m_estimatedSize, " Default UL Grant MCS does not allow to send RACH messages");
737  BuildRarListElement_s newRar;
738  newRar.m_rnti = (*itRach).m_rnti;
739  // DL-RACH Allocation
740  // Ideal: no needs of configuring m_dci
741  // UL-RACH Allocation
742  newRar.m_grant.m_rnti = newRar.m_rnti;
743  newRar.m_grant.m_mcs = m_ulGrantMcs;
744  uint16_t rbLen = 1;
745  uint16_t tbSizeBits = 0;
746  // find lowest TB size that fits UL grant estimated size
747  while ((tbSizeBits < (*itRach).m_estimatedSize) && (rbStart + rbLen < (ffrRbStartOffset + maxContinuousUlBandwidth)))
748  {
749  rbLen++;
750  tbSizeBits = m_amc->GetUlTbSizeFromMcs (m_ulGrantMcs, rbLen);
751  }
752  if (tbSizeBits < (*itRach).m_estimatedSize)
753  {
754  // no more allocation space: finish allocation
755  break;
756  }
757  newRar.m_grant.m_rbStart = rbStart;
758  newRar.m_grant.m_rbLen = rbLen;
759  newRar.m_grant.m_tbSize = tbSizeBits / 8;
760  newRar.m_grant.m_hopping = false;
761  newRar.m_grant.m_tpc = 0;
762  newRar.m_grant.m_cqiRequest = false;
763  newRar.m_grant.m_ulDelay = false;
764  NS_LOG_INFO (this << " UL grant allocated to RNTI " << (*itRach).m_rnti << " rbStart " << rbStart << " rbLen " << rbLen << " MCS " << m_ulGrantMcs << " tbSize " << newRar.m_grant.m_tbSize);
765  for (uint16_t i = rbStart; i < rbStart + rbLen; i++)
766  {
767  m_rachAllocationMap.at (i) = (*itRach).m_rnti;
768  }
769 
770  if (m_harqOn == true)
771  {
772  // generate UL-DCI for HARQ retransmissions
773  UlDciListElement_s uldci;
774  uldci.m_rnti = newRar.m_rnti;
775  uldci.m_rbLen = rbLen;
776  uldci.m_rbStart = rbStart;
777  uldci.m_mcs = m_ulGrantMcs;
778  uldci.m_tbSize = tbSizeBits / 8;
779  uldci.m_ndi = 1;
780  uldci.m_cceIndex = 0;
781  uldci.m_aggrLevel = 1;
782  uldci.m_ueTxAntennaSelection = 3; // antenna selection OFF
783  uldci.m_hopping = false;
784  uldci.m_n2Dmrs = 0;
785  uldci.m_tpc = 0; // no power control
786  uldci.m_cqiRequest = false; // only period CQI at this stage
787  uldci.m_ulIndex = 0; // TDD parameter
788  uldci.m_dai = 1; // TDD parameter
789  uldci.m_freqHopping = 0;
790  uldci.m_pdcchPowerOffset = 0; // not used
791 
792  uint8_t harqId = 0;
793  std::map <uint16_t, uint8_t>::iterator itProcId;
794  itProcId = m_ulHarqCurrentProcessId.find (uldci.m_rnti);
795  if (itProcId == m_ulHarqCurrentProcessId.end ())
796  {
797  NS_FATAL_ERROR ("No info find in HARQ buffer for UE " << uldci.m_rnti);
798  }
799  harqId = (*itProcId).second;
800  std::map <uint16_t, UlHarqProcessesDciBuffer_t>::iterator itDci = m_ulHarqProcessesDciBuffer.find (uldci.m_rnti);
801  if (itDci == m_ulHarqProcessesDciBuffer.end ())
802  {
803  NS_FATAL_ERROR ("Unable to find RNTI entry in UL DCI HARQ buffer for RNTI " << uldci.m_rnti);
804  }
805  (*itDci).second.at (harqId) = uldci;
806  }
807 
808  rbStart = rbStart + rbLen;
809  ret.m_buildRarList.push_back (newRar);
810  }
811  m_rachList.clear ();
812 
813 
814  // Process DL HARQ feedback
816  // retrieve past HARQ retx buffered
817  if (m_dlInfoListBuffered.size () > 0)
818  {
819  if (params.m_dlInfoList.size () > 0)
820  {
821  NS_LOG_INFO (this << " Received DL-HARQ feedback");
822  m_dlInfoListBuffered.insert (m_dlInfoListBuffered.end (), params.m_dlInfoList.begin (), params.m_dlInfoList.end ());
823  }
824  }
825  else
826  {
827  if (params.m_dlInfoList.size () > 0)
828  {
830  }
831  }
832  if (m_harqOn == false)
833  {
834  // Ignore HARQ feedback
835  m_dlInfoListBuffered.clear ();
836  }
837  std::vector <struct DlInfoListElement_s> dlInfoListUntxed;
838  for (uint16_t i = 0; i < m_dlInfoListBuffered.size (); i++)
839  {
840  std::set <uint16_t>::iterator itRnti = rntiAllocated.find (m_dlInfoListBuffered.at (i).m_rnti);
841  if (itRnti != rntiAllocated.end ())
842  {
843  // RNTI already allocated for retx
844  continue;
845  }
846  uint8_t nLayers = m_dlInfoListBuffered.at (i).m_harqStatus.size ();
847  std::vector <bool> retx;
848  NS_LOG_INFO (this << " Processing DLHARQ feedback");
849  if (nLayers == 1)
850  {
851  retx.push_back (m_dlInfoListBuffered.at (i).m_harqStatus.at (0) == DlInfoListElement_s::NACK);
852  retx.push_back (false);
853  }
854  else
855  {
856  retx.push_back (m_dlInfoListBuffered.at (i).m_harqStatus.at (0) == DlInfoListElement_s::NACK);
857  retx.push_back (m_dlInfoListBuffered.at (i).m_harqStatus.at (1) == DlInfoListElement_s::NACK);
858  }
859  if (retx.at (0) || retx.at (1))
860  {
861  // retrieve HARQ process information
862  uint16_t rnti = m_dlInfoListBuffered.at (i).m_rnti;
863  uint8_t harqId = m_dlInfoListBuffered.at (i).m_harqProcessId;
864  NS_LOG_INFO (this << " HARQ retx RNTI " << rnti << " harqId " << (uint16_t)harqId);
865  std::map <uint16_t, DlHarqProcessesDciBuffer_t>::iterator itHarq = m_dlHarqProcessesDciBuffer.find (rnti);
866  if (itHarq == m_dlHarqProcessesDciBuffer.end ())
867  {
868  NS_FATAL_ERROR ("No info find in HARQ buffer for UE " << rnti);
869  }
870 
871  DlDciListElement_s dci = (*itHarq).second.at (harqId);
872  int rv = 0;
873  if (dci.m_rv.size () == 1)
874  {
875  rv = dci.m_rv.at (0);
876  }
877  else
878  {
879  rv = (dci.m_rv.at (0) > dci.m_rv.at (1) ? dci.m_rv.at (0) : dci.m_rv.at (1));
880  }
881 
882  if (rv == 3)
883  {
884  // maximum number of retx reached -> drop process
885  NS_LOG_INFO ("Maximum number of retransmissions reached -> drop process");
886  std::map <uint16_t, DlHarqProcessesStatus_t>::iterator it = m_dlHarqProcessesStatus.find (rnti);
887  if (it == m_dlHarqProcessesStatus.end ())
888  {
889  NS_LOG_ERROR ("No info find in HARQ buffer for UE (might change eNB) " << m_dlInfoListBuffered.at (i).m_rnti);
890  }
891  (*it).second.at (harqId) = 0;
892  std::map <uint16_t, DlHarqRlcPduListBuffer_t>::iterator itRlcPdu = m_dlHarqProcessesRlcPduListBuffer.find (rnti);
893  if (itRlcPdu == m_dlHarqProcessesRlcPduListBuffer.end ())
894  {
895  NS_FATAL_ERROR ("Unable to find RlcPdcList in HARQ buffer for RNTI " << m_dlInfoListBuffered.at (i).m_rnti);
896  }
897  for (uint16_t k = 0; k < (*itRlcPdu).second.size (); k++)
898  {
899  (*itRlcPdu).second.at (k).at (harqId).clear ();
900  }
901  continue;
902  }
903  // check the feasibility of retransmitting on the same RBGs
904  // translate the DCI to Spectrum framework
905  std::vector <int> dciRbg;
906  uint32_t mask = 0x1;
907  NS_LOG_INFO ("Original RBGs " << dci.m_rbBitmap << " rnti " << dci.m_rnti);
908  for (int j = 0; j < 32; j++)
909  {
910  if (((dci.m_rbBitmap & mask) >> j) == 1)
911  {
912  dciRbg.push_back (j);
913  NS_LOG_INFO ("\t" << j);
914  }
915  mask = (mask << 1);
916  }
917  bool free = true;
918  for (uint8_t j = 0; j < dciRbg.size (); j++)
919  {
920  if (rbgMap.at (dciRbg.at (j)) == true)
921  {
922  free = false;
923  break;
924  }
925  }
926  if (free)
927  {
928  // use the same RBGs for the retx
929  // reserve RBGs
930  for (uint8_t j = 0; j < dciRbg.size (); j++)
931  {
932  rbgMap.at (dciRbg.at (j)) = true;
933  NS_LOG_INFO ("RBG " << dciRbg.at (j) << " assigned");
934  rbgAllocatedNum++;
935  }
936 
937  NS_LOG_INFO (this << " Send retx in the same RBGs");
938  }
939  else
940  {
941  // find RBGs for sending HARQ retx
942  uint8_t j = 0;
943  uint8_t rbgId = (dciRbg.at (dciRbg.size () - 1) + 1) % numberOfRBGs;
944  uint8_t startRbg = dciRbg.at (dciRbg.size () - 1);
945  std::vector <bool> rbgMapCopy = rbgMap;
946  while ((j < dciRbg.size ())&&(startRbg != rbgId))
947  {
948  if (rbgMapCopy.at (rbgId) == false)
949  {
950  rbgMapCopy.at (rbgId) = true;
951  dciRbg.at (j) = rbgId;
952  j++;
953  }
954  rbgId = (rbgId + 1) % numberOfRBGs;
955  }
956  if (j == dciRbg.size ())
957  {
958  // find new RBGs -> update DCI map
959  uint32_t rbgMask = 0;
960  for (uint16_t k = 0; k < dciRbg.size (); k++)
961  {
962  rbgMask = rbgMask + (0x1 << dciRbg.at (k));
963  rbgAllocatedNum++;
964  }
965  dci.m_rbBitmap = rbgMask;
966  rbgMap = rbgMapCopy;
967  NS_LOG_INFO (this << " Move retx in RBGs " << dciRbg.size ());
968  }
969  else
970  {
971  // HARQ retx cannot be performed on this TTI -> store it
972  dlInfoListUntxed.push_back (m_dlInfoListBuffered.at (i));
973  NS_LOG_INFO (this << " No resource for this retx -> buffer it");
974  }
975  }
976  // retrieve RLC PDU list for retx TBsize and update DCI
978  std::map <uint16_t, DlHarqRlcPduListBuffer_t>::iterator itRlcPdu = m_dlHarqProcessesRlcPduListBuffer.find (rnti);
979  if (itRlcPdu == m_dlHarqProcessesRlcPduListBuffer.end ())
980  {
981  NS_FATAL_ERROR ("Unable to find RlcPdcList in HARQ buffer for RNTI " << rnti);
982  }
983  for (uint8_t j = 0; j < nLayers; j++)
984  {
985  if (retx.at (j))
986  {
987  if (j >= dci.m_ndi.size ())
988  {
989  // for avoiding errors in MIMO transient phases
990  dci.m_ndi.push_back (0);
991  dci.m_rv.push_back (0);
992  dci.m_mcs.push_back (0);
993  dci.m_tbsSize.push_back (0);
994  NS_LOG_INFO (this << " layer " << (uint16_t)j << " no txed (MIMO transition)");
995  }
996  else
997  {
998  dci.m_ndi.at (j) = 0;
999  dci.m_rv.at (j)++;
1000  (*itHarq).second.at (harqId).m_rv.at (j)++;
1001  NS_LOG_INFO (this << " layer " << (uint16_t)j << " RV " << (uint16_t)dci.m_rv.at (j));
1002  }
1003  }
1004  else
1005  {
1006  // empty TB of layer j
1007  dci.m_ndi.at (j) = 0;
1008  dci.m_rv.at (j) = 0;
1009  dci.m_mcs.at (j) = 0;
1010  dci.m_tbsSize.at (j) = 0;
1011  NS_LOG_INFO (this << " layer " << (uint16_t)j << " no retx");
1012  }
1013  }
1014  for (uint16_t k = 0; k < (*itRlcPdu).second.at (0).at (dci.m_harqProcess).size (); k++)
1015  {
1016  std::vector <struct RlcPduListElement_s> rlcPduListPerLc;
1017  for (uint8_t j = 0; j < nLayers; j++)
1018  {
1019  if (retx.at (j))
1020  {
1021  if (j < dci.m_ndi.size ())
1022  {
1023  NS_LOG_INFO (" layer " << (uint16_t)j << " tb size " << dci.m_tbsSize.at (j));
1024  rlcPduListPerLc.push_back ((*itRlcPdu).second.at (j).at (dci.m_harqProcess).at (k));
1025  }
1026  }
1027  else
1028  { // if no retx needed on layer j, push an RlcPduListElement_s object with m_size=0 to keep the size of rlcPduListPerLc vector = 2 in case of MIMO
1029  NS_LOG_INFO (" layer " << (uint16_t)j << " tb size "<<dci.m_tbsSize.at (j));
1030  RlcPduListElement_s emptyElement;
1031  emptyElement.m_logicalChannelIdentity = (*itRlcPdu).second.at (j).at (dci.m_harqProcess).at (k).m_logicalChannelIdentity;
1032  emptyElement.m_size = 0;
1033  rlcPduListPerLc.push_back (emptyElement);
1034  }
1035  }
1036 
1037  if (rlcPduListPerLc.size () > 0)
1038  {
1039  newEl.m_rlcPduList.push_back (rlcPduListPerLc);
1040  }
1041  }
1042  newEl.m_rnti = rnti;
1043  newEl.m_dci = dci;
1044  (*itHarq).second.at (harqId).m_rv = dci.m_rv;
1045  // refresh timer
1046  std::map <uint16_t, DlHarqProcessesTimer_t>::iterator itHarqTimer = m_dlHarqProcessesTimer.find (rnti);
1047  if (itHarqTimer== m_dlHarqProcessesTimer.end ())
1048  {
1049  NS_FATAL_ERROR ("Unable to find HARQ timer for RNTI " << (uint16_t)rnti);
1050  }
1051  (*itHarqTimer).second.at (harqId) = 0;
1052  ret.m_buildDataList.push_back (newEl);
1053  rntiAllocated.insert (rnti);
1054  }
1055  else
1056  {
1057  // update HARQ process status
1058  NS_LOG_INFO (this << " HARQ received ACK for UE " << m_dlInfoListBuffered.at (i).m_rnti);
1059  std::map <uint16_t, DlHarqProcessesStatus_t>::iterator it = m_dlHarqProcessesStatus.find (m_dlInfoListBuffered.at (i).m_rnti);
1060  if (it == m_dlHarqProcessesStatus.end ())
1061  {
1062  NS_FATAL_ERROR ("No info find in HARQ buffer for UE " << m_dlInfoListBuffered.at (i).m_rnti);
1063  }
1064  (*it).second.at (m_dlInfoListBuffered.at (i).m_harqProcessId) = 0;
1065  std::map <uint16_t, DlHarqRlcPduListBuffer_t>::iterator itRlcPdu = m_dlHarqProcessesRlcPduListBuffer.find (m_dlInfoListBuffered.at (i).m_rnti);
1066  if (itRlcPdu == m_dlHarqProcessesRlcPduListBuffer.end ())
1067  {
1068  NS_FATAL_ERROR ("Unable to find RlcPdcList in HARQ buffer for RNTI " << m_dlInfoListBuffered.at (i).m_rnti);
1069  }
1070  for (uint16_t k = 0; k < (*itRlcPdu).second.size (); k++)
1071  {
1072  (*itRlcPdu).second.at (k).at (m_dlInfoListBuffered.at (i).m_harqProcessId).clear ();
1073  }
1074  }
1075  }
1076  m_dlInfoListBuffered.clear ();
1077  m_dlInfoListBuffered = dlInfoListUntxed;
1078 
1079  if (rbgAllocatedNum == numberOfRBGs)
1080  {
1081  // all the RBGs are already allocated -> exit
1082  if ((ret.m_buildDataList.size () > 0) || (ret.m_buildRarList.size () > 0))
1083  {
1085  }
1086  return;
1087  }
1088 
1089  std::map <LteFlowId_t,struct LogicalChannelConfigListElement_s>::iterator itLogicalChannels;
1090 
1091  for (itLogicalChannels = m_ueLogicalChannelsConfigList.begin (); itLogicalChannels != m_ueLogicalChannelsConfigList.end (); itLogicalChannels++)
1092  {
1093  std::set <uint16_t>::iterator itRnti = rntiAllocated.find (itLogicalChannels->first.m_rnti);
1094  if ((itRnti != rntiAllocated.end ())||(!HarqProcessAvailability (itLogicalChannels->first.m_rnti)))
1095  {
1096  // UE already allocated for HARQ or without HARQ process available -> drop it
1097  if (itRnti != rntiAllocated.end ())
1098  {
1099  NS_LOG_DEBUG (this << " RNTI discared for HARQ tx" << (uint16_t)(itLogicalChannels->first.m_rnti));
1100  }
1101  if (!HarqProcessAvailability (itLogicalChannels->first.m_rnti))
1102  {
1103  NS_LOG_DEBUG (this << " RNTI discared for HARQ id" << (uint16_t)(itLogicalChannels->first.m_rnti));
1104  }
1105  continue;
1106  }
1107 
1108 
1109  std::map <LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator itRlcBufferReq = m_rlcBufferReq.find (itLogicalChannels->first);
1110  if (itRlcBufferReq==m_rlcBufferReq.end ())
1111  continue;
1112 
1113  int group = -1;
1114  int delay = 0;
1115 
1116  if (itRlcBufferReq->second.m_rlcRetransmissionQueueSize > 0)
1117  {
1118  delay = itRlcBufferReq->second.m_rlcRetransmissionHolDelay;
1119  group = delay/grouping_parameter;
1120  }
1121  else if (itRlcBufferReq->second.m_rlcTransmissionQueueSize > 0)
1122  {
1123  delay = itRlcBufferReq->second.m_rlcTransmissionQueueHolDelay;
1124  group = delay/grouping_parameter;
1125  }
1126  else
1127  {
1128  continue;
1129  }
1130 
1131  UEtoHOL.insert (std::pair<LteFlowId_t,int>(itLogicalChannels->first,delay));
1132 
1133  if (itLogicalChannels->second.m_qosBearerType == itLogicalChannels->second.QBT_NON_GBR )
1134  {
1135  if (map_nonGBRHOLgroupToUE.count (group)==0)
1136  {
1137  std::set<LteFlowId_t> v;
1138  v.insert (itRlcBufferReq->first);
1139  map_nonGBRHOLgroupToUE.insert (std::pair<int,std::set<LteFlowId_t> >(group,v));
1140  }
1141  else
1142  {
1143  map_nonGBRHOLgroupToUE.find (group)->second.insert (itRlcBufferReq->first);
1144  }
1145  }
1146  else if (itLogicalChannels->second.m_qosBearerType == itLogicalChannels->second.QBT_GBR) {
1147  if (map_GBRHOLgroupToUE.count (group)==0)
1148  {
1149  std::set<LteFlowId_t> v;
1150  v.insert (itRlcBufferReq->first);
1151  map_GBRHOLgroupToUE.insert (std::pair<int,std::set<LteFlowId_t> >(group,v));
1152  }
1153  else
1154  {
1155  map_GBRHOLgroupToUE.find (group)->second.insert (itRlcBufferReq->first);
1156  }
1157  }
1158  };
1159 
1160 
1161  // Prepare data for the scheduling mechanism
1162  // map: UE, to the amount of traffic they have to transfer
1163  std::map<LteFlowId_t, int> UeToAmountOfDataToTransfer;
1164  //Initialize the map per UE, how much resources is already assigned to the user
1165  std::map<LteFlowId_t, int> UeToAmountOfAssignedResources;
1166  // prepare values to calculate FF metric, this metric will be the same for all flows(logical channels) that belong to the same RNTI
1167  std::map < uint16_t, uint8_t > sbCqiSum;
1168 
1169  for( std::map <LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator itrbr = m_rlcBufferReq.begin ();
1170  itrbr!=m_rlcBufferReq.end (); itrbr++)
1171  {
1172 
1173  LteFlowId_t flowId = itrbr->first; // Prepare data for the scheduling mechanism
1174  // check first the channel conditions for this UE, if CQI!=0
1175  std::map <uint16_t,SbMeasResult_s>::iterator itCqi;
1176  itCqi = m_a30CqiRxed.find ((*itrbr).first.m_rnti);
1177  std::map <uint16_t,uint8_t>::iterator itTxMode;
1178  itTxMode = m_uesTxMode.find ((*itrbr).first.m_rnti);
1179  if (itTxMode == m_uesTxMode.end ())
1180  {
1181  NS_FATAL_ERROR ("No Transmission Mode info on user " << (*itrbr).first.m_rnti);
1182  }
1183  int nLayer = TransmissionModesLayers::TxMode2LayerNum ((*itTxMode).second);
1184 
1185  uint8_t cqiSum = 0;
1186  for (int k = 0; k < numberOfRBGs; k++)
1187  {
1188  for (uint8_t j = 0; j < nLayer; j++)
1189  {
1190  if (itCqi == m_a30CqiRxed.end ())
1191  {
1192  cqiSum += 1; // no info on this user -> lowest MCS
1193  }
1194  else
1195  {
1196  cqiSum += (*itCqi).second.m_higherLayerSelected.at (k).m_sbCqi.at(j);
1197  }
1198  }
1199  }
1200 
1201  if (cqiSum == 0)
1202  {
1203  NS_LOG_INFO ("Skip this flow, CQI==0, rnti:"<<(*itrbr).first.m_rnti);
1204  continue;
1205  }
1206 
1207  // map: UE, to the amount of traffic they have to transfer
1208  int amountOfDataToTransfer = 8*((int)m_rlcBufferReq.find (flowId)->second.m_rlcRetransmissionQueueSize +
1209  (int)m_rlcBufferReq.find (flowId)->second.m_rlcTransmissionQueueSize);
1210 
1211  UeToAmountOfDataToTransfer.insert (std::pair<LteFlowId_t,int>(flowId,amountOfDataToTransfer));
1212  UeToAmountOfAssignedResources.insert (std::pair<LteFlowId_t,int>(flowId,0));
1213 
1214  uint8_t sum = 0;
1215  for (int i = 0; i < numberOfRBGs; i++)
1216  {
1217  std::map <uint16_t,SbMeasResult_s>::iterator itCqi;
1218  itCqi = m_a30CqiRxed.find ((*itrbr).first.m_rnti);
1219  std::map <uint16_t,uint8_t>::iterator itTxMode;
1220  itTxMode = m_uesTxMode.find ((*itrbr).first.m_rnti);
1221  if (itTxMode == m_uesTxMode.end ())
1222  {
1223  NS_FATAL_ERROR ("No Transmission Mode info on user " << (*itrbr).first.m_rnti);
1224  }
1225  int nLayer = TransmissionModesLayers::TxMode2LayerNum ((*itTxMode).second);
1226  std::vector <uint8_t> sbCqis;
1227  if (itCqi == m_a30CqiRxed.end ())
1228  {
1229  for (uint8_t k = 0; k < nLayer; k++)
1230  {
1231  sbCqis.push_back (1); // start with lowest value
1232  }
1233  }
1234  else
1235  {
1236  sbCqis = (*itCqi).second.m_higherLayerSelected.at (i).m_sbCqi;
1237  }
1238 
1239  uint8_t cqi1 = sbCqis.at (0);
1240  uint8_t cqi2 = 0;
1241  if (sbCqis.size () > 1)
1242  {
1243  cqi2 = sbCqis.at (1);
1244  }
1245 
1246  uint8_t sbCqi = 0;
1247  if ((cqi1 > 0)||(cqi2 > 0)) // CQI == 0 means "out of range" (see table 7.2.3-1 of 36.213)
1248  {
1249  for (uint8_t k = 0; k < nLayer; k++)
1250  {
1251  if (sbCqis.size () > k)
1252  {
1253  sbCqi = sbCqis.at (k);
1254  }
1255  else
1256  {
1257  // no info on this subband
1258  sbCqi = 0;
1259  }
1260  sum += sbCqi;
1261  }
1262  } // end if cqi
1263  } // end of rbgNum
1264 
1265  sbCqiSum.insert (std::pair<uint16_t, uint8_t> ((*itrbr).first.m_rnti, sum));
1266  }
1267 
1268  // availableRBGs - set that contains indexes of available resource block groups
1269  std::set<int> availableRBGs;
1270  for (int i = 0; i < numberOfRBGs; i++)
1271  {
1272  if (rbgMap.at (i) == false)
1273  {
1274  availableRBGs.insert (i);
1275  }
1276  }
1277 
1278  t_it_HOLgroupToUEs itGBRgroups = map_GBRHOLgroupToUE.begin ();
1279  t_it_HOLgroupToUEs itnonGBRgroups = map_nonGBRHOLgroupToUE.begin ();
1280 
1281 
1282 
1283  // while there are more resources available, loop through the users that are grouped by HOL value
1284  while (availableRBGs.size ()>0)
1285  {
1286  if (UeToAmountOfDataToTransfer.size() == 0)
1287  {
1288  NS_LOG_INFO ("No UEs to be scheduled (no data or CQI==0),");
1289  break;
1290  }
1291  std::set<LteFlowId_t> vUEs;
1292  t_it_HOLgroupToUEs itCurrentGroup;
1293 
1294  if (itGBRgroups!=map_GBRHOLgroupToUE.end ())
1295  {
1296  itCurrentGroup=itGBRgroups;
1297  itGBRgroups++;
1298  }
1299  else if (itnonGBRgroups!=map_nonGBRHOLgroupToUE.end ()) // if there are no more flows with retransmission queue start to scheduler flows with transmission queue
1300  {
1301  itCurrentGroup=itnonGBRgroups;
1302  itnonGBRgroups++;
1303  }
1304  else
1305  {
1306  NS_LOG_INFO ("Available RBGs:"<< availableRBGs.size ()<<"but no users");
1307  break;
1308  }
1309 
1310  while (availableRBGs.size ()>0 and itCurrentGroup->second.size ()>0)
1311  {
1312  bool currentRBchecked = false;
1313  int currentRB = *(availableRBGs.begin ());
1314  std::map<LteFlowId_t, CQI_value> UeToCQIValue;
1315  std::map<LteFlowId_t, double > UeToCoitaMetric;
1316  std::map<LteFlowId_t, bool> UeHasReachedGBR;
1317  double maximumValueMetric = 0;
1318  LteFlowId_t userWithMaximumMetric;
1319  UeToCQIValue.clear ();
1320  UeToCoitaMetric.clear ();
1321 
1322  // Iterate through the users and calculate which user will use the best of the current resource bloc.end()k and assign to that user.
1323  for (std::set<LteFlowId_t>::iterator it=itCurrentGroup->second.begin (); it!=itCurrentGroup->second.end (); it++)
1324  {
1325  LteFlowId_t flowId = *it;
1326  uint8_t cqi_value = 1; //higher better, maximum is 15
1327  double coita_metric = 1;
1328  double coita_sum = 0;
1329  double metric = 0;
1330  uint8_t worstCQIAmongRBGsAllocatedForThisUser = 15;
1331  int numberOfRBGAllocatedForThisUser = 0;
1333  std::map <uint16_t,SbMeasResult_s>::iterator itRntiCQIsMap = m_a30CqiRxed.find (flowId.m_rnti);
1334 
1335  std::map <uint16_t, CqasFlowPerf_t>::iterator itStats;
1336 
1337  if ((m_ffrSapProvider->IsDlRbgAvailableForUe (currentRB, flowId.m_rnti)) == false)
1338  {
1339  continue;
1340  }
1341 
1342  if (m_flowStatsDl.find (flowId.m_rnti) == m_flowStatsDl.end ())
1343  {
1344  continue; // TO DO: check if this should be logged and how.
1345  }
1346  currentRBchecked = true;
1347 
1348  itStats = m_flowStatsDl.find (flowId.m_rnti);
1349  double tbr_weight = (*itStats).second.targetThroughput / (*itStats).second.lastAveragedThroughput;
1350  if (tbr_weight < 1.0)
1351  tbr_weight = 1.0;
1352 
1353  if (itRntiCQIsMap != m_a30CqiRxed.end ())
1354  {
1355  for(std::set<int>::iterator it=availableRBGs.begin (); it!=availableRBGs.end (); it++)
1356  {
1357  try
1358  {
1359  int val = (itRntiCQIsMap->second.m_higherLayerSelected.at (*it).m_sbCqi.at (0));
1360  if (val==0)
1361  val=1; //if no info, use minimum
1362  if (*it == currentRB)
1363  cqi_value = val;
1364  coita_sum+=val;
1365 
1366  }
1367  catch(std::out_of_range&)
1368  {
1369  coita_sum+=1; //if no info on channel use the worst cqi
1370  NS_LOG_INFO ("No CQI for lcId:"<<flowId.m_lcId<<" rnti:"<<flowId.m_rnti<<" at subband:"<<currentRB);
1371  //std::cout<<"\n No CQI for lcId:.....................................";
1372  }
1373  }
1374  coita_metric =cqi_value/coita_sum;
1375  UeToCQIValue.insert (std::pair<LteFlowId_t,CQI_value>(flowId,cqi_value));
1376  UeToCoitaMetric.insert (std::pair<LteFlowId_t, double>(flowId,coita_metric));
1377  }
1378 
1379  if (allocationMapPerRntiPerLCId.find (flowId.m_rnti)==allocationMapPerRntiPerLCId.end ())
1380  {
1381  worstCQIAmongRBGsAllocatedForThisUser=cqi_value;
1382  }
1383  else {
1384 
1385  numberOfRBGAllocatedForThisUser = (allocationMapPerRntiPerLCId.find (flowId.m_rnti)->second.size ());
1386 
1387  for (std::multimap <uint8_t, qos_rb_and_CQI_assigned_to_lc>::iterator itRBG = allocationMapPerRntiPerLCId.find (flowId.m_rnti)->second.begin ();
1388  itRBG!=allocationMapPerRntiPerLCId.find (flowId.m_rnti)->second.end (); itRBG++)
1389  {
1390  qos_rb_and_CQI_assigned_to_lc e = itRBG->second;
1391  if (e.cqi_value_for_lc < worstCQIAmongRBGsAllocatedForThisUser)
1392  worstCQIAmongRBGsAllocatedForThisUser=e.cqi_value_for_lc;
1393  }
1394 
1395  if (cqi_value < worstCQIAmongRBGsAllocatedForThisUser)
1396  {
1397  worstCQIAmongRBGsAllocatedForThisUser=cqi_value;
1398  }
1399  }
1400 
1401  int mcsForThisUser = m_amc->GetMcsFromCqi (worstCQIAmongRBGsAllocatedForThisUser);
1402  int tbSize = m_amc->GetDlTbSizeFromMcs (mcsForThisUser, (numberOfRBGAllocatedForThisUser+1) * rbgSize)/8; // similar to calculation of TB size (size of TB in bytes according to table 7.1.7.2.1-1 of 36.213)
1403 
1404 
1405  double achievableRate = (( m_amc->GetDlTbSizeFromMcs (mcsForThisUser, rbgSize)/ 8) / 0.001);
1406  double pf_weight = achievableRate / (*itStats).second.secondLastAveragedThroughput;
1407 
1408  UeToAmountOfAssignedResources.find (flowId)->second = 8*tbSize;
1409  FfMacSchedSapProvider::SchedDlRlcBufferReqParameters lcBufferInfo = m_rlcBufferReq.find (flowId)->second;
1410 
1411  if (UeToAmountOfDataToTransfer.find (flowId)->second - UeToAmountOfAssignedResources.find (flowId)->second < 0)
1412  {
1413  UeHasReachedGBR.insert (std::pair<LteFlowId_t,bool>(flowId,false));
1414  }
1415 
1416  double bitRateWithNewRBG = 0;
1417 
1418  if (m_flowStatsDl.find (flowId.m_rnti)!= m_flowStatsDl.end ()) // there are some statistics{
1419  {
1420  bitRateWithNewRBG = (1.0 - (1.0 / m_timeWindow)) * (m_flowStatsDl.find (flowId.m_rnti)->second.lastAveragedThroughput) + ((1.0 / m_timeWindow) * (double)(tbSize*1000));
1421  }
1422  else
1423  {
1424  bitRateWithNewRBG = (1.0 / m_timeWindow) * (double)(tbSize*1000);
1425  }
1426 
1427  if(bitRateWithNewRBG > lc.m_eRabGuaranteedBitrateDl)
1428  {
1429  UeHasReachedGBR.insert (std::pair<LteFlowId_t,bool>(flowId,true));
1430  }
1431  else
1432  {
1433  UeHasReachedGBR.insert (std::pair<LteFlowId_t,bool>(flowId,false));
1434  }
1435 
1436  int hol = UEtoHOL.find (flowId)->second;
1437 
1438  if (hol==0)
1439  hol=1;
1440 
1441  if ( m_CqaMetric.compare ("CqaFf") == 0)
1442  {
1443  metric = coita_metric*tbr_weight*hol;
1444  }
1445  else if (m_CqaMetric.compare ("CqaPf") == 0)
1446  {
1447  metric = tbr_weight*pf_weight*hol;
1448  }
1449  else
1450  {
1451  metric = 1;
1452  }
1453 
1454  if (metric >= maximumValueMetric)
1455  {
1456  maximumValueMetric = metric;
1457  userWithMaximumMetric = flowId;
1458  }
1459  }
1460 
1461  if (!currentRBchecked)
1462  {
1463  // erase current RBG from the list of available RBG
1464  availableRBGs.erase (currentRB);
1465  continue;
1466  }
1467 
1469  s.cqi_value_for_lc = UeToCQIValue.find (userWithMaximumMetric)->second;
1470  s.resource_block_index = currentRB;
1471 
1472  itMap = allocationMapPerRntiPerLCId.find (userWithMaximumMetric.m_rnti);
1473 
1474  if (itMap == allocationMapPerRntiPerLCId.end ())
1475  {
1476  std::multimap <uint8_t, qos_rb_and_CQI_assigned_to_lc> tempMap;
1477  tempMap.insert (std::pair<uint8_t, qos_rb_and_CQI_assigned_to_lc> (userWithMaximumMetric.m_lcId,s));
1478  allocationMapPerRntiPerLCId.insert (std::pair <uint16_t, std::multimap <uint8_t,qos_rb_and_CQI_assigned_to_lc> > (userWithMaximumMetric.m_rnti, tempMap));
1479  }
1480  else
1481  {
1482  itMap->second.insert (std::pair<uint8_t,qos_rb_and_CQI_assigned_to_lc> (userWithMaximumMetric.m_lcId,s));
1483  }
1484 
1485  // erase current RBG from the list of available RBG
1486  availableRBGs.erase (currentRB);
1487 
1488  if (UeToAmountOfDataToTransfer.find (userWithMaximumMetric)->second <= UeToAmountOfAssignedResources.find (userWithMaximumMetric)->second*tolerance)
1489  //||(UeHasReachedGBR.find(userWithMaximumMetric)->second == true))
1490  {
1491  itCurrentGroup->second.erase (userWithMaximumMetric);
1492  }
1493 
1494  } // while there are more users in current group
1495  } // while there are more groups of users
1496 
1497 
1498  // reset TTI stats of users
1499  std::map <uint16_t, CqasFlowPerf_t>::iterator itStats;
1500  for (itStats = m_flowStatsDl.begin (); itStats != m_flowStatsDl.end (); itStats++)
1501  {
1502  (*itStats).second.lastTtiBytesTransmitted = 0;
1503  }
1504 
1505  // 3) Creating the correspondent DCIs (Generate the transmission opportunities by grouping the RBGs of the same RNTI)
1506  //FfMacSchedSapUser::SchedDlConfigIndParameters ret;
1507  itMap = allocationMapPerRntiPerLCId.begin ();
1508  int counter = 0;
1509  std::map<uint16_t, double> m_rnti_per_ratio;
1510 
1511  while (itMap != allocationMapPerRntiPerLCId.end ())
1512  {
1513  // create new BuildDataListElement_s for this LC
1514  BuildDataListElement_s newEl;
1515  newEl.m_rnti = (*itMap).first;
1516  NS_LOG_INFO ("Scheduled RNTI:"<<newEl.m_rnti);
1517  // create the DlDciListElement_s
1518  DlDciListElement_s newDci;
1519  std::vector <struct RlcPduListElement_s> newRlcPduLe;
1520  newDci.m_rnti = (*itMap).first;
1521  newDci.m_harqProcess = UpdateHarqProcessId ((*itMap).first);
1522  uint16_t lcActives = LcActivePerFlow (itMap->first);
1523  if (lcActives==0) // if there is still no buffer report information on any flow
1524  lcActives = 1;
1525  // NS_LOG_DEBUG (this << "Allocate user " << newEl.m_rnti << " rbg " << lcActives);
1526  uint16_t RgbPerRnti = (*itMap).second.size ();
1527  double doubleRBgPerRnti = RgbPerRnti;
1528  double doubleRbgNum = numberOfRBGs;
1529  double rrRatio = doubleRBgPerRnti/doubleRbgNum;
1530  m_rnti_per_ratio.insert (std::pair<uint16_t,double>((*itMap).first,rrRatio));
1531  std::map <uint16_t,SbMeasResult_s>::iterator itCqi;
1532  itCqi = m_a30CqiRxed.find ((*itMap).first);
1533  uint8_t worstCqi = 15;
1534 
1535  // assign the worst value of CQI that user experienced on any of its subbands
1536  for ( std::multimap <uint8_t, qos_rb_and_CQI_assigned_to_lc> ::iterator it = (*itMap).second.begin (); it != (*itMap).second.end (); it++)
1537  {
1538  if (it->second.cqi_value_for_lc<worstCqi)
1539  {
1540  worstCqi = it->second.cqi_value_for_lc;
1541  }
1542  counter++;
1543  }
1544 
1545  newDci.m_mcs.push_back (m_amc->GetMcsFromCqi (worstCqi));
1546  int tbSize = (m_amc->GetDlTbSizeFromMcs (newDci.m_mcs.at (0), RgbPerRnti * rbgSize) / 8); // (size of TB in bytes according to table 7.1.7.2.1-1 of 36.213)
1547  newDci.m_tbsSize.push_back (tbSize);
1548  newDci.m_resAlloc = 0; // only allocation type 0 at this stage
1549  newDci.m_rbBitmap = 0; // TBD (32 bit bitmap see 7.1.6 of 36.213)
1550  uint32_t rbgMask = 0;
1551  std::multimap <uint8_t, qos_rb_and_CQI_assigned_to_lc> ::iterator itRBGsPerRNTI;
1552  for ( itRBGsPerRNTI = (*itMap).second.begin (); itRBGsPerRNTI != (*itMap).second.end (); itRBGsPerRNTI++)
1553  {
1554  rbgMask = rbgMask + (0x1 << itRBGsPerRNTI->second.resource_block_index);
1555  }
1556  newDci.m_rbBitmap = rbgMask; // (32 bit bitmap see 7.1.6 of 36.213)
1557  // NOTE: In this first version of CqaFfMacScheduler, it is assumed one flow per user.
1558  // create the rlc PDUs -> equally divide resources among active LCs
1559  std::map <LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator itBufReq;
1560  for (itBufReq = m_rlcBufferReq.begin (); itBufReq != m_rlcBufferReq.end (); itBufReq++)
1561  {
1562  if (((*itBufReq).first.m_rnti == (*itMap).first)
1563  && (((*itBufReq).second.m_rlcTransmissionQueueSize > 0)
1564  || ((*itBufReq).second.m_rlcRetransmissionQueueSize > 0)
1565  || ((*itBufReq).second.m_rlcStatusPduSize > 0) ))
1566  {
1567  std::vector <struct RlcPduListElement_s> newRlcPduLe;
1568  //for (uint8_t j = 0; j < nLayer; j++)
1569  //{
1570  RlcPduListElement_s newRlcEl;
1571  newRlcEl.m_logicalChannelIdentity = (*itBufReq).first.m_lcId;
1572  // newRlcEl.m_size = newDci.m_tbsSize.at (j) / lcActives;
1573  newRlcEl.m_size = tbSize / lcActives;
1574  // NS_LOG_INFO (this << " LCID " << (uint32_t) newRlcEl.m_logicalChannelIdentity << " size " << newRlcEl.m_size << " layer " << (uint16_t)j);
1575  newRlcPduLe.push_back (newRlcEl);
1576  UpdateDlRlcBufferInfo (newDci.m_rnti, newRlcEl.m_logicalChannelIdentity, newRlcEl.m_size);
1577  if (m_harqOn == true)
1578  {
1579  // store RLC PDU list for HARQ
1580  std::map <uint16_t, DlHarqRlcPduListBuffer_t>::iterator itRlcPdu = m_dlHarqProcessesRlcPduListBuffer.find ((*itMap).first);
1581  if (itRlcPdu == m_dlHarqProcessesRlcPduListBuffer.end ())
1582  {
1583  NS_FATAL_ERROR ("Unable to find RlcPdcList in HARQ buffer for RNTI " << (*itMap).first);
1584  }
1585  int j=0;
1586  (*itRlcPdu).second.at (j).at (newDci.m_harqProcess).push_back (newRlcEl);
1587  }
1588  // }
1589  newEl.m_rlcPduList.push_back (newRlcPduLe);
1590  }
1591  if ((*itBufReq).first.m_rnti > (*itMap).first)
1592  {
1593  break;
1594  }
1595  }
1596  // for (uint8_t j = 0; j < nLayer; j++)
1597  // {
1598  newDci.m_ndi.push_back (1);
1599  newDci.m_rv.push_back (0);
1600  //}
1601 
1602  newDci.m_tpc = m_ffrSapProvider->GetTpc ((*itMap).first);
1603 
1604  newEl.m_dci = newDci;
1605 
1606  if (m_harqOn == true)
1607  {
1608  // store DCI for HARQ
1609  std::map <uint16_t, DlHarqProcessesDciBuffer_t>::iterator itDci = m_dlHarqProcessesDciBuffer.find (newEl.m_rnti);
1610  if (itDci == m_dlHarqProcessesDciBuffer.end ())
1611  {
1612  NS_FATAL_ERROR ("Unable to find RNTI entry in DCI HARQ buffer for RNTI " << newEl.m_rnti);
1613  }
1614  (*itDci).second.at (newDci.m_harqProcess) = newDci;
1615  // refresh timer
1616  std::map <uint16_t, DlHarqProcessesTimer_t>::iterator itHarqTimer = m_dlHarqProcessesTimer.find (newEl.m_rnti);
1617  if (itHarqTimer== m_dlHarqProcessesTimer.end ())
1618  {
1619  NS_FATAL_ERROR ("Unable to find HARQ timer for RNTI " << (uint16_t)newEl.m_rnti);
1620  }
1621  (*itHarqTimer).second.at (newDci.m_harqProcess) = 0;
1622  }
1623 
1624  // ...more parameters -> ignored in this version
1625 
1626  ret.m_buildDataList.push_back (newEl);
1627  // update UE stats
1628  std::map <uint16_t, CqasFlowPerf_t>::iterator it;
1629  it = m_flowStatsDl.find ((*itMap).first);
1630  if (it != m_flowStatsDl.end ())
1631  {
1632  (*it).second.lastTtiBytesTransmitted = tbSize;
1633  }
1634  else
1635  {
1636  NS_FATAL_ERROR (this << " No Stats for this allocated UE");
1637  }
1638 
1639  itMap++;
1640  } // end while allocation
1641  ret.m_nrOfPdcchOfdmSymbols = 1; // TODO: check correct value according the DCIs txed
1642 
1643  // update UEs stats
1644  NS_LOG_INFO (this << " Update UEs statistics");
1645  for (itStats = m_flowStatsDl.begin (); itStats != m_flowStatsDl.end (); itStats++)
1646  {
1647  if (allocationMapPerRntiPerLCId.find (itStats->first)!= allocationMapPerRntiPerLCId.end ())
1648  {
1649  (*itStats).second.secondLastAveragedThroughput = ((1.0 - (1 / m_timeWindow)) * (*itStats).second.secondLastAveragedThroughput) + ((1 / m_timeWindow) * (double)((*itStats).second.lastTtiBytesTransmitted / 0.001));
1650  }
1651 
1652  (*itStats).second.totalBytesTransmitted += (*itStats).second.lastTtiBytesTransmitted;
1653  // update average throughput (see eq. 12.3 of Sec 12.3.1.2 of LTE – The UMTS Long Term Evolution, Ed Wiley)
1654  (*itStats).second.lastAveragedThroughput = ((1.0 - (1.0 / m_timeWindow)) * (*itStats).second.lastAveragedThroughput) + ((1.0 / m_timeWindow) * (double)((*itStats).second.lastTtiBytesTransmitted / 0.001));
1655  NS_LOG_INFO (this << " UE total bytes " << (*itStats).second.totalBytesTransmitted);
1656  NS_LOG_INFO (this << " UE average throughput " << (*itStats).second.lastAveragedThroughput);
1657  (*itStats).second.lastTtiBytesTransmitted = 0;
1658  }
1659 
1661 
1662  int count_allocated_resource_blocks = 0;
1663  for (std::map <uint16_t, std::multimap <uint8_t, qos_rb_and_CQI_assigned_to_lc> >::iterator itMap = allocationMapPerRntiPerLCId.begin (); itMap!=allocationMapPerRntiPerLCId.end (); itMap++)
1664  {
1665  count_allocated_resource_blocks+=itMap->second.size ();
1666  }
1667  NS_LOG_INFO (this << " Allocated RBs:" << count_allocated_resource_blocks);
1668 
1669  return;
1670 }
1671 
1672 void
1674 {
1675  NS_LOG_FUNCTION (this);
1676 
1677  m_rachList = params.m_rachList;
1678 
1679  return;
1680 }
1681 
1682 void
1684 {
1685  NS_LOG_FUNCTION (this);
1687 
1688  for (unsigned int i = 0; i < params.m_cqiList.size (); i++)
1689  {
1690  if ( params.m_cqiList.at (i).m_cqiType == CqiListElement_s::P10 )
1691  {
1692  NS_LOG_LOGIC ("wideband CQI " << (uint32_t) params.m_cqiList.at (i).m_wbCqi.at (0) << " reported");
1693  std::map <uint16_t,uint8_t>::iterator it;
1694  uint16_t rnti = params.m_cqiList.at (i).m_rnti;
1695  it = m_p10CqiRxed.find (rnti);
1696  if (it == m_p10CqiRxed.end ())
1697  {
1698  // create the new entry
1699  m_p10CqiRxed.insert ( std::pair<uint16_t, uint8_t > (rnti, params.m_cqiList.at (i).m_wbCqi.at (0)) ); // only codeword 0 at this stage (SISO)
1700  // generate correspondent timer
1701  m_p10CqiTimers.insert ( std::pair<uint16_t, uint32_t > (rnti, m_cqiTimersThreshold));
1702  }
1703  else
1704  {
1705  // update the CQI value and refresh correspondent timer
1706  (*it).second = params.m_cqiList.at (i).m_wbCqi.at (0);
1707  // update correspondent timer
1708  std::map <uint16_t,uint32_t>::iterator itTimers;
1709  itTimers = m_p10CqiTimers.find (rnti);
1710  (*itTimers).second = m_cqiTimersThreshold;
1711  }
1712  }
1713  else if ( params.m_cqiList.at (i).m_cqiType == CqiListElement_s::A30 )
1714  {
1715  // subband CQI reporting high layer configured
1716  std::map <uint16_t,SbMeasResult_s>::iterator it;
1717  uint16_t rnti = params.m_cqiList.at (i).m_rnti;
1718  it = m_a30CqiRxed.find (rnti);
1719  if (it == m_a30CqiRxed.end ())
1720  {
1721  // create the new entry
1722  m_a30CqiRxed.insert ( std::pair<uint16_t, SbMeasResult_s > (rnti, params.m_cqiList.at (i).m_sbMeasResult) );
1723  m_a30CqiTimers.insert ( std::pair<uint16_t, uint32_t > (rnti, m_cqiTimersThreshold));
1724  }
1725  else
1726  {
1727  // update the CQI value and refresh correspondent timer
1728  (*it).second = params.m_cqiList.at (i).m_sbMeasResult;
1729  std::map <uint16_t,uint32_t>::iterator itTimers;
1730  itTimers = m_a30CqiTimers.find (rnti);
1731  (*itTimers).second = m_cqiTimersThreshold;
1732  }
1733  }
1734  else
1735  {
1736  NS_LOG_ERROR (this << " CQI type unknown");
1737  }
1738  }
1739 
1740  return;
1741 }
1742 
1743 
1744 double
1745 CqaFfMacScheduler::EstimateUlSinr (uint16_t rnti, uint16_t rb)
1746 {
1747  std::map <uint16_t, std::vector <double> >::iterator itCqi = m_ueCqi.find (rnti);
1748  if (itCqi == m_ueCqi.end ())
1749  {
1750  // no cqi info about this UE
1751  return (NO_SINR);
1752 
1753  }
1754  else
1755  {
1756  // take the average SINR value among the available
1757  double sinrSum = 0;
1758  unsigned int sinrNum = 0;
1759  for (uint32_t i = 0; i < m_cschedCellConfig.m_ulBandwidth; i++)
1760  {
1761  double sinr = (*itCqi).second.at (i);
1762  if (sinr != NO_SINR)
1763  {
1764  sinrSum += sinr;
1765  sinrNum++;
1766  }
1767  }
1768  double estimatedSinr = (sinrNum > 0) ? (sinrSum / sinrNum) : DBL_MAX;
1769  // store the value
1770  (*itCqi).second.at (rb) = estimatedSinr;
1771  return (estimatedSinr);
1772  }
1773 }
1774 
1775 void
1777 {
1778  NS_LOG_FUNCTION (this << " UL - Frame no. " << (params.m_sfnSf >> 4) << " subframe no. " << (0xF & params.m_sfnSf) << " size " << params.m_ulInfoList.size ());
1779 
1780  RefreshUlCqiMaps ();
1782 
1783  // Generate RBs map
1785  std::vector <bool> rbMap;
1786  uint16_t rbAllocatedNum = 0;
1787  std::set <uint16_t> rntiAllocated;
1788  std::vector <uint16_t> rbgAllocationMap;
1789  // update with RACH allocation map
1790  rbgAllocationMap = m_rachAllocationMap;
1791  //rbgAllocationMap.resize (m_cschedCellConfig.m_ulBandwidth, 0);
1792  m_rachAllocationMap.clear ();
1794 
1795  rbMap.resize (m_cschedCellConfig.m_ulBandwidth, false);
1796 
1797  rbMap = m_ffrSapProvider->GetAvailableUlRbg ();
1798 
1799  for (std::vector<bool>::iterator it = rbMap.begin (); it != rbMap.end (); it++)
1800  {
1801  if ((*it) == true )
1802  {
1803  rbAllocatedNum++;
1804  }
1805  }
1806 
1807  uint8_t minContinuousUlBandwidth = m_ffrSapProvider->GetMinContinuousUlBandwidth ();
1808  uint8_t ffrUlBandwidth = m_cschedCellConfig.m_ulBandwidth - rbAllocatedNum;
1809 
1810  // remove RACH allocation
1811  for (uint16_t i = 0; i < m_cschedCellConfig.m_ulBandwidth; i++)
1812  {
1813  if (rbgAllocationMap.at (i) != 0)
1814  {
1815  rbMap.at (i) = true;
1816  NS_LOG_DEBUG (this << " Allocated for RACH " << i);
1817  }
1818  }
1819 
1820 
1821  if (m_harqOn == true)
1822  {
1823  // Process UL HARQ feedback
1824  for (uint16_t i = 0; i < params.m_ulInfoList.size (); i++)
1825  {
1826  if (params.m_ulInfoList.at (i).m_receptionStatus == UlInfoListElement_s::NotOk)
1827  {
1828  // retx correspondent block: retrieve the UL-DCI
1829  uint16_t rnti = params.m_ulInfoList.at (i).m_rnti;
1830  std::map <uint16_t, uint8_t>::iterator itProcId = m_ulHarqCurrentProcessId.find (rnti);
1831  if (itProcId == m_ulHarqCurrentProcessId.end ())
1832  {
1833  NS_LOG_ERROR ("No info find in HARQ buffer for UE (might change eNB) " << rnti);
1834  }
1835  uint8_t harqId = (uint8_t)((*itProcId).second - HARQ_PERIOD) % HARQ_PROC_NUM;
1836  NS_LOG_INFO (this << " UL-HARQ retx RNTI " << rnti << " harqId " << (uint16_t)harqId << " i " << i << " size " << params.m_ulInfoList.size ());
1837  std::map <uint16_t, UlHarqProcessesDciBuffer_t>::iterator itHarq = m_ulHarqProcessesDciBuffer.find (rnti);
1838  if (itHarq == m_ulHarqProcessesDciBuffer.end ())
1839  {
1840  NS_LOG_ERROR ("No info find in HARQ buffer for UE (might change eNB) " << rnti);
1841  continue;
1842  }
1843  UlDciListElement_s dci = (*itHarq).second.at (harqId);
1844  std::map <uint16_t, UlHarqProcessesStatus_t>::iterator itStat = m_ulHarqProcessesStatus.find (rnti);
1845  if (itStat == m_ulHarqProcessesStatus.end ())
1846  {
1847  NS_LOG_ERROR ("No info find in HARQ buffer for UE (might change eNB) " << rnti);
1848  }
1849  if ((*itStat).second.at (harqId) >= 3)
1850  {
1851  NS_LOG_INFO ("Max number of retransmissions reached (UL)-> drop process");
1852  continue;
1853  }
1854  bool free = true;
1855 
1856  for (int j = dci.m_rbStart; j < dci.m_rbStart + dci.m_rbLen; j++)
1857  {
1858  if (rbMap.at (j) == true)
1859  {
1860  free = false;
1861  NS_LOG_INFO (this << " BUSY " << j);
1862  }
1863  }
1864  if (free)
1865  {
1866  // retx on the same RBs
1867  for (int j = dci.m_rbStart; j < dci.m_rbStart + dci.m_rbLen; j++)
1868  {
1869  rbMap.at (j) = true;
1870  rbgAllocationMap.at (j) = dci.m_rnti;
1871  NS_LOG_INFO ("\tRB " << j);
1872  rbAllocatedNum++;
1873  }
1874  NS_LOG_INFO (this << " Send retx in the same RBs " << (uint16_t)dci.m_rbStart << " to " << dci.m_rbStart + dci.m_rbLen << " RV " << (*itStat).second.at (harqId) + 1);
1875  }
1876  else
1877  {
1878  NS_LOG_INFO ("Cannot allocate retx due to RACH allocations for UE " << rnti);
1879  continue;
1880  }
1881  dci.m_ndi = 0;
1882  // Update HARQ buffers with new HarqId
1883  (*itStat).second.at ((*itProcId).second) = (*itStat).second.at (harqId) + 1;
1884  (*itStat).second.at (harqId) = 0;
1885  (*itHarq).second.at ((*itProcId).second) = dci;
1886  ret.m_dciList.push_back (dci);
1887  rntiAllocated.insert (dci.m_rnti);
1888  }
1889  else
1890  {
1891  NS_LOG_INFO (this << " HARQ-ACK feedback from RNTI " << params.m_ulInfoList.at (i).m_rnti);
1892  }
1893  }
1894  }
1895 
1896  std::map <uint16_t,uint32_t>::iterator it;
1897  int nflows = 0;
1898 
1899  for (it = m_ceBsrRxed.begin (); it != m_ceBsrRxed.end (); it++)
1900  {
1901  std::set <uint16_t>::iterator itRnti = rntiAllocated.find ((*it).first);
1902  // select UEs with queues not empty and not yet allocated for HARQ
1903  if (((*it).second > 0)&&(itRnti == rntiAllocated.end ()))
1904  {
1905  nflows++;
1906  }
1907  }
1908 
1909  if (nflows == 0)
1910  {
1911  if (ret.m_dciList.size () > 0)
1912  {
1913  m_allocationMaps.insert (std::pair <uint16_t, std::vector <uint16_t> > (params.m_sfnSf, rbgAllocationMap));
1915  }
1916 
1917  return; // no flows to be scheduled
1918  }
1919 
1920 
1921  // Divide the remaining resources equally among the active users starting from the subsequent one served last scheduling trigger
1922  uint16_t tempRbPerFlow = (ffrUlBandwidth) / (nflows + rntiAllocated.size ());
1923  uint16_t rbPerFlow = (minContinuousUlBandwidth < tempRbPerFlow) ? minContinuousUlBandwidth : tempRbPerFlow;
1924 
1925  if (rbPerFlow < 3)
1926  {
1927  rbPerFlow = 3; // at least 3 rbg per flow (till available resource) to ensure TxOpportunity >= 7 bytes
1928  }
1929  int rbAllocated = 0;
1930 
1931  std::map <uint16_t, CqasFlowPerf_t>::iterator itStats;
1932  if (m_nextRntiUl != 0)
1933  {
1934  for (it = m_ceBsrRxed.begin (); it != m_ceBsrRxed.end (); it++)
1935  {
1936  if ((*it).first == m_nextRntiUl)
1937  {
1938  break;
1939  }
1940  }
1941  if (it == m_ceBsrRxed.end ())
1942  {
1943  NS_LOG_ERROR (this << " no user found");
1944  }
1945  }
1946  else
1947  {
1948  it = m_ceBsrRxed.begin ();
1949  m_nextRntiUl = (*it).first;
1950  }
1951  do
1952  {
1953  std::set <uint16_t>::iterator itRnti = rntiAllocated.find ((*it).first);
1954  if ((itRnti != rntiAllocated.end ())||((*it).second == 0))
1955  {
1956  // UE already allocated for UL-HARQ -> skip it
1957  NS_LOG_DEBUG (this << " UE already allocated in HARQ -> discared, RNTI " << (*it).first);
1958  it++;
1959  if (it == m_ceBsrRxed.end ())
1960  {
1961  // restart from the first
1962  it = m_ceBsrRxed.begin ();
1963  }
1964  continue;
1965  }
1966  if (rbAllocated + rbPerFlow - 1 > m_cschedCellConfig.m_ulBandwidth)
1967  {
1968  // limit to physical resources last resource assignment
1969  rbPerFlow = m_cschedCellConfig.m_ulBandwidth - rbAllocated;
1970  // at least 3 rbg per flow to ensure TxOpportunity >= 7 bytes
1971  if (rbPerFlow < 3)
1972  {
1973  // terminate allocation
1974  rbPerFlow = 0;
1975  }
1976  }
1977 
1978  rbAllocated = 0;
1979  UlDciListElement_s uldci;
1980  uldci.m_rnti = (*it).first;
1981  uldci.m_rbLen = rbPerFlow;
1982  bool allocated = false;
1983  NS_LOG_INFO (this << " RB Allocated " << rbAllocated << " rbPerFlow " << rbPerFlow << " flows " << nflows);
1984  while ((!allocated)&&((rbAllocated + rbPerFlow - m_cschedCellConfig.m_ulBandwidth) < 1) && (rbPerFlow != 0))
1985  {
1986  // check availability
1987  bool free = true;
1988  for (uint16_t j = rbAllocated; j < rbAllocated + rbPerFlow; j++)
1989  {
1990  if (rbMap.at (j) == true)
1991  {
1992  free = false;
1993  break;
1994  }
1995  if ((m_ffrSapProvider->IsUlRbgAvailableForUe (j, (*it).first)) == false)
1996  {
1997  free = false;
1998  break;
1999  }
2000  }
2001  if (free)
2002  {
2003  NS_LOG_INFO (this << "RNTI: "<< (*it).first<< " RB Allocated " << rbAllocated << " rbPerFlow " << rbPerFlow << " flows " << nflows);
2004  uldci.m_rbStart = rbAllocated;
2005 
2006  for (uint16_t j = rbAllocated; j < rbAllocated + rbPerFlow; j++)
2007  {
2008  rbMap.at (j) = true;
2009  // store info on allocation for managing ul-cqi interpretation
2010  rbgAllocationMap.at (j) = (*it).first;
2011  }
2012  rbAllocated += rbPerFlow;
2013  allocated = true;
2014  break;
2015  }
2016  rbAllocated++;
2017  if (rbAllocated + rbPerFlow - 1 > m_cschedCellConfig.m_ulBandwidth)
2018  {
2019  // limit to physical resources last resource assignment
2020  rbPerFlow = m_cschedCellConfig.m_ulBandwidth - rbAllocated;
2021  // at least 3 rbg per flow to ensure TxOpportunity >= 7 bytes
2022  if (rbPerFlow < 3)
2023  {
2024  // terminate allocation
2025  rbPerFlow = 0;
2026  }
2027  }
2028  }
2029  if (!allocated)
2030  {
2031  // unable to allocate new resource: finish scheduling
2032 // m_nextRntiUl = (*it).first;
2033 // if (ret.m_dciList.size () > 0)
2034 // {
2035 // m_schedSapUser->SchedUlConfigInd (ret);
2036 // }
2037 // m_allocationMaps.insert (std::pair <uint16_t, std::vector <uint16_t> > (params.m_sfnSf, rbgAllocationMap));
2038 // return;
2039  break;
2040  }
2041 
2042 
2043 
2044  std::map <uint16_t, std::vector <double> >::iterator itCqi = m_ueCqi.find ((*it).first);
2045  int cqi = 0;
2046  if (itCqi == m_ueCqi.end ())
2047  {
2048  // no cqi info about this UE
2049  uldci.m_mcs = 0; // MCS 0 -> UL-AMC TBD
2050  }
2051  else
2052  {
2053  // take the lowest CQI value (worst RB)
2054  NS_ABORT_MSG_IF ((*itCqi).second.size() == 0, "CQI of RNTI = " << (*it).first << " has expired");
2055  double minSinr = (*itCqi).second.at (uldci.m_rbStart);
2056  if (minSinr == NO_SINR)
2057  {
2058  minSinr = EstimateUlSinr ((*it).first, uldci.m_rbStart);
2059  }
2060  for (uint16_t i = uldci.m_rbStart; i < uldci.m_rbStart + uldci.m_rbLen; i++)
2061  {
2062  double sinr = (*itCqi).second.at (i);
2063  if (sinr == NO_SINR)
2064  {
2065  sinr = EstimateUlSinr ((*it).first, i);
2066  }
2067  if (sinr < minSinr)
2068  {
2069  minSinr = sinr;
2070  }
2071  }
2072 
2073  // translate SINR -> cqi: WILD ACK: same as DL
2074  double s = log2 ( 1 + (
2075  std::pow (10, minSinr / 10 ) /
2076  ( (-std::log (5.0 * 0.00005 )) / 1.5) ));
2077  cqi = m_amc->GetCqiFromSpectralEfficiency (s);
2078  if (cqi == 0)
2079  {
2080  it++;
2081  if (it == m_ceBsrRxed.end ())
2082  {
2083  // restart from the first
2084  it = m_ceBsrRxed.begin ();
2085  }
2086  NS_LOG_DEBUG (this << " UE discarded for CQI = 0, RNTI " << uldci.m_rnti);
2087  // remove UE from allocation map
2088  for (uint16_t i = uldci.m_rbStart; i < uldci.m_rbStart + uldci.m_rbLen; i++)
2089  {
2090  rbgAllocationMap.at (i) = 0;
2091  }
2092  continue; // CQI == 0 means "out of range" (see table 7.2.3-1 of 36.213)
2093  }
2094  uldci.m_mcs = m_amc->GetMcsFromCqi (cqi);
2095  }
2096 
2097  uldci.m_tbSize = (m_amc->GetUlTbSizeFromMcs (uldci.m_mcs, rbPerFlow) / 8);
2098  UpdateUlRlcBufferInfo (uldci.m_rnti, uldci.m_tbSize);
2099  uldci.m_ndi = 1;
2100  uldci.m_cceIndex = 0;
2101  uldci.m_aggrLevel = 1;
2102  uldci.m_ueTxAntennaSelection = 3; // antenna selection OFF
2103  uldci.m_hopping = false;
2104  uldci.m_n2Dmrs = 0;
2105  uldci.m_tpc = 0; // no power control
2106  uldci.m_cqiRequest = false; // only period CQI at this stage
2107  uldci.m_ulIndex = 0; // TDD parameter
2108  uldci.m_dai = 1; // TDD parameter
2109  uldci.m_freqHopping = 0;
2110  uldci.m_pdcchPowerOffset = 0; // not used
2111  ret.m_dciList.push_back (uldci);
2112  // store DCI for HARQ_PERIOD
2113  uint8_t harqId = 0;
2114  if (m_harqOn == true)
2115  {
2116  std::map <uint16_t, uint8_t>::iterator itProcId;
2117  itProcId = m_ulHarqCurrentProcessId.find (uldci.m_rnti);
2118  if (itProcId == m_ulHarqCurrentProcessId.end ())
2119  {
2120  NS_FATAL_ERROR ("No info find in HARQ buffer for UE " << uldci.m_rnti);
2121  }
2122  harqId = (*itProcId).second;
2123  std::map <uint16_t, UlHarqProcessesDciBuffer_t>::iterator itDci = m_ulHarqProcessesDciBuffer.find (uldci.m_rnti);
2124  if (itDci == m_ulHarqProcessesDciBuffer.end ())
2125  {
2126  NS_FATAL_ERROR ("Unable to find RNTI entry in UL DCI HARQ buffer for RNTI " << uldci.m_rnti);
2127  }
2128  (*itDci).second.at (harqId) = uldci;
2129  // Update HARQ process status (RV 0)
2130  std::map <uint16_t, UlHarqProcessesStatus_t>::iterator itStat = m_ulHarqProcessesStatus.find (uldci.m_rnti);
2131  if (itStat == m_ulHarqProcessesStatus.end ())
2132  {
2133  NS_LOG_ERROR ("No info find in HARQ buffer for UE (might change eNB) " << uldci.m_rnti);
2134  }
2135  (*itStat).second.at (harqId) = 0;
2136  }
2137 
2138  NS_LOG_INFO (this << " UE Allocation RNTI " << (*it).first << " startPRB " << (uint32_t)uldci.m_rbStart << " nPRB " << (uint32_t)uldci.m_rbLen << " CQI " << cqi << " MCS " << (uint32_t)uldci.m_mcs << " TBsize " << uldci.m_tbSize << " RbAlloc " << rbAllocated << " harqId " << (uint16_t)harqId);
2139 
2140  // update TTI UE stats
2141  itStats = m_flowStatsUl.find ((*it).first);
2142  if (itStats != m_flowStatsUl.end ())
2143  {
2144  (*itStats).second.lastTtiBytesTransmitted = uldci.m_tbSize;
2145  }
2146  else
2147  {
2148  NS_LOG_DEBUG (this << " No Stats for this allocated UE");
2149  }
2150 
2151 
2152  it++;
2153  if (it == m_ceBsrRxed.end ())
2154  {
2155  // restart from the first
2156  it = m_ceBsrRxed.begin ();
2157  }
2158  if ((rbAllocated == m_cschedCellConfig.m_ulBandwidth) || (rbPerFlow == 0))
2159  {
2160  // Stop allocation: no more PRBs
2161  m_nextRntiUl = (*it).first;
2162  break;
2163  }
2164  }
2165  while (((*it).first != m_nextRntiUl)&&(rbPerFlow!=0));
2166 
2167 
2168  // Update global UE stats
2169  // update UEs stats
2170  for (itStats = m_flowStatsUl.begin (); itStats != m_flowStatsUl.end (); itStats++)
2171  {
2172  (*itStats).second.totalBytesTransmitted += (*itStats).second.lastTtiBytesTransmitted;
2173  // update average throughput (see eq. 12.3 of Sec 12.3.1.2 of LTE – The UMTS Long Term Evolution, Ed Wiley)
2174  (*itStats).second.lastAveragedThroughput = ((1.0 - (1.0 / m_timeWindow)) * (*itStats).second.lastAveragedThroughput) + ((1.0 / m_timeWindow) * (double)((*itStats).second.lastTtiBytesTransmitted / 0.001));
2175  NS_LOG_INFO (this << " UE total bytes " << (*itStats).second.totalBytesTransmitted);
2176  NS_LOG_INFO (this << " UE average throughput " << (*itStats).second.lastAveragedThroughput);
2177  (*itStats).second.lastTtiBytesTransmitted = 0;
2178  }
2179  m_allocationMaps.insert (std::pair <uint16_t, std::vector <uint16_t> > (params.m_sfnSf, rbgAllocationMap));
2181 
2182  return;
2183 }
2184 
2185 void
2187 {
2188  NS_LOG_FUNCTION (this);
2189  return;
2190 }
2191 
2192 void
2194 {
2195  NS_LOG_FUNCTION (this);
2196  return;
2197 }
2198 
2199 void
2201 {
2202  NS_LOG_FUNCTION (this);
2203 
2204  std::map <uint16_t,uint32_t>::iterator it;
2205 
2206  for (unsigned int i = 0; i < params.m_macCeList.size (); i++)
2207  {
2208  if ( params.m_macCeList.at (i).m_macCeType == MacCeListElement_s::BSR )
2209  {
2210  // buffer status report
2211  // note that this scheduler does not differentiate the
2212  // allocation according to which LCGs have more/less bytes
2213  // to send.
2214  // Hence the BSR of different LCGs are just summed up to get
2215  // a total queue size that is used for allocation purposes.
2216 
2217  uint32_t buffer = 0;
2218  for (uint8_t lcg = 0; lcg < 4; ++lcg)
2219  {
2220  uint8_t bsrId = params.m_macCeList.at (i).m_macCeValue.m_bufferStatus.at (lcg);
2221  buffer += BufferSizeLevelBsr::BsrId2BufferSize (bsrId);
2222  }
2223 
2224  uint16_t rnti = params.m_macCeList.at (i).m_rnti;
2225  NS_LOG_LOGIC (this << "RNTI=" << rnti << " buffer=" << buffer);
2226  it = m_ceBsrRxed.find (rnti);
2227  if (it == m_ceBsrRxed.end ())
2228  {
2229  // create the new entry
2230  m_ceBsrRxed.insert ( std::pair<uint16_t, uint32_t > (rnti, buffer));
2231  }
2232  else
2233  {
2234  // update the buffer size value
2235  (*it).second = buffer;
2236  }
2237  }
2238  }
2239 
2240  return;
2241 }
2242 
2243 void
2245 {
2246  NS_LOG_FUNCTION (this);
2247 // retrieve the allocation for this subframe
2248  switch (m_ulCqiFilter)
2249  {
2251  {
2252  // filter all the CQIs that are not SRS based
2253  if (params.m_ulCqi.m_type != UlCqi_s::SRS)
2254  {
2255  return;
2256  }
2257  }
2258  break;
2260  {
2261  // filter all the CQIs that are not SRS based
2262  if (params.m_ulCqi.m_type != UlCqi_s::PUSCH)
2263  {
2264  return;
2265  }
2266  }
2267  break;
2268  default:
2269  NS_FATAL_ERROR ("Unknown UL CQI type");
2270  }
2271 
2272  switch (params.m_ulCqi.m_type)
2273  {
2274  case UlCqi_s::PUSCH:
2275  {
2276  std::map <uint16_t, std::vector <uint16_t> >::iterator itMap;
2277  std::map <uint16_t, std::vector <double> >::iterator itCqi;
2278  NS_LOG_DEBUG (this << " Collect PUSCH CQIs of Frame no. " << (params.m_sfnSf >> 4) << " subframe no. " << (0xF & params.m_sfnSf));
2279  itMap = m_allocationMaps.find (params.m_sfnSf);
2280  if (itMap == m_allocationMaps.end ())
2281  {
2282  return;
2283  }
2284  for (uint32_t i = 0; i < (*itMap).second.size (); i++)
2285  {
2286  // convert from fixed point notation Sxxxxxxxxxxx.xxx to double
2287  double sinr = LteFfConverter::fpS11dot3toDouble (params.m_ulCqi.m_sinr.at (i));
2288  itCqi = m_ueCqi.find ((*itMap).second.at (i));
2289  if (itCqi == m_ueCqi.end ())
2290  {
2291  // create a new entry
2292  std::vector <double> newCqi;
2293  for (uint32_t j = 0; j < m_cschedCellConfig.m_ulBandwidth; j++)
2294  {
2295  if (i == j)
2296  {
2297  newCqi.push_back (sinr);
2298  }
2299  else
2300  {
2301  // initialize with NO_SINR value.
2302  newCqi.push_back (NO_SINR);
2303  }
2304 
2305  }
2306  m_ueCqi.insert (std::pair <uint16_t, std::vector <double> > ((*itMap).second.at (i), newCqi));
2307  // generate correspondent timer
2308  m_ueCqiTimers.insert (std::pair <uint16_t, uint32_t > ((*itMap).second.at (i), m_cqiTimersThreshold));
2309  }
2310  else
2311  {
2312  // update the value
2313  (*itCqi).second.at (i) = sinr;
2314  NS_LOG_DEBUG (this << " RNTI " << (*itMap).second.at (i) << " RB " << i << " SINR " << sinr);
2315  // update correspondent timer
2316  std::map <uint16_t, uint32_t>::iterator itTimers;
2317  itTimers = m_ueCqiTimers.find ((*itMap).second.at (i));
2318  (*itTimers).second = m_cqiTimersThreshold;
2319 
2320  }
2321 
2322  }
2323  // remove obsolete info on allocation
2324  m_allocationMaps.erase (itMap);
2325  }
2326  break;
2327  case UlCqi_s::SRS:
2328  {
2329  NS_LOG_DEBUG (this << " Collect SRS CQIs of Frame no. " << (params.m_sfnSf >> 4) << " subframe no. " << (0xF & params.m_sfnSf));
2330  // get the RNTI from vendor specific parameters
2331  uint16_t rnti = 0;
2332  NS_ASSERT (params.m_vendorSpecificList.size () > 0);
2333  for (uint16_t i = 0; i < params.m_vendorSpecificList.size (); i++)
2334  {
2335  if (params.m_vendorSpecificList.at (i).m_type == SRS_CQI_RNTI_VSP)
2336  {
2337  Ptr<SrsCqiRntiVsp> vsp = DynamicCast<SrsCqiRntiVsp> (params.m_vendorSpecificList.at (i).m_value);
2338  rnti = vsp->GetRnti ();
2339  }
2340  }
2341  std::map <uint16_t, std::vector <double> >::iterator itCqi;
2342  itCqi = m_ueCqi.find (rnti);
2343  if (itCqi == m_ueCqi.end ())
2344  {
2345  // create a new entry
2346  std::vector <double> newCqi;
2347  for (uint32_t j = 0; j < m_cschedCellConfig.m_ulBandwidth; j++)
2348  {
2349  double sinr = LteFfConverter::fpS11dot3toDouble (params.m_ulCqi.m_sinr.at (j));
2350  newCqi.push_back (sinr);
2351  NS_LOG_INFO (this << " RNTI " << rnti << " new SRS-CQI for RB " << j << " value " << sinr);
2352 
2353  }
2354  m_ueCqi.insert (std::pair <uint16_t, std::vector <double> > (rnti, newCqi));
2355  // generate correspondent timer
2356  m_ueCqiTimers.insert (std::pair <uint16_t, uint32_t > (rnti, m_cqiTimersThreshold));
2357  }
2358  else
2359  {
2360  // update the values
2361  for (uint32_t j = 0; j < m_cschedCellConfig.m_ulBandwidth; j++)
2362  {
2363  double sinr = LteFfConverter::fpS11dot3toDouble (params.m_ulCqi.m_sinr.at (j));
2364  (*itCqi).second.at (j) = sinr;
2365  NS_LOG_INFO (this << " RNTI " << rnti << " update SRS-CQI for RB " << j << " value " << sinr);
2366  }
2367  // update correspondent timer
2368  std::map <uint16_t, uint32_t>::iterator itTimers;
2369  itTimers = m_ueCqiTimers.find (rnti);
2370  (*itTimers).second = m_cqiTimersThreshold;
2371 
2372  }
2373 
2374 
2375  }
2376  break;
2377  case UlCqi_s::PUCCH_1:
2378  case UlCqi_s::PUCCH_2:
2379  case UlCqi_s::PRACH:
2380  {
2381  NS_FATAL_ERROR ("PfFfMacScheduler supports only PUSCH and SRS UL-CQIs");
2382  }
2383  break;
2384  default:
2385  NS_FATAL_ERROR ("Unknown type of UL-CQI");
2386  }
2387  return;
2388 }
2389 
2390 void
2392 {
2393  // refresh DL CQI P01 Map
2394  std::map <uint16_t,uint32_t>::iterator itP10 = m_p10CqiTimers.begin ();
2395  while (itP10 != m_p10CqiTimers.end ())
2396  {
2397  NS_LOG_INFO (this << " P10-CQI for user " << (*itP10).first << " is " << (uint32_t)(*itP10).second << " thr " << (uint32_t)m_cqiTimersThreshold);
2398  if ((*itP10).second == 0)
2399  {
2400  // delete correspondent entries
2401  std::map <uint16_t,uint8_t>::iterator itMap = m_p10CqiRxed.find ((*itP10).first);
2402  NS_ASSERT_MSG (itMap != m_p10CqiRxed.end (), " Does not find CQI report for user " << (*itP10).first);
2403  NS_LOG_INFO (this << " P10-CQI expired for user " << (*itP10).first);
2404  m_p10CqiRxed.erase (itMap);
2405  std::map <uint16_t,uint32_t>::iterator temp = itP10;
2406  itP10++;
2407  m_p10CqiTimers.erase (temp);
2408  }
2409  else
2410  {
2411  (*itP10).second--;
2412  itP10++;
2413  }
2414  }
2415 
2416  // refresh DL CQI A30 Map
2417  std::map <uint16_t,uint32_t>::iterator itA30 = m_a30CqiTimers.begin ();
2418  while (itA30 != m_a30CqiTimers.end ())
2419  {
2420  NS_LOG_INFO (this << " A30-CQI for user " << (*itA30).first << " is " << (uint32_t)(*itA30).second << " thr " << (uint32_t)m_cqiTimersThreshold);
2421  if ((*itA30).second == 0)
2422  {
2423  // delete correspondent entries
2424  std::map <uint16_t,SbMeasResult_s>::iterator itMap = m_a30CqiRxed.find ((*itA30).first);
2425  NS_ASSERT_MSG (itMap != m_a30CqiRxed.end (), " Does not find CQI report for user " << (*itA30).first);
2426  NS_LOG_INFO (this << " A30-CQI expired for user " << (*itA30).first);
2427  m_a30CqiRxed.erase (itMap);
2428  std::map <uint16_t,uint32_t>::iterator temp = itA30;
2429  itA30++;
2430  m_a30CqiTimers.erase (temp);
2431  }
2432  else
2433  {
2434  (*itA30).second--;
2435  itA30++;
2436  }
2437  }
2438 
2439  return;
2440 }
2441 
2442 
2443 void
2445 {
2446  // refresh UL CQI Map
2447  std::map <uint16_t,uint32_t>::iterator itUl = m_ueCqiTimers.begin ();
2448  while (itUl != m_ueCqiTimers.end ())
2449  {
2450  NS_LOG_INFO (this << " UL-CQI for user " << (*itUl).first << " is " << (uint32_t)(*itUl).second << " thr " << (uint32_t)m_cqiTimersThreshold);
2451  if ((*itUl).second == 0)
2452  {
2453  // delete correspondent entries
2454  std::map <uint16_t, std::vector <double> >::iterator itMap = m_ueCqi.find ((*itUl).first);
2455  NS_ASSERT_MSG (itMap != m_ueCqi.end (), " Does not find CQI report for user " << (*itUl).first);
2456  NS_LOG_INFO (this << " UL-CQI exired for user " << (*itUl).first);
2457  (*itMap).second.clear ();
2458  m_ueCqi.erase (itMap);
2459  std::map <uint16_t,uint32_t>::iterator temp = itUl;
2460  itUl++;
2461  m_ueCqiTimers.erase (temp);
2462  }
2463  else
2464  {
2465  (*itUl).second--;
2466  itUl++;
2467  }
2468  }
2469 
2470  return;
2471 }
2472 
2473 void
2474 CqaFfMacScheduler::UpdateDlRlcBufferInfo (uint16_t rnti, uint8_t lcid, uint16_t size)
2475 {
2476  std::map<LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it;
2477  LteFlowId_t flow (rnti, lcid);
2478  it = m_rlcBufferReq.find (flow);
2479  if (it != m_rlcBufferReq.end ())
2480  {
2481  NS_LOG_INFO (this << " UE " << rnti << " LC " << (uint16_t)lcid << " txqueue " << (*it).second.m_rlcTransmissionQueueSize << " retxqueue " << (*it).second.m_rlcRetransmissionQueueSize << " status " << (*it).second.m_rlcStatusPduSize << " decrease " << size);
2482  // Update queues: RLC tx order Status, ReTx, Tx
2483  // Update status queue
2484  if (((*it).second.m_rlcStatusPduSize > 0) && (size >= (*it).second.m_rlcStatusPduSize))
2485  {
2486  (*it).second.m_rlcStatusPduSize = 0;
2487  }
2488  else if (((*it).second.m_rlcRetransmissionQueueSize > 0) && (size >= (*it).second.m_rlcRetransmissionQueueSize))
2489  {
2490  (*it).second.m_rlcRetransmissionQueueSize = 0;
2491  }
2492  else if ((*it).second.m_rlcTransmissionQueueSize > 0)
2493  {
2494  uint32_t rlcOverhead;
2495  if (lcid == 1)
2496  {
2497  // for SRB1 (using RLC AM) it's better to
2498  // overestimate RLC overhead rather than
2499  // underestimate it and risk unneeded
2500  // segmentation which increases delay
2501  rlcOverhead = 4;
2502  }
2503  else
2504  {
2505  // minimum RLC overhead due to header
2506  rlcOverhead = 2;
2507  }
2508  // update transmission queue
2509  if ((*it).second.m_rlcTransmissionQueueSize <= size - rlcOverhead)
2510  {
2511  (*it).second.m_rlcTransmissionQueueSize = 0;
2512  }
2513  else
2514  {
2515  (*it).second.m_rlcTransmissionQueueSize -= size - rlcOverhead;
2516  }
2517  }
2518  }
2519  else
2520  {
2521  NS_LOG_ERROR (this << " Does not find DL RLC Buffer Report of UE " << rnti);
2522  }
2523 }
2524 
2525 void
2526 CqaFfMacScheduler::UpdateUlRlcBufferInfo (uint16_t rnti, uint16_t size)
2527 {
2528 
2529  size = size - 2; // remove the minimum RLC overhead
2530  std::map <uint16_t,uint32_t>::iterator it = m_ceBsrRxed.find (rnti);
2531  if (it != m_ceBsrRxed.end ())
2532  {
2533  NS_LOG_INFO (this << " UE " << rnti << " size " << size << " BSR " << (*it).second);
2534  if ((*it).second >= size)
2535  {
2536  (*it).second -= size;
2537  }
2538  else
2539  {
2540  (*it).second = 0;
2541  }
2542  }
2543  else
2544  {
2545  NS_LOG_ERROR (this << " Does not find BSR report info of UE " << rnti);
2546  }
2547 
2548 }
2549 
2550 void
2552 {
2553  NS_LOG_FUNCTION (this << " RNTI " << rnti << " txMode " << (uint16_t)txMode);
2555  params.m_rnti = rnti;
2556  params.m_transmissionMode = txMode;
2558 }
2559 
2560 
2561 }
ns3::FfMacSchedSapUser::SchedDlConfigIndParameters::m_buildRarList
std::vector< struct BuildRarListElement_s > m_buildRarList
build rar list
Definition: ff-mac-sched-sap.h:296
ns3::CqaFfMacScheduler::CqaFfMacScheduler
CqaFfMacScheduler()
Constructor.
Definition: cqa-ff-mac-scheduler.cc:130
ns3::FfMacCschedSapProvider::CschedUeReleaseReqParameters
Parameters of the CSCHED_UE_RELEASE_REQ primitive.
Definition: ff-mac-csched-sap.h:230
ns3::FfMacScheduler::m_ulCqiFilter
UlCqiFilter_t m_ulCqiFilter
UL CQI filter.
Definition: ff-mac-scheduler.h:132
ns3::TypeId
a unique identifier for an interface.
Definition: type-id.h:59
NS_LOG_COMPONENT_DEFINE
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
ns3::FfMacCschedSapProvider::CschedLcConfigReqParameters::m_logicalChannelConfigList
std::vector< struct LogicalChannelConfigListElement_s > m_logicalChannelConfigList
logicalChannelConfigList
Definition: ff-mac-csched-sap.h:207
ns3::FfMacSchedSapUser::SchedUlConfigIndParameters::m_dciList
std::vector< struct UlDciListElement_s > m_dciList
DCI list.
Definition: ff-mac-sched-sap.h:310
ns3::FfMacCschedSapProvider::CschedLcConfigReqParameters
Parameters of the CSCHED_LC_CONFIG_REQ primitive.
Definition: ff-mac-csched-sap.h:203
ns3::CqaFfMacScheduler::DoSchedDlRachInfoReq
void DoSchedDlRachInfoReq(const struct FfMacSchedSapProvider::SchedDlRachInfoReqParameters &params)
Sched DL RACH Info Request.
Definition: cqa-ff-mac-scheduler.cc:1673
ns3::FfMacSchedSapProvider::SchedDlRlcBufferReqParameters::m_logicalChannelIdentity
uint8_t m_logicalChannelIdentity
logical channel identity
Definition: ff-mac-sched-sap.h:62
ns3::UlDciListElement_s::m_aggrLevel
uint8_t m_aggrLevel
The aggregation level.
Definition: ff-mac-common.h:149
ns3::CqasFlowPerf_t
CGA Flow Performance structure.
Definition: cqa-ff-mac-scheduler.h:64
ns3::qos_rb_and_CQI_assigned_to_lc::cqi_value_for_lc
uint8_t cqi_value_for_lc
CQI indicator value.
Definition: cqa-ff-mac-scheduler.cc:62
ns3::FfMacCschedSapProvider::CschedLcReleaseReqParameters::m_rnti
uint16_t m_rnti
RNTI.
Definition: ff-mac-csched-sap.h:218
ns3::LteFfrSapProvider::GetAvailableUlRbg
virtual std::vector< bool > GetAvailableUlRbg()=0
Get vector of available RB in UL for this Cell.
NS_OBJECT_ENSURE_REGISTERED
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
NS_ASSERT
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
ns3::FfMacSchedSapProvider::SchedUlTriggerReqParameters::m_ulInfoList
std::vector< struct UlInfoListElement_s > m_ulInfoList
UL info list.
Definition: ff-mac-sched-sap.h:139
ns3::CqaFfMacScheduler::m_harqOn
bool m_harqOn
m_harqOn when false inhibit the HARQ mechanisms (by default active)
Definition: cqa-ff-mac-scheduler.h:383
ns3::BooleanValue
AttributeValue implementation for Boolean.
Definition: boolean.h:37
ns3::LteFfrSapUser
Service Access Point (SAP) offered by the eNodeB RRC instance to the Frequency Reuse algorithm instan...
Definition: lte-ffr-sap.h:139
ns3::FfMacSchedSapUser::SchedDlConfigInd
virtual void SchedDlConfigInd(const struct SchedDlConfigIndParameters &params)=0
SCHED_DL_CONFIG_IND.
ns3::LteFlowId_t::m_lcId
uint8_t m_lcId
LCID.
Definition: lte-common.h:39
ns3::CqaFfMacScheduler::m_amc
Ptr< LteAmc > m_amc
LTE AMC object.
Definition: cqa-ff-mac-scheduler.h:296
ns3::FfMacSchedSapUser::SchedDlConfigIndParameters::m_nrOfPdcchOfdmSymbols
uint8_t m_nrOfPdcchOfdmSymbols
number of PDCCH OFDM symbols
Definition: ff-mac-sched-sap.h:299
ns3::CqaFfMacScheduler::m_cschedSapUser
FfMacCschedSapUser * m_cschedSapUser
MAC Csched SAP user.
Definition: cqa-ff-mac-scheduler.h:361
ns3::CqaFfMacScheduler::m_dlHarqProcessesRlcPduListBuffer
std::map< uint16_t, DlHarqRlcPduListBuffer_t > m_dlHarqProcessesRlcPduListBuffer
DL HARQ process RLC PDU list buffer.
Definition: cqa-ff-mac-scheduler.h:391
ns3::FfMacCschedSapProvider::CschedUeConfigReqParameters::m_rnti
uint16_t m_rnti
RNTI.
Definition: ff-mac-csched-sap.h:138
ns3::UlCqi_s::SRS
@ SRS
Definition: ff-mac-common.h:507
ns3::FfMacScheduler
This abstract base class identifies the interface by means of which the helper object can plug on the...
Definition: ff-mac-scheduler.h:54
ns3::CqaFfMacScheduler::DoCschedCellConfigReq
void DoCschedCellConfigReq(const struct FfMacCschedSapProvider::CschedCellConfigReqParameters &params)
Csched Cell Config Request.
Definition: cqa-ff-mac-scheduler.cc:234
ns3::FfMacSchedSapProvider::SchedDlCqiInfoReqParameters
Parameters of the SCHED_DL_CQI_INFO_REQ primitive.
Definition: ff-mac-sched-sap.h:125
ns3::Simulator::Now
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
ns3::t_map_RBGToCQIsSorted
std::map< RBG_index, t_map_CQIToUE > t_map_RBGToCQIsSorted
RBG index map typedef.
Definition: cqa-ff-mac-scheduler.cc:98
ns3::FfMacSchedSapProvider::SchedDlRachInfoReqParameters
Parameters of the SCHED_DL_RACH_INFO_REQ primitive.
Definition: ff-mac-sched-sap.h:113
ns3
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::DlHarqRlcPduListBuffer_t
std::vector< RlcPduList_t > DlHarqRlcPduListBuffer_t
vector of the 8 HARQ processes per UE
Definition: cqa-ff-mac-scheduler.h:56
ns3::CqaFfMacScheduler::GetFfMacSchedSapProvider
virtual FfMacSchedSapProvider * GetFfMacSchedSapProvider()
Definition: cqa-ff-mac-scheduler.cc:216
ns3::CqaKeyDescComparator
bool CqaKeyDescComparator(uint16_t key1, uint16_t key2)
CQA key comparator.
Definition: cqa-ff-mac-scheduler.cc:124
ns3::CqasFlowPerf_t::secondLastAveragedThroughput
double secondLastAveragedThroughput
Second last average throughput.
Definition: cqa-ff-mac-scheduler.h:69
ns3::CqaFfMacScheduler::MemberCschedSapProvider< CqaFfMacScheduler >
friend class MemberCschedSapProvider< CqaFfMacScheduler >
allow MemberCschedSapProvider<CqaFfMacScheduler> class friend access
Definition: cqa-ff-mac-scheduler.h:115
ns3::t_it_CQIToUE
std::map< CQI_value, LteFlowId_t, bool(*)(uint8_t, uint8_t)>::iterator t_it_CQIToUE
CQI value map iterator typedef.
Definition: cqa-ff-mac-scheduler.cc:103
ns3::UlCqi_s::PUCCH_2
@ PUCCH_2
Definition: ff-mac-common.h:510
ns3::DlHarqProcessesStatus_t
std::vector< uint8_t > DlHarqProcessesStatus_t
DL HARQ process status vector typedef.
Definition: cqa-ff-mac-scheduler.h:48
ns3::FfMacSchedSapProvider::SchedUlCqiInfoReqParameters
Parameters of the SCHED_UL_CQI_INFO_REQ primitive.
Definition: ff-mac-sched-sap.h:186
ns3::UlDciListElement_s::m_tpc
int8_t m_tpc
Tx power control command.
Definition: ff-mac-common.h:153
ns3::FfMacSchedSapUser::SchedUlConfigIndParameters
Parameters of the SCHED_UL_CONFIG_IND primitive.
Definition: ff-mac-sched-sap.h:309
ns3::CqaFfMacScheduler::m_ulHarqProcessesStatus
std::map< uint16_t, UlHarqProcessesStatus_t > m_ulHarqProcessesStatus
UL HARQ process status.
Definition: cqa-ff-mac-scheduler.h:398
ns3::UlGrant_s::m_hopping
bool m_hopping
hopping?
Definition: ff-mac-common.h:269
ns3::CqaFfMacScheduler::m_dlHarqProcessesTimer
std::map< uint16_t, DlHarqProcessesTimer_t > m_dlHarqProcessesTimer
DL HARQ process timers.
Definition: cqa-ff-mac-scheduler.h:389
ns3::FfMacCschedSapProvider::CschedUeConfigReqParameters::m_transmissionMode
uint8_t m_transmissionMode
transmission mode
Definition: ff-mac-csched-sap.h:159
ns3::BuildRarListElement_s
See section 4.3.10 buildRARListElement.
Definition: ff-mac-common.h:279
ns3::CqaFfMacScheduler::DoSchedDlCqiInfoReq
void DoSchedDlCqiInfoReq(const struct FfMacSchedSapProvider::SchedDlCqiInfoReqParameters &params)
Sched DL CGI Info Request.
Definition: cqa-ff-mac-scheduler.cc:1683
ns3::CqaFfMacScheduler::m_uesTxMode
std::map< uint16_t, uint8_t > m_uesTxMode
txMode of the UEs
Definition: cqa-ff-mac-scheduler.h:380
ns3::CqaFfMacScheduler::m_a30CqiRxed
std::map< uint16_t, SbMeasResult_s > m_a30CqiRxed
Map of UE's DL CQI A30 received.
Definition: cqa-ff-mac-scheduler.h:332
ns3::CqaFfMacScheduler::m_nextRntiUl
uint16_t m_nextRntiUl
RNTI of the next user to be served next scheduling in UL.
Definition: cqa-ff-mac-scheduler.h:376
ns3::FfMacSchedSapProvider::SchedUlCqiInfoReqParameters::m_vendorSpecificList
std::vector< struct VendorSpecificListElement_s > m_vendorSpecificList
vendor specific list
Definition: ff-mac-sched-sap.h:190
ns3::FfMacSchedSapProvider::SchedDlMacBufferReqParameters
Parameters of the SCHED_DL_MAC_BUFFER_REQ primitive.
Definition: ff-mac-sched-sap.h:89
ns3::CqaFfMacScheduler::m_ceBsrRxed
std::map< uint16_t, uint32_t > m_ceBsrRxed
Map of UE's buffer status reports received.
Definition: cqa-ff-mac-scheduler.h:358
ns3::FfMacSchedSapProvider::SchedDlRlcBufferReqParameters::m_rnti
uint16_t m_rnti
RNTI.
Definition: ff-mac-sched-sap.h:61
ns3::CqaFfMacScheduler::m_ueCqiTimers
std::map< uint16_t, uint32_t > m_ueCqiTimers
Map of UEs' timers on UL-CQI per RBG.
Definition: cqa-ff-mac-scheduler.h:353
ns3::CqaFfMacScheduler::SetFfMacSchedSapUser
virtual void SetFfMacSchedSapUser(FfMacSchedSapUser *s)
set the user part of the FfMacSchedSap that this Scheduler will interact with.
Definition: cqa-ff-mac-scheduler.cc:204
ns3::SUCCESS
@ SUCCESS
Definition: ff-mac-common.h:62
ns3::CqaFfMacScheduler::m_schedSapProvider
FfMacSchedSapProvider * m_schedSapProvider
Sched SAP provider.
Definition: cqa-ff-mac-scheduler.h:364
ns3::FfMacCschedSapUser::CschedUeConfigCnfParameters
Parameters of the CSCHED_UE_CONFIG_CNF primitive.
Definition: ff-mac-csched-sap.h:308
ns3::DlDciListElement_s::m_resAlloc
uint8_t m_resAlloc
The type of resource allocation.
Definition: ff-mac-common.h:98
HARQ_DL_TIMEOUT
#define HARQ_DL_TIMEOUT
Definition: cqa-ff-mac-scheduler.h:43
ns3::DlDciListElement_s
See section 4.3.1 dlDciListElement.
Definition: ff-mac-common.h:94
ns3::CqaFfMacScheduler::DoSchedDlRlcBufferReq
void DoSchedDlRlcBufferReq(const struct FfMacSchedSapProvider::SchedDlRlcBufferReqParameters &params)
Sched DL RLC Buffer Request.
Definition: cqa-ff-mac-scheduler.cc:460
ns3::UlCqi_s::m_sinr
std::vector< uint16_t > m_sinr
SINR.
Definition: ff-mac-common.h:503
ns3::t_it_HOLGroupToRBGs
std::map< HOL_group, t_map_RBGToCQIsSorted >::iterator t_it_HOLGroupToRBGs
HOL group map iterator typedef.
Definition: cqa-ff-mac-scheduler.cc:107
ns3::MakeBooleanAccessor
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: boolean.h:85
ns3::FfMacSchedSapProvider::SchedUlSrInfoReqParameters
Parameters of the SCHED_UL_SR_INFO_REQ primitive.
Definition: ff-mac-sched-sap.h:162
ns3::DlDciListElement_s::m_rnti
uint16_t m_rnti
RNTI.
Definition: ff-mac-common.h:95
ns3::CqaFfMacScheduler::DoCschedUeConfigReq
void DoCschedUeConfigReq(const struct FfMacCschedSapProvider::CschedUeConfigReqParameters &params)
Csched UE Config Request.
Definition: cqa-ff-mac-scheduler.cc:247
ns3::FfMacSchedSapUser
FfMacSchedSapUser class.
Definition: ff-mac-sched-sap.h:281
ns3::DlHarqProcessesTimer_t
std::vector< uint8_t > DlHarqProcessesTimer_t
DL HARQ process timer vector typedef.
Definition: cqa-ff-mac-scheduler.h:50
ns3::TypeId::SetParent
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
ns3::CqaFfMacScheduler::DoCschedLcReleaseReq
void DoCschedLcReleaseReq(const struct FfMacCschedSapProvider::CschedLcReleaseReqParameters &params)
Csched LC Release Request.
Definition: cqa-ff-mac-scheduler.cc:367
ns3::LteFfrSapProvider::GetTpc
virtual uint8_t GetTpc(uint16_t rnti)=0
GetTpc.
ns3::UlDciListElement_s::m_rnti
uint16_t m_rnti
RNTI.
Definition: ff-mac-common.h:142
ns3::LogicalChannelConfigListElement_s::m_eRabGuaranteedBitrateDl
uint64_t m_eRabGuaranteedBitrateDl
ERAB guaranteed bit rate DL.
Definition: ff-mac-common.h:211
ns3::CqaFfMacScheduler::TransmissionModeConfigurationUpdate
void TransmissionModeConfigurationUpdate(uint16_t rnti, uint8_t txMode)
Trans mode config update.
Definition: cqa-ff-mac-scheduler.cc:2551
ns3::FfMacSchedSapProvider::SchedUlCqiInfoReqParameters::m_ulCqi
struct UlCqi_s m_ulCqi
UL CQI.
Definition: ff-mac-sched-sap.h:188
ns3::FfMacSchedSapProvider::SchedDlRlcBufferReqParameters
Parameters of the API primitives.
Definition: ff-mac-sched-sap.h:60
ns3::CqaType0AllocationRbg
static const int CqaType0AllocationRbg[4]
CGA Type 0 Allocation.
Definition: cqa-ff-mac-scheduler.cc:47
ns3::CqasFlowPerf_t::lastAveragedThroughput
double lastAveragedThroughput
Past average throughput.
Definition: cqa-ff-mac-scheduler.h:68
ns3::RlcPduListElement_s::m_size
uint16_t m_size
size
Definition: ff-mac-common.h:244
ns3::FfMacSchedSapProvider::SchedUlTriggerReqParameters::m_sfnSf
uint16_t m_sfnSf
sfn SF
Definition: ff-mac-sched-sap.h:138
ns3::qos_rb_and_CQI_assigned_to_lc::resource_block_index
uint16_t resource_block_index
Resource block indexHOL_GROUP_index.
Definition: cqa-ff-mac-scheduler.cc:61
ns3::FfMacCschedSapUser::CschedUeConfigUpdateIndParameters
Parameters of the CSCHED_UE_CONFIG_UPDATE_IND primitive.
Definition: ff-mac-csched-sap.h:360
ns3::t_it_HOLgroupToUEs
std::map< HOL_group, std::set< LteFlowId_t > >::iterator t_it_HOLgroupToUEs
HOL group multi map iterator typedef.
Definition: cqa-ff-mac-scheduler.cc:112
ns3::FfMacSchedSapProvider::SchedDlTriggerReqParameters::m_sfnSf
uint16_t m_sfnSf
sfn SF
Definition: ff-mac-sched-sap.h:102
ns3::CqaFfMacScheduler::m_ueLogicalChannelsConfigList
std::map< LteFlowId_t, struct LogicalChannelConfigListElement_s > m_ueLogicalChannelsConfigList
Map of UE logical channel config list.
Definition: cqa-ff-mac-scheduler.h:317
ns3::CqiListElement_s::P10
@ P10
Definition: ff-mac-common.h:490
ns3::UlInfoListElement_s::NotOk
@ NotOk
Definition: ff-mac-common.h:310
ns3::CqaFfMacScheduler::m_ulGrantMcs
uint8_t m_ulGrantMcs
MCS for UL grant (default 0)
Definition: cqa-ff-mac-scheduler.h:405
ns3::CqaFfMacScheduler::EstimateUlSinr
double EstimateUlSinr(uint16_t rnti, uint16_t rb)
Estimate UL Sinr.
Definition: cqa-ff-mac-scheduler.cc:1745
ns3::UlDciListElement_s::m_cqiRequest
bool m_cqiRequest
CQI request.
Definition: ff-mac-common.h:154
ns3::CqaFfMacScheduler::UpdateHarqProcessId
uint8_t UpdateHarqProcessId(uint16_t rnti)
Update and return a new process Id for the RNTI specified.
Definition: cqa-ff-mac-scheduler.cc:571
ns3::qos_rb_and_CQI_assigned_to_lc
qos_rb_and_CQI_assigned_to_lc
Definition: cqa-ff-mac-scheduler.cc:60
ns3::FfMacSchedSapProvider::SchedDlCqiInfoReqParameters::m_cqiList
std::vector< struct CqiListElement_s > m_cqiList
CQI list.
Definition: ff-mac-sched-sap.h:127
ns3::CqaFfMacScheduler::RefreshUlCqiMaps
void RefreshUlCqiMaps(void)
Refresh UL CGI maps.
Definition: cqa-ff-mac-scheduler.cc:2444
ns3::FfMacScheduler::PUSCH_UL_CQI
@ PUSCH_UL_CQI
Definition: ff-mac-scheduler.h:64
ns3::CqaFfMacScheduler::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: cqa-ff-mac-scheduler.cc:165
ns3::CqaFfMacScheduler::~CqaFfMacScheduler
virtual ~CqaFfMacScheduler()
Destructor.
Definition: cqa-ff-mac-scheduler.cc:143
ns3::Ptr
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
ns3::UlCqi_s::PUSCH
@ PUSCH
Definition: ff-mac-common.h:508
ns3::RlcPduListElement_s
See section 4.3.9 rlcPDU_ListElement.
Definition: ff-mac-common.h:242
ns3::CqaFfMacScheduler::DoCschedLcConfigReq
void DoCschedLcConfigReq(const struct FfMacCschedSapProvider::CschedLcConfigReqParameters &params)
Csched LC Config Request.
Definition: cqa-ff-mac-scheduler.cc:286
NS_FATAL_ERROR
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
ns3::HOL_group
int HOL_group
HOL group typedef.
Definition: cqa-ff-mac-scheduler.cc:93
ns3::UlDciListElement_s::m_cceIndex
uint8_t m_cceIndex
Control Channel Element index.
Definition: ff-mac-common.h:148
ns3::CqaFfMacScheduler::m_rlcBufferReq
std::map< LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters > m_rlcBufferReq
Vectors of UE's LC info.
Definition: cqa-ff-mac-scheduler.h:301
ns3::CqaFfMacScheduler::m_allocationMaps
std::map< uint16_t, std::vector< uint16_t > > m_allocationMaps
Map of previous allocated UE per RBG (used to retrieve info from UL-CQI)
Definition: cqa-ff-mac-scheduler.h:343
ns3::CqaFfMacScheduler::m_dlHarqProcessesDciBuffer
std::map< uint16_t, DlHarqProcessesDciBuffer_t > m_dlHarqProcessesDciBuffer
DL HARQ process DCI buffer.
Definition: cqa-ff-mac-scheduler.h:390
ns3::CqasFlowPerf_t::flowStart
Time flowStart
flow start time
Definition: cqa-ff-mac-scheduler.h:65
ns3::CqaFfMacScheduler::GetLteFfrSapUser
virtual LteFfrSapUser * GetLteFfrSapUser()
Definition: cqa-ff-mac-scheduler.cc:228
ns3::BuildDataListElement_s::m_rlcPduList
std::vector< std::vector< struct RlcPduListElement_s > > m_rlcPduList
RLC PDU list.
Definition: ff-mac-common.h:256
ns3::LteFlowId_t
LteFlowId structure.
Definition: lte-common.h:37
ns3::FfMacCschedSapProvider::CschedLcConfigReqParameters::m_reconfigureFlag
bool m_reconfigureFlag
reconfigure flag
Definition: ff-mac-csched-sap.h:205
ns3::CqaFfMacScheduler::m_rachList
std::vector< struct RachListElement_s > m_rachList
RACH list.
Definition: cqa-ff-mac-scheduler.h:403
bianchi11ax.k
int k
Definition: bianchi11ax.py:129
ns3::CqaFfMacScheduler::m_cschedSapProvider
FfMacCschedSapProvider * m_cschedSapProvider
Csched SAP provider.
Definition: cqa-ff-mac-scheduler.h:363
ns3::DlDciListElement_s::m_tbsSize
std::vector< uint16_t > m_tbsSize
The TBs size.
Definition: ff-mac-common.h:99
ns3::FfMacCschedSapUser::CschedUeConfigUpdateIndParameters::m_rnti
uint16_t m_rnti
RNTI.
Definition: ff-mac-csched-sap.h:361
ns3::UlDciListElement_s
See section 4.3.2 ulDciListElement.
Definition: ff-mac-common.h:141
ns3::FfMacSchedSapProvider::SchedUlMacCtrlInfoReqParameters::m_macCeList
std::vector< struct MacCeListElement_s > m_macCeList
MAC CE list.
Definition: ff-mac-sched-sap.h:176
ns3::MacCeListElement_s::BSR
@ BSR
Definition: ff-mac-common.h:342
ns3::CqiListElement_s::A30
@ A30
Definition: ff-mac-common.h:490
ns3::t_map_HOLgroupToUEs
std::multimap< HOL_group, std::set< LteFlowId_t >, bool(*)(int, int)> t_map_HOLgroupToUEs
HOL group map typedef.
Definition: cqa-ff-mac-scheduler.cc:110
ns3::FfMacSchedSapProvider::SchedDlTriggerReqParameters::m_dlInfoList
std::vector< struct DlInfoListElement_s > m_dlInfoList
DL info list.
Definition: ff-mac-sched-sap.h:103
ns3::FfMacSchedSapProvider::SchedUlNoiseInterferenceReqParameters
Parameters of the SCHED_UL_NOISE_INTERFERENCE_REQ primitive.
Definition: ff-mac-sched-sap.h:149
ns3::CQI_value
uint8_t CQI_value
CQI value typedef.
Definition: cqa-ff-mac-scheduler.cc:89
ns3::RlcPduListElement_s::m_logicalChannelIdentity
uint8_t m_logicalChannelIdentity
logical channel identity
Definition: ff-mac-common.h:243
ns3::FfMacSchedSapProvider::SchedDlPagingBufferReqParameters
Parameters of the SCHED_DL_PAGING_BUFFER_REQ primitive.
Definition: ff-mac-sched-sap.h:77
ns3::CqaFfMacScheduler::m_p10CqiTimers
std::map< uint16_t, uint32_t > m_p10CqiTimers
Map of UE's timers on DL CQI P01 received.
Definition: cqa-ff-mac-scheduler.h:327
ns3::CqaFfMacScheduler::DoSchedUlMacCtrlInfoReq
void DoSchedUlMacCtrlInfoReq(const struct FfMacSchedSapProvider::SchedUlMacCtrlInfoReqParameters &params)
Sched UL MAC Control Info Request.
Definition: cqa-ff-mac-scheduler.cc:2200
NS_LOG_INFO
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
ns3::LteFfrSapProvider
Service Access Point (SAP) offered by the Frequency Reuse algorithm instance to the MAC Scheduler ins...
Definition: lte-ffr-sap.h:40
MAX_LC_LIST
#define MAX_LC_LIST
Definition: ff-mac-common.h:33
ns3::t_map_CQIToUE
std::map< CQI_value, LteFlowId_t, bool(*)(uint8_t, uint8_t)> t_map_CQIToUE
CQI value map typedef.
Definition: cqa-ff-mac-scheduler.cc:96
ns3::UlDciListElement_s::m_rbStart
uint8_t m_rbStart
start
Definition: ff-mac-common.h:143
ns3::UlGrant_s::m_tpc
int8_t m_tpc
Tx power control command.
Definition: ff-mac-common.h:270
ns3::FfMacCschedSapProvider
Provides the CSCHED SAP.
Definition: ff-mac-csched-sap.h:46
ns3::CqaGroupDescComparator
bool CqaGroupDescComparator(int key1, int key2)
CGA group comparator function.
Definition: cqa-ff-mac-scheduler.cc:83
ns3::CqaFfMacScheduler::m_dlHarqCurrentProcessId
std::map< uint16_t, uint8_t > m_dlHarqCurrentProcessId
DL HARQ process ID.
Definition: cqa-ff-mac-scheduler.h:384
ns3::CqaFfMacScheduler::DoDispose
virtual void DoDispose(void)
Destructor implementation.
Definition: cqa-ff-mac-scheduler.cc:149
ns3::BuildRarListElement_s::m_rnti
uint16_t m_rnti
RNTI.
Definition: ff-mac-common.h:280
ns3::FfMacSchedSapUser::SchedUlConfigInd
virtual void SchedUlConfigInd(const struct SchedUlConfigIndParameters &params)=0
SCHED_UL_CONFIG_IND.
ns3::MakeBooleanChecker
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
ns3::UlDciListElement_s::m_freqHopping
uint8_t m_freqHopping
freq hopping
Definition: ff-mac-common.h:157
ns3::CqaFfMacScheduler::m_flowStatsDl
std::map< uint16_t, CqasFlowPerf_t > m_flowStatsDl
Map of UE statistics (per RNTI basis) in downlink.
Definition: cqa-ff-mac-scheduler.h:307
ns3::CqasFlowPerf_t::totalBytesTransmitted
unsigned long totalBytesTransmitted
Total bytes send by eNb for this UE.
Definition: cqa-ff-mac-scheduler.h:66
ns3::UlDciListElement_s::m_ulIndex
uint8_t m_ulIndex
UL index.
Definition: ff-mac-common.h:155
ns3::FfMacCschedSapProvider::CschedUeReleaseReqParameters::m_rnti
uint16_t m_rnti
RNTI.
Definition: ff-mac-csched-sap.h:231
ns3::CqaFfMacScheduler::LcActivePerFlow
unsigned int LcActivePerFlow(uint16_t rnti)
LC Active per flow.
Definition: cqa-ff-mac-scheduler.cc:515
ns3::UlDciListElement_s::m_ndi
uint8_t m_ndi
NDI.
Definition: ff-mac-common.h:147
ns3::CqasFlowPerf_t::targetThroughput
double targetThroughput
Target throughput.
Definition: cqa-ff-mac-scheduler.h:70
ns3::CqaFfMacScheduler::HarqProcessAvailability
uint8_t HarqProcessAvailability(uint16_t rnti)
Return the availability of free process for the RNTI specified.
Definition: cqa-ff-mac-scheduler.cc:538
NS_ABORT_MSG_IF
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
ns3::CqaFfMacScheduler::GetRbgSize
int GetRbgSize(int dlbandwidth)
Get RGB Size.
Definition: cqa-ff-mac-scheduler.cc:500
ns3::LteFfConverter::fpS11dot3toDouble
static double fpS11dot3toDouble(uint16_t val)
Convert from fixed point S11.3 notation to double.
Definition: lte-common.cc:155
NS_ASSERT_MSG
#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:88
ns3::FfMacCschedSapProvider::CschedLcReleaseReqParameters::m_logicalChannelIdentity
std::vector< uint8_t > m_logicalChannelIdentity
logical channel identity
Definition: ff-mac-csched-sap.h:220
ns3::UlCqi_s::PUCCH_1
@ PUCCH_1
Definition: ff-mac-common.h:509
ns3::CqaFfMacScheduler::UpdateDlRlcBufferInfo
void UpdateDlRlcBufferInfo(uint16_t rnti, uint8_t lcid, uint16_t size)
Update DL RLC buffer info.
Definition: cqa-ff-mac-scheduler.cc:2474
ns3::UlGrant_s::m_rbLen
uint8_t m_rbLen
length
Definition: ff-mac-common.h:266
ns3::BuildRarListElement_s::m_grant
UlGrant_s m_grant
grant
Definition: ff-mac-common.h:282
ns3::CqaFfMacScheduler::DoSchedDlTriggerReq
void DoSchedDlTriggerReq(const struct FfMacSchedSapProvider::SchedDlTriggerReqParameters &params)
Sched DL RLC Buffer Request.
Definition: cqa-ff-mac-scheduler.cc:645
ns3::FfMacSchedSapProvider::SchedDlTriggerReqParameters
Parameters of the SCHED_DL_TRIGGER_REQ primitive.
Definition: ff-mac-sched-sap.h:101
ns3::UlGrant_s::m_cqiRequest
bool m_cqiRequest
CQI request?
Definition: ff-mac-common.h:271
ns3::CqaFfMacScheduler::m_ulHarqProcessesDciBuffer
std::map< uint16_t, UlHarqProcessesDciBuffer_t > m_ulHarqProcessesDciBuffer
UL HARQ process DCI buffer.
Definition: cqa-ff-mac-scheduler.h:399
ns3::CqaFfMacScheduler::UpdateUlRlcBufferInfo
void UpdateUlRlcBufferInfo(uint16_t rnti, uint16_t size)
Update UL RLC buffer info.
Definition: cqa-ff-mac-scheduler.cc:2526
ns3::CqaFfMacScheduler::RefreshHarqProcesses
void RefreshHarqProcesses()
Refresh HARQ processes according to the timers.
Definition: cqa-ff-mac-scheduler.cc:612
ns3::t_map_HOLGroupToRBGs
std::map< HOL_group, t_map_RBGToCQIsSorted > t_map_HOLGroupToRBGs
HOL group map typedef.
Definition: cqa-ff-mac-scheduler.cc:100
ns3::FfMacCschedSapProvider::CschedCellConfigReqParameters::m_dlBandwidth
uint16_t m_dlBandwidth
DL badnwidth.
Definition: ff-mac-csched-sap.h:88
ns3::CqaFfMacScheduler::GetFfMacCschedSapProvider
virtual FfMacCschedSapProvider * GetFfMacCschedSapProvider()
Definition: cqa-ff-mac-scheduler.cc:210
NS_LOG_LOGIC
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
ns3::CqaFfMacScheduler::m_p10CqiRxed
std::map< uint16_t, uint8_t > m_p10CqiRxed
Map of UE's DL CQI P01 received.
Definition: cqa-ff-mac-scheduler.h:322
ns3::MemberLteFfrSapUser
Template for the implementation of the LteFfrSapUser as a member of an owner class of type C to which...
Definition: lte-ffr-sap.h:256
ns3::StringValue
Hold variables of type string.
Definition: string.h:41
ns3::CqaFfMacScheduler::m_a30CqiTimers
std::map< uint16_t, uint32_t > m_a30CqiTimers
Map of UE's timers on DL CQI A30 received.
Definition: cqa-ff-mac-scheduler.h:337
ns3::t_it_RBGToCQIsSorted
std::map< RBG_index, t_map_CQIToUE >::iterator t_it_RBGToCQIsSorted
RBG index map iterator typedef.
Definition: cqa-ff-mac-scheduler.cc:105
NS_LOG_ERROR
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:257
ns3::CqaFfMacScheduler::m_CqaMetric
std::string m_CqaMetric
CQA metric name.
Definition: cqa-ff-mac-scheduler.h:408
ns3::CqaFfMacScheduler::m_ffrSapUser
LteFfrSapUser * m_ffrSapUser
FFR SAP user.
Definition: cqa-ff-mac-scheduler.h:367
ns3::FfMacCschedSapProvider::CschedUeConfigReqParameters
Parameters of the CSCHED_UE_CONFIG_REQ primitive.
Definition: ff-mac-csched-sap.h:137
ns3::FfMacSchedSapProvider::SchedUlCqiInfoReqParameters::m_sfnSf
uint16_t m_sfnSf
sfn SF
Definition: ff-mac-sched-sap.h:187
ns3::BuildDataListElement_s::m_rnti
uint16_t m_rnti
RNTI.
Definition: ff-mac-common.h:253
ns3::CQIValueDescComparator
bool CQIValueDescComparator(uint8_t key1, uint8_t key2)
CQI value comparator function.
Definition: cqa-ff-mac-scheduler.cc:72
ns3::FfMacCschedSapUser::CschedUeConfigCnfParameters::m_result
enum Result_e m_result
result
Definition: ff-mac-csched-sap.h:310
ns3::FfMacCschedSapProvider::CschedLcConfigReqParameters::m_rnti
uint16_t m_rnti
RNTI.
Definition: ff-mac-csched-sap.h:204
ns3::UlDciListElement_s::m_ueTxAntennaSelection
uint8_t m_ueTxAntennaSelection
UE antenna selection.
Definition: ff-mac-common.h:150
ns3::FfMacSchedSapProvider::SchedUlMacCtrlInfoReqParameters
Parameters of the SCHED_UL_MAC_CTRL_INFO_REQ primitive.
Definition: ff-mac-sched-sap.h:174
ns3::UlCqi_s::PRACH
@ PRACH
Definition: ff-mac-common.h:511
ns3::UlGrant_s::m_ulDelay
bool m_ulDelay
UL delay?
Definition: ff-mac-common.h:272
ns3::FfMacSchedSapUser::SchedDlConfigIndParameters::m_buildDataList
std::vector< struct BuildDataListElement_s > m_buildDataList
build data list
Definition: ff-mac-sched-sap.h:295
ns3::BufferSizeLevelBsr::BsrId2BufferSize
static uint32_t BsrId2BufferSize(uint8_t val)
Convert BSR ID to buffer size.
Definition: lte-common.cc:184
NS_LOG_DEBUG
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
ns3::FfMacCschedSapUser::CschedUeConfigUpdateIndParameters::m_transmissionMode
uint8_t m_transmissionMode
transmission mode
Definition: ff-mac-csched-sap.h:362
ns3::DlDciListElement_s::m_mcs
std::vector< uint8_t > m_mcs
MCS.
Definition: ff-mac-common.h:100
ns3::CqaFfMacScheduler::m_dlInfoListBuffered
std::vector< DlInfoListElement_s > m_dlInfoListBuffered
DL HARQ retx buffered.
Definition: cqa-ff-mac-scheduler.h:392
ns3::FfMacCschedSapUser::CschedUeConfigCnf
virtual void CschedUeConfigCnf(const struct CschedUeConfigCnfParameters &params)=0
CSCHED_UE_CONFIG_CNF.
ns3::UlGrant_s::m_tbSize
uint16_t m_tbSize
size
Definition: ff-mac-common.h:267
ns3::CqaFfMacScheduler::m_dlHarqProcessesStatus
std::map< uint16_t, DlHarqProcessesStatus_t > m_dlHarqProcessesStatus
DL HARQ process statuses.
Definition: cqa-ff-mac-scheduler.h:388
ns3::DlHarqProcessesDciBuffer_t
std::vector< DlDciListElement_s > DlHarqProcessesDciBuffer_t
DL HARQ process DCI buffer vector typedef.
Definition: cqa-ff-mac-scheduler.h:52
ns3::LteFfrSapProvider::ReportUlCqiInfo
virtual void ReportUlCqiInfo(const struct FfMacSchedSapProvider::SchedUlCqiInfoReqParameters &params)=0
ReportUlCqiInfo.
NO_SINR
#define NO_SINR
Definition: cqa-ff-mac-scheduler.h:41
ns3::UlHarqProcessesDciBuffer_t
std::vector< UlDciListElement_s > UlHarqProcessesDciBuffer_t
UL HARQ process DCI buffer vector.
Definition: cqa-ff-mac-scheduler.h:58
ns3::UlDciListElement_s::m_hopping
bool m_hopping
hopping?
Definition: ff-mac-common.h:151
ns3::FfMacSchedSapProvider::SchedUlTriggerReqParameters
Parameters of the SCHED_UL_TRIGGER_REQ primitive.
Definition: ff-mac-sched-sap.h:137
ns3::CqaFfMacScheduler::m_cqiTimersThreshold
uint32_t m_cqiTimersThreshold
Definition: cqa-ff-mac-scheduler.h:378
ns3::FfMacCschedSapUser::CschedUeConfigUpdateInd
virtual void CschedUeConfigUpdateInd(const struct CschedUeConfigUpdateIndParameters &params)=0
CSCHED_UE_UPDATE_IND.
ns3::CqaFfMacScheduler::DoSchedUlTriggerReq
void DoSchedUlTriggerReq(const struct FfMacSchedSapProvider::SchedUlTriggerReqParameters &params)
Sched UL Trigger Request.
Definition: cqa-ff-mac-scheduler.cc:1776
ns3::CqasFlowPerf_t::lastTtiBytesTransmitted
unsigned int lastTtiBytesTransmitted
Total bytes send by eNB in last tti for this UE.
Definition: cqa-ff-mac-scheduler.h:67
ns3::CqaFfMacScheduler::DoSchedUlNoiseInterferenceReq
void DoSchedUlNoiseInterferenceReq(const struct FfMacSchedSapProvider::SchedUlNoiseInterferenceReqParameters &params)
Sched UL Noise InterferenceRequest.
Definition: cqa-ff-mac-scheduler.cc:2186
ns3::UlDciListElement_s::m_mcs
uint8_t m_mcs
MCS.
Definition: ff-mac-common.h:146
ns3::UlDciListElement_s::m_rbLen
uint8_t m_rbLen
length
Definition: ff-mac-common.h:144
ns3::FfMacCschedSapProvider::CschedLcReleaseReqParameters
Parameters of the CSCHED_LC_RELEASE_REQ primitive.
Definition: ff-mac-csched-sap.h:217
NS_LOG_FUNCTION
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Definition: log-macros-enabled.h:244
ns3::CqaFfMacScheduler::DoSchedUlCqiInfoReq
void DoSchedUlCqiInfoReq(const struct FfMacSchedSapProvider::SchedUlCqiInfoReqParameters &params)
Sched UL CGI Info Request.
Definition: cqa-ff-mac-scheduler.cc:2244
HARQ_PROC_NUM
#define HARQ_PROC_NUM
Definition: cqa-ff-mac-scheduler.h:42
ns3::CqaFfMacScheduler::SetFfMacCschedSapUser
virtual void SetFfMacCschedSapUser(FfMacCschedSapUser *s)
set the user part of the FfMacCschedSap that this Scheduler will interact with.
Definition: cqa-ff-mac-scheduler.cc:198
ns3::FfMacCschedSapUser
FfMacCschedSapUser class.
Definition: ff-mac-csched-sap.h:284
ns3::RBG_index
int RBG_index
RBG index typedef.
Definition: cqa-ff-mac-scheduler.cc:91
ns3::UlGrant_s::m_rbStart
uint8_t m_rbStart
start
Definition: ff-mac-common.h:265
HARQ_PERIOD
#define HARQ_PERIOD
Definition: lte-common.h:30
ns3::CqaFfMacScheduler::MemberSchedSapProvider< CqaFfMacScheduler >
friend class MemberSchedSapProvider< CqaFfMacScheduler >
allow MemberSchedSapProvider<CqaFfMacScheduler> class friend access
Definition: cqa-ff-mac-scheduler.h:117
ns3::MakeStringChecker
Ptr< const AttributeChecker > MakeStringChecker(void)
Definition: string.cc:30
ns3::LteFlowId_t::m_rnti
uint16_t m_rnti
RNTI.
Definition: lte-common.h:38
ns3::CqaFfMacScheduler::DoSchedUlSrInfoReq
void DoSchedUlSrInfoReq(const struct FfMacSchedSapProvider::SchedUlSrInfoReqParameters &params)
Sched UL Sr Info Request.
Definition: cqa-ff-mac-scheduler.cc:2193
ns3::UintegerValue
Hold an unsigned integer type.
Definition: uinteger.h:44
ns3::FfMacCschedSapProvider::CschedCellConfigReqParameters
Parameters of the API primitives.
Definition: ff-mac-csched-sap.h:59
ns3::DlDciListElement_s::m_tpc
uint8_t m_tpc
Tx power control command.
Definition: ff-mac-common.h:111
ns3::UlDciListElement_s::m_n2Dmrs
uint8_t m_n2Dmrs
n2 DMRS
Definition: ff-mac-common.h:152
ns3::LteFfrSapProvider::IsUlRbgAvailableForUe
virtual bool IsUlRbgAvailableForUe(int i, uint16_t rnti)=0
Check if UE can be served on i-th RB in UL.
ns3::UlDciListElement_s::m_pdcchPowerOffset
int8_t m_pdcchPowerOffset
CCH power offset.
Definition: ff-mac-common.h:158
ns3::CqaFfMacScheduler::m_ueCqi
std::map< uint16_t, std::vector< double > > m_ueCqi
Map of UEs' UL-CQI per RBG.
Definition: cqa-ff-mac-scheduler.h:348
ns3::CqaFfMacScheduler::SetLteFfrSapProvider
virtual void SetLteFfrSapProvider(LteFfrSapProvider *s)
Set the Provider part of the LteFfrSap that this Scheduler will interact with.
Definition: cqa-ff-mac-scheduler.cc:222
ns3::UlGrant_s::m_mcs
uint8_t m_mcs
MCS.
Definition: ff-mac-common.h:268
ns3::MakeUintegerAccessor
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: uinteger.h:45
ns3::CqaFfMacScheduler::m_ulHarqCurrentProcessId
std::map< uint16_t, uint8_t > m_ulHarqCurrentProcessId
UL HARQ current process ID.
Definition: cqa-ff-mac-scheduler.h:394
ns3::CqaFfMacScheduler
Implements the SCHED SAP and CSCHED SAP for the Channel and QoS Aware Scheduler.
Definition: cqa-ff-mac-scheduler.h:82
ns3::CqaFfMacScheduler::m_flowStatsUl
std::map< uint16_t, CqasFlowPerf_t > m_flowStatsUl
Map of UE statistics (per RNTI basis)
Definition: cqa-ff-mac-scheduler.h:312
ns3::FfMacSchedSapProvider::SchedDlRachInfoReqParameters::m_rachList
std::vector< struct RachListElement_s > m_rachList
RACH list.
Definition: ff-mac-sched-sap.h:115
ns3::TransmissionModesLayers::TxMode2LayerNum
static uint8_t TxMode2LayerNum(uint8_t txMode)
Transmit mode 2 layer number.
Definition: lte-common.cc:212
ns3::DlDciListElement_s::m_rbBitmap
uint32_t m_rbBitmap
RB bitmap.
Definition: ff-mac-common.h:96
ns3::CqaFfMacScheduler::m_cschedCellConfig
FfMacCschedSapProvider::CschedCellConfigReqParameters m_cschedCellConfig
Internal parameters.
Definition: cqa-ff-mac-scheduler.h:371
SRS_CQI_RNTI_VSP
#define SRS_CQI_RNTI_VSP
Definition: lte-vendor-specific-parameters.h:27
ns3::CqaFfMacScheduler::m_rachAllocationMap
std::vector< uint16_t > m_rachAllocationMap
RACH allocation map.
Definition: cqa-ff-mac-scheduler.h:404
ns3::UlGrant_s::m_rnti
uint16_t m_rnti
RNTI.
Definition: ff-mac-common.h:264
ns3::DlDciListElement_s::m_ndi
std::vector< uint8_t > m_ndi
New data indicator.
Definition: ff-mac-common.h:101
ns3::FfMacCschedSapProvider::CschedCellConfigReqParameters::m_ulBandwidth
uint16_t m_ulBandwidth
UL bandwidth.
Definition: ff-mac-csched-sap.h:87
ns3::BuildDataListElement_s
See section 4.3.8 builDataListElement.
Definition: ff-mac-common.h:252
ns3::DlInfoListElement_s::NACK
@ NACK
Definition: ff-mac-common.h:436
ns3::BuildDataListElement_s::m_dci
struct DlDciListElement_s m_dci
DCI.
Definition: ff-mac-common.h:254
ns3::FfMacScheduler::SRS_UL_CQI
@ SRS_UL_CQI
Definition: ff-mac-scheduler.h:63
ns3::DlDciListElement_s::m_rv
std::vector< uint8_t > m_rv
Redundancy version.
Definition: ff-mac-common.h:102
ns3::CqaFfMacScheduler::DoSchedDlMacBufferReq
void DoSchedDlMacBufferReq(const struct FfMacSchedSapProvider::SchedDlMacBufferReqParameters &params)
Sched DL MAC Buffer Request.
Definition: cqa-ff-mac-scheduler.cc:492
ns3::UlDciListElement_s::m_dai
uint8_t m_dai
DL assignment index.
Definition: ff-mac-common.h:156
ns3::CqaFfMacScheduler::m_ffrSapProvider
LteFfrSapProvider * m_ffrSapProvider
FFR SAP provider.
Definition: cqa-ff-mac-scheduler.h:368
ns3::FfMacSchedSapProvider
Provides the SCHED SAP.
Definition: ff-mac-sched-sap.h:47
ns3::LteFfrSapProvider::GetAvailableDlRbg
virtual std::vector< bool > GetAvailableDlRbg()=0
Get vector of available RBG in DL for this Cell.
ns3::UlHarqProcessesStatus_t
std::vector< uint8_t > UlHarqProcessesStatus_t
UL HARQ process status vector.
Definition: cqa-ff-mac-scheduler.h:60
ns3::MakeStringAccessor
Ptr< const AttributeAccessor > MakeStringAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: string.h:42
ns3::UlDciListElement_s::m_tbSize
uint16_t m_tbSize
size
Definition: ff-mac-common.h:145
ns3::CqaFfMacScheduler::m_timeWindow
double m_timeWindow
time window
Definition: cqa-ff-mac-scheduler.h:374
ns3::LogicalChannelConfigListElement_s
See section 4.3.4 logicalChannelConfigListElement.
Definition: ff-mac-common.h:186
ns3::LteFfrSapProvider::ReportDlCqiInfo
virtual void ReportDlCqiInfo(const struct FfMacSchedSapProvider::SchedDlCqiInfoReqParameters &params)=0
ReportDlCqiInfo.
ns3::CqaFfMacScheduler::m_schedSapUser
FfMacSchedSapUser * m_schedSapUser
MAC Sched SAP user.
Definition: cqa-ff-mac-scheduler.h:362
ns3::LteFfrSapProvider::IsDlRbgAvailableForUe
virtual bool IsDlRbgAvailableForUe(int i, uint16_t rnti)=0
Check if UE can be served on i-th RB in DL.
ns3::LteFfrSapProvider::GetMinContinuousUlBandwidth
virtual uint16_t GetMinContinuousUlBandwidth()=0
Get the minimum continuous Ul bandwidth.
ns3::FfMacSchedSapUser::SchedDlConfigIndParameters
Parameters of the API primitives.
Definition: ff-mac-sched-sap.h:294
ns3::DlDciListElement_s::m_harqProcess
uint8_t m_harqProcess
HARQ process.
Definition: ff-mac-common.h:112
ns3::CqaFfMacScheduler::DoCschedUeReleaseReq
void DoCschedUeReleaseReq(const struct FfMacCschedSapProvider::CschedUeReleaseReqParameters &params)
Csched UE Release Request.
Definition: cqa-ff-mac-scheduler.cc:409
ns3::CqaFfMacScheduler::DoSchedDlPagingBufferReq
void DoSchedDlPagingBufferReq(const struct FfMacSchedSapProvider::SchedDlPagingBufferReqParameters &params)
Sched DL Paging Buffer Request.
Definition: cqa-ff-mac-scheduler.cc:484
ns3::CqaFfMacScheduler::RefreshDlCqiMaps
void RefreshDlCqiMaps(void)
Refresh DL CGI maps.
Definition: cqa-ff-mac-scheduler.cc:2391