Commit 7d2f74bd authored by Raymond Knopp's avatar Raymond Knopp

Merge branch 'develop' into RU-RAU-split-parallel-EMUFH-phy-test-merge

parents a6edc8c5 4aa8ac6d
......@@ -280,7 +280,7 @@ set(protobuf_generated_dir ${OPENAIR_BIN_DIR})
# 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")
set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-86.asn)
......@@ -2239,6 +2239,7 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr
${XFORMS_SOURCE}
${T_SOURCE}
${CONFIG_SOURCES}
${SHLIB_LOADER_SOURCES}
)
target_link_libraries (${myExe}
......
......@@ -626,12 +626,17 @@ function main() {
if [ "$SIMUS_PHY" = "1" ] ; then
# lte unitary simulators compilation
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
compilations \
lte-simulators $f \
$f $dbin/$f.$REL
done
compilations \
lte-simulators coding \
libcoding.so $dbin/libcoding.so
fi
# Core simulators
......
......@@ -210,7 +210,7 @@ install_protobuf_from_source(){
#cd protobuf-2.6.1/
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
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/
./configure
echo "Compiling protobuf"
......
......@@ -328,8 +328,11 @@ int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, Me
/* Increment the global 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,
sizeof(MessageHeader) + message->ittiMsgHeader.ittiMsgSize);
#endif
if (destination_task_id != TASK_UNKNOWN) {
......@@ -426,8 +429,11 @@ int itti_try_send_msg_to_task(task_id_t destination_task_id, instance_t instance
/* Increment the global 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,
sizeof(MessageHeader) + message->ittiMsgHeader.ittiMsgSize);
#endif
if (destination_task_id != TASK_UNKNOWN) {
......@@ -721,8 +727,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);
#if 0
/* itti dump is disabled */
/* Register the thread in itti dump */
itti_dump_thread_use_ring_buffer();
#endif
/* Mark the thread as using LFDS queue */
lfds611_queue_use(itti_desc.tasks[task_id].message_queue);
......@@ -853,7 +862,10 @@ int itti_init(task_id_t task_max, thread_id_t thread_max, MessagesIds messages_i
itti_desc.wait_tasks = 0;
itti_desc.created_tasks = 0;
itti_desc.ready_tasks = 0;
#if 0
/* itti dump is disabled */
itti_dump_init (messages_definition_xml, dump_file_name);
#endif
CHECK_INIT_RETURN(timer_init ());
......@@ -920,7 +932,10 @@ void itti_wait_tasks_end(void)
exit (0);
}
#if 0
/* itti dump is disabled */
itti_dump_exit();
#endif
}
void itti_send_terminate_message(task_id_t task_id)
......
......@@ -1489,7 +1489,9 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe)
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_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
......@@ -1510,11 +1512,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];
AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n");
dlsch0_harq->status = SCH_IDLE;
/*if ((dlsch1_harq == NULL)||
((dlsch1_harq!=NULL)&&
(dlsch1_harq->status == SCH_IDLE)))*/
dlsch0->harq_mask &= ~(1<<harq_pid);
if (dlsch0_harq->round >= after_rounds) {
dlsch0_harq->status = SCH_IDLE;
/*if ((dlsch1_harq == NULL)||
((dlsch1_harq!=NULL)&&
(dlsch1_harq->status == SCH_IDLE)))*/
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);
}
......@@ -1534,17 +1538,28 @@ 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];
AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n");
dlsch0_harq->status = SCH_IDLE;
if ((dlsch1_harq == NULL)||
((dlsch1_harq!=NULL)&&
(dlsch1_harq->status == SCH_IDLE)))
dlsch0->harq_mask &= ~(1<<harq_pid);
if (dlsch0_harq->round >= after_rounds) {
dlsch0_harq->status = SCH_IDLE;
if ((dlsch1_harq == NULL)||
((dlsch1_harq!=NULL)&&
(dlsch1_harq->status == SCH_IDLE)))
dlsch0->harq_mask &= ~(1<<harq_pid);
}
}
}
}
}
}
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 M,Mtx=0;
......@@ -1645,7 +1660,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];
// 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 (ulsch_harq->o_ACK[i] != 1)
//printf("got NACK %d.%d rnti %d harq %d\n", frame, subframe, rnti, eNB->dlsch[UE_id][0]->harq_ids[(subframe+6)%10]);
......@@ -1674,13 +1689,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];
// release DLSCH if needed
if (ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff);
if (M==1 && ulsch_harq->O_ACK==1 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
else if (M==1 && ulsch_harq->O_ACK==2 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff);
/* TODO: review this code, it's most certainly wrong.
* We have to release the proper HARQ in case of ACK or NACK if max retransmission reached.
* 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) {
// spatial bundling
release_harq(eNB,UE_id,0,frame,subframe,1<<i);
release_harq(eNB,UE_id,1,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, ulsch_harq->o_ACK[i] == 1);
}
}
}
......@@ -1742,7 +1761,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]);
pdu->harq_indication_fdd_rel13.harq_tb_n[0] = harq_ack[0];
// 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[0] != 1)
//printf("got NACK %d.%d rnti %d harq %d\n", frame, subframe, uci->rnti, eNB->dlsch[UE_id][0]->harq_ids[(subframe+6)%10]);
......@@ -1765,8 +1784,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[1] = harq_ack[1];
// release DLSCH if needed
if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
if (harq_ack[1] == 1) release_harq(eNB,UE_id,1,frame,subframe,0xffff);
release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
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);
}
......@@ -1787,7 +1806,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]);
pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = harq_ack[0];
// 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) {
pdu->harq_indication_tdd_rel13.number_of_ack_nack = 2;
......@@ -1797,8 +1816,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[1].bundling.value_0 = harq_ack[1];
// release all DLSCH if needed
if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
if (harq_ack[1] == 1) release_harq(eNB,UE_id,1,frame,subframe,0xffff);
release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
release_harq(eNB,UE_id,1,frame,subframe,0xffff, harq_ack[1] == 1);
}
break;
case 1: // multiplexing
......@@ -1810,7 +1829,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]);
pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0];
// 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) {
pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG;
......@@ -1820,8 +1839,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[1].multiplex.value_0 = harq_ack[1];
// release all DLSCH if needed
if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
if (harq_ack[1] == 1) release_harq(eNB,UE_id,1,frame,subframe,0xffff);
release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
release_harq(eNB,UE_id,1,frame,subframe,0xffff, harq_ack[1] == 1);
}
else { // num_pucch_resources (M) > 1
pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG;
......@@ -1832,8 +1851,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 == 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
release_harq(eNB,UE_id,0,frame,subframe,tdd_multiplexing_mask);
release_harq(eNB,UE_id,1,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, 1 /* force release? previous code was unconditional */);
}
break;
case 2: // special bundling (SR collision)
......@@ -1844,26 +1863,27 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
switch (harq_ack[0]) {
case 0:
/* TODO: release_harq here? this whole code looks suspicious */
break;
case 1: // check if M=1,4,7
if (uci->num_pucch_resources == 1 || uci->num_pucch_resources == 4 ||
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,1,frame,subframe,0xffff);
release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1);
release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1);
}
break;
case 2: // check if M=2,5,8
if (uci->num_pucch_resources == 2 || tdd_config5_sf2scheds == 2 ||
tdd_config5_sf2scheds == 5 || tdd_config5_sf2scheds == 8) {
release_harq(eNB,UE_id,0,frame,subframe,0xffff);
release_harq(eNB,UE_id,1,frame,subframe,0xffff);
release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1);
release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1);
}
break;
case 3: // check if M=3,6,9
if (uci->num_pucch_resources == 3 || tdd_config5_sf2scheds == 3 ||
tdd_config5_sf2scheds == 6 || tdd_config5_sf2scheds == 9) {
release_harq(eNB,UE_id,0,frame,subframe,0xffff);
release_harq(eNB,UE_id,1,frame,subframe,0xffff);
release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1);
release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1);
}
break;
}
......
......@@ -131,7 +131,7 @@ message flex_enb_config_request {
message flex_enb_config_reply {
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;
optional uint32 device_spec = 4;
}
......
......@@ -60,37 +60,124 @@
extern uint16_t sf_ahead;
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;
config_get(flexranParams, sizeof(flexranParams)/sizeof(paramdef_t), CONFIG_STRING_NETWORK_CONTROLLER_CONFIG);
if (!RC.flexran) {
RC.flexran = calloc(RC.nb_L1_inst, sizeof(flexran_agent_info_t*));
AssertFatal(RC.flexran != NULL,
RC.flexran = calloc(num_enbs, sizeof(flexran_agent_info_t*));
AssertFatal(RC.flexran,
"can't ALLOCATE %zu Bytes for %d flexran agent info with size %zu\n",
RC.nb_L1_inst * sizeof(flexran_agent_info_t*),
RC.nb_L1_inst, sizeof(flexran_agent_info_t*));
num_enbs * 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 < RC.nb_L1_inst; i++) {
for (i = 0; i < num_enbs; i++) {
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",
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" */
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));
//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_port = *(flexranParams[FLEXRAN_PORT_IDX].uptr);
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]->enb_id = i;
RC.flexran[i]->node_ctrl_state = strcasecmp(*(flexranParams[FLEXRAN_AWAIT_RECONF_IDX].strptr), "yes") == 0 ? ENB_WAIT : ENB_NORMAL_OPERATION;
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) {
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);
// 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);
......@@ -127,7 +127,7 @@ void *receive_thread(void *args) {
if (msg != NULL){
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;
goto error;
}
......@@ -190,13 +190,6 @@ int flexran_agent_start(mid_t mod_id)
LOG_I(FLEXRAN_AGENT, "FlexRAN Agent for eNB %d is DISABLED\n", mod_id);
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
......
......@@ -804,7 +804,6 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F
xid = (enb_config_req_msg->header)->xid;
int i, j;
int enb_id = mod_id;
Protocol__FlexEnbConfigReply *enb_config_reply_msg;
enb_config_reply_msg = malloc(sizeof(Protocol__FlexEnbConfigReply));
......@@ -816,10 +815,10 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F
goto error;
enb_config_reply_msg->header = header;
enb_config_reply_msg->enb_id = mod_id;
enb_config_reply_msg->enb_id = RC.flexran[mod_id]->agent_id;
enb_config_reply_msg->has_enb_id = 1;
enb_config_reply_msg->n_cell_config = MAX_NUM_CCs;
Protocol__FlexCellConfig **cell_conf;
......@@ -832,61 +831,60 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F
protocol__flex_cell_config__init(cell_conf[i]);
cell_conf[i]->phy_cell_id = 1;
cell_conf[i]->has_phy_cell_id = flexran_get_cell_id(enb_id,i);
cell_conf[i]->has_phy_cell_id = flexran_get_cell_id(mod_id,i);
cell_conf[i]->cell_id = i;
cell_conf[i]->has_cell_id = 1;
cell_conf[i]->pusch_hopping_offset = flexran_get_hopping_offset(enb_id,i);
cell_conf[i]->pusch_hopping_offset = flexran_get_hopping_offset(mod_id,i);
cell_conf[i]->has_pusch_hopping_offset = 1;
if (flexran_get_hopping_mode(enb_id,i) == 0) {
if (flexran_get_hopping_mode(mod_id,i) == 0) {
cell_conf[i]->hopping_mode = PROTOCOL__FLEX_HOPPING_MODE__FLHM_INTER;
} else if(flexran_get_hopping_mode(enb_id,i) == 1) {
} else if(flexran_get_hopping_mode(mod_id,i) == 1) {
cell_conf[i]->hopping_mode = PROTOCOL__FLEX_HOPPING_MODE__FLHM_INTERINTRA;
}
cell_conf[i]->has_hopping_mode = 1;
cell_conf[i]->n_sb = flexran_get_n_SB(enb_id,i);
cell_conf[i]->n_sb = flexran_get_n_SB(mod_id,i);
cell_conf[i]->has_n_sb = 1;
if (flexran_get_phich_resource(enb_id,i) == 0) {
if (flexran_get_phich_resource(mod_id,i) == 0) {
cell_conf[i]->phich_resource = PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_ONE_SIXTH; //0
} else if (flexran_get_phich_resource(enb_id,i) == 1) {
} else if (flexran_get_phich_resource(mod_id,i) == 1) {
cell_conf[i]->phich_resource = PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_HALF; //1
} else if (flexran_get_phich_resource(enb_id,i) == 2) {
} else if (flexran_get_phich_resource(mod_id,i) == 2) {
cell_conf[i]->phich_resource = PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_ONE; // 2
} else if (flexran_get_phich_resource(enb_id,i) == 3) {
} else if (flexran_get_phich_resource(mod_id,i) == 3) {
cell_conf[i]->phich_resource = PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_TWO;//3
}
cell_conf[i]->has_phich_resource = 1;
if (flexran_get_phich_duration(enb_id,i) == 0) {
if (flexran_get_phich_duration(mod_id,i) == 0) {
cell_conf[i]->phich_duration = PROTOCOL__FLEX_PHICH_DURATION__FLPD_NORMAL;
} else if(flexran_get_phich_duration(enb_id,i) == 1) {
} else if(flexran_get_phich_duration(mod_id,i) == 1) {
cell_conf[i]->phich_duration = PROTOCOL__FLEX_PHICH_DURATION__FLPD_EXTENDED;
}
cell_conf[i]->has_phich_duration = 1;
//TODO: Fill in with actual value, See TS 36.211, section 6.9
cell_conf[i]->init_nr_pdcch_ofdm_sym = flexran_get_num_pdcch_symb(enb_id,i);
cell_conf[i]->has_init_nr_pdcch_ofdm_sym = 0;
//TODO: Fill in with actual value
/* Protocol__FlexSiConfig *si_config; */
/* si_config = malloc(sizeof(Protocol__FlexSiConfig)); */
/* if(si_config == NULL) */
/* goto error; */
/* protocol__flex_si_config__init(si_config); */
/* //TODO: Fill in with actual value, Frame number to apply the SI configuration */
/* si_config->sfn = 1; */
/* si_config->has_sfn = 1; */
/* //TODO: Fill in with actual value, the length of SIB1 in bytes */
/* si_config->sib1_length = get_sib1_length(enb_id,i); */
/* si_config->has_sib1_length = 1; */
/* //TODO: Fill in with actual value, Scheduling window for all SIs in SF */
/* si_config->si_window_length = (uint32_t) get_si_window_length(enb_id,i); */
/* si_config->has_si_window_length = 1; */
/* //TODO: Fill in with actual value, the number of SI messages */
/* si_config->n_si_message=1; */
cell_conf[i]->init_nr_pdcch_ofdm_sym = flexran_get_num_pdcch_symb(mod_id,i);
cell_conf[i]->has_init_nr_pdcch_ofdm_sym = 1;
Protocol__FlexSiConfig *si_config;
si_config = malloc(sizeof(Protocol__FlexSiConfig));
if(si_config == NULL)
goto error;
protocol__flex_si_config__init(si_config);
si_config->sfn = flexran_get_current_system_frame_num(mod_id);
si_config->has_sfn = 1;
si_config->sib1_length = flexran_get_sib1_length(mod_id,i);
si_config->has_sib1_length = 1;
si_config->si_window_length = (uint32_t) flexran_get_si_window_length(mod_id, i);
si_config->has_si_window_length = 1;
si_config->n_si_message = 0;
/* Protocol__FlexSiMessage **si_message; */
/* si_message = malloc(sizeof(Protocol__FlexSiMessage *) * si_config->n_si_message); */
/* if(si_message == NULL) */
......@@ -906,44 +904,42 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F
/* if(si_config->n_si_message > 0){ */
/* si_config->si_message = si_message; */
/* } */
/* cell_conf[i]->si_config = si_config; */
cell_conf[i]->dl_bandwidth = flexran_get_N_RB_DL(enb_id,i);
cell_conf[i]->si_config = si_config;
cell_conf[i]->dl_bandwidth = flexran_get_N_RB_DL(mod_id,i);
cell_conf[i]->has_dl_bandwidth = 1;
cell_conf[i]->ul_bandwidth = flexran_get_N_RB_UL(enb_id,i);
cell_conf[i]->ul_bandwidth = flexran_get_N_RB_UL(mod_id,i);
cell_conf[i]->has_ul_bandwidth = 1;
if (flexran_get_ul_cyclic_prefix_length(enb_id, i) == 0) {
if (flexran_get_ul_cyclic_prefix_length(mod_id, i) == 0) {
cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_NORMAL;
} else if(flexran_get_ul_cyclic_prefix_length(enb_id, i) == 1) {
cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_EXTENDED;
} else if(flexran_get_ul_cyclic_prefix_length(mod_id, i) == 1) {
cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_EXTENDED;
}
cell_conf[i]->has_ul_cyclic_prefix_length = 1;
if (flexran_get_ul_cyclic_prefix_length(enb_id,i) == 0) {
if (flexran_get_ul_cyclic_prefix_length(mod_id,i) == 0) {
cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_DL_CYCLIC_PREFIX_LENGTH__FLDCPL_NORMAL;
} else if (flexran_get_ul_cyclic_prefix_length(enb_id,i) == 1) {
} else if (flexran_get_ul_cyclic_prefix_length(mod_id,i) == 1) {
cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_DL_CYCLIC_PREFIX_LENGTH__FLDCPL_EXTENDED;
}
cell_conf[i]->has_dl_cyclic_prefix_length = 1;
//TODO: Fill in with actual value, number of cell specific antenna ports. Currently single port support
cell_conf[i]->antenna_ports_count = 1;
cell_conf[i]->antenna_ports_count = flexran_get_antenna_ports(mod_id, i);
cell_conf[i]->has_antenna_ports_count = 1;
if (flexran_get_duplex_mode(enb_id,i) == 1) {
if (flexran_get_duplex_mode(mod_id,i) == 1) {
cell_conf[i]->duplex_mode = PROTOCOL__FLEX_DUPLEX_MODE__FLDM_FDD;
} else if(flexran_get_duplex_mode(enb_id,i) == 0) {
} else if(flexran_get_duplex_mode(mod_id,i) == 0) {
cell_conf[i]->duplex_mode = PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD;
}
cell_conf[i]->has_duplex_mode = 1;
//TODO: Fill in with actual value, DL/UL subframe assignment. TDD only
cell_conf[i]->subframe_assignment = flexran_get_subframe_assignment(enb_id, i);
cell_conf[i]->has_subframe_assignment = 0;
//TODO: Fill in with actual value, TDD only. See TS 36.211, table 4.2.1
cell_conf[i]->special_subframe_patterns = flexran_get_special_subframe_assignment(enb_id,i);
cell_conf[i]->has_special_subframe_patterns = 0;
cell_conf[i]->subframe_assignment = flexran_get_subframe_assignment(mod_id, i);
cell_conf[i]->has_subframe_assignment = 1;
cell_conf[i]->special_subframe_patterns = flexran_get_special_subframe_assignment(mod_id,i);
cell_conf[i]->has_special_subframe_patterns = 1;
//TODO: Fill in with actual value, The MBSFN radio frame period
cell_conf[i]->n_mbsfn_subframe_config_rfperiod = 0;
uint32_t *elem_rfperiod;
......@@ -954,7 +950,7 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F
elem_rfperiod[j] = 1;
}
cell_conf[i]->mbsfn_subframe_config_rfperiod = elem_rfperiod;
//TODO: Fill in with actual value, The MBSFN radio frame offset
cell_conf[i]->n_mbsfn_subframe_config_rfoffset = 0;
uint32_t *elem_rfoffset;
......@@ -965,7 +961,7 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F
elem_rfoffset[j] = 1;
}
cell_conf[i]->mbsfn_subframe_config_rfoffset = elem_rfoffset;
//TODO: Fill in with actual value, Bitmap indicating the MBSFN subframes
cell_conf[i]->n_mbsfn_subframe_config_sfalloc = 0;
uint32_t *elem_sfalloc;
......@@ -976,63 +972,62 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F
elem_sfalloc[j] = 1;
}
cell_conf[i]->mbsfn_subframe_config_sfalloc = elem_sfalloc;
cell_conf[i]->prach_config_index = flexran_get_prach_ConfigIndex(enb_id,i);
cell_conf[i]->prach_config_index = flexran_get_prach_ConfigIndex(mod_id,i);
cell_conf[i]->has_prach_config_index = 1;
cell_conf[i]->prach_freq_offset = flexran_get_prach_FreqOffset(enb_id,i);
cell_conf[i]->prach_freq_offset = flexran_get_prach_FreqOffset(mod_id,i);
cell_conf[i]->has_prach_freq_offset = 1;
cell_conf[i]->ra_response_window_size = flexran_get_ra_ResponseWindowSize(enb_id,i);
cell_conf[i]->ra_response_window_size = flexran_get_ra_ResponseWindowSize(mod_id,i);
cell_conf[i]->has_ra_response_window_size = 1;
cell_conf[i]->mac_contention_resolution_timer = flexran_get_mac_ContentionResolutionTimer(enb_id,i);
cell_conf[i]->mac_contention_resolution_timer = flexran_get_mac_ContentionResolutionTimer(mod_id,i);
cell_conf[i]->has_mac_contention_resolution_timer = 1;
cell_conf[i]->max_harq_msg3tx = flexran_get_maxHARQ_Msg3Tx(enb_id,i);
cell_conf[i]->max_harq_msg3tx = flexran_get_maxHARQ_Msg3Tx(mod_id,i);
cell_conf[i]->has_max_harq_msg3tx = 1;
cell_conf[i]->n1pucch_an = flexran_get_n1pucch_an(enb_id,i);
cell_conf[i]->n1pucch_an = flexran_get_n1pucch_an(mod_id,i);
cell_conf[i]->has_n1pucch_an = 1;
cell_conf[i]->deltapucch_shift = flexran_get_deltaPUCCH_Shift(enb_id,i);
cell_conf[i]->deltapucch_shift = flexran_get_deltaPUCCH_Shift(mod_id,i);
cell_conf[i]->has_deltapucch_shift = 1;
cell_conf[i]->nrb_cqi = flexran_get_nRB_CQI(enb_id,i);
cell_conf[i]->nrb_cqi = flexran_get_nRB_CQI(mod_id,i);
cell_conf[i]->has_nrb_cqi = 1;
cell_conf[i]->srs_subframe_config = flexran_get_srs_SubframeConfig(enb_id,i);
cell_conf[i]->srs_subframe_config = flexran_get_srs_SubframeConfig(mod_id,i);
cell_conf[i]->has_srs_subframe_config = 1;
cell_conf[i]->srs_bw_config = flexran_get_srs_BandwidthConfig(enb_id,i);
cell_conf[i]->srs_bw_config = flexran_get_srs_BandwidthConfig(mod_id,i);
cell_conf[i]->has_srs_bw_config = 1;
cell_conf[i]->srs_mac_up_pts = flexran_get_srs_MaxUpPts(enb_id,i);
cell_conf[i]->srs_mac_up_pts = flexran_get_srs_MaxUpPts(mod_id,i);
cell_conf[i]->has_srs_mac_up_pts = 1;
cell_conf[i]->dl_freq = flexran_agent_get_operating_dl_freq (enb_id,i);
cell_conf[i]->dl_freq = flexran_agent_get_operating_dl_freq (mod_id,i);
cell_conf[i]->has_dl_freq = 1;
cell_conf[i]->ul_freq = flexran_agent_get_operating_ul_freq (enb_id, i);
cell_conf[i]->ul_freq = flexran_agent_get_operating_ul_freq (mod_id, i);
cell_conf[i]->has_ul_freq = 1;
cell_conf[i]->eutra_band = flexran_agent_get_operating_eutra_band (enb_id,i);
cell_conf[i]->eutra_band = flexran_agent_get_operating_eutra_band (mod_id,i);
cell_conf[i]->has_eutra_band = 1;
cell_conf[i]->dl_pdsch_power = flexran_agent_get_operating_pdsch_refpower(enb_id, i);
cell_conf[i]->dl_pdsch_power = flexran_agent_get_operating_pdsch_refpower(mod_id, i);
cell_conf[i]->has_dl_pdsch_power = 1;
cell_conf[i]->ul_pusch_power = flexran_agent_get_operating_pusch_p0 (enb_id,i);
cell_conf[i]->ul_pusch_power = flexran_agent_get_operating_pusch_p0 (mod_id,i);
cell_conf[i]->has_ul_pusch_power = 1;
if (flexran_get_enable64QAM(enb_id,i) == 0) {
if (flexran_get_enable64QAM(mod_id,i) == 0) {
cell_conf[i]->enable_64qam = PROTOCOL__FLEX_QAM__FLEQ_MOD_16QAM;
} else if(flexran_get_enable64QAM(enb_id,i) == 1) {
} else if(flexran_get_enable64QAM(mod_id,i) == 1) {
cell_conf[i]->enable_64qam = PROTOCOL__FLEX_QAM__FLEQ_MOD_64QAM;
}
cell_conf[i]->has_enable_64qam = 1;
cell_conf[i]->carrier_index = i;
cell_conf[i]->has_carrier_index = 1;
}
......
......@@ -138,12 +138,14 @@ typedef enum {
FLEXRAN_AGENT_TIMER_STATE_MAX,
} flexran_agent_timer_state_t;
#define FLEXRAN_CAP_LOL1 0x1
#define FLEXRAN_CAP_HIL1 0x2
#define FLEXRAN_CAP_LOL2 0x4 // is: MAC
#define FLEXRAN_CAP_HIL2 0x8 // is: RLC
#define FLEXRAN_CAP_PDCP 0x16
#define FLEXRAN_CAP_RRC 0x32
#define FLEXRAN_CAP_LOPHY 1
#define FLEXRAN_CAP_HIPHY 2
#define FLEXRAN_CAP_LOMAC 4
#define FLEXRAN_CAP_HIMAC 8
#define FLEXRAN_CAP_RLC 16
#define FLEXRAN_CAP_PDCP 32
#define FLEXRAN_CAP_SDAP 64
#define FLEXRAN_CAP_RRC 128
typedef enum {
ENB_NORMAL_OPERATION = 0x0,
......@@ -159,7 +161,8 @@ typedef struct {
uint16_t remote_port;
char *cache_name;
int enb_id;
mid_t mod_id;
uint64_t agent_id;
uint8_t capability_mask;
/* lock for waiting before starting or soft-restart */
......
......@@ -424,12 +424,15 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id,
}
} // 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++;
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);
mac_eNB_rrc_uplane_failure(module_idP,CC_id,frameP,subframeP,rnti);
UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
}// time > 60s
#endif
}
void
......
......@@ -3268,8 +3268,13 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
if (pdu[0] == 1) { // ACK
sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process
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
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 {
// one or two ACK/NAK bits
AssertFatal(num_ack_nak <= 2,
......@@ -3285,8 +3290,13 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
if ((num_ack_nak == 2)
&& (sched_ctl->round[CC_idP][harq_pid] < 8)
&& (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]++;
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)
&& (sched_ctl->round[CC_idP][harq_pid] < 8)
&& (sched_ctl->tbcnt[0][harq_pid] == 2)
......@@ -3297,11 +3307,20 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
&& (pdu[0] == 2) && (pdu[1] == 1))) {
sched_ctl->round[CC_idP][harq_pid]++;
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)
&& (sched_ctl->round[CC_idP][harq_pid] < 8)
&& (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]++;
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
AssertFatal(1 == 0,
"Illegal ACK/NAK/round combination (%d,%d,%d,%d,%d) for harq_pid %d, UE %d/%x\n",
......@@ -3327,12 +3346,18 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
pdu[1]);
if (pdu[0] == 1)
sched_ctl->round[pCCid][harq_pid] = 8;
else
else {
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)
sched_ctl->round[1 - pCCid][harq_pid] = 8;
else
else {
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
else if ((num_ack_nak == 3)
&& (sched_ctl->round[pCCid][harq_pid] < 8)
......@@ -3358,13 +3383,26 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
((pdu[0] == 1) && (pdu[1] == 2))) {
sched_ctl->round[pCCid][harq_pid]++;
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]++;
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)
sched_ctl->round[1 - pCCid][harq_pid] = 8;
else
else {
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
else if ((num_ack_nak == 3)
&& (sched_ctl->round[1 - pCCid][harq_pid] < 8)
......@@ -3390,13 +3428,26 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
|| ((pdu[0] == 1) && (pdu[1] >= 2))) { // one ACK
sched_ctl->round[1 - pCCid][harq_pid]++;
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]++;
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)
sched_ctl->round[pCCid][harq_pid] = 8;
else
else {
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
#if MAX_NUM_CCs>1
else if ((num_ack_nak == 4)
......@@ -3425,8 +3476,17 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
|| ((pdu[0] == 1) && (pdu[1] >= 2))) { // one ACK
sched_ctl->round[0][harq_pid]++;
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]++;
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
sched_ctl->round[1][harq_pid] = 8;
......@@ -3435,8 +3495,17 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
|| ((pdu[2] == 1) && (pdu[3] >= 2))) { // one ACK
sched_ctl->round[1][harq_pid]++;
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]++;
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
#endif
break;
......@@ -3451,8 +3520,13 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
if (pdu[j] == 1) {
sched_ctl->round[i][harq_pid] = 8;
sched_ctl->tbcnt[i][harq_pid] = 0;
} else if (pdu[j] == 2)
} else if (pdu[j] == 2) {
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
AssertFatal(1 == 0,
"Illegal harq_ack value for CC %d harq_pid %d (%d) UE %d/%x\n",
......@@ -3467,13 +3541,25 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
&& (pdu[j] == 1) && (pdu[j + 1] == 2)) {
sched_ctl->round[i][harq_pid]++;
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)
&& (pdu[j] == 2) && (pdu[j + 1] == 1)) {
sched_ctl->round[i][harq_pid]++;
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)
&& (pdu[j] == 2) && (pdu[j + 1] == 2)) {
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
AssertFatal(1 == 0,
"Illegal combination for CC %d harq_pid %d (%d,%d,%d) UE %d/%x\n",
......@@ -3487,6 +3573,10 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
sched_ctl->tbcnt[i][harq_pid] = 0;
} else if (pdu[j] == 2) {
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
AssertFatal(1 == 0,
"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,
UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes = 0;
} else
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;
}
......@@ -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;
add_msg3(enb_mod_idP, CC_idP, &ra[RA_id], frameP, subframeP);
}
/* TODO: program NACK for PHICH? */
return;
}
} else {
......@@ -1448,6 +1475,10 @@ schedule_ulsch_rnti(module_id_t module_idP,
T_INT(first_rb[CC_id]),
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
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,
UE_template->first_rb_ul[harq_pid],
UE_template->nb_rb_ul[harq_pid],
UE_template->TBS_UL[harq_pid], round);
#endif
// Add UL_config PDUs
LOG_D(MAC,
"[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,
// control channel or 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[CC_id][UE_id];
} else {
......
......@@ -35,6 +35,9 @@
#include <stdlib.h>
#include <string.h>
#include "COMMON/s1ap_messages_types.h"
#include "COMMON/rrc_messages_types.h"
#include "collection/tree.h"
#include "rrc_types_NB_IoT.h"
#include "COMMON/platform_constants.h"
......
......@@ -290,6 +290,7 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req(
hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS;
gtpv1u_teid_data_t *gtpv1u_teid_data_p = NULL;
protocol_ctxt_t ctxt;
NwGtpv1uRcT rc;
switch(pUlpApi->apiType) {
/* Here there are two type of messages handled:
......@@ -314,6 +315,12 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req(
gtpv1u_eNB_write_dump_socket(buffer,buffer_len);
#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
//-----------------------
......
......@@ -927,7 +927,6 @@ int main( int argc, char **argv )
int ret;
#endif
start_background_system();
if ( load_configmodule(argc,argv) == NULL) {
exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
}
......@@ -1232,9 +1231,6 @@ int main( int argc, char **argv )
sync_var=0;
pthread_cond_broadcast(&sync_cond);
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
printf("TYPE <CTRL-C> TO TERMINATE\n");
......@@ -1294,6 +1290,9 @@ int main( int argc, char **argv )
}
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_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