Commit 2f0646f3 authored by nikaeinn's avatar nikaeinn
Browse files

* add a ulsch scheduler and preprocessor

* check for false msg3 detection at the MAC layer, and indicate PHY tp cancel the RA proc 
* fix few compilation errors for Rel10


git-svn-id: http://svn.eurecom.fr/openair4G/trunk@5824 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent b79bd77b
......@@ -223,7 +223,7 @@ hashtable_rc_t hashtable_remove(hash_table_t *hashtblP, const hash_key_t keyP)
hash=hashtblP->hashfunc(keyP)%hashtblP->size;
node=hashtblP->nodes[hash];
while(node) {
if(node->key != keyP) {
if(node->key == keyP) {
if(prevnode) prevnode->next=node->next;
else hashtblP->nodes[hash]=node->next;
if (node->data) {
......
......@@ -86,6 +86,21 @@ int32_t lte_segmentation(uint8_t *input_buffer,
uint32_t *Kminus,
uint32_t *F);
/** \fn int16_t estimate_ue_tx_power(uint32_t tbs, uint32_t nb_rb, uint8_t control_only, lte_prefix_type_t ncp, uint8_t use_srs)
\brief this functions calculates the delta MCS in dB based on the lte_segmentation function
\param tbs transport block size
\param nb_rb number of required rb
\param control_only a flag for the type of data
\param ncp cyclic prefix
\param use_srs a flag indicating the use of srs in the current SF
\returns ue_tx_power estimated ue tx power = delat_ mcs + bw_factor
*/
int16_t estimate_ue_tx_power(uint32_t tbs,
uint32_t nb_rb,
uint8_t control_only,
lte_prefix_type_t ncp,
uint8_t use_srs);
/** \fn uint32_t sub_block_interleaving_turbo(uint32_t D, uint8_t *d,uint8_t *w)
\brief This is the subblock interleaving algorithm from 36-212 (Release 8, 8.6 2009-03), pages 15-16.
This function takes the d-sequence and generates the w-sequence. The nu-sequence from 36-212 is implicit.
......
......@@ -32,6 +32,7 @@
date: 21.10.2009
*/
#include "PHY/defs.h"
#include "SCHED/extern.h"
//#define DEBUG_SEGMENTATION
......@@ -166,6 +167,72 @@ int lte_segmentation(unsigned char *input_buffer,
return(0);
}
// uint8_t eNB_id,uint8_t harq_pid, uint8_t UE_id,
int16_t estimate_ue_tx_power(uint32_t tbs, uint32_t nb_rb, uint8_t control_only, lte_prefix_type_t ncp, uint8_t use_srs){
/// The payload + CRC size in bits, "B"
uint32_t B;
/// Number of code segments
uint32_t C;
/// Number of "small" code segments
uint32_t Cminus;
/// Number of "large" code segments
uint32_t Cplus;
/// Number of bits in "small" code segments (<6144)
uint32_t Kminus;
/// Number of bits in "large" code segments (<6144)
uint32_t Kplus;
/// Total number of bits across all segments
uint32_t sumKr;
/// Number of "Filler" bits
uint32_t F;
// num resource elements
uint32_t num_re=0.0;
// num symbols
uint32_t num_symb=0.0;
/// effective spectral efficiency of the PUSCH
uint32_t MPR_x100=0;
/// beta_offset
uint16_t beta_offset_pusch_x8=8;
/// delta mcs
float delta_mcs=0.0;
/// bandwidth factor
float bw_factor=0.0;
B= tbs+24;
lte_segmentation(NULL,
NULL,
B,
&C,
&Cplus,
&Cminus,
&Kplus,
&Kminus,
&F);
sumKr = Cminus*Kminus + Cplus*Kplus;
num_symb = 12-(ncp<<1)-(use_srs==0?0:1);
num_re = num_symb * nb_rb * 12;
if (num_re == 0)
return(0);
MPR_x100 = 100*sumKr/num_re;
if (control_only == 1 )
beta_offset_pusch_x8=8; // fixme
//(beta_offset_pusch_x8=phy_vars_ue->ulsch_ue[eNB_id]->harq_processes[harq_pid]->control_only == 1) ? phy_vars_ue->ulsch_ue[eNB_id]->beta_offset_cqi_times8:8;
// if deltamcs_enabledm
delta_mcs = ((hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_times10((beta_offset_pusch_x8)>>3))/100.0);
bw_factor = (hundred_times_log10_NPRB[nb_rb-1]/100.0);
#ifdef DEBUG_SEGMENTATION
printf("estimated ue tx power %d (num_re %d, sumKr %d, mpr_x100 %d, delta_mcs %f, bw_factor %f)\n",
(int16_t)ceil(delta_mcs + bw_factor), num_re, sumKr, MPR_x100, delta_mcs, bw_factor);
#endif
return (int16_t)ceil(delta_mcs + bw_factor);
}
#ifdef MAIN
main() {
......
......@@ -51,10 +51,10 @@
* Memory Initializaion and Cleanup for LTE MODEM.
* @{
\section _Memory_init_ Memory Initialization for LTE MODEM
Blah Blah
*/
#define DEBUG_PHY
//#define DEBUG_PHY
/*
#ifndef USER_MODE
......
......@@ -77,6 +77,8 @@ extern int synch_wait_cnt;
extern OPENAIR_DAQ_VARS openair_daq_vars;
extern int16_t hundred_times_delta_TF[100];
extern uint16_t hundred_times_log10_NPRB[100];
/*
#ifdef EMOS
extern fifo_dump_emos_UE emos_dump_UE;
......
......@@ -3132,7 +3132,18 @@ void phy_procedures_eNB_RX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e
phy_vars_eNB->ulsch_eNB[i]->rnti,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->b,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3,
harq_pid);
harq_pid,
&phy_vars_eNB->ulsch_eNB[i]->Msg3_flag);
// false msg3 detection by MAC: empty PDU
if (phy_vars_eNB->ulsch_eNB[i]->Msg3_flag == 0 ) {
phy_vars_eNB->eNB_UE_stats[i].mode = PRACH;
mac_xface->cancel_ra_proc(phy_vars_eNB->Mod_id,
phy_vars_eNB->CC_id,
frame,
phy_vars_eNB->eNB_UE_stats[i].crnti);
remove_ue(phy_vars_eNB->eNB_UE_stats[i].crnti,phy_vars_eNB,abstraction_flag);
phy_vars_eNB->ulsch_eNB[(uint32_t)i]->Msg3_active = 0;
}
/*
mac_xface->terminate_ra_proc(phy_vars_eNB->Mod_id,
frame,
......@@ -3193,7 +3204,8 @@ void phy_procedures_eNB_RX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e
phy_vars_eNB->ulsch_eNB[i]->rnti,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->b,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3,
harq_pid);
harq_pid,
NULL);
//}
/*
else {
......@@ -3663,7 +3675,9 @@ void phy_procedures_eNB_RX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e
phy_vars_eNB->ulsch_eNB[i]->rnti,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->b,
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3,
harq_pid);
harq_pid,
NULL);
phy_vars_eNB->cba_last_reception[i%num_active_cba_groups]=1;//(subframe);
} else {
LOG_N(PHY,"[eNB %d] Frame %d subframe %d : CBA collision detected for UE%d for group %d, set the SR for this UE \n ",
......
......@@ -466,6 +466,8 @@ typedef struct{
uint64_t total_pdu_bytes_rx;
// total num pdu
uint32_t total_num_pdus_rx;
// num of error pdus
uint32_t total_num_errors_rx;
}eNB_UE_STATS;
......@@ -496,10 +498,22 @@ typedef struct{
uint8_t DLSCH_DCI[8][(MAX_DCI_SIZE_BITS>>3)+1];
/// Number of Allocated RBs for DL after scheduling (prior to frequency allocation)
uint16_t nb_rb[8];
uint16_t nb_rb[8]; // num_max_harq
/// Number of Allocated RBs for UL after scheduling (prior to frequency allocation)
uint16_t nb_rb_ul[8];
uint16_t nb_rb_ul[8]; // num_max_harq
/// Number of Allocated RBs by the ulsch preprocessor
uint8_t pre_allocated_nb_rb_ul;
/// index of Allocated RBs by the ulsch preprocessor
int8_t pre_allocated_rb_table_index_ul;
/// total allocated RBs
int8_t total_allocated_rbs;
/// assigned MCS by the ulsch preprocessor
uint8_t pre_assigned_mcs_ul;
/// DCI buffer for ULSCH
uint8_t ULSCH_DCI[8][(MAX_DCI_SIZE_BITS>>3)+1];
......@@ -524,6 +538,9 @@ typedef struct{
/// phr information
int8_t phr_info;
/// phr information
int8_t phr_info_configured;
//dl buffer info
uint32_t dl_buffer_info[MAX_NUM_LCID];
......@@ -541,6 +558,15 @@ typedef struct{
uint32_t dl_buffer_head_sdu_remaining_size_to_send[MAX_NUM_LCID];
// uplink info
uint32_t ul_total_buffer;
uint32_t ul_buffer_creation_time[MAX_NUM_LCGID];
uint32_t ul_buffer_creation_time_max;
uint32_t ul_buffer_info[MAX_NUM_LCGID];
} UE_TEMPLATE;
typedef struct{
......@@ -645,6 +671,8 @@ typedef struct{
int next[NUMBER_OF_UE_MAX];
int head;
int next_ul[NUMBER_OF_UE_MAX];
int head_ul;
int avail;
int num_UEs;
boolean_t active[NUMBER_OF_UE_MAX];
......
......@@ -1695,6 +1695,7 @@ void fill_DLSCH_dci(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP
// Get candidate harq_pid from PHY
mac_xface->get_ue_active_harq_pid(module_idP,CC_id,RA_template->rnti,frameP,subframeP,&harq_pid,&round,0);
if (round>0) {
//RA_template->wait_ack_Msg4++;
// we have to schedule a retransmission
if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD)
((DCI1A_5MHz_TDD_1_6_t*)&RA_template->RA_alloc_pdu2[0])->ndi=1;
......@@ -1733,6 +1734,11 @@ void fill_DLSCH_dci(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP
module_idP,frameP,subframeP,RA_template->rnti);
}
else {
/* msg4 not received
if ((round == 0) && (RA_template->wait_ack_Msg4>1){
remove UE instance across all the layers: mac_xface->cancel_RA();
}
*/
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d : Msg4 acknowledged\n",module_idP,frameP,subframeP);
RA_template->wait_ack_Msg4=0;
RA_template->RA_active=FALSE;
......
......@@ -195,12 +195,17 @@ uint8_t find_num_active_UEs_in_cbagroup(module_id_t module_idP, int CC_id,unsign
}
#endif
void dump_ue_list(UE_list_t *listP) {
void dump_ue_list(UE_list_t *listP, int ul_flag) {
int j;
if ( ul_flag == 0 ){
for (j=listP->head;j>=0;j=listP->next[j]) {
LOG_T(MAC,"node %d => %d\n",j,listP->next[j]);
}
} else {
for (j=listP->head_ul;j>=0;j=listP->next_ul[j]) {
LOG_T(MAC,"node %d => %d\n",j,listP->next_ul[j]);
}
}
}
int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP,int harq_pidP) {
......@@ -210,14 +215,15 @@ int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP,int harq_pidP) {
UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list;
LOG_D(MAC,"[eNB %d, CC_id %d] Adding UE with rnti %x (next avail %d, num_UEs %d)\n",mod_idP,cc_idP,rntiP,UE_list->avail,UE_list->num_UEs);
dump_ue_list(UE_list);
dump_ue_list(UE_list,0);
if (UE_list->avail>=0) {
UE_id = UE_list->avail;
UE_list->avail = UE_list->next[UE_list->avail];
UE_list->next[UE_id] = UE_list->head;
UE_list->next_ul[UE_id] = UE_list->head;
UE_list->head = UE_id;
UE_list->head_ul = UE_id;
UE_list->UE_template[cc_idP][UE_id].rnti = rntiP;
UE_list->UE_template[cc_idP][UE_id].configured = FALSE;
UE_list->numactiveCCs[UE_id] = 1;
......@@ -235,24 +241,24 @@ int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP,int harq_pidP) {
eNB_ulsch_info[mod_idP][UE_id].status = S_UL_WAITING;
eNB_dlsch_info[mod_idP][UE_id].status = S_UL_WAITING;
LOG_D(MAC,"[eNB %d] Add UE_id %d on Primary CC_id %d: rnti %x\n",mod_idP,UE_id,cc_idP,rntiP);
dump_ue_list(UE_list);
dump_ue_list(UE_list,0);
return(UE_id);
}
LOG_E(MAC,"error in add_new_ue(), could not find space in UE_list, Dumping UE list\n");
dump_ue_list(UE_list);
dump_ue_list(UE_list,0);
return(-1);
}
int mac_remove_ue(module_id_t mod_idP, int ue_idP) {
int prev,i;
int prev,i, ret=-1;
UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list;
int pCC_id = UE_PCCID(mod_idP,ue_idP);
LOG_I(MAC,"Removing UE %d from Primary CC_id %d (rnti %x)\n",ue_idP,pCC_id, UE_list->UE_template[pCC_id][ue_idP].rnti);
dump_ue_list(UE_list);
dump_ue_list(UE_list,0);
// clear all remaining pending transmissions
UE_list->UE_template[pCC_id][ue_idP].bsr_info[LCGID0] = 0;
......@@ -283,15 +289,32 @@ int mac_remove_ue(module_id_t mod_idP, int ue_idP) {
UE_list->avail = i;
UE_list->active[i] = FALSE;
UE_list->num_UEs--;
return(0);
ret=0;
break;
}
prev=i;
}
// do the same for UL
prev = UE_list->head_ul;
for (i=UE_list->head_ul;i>=0;i=UE_list->next_ul[i]) {
if (i == ue_idP) {
// link prev to next in Active list
if (prev==UE_list->head_ul)
UE_list->head_ul = UE_list->next_ul[i];
else
UE_list->next_ul[prev] = UE_list->next_ul[i];
// add UE id (i)to available
UE_list->next_ul[i] = UE_list->avail;
ret = 0;
break;
}
prev=i;
}
if (ret == 0)
return (0);
LOG_E(MAC,"error in mac_remove_ue(), could not find previous to %d in UE_list, should never happen, Dumping UE list\n",ue_idP);
dump_ue_list(UE_list);
dump_ue_list(UE_list,0);
mac_xface->macphy_exit("");
return(-1);
......@@ -299,43 +322,63 @@ int mac_remove_ue(module_id_t mod_idP, int ue_idP) {
int prev(UE_list_t *listP, int nodeP) {
int prev(UE_list_t *listP, int nodeP, int ul_flag) {
int j;
if (ul_flag == 0 ) {
if (nodeP==listP->head)
return(nodeP);
for (j=listP->head;j>=0;j=listP->next[j]) {
if (listP->next[j]==nodeP)
return(j);
}
} else {
if (nodeP==listP->head_ul)
return(nodeP);
for (j=listP->head_ul;j>=0;j=listP->next_ul[j]) {
if (listP->next_ul[j]==nodeP)
return(j);
}
}
LOG_E(MAC,"error in prev(), could not find previous to %d in UE_list, should never happen, Dumping UE list\n",nodeP);
dump_ue_list(listP);
LOG_E(MAC,"error in prev(), could not find previous to %d in UE_list %s, should never happen, Dumping UE list\n",
nodeP, (ul_flag == 0)? "DL" : "UL");
dump_ue_list(listP, ul_flag);
return(-1);
}
void swap_UEs(UE_list_t *listP,int nodeiP, int nodejP) {
void swap_UEs(UE_list_t *listP,int nodeiP, int nodejP, int ul_flag) {
int prev_i,prev_j,next_i,next_j;
LOG_D(MAC,"Swapping UE %d,%d\n",nodeiP,nodejP);
dump_ue_list(listP);
LOG_T(MAC,"Swapping UE %d,%d\n",nodeiP,nodejP);
dump_ue_list(listP,ul_flag);
prev_i = prev(listP,nodeiP);
prev_j = prev(listP,nodejP);
prev_i = prev(listP,nodeiP,ul_flag);
prev_j = prev(listP,nodejP,ul_flag);
if ((prev_i<0) || (prev_j<0))
mac_xface->macphy_exit("");
if (ul_flag == 0){
next_i = listP->next[nodeiP];
next_j = listP->next[nodejP];
LOG_D(MAC,"next_i %d, next_i, next_j %d, head %d\n",next_i,next_j,listP->head);
} else {
next_i = listP->next_ul[nodeiP];
next_j = listP->next_ul[nodejP];
}
LOG_T(MAC,"[%s] next_i %d, next_i, next_j %d, head %d \n",
(ul_flag == 0)? "DL" : "UL",
next_i,next_j,listP->head);
if (ul_flag == 0 ) {
if (next_i == nodejP) { // case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...
LOG_D(MAC,"Case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...\n");
LOG_T(MAC,"Case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...\n");
listP->next[nodeiP] = next_j;
listP->next[nodejP] = nodeiP;
......@@ -345,7 +388,7 @@ void swap_UEs(UE_list_t *listP,int nodeiP, int nodejP) {
listP->next[prev_i] = nodejP;
}
else if (next_j == nodeiP) { // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...
LOG_D(MAC,"Case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...\n");
LOG_T(MAC,"Case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...\n");
listP->next[nodejP] = next_i;
listP->next[nodeiP] = nodejP;
if (nodejP==listP->head) // case j i n(i)
......@@ -360,7 +403,7 @@ void swap_UEs(UE_list_t *listP,int nodeiP, int nodejP) {
if (nodeiP==listP->head) {
LOG_D(MAC,"changing head to %d\n",nodejP);
LOG_T(MAC,"changing head to %d\n",nodejP);
listP->head=nodejP;
listP->next[prev_j] = nodeiP;
}
......@@ -374,9 +417,51 @@ void swap_UEs(UE_list_t *listP,int nodeiP, int nodejP) {
listP->next[prev_j] = nodeiP;
}
}
} else { // ul_flag
if (next_i == nodejP) { // case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...
LOG_T(MAC,"[UL] Case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...\n");
LOG_D(MAC,"After swap\n");
dump_ue_list(listP);
listP->next_ul[nodeiP] = next_j;
listP->next_ul[nodejP] = nodeiP;
if (nodeiP==listP->head_ul) // case i j n(j)
listP->head_ul = nodejP;
else
listP->next_ul[prev_i] = nodejP;
}
else if (next_j == nodeiP) { // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...
LOG_T(MAC,"[UL]Case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...\n");
listP->next_ul[nodejP] = next_i;
listP->next_ul[nodeiP] = nodejP;
if (nodejP==listP->head_ul) // case j i n(i)
listP->head_ul = nodeiP;
else
listP->next_ul[prev_j] = nodeiP;
}
else { // case ... p(i) i n(i) ... p(j) j n(j) ...
listP->next_ul[nodejP] = next_i;
listP->next_ul[nodeiP] = next_j;
if (nodeiP==listP->head_ul) {
LOG_T(MAC,"[UL]changing head to %d\n",nodejP);
listP->head_ul=nodejP;
listP->next_ul[prev_j] = nodeiP;
}
else if (nodejP==listP->head_ul){
LOG_T(MAC,"[UL]changing head to %d\n",nodeiP);
listP->head_ul=nodeiP;
listP->next_ul[prev_i] = nodejP;
}
else {
listP->next_ul[prev_i] = nodejP;
listP->next_ul[prev_j] = nodeiP;
}
}
}
LOG_T(MAC,"After swap\n");
dump_ue_list(listP,ul_flag);
}
void SR_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, rnti_t rntiP, sub_frame_t subframeP) {
......
This diff is collapsed.
......@@ -90,6 +90,7 @@ extern int cqi_to_mcs[16];
extern uint32_t RRC_CONNECTION_FLAG;
extern uint8_t rb_table[33];
extern DCI0_5MHz_TDD_1_6_t UL_alloc_pdu;
......
......@@ -157,11 +157,14 @@ int mac_top_init(int eMBMS_active, uint8_t cba_group_active, uint8_t HO_active){
UE_list->num_UEs=0;
UE_list->head=-1;
UE_list->head_ul=-1;
UE_list->avail=0;
for (list_el=0;list_el<NUMBER_OF_UE_MAX-1;list_el++) {
UE_list->next[list_el]=list_el+1;
UE_list->next_ul[list_el]=list_el+1;
}
UE_list->next[list_el]=-1;
UE_list->next_ul[list_el]=-1;
#ifdef PHY_EMUL
Mac_rlc_xface->Is_cluster_head[Mod_id]=2;//0: MR, 1: CH, 2: not CH neither MR
......@@ -481,6 +484,7 @@ int l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, uint8_t cba_group_
#ifdef CBA
mac_xface->phy_config_cba_rnti = phy_config_cba_rnti ;
#endif
mac_xface->estimate_ue_tx_power = estimate_ue_tx_power;
mac_xface->phy_config_meas_ue = phy_config_meas_ue;
mac_xface->phy_reset_ue = phy_reset_ue;
......
......@@ -224,13 +224,13 @@ void assign_rbs_required (module_id_t Mod_id,
// This function scans all CC_ids for a particular UE to find the maximum round index of its HARQ processes
int maxround(module_id_t Mod_id,uint16_t rnti,int frame,sub_frame_t subframe) {
int maxround(module_id_t Mod_id,uint16_t rnti,int frame,sub_frame_t subframe,uint8_t ul_flag ) {
uint8_t round,round_max=0,harq_pid;
int CC_id;
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++){
mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frame,subframe,&harq_pid,&round,0);
mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frame,subframe,&harq_pid,&round,ul_flag);
if (round > round_max)
round_max = round;
}
......@@ -279,7 +279,7 @@ void sort_UEs (module_id_t Mod_idP,
UE_id1 = i;
pCC_id1 = UE_PCCID(Mod_idP,UE_id1);
cqi1 = maxcqi(Mod_idP,rnti1); //
round1 = maxround(Mod_idP,rnti1,frameP,subframeP);
round1 = maxround(Mod_idP,rnti1,frameP,subframeP,0);
for(ii=UE_list->next[i];ii>=0;ii=UE_list->next[ii]){
......@@ -290,11 +290,11 @@ void sort_UEs (module_id_t Mod_idP,
continue;
cqi2 = maxcqi(Mod_idP,rnti2);
round2 = maxround(Mod_idP,rnti2,frameP,subframeP); //mac_xface->get_ue_active_harq_pid(Mod_id,rnti2,subframe,&harq_pid2,&round2,0);
round2 = maxround(Mod_idP,rnti2,frameP,subframeP,0); //mac_xface->get_ue_active_harq_pid(Mod_id,rnti2,subframe,&harq_pid2,&round2,0);
pCC_id2 = UE_PCCID(Mod_idP,UE_id2);
if(round2 > round1){ // Check first if one of the UEs has an active HARQ process which needs service and swap order
swap_UEs(UE_list,UE_id1,UE_id2);
swap_UEs(UE_list,UE_id1,UE_id2,0);
}
else if (round2 == round1){
// RK->NN : I guess this is for fairness in the scheduling. This doesn't make sense unless all UEs have the same configuration of logical channels. This should be done on the sum of all information that has to be sent. And still it wouldn't ensure fairness. It should be based on throughput seen by each UE or maybe using the head_sdu_creation_time, i.e. swap UEs if one is waiting longer for service.
......@@ -306,18 +306,18 @@ void sort_UEs (module_id_t Mod_idP,
if ( (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] + UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2]) <
(UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] + UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2]) ){
swap_UEs(UE_list,UE_id1,UE_id2);
swap_UEs(UE_list,UE_id1,UE_id2,0);
}
else if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max <
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max ){
swap_UEs(UE_list,UE_id1,UE_id2);
swap_UEs(UE_list,UE_id1,UE_id2,0);