Commit bb15ec4e authored by Raymond Knopp's avatar Raymond Knopp

Merge remote-tracking branch 'origin/develop' into ru_rau_enhancement

parents 0eb2f017 1272cabb
...@@ -280,7 +280,7 @@ set(protobuf_generated_dir ${OPENAIR_BIN_DIR}) ...@@ -280,7 +280,7 @@ set(protobuf_generated_dir ${OPENAIR_BIN_DIR})
# RRC # RRC
###### ######
add_list2_option(RRC_ASN1_VERSION "Rel10" "ASN.1 version of RRC interface" "Rel8" "Rel10" "CBA") add_list2_option(RRC_ASN1_VERSION "Rel14" "ASN.1 version of RRC interface" "Rel8" "Rel10" "Rel14" "CBA")
if (${RRC_ASN1_VERSION} STREQUAL "Rel8") if (${RRC_ASN1_VERSION} STREQUAL "Rel8")
set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-86.asn) set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-86.asn)
...@@ -2238,6 +2238,7 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr ...@@ -2238,6 +2238,7 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr
${XFORMS_SOURCE} ${XFORMS_SOURCE}
${T_SOURCE} ${T_SOURCE}
${CONFIG_SOURCES} ${CONFIG_SOURCES}
${SHLIB_LOADER_SOURCES}
) )
target_link_libraries (${myExe} target_link_libraries (${myExe}
......
...@@ -626,12 +626,17 @@ function main() { ...@@ -626,12 +626,17 @@ function main() {
if [ "$SIMUS_PHY" = "1" ] ; then if [ "$SIMUS_PHY" = "1" ] ; then
# lte unitary simulators compilation # lte unitary simulators compilation
echo_info "Compiling unitary tests simulators" echo_info "Compiling unitary tests simulators"
simlist="dlsim_tm4 dlsim ulsim pucchsim prachsim pdcchsim pbchsim mbmssim" # TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim
#simlist="dlsim_tm4 dlsim ulsim pucchsim prachsim pdcchsim pbchsim mbmssim"
simlist="dlsim ulsim"
for f in $simlist ; do for f in $simlist ; do
compilations \ compilations \
lte-simulators $f \ lte-simulators $f \
$f $dbin/$f.$REL $f $dbin/$f.$REL
done done
compilations \
lte-simulators coding \
libcoding.so $dbin/libcoding.so
fi fi
# Core simulators # Core simulators
......
...@@ -210,7 +210,7 @@ install_protobuf_from_source(){ ...@@ -210,7 +210,7 @@ install_protobuf_from_source(){
#cd protobuf-2.6.1/ #cd protobuf-2.6.1/
rm -rf /tmp/protobuf-cpp-3.3.0.tar.gz* /tmp/protobuf-3.3.0 rm -rf /tmp/protobuf-cpp-3.3.0.tar.gz* /tmp/protobuf-3.3.0
wget https://github.com/google/protobuf/releases/download/v3.3.0/protobuf-cpp-3.3.0.tar.gz wget https://github.com/google/protobuf/releases/download/v3.3.0/protobuf-cpp-3.3.0.tar.gz
tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner $USER --group $USER --no-same-owner tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner $USER --group $(groups | cut -d" " -f1) --no-same-owner
cd protobuf-3.3.0/ cd protobuf-3.3.0/
./configure ./configure
echo "Compiling protobuf" echo "Compiling protobuf"
......
...@@ -325,8 +325,11 @@ int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, Me ...@@ -325,8 +325,11 @@ int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, Me
/* Increment the global message number */ /* Increment the global message number */
message_number = itti_increment_message_number (); message_number = itti_increment_message_number ();
#if 0
/* itti dump is disabled */
itti_dump_queue_message (origin_task_id, message_number, message, itti_desc.messages_info[message_id].name, itti_dump_queue_message (origin_task_id, message_number, message, itti_desc.messages_info[message_id].name,
sizeof(MessageHeader) + message->ittiMsgHeader.ittiMsgSize); sizeof(MessageHeader) + message->ittiMsgHeader.ittiMsgSize);
#endif
if (destination_task_id != TASK_UNKNOWN) { if (destination_task_id != TASK_UNKNOWN) {
...@@ -421,8 +424,11 @@ int itti_try_send_msg_to_task(task_id_t destination_task_id, instance_t instance ...@@ -421,8 +424,11 @@ int itti_try_send_msg_to_task(task_id_t destination_task_id, instance_t instance
/* Increment the global message number */ /* Increment the global message number */
message_number = itti_increment_message_number (); message_number = itti_increment_message_number ();
#if 0
/* itti dump is disabled */
itti_dump_queue_message (origin_task_id, message_number, message, itti_desc.messages_info[message_id].name, itti_dump_queue_message (origin_task_id, message_number, message, itti_desc.messages_info[message_id].name,
sizeof(MessageHeader) + message->ittiMsgHeader.ittiMsgSize); sizeof(MessageHeader) + message->ittiMsgHeader.ittiMsgSize);
#endif
if (destination_task_id != TASK_UNKNOWN) { if (destination_task_id != TASK_UNKNOWN) {
...@@ -716,8 +722,11 @@ void itti_mark_task_ready(task_id_t task_id) ...@@ -716,8 +722,11 @@ void itti_mark_task_ready(task_id_t task_id)
AssertFatal (thread_id < itti_desc.thread_max, "Thread id (%d) is out of range (%d)!\n", thread_id, itti_desc.thread_max); AssertFatal (thread_id < itti_desc.thread_max, "Thread id (%d) is out of range (%d)!\n", thread_id, itti_desc.thread_max);
#if 0
/* itti dump is disabled */
/* Register the thread in itti dump */ /* Register the thread in itti dump */
itti_dump_thread_use_ring_buffer(); itti_dump_thread_use_ring_buffer();
#endif
/* Mark the thread as using LFDS queue */ /* Mark the thread as using LFDS queue */
lfds611_queue_use(itti_desc.tasks[task_id].message_queue); lfds611_queue_use(itti_desc.tasks[task_id].message_queue);
...@@ -848,7 +857,10 @@ int itti_init(task_id_t task_max, thread_id_t thread_max, MessagesIds messages_i ...@@ -848,7 +857,10 @@ int itti_init(task_id_t task_max, thread_id_t thread_max, MessagesIds messages_i
itti_desc.wait_tasks = 0; itti_desc.wait_tasks = 0;
itti_desc.created_tasks = 0; itti_desc.created_tasks = 0;
itti_desc.ready_tasks = 0; itti_desc.ready_tasks = 0;
#if 0
/* itti dump is disabled */
itti_dump_init (messages_definition_xml, dump_file_name); itti_dump_init (messages_definition_xml, dump_file_name);
#endif
CHECK_INIT_RETURN(timer_init ()); CHECK_INIT_RETURN(timer_init ());
...@@ -915,7 +927,10 @@ void itti_wait_tasks_end(void) ...@@ -915,7 +927,10 @@ void itti_wait_tasks_end(void)
exit (0); exit (0);
} }
#if 0
/* itti dump is disabled */
itti_dump_exit(); itti_dump_exit();
#endif
} }
void itti_send_terminate_message(task_id_t task_id) void itti_send_terminate_message(task_id_t task_id)
......
...@@ -1451,7 +1451,9 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe) ...@@ -1451,7 +1451,9 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe)
pthread_mutex_unlock(&eNB->UL_INFO_mutex); pthread_mutex_unlock(&eNB->UL_INFO_mutex);
} }
void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subframe,uint16_t mask) { /* release the harq if its round is >= 'after_rounds' */
static void do_release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subframe,uint16_t mask, int after_rounds)
{
LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL; LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL; LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
...@@ -1472,11 +1474,13 @@ void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subf ...@@ -1472,11 +1474,13 @@ void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subf
dlsch1_harq = dlsch1->harq_processes[harq_pid]; dlsch1_harq = dlsch1->harq_processes[harq_pid];
AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n"); AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n");
if (dlsch0_harq->round >= after_rounds) {
dlsch0_harq->status = SCH_IDLE; dlsch0_harq->status = SCH_IDLE;
/*if ((dlsch1_harq == NULL)|| /*if ((dlsch1_harq == NULL)||
((dlsch1_harq!=NULL)&& ((dlsch1_harq!=NULL)&&
(dlsch1_harq->status == SCH_IDLE)))*/ (dlsch1_harq->status == SCH_IDLE)))*/
dlsch0->harq_mask &= ~(1<<harq_pid); dlsch0->harq_mask &= ~(1<<harq_pid);
}
LOG_D(PHY,"Frame %d, subframe %d: Releasing harq %d for UE %x\n",frame,subframe,harq_pid,dlsch0->rnti); LOG_D(PHY,"Frame %d, subframe %d: Releasing harq %d for UE %x\n",frame,subframe,harq_pid,dlsch0->rnti);
} }
...@@ -1496,6 +1500,7 @@ void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subf ...@@ -1496,6 +1500,7 @@ void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subf
dlsch1_harq = dlsch1->harq_processes[harq_pid]; dlsch1_harq = dlsch1->harq_processes[harq_pid];
AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n"); AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n");
if (dlsch0_harq->round >= after_rounds) {
dlsch0_harq->status = SCH_IDLE; dlsch0_harq->status = SCH_IDLE;
if ((dlsch1_harq == NULL)|| if ((dlsch1_harq == NULL)||
((dlsch1_harq!=NULL)&& ((dlsch1_harq!=NULL)&&
...@@ -1505,6 +1510,16 @@ void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subf ...@@ -1505,6 +1510,16 @@ void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subf
} }
} }
} }
}
}
static void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subframe,uint16_t mask, int is_ack)
{
/* Maximum number of DL transmissions = 4.
* TODO: get the value from configuration.
* If is_ack is true then we release immediately. The value -1 can be used for that.
*/
do_release_harq(eNB, UE_id, tb, frame, subframe, mask, is_ack ? -1 : 4);
} }
int getM(PHY_VARS_eNB *eNB,int frame,int subframe) { int getM(PHY_VARS_eNB *eNB,int frame,int subframe) {
...@@ -1607,7 +1622,7 @@ void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq, ...@@ -1607,7 +1622,7 @@ void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq,
pdu->harq_indication_fdd_rel13.harq_tb_n[i] = 2-ulsch_harq->o_ACK[i]; pdu->harq_indication_fdd_rel13.harq_tb_n[i] = 2-ulsch_harq->o_ACK[i];
// release DLSCH if needed // release DLSCH if needed
if (ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff); release_harq(eNB,UE_id,i,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1);
#if T_TRACER #if T_TRACER
/* TODO: get correct harq pid */ /* TODO: get correct harq pid */
...@@ -1633,13 +1648,17 @@ void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq, ...@@ -1633,13 +1648,17 @@ void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq,
pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = 2-ulsch_harq->o_ACK[i]; pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = 2-ulsch_harq->o_ACK[i];
// release DLSCH if needed // release DLSCH if needed
if (ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff); /* TODO: review this code, it's most certainly wrong.
if (M==1 && ulsch_harq->O_ACK==1 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff); * We have to release the proper HARQ in case of ACK or NACK if max retransmission reached.
else if (M==1 && ulsch_harq->O_ACK==2 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff); * Basically, call release_harq with 1 as last argument when ACK and 0 when NACK.
*/
release_harq(eNB,UE_id,i,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1);
if (M==1 && ulsch_harq->O_ACK==1 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1);
else if (M==1 && ulsch_harq->O_ACK==2 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1);
else if (M>1 && ulsch_harq->o_ACK[i] == 1) { else if (M>1 && ulsch_harq->o_ACK[i] == 1) {
// spatial bundling // spatial bundling
release_harq(eNB,UE_id,0,frame,subframe,1<<i); release_harq(eNB,UE_id,0,frame,subframe,1<<i, ulsch_harq->o_ACK[i] == 1);
release_harq(eNB,UE_id,1,frame,subframe,1<<i); release_harq(eNB,UE_id,1,frame,subframe,1<<i, ulsch_harq->o_ACK[i] == 1);
} }
} }
} }
...@@ -1701,7 +1720,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, ...@@ -1701,7 +1720,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]); AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]);
pdu->harq_indication_fdd_rel13.harq_tb_n[0] = harq_ack[0]; pdu->harq_indication_fdd_rel13.harq_tb_n[0] = harq_ack[0];
// release DLSCH if needed // release DLSCH if needed
if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff); release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
#if T_TRACER #if T_TRACER
if (harq_ack[0] != 1) if (harq_ack[0] != 1)
...@@ -1721,8 +1740,8 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, ...@@ -1721,8 +1740,8 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
pdu->harq_indication_fdd_rel13.harq_tb_n[0] = harq_ack[0]; pdu->harq_indication_fdd_rel13.harq_tb_n[0] = harq_ack[0];
pdu->harq_indication_fdd_rel13.harq_tb_n[1] = harq_ack[1]; pdu->harq_indication_fdd_rel13.harq_tb_n[1] = harq_ack[1];
// release DLSCH if needed // release DLSCH if needed
if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff); release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
if (harq_ack[1] == 1) release_harq(eNB,UE_id,1,frame,subframe,0xffff); release_harq(eNB,UE_id,1,frame,subframe,0xffff, harq_ack[1] == 1);
} }
else AssertFatal(1==0,"only format 1a/b for now, received %d\n",uci->pucch_fmt); else AssertFatal(1==0,"only format 1a/b for now, received %d\n",uci->pucch_fmt);
} }
...@@ -1743,7 +1762,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, ...@@ -1743,7 +1762,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]); AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]);
pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = harq_ack[0]; pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = harq_ack[0];
// release all bundled DLSCH if needed // release all bundled DLSCH if needed
if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff); release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
} }
else if (uci->pucch_fmt == pucch_format1b) { else if (uci->pucch_fmt == pucch_format1b) {
pdu->harq_indication_tdd_rel13.number_of_ack_nack = 2; pdu->harq_indication_tdd_rel13.number_of_ack_nack = 2;
...@@ -1753,8 +1772,8 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, ...@@ -1753,8 +1772,8 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = harq_ack[0]; pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = harq_ack[0];
pdu->harq_indication_tdd_rel13.harq_data[1].bundling.value_0 = harq_ack[1]; pdu->harq_indication_tdd_rel13.harq_data[1].bundling.value_0 = harq_ack[1];
// release all DLSCH if needed // release all DLSCH if needed
if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff); release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
if (harq_ack[1] == 1) release_harq(eNB,UE_id,1,frame,subframe,0xffff); release_harq(eNB,UE_id,1,frame,subframe,0xffff, harq_ack[1] == 1);
} }
break; break;
case 1: // multiplexing case 1: // multiplexing
...@@ -1766,7 +1785,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, ...@@ -1766,7 +1785,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]); AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]);
pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0]; pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0];
// release all DLSCH if needed // release all DLSCH if needed
if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff); release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
} }
else if (uci->num_pucch_resources == 1 && uci->pucch_fmt == pucch_format1b) { else if (uci->num_pucch_resources == 1 && uci->pucch_fmt == pucch_format1b) {
pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG;
...@@ -1776,8 +1795,8 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, ...@@ -1776,8 +1795,8 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0]; pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0];
pdu->harq_indication_tdd_rel13.harq_data[1].multiplex.value_0 = harq_ack[1]; pdu->harq_indication_tdd_rel13.harq_data[1].multiplex.value_0 = harq_ack[1];
// release all DLSCH if needed // release all DLSCH if needed
if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff); release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
if (harq_ack[1] == 1) release_harq(eNB,UE_id,1,frame,subframe,0xffff); release_harq(eNB,UE_id,1,frame,subframe,0xffff, harq_ack[1] == 1);
} }
else { // num_pucch_resources (M) > 1 else { // num_pucch_resources (M) > 1
pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG;
...@@ -1788,8 +1807,8 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, ...@@ -1788,8 +1807,8 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
if (uci->num_pucch_resources == 3) pdu->harq_indication_tdd_rel13.harq_data[2].multiplex.value_0 = harq_ack[2]; if (uci->num_pucch_resources == 3) pdu->harq_indication_tdd_rel13.harq_data[2].multiplex.value_0 = harq_ack[2];
if (uci->num_pucch_resources == 4) pdu->harq_indication_tdd_rel13.harq_data[3].multiplex.value_0 = harq_ack[3]; if (uci->num_pucch_resources == 4) pdu->harq_indication_tdd_rel13.harq_data[3].multiplex.value_0 = harq_ack[3];
// spatial-bundling in this case so release both HARQ if necessary // spatial-bundling in this case so release both HARQ if necessary
release_harq(eNB,UE_id,0,frame,subframe,tdd_multiplexing_mask); release_harq(eNB,UE_id,0,frame,subframe,tdd_multiplexing_mask, 1 /* force release? previous code was unconditional */);
release_harq(eNB,UE_id,1,frame,subframe,tdd_multiplexing_mask); release_harq(eNB,UE_id,1,frame,subframe,tdd_multiplexing_mask, 1 /* force release? previous code was unconditional */);
} }
break; break;
case 2: // special bundling (SR collision) case 2: // special bundling (SR collision)
...@@ -1800,26 +1819,27 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, ...@@ -1800,26 +1819,27 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
switch (harq_ack[0]) { switch (harq_ack[0]) {
case 0: case 0:
/* TODO: release_harq here? this whole code looks suspicious */
break; break;
case 1: // check if M=1,4,7 case 1: // check if M=1,4,7
if (uci->num_pucch_resources == 1 || uci->num_pucch_resources == 4 || if (uci->num_pucch_resources == 1 || uci->num_pucch_resources == 4 ||
tdd_config5_sf2scheds == 1 || tdd_config5_sf2scheds == 4 || tdd_config5_sf2scheds == 7) { tdd_config5_sf2scheds == 1 || tdd_config5_sf2scheds == 4 || tdd_config5_sf2scheds == 7) {
release_harq(eNB,UE_id,0,frame,subframe,0xffff); release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1);
release_harq(eNB,UE_id,1,frame,subframe,0xffff); release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1);
} }
break; break;
case 2: // check if M=2,5,8 case 2: // check if M=2,5,8
if (uci->num_pucch_resources == 2 || tdd_config5_sf2scheds == 2 || if (uci->num_pucch_resources == 2 || tdd_config5_sf2scheds == 2 ||
tdd_config5_sf2scheds == 5 || tdd_config5_sf2scheds == 8) { tdd_config5_sf2scheds == 5 || tdd_config5_sf2scheds == 8) {
release_harq(eNB,UE_id,0,frame,subframe,0xffff); release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1);
release_harq(eNB,UE_id,1,frame,subframe,0xffff); release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1);
} }
break; break;
case 3: // check if M=3,6,9 case 3: // check if M=3,6,9
if (uci->num_pucch_resources == 3 || tdd_config5_sf2scheds == 3 || if (uci->num_pucch_resources == 3 || tdd_config5_sf2scheds == 3 ||
tdd_config5_sf2scheds == 6 || tdd_config5_sf2scheds == 9) { tdd_config5_sf2scheds == 6 || tdd_config5_sf2scheds == 9) {
release_harq(eNB,UE_id,0,frame,subframe,0xffff); release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1);
release_harq(eNB,UE_id,1,frame,subframe,0xffff); release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1);
} }
break; break;
} }
......
...@@ -131,7 +131,7 @@ message flex_enb_config_request { ...@@ -131,7 +131,7 @@ message flex_enb_config_request {
message flex_enb_config_reply { message flex_enb_config_reply {
optional flex_header header = 1; optional flex_header header = 1;
optional uint32 eNB_id = 2; // Unique id to distinguish the eNB optional uint64 eNB_id = 2; // Unique id to distinguish the eNB
repeated flex_cell_config cell_config = 3; repeated flex_cell_config cell_config = 3;
optional uint32 device_spec = 4; optional uint32 device_spec = 4;
} }
......
...@@ -64,37 +64,124 @@ ...@@ -64,37 +64,124 @@
extern uint16_t sf_ahead; extern uint16_t sf_ahead;
void RCconfig_flexran() void RCconfig_flexran()
{ {
int i; uint16_t i;
uint16_t num_enbs;
char aprefix[MAX_OPTNAME_SIZE*2 + 8];
/* this will possibly truncate the cell id (RRC assumes int32_t).
* Both Nid_cell and enb_id are signed in RRC case, but we use unsigned for
* the bitshifting to work properly */
int32_t Nid_cell = 0;
uint16_t Nid_cell_tr = 0;
uint32_t enb_id = 0;
/*
* the only reason for all these variables is, that they are "hard-encoded"
* into the CCPARAMS_DESC macro and we need it for the Nid_cell variable ...
*/
char *frame_type, *prefix_type, *pbch_repetition, *prach_high_speed,
*pusch_hoppingMode, *pusch_enable64QAM, *pusch_groupHoppingEnabled,
*pusch_sequenceHoppingEnabled, *phich_duration, *phich_resource,
*srs_enable, *srs_ackNackST, *srs_MaxUpPts, *pusch_alpha,
*pucch_deltaF_Format1, *pucch_deltaF_Format1b, *pucch_deltaF_Format2,
*pucch_deltaF_Format2a, *pucch_deltaF_Format2b,
*rach_preamblesGroupAConfig, *rach_messagePowerOffsetGroupB, *pcch_nB;
long long int downlink_frequency;
int32_t tdd_config, tdd_config_s, eutra_band, uplink_frequency_offset,
Nid_cell_mbsfn, N_RB_DL, nb_antenna_ports, prach_root, prach_config_index,
prach_zero_correlation, prach_freq_offset, pucch_delta_shift,
pucch_nRB_CQI, pucch_nCS_AN, pucch_n1_AN, pdsch_referenceSignalPower,
pdsch_p_b, pusch_n_SB, pusch_hoppingOffset, pusch_groupAssignment,
pusch_nDMRS1, srs_BandwidthConfig, srs_SubframeConfig, pusch_p0_Nominal,
pucch_p0_Nominal, msg3_delta_Preamble, rach_numberOfRA_Preambles,
rach_sizeOfRA_PreamblesGroupA, rach_messageSizeGroupA,
rach_powerRampingStep, rach_preambleInitialReceivedTargetPower,
rach_preambleTransMax, rach_raResponseWindowSize,
rach_macContentionResolutionTimer, rach_maxHARQ_Msg3Tx,
pcch_defaultPagingCycle, bcch_modificationPeriodCoeff,
ue_TimersAndConstants_t300, ue_TimersAndConstants_t301,
ue_TimersAndConstants_t310, ue_TimersAndConstants_t311,
ue_TimersAndConstants_n310, ue_TimersAndConstants_n311,
ue_TransmissionMode;
/* get number of eNBs */
paramdef_t ENBSParams[] = ENBSPARAMS_DESC;
config_get(ENBSParams, sizeof(ENBSParams)/sizeof(paramdef_t), NULL);
num_enbs = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt;
/* for eNB ID */
paramdef_t ENBParams[] = ENBPARAMS_DESC;
paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST, NULL, 0};
/* for Nid_cell */
checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK;
paramdef_t CCsParams[] = CCPARAMS_DESC;
paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS, NULL, 0};
/* map parameter checking array instances to parameter definition array instances */
for (int I = 0; I < (sizeof(CCsParams) / sizeof(paramdef_t)); I++) {
CCsParams[I].chkPptr = &(config_check_CCparams[I]);
}
paramdef_t flexranParams[] = FLEXRANPARAMS_DESC; paramdef_t flexranParams[] = FLEXRANPARAMS_DESC;
config_get(flexranParams, sizeof(flexranParams)/sizeof(paramdef_t), CONFIG_STRING_NETWORK_CONTROLLER_CONFIG); config_get(flexranParams, sizeof(flexranParams)/sizeof(paramdef_t), CONFIG_STRING_NETWORK_CONTROLLER_CONFIG);
if (!RC.flexran) { if (!RC.flexran) {
RC.flexran = calloc(RC.nb_L1_inst, sizeof(flexran_agent_info_t*)); RC.flexran = calloc(num_enbs, sizeof(flexran_agent_info_t*));
AssertFatal(RC.flexran != NULL, AssertFatal(RC.flexran,
"can't ALLOCATE %zu Bytes for %d flexran agent info with size %zu\n", "can't ALLOCATE %zu Bytes for %d flexran agent info with size %zu\n",
RC.nb_L1_inst * sizeof(flexran_agent_info_t*), num_enbs * sizeof(flexran_agent_info_t*),
RC.nb_L1_inst, sizeof(flexran_agent_info_t*)); num_enbs, sizeof(flexran_agent_info_t*));
} }
/* For all agent instance, fill in the same controller configuration. */ for (i = 0; i < num_enbs; i++) {
for (i = 0; i < RC.nb_L1_inst; i++) {
RC.flexran[i] = calloc(1, sizeof(flexran_agent_info_t)); RC.flexran[i] = calloc(1, sizeof(flexran_agent_info_t));
AssertFatal(RC.flexran[i] != NULL, AssertFatal(RC.flexran[i],
"can't ALLOCATE %zu Bytes for flexran agent info (iteration %d/%d)\n", "can't ALLOCATE %zu Bytes for flexran agent info (iteration %d/%d)\n",
sizeof(flexran_agent_info_t), i + 1, RC.nb_L1_inst); sizeof(flexran_agent_info_t), i + 1, num_enbs);
/* if config says "yes", enable Agent, in all other cases it's like "no" */ /* if config says "yes", enable Agent, in all other cases it's like "no" */
RC.flexran[i]->enabled = strcmp(*(flexranParams[FLEXRAN_ENABLED].strptr), "yes") == 0; RC.flexran[i]->enabled = strcasecmp(*(flexranParams[FLEXRAN_ENABLED].strptr), "yes") == 0;
/* if not enabled, simply skip the rest, it is not needed anyway */
if (!RC.flexran[i]->enabled)
continue;
RC.flexran[i]->interface_name = strdup(*(flexranParams[FLEXRAN_INTERFACE_NAME_IDX].strptr)); RC.flexran[i]->interface_name = strdup(*(flexranParams[FLEXRAN_INTERFACE_NAME_IDX].strptr));
//inet_ntop(AF_INET, &(enb_properties->properties[mod_id]->flexran_agent_ipv4_address), in_ip, INET_ADDRSTRLEN); //inet_ntop(AF_INET, &(enb_properties->properties[mod_id]->flexran_agent_ipv4_address), in_ip, INET_ADDRSTRLEN);
RC.flexran[i]->remote_ipv4_addr = strdup(*(flexranParams[FLEXRAN_IPV4_ADDRESS_IDX].strptr)); RC.flexran[i]->remote_ipv4_addr = strdup(*(flexranParams[FLEXRAN_IPV4_ADDRESS_IDX].strptr));
RC.flexran[i]->remote_port = *(flexranParams[FLEXRAN_PORT_IDX].uptr); RC.flexran[i]->remote_port = *(flexranParams[FLEXRAN_PORT_IDX].uptr);
RC.flexran[i]->cache_name = strdup(*(flexranParams[FLEXRAN_CACHE_IDX].strptr)); RC.flexran[i]->cache_name = strdup(*(flexranParams[FLEXRAN_CACHE_IDX].strptr));
RC.flexran[i]->node_ctrl_state = strcmp(*(flexranParams[FLEXRAN_AWAIT_RECONF_IDX].strptr), "yes") == 0 ? ENB_WAIT : ENB_NORMAL_OPERATION; RC.flexran[i]->node_ctrl_state = strcasecmp(*(flexranParams[FLEXRAN_AWAIT_RECONF_IDX].strptr), "yes") == 0 ? ENB_WAIT : ENB_NORMAL_OPERATION;
RC.flexran[i]->enb_id = i;
config_getlist(&ENBParamList, ENBParams, sizeof(ENBParams)/sizeof(paramdef_t),NULL);
/* eNB ID from configuration, as read in by RCconfig_RRC() */
if (!ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr) {
// Calculate a default eNB ID
# if defined(ENABLE_USE_MME)
enb_id = i + (s1ap_generate_eNB_id () & 0xFFFF8);
# else
enb_id = i;
# endif
} else {
enb_id = *(ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr);
}
/* cell ID */
sprintf(aprefix, "%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, i);
config_getlist(&CCsParamList, NULL, 0, aprefix);
if (CCsParamList.numelt > 0) {
sprintf(aprefix, "%s.[%i].%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, i, ENB_CONFIG_STRING_COMPONENT_CARRIERS, 0);
config_get(CCsParams, sizeof(CCsParams)/sizeof(paramdef_t), aprefix);
Nid_cell_tr = (uint16_t) Nid_cell;
}
RC.flexran[i]->mod_id = i;
RC.flexran[i]->agent_id = (((uint64_t)i) << 48) | (((uint64_t)enb_id) << 16) | ((uint64_t)Nid_cell_tr);
/* assume for the moment the monolithic case, i.e. agent can provide
* information for all layers */
RC.flexran[i]->capability_mask = FLEXRAN_CAP_LOPHY | FLEXRAN_CAP_HIPHY
| FLEXRAN_CAP_LOMAC | FLEXRAN_CAP_HIMAC
| FLEXRAN_CAP_RLC | FLEXRAN_CAP_PDCP
| FLEXRAN_CAP_SDAP | FLEXRAN_CAP_RRC;
} }
} }
......
...@@ -114,12 +114,12 @@ void *receive_thread(void *args) { ...@@ -114,12 +114,12 @@ void *receive_thread(void *args) {
while (1) { while (1) {
while (flexran_agent_msg_recv(d->enb_id, FLEXRAN_AGENT_DEFAULT, &data, &size, &priority) == 0) { while (flexran_agent_msg_recv(d->mod_id, FLEXRAN_AGENT_DEFAULT, &data, &size, &priority) == 0) {
LOG_D(FLEXRAN_AGENT,"received message with size %d\n", size); LOG_D(FLEXRAN_AGENT,"received message with size %d\n", size);
// Invoke the message handler // Invoke the message handler
msg=flexran_agent_handle_message(d->enb_id, data, size); msg=flexran_agent_handle_message(d->mod_id, data, size);
free(data); free(data);
...@@ -127,7 +127,7 @@ void *receive_thread(void *args) { ...@@ -127,7 +127,7 @@ void *receive_thread(void *args) {
if (msg != NULL){ if (msg != NULL){
data=flexran_agent_pack_message(msg,&size); data=flexran_agent_pack_message(msg,&size);
if (flexran_agent_msg_send(d->enb_id, FLEXRAN_AGENT_DEFAULT, data, size, priority)) { if (flexran_agent_msg_send(d->mod_id, FLEXRAN_AGENT_DEFAULT, data, size, priority)) {
err_code = PROTOCOL__FLEXRAN_ERR__MSG_ENQUEUING; err_code = PROTOCOL__FLEXRAN_ERR__MSG_ENQUEUING;
goto error; goto error;
} }
...@@ -191,13 +191,6 @@ int flexran_agent_start(mid_t mod_id) ...@@ -191,13 +191,6 @@ int flexran_agent_start(mid_t mod_id)
return 100; return 100;
} }
flexran->enb_id = mod_id;
/* assume for the moment the monolithic case, i.e. agent can provide
* information for all layers */
flexran->capability_mask = FLEXRAN_CAP_LOL1 | FLEXRAN_CAP_HIL1
| FLEXRAN_CAP_LOL2 | FLEXRAN_CAP_HIL2
| FLEXRAN_CAP_PDCP | FLEXRAN_CAP_RRC;
/* /*
* Initialize the channel container * Initialize the channel container
*/ */
......
This diff is collapsed.
...@@ -138,12 +138,14 @@ typedef enum { ...@@ -138,12 +138,14 @@ typedef enum {
FLEXRAN_AGENT_TIMER_STATE_MAX, FLEXRAN_AGENT_TIMER_STATE_MAX,
} flexran_agent_timer_state_t; } flexran_agent_timer_state_t;
#define FLEXRAN_CAP_LOL1 0x1 #define FLEXRAN_CAP_LOPHY 1
#define FLEXRAN_CAP_HIL1 0x2 #define FLEXRAN_CAP_HIPHY 2
#define FLEXRAN_CAP_LOL2 0x4 // is: MAC #define FLEXRAN_CAP_LOMAC 4
#define FLEXRAN_CAP_HIL2 0x8 // is: RLC #define FLEXRAN_CAP_HIMAC 8
#define FLEXRAN_CAP_PDCP 0x16 #define FLEXRAN_CAP_RLC 16
#define FLEXRAN_CAP_RRC 0x32 #define FLEXRAN_CAP_PDCP 32
#define FLEXRAN_CAP_SDAP 64
#define FLEXRAN_CAP_RRC 128
typedef enum { typedef enum {
ENB_NORMAL_OPERATION = 0x0, ENB_NORMAL_OPERATION = 0x0,
...@@ -159,7 +161,8 @@ typedef struct { ...@@ -159,7 +161,8 @@ typedef struct {
uint16_t remote_port; uint16_t remote_port;
char *cache_name; char *cache_name;
int enb_id; mid_t mod_id;
uint64_t agent_id;
uint8_t capability_mask; uint8_t capability_mask;
/* lock for waiting before starting or soft-restart */ /* lock for waiting before starting or soft-restart */
......
...@@ -423,12 +423,15 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id, ...@@ -423,12 +423,15 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id,
} }
} // ul_failure_timer>0 } // ul_failure_timer>0
#if 0
/* U-plane inactivity timer is disabled. Uncomment to re-enable. */
UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer++; UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer++;
if(UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer > (U_PLANE_INACTIVITY_VALUE*subframe_num(&RC.eNB[module_idP][CC_id]->frame_parms))){ if(UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer > (U_PLANE_INACTIVITY_VALUE*subframe_num(&RC.eNB[module_idP][CC_id]->frame_parms))){
LOG_D(MAC,"UE %d rnti %x: U-Plane Failure after repeated PDCCH orders: Triggering RRC \n",UE_id,rnti); LOG_D(MAC,"UE %d rnti %x: U-Plane Failure after repeated PDCCH orders: Triggering RRC \n",UE_id,rnti);
mac_eNB_rrc_uplane_failure(module_idP,CC_id,frameP,subframeP,rnti); mac_eNB_rrc_uplane_failure(module_idP,CC_id,frameP,subframeP,rnti);
UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
}// time > 60s }// time > 60s
#endif
} }
void void
......
...@@ -3297,8 +3297,13 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id, ...@@ -3297,8 +3297,13 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
if (pdu[0] == 1) { // ACK if (pdu[0] == 1) { // ACK
sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process
sched_ctl->tbcnt[CC_idP][harq_pid] = 0; sched_ctl->tbcnt[CC_idP][harq_pid] = 0;
} else if (pdu[0] == 2 || pdu[0] == 4) // NAK (treat DTX as NAK) } else if (pdu[0] == 2 || pdu[0] == 4) { // NAK (treat DTX as NAK)
sched_ctl->round[CC_idP][harq_pid]++; // increment round sched_ctl->round[CC_idP][harq_pid]++; // increment round
if (sched_ctl->round[CC_idP][harq_pid] == 4) {
sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process
sched_ctl->tbcnt[CC_idP][harq_pid] = 0;
}
}
} else { } else {
// one or two ACK/NAK bits // one or two ACK/NAK bits
AssertFatal(num_ack_nak <= 2, AssertFatal(num_ack_nak <= 2,
...@@ -3314,8 +3319,13 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id, ...@@ -3314,8 +3319,13 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
if ((num_ack_nak == 2) if ((num_ack_nak == 2)
&& (sched_ctl->round[CC_idP][harq_pid] < 8) && (sched_ctl->round[CC_idP][harq_pid] < 8)
&& (sched_ctl->tbcnt[CC_idP][harq_pid] == 1) && (sched_ctl->tbcnt[CC_idP][harq_pid] == 1)
&& (pdu[0] == 2) && (pdu[1] == 2)) && (pdu[0] == 2) && (pdu[1] == 2)) {
sched_ctl->round[CC_idP][harq_pid]++; sched_ctl->round[CC_idP][harq_pid]++;
if (sched_ctl->round[CC_idP][harq_pid] == 4) {
sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process
sched_ctl->tbcnt[CC_idP][harq_pid] = 0;
}
}
else if (((num_ack_nak == 2) else if (((num_ack_nak == 2)
&& (sched_ctl->round[CC_idP][harq_pid] < 8) && (sched_ctl->round[CC_idP][harq_pid] < 8)
&& (sched_ctl->tbcnt[0][harq_pid] == 2) && (sched_ctl->tbcnt[0][harq_pid] == 2)
...@@ -3326,11 +3336,20 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id, ...@@ -3326,11 +3336,20 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
&& (pdu[0] == 2) && (pdu[1] == 1))) { && (pdu[0] == 2) && (pdu[1] == 1))) {
sched_ctl->round[CC_idP][harq_pid]++; sched_ctl->round[CC_idP][harq_pid]++;
sched_ctl->tbcnt[CC_idP][harq_pid] = 1; sched_ctl->tbcnt[CC_idP][harq_pid] = 1;
if (sched_ctl->round[CC_idP][harq_pid] == 4) {
sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process
sched_ctl->tbcnt[CC_idP][harq_pid] = 0; /* TODO: do we have to set it to 0? */
}
} else if ((num_ack_nak == 2) } else if ((num_ack_nak == 2)
&& (sched_ctl->round[CC_idP][harq_pid] < 8) && (sched_ctl->round[CC_idP][harq_pid] < 8)
&& (sched_ctl->tbcnt[CC_idP][harq_pid] == 2) && (sched_ctl->tbcnt[CC_idP][harq_pid] == 2)
&& (pdu[0] == 2) && (pdu[1] == 2)) && (pdu[0] == 2) && (pdu[1] == 2)) {
sched_ctl->round[CC_idP][harq_pid]++; sched_ctl->round[CC_idP][harq_pid]++;
if (sched_ctl->round[CC_idP][harq_pid] == 4) {
sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process
sched_ctl->tbcnt[CC_idP][harq_pid] = 0;
}
}
else else
AssertFatal(1 == 0, AssertFatal(1 == 0,
"Illegal ACK/NAK/round combination (%d,%d,%d,%d,%d) for harq_pid %d, UE %d/%x\n", "Illegal ACK/NAK/round combination (%d,%d,%d,%d,%d) for harq_pid %d, UE %d/%x\n",
...@@ -3356,12 +3375,18 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id, ...@@ -3356,12 +3375,18 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
pdu[1]); pdu[1]);
if (pdu[0] == 1) if (pdu[0] == 1)
sched_ctl->round[pCCid][harq_pid] = 8; sched_ctl->round[pCCid][harq_pid] = 8;
else else {
sched_ctl->round[pCCid][harq_pid]++; sched_ctl->round[pCCid][harq_pid]++;
if (sched_ctl->round[pCCid][harq_pid] == 4)
sched_ctl->round[pCCid][harq_pid] = 8;
}
if (pdu[1] == 1) if (pdu[1] == 1)
sched_ctl->round[1 - pCCid][harq_pid] = 8; sched_ctl->round[1 - pCCid][harq_pid] = 8;
else else {
sched_ctl->round[1 - pCCid][harq_pid]++; sched_ctl->round[1 - pCCid][harq_pid]++;
if (sched_ctl->round[1 - pCCid][harq_pid] == 4)
sched_ctl->round[1 - pCCid][harq_pid] = 8;
}
} // A=2 } // A=2
else if ((num_ack_nak == 3) else if ((num_ack_nak == 3)
&& (sched_ctl->round[pCCid][harq_pid] < 8) && (sched_ctl->round[pCCid][harq_pid] < 8)
...@@ -3387,13 +3412,26 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id, ...@@ -3387,13 +3412,26 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
((pdu[0] == 1) && (pdu[1] == 2))) { ((pdu[0] == 1) && (pdu[1] == 2))) {
sched_ctl->round[pCCid][harq_pid]++; sched_ctl->round[pCCid][harq_pid]++;
sched_ctl->tbcnt[pCCid][harq_pid] = 1; sched_ctl->tbcnt[pCCid][harq_pid] = 1;
} else if (sched_ctl->round[pCCid][harq_pid] == 4) {
sched_ctl->round[pCCid][harq_pid] = 8;
sched_ctl->tbcnt[pCCid][harq_pid] = 0; /* TODO: do we have to set it to 0? */
}
} else {
sched_ctl->round[pCCid][harq_pid]++; sched_ctl->round[pCCid][harq_pid]++;
if (sched_ctl->round[pCCid][harq_pid] == 4) {
sched_ctl->round[pCCid][harq_pid] = 8;
sched_ctl->tbcnt[pCCid][harq_pid] = 0;
}
}
if (pdu[2] == 1) if (pdu[2] == 1)
sched_ctl->round[1 - pCCid][harq_pid] = 8; sched_ctl->round[1 - pCCid][harq_pid] = 8;
else else {
sched_ctl->round[1 - pCCid][harq_pid]++; sched_ctl->round[1 - pCCid][harq_pid]++;
if (sched_ctl->round[1 - pCCid][harq_pid] == 4) {
sched_ctl->round[1 - pCCid][harq_pid] = 8;
}
}
} // A=3 primary cell has 2 TBs } // A=3 primary cell has 2 TBs
else if ((num_ack_nak == 3) else if ((num_ack_nak == 3)
&& (sched_ctl->round[1 - pCCid][harq_pid] < 8) && (sched_ctl->round[1 - pCCid][harq_pid] < 8)
...@@ -3419,13 +3457,26 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id, ...@@ -3419,13 +3457,26 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
|| ((pdu[0] == 1) && (pdu[1] >= 2))) { // one ACK || ((pdu[0] == 1) && (pdu[1] >= 2))) { // one ACK
sched_ctl->round[1 - pCCid][harq_pid]++; sched_ctl->round[1 - pCCid][harq_pid]++;
sched_ctl->tbcnt[1 - pCCid][harq_pid] = 1; sched_ctl->tbcnt[1 - pCCid][harq_pid] = 1;
} else // both NAK/DTX if (sched_ctl->round[1 - pCCid][harq_pid] == 4) {
sched_ctl->round[1 - pCCid][harq_pid] = 8;
sched_ctl->tbcnt[1 - pCCid][harq_pid] = 0;
}
} else { // both NAK/DTX
sched_ctl->round[1 - pCCid][harq_pid]++; sched_ctl->round[1 - pCCid][harq_pid]++;
if (sched_ctl->round[1 - pCCid][harq_pid] == 4) {
sched_ctl->round[1 - pCCid][harq_pid] = 8;
sched_ctl->tbcnt[1 - pCCid][harq_pid] = 0;
}
}
if (pdu[2] == 1) if (pdu[2] == 1)
sched_ctl->round[pCCid][harq_pid] = 8; sched_ctl->round[pCCid][harq_pid] = 8;
else else {
sched_ctl->round[pCCid][harq_pid]++; sched_ctl->round[pCCid][harq_pid]++;
if (sched_ctl->round[pCCid][harq_pid] == 4) {
sched_ctl->round[pCCid][harq_pid] = 8;
}
}
} // A=3 secondary cell has 2 TBs } // A=3 secondary cell has 2 TBs
#if MAX_NUM_CCs>1 #if MAX_NUM_CCs>1
else if ((num_ack_nak == 4) else if ((num_ack_nak == 4)
...@@ -3454,8 +3505,17 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id, ...@@ -3454,8 +3505,17 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
|| ((pdu[0] == 1) && (pdu[1] >= 2))) { // one ACK || ((pdu[0] == 1) && (pdu[1] >= 2))) { // one ACK
sched_ctl->round[0][harq_pid]++; sched_ctl->round[0][harq_pid]++;
sched_ctl->tbcnt[0][harq_pid] = 1; sched_ctl->tbcnt[0][harq_pid] = 1;
} else // both NAK/DTX if (sched_ctl->round[0][harq_pid] == 4) {
sched_ctl->round[0][harq_pid] = 8;
sched_ctl->tbcnt[0][harq_pid] = 0;
}
} else { // both NAK/DTX
sched_ctl->round[0][harq_pid]++; sched_ctl->round[0][harq_pid]++;
if (sched_ctl->round[0][harq_pid] == 4) {
sched_ctl->round[0][harq_pid] = 8;
sched_ctl->tbcnt[0][harq_pid] = 0;
}
}
if ((pdu[2] == 1) && (pdu[3] == 1)) { // both ACK if ((pdu[2] == 1) && (pdu[3] == 1)) { // both ACK
sched_ctl->round[1][harq_pid] = 8; sched_ctl->round[1][harq_pid] = 8;
...@@ -3464,8 +3524,17 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id, ...@@ -3464,8 +3524,17 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
|| ((pdu[2] == 1) && (pdu[3] >= 2))) { // one ACK || ((pdu[2] == 1) && (pdu[3] >= 2))) { // one ACK
sched_ctl->round[1][harq_pid]++; sched_ctl->round[1][harq_pid]++;
sched_ctl->tbcnt[1][harq_pid] = 1; sched_ctl->tbcnt[1][harq_pid] = 1;
} else // both NAK/DTX if (sched_ctl->round[1][harq_pid] == 4) {
sched_ctl->round[1][harq_pid] = 8;
sched_ctl->tbcnt[1][harq_pid] = 0;
}
} else { // both NAK/DTX
sched_ctl->round[1][harq_pid]++; sched_ctl->round[1][harq_pid]++;
if (sched_ctl->round[1][harq_pid] == 4) {
sched_ctl->round[1][harq_pid] = 8;
sched_ctl->tbcnt[1][harq_pid] = 0;
}
}
} // A=4 both serving cells have 2 TBs } // A=4 both serving cells have 2 TBs
#endif #endif
break; break;
...@@ -3480,8 +3549,13 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id, ...@@ -3480,8 +3549,13 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
if (pdu[j] == 1) { if (pdu[j] == 1) {
sched_ctl->round[i][harq_pid] = 8; sched_ctl->round[i][harq_pid] = 8;
sched_ctl->tbcnt[i][harq_pid] = 0; sched_ctl->tbcnt[i][harq_pid] = 0;
} else if (pdu[j] == 2) } else if (pdu[j] == 2) {
sched_ctl->round[i][harq_pid]++; sched_ctl->round[i][harq_pid]++;
if (sched_ctl->round[i][harq_pid] == 4) {
sched_ctl->round[i][harq_pid] = 8;
sched_ctl->tbcnt[i][harq_pid] = 0;
}
}
else else
AssertFatal(1 == 0, AssertFatal(1 == 0,
"Illegal harq_ack value for CC %d harq_pid %d (%d) UE %d/%x\n", "Illegal harq_ack value for CC %d harq_pid %d (%d) UE %d/%x\n",
...@@ -3496,13 +3570,25 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id, ...@@ -3496,13 +3570,25 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
&& (pdu[j] == 1) && (pdu[j + 1] == 2)) { && (pdu[j] == 1) && (pdu[j + 1] == 2)) {
sched_ctl->round[i][harq_pid]++; sched_ctl->round[i][harq_pid]++;
sched_ctl->tbcnt[i][harq_pid] = 1; sched_ctl->tbcnt[i][harq_pid] = 1;
if (sched_ctl->round[i][harq_pid] == 4) {
sched_ctl->round[i][harq_pid] = 8;
sched_ctl->tbcnt[i][harq_pid] = 0;
}
} else if ((sched_ctl->tbcnt[i][harq_pid] == 2) } else if ((sched_ctl->tbcnt[i][harq_pid] == 2)
&& (pdu[j] == 2) && (pdu[j + 1] == 1)) { && (pdu[j] == 2) && (pdu[j + 1] == 1)) {
sched_ctl->round[i][harq_pid]++; sched_ctl->round[i][harq_pid]++;
sched_ctl->tbcnt[i][harq_pid] = 1; sched_ctl->tbcnt[i][harq_pid] = 1;
if (sched_ctl->round[i][harq_pid] == 4) {
sched_ctl->round[i][harq_pid] = 8;
sched_ctl->tbcnt[i][harq_pid] = 0;
}
} else if ((sched_ctl->tbcnt[i][harq_pid] == 2) } else if ((sched_ctl->tbcnt[i][harq_pid] == 2)
&& (pdu[j] == 2) && (pdu[j + 1] == 2)) { && (pdu[j] == 2) && (pdu[j + 1] == 2)) {
sched_ctl->round[i][harq_pid]++; sched_ctl->round[i][harq_pid]++;
if (sched_ctl->round[i][harq_pid] == 4) {
sched_ctl->round[i][harq_pid] = 8;
sched_ctl->tbcnt[i][harq_pid] = 0;
}
} else } else
AssertFatal(1 == 0, AssertFatal(1 == 0,
"Illegal combination for CC %d harq_pid %d (%d,%d,%d) UE %d/%x\n", "Illegal combination for CC %d harq_pid %d (%d,%d,%d) UE %d/%x\n",
...@@ -3516,6 +3602,10 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id, ...@@ -3516,6 +3602,10 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
sched_ctl->tbcnt[i][harq_pid] = 0; sched_ctl->tbcnt[i][harq_pid] = 0;
} else if (pdu[j] == 2) { } else if (pdu[j] == 2) {
sched_ctl->round[i][harq_pid]++; sched_ctl->round[i][harq_pid]++;
if (sched_ctl->round[i][harq_pid] == 4) {
sched_ctl->round[i][harq_pid] = 8;
sched_ctl->tbcnt[i][harq_pid] = 0;
}
} else } else
AssertFatal(1 == 0, AssertFatal(1 == 0,
"Illegal hack_nak value %d for CC %d harq_pid %d UE %d/%x\n", "Illegal hack_nak value %d for CC %d harq_pid %d UE %d/%x\n",
......
...@@ -212,6 +212,30 @@ rx_sdu(const module_id_t enb_mod_idP, ...@@ -212,6 +212,30 @@ rx_sdu(const module_id_t enb_mod_idP,
UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes = 0; UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes = 0;
} else } else
UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]++; UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]++;
first_rb = UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid];
// Program NACK for PHICH
LOG_D(MAC,
"Programming PHICH NACK for rnti %x harq_pid %d (first_rb %d)\n",
current_rnti, harq_pid, first_rb);
nfapi_hi_dci0_request_t *hi_dci0_req = &mac->HI_DCI0_req[CC_idP];
nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body;
nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu =
&hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi];
memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t));
hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE;
hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu);
hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG;
hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = first_rb;
hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0;
hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 0;
hi_dci0_req_body->number_of_hi++;
hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP,subframeP, 0);
hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG;
hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP,subframeP, 4);
hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST;
return; return;
} }
...@@ -251,6 +275,9 @@ rx_sdu(const module_id_t enb_mod_idP, ...@@ -251,6 +275,9 @@ rx_sdu(const module_id_t enb_mod_idP,
ra[RA_id].Msg3_subframe = (ra[RA_id].Msg3_subframe + 8) % 10; ra[RA_id].Msg3_subframe = (ra[RA_id].Msg3_subframe + 8) % 10;
add_msg3(enb_mod_idP, CC_idP, &ra[RA_id], frameP, subframeP); add_msg3(enb_mod_idP, CC_idP, &ra[RA_id], frameP, subframeP);
} }
/* TODO: program NACK for PHICH? */
return; return;
} }
} else { } else {
...@@ -1448,6 +1475,10 @@ schedule_ulsch_rnti(module_id_t module_idP, ...@@ -1448,6 +1475,10 @@ schedule_ulsch_rnti(module_id_t module_idP,
T_INT(first_rb[CC_id]), T_INT(first_rb[CC_id]),
T_INT(rb_table[rb_table_index]), T_INT(round)); T_INT(rb_table[rb_table_index]), T_INT(round));
#if 0
/* This is done in rx_sdu, as it has to.
* Since the code is a bit different, let's keep this version here for review, in case of problem.
*/
// fill in NAK information // fill in NAK information
hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi];
...@@ -1471,6 +1502,7 @@ schedule_ulsch_rnti(module_id_t module_idP, ...@@ -1471,6 +1502,7 @@ schedule_ulsch_rnti(module_id_t module_idP,
UE_template->first_rb_ul[harq_pid], UE_template->first_rb_ul[harq_pid],
UE_template->nb_rb_ul[harq_pid], UE_template->nb_rb_ul[harq_pid],
UE_template->TBS_UL[harq_pid], round); UE_template->TBS_UL[harq_pid], round);
#endif
// Add UL_config PDUs // Add UL_config PDUs
LOG_D(MAC, LOG_D(MAC,
"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n",
......
...@@ -734,7 +734,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, ...@@ -734,7 +734,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id,
// control channel or retransmission // control channel or retransmission
/* TODO: do we have to check for retransmission? */ /* TODO: do we have to check for retransmission? */
if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED || round > 0) { if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED || round != 8) {
nb_rbs_required_remaining_1[CC_id][UE_id] = nb_rbs_required_remaining_1[CC_id][UE_id] =
nb_rbs_required[CC_id][UE_id]; nb_rbs_required[CC_id][UE_id];
} else { } else {
......
...@@ -35,6 +35,9 @@ ...@@ -35,6 +35,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "COMMON/s1ap_messages_types.h"
#include "COMMON/rrc_messages_types.h"
#include "collection/tree.h" #include "collection/tree.h"
#include "rrc_types_NB_IoT.h" #include "rrc_types_NB_IoT.h"
#include "COMMON/platform_constants.h" #include "COMMON/platform_constants.h"
......
...@@ -290,6 +290,7 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req( ...@@ -290,6 +290,7 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req(
hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS; hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS;
gtpv1u_teid_data_t *gtpv1u_teid_data_p = NULL; gtpv1u_teid_data_t *gtpv1u_teid_data_p = NULL;
protocol_ctxt_t ctxt; protocol_ctxt_t ctxt;
NwGtpv1uRcT rc;
switch(pUlpApi->apiType) { switch(pUlpApi->apiType) {
/* Here there are two type of messages handled: /* Here there are two type of messages handled:
...@@ -314,6 +315,12 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req( ...@@ -314,6 +315,12 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req(
gtpv1u_eNB_write_dump_socket(buffer,buffer_len); gtpv1u_eNB_write_dump_socket(buffer,buffer_len);
#endif #endif
rc = nwGtpv1uMsgDelete(RC.gtpv1u_data_g->gtpv1u_stack,
pUlpApi->apiInfo.recvMsgInfo.hMsg);
if (rc != NW_GTPV1U_OK) {
LOG_E(GTPU, "nwGtpv1uMsgDelete failed: 0x%x\n", rc);
}
//----------------------- //-----------------------
// GTPV1U->PDCP mapping // GTPV1U->PDCP mapping
//----------------------- //-----------------------
......
...@@ -905,7 +905,6 @@ int main( int argc, char **argv ) ...@@ -905,7 +905,6 @@ int main( int argc, char **argv )
int ret; int ret;
#endif #endif
start_background_system();
if ( load_configmodule(argc,argv) == NULL) { if ( load_configmodule(argc,argv) == NULL) {
exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
} }
...@@ -1210,9 +1209,6 @@ int main( int argc, char **argv ) ...@@ -1210,9 +1209,6 @@ int main( int argc, char **argv )
sync_var=0; sync_var=0;
pthread_cond_broadcast(&sync_cond); pthread_cond_broadcast(&sync_cond);
pthread_mutex_unlock(&sync_mutex); pthread_mutex_unlock(&sync_mutex);
printf("About to call end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__);
end_configmodule();
printf("Called end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__);
// wait for end of program // wait for end of program
printf("TYPE <CTRL-C> TO TERMINATE\n"); printf("TYPE <CTRL-C> TO TERMINATE\n");
...@@ -1272,6 +1268,9 @@ int main( int argc, char **argv ) ...@@ -1272,6 +1268,9 @@ int main( int argc, char **argv )
} }
free_lte_top(); free_lte_top();
printf("About to call end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__);
end_configmodule();
printf("Called end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__);
pthread_cond_destroy(&sync_cond); pthread_cond_destroy(&sync_cond);
pthread_mutex_destroy(&sync_mutex); pthread_mutex_destroy(&sync_mutex);
......
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