Commit 663b1d8b authored by Xu Bo's avatar Xu Bo

fix bugs for hundreds_of_ues(UE SCD)

parent 741c87c0
......@@ -63,6 +63,9 @@
#include "signals.h"
#include "timer.h"
#ifdef UE_EXPANSION
#include "log.h"
#endif
#ifdef RTAI
# include <rtai.h>
......@@ -455,7 +458,21 @@ int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, Me
/* Enqueue message in destination task queue */
if (lfds611_queue_enqueue(itti_desc.tasks[destination_task_id].message_queue, new) == 0) {
#ifdef UE_EXPANSION
LOG_I(UDP_, " Assertion Message %s(id:%d), number %lu with priority %d can not be sent from (%u:%s) to queue (%u:%s). discarding...\n",
itti_desc.messages_info[message_id].name,
message_id,
message_number,
priority,
origin_task_id,
itti_get_task_name(origin_task_id),
destination_task_id,
itti_get_task_name(destination_task_id));
int result = itti_free(origin_task_id, message);
AssertFatal( result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
#else
AssertFatal(0, "Error: lfds611_queue_enqueue returns 0, queue is full, exiting\n");
#endif
}
#if defined(OAI_EMU) || defined(RTAI)
......@@ -625,7 +642,14 @@ static inline void itti_receive_msg_internal_event_fd(task_id_t task_id, uint8_t
if (lfds611_queue_dequeue (itti_desc.tasks[task_id].message_queue, (void **) &message) == 0) {
/* No element in list -> this should not happen */
#ifdef UE_EXPANSION
LOG_I(UDP_, "Assertion No message in queue for task %d while there are %d events and some for the messages queue!\n", task_id, epoll_ret);
/* Mark that the event has been processed */
itti_desc.threads[thread_id].events[i].events &= ~EPOLLIN;
return;
#else
AssertFatal (0, "No message in queue for task %d while there are %d events and some for the messages queue!\n", task_id, epoll_ret);
#endif
}
AssertFatal(message != NULL, "Message from message queue is NULL!\n");
......
......@@ -2639,8 +2639,15 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu
ulsch->harq_processes[harq_pid]->Or1 = 0;
ulsch->harq_processes[harq_pid]->Or2 = 0;
}
#ifndef UE_EXPANSION
else ulsch->harq_processes[harq_pid]->round++;
#else
else {
ulsch->harq_processes[harq_pid]->round++;
ulsch->harq_processes[harq_pid]->TBS = ulsch_pdu->ulsch_pdu_rel8.size<<3;
ulsch->harq_processes[harq_pid]->Msc_initial = 12*ulsch_pdu->ulsch_pdu_rel8.number_of_resource_blocks;
}
#endif
ulsch->rnti = ulsch_pdu->ulsch_pdu_rel8.rnti;
LOG_D(PHY,"Filling ULSCH %x (UE_id %d) (new_ulsch %d) for Frame %d, Subframe %d : harq_pid %d, first_rb %d, nb_rb %d, rvidx %d, Qm %d, TBS %d, round %d \n",
ulsch->rnti,
......
......@@ -916,8 +916,9 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
G);
//#endif
#ifndef UE_EXPANSION
if (ulsch_harq->round == 0) {
#endif
// This is a new packet, so compute quantities regarding segmentation
ulsch_harq->B = A+24;
lte_segmentation(NULL,
......@@ -930,8 +931,9 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
&ulsch_harq->Kminus,
&ulsch_harq->F);
// CLEAR LLR's HERE for first packet in process
#ifndef UE_EXPANSION
}
#endif
// printf("after segmentation c[%d] = %p\n",0,ulsch_harq->c[0]);
sumKr = 0;
......
......@@ -549,7 +549,7 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id,
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer++;
// check threshold
if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 200) {
if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 20000) {
// inform RRC of failure and clear timer
LOG_I(MAC,
"UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n",
......@@ -724,7 +724,9 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP,
}
#endif
#ifdef UE_EXPANSION
memset(dlsch_ue_select, 0, sizeof(dlsch_ue_select));
#endif
// This schedules MIB
if ((subframeP == 0) && (frameP & 3) == 0)
schedule_mib(module_idP, frameP, subframeP);
......
......@@ -507,6 +507,13 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP,
TX_req->segments[0].segment_data =
cc[CC_idP].RAR_pdu.payload;
mac->TX_req[CC_idP].tx_request_body.number_of_pdus++;
#ifdef UE_EXPANSION
dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].ue_priority = SCH_DL_MSG2;
dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].nb_rb = 4;
dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].UE_id = -1;
dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].rnti = ra->rnti;
dlsch_ue_select[CC_idP].ue_num++;
#endif
}
}
......@@ -634,6 +641,13 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP,
TX_req->segments[0].segment_data =
cc[CC_idP].RAR_pdu.payload;
mac->TX_req[CC_idP].tx_request_body.number_of_pdus++;
#ifdef UE_EXPANSION
dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].ue_priority = SCH_DL_MSG2;
dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].nb_rb = 4;
dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].UE_id = -1;
dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].rnti = ra->rnti;
dlsch_ue_select[CC_idP].ue_num++;
#endif
} // PDCCH CCE allocation is feasible
} // Msg2 frame/subframe condition
} // else BL/CE
......@@ -1092,6 +1106,13 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP,
UE_id),
rrc_sdu_length);
}
#ifdef UE_EXPANSION
dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].ue_priority = SCH_DL_MSG4;
dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].nb_rb = 4;
dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].UE_id = UE_id;
dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].rnti = ra->rnti;
dlsch_ue_select[CC_idP].ue_num++;
#endif
} // Msg4 frame/subframe
} // msg4_mpdcch_repetition_count
} // rach_resource_type > 0
......@@ -1293,7 +1314,13 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP,
UE_id),
rrc_sdu_length);
}
#ifdef UE_EXPANSION
dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].ue_priority = SCH_DL_MSG4;
dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].nb_rb = 4;
dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].UE_id = UE_id;
dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].rnti = ra->rnti;
dlsch_ue_select[CC_idP].ue_num++;
#endif
} // CCE Allocation feasible
} // msg4 frame/subframe
} // else rach_resource_type
......@@ -1431,6 +1458,13 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP,
(cc->p_eNB == 1) ? 1 : 2, // transmission mode
1, // num_bf_prb_per_subband
1); // num_bf_vector
#ifdef UE_EXPANSION
dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].ue_priority = SCH_DL_MSG4;
dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].nb_rb = 4;
dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].UE_id = UE_id;
dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].rnti = ra->rnti;
dlsch_ue_select[CC_idP].ue_num++;
#endif
} else
LOG_D(MAC,
"msg4 retransmission for rnti %x (round %d) fsf %d/%d CCE allocation failed!\n",
......
......@@ -511,10 +511,6 @@ schedule_ue_spec(module_id_t module_idP,
}
}
#ifdef UE_EXPANSION
DLSCH_UE_SELECT dlsch_ue_select[MAX_NUM_CCs];
memset(dlsch_ue_select, 0, sizeof(dlsch_ue_select));
#endif
//weight = get_ue_weight(module_idP,UE_id);
aggregation = 2;
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
......@@ -546,11 +542,7 @@ schedule_ue_spec(module_id_t module_idP,
frameP,
subframeP,
N_RBG,
mbsfn_flag
#ifdef UE_EXPANSION
, dlsch_ue_select
#endif
);
mbsfn_flag);
stop_meas(&eNB->schedule_dlsch_preprocessor);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,VCD_FUNCTION_OUT);
......@@ -564,11 +556,52 @@ schedule_ue_spec(module_id_t module_idP,
#ifdef UE_EXPANSION
for (i = 0; i < dlsch_ue_select[CC_id].ue_num; i++) {
if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG2){
continue;
}
if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG4){
continue;
}
UE_id = dlsch_ue_select[CC_id].list[i].UE_id;
rnti = UE_RNTI(module_idP,UE_id);
if (rnti==NOT_A_RNTI) {
LOG_E(MAC,"Cannot find rnti for UE_id %d (num_UEs %d)\n",UE_id,UE_list->num_UEs);
continue;
}
eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
switch(get_tmode(module_idP,CC_id,UE_id)){
case 1:
case 2:
case 7:
aggregation = get_aggregation(get_bw_index(module_idP,CC_id),
ue_sched_ctl->dl_cqi[CC_id],
format1);
break;
case 3:
aggregation = get_aggregation(get_bw_index(module_idP,CC_id),
ue_sched_ctl->dl_cqi[CC_id],
format2A);
break;
default:
LOG_W(MAC,"Unsupported transmission mode %d\n", get_tmode(module_idP,CC_id,UE_id));
aggregation = 2;
break;
}
if (cc[CC_id].tdd_Config != NULL) { //TDD
set_ue_dai (subframeP,
UE_id,
CC_id,
cc[CC_id].tdd_Config->subframeAssignment,
UE_list);
// update UL DAI after DLSCH scheduling
set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP);
}
#else
for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
#endif
continue_flag=0; // reset the flag to allow allocation for the remaining UEs
rnti = UE_RNTI(module_idP,UE_id);
......@@ -632,6 +665,7 @@ schedule_ue_spec(module_id_t module_idP,
CC_id, UE_id, subframeP, S_DL_NONE);
continue;
}
#endif
#warning RK->CR This old API call has to be revisited for FAPI, or logic must be changed
#if 0
/* add "fake" DCI to have CCE_allocation_infeasible work properly for next allocations */
......@@ -1415,7 +1449,9 @@ schedule_ue_spec(module_id_t module_idP,
eNB->pdu_index[CC_id]++;
program_dlsch_acknak(module_idP,CC_id,UE_id,frameP,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx);
#ifdef UE_EXPANSION
last_dlsch_ue_id[CC_id] = UE_id;
#endif
}
else {
LOG_W(MAC,"Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d/%x, infeasible CCE allocations\n",
......@@ -1434,11 +1470,7 @@ schedule_ue_spec(module_id_t module_idP,
} // CC_id loop
#ifndef UE_EXPANSION
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_flag);
#else
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_flag,dlsch_ue_select);
#endif
stop_meas(&eNB->schedule_dlsch);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,VCD_FUNCTION_OUT);
......@@ -1451,11 +1483,7 @@ fill_DLSCH_dci(
module_id_t module_idP,
frame_t frameP,
sub_frame_t subframeP,
int* mbsfn_flagP
#ifdef UE_EXPANSION
, DLSCH_UE_SELECT dlsch_ue_select[MAX_NUM_CCs]
#endif
)
int* mbsfn_flagP)
//------------------------------------------------------------------------------
{
......@@ -1495,7 +1523,13 @@ fill_DLSCH_dci(
// UE specific DCIs
#ifdef UE_EXPANSION
for (j = 0; j < dlsch_ue_select[CC_id].ue_num; j++) {
UE_id = dlsch_ue_select[CC_id].list[j].UE_id;
if(dlsch_ue_select[CC_id].list[j].ue_priority == SCH_DL_MSG2){
continue;
}
if(dlsch_ue_select[CC_id].list[j].ue_priority == SCH_DL_MSG4){
continue;
}
UE_id = dlsch_ue_select[CC_id].list[j].UE_id;
#else
for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
#endif
......
......@@ -933,10 +933,12 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP,
int CC_id;
eNB_MAC_INST *mac = RC.mac[module_idP];
COMMON_channels_t *cc;
int sched_frame=frameP;
start_meas(&mac->schedule_ulsch);
int sched_subframe = (subframeP+4)%10;
if (sched_subframe < subframeP) sched_frame++;
cc = &mac->common_channels[0];
int tdd_sfa;
......@@ -1051,7 +1053,7 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP,
}
//PRACH
if (is_prach_subframe(frame_parms,frameP,subframeP)==1) {
if (is_prach_subframe(frame_parms,sched_frame,sched_subframe)==1) {
ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ue_priority = SCH_UL_PRACH;
ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = get_prach_prb_offset(
frame_parms,
......
......@@ -102,6 +102,7 @@ extern DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu2;
extern DCI1E_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu1E;
#ifdef UE_EXPANSION
extern DLSCH_UE_SELECT dlsch_ue_select[MAX_NUM_CCs];
extern int last_dlsch_ue_id[MAX_NUM_CCs];
extern int last_ulsch_ue_id[MAX_NUM_CCs];
#endif
......
......@@ -117,13 +117,6 @@ store_dlsch_buffer(module_id_t Mod_id, frame_t frameP,
UE_template->dl_buffer_total = 0;
UE_template->dl_pdus_total = 0;
for (i = 0; i < MAX_NUM_LCID; i++) {
UE_template->dl_buffer_info[i] = 0;
UE_template->dl_pdus_in_buffer[i] = 0;
UE_template->dl_buffer_head_sdu_creation_time[i] = 0;
UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = 0;
}
rnti = UE_RNTI(Mod_id, UE_id);
for (i = 0; i < MAX_NUM_LCID; i++) { // loop over all the logical channels
......@@ -551,6 +544,18 @@ void sort_UEs(module_id_t Mod_idP, int frameP, sub_frame_t subframeP)
}
#ifdef UE_EXPANSION
int cc_id_end(uint8_t *cc_id_flag )
{
int end_flag = 1;
for (int CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
if (cc_id_flag[CC_id]==0) {
end_flag = 0;
break;
}
}
return end_flag;
}
void dlsch_scheduler_pre_ue_select(
module_id_t module_idP,
frame_t frameP,
......@@ -559,43 +564,31 @@ void dlsch_scheduler_pre_ue_select(
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
DLSCH_UE_SELECT dlsch_ue_select[MAX_NUM_CCs])
{
uint8_t CC_id;
int UE_id;
// uint16_t nb_rb;
unsigned char round = 0;
unsigned char harq_pid = 0;
eNB_MAC_INST *eNB = RC.mac[module_idP];
COMMON_channels_t *cc = eNB->common_channels;
UE_list_t *UE_list = &eNB->UE_list;
UE_sched_ctrl *ue_sched_ctl;
uint8_t CC_id;
int UE_id;
unsigned char round = 0;
unsigned char harq_pid = 0;
rnti_t rnti;
uint16_t i;
unsigned char aggregation;
// int i;
// int N_RB_DL[MAX_NUM_CCs];
uint16_t used_dlsch_rbs_num[MAX_NUM_CCs] = {0};
uint16_t available_dlsch_rbs_num[MAX_NUM_CCs] = {0};
uint16_t dl_ue_max_num[MAX_NUM_CCs] = {0};
uint16_t dlsch_ue_max_num[MAX_NUM_CCs] = {0};
int format_flag;
nfapi_dl_config_request_body_t *DL_req;
nfapi_dl_config_request_pdu_t *dl_config_pdu;
uint16_t dlsch_ue_max_num[MAX_NUM_CCs] = {0};
uint16_t saved_dlsch_dci[MAX_NUM_CCs] = {0};
int continue_flag = 0;
int old_last_dlsch_ue_id[MAX_NUM_CCs];
uint8_t end_flag[MAX_NUM_CCs] = {0};
// Initialization
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
// get maximum UE number of DLSCH
dl_ue_max_num[CC_id] = NUMBER_OF_UE_MAX;
dlsch_ue_max_num[CC_id] = (uint16_t)RC.rrc[module_idP]->configuration.ue_multiple_max[CC_id];
// save origin DL PDU number
DL_req = &eNB->DL_req[CC_id].dl_config_request_body;
saved_dlsch_dci[CC_id] = DL_req->number_pdu;
// set available_dlsch_rbs
available_dlsch_rbs_num[CC_id] = eNB->eNB_stats[CC_id].available_prbs;
// get last DLSCH ue_id
old_last_dlsch_ue_id[CC_id] = last_dlsch_ue_id[CC_id];
}
// Insert DLSCH(retransmission) UE into selected UE list
......@@ -605,7 +598,7 @@ void dlsch_scheduler_pre_ue_select(
}
DL_req = &eNB->DL_req[CC_id].dl_config_request_body;
for (UE_id = 0; UE_id < dl_ue_max_num[CC_id] /*NUMBER_OF_UE_MAX*/; UE_id++) {
for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
if (UE_list->active[UE_id] == FALSE) {
continue;
}
......@@ -620,15 +613,14 @@ void dlsch_scheduler_pre_ue_select(
continue;
}
if (nb_rbs_required[CC_id][UE_id] == 0) {
continue;
}
if (cc[CC_id].tdd_Config) harq_pid = ((frameP*10)+subframeP)%10;
else harq_pid = ((frameP*10)+subframeP)&7;
round = ue_sched_ctl->round[CC_id][harq_pid];
if (round != 8) { // retransmission
if(UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] == 0){
continue;
}
switch (get_tmode(module_idP, CC_id, UE_id)) {
case 1:
case 2:
......@@ -667,12 +659,8 @@ void dlsch_scheduler_pre_ue_select(
dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].rnti = rnti;
dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].nb_rb = nb_rbs_required[CC_id][UE_id];
dlsch_ue_select[CC_id].ue_num++;
used_dlsch_rbs_num[CC_id] += nb_rbs_required[CC_id][UE_id];
if (dlsch_ue_select[CC_id].ue_num == dlsch_ue_max_num[CC_id]) {
break;
}
if (used_dlsch_rbs_num[CC_id] > available_dlsch_rbs_num[CC_id]) {
dlsch_ue_select[CC_id].ue_num--; // roll back
end_flag[CC_id] = 1;
break;
}
} else {
......@@ -691,22 +679,29 @@ void dlsch_scheduler_pre_ue_select(
UE_id,
subframeP,
S_DL_NONE);
end_flag[CC_id] = 1;
break;
}
}
}
}
if(cc_id_end(end_flag) == 1){
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
DL_req = &eNB->DL_req[CC_id].dl_config_request_body;
DL_req->number_pdu = saved_dlsch_dci[CC_id];
}
return;
}
// Insert DLSCH(first transmission) UE into selected UE list (UE_id > last_dlsch_ue_id[CC_id])
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
if (mbsfn_flag[CC_id]>0) {
continue;
}
if (mbsfn_flag[CC_id]>0) {
continue;
}
if (dlsch_ue_select[CC_id].ue_num < dlsch_ue_max_num[CC_id] &&
used_dlsch_rbs_num[CC_id] < available_dlsch_rbs_num[CC_id]) {
DL_req = &eNB->DL_req[CC_id].dl_config_request_body;
for (UE_id = (old_last_dlsch_ue_id[CC_id]+1); UE_id < dl_ue_max_num[CC_id]; UE_id++) {
if (dlsch_ue_select[CC_id].ue_num >= dlsch_ue_max_num[CC_id]) {
for (UE_id = (last_dlsch_ue_id[CC_id]+1); UE_id <NUMBER_OF_UE_MAX; UE_id++) {
if(end_flag[CC_id] == 1){
break;
}
......@@ -723,16 +718,22 @@ void dlsch_scheduler_pre_ue_select(
continue;
}
continue_flag = 0;
if (nb_rbs_required[CC_id][UE_id] == 0) {
continue_flag = 1;
} else {
if (cc[CC_id].tdd_Config) harq_pid = ((frameP*10)+subframeP)%10;
else harq_pid = ((frameP*10)+subframeP)&7;
for(i = 0;i<dlsch_ue_select[CC_id].ue_num;i++){
if(dlsch_ue_select[CC_id].list[i].UE_id == UE_id){
break;
}
}
if(i < dlsch_ue_select[CC_id].ue_num)
continue;
round = ue_sched_ctl->round[CC_id][harq_pid];
if (round == 8) {
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
if (cc[CC_id].tdd_Config) harq_pid = ((frameP*10)+subframeP)%10;
else harq_pid = ((frameP*10)+subframeP)&7;
round = ue_sched_ctl->round[CC_id][harq_pid];
if (round == 8) {
if (nb_rbs_required[CC_id][UE_id] == 0) {
continue;
}
switch (get_tmode(module_idP, CC_id, UE_id)) {
case 1:
case 2:
......@@ -749,6 +750,7 @@ void dlsch_scheduler_pre_ue_select(
default:
LOG_W(MAC,"Unsupported transmission mode %d\n", get_tmode(module_idP,CC_id,UE_id));
aggregation = 2;
break;
}
format_flag = 1;
if (!CCE_allocation_infeasible(module_idP,
......@@ -770,45 +772,49 @@ void dlsch_scheduler_pre_ue_select(
dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].UE_id = UE_id;
dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].rnti = rnti;
dlsch_ue_select[CC_id].ue_num++;
last_dlsch_ue_id[CC_id] = UE_id;
} else {
continue_flag = 1;
}
}
}
if (continue_flag == 1) {
if (cc[CC_id].tdd_Config != NULL) { //TDD
set_ue_dai (subframeP,
UE_id,
CC_id,
cc[CC_id].tdd_Config->subframeAssignment,
UE_list);
// update UL DAI after DLSCH scheduling
set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP);
}
add_ue_dlsch_info(module_idP,
if (dlsch_ue_select[CC_id].ue_num == dlsch_ue_max_num[CC_id]) {
end_flag[CC_id] = 1;
break;
}
}else {
if (cc[CC_id].tdd_Config != NULL) { //TDD
set_ue_dai (subframeP,
UE_id,
CC_id,
cc[CC_id].tdd_Config->subframeAssignment,
UE_list);
// update UL DAI after DLSCH scheduling
set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP);
}
add_ue_dlsch_info(module_idP,
CC_id,
UE_id,
subframeP,
S_DL_NONE);
}
end_flag[CC_id] = 1;
break;
}
}
}
}
if(cc_id_end(end_flag) == 1){
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
DL_req = &eNB->DL_req[CC_id].dl_config_request_body;
DL_req->number_pdu = saved_dlsch_dci[CC_id];
}
return;
}
// Insert DLSCH(first transmission) UE into selected UE list (UE_id <= last_dlsch_ue_id[CC_id])
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
if (mbsfn_flag[CC_id]>0) {
continue;
}
if (mbsfn_flag[CC_id]>0) {
continue;
}
if (dlsch_ue_select[CC_id].ue_num < dlsch_ue_max_num[CC_id] &&
used_dlsch_rbs_num[CC_id] < available_dlsch_rbs_num[CC_id]) {
DL_req = &eNB->DL_req[CC_id].dl_config_request_body;
for (UE_id = 0; UE_id <= old_last_dlsch_ue_id[CC_id]; UE_id++) {
if (dlsch_ue_select[CC_id].ue_num >= dlsch_ue_max_num[CC_id]) {
for (UE_id = 0; UE_id <= last_dlsch_ue_id[CC_id]; UE_id++) {
if(end_flag[CC_id] == 1){
break;
}
......@@ -825,16 +831,22 @@ void dlsch_scheduler_pre_ue_select(
continue;
}
continue_flag = 0;
if (nb_rbs_required[CC_id][UE_id] == 0) {
continue_flag = 1;
} else {
if (cc[CC_id].tdd_Config) harq_pid = ((frameP*10)+subframeP)%10;
else harq_pid = ((frameP*10)+subframeP)&7;
for(i = 0;i<dlsch_ue_select[CC_id].ue_num;i++){
if(dlsch_ue_select[CC_id].list[i].UE_id == UE_id){
break;
}
}
if(i < dlsch_ue_select[CC_id].ue_num)
continue;
round = ue_sched_ctl->round[CC_id][harq_pid];
if (round == 8) {
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
if (cc[CC_id].tdd_Config) harq_pid = ((frameP*10)+subframeP)%10;
else harq_pid = ((frameP*10)+subframeP)&7;
round = ue_sched_ctl->round[CC_id][harq_pid];
if (round == 8) {
if (nb_rbs_required[CC_id][UE_id] == 0) {
continue;
}
switch (get_tmode(module_idP, CC_id, UE_id)) {
case 1:
case 2:
......@@ -851,6 +863,7 @@ void dlsch_scheduler_pre_ue_select(
default:
LOG_W(MAC,"Unsupported transmission mode %d\n", get_tmode(module_idP,CC_id,UE_id));
aggregation = 2;
break;
}
format_flag = 1;
if (!CCE_allocation_infeasible(module_idP,
......@@ -872,30 +885,29 @@ void dlsch_scheduler_pre_ue_select(
dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].UE_id = UE_id;
dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].rnti = rnti;
dlsch_ue_select[CC_id].ue_num++;
last_dlsch_ue_id[CC_id] = UE_id;
} else {
continue_flag = 1;
}
}
}
if (continue_flag == 1) {
if (cc[CC_id].tdd_Config != NULL) { //TDD
set_ue_dai (subframeP,
UE_id,
CC_id,
cc[CC_id].tdd_Config->subframeAssignment,
UE_list);
// update UL DAI after DLSCH scheduling
set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP);
}
if (dlsch_ue_select[CC_id].ue_num == dlsch_ue_max_num[CC_id]) {
end_flag[CC_id] = 1;
break;
}
} else {
if (cc[CC_id].tdd_Config != NULL) { //TDD
set_ue_dai (subframeP,
UE_id,
CC_id,
cc[CC_id].tdd_Config->subframeAssignment,
UE_list);
// update UL DAI after DLSCH scheduling
set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP);
}
add_ue_dlsch_info(module_idP,
CC_id,
UE_id,
subframeP,
S_DL_NONE);
}
end_flag[CC_id] = 1;
break;
}
}
}
}
......@@ -904,6 +916,7 @@ void dlsch_scheduler_pre_ue_select(
DL_req = &eNB->DL_req[CC_id].dl_config_request_body;
DL_req->number_pdu = saved_dlsch_dci[CC_id];
}
return;
}
......@@ -916,11 +929,7 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id,
frame_t frameP,
sub_frame_t subframeP,
int N_RBG[MAX_NUM_CCs],
int *mbsfn_flag
#ifdef UE_EXPANSION
, DLSCH_UE_SELECT dlsch_ue_select[MAX_NUM_CCs]
#endif
)
int *mbsfn_flag)
{
#ifndef UE_EXPANSION
......@@ -931,6 +940,8 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id,
// int rrc_status = RRC_IDLE;
#else
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],harq_pid=0,Round=0;
uint16_t temp_total_rbs_count;
unsigned char temp_total_ue_count;
#endif
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX];
int UE_id, i;
......@@ -962,11 +973,6 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id,
UE_sched_ctrl *ue_sched_ctl1, *ue_sched_ctl2;
#endif
#ifdef UE_EXPANSION
uint16_t temp_total_rbs_count;
unsigned char temp_total_ue_count;
#endif
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
if (mbsfn_flag[CC_id] > 0) // If this CC is allocated for MBSFN skip it here
......@@ -1031,14 +1037,23 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id,
temp_total_ue_count = dlsch_ue_select[CC_id].ue_num;
for (i = 0; i < dlsch_ue_select[CC_id].ue_num; i++) {
if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG2){
temp_total_ue_count--;
continue;
}
if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG4){
temp_total_ue_count--;
continue;
}
UE_id = dlsch_ue_select[CC_id].list[i].UE_id;
nb_rbs_required[CC_id][UE_id] = dlsch_ue_select[CC_id].list[i].nb_rb;
if( (min_rb_unit[CC_id] * temp_total_ue_count) <= temp_total_rbs_count ) {
//average_rbs_per_user[CC_id] = ((uint16_t)round((double)temp_total_rbs_count/(double)(temp_total_ue_count*min_rb_unit[CC_id])))*min_rb_unit[CC_id];
average_rbs_per_user[CC_id] = (uint16_t)round((double)temp_total_rbs_count/(double)temp_total_ue_count);
} else {
average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; // consider the total number of use that can be scheduled UE
average_rbs_per_user[CC_id] = (uint16_t)round((double)temp_total_rbs_count/(double)temp_total_ue_count);
if( average_rbs_per_user[CC_id] < min_rb_unit[CC_id] ){
temp_total_ue_count--;
dlsch_ue_select[CC_id].ue_num--;
i--;
continue;
}
rnti = dlsch_ue_select[CC_id].list[i].rnti;
......@@ -1069,17 +1084,15 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id,
nb_rbs_required_remaining,
rballoc_sub,
MIMO_mode_indicator);
temp_total_rbs_count -= ue_sched_ctl->pre_nb_available_rbs[CC_id];
temp_total_ue_count--;
if (ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) {
last_dlsch_ue_id[CC_id] = dlsch_ue_select[CC_id].list[i-1].UE_id;
dlsch_ue_select[CC_id].ue_num = i;
break;
}
temp_total_rbs_count -= ue_sched_ctl->pre_nb_available_rbs[CC_id];
temp_total_ue_count--;
if (temp_total_rbs_count == 0) {
last_dlsch_ue_id[CC_id] = UE_id;
dlsch_ue_select[CC_id].ue_num = i+1;
break;
}
......@@ -1466,6 +1479,12 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id,
#ifdef UE_EXPANSION
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
for (i = 0; i < dlsch_ue_select[CC_id].ue_num; i++) {
if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG2){
continue;
}
if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG4){
continue;
}
UE_id = dlsch_ue_select[CC_id].list[i].UE_id;
ue_sched_ctl = &RC.mac[Mod_id]->UE_list.UE_sched_ctrl[UE_id];
#else
......@@ -2299,20 +2318,7 @@ void sort_ue_ul(module_id_t module_idP, int frameP, sub_frame_t subframeP)
}
#endif
}
#ifdef UE_EXPANSION
int ulsch_cc_id_end(uint8_t *cc_id_flag )
{
int end_flag = 1;
for (int CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
if (cc_id_flag[CC_id]==0) {
end_flag = 0;
break;
}
}
return end_flag;
}
void ulsch_scheduler_pre_ue_select(
module_id_t module_idP,
frame_t frameP,
......@@ -2323,6 +2329,7 @@ void ulsch_scheduler_pre_ue_select(
COMMON_channels_t *cc;
int CC_id,UE_id;
int ret;
uint16_t i;
uint8_t ue_first_num[MAX_NUM_CCs];
uint8_t first_ue_total[MAX_NUM_CCs][20];
uint8_t first_ue_id[MAX_NUM_CCs][20];
......@@ -2373,7 +2380,7 @@ void ulsch_scheduler_pre_ue_select(
if ( (ulsch_ue_select[CC_id].ue_num >= ulsch_ue_max_num[CC_id]) || (cc_id_flag[CC_id] == 1) ) {
cc_id_flag[CC_id] = 1;
HI_DCI0_req->number_of_dci = saved_ulsch_dci[CC_id];
ret = ulsch_cc_id_end(cc_id_flag);
ret = cc_id_end(cc_id_flag);
if ( ret == 0 ) {
continue;
}
......@@ -2479,7 +2486,7 @@ void ulsch_scheduler_pre_ue_select(
if ( (ulsch_ue_select[CC_id].ue_num >= ulsch_ue_max_num[CC_id]) || (cc_id_flag[CC_id] == 1) ) {
cc_id_flag[CC_id] = 1;
HI_DCI0_req->number_of_dci = saved_ulsch_dci[CC_id];
ret = ulsch_cc_id_end(cc_id_flag);
ret = cc_id_end(cc_id_flag);
if ( ret == 0 ) {
continue;
}
......@@ -2491,6 +2498,14 @@ void ulsch_scheduler_pre_ue_select(
if (UE_id > last_ulsch_ue_id[CC_id])
continue;
for(i = 0;i<ulsch_ue_select[CC_id].ue_num;i++){
if(ulsch_ue_select[CC_id].list[i].UE_id == UE_id){
break;
}
}
if(i < ulsch_ue_select[CC_id].ue_num)
continue;
HI_DCI0_req = &eNB->HI_DCI0_req[CC_id].hi_dci0_request_body;
//SR BSR
if ( (UE_list->UE_template[CC_id][UE_id].ul_total_buffer > 0) || (UE_list->UE_template[CC_id][UE_id].ul_SR > 0) ) {
......
......@@ -118,11 +118,7 @@ void schedule_ulsch_rnti(module_id_t module_idP, frame_t frameP, sub_frame_t sub
@param subframe Index of subframe
@param mbsfn_flag Indicates that this subframe is for MCH/MCCH
*/
#ifndef UE_EXPANSION
void fill_DLSCH_dci(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,int *mbsfn_flag);
#else
void fill_DLSCH_dci(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,int *mbsfn_flag, DLSCH_UE_SELECT dlsch_ue_select[MAX_NUM_CCs]);
#endif
/** \brief UE specific DLSCH scheduling. Retrieves next ue to be schduled from round-robin scheduler and gets the appropriate harq_pid for the subframe from PHY. If the process is active and requires a retransmission, it schedules the retransmission with the same PRB count and MCS as the first transmission. Otherwise it consults RLC for DCCH/DTCH SDUs (status with maximum number of available PRBS), builds the MAC header (timing advance sent by default) and copies
@param Mod_id Instance ID of eNB
......@@ -216,11 +212,7 @@ void dlsch_scheduler_pre_processor (module_id_t module_idP,
frame_t frameP,
sub_frame_t subframe,
int N_RBG[MAX_NUM_CCs],
int *mbsfn_flag
#ifdef UE_EXPANSION
, DLSCH_UE_SELECT dlsch_ue_select[MAX_NUM_CCs]
#endif
);
int *mbsfn_flag);
void dlsch_scheduler_pre_processor_allocate (module_id_t Mod_id,
......
......@@ -71,7 +71,7 @@ fill_rar(const module_id_t module_idP,
ra->timing_offset /= 16; //T_A = N_TA/16, where N_TA should be on a 30.72Msps
rar[0] = (uint8_t) (ra->timing_offset >> (2 + 4)); // 7 MSBs of timing advance + divide by 4
rar[1] = (uint8_t) (ra->timing_offset << (4 - 2)) & 0xf0; // 4 LSBs of timing advance + divide by 4
ra->msg3_first_rb = 6;
ra->msg3_first_rb = 1;
ra->msg3_nb_rb = 1;
uint16_t rballoc = mac_computeRIV(N_RB_UL, ra->msg3_first_rb, ra->msg3_nb_rb); // first PRB only for UL Grant
rar[1] |= (rballoc >> 7) & 7; // Hopping = 0 (bit 3), 3 MSBs of rballoc
......
......@@ -146,6 +146,7 @@ DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu2;
DCI1E_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu1E;
#ifdef UE_EXPANSION
DLSCH_UE_SELECT dlsch_ue_select[MAX_NUM_CCs];
int last_dlsch_ue_id[MAX_NUM_CCs] = {-1};
int last_ulsch_ue_id[MAX_NUM_CCs] = {-1};
#endif
......
......@@ -438,6 +438,14 @@ typedef struct eNB_RRC_UE_s {
uint32_t ul_failure_timer;
uint32_t ue_release_timer;
uint32_t ue_release_timer_thres;
#ifdef UE_EXPANSION
uint32_t ue_release_timer_s1;
uint32_t ue_release_timer_thres_s1;
uint32_t ue_release_timer_rrc;
uint32_t ue_release_timer_thres_rrc;
uint32_t ue_reestablishment_timer;
uint32_t ue_reestablishment_timer_thres;
#endif
} eNB_RRC_UE_t;
typedef uid_t ue_uid_t;
......
......@@ -333,26 +333,62 @@ rrc_rx_tx(
RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
if ((ctxt_pP->frame == 0) && (ctxt_pP->subframe==0)) {
if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) {
LOG_I(RRC,"UE rnti %x:S-TMSI %x failure timer %d/20000\n",
LOG_I(RRC,"UE rnti %x:S-TMSI %x failure timer %d/8\n",
ue_context_p->ue_context.rnti,
ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi,
ue_context_p->ue_context.ul_failure_timer);
}
else {
LOG_I(RRC,"UE rnti %x failure timer %d/20000\n",
LOG_I(RRC,"UE rnti %x failure timer %d/8\n",
ue_context_p->ue_context.rnti,
ue_context_p->ue_context.ul_failure_timer);
}
}
if (ue_context_p->ue_context.ul_failure_timer>0) {
ue_context_p->ue_context.ul_failure_timer++;
if (ue_context_p->ue_context.ul_failure_timer >= 20000) {
if (ue_context_p->ue_context.ul_failure_timer >= 8) {
// remove UE after 20 seconds after MAC has indicated UL failure
LOG_I(RRC,"Removing UE %x instance\n",ue_context_p->ue_context.rnti);
ue_to_be_removed = ue_context_p;
break;
}
}
#ifdef UE_EXPANSION
if (ue_context_p->ue_context.ue_release_timer_s1>0) {
ue_context_p->ue_context.ue_release_timer_s1++;
if (ue_context_p->ue_context.ue_release_timer_s1 >=
ue_context_p->ue_context.ue_release_timer_thres_s1) {
LOG_I(RRC,"Removing UE %x instance Because of UE_CONTEXT_RELEASE_COMMAND not received after %d ms from sending request\n",
ue_context_p->ue_context.rnti, ue_context_p->ue_context.ue_release_timer_thres_s1);
ue_to_be_removed = ue_context_p;
break;
}
}
if (ue_context_p->ue_context.ue_release_timer_rrc>0) {
ue_context_p->ue_context.ue_release_timer_rrc++;
if (ue_context_p->ue_context.ue_release_timer_rrc >=
ue_context_p->ue_context.ue_release_timer_thres_rrc) {
LOG_I(RRC,"Removing UE %x instance After UE_CONTEXT_RELEASE_Complete\n", ue_context_p->ue_context.rnti);
ue_to_be_removed = ue_context_p;
break;
}
}
if (ue_context_p->ue_context.ue_reestablishment_timer>0) {
ue_context_p->ue_context.ue_reestablishment_timer++;
if (ue_context_p->ue_context.ue_reestablishment_timer >=
ue_context_p->ue_context.ue_reestablishment_timer_thres) {
LOG_I(RRC,"UE %d reestablishment_timer max\n",ue_context_p->ue_context.rnti);
ue_context_p->ue_context.ul_failure_timer = 20000;
ue_to_be_removed = ue_context_p;
ue_context_p->ue_context.ue_reestablishment_timer = 0;
break;
}
}
#endif
if (ue_context_p->ue_context.ue_release_timer>0) {
ue_context_p->ue_context.ue_release_timer++;
if (ue_context_p->ue_context.ue_release_timer >=
......@@ -363,9 +399,17 @@ rrc_rx_tx(
}
}
}
if (ue_to_be_removed)
if (ue_to_be_removed) {
#ifdef UE_EXPANSION
if(ue_to_be_removed->ue_context.ul_failure_timer >= 8) {
ue_to_be_removed->ue_context.ue_release_timer_s1 = 1;
ue_to_be_removed->ue_context.ue_release_timer_thres_s1 = 100;
ue_to_be_removed->ue_context.ue_release_timer = 0;
ue_to_be_removed->ue_context.ue_reestablishment_timer = 0;
}
#endif
rrc_eNB_free_UE(ctxt_pP->module_id,ue_to_be_removed);
}
#ifdef RRC_LOCALIZATION
/* for the localization, only primary CC_id might be relevant*/
......
......@@ -571,6 +571,7 @@ rrc_eNB_get_next_free_ue_context(
ctxt_pP->rnti);
if (ue_context_p == NULL) {
#ifndef UE_EXPANSION
RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
if (ue_context_p->ue_context.random_ue_identity == ue_identityP) {
LOG_D(RRC,
......@@ -581,6 +582,7 @@ rrc_eNB_get_next_free_ue_context(
return NULL;
}
}
#endif
ue_context_p = rrc_eNB_allocate_new_UE_context(RC.rrc[ctxt_pP->module_id]);
if (ue_context_p == NULL) {
......@@ -778,7 +780,11 @@ rrc_eNB_free_UE(const module_id_t enb_mod_idP,const struct rrc_eNB_ue_context_s*
(void)ue_module_id;
#endif
rnti_t rnti = ue_context_pP->ue_context.rnti;
int i, j , CC_id, pdu_number;
LTE_eNB_ULSCH_t *ulsch = NULL;
nfapi_ul_config_request_body_t *ul_req_tmp = NULL;
PHY_VARS_eNB *eNB_PHY = NULL;
eNB_MAC_INST *eNB_MAC = RC.mac[enb_mod_idP];
AssertFatal(enb_mod_idP < NB_eNB_INST, "eNB inst invalid (%d/%d) for UE %x!", enb_mod_idP, NB_eNB_INST, rnti);
/* ue_context_p = rrc_eNB_get_ue_context(
......@@ -807,7 +813,33 @@ rrc_eNB_free_UE(const module_id_t enb_mod_idP,const struct rrc_eNB_ue_context_s*
oai_emulation.info.eNB_ue_module_id_to_rnti[enb_mod_idP][ue_module_id] = NOT_A_RNTI;
#endif
#endif
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
eNB_PHY = RC.eNB[enb_mod_idP][CC_id];
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
ulsch = eNB_PHY->ulsch[i];
if((ulsch != NULL) && (ulsch->rnti == rnti)){
LOG_I(RRC, "clean_eNb_ulsch UE %x \n", rnti);
clean_eNb_ulsch(ulsch);
break;
}
}
for(j = 0; j < 10; j++){
ul_req_tmp = &eNB_MAC->UL_req_tmp[CC_id][j].ul_config_request_body;
if(ul_req_tmp){
pdu_number = ul_req_tmp->number_of_pdus;
for(int pdu_index = pdu_number-1; pdu_index >= 0; pdu_index--){
if(ul_req_tmp->ul_config_pdu_list[pdu_index].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti){
LOG_I(RRC, "remove UE %x from ul_config_pdu_list %d/%d\n", rnti, pdu_index, pdu_number);
if(pdu_index < pdu_number -1){
memcpy(&ul_req_tmp->ul_config_pdu_list[pdu_index], &ul_req_tmp->ul_config_pdu_list[pdu_index+1], (pdu_number-1-pdu_index) * sizeof(nfapi_ul_config_request_pdu_t));
}
ul_req_tmp->number_of_pdus--;
}
}
}
}
}
rrc_mac_remove_ue(enb_mod_idP,rnti);
rrc_rlc_remove_ue(&ctxt);
pdcp_remove_UE(&ctxt);
......@@ -1085,10 +1117,20 @@ rrc_eNB_generate_RRCConnectionRelease(
memset(buffer, 0, RRC_BUF_SIZE);
size = do_RRCConnectionRelease(ctxt_pP->module_id, buffer,rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id));
#ifdef UE_EXPANSION
// set release timer
ue_context_pP->ue_context.ue_release_timer_rrc = 1;
// remove UE after 10 frames after RRCConnectionRelease is triggered
ue_context_pP->ue_context.ue_release_timer_thres_rrc = 100;
ue_context_pP->ue_context.ue_reestablishment_timer = 0;
ue_context_pP->ue_context.ue_release_timer = 0;
ue_context_pP->ue_context.ue_release_timer_s1 = 0;
#else
// set release timer
ue_context_pP->ue_context.ue_release_timer=1;
// remove UE after 10 frames after RRCConnectionRelease is triggered
ue_context_pP->ue_context.ue_release_timer_thres=100;
#endif
LOG_I(RRC,
PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate RRCConnectionRelease (bytes %d)\n",
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
......@@ -3805,10 +3847,17 @@ rrc_eNB_generate_RRCConnectionSetup(
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size);
#ifdef UE_EXPANSION
// activate release timer, if RRCSetupComplete not received after 100 frames, remove UE
ue_context_pP->ue_context.ue_release_timer=1;
// remove UE after 10 frames after RRCConnectionRelease is triggered
ue_context_pP->ue_context.ue_release_timer_thres=1000;
#else
// activate release timer, if RRCSetupComplete not received after 10 frames, remove UE
ue_context_pP->ue_context.ue_release_timer=1;
// remove UE after 10 frames after RRCConnectionRelease is triggered
ue_context_pP->ue_context.ue_release_timer_thres=100;
#endif
}
......@@ -4156,6 +4205,7 @@ rrc_eNB_decode_ccch(
/* if there is already a registered UE (with another RNTI) with this random_value,
* the current one must be removed from MAC/PHY (zombie UE)
*/
#ifndef UE_EXPANSION
if ((ue_context_p = rrc_eNB_ue_context_random_exist(ctxt_pP, random_value))) {
LOG_W(RRC, "new UE rnti %x (coming with random value) is already there as UE %x, removing %x from MAC/PHY\n",
ctxt_pP->rnti, ue_context_p->ue_context.rnti, ctxt_pP->rnti);
......@@ -4165,6 +4215,14 @@ rrc_eNB_decode_ccch(
} else {
ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP, random_value);
}
#else
if ((ue_context_p = rrc_eNB_ue_context_random_exist(ctxt_pP, random_value))) {
LOG_W(RRC, "new UE rnti %x (coming with random value) is already there as UE %x, removing %x from MAC/PHY\n",
ctxt_pP->rnti, ue_context_p->ue_context.rnti, ue_context_p->ue_context.rnti);
ue_context_p->ue_context.ul_failure_timer = 20000;
}
ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP, random_value);
#endif
} else if (InitialUE_Identity_PR_s_TMSI == rrcConnectionRequest->ue_Identity.present) {
/* Save s-TMSI */
S_TMSI_t s_TMSI = rrcConnectionRequest->ue_Identity.choice.s_TMSI;
......@@ -4185,6 +4243,11 @@ rrc_eNB_decode_ccch(
/* reset timers */
ue_context_p->ue_context.ul_failure_timer = 0;
ue_context_p->ue_context.ue_release_timer = 0;
#ifdef UE_EXPANSION
ue_context_p->ue_context.ue_reestablishment_timer = 0;
ue_context_p->ue_context.ue_release_timer_s1 = 0;
ue_context_p->ue_context.ue_release_timer_rrc = 0;
#endif
} else {
LOG_I(RRC," S-TMSI doesn't exist, setting Initialue_identity_s_TMSI.m_tmsi to %p => %x\n",ue_context_p,m_tmsi);
ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP, NOT_A_RANDOM_UE_IDENTITY);
......@@ -4451,6 +4514,11 @@ rrc_eNB_decode_dcch(
break;
case UL_DCCH_MessageType__c1_PR_measurementReport:
// to avoid segmentation fault
if(!ue_context_p){
LOG_I(RRC, "Processing measurementReport UE %x, ue_context_p is NULL\n", ctxt_pP->rnti);
break;
}
LOG_D(RRC,
PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND "
"%d bytes (measurementReport) ---> RRC_eNB\n",
......@@ -4465,6 +4533,11 @@ rrc_eNB_decode_dcch(
break;
case UL_DCCH_MessageType__c1_PR_rrcConnectionReconfigurationComplete:
// to avoid segmentation fault
if(!ue_context_p){
LOG_I(RRC, "Processing RRCConnectionReconfigurationComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti);
break;
}
#ifdef RRC_MSG_PRINT
LOG_F(RRC,"[MSG] RRC Connection Reconfiguration Complete\n");
......@@ -4573,9 +4646,19 @@ rrc_eNB_decode_dcch(
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
DCCH,
sdu_sizeP);
#ifdef UE_EXPANSION
ue_context_p->ue_context.ue_reestablishment_timer = 0;
#else
ue_context_p->ue_context.ue_release_timer = 0;
#endif
break;
case UL_DCCH_MessageType__c1_PR_rrcConnectionSetupComplete:
// to avoid segmentation fault
if(!ue_context_p){
LOG_I(RRC, "Processing RRCConnectionSetupComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti);
break;
}
#ifdef RRC_MSG_PRINT
LOG_F(RRC,"[MSG] RRC Connection SetupComplete\n");
......@@ -4633,7 +4716,11 @@ rrc_eNB_decode_dcch(
case UL_DCCH_MessageType__c1_PR_securityModeComplete:
T(T_ENB_RRC_SECURITY_MODE_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
// to avoid segmentation fault
if(!ue_context_p){
LOG_I(RRC, "Processing securityModeComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti);
break;
}
#ifdef RRC_MSG_PRINT
LOG_F(RRC,"[MSG] RRC Security Mode Complete\n");
......@@ -4718,7 +4805,11 @@ rrc_eNB_decode_dcch(
case UL_DCCH_MessageType__c1_PR_ueCapabilityInformation:
T(T_ENB_RRC_UE_CAPABILITY_INFORMATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
// to avoid segmentation fault
if(!ue_context_p){
LOG_I(RRC, "Processing ueCapabilityInformation UE %x, ue_context_p is NULL\n", ctxt_pP->rnti);
break;
}
#ifdef RRC_MSG_PRINT
LOG_F(RRC,"[MSG] RRC UECapablility Information \n");
......@@ -4797,7 +4888,11 @@ rrc_eNB_decode_dcch(
case UL_DCCH_MessageType__c1_PR_ulInformationTransfer:
T(T_ENB_RRC_UL_INFORMATION_TRANSFER, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
// to avoid segmentation fault
if(!ue_context_p){
LOG_I(RRC, "Processing ulInformationTransfer UE %x, ue_context_p is NULL\n", ctxt_pP->rnti);
break;
}
#ifdef RRC_MSG_PRINT
LOG_F(RRC,"[MSG] RRC UL Information Transfer \n");
......@@ -5044,6 +5139,12 @@ rrc_enb_task(
/* Nothing to do. Apparently everything is done in S1AP processing */
//LOG_I(RRC, "[eNB %d] Received message %s, not processed because procedure not synched\n",
//instance, msg_name_p);
#ifdef UE_EXPANSION
if (rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)) {
rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_rrc =
rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_thres_rrc;
}
#endif
break;
# endif
......
......@@ -1191,6 +1191,9 @@ int rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND (MessageDef *msg_p, const ch
}
return (-1);
} else {
#ifdef UE_EXPANSION
ue_context_p->ue_context.ue_release_timer_s1 = 0;
#endif
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0);
rrc_eNB_generate_RRCConnectionRelease(&ctxt, ue_context_p);
/*
......
......@@ -484,7 +484,11 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
s->tx_md.start_of_burst = false;
s->tx_md.end_of_burst = false;
}
if(flags==10){ // fail safe mode
s->tx_md.has_time_spec = false;
s->tx_md.start_of_burst = false;
s->tx_md.end_of_burst = true;
}
if (cc>1) {
std::vector<void *> buff_ptrs;
for (int i=0; i<cc; i++)
......
......@@ -667,6 +667,20 @@ void fh_if4p5_north_out(RU_t *ru) {
stop_meas(&ru->tx_fhaul);
}
/* add fail safe for late command */
typedef enum {
STATE_BURST_NORMAL = 0,
STATE_BURST_TERMINATE = 1,
STATE_BURST_STOP_1 = 2,
STATE_BURST_STOP_2 = 3,
STATE_BURST_RESTART = 4,
} late_control_e;
volatile late_control_e late_control=STATE_BURST_NORMAL;
/* add fail safe for late command end */
void rx_rf(RU_t *ru,int *frame,int *subframe) {
RU_proc_t *proc = &ru->proc;
......@@ -693,8 +707,12 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
proc->timestamp_rx = ts-ru->ts_offset;
AssertFatal(rxs == fp->samples_per_tti,
"rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_tti,rxs);
// AssertFatal(rxs == fp->samples_per_tti,
// "rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_tti,rxs);
if(rxs != fp->samples_per_tti){
LOG_E(PHY,"rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_tti,rxs);
late_control=STATE_BURST_TERMINATE;
}
if (proc->first_rx == 1) {
ru->ts_offset = proc->timestamp_rx;
......@@ -750,8 +768,8 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff );
if (rxs != fp->samples_per_tti)
exit_fun( "problem receiving samples" );
// if (rxs != fp->samples_per_tti)
// exit_fun( "problem receiving samples" );
......@@ -802,7 +820,33 @@ void tx_rf(RU_t *ru) {
for (i=0; i<ru->nb_tx; i++)
txp[i] = (void*)&ru->common.txdata[i][(proc->subframe_tx*fp->samples_per_tti)-sf_extension];
/* add fail safe for late command */
if(late_control!=STATE_BURST_NORMAL){//stop burst
switch (late_control) {
case STATE_BURST_TERMINATE:
flags=10; // end of burst and no time spec
late_control=STATE_BURST_STOP_1;
break;
case STATE_BURST_STOP_1:
flags=0; // no send
late_control=STATE_BURST_STOP_2;
return;//no send
break;
case STATE_BURST_STOP_2:
flags=0; // no send
late_control=STATE_BURST_RESTART;
return;//no send
break;
case STATE_BURST_RESTART:
flags=2; // start burst
late_control=STATE_BURST_NORMAL;
break;
}
}
/* add fail safe for late command end */
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_tx-ru->openair0_cfg.tx_sample_advance)&0xffffffff );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
......@@ -820,8 +864,11 @@ void tx_rf(RU_t *ru) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %d/%d)\n",txs, siglen);
// AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %d/%d)\n",txs, siglen);
if( (txs != siglen+sf_extension) && (late_control==STATE_BURST_NORMAL) ){ /* add fail safe for late command */
late_control=STATE_BURST_TERMINATE;
LOG_E(PHY,"TX : Timeout (sent %d/%d) state =%d\n",txs, siglen,late_control);
}
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment