From 0b83862fc29012effdba3147a4b3eb6d1b40984c Mon Sep 17 00:00:00 2001 From: shahab SHARIATBAGHERI Date: Tue, 28 Mar 2017 18:28:30 +0200 Subject: [PATCH 001/195] uplink proto --- .../MESSAGES/V2/controller_commands.proto | 11 +++++-- openair2/ENB_APP/MESSAGES/V2/flexran.proto | 13 ++++++-- .../ENB_APP/MESSAGES/V2/mac_primitives.proto | 31 +++++++++++++++++++ 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto b/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto index cbec332b30..98ca6b8bee 100644 --- a/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto +++ b/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto @@ -3,7 +3,7 @@ package protocol; import "mac_primitives.proto"; // -// Body of UE DL MAC scheduling configuration info +// Body of UE DL/UL MAC scheduling configuration info // message flex_dl_data { @@ -15,6 +15,13 @@ message flex_dl_data { optional uint32 act_deact_ce = 6; //Hex content of MAC CE for Activation/Deactivation in CA } + +message flex_ul_data { + optional uint32 rnti = 1; + optional flex_ul_dci dl_dci = 2; + +} + // // Body of the RAR scheduler configuration // @@ -55,4 +62,4 @@ message flex_pdcch_ofdm_sym_count { enum flex_broadcast_type { FLBT_BCCH = 0; FLBT_PCCH = 1; -} \ No newline at end of file +} diff --git a/openair2/ENB_APP/MESSAGES/V2/flexran.proto b/openair2/ENB_APP/MESSAGES/V2/flexran.proto index 3a1d40bca6..ffd58daaae 100644 --- a/openair2/ENB_APP/MESSAGES/V2/flexran.proto +++ b/openair2/ENB_APP/MESSAGES/V2/flexran.proto @@ -25,9 +25,10 @@ message flexran_message { flex_lc_config_request lc_config_request_msg = 12; flex_lc_config_reply lc_config_reply_msg = 13; flex_dl_mac_config dl_mac_config_msg = 14; - flex_ue_state_change ue_state_change_msg = 15; - flex_control_delegation control_delegation_msg = 16; - flex_agent_reconfiguration agent_reconfiguration_msg = 17; + flex_ul_mac_config ul_mac_config_msg = 15 + flex_ue_state_change ue_state_change_msg = 16; + flex_control_delegation control_delegation_msg = 17; + flex_agent_reconfiguration agent_reconfiguration_msg = 18; } } @@ -163,6 +164,12 @@ message flex_dl_mac_config { repeated flex_pdcch_ofdm_sym_count ofdm_sym = 6; // OFDM symbol count for each CC } +message flex_ul_mac_config { + optional flex_header header = 1; + optional uint32 sfn_sf = 2; + repeated flex_ul_data ul_ue_data = 3; +} + // // UE state change message // diff --git a/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto b/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto index be7c72ab7b..3b3bc4e912 100644 --- a/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto +++ b/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto @@ -35,6 +35,37 @@ message flex_dl_dci { optional uint32 cif = 27; // CIF for cross-carrier scheduling } +message flex_ul_dci { + optional uint32 rnti = 1; + optional uint32 res_alloc = 2; // Type of resource allocation + optional uint32 rb_bitmap = 3; // Bitmap for RB allocation + optional uint32 rb_shift = 4; // See TS 36.214, section 7.1.6.2 + repeated uint32 tbs_size = 5; // The size of each TBS + repeated uint32 mcs = 6; // The MCS of each TB + repeated uint32 ndi = 7; // New data indicator of each TB + //repeated uint32 rv = 8; // Redundancy version of each TB + //optional uint32 cce_index = 9; // CCE index used to send the DCI + //optional uint32 aggr_level = 10; + //optional uint32 precoding_info = 11; // 2 antenna ports:0..6, + // 4 antenna ports:0..50 + optional uint32 format = 12; // DCI format. A FLDCIF_* value + optional uint32 tpc = 13; // TS 36.213, sec 5.1.1.1 + optional uint32 harq_process = 14; // HARQ process ID + optional uint32 dai = 15; // TDD only + //optional uint32 vrb_format = 16; // One of the FLVRBF_* values + optional uint32 tb_swap = 17; // Boolean. TB to codeword swap flag + //optional uint32 sps_release = 18; // Flag value + optional uint32 pdcch_order = 19; +// optional uint32 preamble_index = 20; // Only valid if pdcch_order = 1 + optional uint32 prach_mask_index = 21; // Only valid if pdcch_order = 1 + optional uint32 n_gap = 22; // One of the FLNGV_* values + optional uint32 tbs_idx = 23; // The TBS index for Format 1A + optional uint32 dl_power_offset = 24; // For format 1D +// optional uint32 pdcch_power_offset = 25; // DL PDCCH power boosting in dB +// optional uint32 cif_present = 26; // Boolean. Indication of CIF field +// optional uint32 cif = 27; // CIF for cross-carrier scheduling +} + // // Messages related to the creation of RLC PDUs // From 1a516df2db06892732fd6663e84abcbf6e18b195 Mon Sep 17 00:00:00 2001 From: shahab SHARIATBAGHERI Date: Fri, 31 Mar 2017 16:40:26 +0200 Subject: [PATCH 002/195] proto uplink mac --- .../ENB_APP/MESSAGES/V2/mac_primitives.proto | 61 +++++++++++-------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto b/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto index 3b3bc4e912..ecc82f116c 100644 --- a/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto +++ b/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto @@ -36,34 +36,39 @@ message flex_dl_dci { } message flex_ul_dci { + optional uint32 handle = 1; + optional uint32 size = 2; // Size of the ULSCH PDU in bytes for UL Grant. optional uint32 rnti = 1; - optional uint32 res_alloc = 2; // Type of resource allocation + optional uint32 res_block_start = 2; // match DCI format 0 PDU optional uint32 rb_bitmap = 3; // Bitmap for RB allocation - optional uint32 rb_shift = 4; // See TS 36.214, section 7.1.6.2 - repeated uint32 tbs_size = 5; // The size of each TBS - repeated uint32 mcs = 6; // The MCS of each TB - repeated uint32 ndi = 7; // New data indicator of each TB - //repeated uint32 rv = 8; // Redundancy version of each TB - //optional uint32 cce_index = 9; // CCE index used to send the DCI - //optional uint32 aggr_level = 10; - //optional uint32 precoding_info = 11; // 2 antenna ports:0..6, - // 4 antenna ports:0..50 + optional uint32 modulation_t = 4; // A FLMOD_* Value + optional uint32 cyclic_shift2 = 5; // match DCI format 0/4 PDU + optional uint32 freq_hop_flag = 6; // 0 no hopping, 1 hoppping + optional uint32 freq_hop_map = 8; // match DCI format 0 PDU + optional uint32 ndi = 7; // New data indicator of each TB + optional uint32 rv = 8; // Redundancy version of each TB + optional uint32 harq_process_number = 14; // A FLHARQ_* value + optional uint32 ultx_mode = 14; // A FLULM_* value + repeated uint32 tbs_size = 5; // The size of each TBS + repeated uint32 current_harq = 9; // CCE index used to send the DCI + optional uint32 n_srs = 10; // Over lap indication with srs + optional uint32 res_alloc = 2; // Type of resource allocation optional uint32 format = 12; // DCI format. A FLDCIF_* value - optional uint32 tpc = 13; // TS 36.213, sec 5.1.1.1 - optional uint32 harq_process = 14; // HARQ process ID - optional uint32 dai = 15; // TDD only - //optional uint32 vrb_format = 16; // One of the FLVRBF_* values - optional uint32 tb_swap = 17; // Boolean. TB to codeword swap flag - //optional uint32 sps_release = 18; // Flag value - optional uint32 pdcch_order = 19; + + +// optional uint32 dai = 15; // TDD only + +// optional uint32 tb_swap = 17; // Boolean. TB to codeword swap flag + +// optional uint32 pdcch_order = 19; // optional uint32 preamble_index = 20; // Only valid if pdcch_order = 1 - optional uint32 prach_mask_index = 21; // Only valid if pdcch_order = 1 - optional uint32 n_gap = 22; // One of the FLNGV_* values - optional uint32 tbs_idx = 23; // The TBS index for Format 1A - optional uint32 dl_power_offset = 24; // For format 1D -// optional uint32 pdcch_power_offset = 25; // DL PDCCH power boosting in dB -// optional uint32 cif_present = 26; // Boolean. Indication of CIF field -// optional uint32 cif = 27; // CIF for cross-carrier scheduling +// optional uint32 prach_mask_index = 21; // Only valid if pdcch_order = 1 + +// optional uint32 tbs_idx = 23; // The TBS index for Format 1A + + + + } // @@ -104,4 +109,10 @@ enum flex_vrb_format { enum flex_ngap_val { FLNGV_1 = 0; FLNGV_2 = 1; -} \ No newline at end of file +} + +enum flex_mod_type { + FLMOD_QPSK = 2; + FLMOD_16QAM = 4; + FLMOD_64QAM = 6; +} From a08178fa0e53f45dc2002ee8036c81192555e5ce Mon Sep 17 00:00:00 2001 From: Xenofon Foukas Date: Tue, 4 Apr 2017 21:11:16 +0000 Subject: [PATCH 003/195] Made modifications to UL scheduling messages --- .../MESSAGES/V2/controller_commands.proto | 3 +- openair2/ENB_APP/MESSAGES/V2/flexran.proto | 12 +++---- .../ENB_APP/MESSAGES/V2/mac_primitives.proto | 34 ++++++++----------- 3 files changed, 22 insertions(+), 27 deletions(-) diff --git a/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto b/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto index 98ca6b8bee..252efc6aef 100644 --- a/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto +++ b/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto @@ -18,8 +18,7 @@ message flex_dl_data { message flex_ul_data { optional uint32 rnti = 1; - optional flex_ul_dci dl_dci = 2; - + optional flex_ul_dci ul_dci = 2; } // diff --git a/openair2/ENB_APP/MESSAGES/V2/flexran.proto b/openair2/ENB_APP/MESSAGES/V2/flexran.proto index ffd58daaae..f49b69f4ad 100644 --- a/openair2/ENB_APP/MESSAGES/V2/flexran.proto +++ b/openair2/ENB_APP/MESSAGES/V2/flexran.proto @@ -25,10 +25,10 @@ message flexran_message { flex_lc_config_request lc_config_request_msg = 12; flex_lc_config_reply lc_config_reply_msg = 13; flex_dl_mac_config dl_mac_config_msg = 14; - flex_ul_mac_config ul_mac_config_msg = 15 - flex_ue_state_change ue_state_change_msg = 16; - flex_control_delegation control_delegation_msg = 17; - flex_agent_reconfiguration agent_reconfiguration_msg = 18; + flex_ul_mac_config ul_mac_config_msg = 18; + flex_ue_state_change ue_state_change_msg = 15; + flex_control_delegation control_delegation_msg = 16; + flex_agent_reconfiguration agent_reconfiguration_msg = 17; } } @@ -166,8 +166,8 @@ message flex_dl_mac_config { message flex_ul_mac_config { optional flex_header header = 1; - optional uint32 sfn_sf = 2; - repeated flex_ul_data ul_ue_data = 3; + optional uint32 sfn_sf = 2; + repeated flex_ul_data ul_ue_data = 3; } // diff --git a/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto b/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto index ecc82f116c..01f8799a17 100644 --- a/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto +++ b/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto @@ -36,27 +36,23 @@ message flex_dl_dci { } message flex_ul_dci { - optional uint32 handle = 1; - optional uint32 size = 2; // Size of the ULSCH PDU in bytes for UL Grant. optional uint32 rnti = 1; - optional uint32 res_block_start = 2; // match DCI format 0 PDU - optional uint32 rb_bitmap = 3; // Bitmap for RB allocation - optional uint32 modulation_t = 4; // A FLMOD_* Value - optional uint32 cyclic_shift2 = 5; // match DCI format 0/4 PDU - optional uint32 freq_hop_flag = 6; // 0 no hopping, 1 hoppping - optional uint32 freq_hop_map = 8; // match DCI format 0 PDU - optional uint32 ndi = 7; // New data indicator of each TB - optional uint32 rv = 8; // Redundancy version of each TB - optional uint32 harq_process_number = 14; // A FLHARQ_* value - optional uint32 ultx_mode = 14; // A FLULM_* value - repeated uint32 tbs_size = 5; // The size of each TBS - repeated uint32 current_harq = 9; // CCE index used to send the DCI - optional uint32 n_srs = 10; // Over lap indication with srs - optional uint32 res_alloc = 2; // Type of resource allocation - optional uint32 format = 12; // DCI format. A FLDCIF_* value + optional uint32 rb_start = 2; // The start RB allocated to the UE + optional uint32 rb_len = 3; // The number of RBs allocated to the UE + optional uint32 mcs = 4; // Modulation and coding scheme + optional uint32 cyclic_shift2 = 5; // match DCI format 0/4 PDU + optional uint32 freq_hop_flag = 6; // 0 no hopping, 1 hoppping + optional uint32 freq_hop_map = 7; // Frequency hopping bits (0..4) + optional uint32 ndi = 8; // New data indicator + optional uint32 rv = 9; // Redundancy version + optional uint32 harq_pid = 10; // The harq process id + optional uint32 ultx_mode = 11; // A FLULM_* value + optional uint32 tbs_size = 12; // The size of each TBS + optional uint32 n_srs = 13; // Overlap indication with srs + optional uint32 res_alloc = 14; // Type of resource allocation + optional uint32 size = 15; // Size of the ULSCH PDU in bytes for UL Grant. - -// optional uint32 dai = 15; // TDD only + optional uint32 dai = 16; // TDD only // optional uint32 tb_swap = 17; // Boolean. TB to codeword swap flag From 4cfa87b6b3854285359f4155f60b04d41ee20a07 Mon Sep 17 00:00:00 2001 From: shahab SHARIATBAGHERI Date: Wed, 5 Apr 2017 10:38:36 +0200 Subject: [PATCH 004/195] downlink throughput enhancement --- cmake_targets/CMakeLists.txt | 4 + .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 1233 ++++++---------- .../CONTROL_MODULES/MAC/flexran_agent_mac.h | 44 +- .../MAC/flexran_agent_mac_internal.c | 10 +- .../CONTROL_MODULES/RRC/flexran_agent_rrc.c | 662 +++++++++ .../CONTROL_MODULES/RRC/flexran_agent_rrc.h | 74 + .../RRC/flexran_agent_rrc_defs.h | 62 + openair2/ENB_APP/MESSAGES/V2/flexran.proto | 8 + openair2/ENB_APP/MESSAGES/V2/header.proto | 2 + .../ENB_APP/MESSAGES/V2/stats_common.proto | 60 + .../ENB_APP/MESSAGES/V2/stats_messages.proto | 6 +- openair2/ENB_APP/enb_config.c | 81 +- openair2/ENB_APP/enb_config.h | 4 + openair2/ENB_APP/flexran_agent.c | 24 +- openair2/ENB_APP/flexran_agent.h | 12 +- openair2/ENB_APP/flexran_agent_common.c | 1296 +---------------- openair2/ENB_APP/flexran_agent_common.h | 395 +---- openair2/ENB_APP/flexran_agent_defs.h | 83 +- openair2/ENB_APP/flexran_agent_extern.h | 16 +- openair2/ENB_APP/flexran_agent_handler.c | 580 +++++++- openair2/ENB_APP/flexran_agent_ran_api.c | 929 ++++++++++++ openair2/ENB_APP/flexran_agent_ran_api.h | 290 ++++ openair2/ENB_APP/flexran_agent_timer.c | 217 +++ openair2/ENB_APP/flexran_agent_timer.h | 133 ++ openair2/LAYER2/MAC/eNB_scheduler.c | 20 +- .../LAYER2/MAC/eNB_scheduler_primitives.c | 10 + openair2/RRC/LITE/rrc_eNB.c | 665 ++++++++- 27 files changed, 4388 insertions(+), 2532 deletions(-) create mode 100644 openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c create mode 100644 openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h create mode 100644 openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h create mode 100644 openair2/ENB_APP/flexran_agent_ran_api.c create mode 100644 openair2/ENB_APP/flexran_agent_ran_api.h create mode 100644 openair2/ENB_APP/flexran_agent_timer.c create mode 100644 openair2/ENB_APP/flexran_agent_timer.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 94a88c095b..5413014fbf 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -820,6 +820,7 @@ include_directories("${OPENAIR_DIR}/targets/ARCH/EXMIMO/USERSPACE/LIB/") include_directories("${OPENAIR_DIR}/targets/ARCH/EXMIMO/DEFS") include_directories("${OPENAIR2_DIR}/ENB_APP") include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC") +include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/RRC") include_directories("${OPENAIR2_DIR}/UTIL/OSA") include_directories("${OPENAIR2_DIR}/UTIL/LFDS/liblfds6.1.1/liblfds611/inc") include_directories("${OPENAIR2_DIR}/UTIL/LFDS/liblfds7.0.0/liblfds700/inc") @@ -905,8 +906,11 @@ if (FLEXRAN_AGENT_SB_IF) add_library(FLEXRAN_AGENT ${OPENAIR2_DIR}/ENB_APP/flexran_agent_handler.c ${OPENAIR2_DIR}/ENB_APP/flexran_agent_common.c + ${OPENAIR2_DIR}/ENB_APP/flexran_agent_ran_api.c + ${OPENAIR2_DIR}/ENB_APP/flexran_agent_timer.c ${OPENAIR2_DIR}/ENB_APP/flexran_agent_common_internal.c ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c + ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c ${OPENAIR2_DIR}/ENB_APP/flexran_agent.c ${OPENAIR2_DIR}/ENB_APP/flexran_agent_task_manager.c ${OPENAIR2_DIR}/ENB_APP/flexran_agent_net_comm.c diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 1a43f203df..01df6248f1 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -31,6 +31,7 @@ #include "flexran_agent_common.h" #include "flexran_agent_mac_internal.h" #include "flexran_agent_net_comm.h" +#include "flexran_agent_timer.h" #include "LAYER2/MAC/proto.h" #include "LAYER2/MAC/flexran_agent_mac_proto.h" @@ -54,683 +55,497 @@ struct lfds700_ringbuffer_element *dl_mac_config_array[NUM_MAX_ENB]; struct lfds700_ringbuffer_state ringbuffer_state[NUM_MAX_ENB]; -int flexran_agent_mac_handle_stats(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg){ +int flexran_agent_mac_stats_reply(mid_t mod_id, + const report_config_t *report_config, + Protocol__FlexUeStatsReport **ue_report, + Protocol__FlexCellStatsReport **cell_report) { - // TODO: Must deal with sanitization of input - // TODO: Must check if RNTIs and cell ids of the request actually exist - // TODO: Must resolve conflicts among stats requests - int i; - err_code_t err_code; - xid_t xid; - uint32_t usec_interval, sec_interval; - - //TODO: We do not deal with multiple CCs at the moment and eNB id is 0 - int enb_id = mod_id; - - //eNB_MAC_INST *eNB = &eNB_mac_inst[enb_id]; - //UE_list_t *eNB_UE_list= &eNB->UE_list; - - report_config_t report_config; - - uint32_t ue_flags = 0; - uint32_t c_flags = 0; - - Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; - - Protocol__FlexStatsRequest *stats_req = input->stats_request_msg; - xid = (stats_req->header)->xid; - - // Check the type of request that is made - switch(stats_req->body_case) { - case PROTOCOL__FLEX_STATS_REQUEST__BODY_COMPLETE_STATS_REQUEST: ; - Protocol__FlexCompleteStatsRequest *comp_req = stats_req->complete_stats_request; - if (comp_req->report_frequency == PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_OFF) { - /*Disable both periodic and continuous updates*/ - flexran_agent_disable_cont_mac_stats_update(mod_id); - flexran_agent_destroy_timer_by_task_id(xid); - *msg = NULL; - return 0; - } else { //One-off, periodical or continuous reporting - //Set the proper flags - ue_flags = comp_req->ue_report_flags; - c_flags = comp_req->cell_report_flags; - //Create a list of all eNB RNTIs and cells - - //Set the number of UEs and create list with their RNTIs stats configs - report_config.nr_ue = flexran_get_num_ues(mod_id); //eNB_UE_list->num_UEs - report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t) * report_config.nr_ue); - if (report_config.ue_report_type == NULL) { - // TODO: Add appropriate error code - err_code = -100; - goto error; - } - for (i = 0; i < report_config.nr_ue; i++) { - report_config.ue_report_type[i].ue_rnti = flexran_get_ue_crnti(enb_id, i); //eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,i)][i].crnti; - report_config.ue_report_type[i].ue_report_flags = ue_flags; - } - //Set the number of CCs and create a list with the cell stats configs - report_config.nr_cc = MAX_NUM_CCs; - report_config.cc_report_type = (cc_report_type_t *) malloc(sizeof(cc_report_type_t) * report_config.nr_cc); - if (report_config.cc_report_type == NULL) { - // TODO: Add appropriate error code - err_code = -100; - goto error; - } - for (i = 0; i < report_config.nr_cc; i++) { - //TODO: Must fill in the proper cell ids - report_config.cc_report_type[i].cc_id = i; - report_config.cc_report_type[i].cc_report_flags = c_flags; - } - /* Check if request was periodical */ - if (comp_req->report_frequency == PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_PERIODICAL) { - /* Create a one off flexran message as an argument for the periodical task */ - Protocol__FlexranMessage *timer_msg; - stats_request_config_t request_config; - request_config.report_type = PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS; - request_config.report_frequency = PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_ONCE; - request_config.period = 0; - /* Need to make sure that the ue flags are saved (Bug) */ - if (report_config.nr_ue == 0) { - report_config.nr_ue = 1; - report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t)); - if (report_config.ue_report_type == NULL) { - // TODO: Add appropriate error code - err_code = -100; - goto error; - } - report_config.ue_report_type[0].ue_rnti = 0; // Dummy value - report_config.ue_report_type[0].ue_report_flags = ue_flags; - } - request_config.config = &report_config; - flexran_agent_mac_stats_request(enb_id, xid, &request_config, &timer_msg); - /* Create a timer */ - long timer_id = 0; - flexran_agent_timer_args_t *timer_args; - timer_args = malloc(sizeof(flexran_agent_timer_args_t)); - memset (timer_args, 0, sizeof(flexran_agent_timer_args_t)); - timer_args->mod_id = enb_id; - timer_args->msg = timer_msg; - /*Convert subframes to usec time*/ - usec_interval = 1000*comp_req->sf; - sec_interval = 0; - /*add seconds if required*/ - if (usec_interval >= 1000*1000) { - sec_interval = usec_interval/(1000*1000); - usec_interval = usec_interval%(1000*1000); - } - flexran_agent_create_timer(sec_interval, usec_interval, FLEXRAN_AGENT_DEFAULT, enb_id, FLEXRAN_AGENT_TIMER_TYPE_PERIODIC, xid, flexran_agent_handle_timed_task,(void*) timer_args, &timer_id); - } else if (comp_req->report_frequency == PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_CONTINUOUS) { - /*If request was for continuous updates, disable the previous configuration and - set up a new one*/ - flexran_agent_disable_cont_mac_stats_update(mod_id); - stats_request_config_t request_config; - request_config.report_type = PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS; - request_config.report_frequency = PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_ONCE; - request_config.period = 0; - /* Need to make sure that the ue flags are saved (Bug) */ - if (report_config.nr_ue == 0) { - report_config.nr_ue = 1; - report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t)); - if (report_config.ue_report_type == NULL) { - // TODO: Add appropriate error code - err_code = -100; - goto error; - } - report_config.ue_report_type[0].ue_rnti = 0; // Dummy value - report_config.ue_report_type[0].ue_report_flags = ue_flags; - } - request_config.config = &report_config; - flexran_agent_enable_cont_mac_stats_update(enb_id, xid, &request_config); - } - } - break; - case PROTOCOL__FLEX_STATS_REQUEST__BODY_CELL_STATS_REQUEST:; - Protocol__FlexCellStatsRequest *cell_req = stats_req->cell_stats_request; - // UE report config will be blank - report_config.nr_ue = 0; - report_config.ue_report_type = NULL; - report_config.nr_cc = cell_req->n_cell; - report_config.cc_report_type = (cc_report_type_t *) malloc(sizeof(cc_report_type_t) * report_config.nr_cc); - if (report_config.cc_report_type == NULL) { - // TODO: Add appropriate error code - err_code = -100; - goto error; - } - for (i = 0; i < report_config.nr_cc; i++) { - //TODO: Must fill in the proper cell ids - report_config.cc_report_type[i].cc_id = cell_req->cell[i]; - report_config.cc_report_type[i].cc_report_flags = cell_req->flags; - } - break; - case PROTOCOL__FLEX_STATS_REQUEST__BODY_UE_STATS_REQUEST:; - Protocol__FlexUeStatsRequest *ue_req = stats_req->ue_stats_request; - // Cell report config will be blank - report_config.nr_cc = 0; - report_config.cc_report_type = NULL; - report_config.nr_ue = ue_req->n_rnti; - report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t) * report_config.nr_ue); - if (report_config.ue_report_type == NULL) { - // TODO: Add appropriate error code - err_code = -100; - goto error; - } - for (i = 0; i < report_config.nr_ue; i++) { - report_config.ue_report_type[i].ue_rnti = ue_req->rnti[i]; - report_config.ue_report_type[i].ue_report_flags = ue_req->flags; - } - break; - default: - //TODO: Add appropriate error code - err_code = -100; - goto error; - } - - if (flexran_agent_mac_stats_reply(enb_id, xid, &report_config, msg) < 0 ){ - err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; - goto error; - } - - free(report_config.ue_report_type); - free(report_config.cc_report_type); - - return 0; - - error : - LOG_E(FLEXRAN_AGENT, "errno %d occured\n", err_code); - return err_code; -} - -int flexran_agent_mac_stats_request(mid_t mod_id, - xid_t xid, - const stats_request_config_t *report_config, - Protocol__FlexranMessage **msg) { - Protocol__FlexHeader *header; - int i; - - Protocol__FlexStatsRequest *stats_request_msg; - stats_request_msg = malloc(sizeof(Protocol__FlexStatsRequest)); - if(stats_request_msg == NULL) - goto error; - protocol__flex_stats_request__init(stats_request_msg); - - if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_STATS_REQUEST, &header) != 0) - goto error; - - stats_request_msg->header = header; - - stats_request_msg->type = report_config->report_type; - stats_request_msg->has_type = 1; - - switch (report_config->report_type) { - case PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS: - stats_request_msg->body_case = PROTOCOL__FLEX_STATS_REQUEST__BODY_COMPLETE_STATS_REQUEST; - Protocol__FlexCompleteStatsRequest *complete_stats; - complete_stats = malloc(sizeof(Protocol__FlexCompleteStatsRequest)); - if(complete_stats == NULL) - goto error; - protocol__flex_complete_stats_request__init(complete_stats); - complete_stats->report_frequency = report_config->report_frequency; - complete_stats->has_report_frequency = 1; - complete_stats->sf = report_config->period; - complete_stats->has_sf = 1; - complete_stats->has_cell_report_flags = 1; - complete_stats->has_ue_report_flags = 1; - if (report_config->config->nr_cc > 0) { - complete_stats->cell_report_flags = report_config->config->cc_report_type[0].cc_report_flags; - } - if (report_config->config->nr_ue > 0) { - complete_stats->ue_report_flags = report_config->config->ue_report_type[0].ue_report_flags; - } - stats_request_msg->complete_stats_request = complete_stats; - break; - case PROTOCOL__FLEX_STATS_TYPE__FLST_CELL_STATS: - stats_request_msg->body_case = PROTOCOL__FLEX_STATS_REQUEST__BODY_CELL_STATS_REQUEST; - Protocol__FlexCellStatsRequest *cell_stats; - cell_stats = malloc(sizeof(Protocol__FlexCellStatsRequest)); - if(cell_stats == NULL) - goto error; - protocol__flex_cell_stats_request__init(cell_stats); - cell_stats->n_cell = report_config->config->nr_cc; - cell_stats->has_flags = 1; - if (cell_stats->n_cell > 0) { - uint32_t *cells; - cells = (uint32_t *) malloc(sizeof(uint32_t)*cell_stats->n_cell); - for (i = 0; i < cell_stats->n_cell; i++) { - cells[i] = report_config->config->cc_report_type[i].cc_id; - } - cell_stats->cell = cells; - cell_stats->flags = report_config->config->cc_report_type[i].cc_report_flags; - } - stats_request_msg->cell_stats_request = cell_stats; - break; - case PROTOCOL__FLEX_STATS_TYPE__FLST_UE_STATS: - stats_request_msg->body_case = PROTOCOL__FLEX_STATS_REQUEST__BODY_UE_STATS_REQUEST; - Protocol__FlexUeStatsRequest *ue_stats; - ue_stats = malloc(sizeof(Protocol__FlexUeStatsRequest)); - if(ue_stats == NULL) - goto error; - protocol__flex_ue_stats_request__init(ue_stats); - ue_stats->n_rnti = report_config->config->nr_ue; - ue_stats->has_flags = 1; - if (ue_stats->n_rnti > 0) { - uint32_t *ues; - ues = (uint32_t *) malloc(sizeof(uint32_t)*ue_stats->n_rnti); - for (i = 0; i < ue_stats->n_rnti; i++) { - ues[i] = report_config->config->ue_report_type[i].ue_rnti; - } - ue_stats->rnti = ues; - ue_stats->flags = report_config->config->ue_report_type[i].ue_report_flags; - } - stats_request_msg->ue_stats_request = ue_stats; - break; - default: - goto error; - } - *msg = malloc(sizeof(Protocol__FlexranMessage)); - if(*msg == NULL) - goto error; - protocol__flexran_message__init(*msg); - (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REQUEST_MSG; - (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE; - (*msg)->stats_request_msg = stats_request_msg; - return 0; - - error: - // TODO: Need to make proper error handling - if (header != NULL) - free(header); - if (stats_request_msg != NULL) - free(stats_request_msg); - if(*msg != NULL) - free(*msg); - //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); - return -1; -} - -int flexran_agent_mac_destroy_stats_request(Protocol__FlexranMessage *msg) { - if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REQUEST_MSG) - goto error; - free(msg->stats_request_msg->header); - if (msg->stats_request_msg->body_case == PROTOCOL__FLEX_STATS_REQUEST__BODY_CELL_STATS_REQUEST) { - free(msg->stats_request_msg->cell_stats_request->cell); - } - if (msg->stats_request_msg->body_case == PROTOCOL__FLEX_STATS_REQUEST__BODY_UE_STATS_REQUEST) { - free(msg->stats_request_msg->ue_stats_request->rnti); - } - free(msg->stats_request_msg); - free(msg); - return 0; - - error: - //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); - return -1; -} - -int flexran_agent_mac_stats_reply(mid_t mod_id, - xid_t xid, - const report_config_t *report_config, - Protocol__FlexranMessage **msg) { - Protocol__FlexHeader *header; + // Protocol__FlexHeader *header; int i, j, k; + int cc_id = 0; int enb_id = mod_id; - //eNB_MAC_INST *eNB = &eNB_mac_inst[enb_id]; - //UE_list_t *eNB_UE_list= &eNB->UE_list; - - Protocol__FlexStatsReply *stats_reply_msg; - stats_reply_msg = malloc(sizeof(Protocol__FlexStatsReply)); - if (stats_reply_msg == NULL) - goto error; - protocol__flex_stats_reply__init(stats_reply_msg); - - if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_STATS_REPLY, &header) != 0) - goto error; - - stats_reply_msg->header = header; - - stats_reply_msg->n_ue_report = report_config->nr_ue; - stats_reply_msg->n_cell_report = report_config->nr_cc; - - Protocol__FlexUeStatsReport **ue_report; - Protocol__FlexCellStatsReport **cell_report; - /* Allocate memory for list of UE reports */ if (report_config->nr_ue > 0) { - ue_report = malloc(sizeof(Protocol__FlexUeStatsReport *) * report_config->nr_ue); - if (ue_report == NULL) - goto error; - for (i = 0; i < report_config->nr_ue; i++) { - ue_report[i] = malloc(sizeof(Protocol__FlexUeStatsReport)); - protocol__flex_ue_stats_report__init(ue_report[i]); - ue_report[i]->rnti = report_config->ue_report_type[i].ue_rnti; - ue_report[i]->has_rnti = 1; - ue_report[i]->flags = report_config->ue_report_type[i].ue_report_flags; - ue_report[i]->has_flags = 1; - /* Check the types of reports that need to be constructed based on flag values */ - /* Check flag for creation of buffer status report */ - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_BSR) { - ue_report[i]->n_bsr = 4; - uint32_t *elem; - elem = (uint32_t *) malloc(sizeof(uint32_t)*ue_report[i]->n_bsr); - if (elem == NULL) - goto error; - for (j = 0; j < ue_report[i]->n_bsr; j++) { - // NN: we need to know the cc_id here, consider the first one - elem[j] = flexran_get_ue_bsr (enb_id, i, j); - } - ue_report[i]->bsr = elem; - } + + for (i = 0; i < report_config->nr_ue; i++) { - /* Check flag for creation of PRH report */ - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PRH) { - ue_report[i]->phr = flexran_get_ue_phr (enb_id, i); // eNB_UE_list->UE_template[UE_PCCID(enb_id,i)][i].phr_info; - ue_report[i]->has_phr = 1; - } - /* Check flag for creation of RLC buffer status report */ - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RLC_BS) { - ue_report[i]->n_rlc_report = 3; // Set this to the number of LCs for this UE. This needs to be generalized for for LCs - Protocol__FlexRlcBsr ** rlc_reports; - rlc_reports = malloc(sizeof(Protocol__FlexRlcBsr *) * ue_report[i]->n_rlc_report); - if (rlc_reports == NULL) - goto error; - // NN: see LAYER2/openair2_proc.c for rlc status - for (j = 0; j < ue_report[i]->n_rlc_report; j++) { - rlc_reports[j] = malloc(sizeof(Protocol__FlexRlcBsr)); - if (rlc_reports[j] == NULL) - goto error; - protocol__flex_rlc_bsr__init(rlc_reports[j]); - rlc_reports[j]->lc_id = j + 1; - rlc_reports[j]->has_lc_id = 1; - rlc_reports[j]->tx_queue_size = flexran_get_tx_queue_size(enb_id,i,j + 1); - rlc_reports[j]->has_tx_queue_size = 1; - - //TODO:Set tx queue head of line delay in ms - rlc_reports[j]->tx_queue_hol_delay = flexran_get_hol_delay(enb_id, i, j+1); - rlc_reports[j]->has_tx_queue_hol_delay = 1; - //TODO:Set retransmission queue size in bytes - rlc_reports[j]->retransmission_queue_size = 10; - rlc_reports[j]->has_retransmission_queue_size = 0; - //TODO:Set retransmission queue head of line delay in ms - rlc_reports[j]->retransmission_queue_hol_delay = 100; - rlc_reports[j]->has_retransmission_queue_hol_delay = 0; - //TODO:Set current size of the pending message in bytes - rlc_reports[j]->status_pdu_size = 100; - rlc_reports[j]->has_status_pdu_size = 0; - } - // Add RLC buffer status reports to the full report - if (ue_report[i]->n_rlc_report > 0) - ue_report[i]->rlc_report = rlc_reports; - } + /* Check flag for creation of buffer status report */ + if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_BSR) { + //TODO should be automated + ue_report[i]->n_bsr = 4; + uint32_t *elem; + elem = (uint32_t *) malloc(sizeof(uint32_t)*ue_report[i]->n_bsr); + if (elem == NULL) + goto error; + for (j = 0; j < ue_report[i]->n_bsr; j++) { + // NN: we need to know the cc_id here, consider the first one + elem[j] = flexran_get_ue_bsr (enb_id, i, j); + } + + ue_report[i]->bsr = elem; + } + + /* Check flag for creation of PHR report */ + if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PHR) { + ue_report[i]->phr = flexran_get_ue_phr (enb_id, i); // eNB_UE_list->UE_template[UE_PCCID(enb_id,i)][i].phr_info; + ue_report[i]->has_phr = 1; + + } - /* Check flag for creation of MAC CE buffer status report */ - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_CE_BS) { - // TODO: Fill in the actual MAC CE buffer status report - ue_report[i]->pending_mac_ces = (flexran_get_MAC_CE_bitmap_TA(enb_id,i,0) | (0 << 1) | (0 << 2) | (0 << 3)) & 15; /* Use as bitmap. Set one or more of the - PROTOCOL__FLEX_CE_TYPE__FLPCET_ values - found in stats_common.pb-c.h. See - flex_ce_type in FlexRAN specification */ - ue_report[i]->has_pending_mac_ces = 1; - } + /* Check flag for creation of RLC buffer status report */ + if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RLC_BS) { + ue_report[i]->n_rlc_report = 3; // Set this to the number of LCs for this UE. This needs to be generalized for for LCs + Protocol__FlexRlcBsr ** rlc_reports; + rlc_reports = malloc(sizeof(Protocol__FlexRlcBsr *) * ue_report[i]->n_rlc_report); + if (rlc_reports == NULL) + goto error; - /* Check flag for creation of DL CQI report */ - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_DL_CQI) { - // TODO: Fill in the actual DL CQI report for the UE based on its configuration - Protocol__FlexDlCqiReport * dl_report; - dl_report = malloc(sizeof(Protocol__FlexDlCqiReport)); - if (dl_report == NULL) - goto error; - protocol__flex_dl_cqi_report__init(dl_report); + // NN: see LAYER2/openair2_proc.c for rlc status + for (j = 0; j < ue_report[i]->n_rlc_report; j++) { - dl_report->sfn_sn = flexran_get_sfn_sf(enb_id); - dl_report->has_sfn_sn = 1; - //Set the number of DL CQI reports for this UE. One for each CC - dl_report->n_csi_report = flexran_get_active_CC(enb_id,i); + rlc_reports[j] = malloc(sizeof(Protocol__FlexRlcBsr)); + if (rlc_reports[j] == NULL) + goto error; + protocol__flex_rlc_bsr__init(rlc_reports[j]); + rlc_reports[j]->lc_id = j+1; + rlc_reports[j]->has_lc_id = 1; + rlc_reports[j]->tx_queue_size = flexran_get_tx_queue_size(enb_id, i, j + 1, "bytes_buffer"); + rlc_reports[j]->has_tx_queue_size = 1; - //Create the actual CSI reports. - Protocol__FlexDlCsi **csi_reports; - csi_reports = malloc(sizeof(Protocol__FlexDlCsi *)*dl_report->n_csi_report); - if (csi_reports == NULL) - goto error; - for (j = 0; j < dl_report->n_csi_report; j++) { - csi_reports[j] = malloc(sizeof(Protocol__FlexDlCsi)); - if (csi_reports[j] == NULL) - goto error; - protocol__flex_dl_csi__init(csi_reports[j]); - //The servCellIndex for this report - csi_reports[j]->serv_cell_index = j; - csi_reports[j]->has_serv_cell_index = 1; - //The rank indicator value for this cc - csi_reports[j]->ri = flexran_get_current_RI(enb_id,i,j); - csi_reports[j]->has_ri = 1; - //TODO: the type of CSI report based on the configuration of the UE - //For now we only support type P10, which only needs a wideband value - //The full set of types can be found in stats_common.pb-c.h and - //in the FlexRAN specifications - csi_reports[j]->type = PROTOCOL__FLEX_CSI_TYPE__FLCSIT_P10; - csi_reports[j]->has_type = 1; - csi_reports[j]->report_case = PROTOCOL__FLEX_DL_CSI__REPORT_P10CSI; - if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P10CSI){ - Protocol__FlexCsiP10 *csi10; - csi10 = malloc(sizeof(Protocol__FlexCsiP10)); - if (csi10 == NULL) - goto error; - protocol__flex_csi_p10__init(csi10); - //TODO: set the wideband value - // NN: this is also depends on cc_id - csi10->wb_cqi = flexran_get_ue_wcqi (enb_id, i); //eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,i)][i].dl_cqi; - csi10->has_wb_cqi = 1; - //Add the type of measurements to the csi report in the proper union type - csi_reports[j]->p10csi = csi10; - } - else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P11CSI){ + //TODO:Set tx queue head of line delay in ms + rlc_reports[j]->tx_queue_hol_delay = flexran_get_tx_queue_size(enb_id, i, j + 1, "head_line"); + rlc_reports[j]->has_tx_queue_hol_delay = 1; + //TODO:Set retransmission queue size in bytes + rlc_reports[j]->retransmission_queue_size = 10; + rlc_reports[j]->has_retransmission_queue_size = 0; + //TODO:Set retransmission queue head of line delay in ms + rlc_reports[j]->retransmission_queue_hol_delay = 100; + rlc_reports[j]->has_retransmission_queue_hol_delay = 0; + //TODO DONE:Set current size of the pending message in bytes + rlc_reports[j]->status_pdu_size = flexran_get_hol_delay(enb_id, i, j + 1); + rlc_reports[j]->has_status_pdu_size = 1; - } - else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P20CSI){ + } + // Add RLC buffer status reports to the full report + if (ue_report[i]->n_rlc_report > 0) + ue_report[i]->rlc_report = rlc_reports; - } - else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P21CSI){ + + } - } - else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A12CSI){ + /* Check flag for creation of MAC CE buffer status report */ + if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_CE_BS) { + // TODO: Fill in the actual MAC CE buffer status report + ue_report[i]->pending_mac_ces = (flexran_get_MAC_CE_bitmap_TA(enb_id,i,0) | (0 << 1) | (0 << 2) + | (0 << 3)) & 15; /* Use as bitmap. Set one or more of the; /* Use as bitmap. Set one or more of the + PROTOCOL__FLEX_CE_TYPE__FLPCET_ values + found in stats_common.pb-c.h. See + flex_ce_type in FlexRAN specification */ + ue_report[i]->has_pending_mac_ces = 1; + + } - } - else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A22CSI){ + /* Check flag for creation of DL CQI report */ + if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_DL_CQI) { + // TODO: Fill in the actual DL CQI report for the UE based on its configuration + Protocol__FlexDlCqiReport * dl_report; + dl_report = malloc(sizeof(Protocol__FlexDlCqiReport)); + if (dl_report == NULL) + goto error; + protocol__flex_dl_cqi_report__init(dl_report); - } - else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A20CSI){ + dl_report->sfn_sn = flexran_get_sfn_sf(enb_id); + dl_report->has_sfn_sn = 1; + //Set the number of DL CQI reports for this UE. One for each CC + dl_report->n_csi_report = flexran_get_active_CC(enb_id,i); + dl_report->n_csi_report = 1 ; + //Create the actual CSI reports. + Protocol__FlexDlCsi **csi_reports; + csi_reports = malloc(sizeof(Protocol__FlexDlCsi *)*dl_report->n_csi_report); + if (csi_reports == NULL) + goto error; + for (j = 0; j < dl_report->n_csi_report; j++) { - } - else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A30CSI){ + csi_reports[j] = malloc(sizeof(Protocol__FlexDlCsi)); + if (csi_reports[j] == NULL) + goto error; + protocol__flex_dl_csi__init(csi_reports[j]); + //The servCellIndex for this report + csi_reports[j]->serv_cell_index = j; + csi_reports[j]->has_serv_cell_index = 1; + //The rank indicator value for this cc + csi_reports[j]->ri = flexran_get_current_RI(enb_id,i,j); + csi_reports[j]->has_ri = 1; + //TODO: the type of CSI report based on the configuration of the UE + //For now we only support type P10, which only needs a wideband value + //The full set of types can be found in stats_common.pb-c.h and + //in the FlexRAN specifications + csi_reports[j]->type = PROTOCOL__FLEX_CSI_TYPE__FLCSIT_P10; + csi_reports[j]->has_type = 1; + csi_reports[j]->report_case = PROTOCOL__FLEX_DL_CSI__REPORT_P10CSI; - } - else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A31CSI){ + if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P10CSI){ - } - } - //Add the csi reports to the full DL CQI report - dl_report->csi_report = csi_reports; - //Add the DL CQI report to the stats report - ue_report[i]->dl_cqi_report = dl_report; - } + Protocol__FlexCsiP10 *csi10; + csi10 = malloc(sizeof(Protocol__FlexCsiP10)); + if (csi10 == NULL) + goto error; + protocol__flex_csi_p10__init(csi10); + //TODO: set the wideband value + // NN: this is also depends on cc_id + csi10->wb_cqi = flexran_get_ue_wcqi (enb_id, i); //eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,i)][i].dl_cqi; + csi10->has_wb_cqi = 1; + //Add the type of measurements to the csi report in the proper union type + csi_reports[j]->p10csi = csi10; + } - /* Check flag for creation of paging buffer status report */ - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PBS) { - //TODO: Fill in the actual paging buffer status report. For this field to be valid, the RNTI - //set in the report must be a P-RNTI - Protocol__FlexPagingBufferReport *paging_report; - paging_report = malloc(sizeof(Protocol__FlexPagingBufferReport)); - if (paging_report == NULL) - goto error; - protocol__flex_paging_buffer_report__init(paging_report); - //Set the number of pending paging messages - paging_report->n_paging_info = 1; - //Provide a report for each pending paging message - Protocol__FlexPagingInfo **p_info; - p_info = malloc(sizeof(Protocol__FlexPagingInfo *) * paging_report->n_paging_info); - if (p_info == NULL) - goto error; - for (j = 0; j < paging_report->n_paging_info; j++) { - p_info[j] = malloc(sizeof(Protocol__FlexPagingInfo)); - if(p_info[j] == NULL) - goto error; - protocol__flex_paging_info__init(p_info[j]); - //TODO: Set paging index. This index is the same that will be used for the scheduling of the - //paging message by the controller - p_info[j]->paging_index = 10; - p_info[j]->has_paging_index = 0; - //TODO:Set the paging message size - p_info[j]->paging_message_size = 100; - p_info[j]->has_paging_message_size = 0; - //TODO: Set the paging subframe - p_info[j]->paging_subframe = 10; - p_info[j]->has_paging_subframe = 0; - //TODO: Set the carrier index for the pending paging message - p_info[j]->carrier_index = 0; - p_info[j]->has_carrier_index = 0; - } - //Add all paging info to the paging buffer rerport - paging_report->paging_info = p_info; - //Add the paging report to the UE report - ue_report[i]->pbr = paging_report; - } + else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P11CSI){ - /* Check flag for creation of UL CQI report */ - if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_UL_CQI) { - //Fill in the full UL CQI report of the UE - Protocol__FlexUlCqiReport *full_ul_report; - full_ul_report = malloc(sizeof(Protocol__FlexUlCqiReport)); - if(full_ul_report == NULL) - goto error; - protocol__flex_ul_cqi_report__init(full_ul_report); - //TODO:Set the SFN and SF of the generated report - full_ul_report->sfn_sn = flexran_get_sfn_sf(enb_id); - full_ul_report->has_sfn_sn = 1; - //TODO:Set the number of UL measurement reports based on the types of measurements - //configured for this UE and on the servCellIndex - full_ul_report->n_cqi_meas = 1; - Protocol__FlexUlCqi **ul_report; - ul_report = malloc(sizeof(Protocol__FlexUlCqi *) * full_ul_report->n_cqi_meas); - if(ul_report == NULL) - goto error; - //Fill each UL report of the UE for each of the configured report types - for(j = 0; j < full_ul_report->n_cqi_meas; j++) { - ul_report[j] = malloc(sizeof(Protocol__FlexUlCqi)); - if(ul_report[j] == NULL) - goto error; - protocol__flex_ul_cqi__init(ul_report[j]); - //TODO: Set the type of the UL report. As an example set it to SRS UL report - // See enum flex_ul_cqi_type in FlexRAN specification for more details - ul_report[j]->type = PROTOCOL__FLEX_UL_CQI_TYPE__FLUCT_SRS; - ul_report[j]->has_type = 1; - //TODO:Set the number of SINR measurements based on the report type - //See struct flex_ul_cqi in FlexRAN specification for more details - ul_report[j]->n_sinr = 0; - uint32_t *sinr_meas; - sinr_meas = (uint32_t *) malloc(sizeof(uint32_t) * ul_report[j]->n_sinr); - if (sinr_meas == NULL) - goto error; - //TODO:Set the SINR measurements for the specified type - for (k = 0; k < ul_report[j]->n_sinr; k++) { - sinr_meas[k] = 10; - } - ul_report[j]->sinr = sinr_meas; - //TODO: Set the servCellIndex for this report - ul_report[j]->serv_cell_index = 0; - ul_report[j]->has_serv_cell_index = 1; - - //Set the list of UL reports of this UE to the full UL report - full_ul_report->cqi_meas = ul_report; - full_ul_report->n_pucch_dbm = MAX_NUM_CCs; - full_ul_report->pucch_dbm = malloc(sizeof(Protocol__FlexPucchDbm *) * full_ul_report->n_pucch_dbm); + Protocol__FlexCsiP11 *csi11; + csi11 = malloc(sizeof(Protocol__FlexCsiP11)); + if (csi11 == NULL) + goto error; + protocol__flex_csi_p11__init(csi11); + + csi11->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + // According To spec 36.213 + + if (flexran_get_antenna_ports(enb_id, j) == 2 && csi_reports[j]->ri == 1) { + // TODO PMI + csi11->wb_pmi = flexran_get_ue_pmi(enb_id); + csi11->has_wb_pmi = 1; - for (j = 0; j < MAX_NUM_CCs; j++) { - full_ul_report->pucch_dbm[j] = malloc(sizeof(Protocol__FlexPucchDbm)); - protocol__flex_pucch_dbm__init(full_ul_report->pucch_dbm[j]); - full_ul_report->pucch_dbm[j]->has_serv_cell_index = 1; - full_ul_report->pucch_dbm[j]->serv_cell_index = j; - if(flexran_get_p0_pucch_dbm(enb_id,i, j) != -1){ - full_ul_report->pucch_dbm[j]->p0_pucch_dbm = flexran_get_p0_pucch_dbm(enb_id,i,j); - full_ul_report->pucch_dbm[j]->has_p0_pucch_dbm = 1; - } - full_ul_report->pucch_dbm[j]->has_p0_pucch_updated = 1; - full_ul_report->pucch_dbm[j]->p0_pucch_updated = flexran_get_p0_pucch_status(enb_id, i, j); - } + } - //Add full UL CQI report to the UE report - ue_report[i]->ul_cqi_report = full_ul_report; - } - } - } - /* Add list of all UE reports to the message */ - stats_reply_msg->ue_report = ue_report; - } + else if (flexran_get_antenna_ports(enb_id, j) == 2 && csi_reports[j]->ri == 2){ + // TODO PMI + csi11->wb_pmi = flexran_get_ue_pmi(enb_id); + csi11->has_wb_pmi = 1; + + } + + else if (flexran_get_antenna_ports(enb_id, j) == 4 && csi_reports[j]->ri == 2){ + // TODO PMI + csi11->wb_pmi = flexran_get_ue_pmi(enb_id); + csi11->has_wb_pmi = 1; + + + } + + csi11->has_wb_pmi = 0; + + csi_reports[j]->p11csi = csi11; + + } + + + + + + else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P20CSI){ + + Protocol__FlexCsiP20 *csi20; + csi20 = malloc(sizeof(Protocol__FlexCsiP20)); + if (csi20 == NULL) + goto error; + protocol__flex_csi_p20__init(csi20); + + csi20->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + csi20->has_wb_cqi = 1; + + + csi20->bandwidth_part_index = 1 ;//TODO + csi20->has_bandwidth_part_index = 1; + + csi20->sb_index = 1 ;//TODO + csi20->has_sb_index = 1 ; + + + csi_reports[j]->p20csi = csi20; + + + } + + else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P21CSI){ + + // Protocol__FlexCsiP21 *csi21; + // csi21 = malloc(sizeof(Protocol__FlexCsiP21)); + // if (csi21 == NULL) + // goto error; + // protocol__flex_csi_p21__init(csi21); + + // csi21->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + + + // csi21->wb_pmi = flexran_get_ue_pmi(enb_id); //TDO inside + // csi21->has_wb_pmi = 1; + + // csi21->sb_cqi = 1; // TODO + + // csi21->bandwidth_part_index = 1 ; //TDO inside + // csi21->has_bandwidth_part_index = 1 ; + + // csi21->sb_index = 1 ;//TODO + // csi21->has_sb_index = 1 ; + + + // csi_reports[j]->p20csi = csi21; + + } + + else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A12CSI){ + + + // Protocol__FlexCsiA12 *csi12; + // csi12 = malloc(sizeof(Protocol__FlexCsiA12)); + // if (csi12 == NULL) + // goto error; + // protocol__flex_csi_a12__init(csi12); + + // csi12->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + + // csi12->sb_pmi = 1 ; //TODO inside + + // TODO continou + } + + else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A22CSI){ + + // Protocol__FlexCsiA22 *csi22; + // csi22 = malloc(sizeof(Protocol__FlexCsiA22)); + // if (csi22 == NULL) + // goto error; + // protocol__flex_csi_a22__init(csi22); + + // csi22->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + + // csi22->sb_cqi = 1 ; //TODO inside + + // csi22->wb_pmi = flexran_get_ue_wcqi (enb_id, i); + // csi22->has_wb_pmi = 1; + + // csi22->sb_pmi = 1 ; //TODO inside + // csi22->has_wb_pmi = 1; + + // csi22->sb_list = flexran_get_ue_wcqi (enb_id, i); + + + } + + else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A20CSI){ + + // Protocol__FlexCsiA20 *csi20; + // csi20 = malloc(sizeof(Protocol__FlexCsiA20)); + // if (csi20 == NULL) + // goto error; + // protocol__flex_csi_a20__init(csi20); + + // csi20->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + // csi20->has_wb_cqi = 1; + + // csi20>sb_cqi = 1 ; //TODO inside + // csi20>has_sb_cqi = 1 ; + + // csi20->sb_list = 1; // TODO inside + + + } + + else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A30CSI){ + + } + + else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A31CSI){ + + } + + } + //Add the csi reports to the full DL CQI report + dl_report->csi_report = csi_reports; + //Add the DL CQI report to the stats report + ue_report[i]->dl_cqi_report = dl_report; + + } + + /* Check flag for creation of paging buffer status report */ + if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PBS) { + //TODO: Fill in the actual paging buffer status report. For this field to be valid, the RNTI + //set in the report must be a P-RNTI + Protocol__FlexPagingBufferReport *paging_report; + paging_report = malloc(sizeof(Protocol__FlexPagingBufferReport)); + if (paging_report == NULL) + goto error; + protocol__flex_paging_buffer_report__init(paging_report); + //Set the number of pending paging messages + paging_report->n_paging_info = 1; + //Provide a report for each pending paging message + Protocol__FlexPagingInfo **p_info; + p_info = malloc(sizeof(Protocol__FlexPagingInfo *) * paging_report->n_paging_info); + if (p_info == NULL) + goto error; + + for (j = 0; j < paging_report->n_paging_info; j++) { + + p_info[j] = malloc(sizeof(Protocol__FlexPagingInfo)); + if(p_info[j] == NULL) + goto error; + protocol__flex_paging_info__init(p_info[j]); + //TODO: Set paging index. This index is the same that will be used for the scheduling of the + //paging message by the controller + p_info[j]->paging_index = 10; + p_info[j]->has_paging_index = 1; + //TODO:Set the paging message size + p_info[j]->paging_message_size = 100; + p_info[j]->has_paging_message_size = 1; + //TODO: Set the paging subframe + p_info[j]->paging_subframe = 10; + p_info[j]->has_paging_subframe = 1; + //TODO: Set the carrier index for the pending paging message + p_info[j]->carrier_index = 0; + p_info[j]->has_carrier_index = 1; + + } + //Add all paging info to the paging buffer rerport + paging_report->paging_info = p_info; + //Add the paging report to the UE report + ue_report[i]->pbr = paging_report; + } + + /* Check flag for creation of UL CQI report */ + if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_UL_CQI) { + + //Fill in the full UL CQI report of the UE + Protocol__FlexUlCqiReport *full_ul_report; + full_ul_report = malloc(sizeof(Protocol__FlexUlCqiReport)); + if(full_ul_report == NULL) + goto error; + protocol__flex_ul_cqi_report__init(full_ul_report); + //TODO:Set the SFN and SF of the generated report + full_ul_report->sfn_sn = flexran_get_sfn_sf(enb_id); + full_ul_report->has_sfn_sn = 1; + //TODO:Set the number of UL measurement reports based on the types of measurements + //configured for this UE and on the servCellIndex + full_ul_report->n_cqi_meas = 1; + Protocol__FlexUlCqi **ul_report; + ul_report = malloc(sizeof(Protocol__FlexUlCqi *) * full_ul_report->n_cqi_meas); + if(ul_report == NULL) + goto error; + //Fill each UL report of the UE for each of the configured report types + for(j = 0; j < full_ul_report->n_cqi_meas; j++) { + + ul_report[j] = malloc(sizeof(Protocol__FlexUlCqi)); + if(ul_report[j] == NULL) + goto error; + protocol__flex_ul_cqi__init(ul_report[j]); + //TODO: Set the type of the UL report. As an example set it to SRS UL report + // See enum flex_ul_cqi_type in FlexRAN specification for more details + ul_report[j]->type = PROTOCOL__FLEX_UL_CQI_TYPE__FLUCT_SRS; + ul_report[j]->has_type = 1; + //TODO:Set the number of SINR measurements based on the report type + //See struct flex_ul_cqi in FlexRAN specification for more details + ul_report[j]->n_sinr = 0; + uint32_t *sinr_meas; + sinr_meas = (uint32_t *) malloc(sizeof(uint32_t) * ul_report[j]->n_sinr); + if (sinr_meas == NULL) + goto error; + //TODO:Set the SINR measurements for the specified type + for (k = 0; k < ul_report[j]->n_sinr; k++) { + sinr_meas[k] = 10; + } + ul_report[j]->sinr = sinr_meas; + //TODO: Set the servCellIndex for this report + ul_report[j]->serv_cell_index = 0; + ul_report[j]->has_serv_cell_index = 1; + + //Set the list of UL reports of this UE to the full UL report + full_ul_report->cqi_meas = ul_report; + + full_ul_report->n_pucch_dbm = MAX_NUM_CCs; + full_ul_report->pucch_dbm = malloc(sizeof(Protocol__FlexPucchDbm *) * full_ul_report->n_pucch_dbm); + + for (j = 0; j < MAX_NUM_CCs; j++) { + + full_ul_report->pucch_dbm[j] = malloc(sizeof(Protocol__FlexPucchDbm)); + protocol__flex_pucch_dbm__init(full_ul_report->pucch_dbm[j]); + full_ul_report->pucch_dbm[j]->has_serv_cell_index = 1; + full_ul_report->pucch_dbm[j]->serv_cell_index = j; + + if(flexran_get_p0_pucch_dbm(enb_id,i, j) != -1){ + full_ul_report->pucch_dbm[j]->p0_pucch_dbm = flexran_get_p0_pucch_dbm(enb_id,i,j); + full_ul_report->pucch_dbm[j]->has_p0_pucch_dbm = 1; + } + } + + + } + // Add full UL CQI report to the UE report + ue_report[i]->ul_cqi_report = full_ul_report; + + + } + + + + + } + + + + + } /* Allocate memory for list of cell reports */ if (report_config->nr_cc > 0) { - cell_report = malloc(sizeof(Protocol__FlexCellStatsReport *) * report_config->nr_cc); - if (cell_report == NULL) - goto error; - // Fill in the Cell reports - for (i = 0; i < report_config->nr_cc; i++) { - cell_report[i] = malloc(sizeof(Protocol__FlexCellStatsReport)); - if(cell_report[i] == NULL) - goto error; - protocol__flex_cell_stats_report__init(cell_report[i]); - cell_report[i]->carrier_index = report_config->cc_report_type[i].cc_id; - cell_report[i]->has_carrier_index = 1; - cell_report[i]->flags = report_config->cc_report_type[i].cc_report_flags; - cell_report[i]->has_flags = 1; + + + // Fill in the Cell reports + for (i = 0; i < report_config->nr_cc; i++) { - /* Check flag for creation of noise and interference report */ - if(report_config->cc_report_type[i].cc_report_flags & PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE) { - // TODO: Fill in the actual noise and interference report for this cell - Protocol__FlexNoiseInterferenceReport *ni_report; - ni_report = malloc(sizeof(Protocol__FlexNoiseInterferenceReport)); - if(ni_report == NULL) - goto error; - protocol__flex_noise_interference_report__init(ni_report); - // Current frame and subframe number - ni_report->sfn_sf = flexran_get_sfn_sf(enb_id); - ni_report->has_sfn_sf = 1; - //TODO:Received interference power in dbm - ni_report->rip = 0; - ni_report->has_rip = 0; - //TODO:Thermal noise power in dbm - ni_report->tnp = 0; - ni_report->has_tnp = 0; - ni_report->p0_nominal_pucch = flexran_get_p0_nominal_pucch(enb_id, 0); - ni_report->has_p0_nominal_pucch = 1; - cell_report[i]->noise_inter_report = ni_report; - } - } - /* Add list of all cell reports to the message */ - stats_reply_msg->cell_report = cell_report; + /* Check flag for creation of noise and interference report */ + if(report_config->cc_report_type[i].cc_report_flags & PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE) { + // TODO: Fill in the actual noise and interference report for this cell + Protocol__FlexNoiseInterferenceReport *ni_report; + ni_report = malloc(sizeof(Protocol__FlexNoiseInterferenceReport)); + if(ni_report == NULL) + goto error; + protocol__flex_noise_interference_report__init(ni_report); + // Current frame and subframe number + ni_report->sfn_sf = flexran_get_sfn_sf(enb_id); + ni_report->has_sfn_sf = 1; + //TODO:Received interference power in dbm + ni_report->rip = 0; + ni_report->has_rip = 1; + //TODO:Thermal noise power in dbm + ni_report->tnp = 0; + ni_report->has_tnp = 1; + + ni_report->p0_nominal_pucch = flexran_get_p0_nominal_pucch(enb_id, 0); + ni_report->has_p0_nominal_pucch = 1; + cell_report[i]->noise_inter_report = ni_report; + } + } + + + + } - *msg = malloc(sizeof(Protocol__FlexranMessage)); - if(*msg == NULL) - goto error; - protocol__flexran_message__init(*msg); - (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REPLY_MSG; - (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME; - (*msg)->stats_reply_msg = stats_reply_msg; return 0; error: - // TODO: Need to make proper error handling - if (header != NULL) - free(header); - if (stats_reply_msg != NULL) - free(stats_reply_msg); - if(*msg != NULL) - free(*msg); - //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); + + if (cell_report != NULL) + free(cell_report); + if (ue_report != NULL) + free(ue_report); + return -1; } @@ -1346,58 +1161,7 @@ void flexran_agent_send_sf_trigger(mid_t mod_id) { LOG_D(FLEXRAN_AGENT, "Could not send sf trigger message\n"); } -void flexran_agent_send_update_mac_stats(mid_t mod_id) { - Protocol__FlexranMessage *current_report = NULL; - void *data; - int size; - err_code_t err_code; - int priority = 0; - - if (pthread_mutex_lock(mac_stats_context[mod_id].mutex)) { - goto error; - } - - if (mac_stats_context[mod_id].cont_update == 1) { - - /*Create a fresh report with the required flags*/ - err_code = flexran_agent_mac_handle_stats(mod_id, (void *) mac_stats_context[mod_id].stats_req, ¤t_report); - if (err_code < 0) { - goto error; - } - } - /* /\*TODO:Check if a previous reports exists and if yes, generate a report */ - /* *that is the diff between the old and the new report, */ - /* *respecting the thresholds. Otherwise send the new report*\/ */ - /* if (mac_stats_context[mod_id].prev_stats_reply != NULL) { */ - - /* msg = flexran_agent_generate_diff_mac_stats_report(current_report, mac_stats_context[mod_id].prev_stats_reply); */ - - /* /\*Destroy the old stats*\/ */ - /* flexran_agent_destroy_flexran_message(mac_stats_context[mod_id].prev_stats_reply); */ - /* } */ - /* /\*Use the current report for future comparissons*\/ */ - /* mac_stats_context[mod_id].prev_stats_reply = current_report; */ - - - if (pthread_mutex_unlock(mac_stats_context[mod_id].mutex)) { - goto error; - } - - if (current_report != NULL){ - data=flexran_agent_pack_message(current_report, &size); - /*Send any stats updates using the MAC channel of the eNB*/ - if (flexran_agent_msg_send(mod_id, FLEXRAN_AGENT_MAC, data, size, priority)) { - err_code = PROTOCOL__FLEXRAN_ERR__MSG_ENQUEUING; - goto error; - } - - LOG_D(FLEXRAN_AGENT,"sent message with size %d\n", size); - return; - } - error: - LOG_D(FLEXRAN_AGENT, "Could not send sf trigger message\n"); -} int flexran_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { if (mac_agent_registered[mod_id]) { @@ -1408,11 +1172,10 @@ int flexran_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { //xface->agent_ctxt = &shared_ctxt[mod_id]; xface->flexran_agent_send_sr_info = flexran_agent_send_sr_info; xface->flexran_agent_send_sf_trigger = flexran_agent_send_sf_trigger; - xface->flexran_agent_send_update_mac_stats = flexran_agent_send_update_mac_stats; + //xface->flexran_agent_send_update_mac_stats = flexran_agent_send_update_mac_stats; xface->flexran_agent_schedule_ue_spec = flexran_schedule_ue_spec_default; //xface->flexran_agent_schedule_ue_spec = flexran_schedule_ue_spec_remote; xface->flexran_agent_get_pending_dl_mac_config = flexran_agent_get_pending_dl_mac_config; - xface->flexran_agent_notify_ue_state_change = flexran_agent_ue_state_change; xface->dl_scheduler_loaded_lib = NULL; @@ -1427,10 +1190,10 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { //xface->agent_ctxt = NULL; xface->flexran_agent_send_sr_info = NULL; xface->flexran_agent_send_sf_trigger = NULL; - xface->flexran_agent_send_update_mac_stats = NULL; + //xface->flexran_agent_send_update_mac_stats = NULL; xface->flexran_agent_schedule_ue_spec = NULL; xface->flexran_agent_get_pending_dl_mac_config = NULL; - xface->flexran_agent_notify_ue_state_change = NULL; + xface->dl_scheduler_loaded_lib = NULL; @@ -1441,89 +1204,7 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { } -/****************************************************** - *Implementations of flexran_agent_mac_internal.h functions - ******************************************************/ - -err_code_t flexran_agent_init_cont_mac_stats_update(mid_t mod_id) { - - /*Initialize the Mac stats update structure*/ - /*Initially the continuous update is set to false*/ - mac_stats_context[mod_id].cont_update = 0; - mac_stats_context[mod_id].is_initialized = 1; - mac_stats_context[mod_id].stats_req = NULL; - mac_stats_context[mod_id].prev_stats_reply = NULL; - mac_stats_context[mod_id].mutex = calloc(1, sizeof(pthread_mutex_t)); - if (mac_stats_context[mod_id].mutex == NULL) - goto error; - if (pthread_mutex_init(mac_stats_context[mod_id].mutex, NULL)) - goto error;; - - return 0; - - error: - return -1; -} - -err_code_t flexran_agent_destroy_cont_mac_stats_update(mid_t mod_id) { - /*Disable the continuous updates for the MAC*/ - mac_stats_context[mod_id].cont_update = 0; - mac_stats_context[mod_id].is_initialized = 0; - flexran_agent_destroy_flexran_message(mac_stats_context[mod_id].stats_req); - flexran_agent_destroy_flexran_message(mac_stats_context[mod_id].prev_stats_reply); - free(mac_stats_context[mod_id].mutex); - - mac_agent_registered[mod_id] = 0; - return 1; -} -err_code_t flexran_agent_enable_cont_mac_stats_update(mid_t mod_id, - xid_t xid, stats_request_config_t *stats_req) { - /*Enable the continuous updates for the MAC*/ - if (pthread_mutex_lock(mac_stats_context[mod_id].mutex)) { - goto error; - } - Protocol__FlexranMessage *req_msg; - flexran_agent_mac_stats_request(mod_id, xid, stats_req, &req_msg); - mac_stats_context[mod_id].stats_req = req_msg; - mac_stats_context[mod_id].prev_stats_reply = NULL; - - mac_stats_context[mod_id].cont_update = 1; - mac_stats_context[mod_id].xid = xid; - - if (pthread_mutex_unlock(mac_stats_context[mod_id].mutex)) { - goto error; - } - return 0; - - error: - LOG_E(FLEXRAN_AGENT, "mac_stats_context for eNB %d is not initialized\n", mod_id); - return -1; -} - -err_code_t flexran_agent_disable_cont_mac_stats_update(mid_t mod_id) { - /*Disable the continuous updates for the MAC*/ - if (pthread_mutex_lock(mac_stats_context[mod_id].mutex)) { - goto error; - } - mac_stats_context[mod_id].cont_update = 0; - mac_stats_context[mod_id].xid = 0; - if (mac_stats_context[mod_id].stats_req != NULL) { - flexran_agent_destroy_flexran_message(mac_stats_context[mod_id].stats_req); - } - if (mac_stats_context[mod_id].prev_stats_reply != NULL) { - flexran_agent_destroy_flexran_message(mac_stats_context[mod_id].prev_stats_reply); - } - if (pthread_mutex_unlock(mac_stats_context[mod_id].mutex)) { - goto error; - } - return 0; - - error: - LOG_E(FLEXRAN_AGENT, "mac_stats_context for eNB %d is not initialized\n", mod_id); - return -1; - -} diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h index e2378e9311..d2db860ce4 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h @@ -37,50 +37,10 @@ #include "flexran_agent_common.h" #include "flexran_agent_extern.h" -/* These types will be used to give - instructions for the type of stats reports - we need to create */ -typedef struct { - uint16_t ue_rnti; - uint32_t ue_report_flags; /* Indicates the report elements - required for this UE id. See - FlexRAN specification 1.2.4.2 */ -} ue_report_type_t; - -typedef struct { - uint16_t cc_id; - uint32_t cc_report_flags; /* Indicates the report elements - required for this CC index. See - FlexRAN specification 1.2.4.3 */ -} cc_report_type_t; - -typedef struct { - int nr_ue; - ue_report_type_t *ue_report_type; - int nr_cc; - cc_report_type_t *cc_report_type; -} report_config_t; - -typedef struct stats_request_config_s{ - uint8_t report_type; - uint8_t report_frequency; - uint16_t period; /*In number of subframes*/ - report_config_t *config; -} stats_request_config_t; /* Initialization function for the agent structures etc */ void flexran_agent_init_mac_agent(mid_t mod_id); -int flexran_agent_mac_handle_stats(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg); - -/* Statistics request protocol message constructor and destructor */ -int flexran_agent_mac_stats_request(mid_t mod_id, xid_t xid, const stats_request_config_t *report_config, Protocol__FlexranMessage **msg); -int flexran_agent_mac_destroy_stats_request(Protocol__FlexranMessage *msg); - -/* Statistics reply protocol message constructor and destructor */ -int flexran_agent_mac_stats_reply(mid_t mod_id, xid_t xid, const report_config_t *report_config, Protocol__FlexranMessage **msg); -int flexran_agent_mac_destroy_stats_reply(Protocol__FlexranMessage *msg); - /* Scheduling request information protocol message constructor and estructor */ int flexran_agent_mac_sr_info(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg); int flexran_agent_mac_destroy_sr_info(Protocol__FlexranMessage *msg); @@ -89,6 +49,10 @@ int flexran_agent_mac_destroy_sr_info(Protocol__FlexranMessage *msg); int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg); int flexran_agent_mac_destroy_sf_trigger(Protocol__FlexranMessage *msg); +/* Statistics reply protocol message constructor and destructor */ +int flexran_agent_mac_stats_reply(mid_t mod_id, const report_config_t *report_config, Protocol__FlexUeStatsReport **ue_report, Protocol__FlexCellStatsReport **cell_report); +int flexran_agent_mac_destroy_stats_reply(Protocol__FlexranMessage *msg); + /* DL MAC scheduling decision protocol message constructor (empty command) and destructor */ int flexran_agent_mac_create_empty_dl_config(mid_t mod_id, Protocol__FlexranMessage **msg); int flexran_agent_mac_destroy_dl_config(Protocol__FlexranMessage *msg); diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index 1fa9852487..66efafae55 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -180,10 +180,12 @@ Protocol__FlexUeStatsReport * copy_ue_stats_report(Protocol__FlexUeStatsReport * } } - if (copy->flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PRH) { - copy->has_phr = original->has_phr; - copy->phr = original->phr; - } + + + if (copy->flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PHR) { + copy->has_phr = original->has_phr; + copy->phr = original->phr; + } if (copy->flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RLC_BS) { copy->n_rlc_report = original->n_rlc_report; diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c new file mode 100644 index 0000000000..9475b06643 --- /dev/null +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c @@ -0,0 +1,662 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file flexran_agent_mac.c + * \brief FlexRAN agent Control Module RRC + * \author shahab SHARIAT BAGHERI + * \date 2017 + * \version 0.1 + */ + +#include "flexran_agent_rrc.h" + + +#include "liblfds700.h" + +#include "log.h" + + +/*Flags showing if a rrc agent has already been registered*/ +unsigned int rrc_agent_registered[NUM_MAX_ENB]; + +/*Array containing the Agent-RRC interfaces*/ +AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB]; + +/* Ringbuffer related structs used for maintaining the dl rrc config messages */ +//message_queue_t *rrc_dl_config_queue; +struct lfds700_misc_prng_state rrc_ps[NUM_MAX_ENB]; +struct lfds700_ringbuffer_element *rrc_dl_config_array[NUM_MAX_ENB]; +struct lfds700_ringbuffer_state rrc_ringbuffer_state[NUM_MAX_ENB]; + + + +void flexran_agent_init_rrc_agent(mid_t mod_id) { + lfds700_misc_library_init_valid_on_current_logical_core(); + lfds700_misc_prng_init(&rrc_ps[mod_id]); + int num_elements = RINGBUFFER_SIZE + 1; + //Allow RINGBUFFER_SIZE messages to be stored in the ringbuffer at any time + rrc_dl_config_array[mod_id] = malloc( sizeof(struct lfds700_ringbuffer_element) * num_elements); + lfds700_ringbuffer_init_valid_on_current_logical_core( &rrc_ringbuffer_state[mod_id], rrc_dl_config_array[mod_id], num_elements, &rrc_ps[mod_id], NULL ); +} + + + + + +int flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_change) { + int size; + Protocol__FlexranMessage *msg; + Protocol__FlexHeader *header; + void *data; + int priority; + err_code_t err_code; + + int xid = 0; + + if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_UE_STATE_CHANGE, &header) != 0) + goto error; + + Protocol__FlexUeStateChange *ue_state_change_msg; + ue_state_change_msg = malloc(sizeof(Protocol__FlexUeStateChange)); + if(ue_state_change_msg == NULL) { + goto error; + } + protocol__flex_ue_state_change__init(ue_state_change_msg); + ue_state_change_msg->has_type = 1; + ue_state_change_msg->type = state_change; + + Protocol__FlexUeConfig *config; + config = malloc(sizeof(Protocol__FlexUeConfig)); + if (config == NULL) { + goto error; + } + protocol__flex_ue_config__init(config); + if (state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED) { + // Simply set the rnti of the UE + config->has_rnti = 1; + config->rnti = rnti; + } else if (state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_UPDATED + || state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED) { + int i = find_UE_id(mod_id, rnti); + config->has_rnti = 1; + config->rnti = rnti; + if(flexran_get_time_alignment_timer(mod_id,i) != -1) { + config->time_alignment_timer = flexran_get_time_alignment_timer(mod_id,i); + config->has_time_alignment_timer = 1; + } + if(flexran_get_meas_gap_config(mod_id,i) != -1){ + config->meas_gap_config_pattern = flexran_get_meas_gap_config(mod_id,i); + config->has_meas_gap_config_pattern = 1; + } + if(config->has_meas_gap_config_pattern == 1 && + config->meas_gap_config_pattern != PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF) { + config->meas_gap_config_sf_offset = flexran_get_meas_gap_config_offset(mod_id,i); + config->has_meas_gap_config_sf_offset = 1; + } + //TODO: Set the SPS configuration (Optional) + //Not supported for now, so we do not set it + + //TODO: Set the SR configuration (Optional) + //We do not set it for now + + //TODO: Set the CQI configuration (Optional) + //We do not set it for now + + if(flexran_get_ue_transmission_mode(mod_id,i) != -1) { + config->transmission_mode = flexran_get_ue_transmission_mode(mod_id,i); + config->has_transmission_mode = 1; + } + + config->ue_aggregated_max_bitrate_ul = flexran_get_ue_aggregated_max_bitrate_ul(mod_id,i); + config->has_ue_aggregated_max_bitrate_ul = 1; + + config->ue_aggregated_max_bitrate_dl = flexran_get_ue_aggregated_max_bitrate_dl(mod_id,i); + config->has_ue_aggregated_max_bitrate_dl = 1; + + //TODO: Set the UE capabilities + Protocol__FlexUeCapabilities *c_capabilities; + c_capabilities = malloc(sizeof(Protocol__FlexUeCapabilities)); + protocol__flex_ue_capabilities__init(c_capabilities); + //TODO: Set half duplex (FDD operation) + c_capabilities->has_half_duplex = 0; + c_capabilities->half_duplex = 1;//flexran_get_half_duplex(i); + //TODO: Set intra-frame hopping flag + c_capabilities->has_intra_sf_hopping = 0; + c_capabilities->intra_sf_hopping = 1;//flexran_get_intra_sf_hopping(i); + //TODO: Set support for type 2 hopping with n_sb > 1 + c_capabilities->has_type2_sb_1 = 0; + c_capabilities->type2_sb_1 = 1;//flexran_get_type2_sb_1(i); + //TODO: Set ue category + c_capabilities->has_ue_category = 0; + c_capabilities->ue_category = 1;//flexran_get_ue_category(i); + //TODO: Set UE support for resource allocation type 1 + c_capabilities->has_res_alloc_type1 = 0; + c_capabilities->res_alloc_type1 = 1;//flexran_get_res_alloc_type1(i); + //Set the capabilites to the message + config->capabilities = c_capabilities; + + if(flexran_get_ue_transmission_antenna(mod_id,i) != -1) { + config->has_ue_transmission_antenna = 1; + config->ue_transmission_antenna = flexran_get_ue_transmission_antenna(mod_id,i); + } + + if(flexran_get_tti_bundling(mod_id,i) != -1) { + config->has_tti_bundling = 1; + config->tti_bundling = flexran_get_tti_bundling(mod_id,i); + } + + if(flexran_get_maxHARQ_TX(mod_id,i) != -1){ + config->has_max_harq_tx = 1; + config->max_harq_tx = flexran_get_maxHARQ_TX(mod_id,i); + } + + if(flexran_get_beta_offset_ack_index(mod_id,i) != -1) { + config->has_beta_offset_ack_index = 1; + config->beta_offset_ack_index = flexran_get_beta_offset_ack_index(mod_id,i); + } + + if(flexran_get_beta_offset_ri_index(mod_id,i) != -1) { + config->has_beta_offset_ri_index = 1; + config->beta_offset_ri_index = flexran_get_beta_offset_ri_index(mod_id,i); + } + + if(flexran_get_beta_offset_cqi_index(mod_id,i) != -1) { + config->has_beta_offset_cqi_index = 1; + config->beta_offset_cqi_index = flexran_get_beta_offset_cqi_index(mod_id,i); + } + + if(flexran_get_ack_nack_simultaneous_trans(mod_id,i) != -1) { + config->has_ack_nack_simultaneous_trans = 1; + config->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id,i); + } + + if(flexran_get_simultaneous_ack_nack_cqi(mod_id,i) != -1) { + config->has_simultaneous_ack_nack_cqi = 1; + config->simultaneous_ack_nack_cqi = flexran_get_simultaneous_ack_nack_cqi(mod_id,i); + } + + if(flexran_get_aperiodic_cqi_rep_mode(mod_id,i) != -1) { + config->has_aperiodic_cqi_rep_mode = 1; + int mode = flexran_get_aperiodic_cqi_rep_mode(mod_id,i); + if (mode > 4) { + config->aperiodic_cqi_rep_mode = PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_NONE; + } else { + config->aperiodic_cqi_rep_mode = mode; + } + } + + if(flexran_get_tdd_ack_nack_feedback(mod_id, i) != -1) { + config->has_tdd_ack_nack_feedback = 1; + config->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback(mod_id,i); + } + + if(flexran_get_ack_nack_repetition_factor(mod_id, i) != -1) { + config->has_ack_nack_repetition_factor = 1; + config->ack_nack_repetition_factor = flexran_get_ack_nack_repetition_factor(mod_id,i); + } + + if(flexran_get_extended_bsr_size(mod_id, i) != -1) { + config->has_extended_bsr_size = 1; + config->extended_bsr_size = flexran_get_extended_bsr_size(mod_id,i); + } + + config->has_pcell_carrier_index = 1; + config->pcell_carrier_index = UE_PCCID(mod_id, i); + //TODO: Set carrier aggregation support (boolean) + config->has_ca_support = 0; + config->ca_support = 0; + if(config->has_ca_support){ + //TODO: Set cross carrier scheduling support (boolean) + config->has_cross_carrier_sched_support = 1; + config->cross_carrier_sched_support = 0; + //TODO: Set secondary cells configuration + // We do not set it for now. No carrier aggregation support + + //TODO: Set deactivation timer for secondary cell + config->has_scell_deactivation_timer = 0; + config->scell_deactivation_timer = 0; + } + } else if (state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_MOVED) { + // TODO: Not supported for now. Leave blank + } + + ue_state_change_msg->config = config; + msg = malloc(sizeof(Protocol__FlexranMessage)); + if (msg == NULL) { + goto error; + } + protocol__flexran_message__init(msg); + msg->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_STATE_CHANGE_MSG; + msg->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE; + msg->ue_state_change_msg = ue_state_change_msg; + + data = flexran_agent_pack_message(msg, &size); + /*Send sr info using the MAC channel of the eNB*/ + if (flexran_agent_msg_send(mod_id, FLEXRAN_AGENT_DEFAULT, data, size, priority)) { + err_code = PROTOCOL__FLEXRAN_ERR__MSG_ENQUEUING; + goto error; + } + + LOG_D(FLEXRAN_AGENT,"sent message with size %d\n", size); + return; + error: + LOG_D(FLEXRAN_AGENT, "Could not send UE state message\n"); +} + + + +int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg) { + if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_STATE_CHANGE_MSG) + goto error; + free(msg->ue_state_change_msg->header); + //TODO: Free the contents of the UE config structure + free(msg->ue_state_change_msg); + free(msg); + return 0; + + error: + //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); + return -1; +} + +/* this is called by RRC as a part of rrc xface . The controller previously requested this*/ +int flexran_trigger_rrc_measurements (mid_t mod_id, MeasResults_t* measResults) { + + // int i, m, k; + int priority; + void *data; + int size; + err_code_t err_code; + Protocol__FlexUeStatsReport **ue_report; + Protocol__FlexCellStatsReport **cell_report; + Protocol__FlexStatsReply *stats_reply_msg; + Protocol__FlexranMessage *msg; + + Protocol__FlexHeader *header; + int xid = 0; + int i; + + if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_STATS_REPLY, &header) != 0) + goto error; + + + + stats_reply_msg = malloc(sizeof(Protocol__FlexStatsReply)); + + if (stats_reply_msg == NULL) + goto error; + + protocol__flex_stats_reply__init(stats_reply_msg); + stats_reply_msg->header = header; + stats_reply_msg->n_ue_report = 1; + stats_reply_msg->n_cell_report = 1; + +/****** LOCK ******************************************************************/ + // pthread_spin_lock(&rrc_meas_t_lock); + + // struct rrc_meas_trigg *ctxt; + // ctxt = rrc_meas_get_trigg(p->rnti, p->meas->measId); + + // pthread_spin_unlock(&rrc_meas_t_lock); +/****** UNLOCK ****************************************************************/ + + // if (ctxt == NULL) { + + // flexran_RRC_meas_reconf(p->rnti, -1, p->meas->measId, NULL, NULL); + // Free the measurement report received from UE. + // ASN_STRUCT_FREE(asn_DEF_MeasResults, p->meas); + // /* Free the params. */ + // free(p); + // return 0; + // } + + + /* Check here whether trigger is registered in agent and then proceed. + */ + // if (em_has_trigger(mod_id, ctxt->t_id, RRC_MEAS_TRIGGER) == 0) { + + // flexran_RRC_meas_reconf(p->rnti, -1, p->meas->measId, NULL, NULL); + // /* Trigger does not exist in agent so remove from wrapper as well. */ + // if (rrc_meas_rem_trigg(ctxt) < 0) { + // goto error; + // } + // } + + + + + /* Set the RNTI of the UE. */ + // repl->rnti = p->rnti; + /* Set the request status. */ + // if (p->reconfig_success == 0) { + // repl->status = STATS_REQ_STATUS__SREQS_FAILURE; + // goto error; + // } + /* Successful outcome. */ + // repl->status = STATS_REQ_STATUS__SREQS_SUCCESS; + /* Set the measurement ID of measurement. */ + // repl->has_measid = 1; + // repl->measid = measResults->measId; + /* Fill the Primary Cell RSRP and RSRQ. */ + // repl->has_pcell_rsrp = 1; + // repl->has_pcell_rsrq = 1; + // #ifdef Rel10 + // repl->has_pcell_rsrp = 1; + // repl->has_pcell_rsrq = 1; + // repl->pcell_rsrp = measResults2->measResultPCell.rsrpResult - 140; + // repl->pcell_rsrq = (measResults2->measResultPCell.rsrqResult)/2 - 20; + + ue_report = malloc(sizeof(Protocol__FlexUeStatsReport *) * 1); + if (ue_report == NULL) + goto error; + + for (i = 0; i < 1; i++) { + + ue_report[i] = malloc(sizeof(Protocol__FlexUeStatsReport)); + if(ue_report[i] == NULL) + goto error; + protocol__flex_ue_stats_report__init(ue_report[i]); + ue_report[i]->rnti = flexran_get_ue_crnti(mod_id, 0); + ue_report[i]->has_rnti = 1; + ue_report[i]->flags = 65536; + ue_report[i]->has_flags = 1; + + } + + cell_report = malloc(sizeof(Protocol__FlexCellStatsReport *) * 1); + if (cell_report == NULL) + goto error; + + for (i = 0; i < 1; i++) { + + cell_report[i] = malloc(sizeof(Protocol__FlexCellStatsReport)); + if(cell_report[i] == NULL) + goto error; + + protocol__flex_cell_stats_report__init(cell_report[i]); + cell_report[i]->carrier_index = 0; //report_config->cc_report_type[i].cc_id; + cell_report[i]->has_carrier_index = 1; + cell_report[i]->flags = 0; // report_config->cc_report_type[i].cc_report_flags; + cell_report[i]->has_flags = 1; + } + + + Protocol__FlexRrcMeasurements *rrc_measurements; + rrc_measurements = malloc(sizeof(Protocol__FlexRrcMeasurements)); + if (rrc_measurements == NULL) + goto error; + protocol__flex_rrc_measurements__init(rrc_measurements); + + rrc_measurements->measid = measResults->measId; + rrc_measurements->has_measid = 1; + + rrc_measurements->pcell_rsrp = measResults->measResultPCell.rsrpResult - 140; + rrc_measurements->has_pcell_rsrp = 1; + + rrc_measurements->pcell_rsrq = (measResults->measResultPCell.rsrqResult)/2 - 20; + rrc_measurements->has_pcell_rsrq = 1 ; + + ue_report[0]->rrc_measurements = rrc_measurements; + + + + + + // #else + // repl->has_pcell_rsrp = 1; + // repl->has_pcell_rsrq = 1; + // repl->pcell_rsrp = RSRP_meas_mapping[meas-> + // measResultServCell.rsrpResult]; + // repl->pcell_rsrq = RSRQ_meas_mapping[meas-> + // measResultServCell.rsrqResult]; + // #endif + + // repl->neigh_meas = NULL; + + // if (meas->measResultNeighCells != NULL) { + // /* + // * Neighboring cells measurements performed by UE. + // */ + // NeighCellsMeasurements *neigh_meas; + // neigh_meas = malloc(sizeof(NeighCellsMeasurements)); + // if (neigh_meas == NULL) + // goto error; + // neigh_cells_measurements__init(neigh_meas); + + // /* EUTRAN RRC Measurements. */ + // if (meas->measResultNeighCells->present == + // MeasResults__measResultNeighCells_PR_measResultListEUTRA) { + + // MeasResultListEUTRA_t meas_list = meas->measResultNeighCells-> + // choice.measResultListEUTRA; + // /* Set the number of EUTRAN measurements present in report. */ + // neigh_meas->n_eutra_meas = meas_list.list.count; + // if (neigh_meas->n_eutra_meas > 0) { + // /* Initialize EUTRAN measurements. */ + // EUTRAMeasurements **eutra_meas; + // eutra_meas = malloc(sizeof(EUTRAMeasurements *) * + // neigh_meas->n_eutra_meas); + // for (i = 0; i < neigh_meas->n_eutra_meas; i++) { + // eutra_meas[i] = malloc(sizeof(EUTRAMeasurements)); + // eutra_measurements__init(eutra_meas[i]); + // /* Fill in the physical cell identifier. */ + // eutra_meas[i]->has_phys_cell_id = 1; + // eutra_meas[i]->phys_cell_id = meas_list.list.array[i]-> + // physCellId; + // // log_i(agent,"PCI of Target %d", eutra_meas[i]->phys_cell_id); + // /* Check for Reference signal measurements. */ + // if (&(meas_list.list.array[i]->measResult)) { + // /* Initialize Ref. signal measurements. */ + // EUTRARefSignalMeas *meas_result; + // meas_result = malloc(sizeof(EUTRARefSignalMeas)); + // eutra_ref_signal_meas__init(meas_result); + + // if (meas_list.list.array[i]->measResult.rsrpResult) { + // meas_result->has_rsrp = 1; + // meas_result->rsrp = RSRP_meas_mapping[*(meas_list. + // list.array[i]->measResult.rsrpResult)]; + // // log_i(agent,"RSRP of Target %d", meas_result->rsrp); + // } + + // if (meas_list.list.array[i]->measResult.rsrqResult) { + // meas_result->has_rsrq = 1; + // meas_result->rsrq = RSRQ_meas_mapping[*(meas_list. + // list.array[i]->measResult.rsrqResult)]; + // // log_i(agent,"RSRQ of Target %d", meas_result->rsrq); + // } + // eutra_meas[i]->meas_result = meas_result; + // } + // /* Check for CGI measurements. */ + // if (meas_list.list.array[i]->cgi_Info) { + // /* Initialize CGI measurements. */ + // EUTRACgiMeasurements *cgi_meas; + // cgi_meas = malloc(sizeof(EUTRACgiMeasurements)); + // eutra_cgi_measurements__init(cgi_meas); + + // /* EUTRA Cell Global Identity (CGI). */ + // CellGlobalIdEUTRA *cgi; + // cgi = malloc(sizeof(CellGlobalIdEUTRA)); + // cell_global_id__eutra__init(cgi); + + // cgi->has_cell_id = 1; + // CellIdentity_t cId = meas_list.list.array[i]-> + // cgi_Info->cellGlobalId.cellIdentity; + // cgi->cell_id = (cId.buf[0] << 20) + (cId.buf[1] << 12) + + // (cId.buf[2] << 4) + (cId.buf[3] >> 4); + + // /* Public land mobile network identifier of neighbor + // * cell. + // */ + // PlmnIdentity *plmn_id; + // plmn_id = malloc(sizeof(PlmnIdentity)); + // plmn_identity__init(plmn_id); + + // MNC_t mnc = meas_list.list.array[i]-> + // cgi_Info->cellGlobalId.plmn_Identity.mnc; + + // plmn_id->has_mnc = 1; + // plmn_id->mnc = 0; + // for (m = 0; m < mnc.list.count; m++) { + // plmn_id->mnc += *mnc.list.array[m] * + // ((uint32_t) pow(10, mnc.list.count - m - 1)); + // } + + // MCC_t *mcc = meas_list.list.array[i]-> + // cgi_Info->cellGlobalId.plmn_Identity.mcc; + + // plmn_id->has_mcc = 1; + // plmn_id->mcc = 0; + // for (m = 0; m < mcc->list.count; m++) { + // plmn_id->mcc += *mcc->list.array[m] * + // ((uint32_t) pow(10, mcc->list.count - m - 1)); + // } + + // TrackingAreaCode_t tac = meas_list.list.array[i]-> + // cgi_Info->trackingAreaCode; + + // cgi_meas->has_tracking_area_code = 1; + // cgi_meas->tracking_area_code = (tac.buf[0] << 8) + + // (tac.buf[1]); + + // PLMN_IdentityList2_t *plmn_l = meas_list.list.array[i]-> + // cgi_Info->plmn_IdentityList; + + // cgi_meas->n_plmn_id = plmn_l->list.count; + // /* Set the PLMN ID list in CGI measurements. */ + // PlmnIdentity **plmn_id_l; + // plmn_id_l = malloc(sizeof(PlmnIdentity *) * + // cgi_meas->n_plmn_id); + + // MNC_t mnc2; + // MCC_t *mcc2; + // for (m = 0; m < cgi_meas->n_plmn_id; m++) { + // plmn_id_l[m] = malloc(sizeof(PlmnIdentity)); + // plmn_identity__init(plmn_id_l[m]); + + // mnc2 = plmn_l->list.array[m]->mnc; + // plmn_id_l[m]->has_mnc = 1; + // plmn_id_l[m]->mnc = 0; + // for (k = 0; k < mnc2.list.count; k++) { + // plmn_id_l[m]->mnc += *mnc2.list.array[k] * + // ((uint32_t) pow(10, mnc2.list.count - k - 1)); + // } + + // mcc2 = plmn_l->list.array[m]->mcc; + // plmn_id_l[m]->has_mcc = 1; + // plmn_id_l[m]->mcc = 0; + // for (k = 0; k < mcc2->list.count; k++) { + // plmn_id_l[m]->mcc += *mcc2->list.array[k] * + // ((uint32_t) pow(10, mcc2->list.count - k - 1)); + // } + // } + // cgi_meas->plmn_id = plmn_id_l; + // eutra_meas[i]->cgi_meas = cgi_meas; + // } + // } + // neigh_meas->eutra_meas = eutra_meas; + // } + // } + // repl->neigh_meas = neigh_meas; + // } + /* Attach the RRC measurement reply message to RRC measurements message. */ + // mrrc_meas->repl = repl; + /* Attach RRC measurement message to triggered event message. */ + // te->mrrc_meas = mrrc_meas; + // te->has_action = 0; + /* Attach the triggered event message to main message. */ + // reply->te = te; + + /* Send the report to controller. */ + // if (flexran_agent_msg_send(b_id, reply) < 0) { + // goto error; + // } + + /* Free the measurement report received from UE. */ + // ASN_STRUCT_FREE(asn_DEF_MeasResults, p->meas); + /* Free the params. */ + // free(p); + + + stats_reply_msg->cell_report = cell_report; + + stats_reply_msg->ue_report = ue_report; + + msg = malloc(sizeof(Protocol__FlexranMessage)); + if(msg == NULL) + goto error; + protocol__flexran_message__init(msg); + msg->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REPLY_MSG; + msg->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME; + msg->stats_reply_msg = stats_reply_msg; + + data = flexran_agent_pack_message(msg, &size); + + + if (flexran_agent_msg_send(mod_id, FLEXRAN_AGENT_DEFAULT, data, size, priority)) { + + err_code = PROTOCOL__FLEXRAN_ERR__MSG_ENQUEUING; + goto error; + } + + LOG_I(FLEXRAN_AGENT,"RRC Trigger is done \n"); + + return 0; + + error: + + LOG_E(RRC, "Error triggering RRC measurements message!"); + /* Free the measurement report received from UE. */ + // ASN_STRUCT_FREE(asn_DEF_MeasResults, p->meas); + /* Free the params. */ + // free(p); + return -1; +} + + +int flexran_agent_register_rrc_xface(mid_t mod_id, AGENT_RRC_xface *xface) { + if (rrc_agent_registered[mod_id]) { + LOG_E(RRC, "RRC agent for eNB %d is already registered\n", mod_id); + return -1; + } + +// xface->flexran_agent_send_update_rrc_stats = flexran_agent_send_update_rrc_stats; + + xface->flexran_agent_notify_ue_state_change = flexran_agent_ue_state_change; + xface->flexran_trigger_rrc_measurements = flexran_trigger_rrc_measurements; + + rrc_agent_registered[mod_id] = 1; + agent_rrc_xface[mod_id] = xface; + + return 0; +} + +int flexran_agent_unregister_rrc_xface(mid_t mod_id, AGENT_RRC_xface *xface) { + + //xface->agent_ctxt = NULL; +// xface->flexran_agent_send_update_rrc_stats = NULL; + + xface->flexran_agent_notify_ue_state_change = NULL; + xface->flexran_trigger_rrc_measurements = NULL; + rrc_agent_registered[mod_id] = 0; + agent_rrc_xface[mod_id] = NULL; + + return 0; +} diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h new file mode 100644 index 0000000000..17b58dac93 --- /dev/null +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h @@ -0,0 +1,74 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2014 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see . + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France. + + *******************************************************************************/ + +/*! \file flexran_agent_rrc.h + * \brief FlexRAN agent Control Module RRC header + * \author shahab SHARIAT BAGHERI + * \date 2017 + * \version 0.1 + */ + +#ifndef FLEXRAN_AGENT_RRC_H_ +#define FLEXRAN_AGENT_RRC_H_ + +#include "header.pb-c.h" +#include "flexran.pb-c.h" +#include "stats_messages.pb-c.h" +#include "stats_common.pb-c.h" +#include "MeasResults.h" + +#include "flexran_agent_common.h" +#include "flexran_agent_rrc_defs.h" + + +/* Initialization function for the agent structures etc */ +void flexran_agent_init_rrc_agent(mid_t mod_id); + +/* UE state change message constructor and destructor */ +int flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_change); +int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg); + + +/********************************** + * FlexRAN agent - technology RRC API + **********************************/ + +/* Send to the controller all the rrc stat updates that occured during this subframe*/ +// void flexran_agent_send_update_rrc_stats(mid_t mod_id); + +/* this is called by RRC as a part of rrc xface . The controller previously requested this*/ +int flexran_trigger_rrc_measurements (mid_t mod_id, MeasResults_t *); + +/*Register technology specific interface callbacks*/ +int flexran_agent_register_rrc_xface(mid_t mod_id, AGENT_RRC_xface *xface); + +/*Unregister technology specific callbacks*/ +int flexran_agent_unregister_rrc_xface(mid_t mod_id, AGENT_RRC_xface*xface); + +#endif diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h new file mode 100644 index 0000000000..10fc4ba254 --- /dev/null +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h @@ -0,0 +1,62 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2016 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see . + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France. + + *******************************************************************************/ + +/*! \file flexran_agent_rrc_defs.h + * \brief FlexRAN agent - RRC interface primitives + * \author shahab SHARIAT BAGHERI + * \date 2017 + * \version 0.1 + * \mail + */ + +#ifndef __FLEXRAN_AGENT_RRC_PRIMITIVES_H__ +#define __FLEXRAN_AGENT_RRC_PRIMITIVES_H__ + +#include "flexran_agent_defs.h" +#include "flexran.pb-c.h" +#include "header.pb-c.h" + +#define RINGBUFFER_SIZE 100 + +/* FLEXRAN AGENT-RRC Interface */ +typedef struct { + + /// Inform the controller about the scheduling requests received during the subframe + //void (*flexran_agent_send_update_rrc_stats)(mid_t mod_id); + + /// Notify the controller for a state change of a particular UE, by sending the proper + /// UE state change message (ACTIVATION, DEACTIVATION, HANDOVER) + void (*flexran_agent_notify_ue_state_change)(mid_t mod_id, uint32_t rnti, + uint32_t state_change); + + void (*flexran_trigger_rrc_measurements)(mid_t mod_id, MeasResults_t* measResults) + +} AGENT_RRC_xface; + +#endif diff --git a/openair2/ENB_APP/MESSAGES/V2/flexran.proto b/openair2/ENB_APP/MESSAGES/V2/flexran.proto index 3a1d40bca6..7fb3a22df8 100644 --- a/openair2/ENB_APP/MESSAGES/V2/flexran.proto +++ b/openair2/ENB_APP/MESSAGES/V2/flexran.proto @@ -28,6 +28,7 @@ message flexran_message { flex_ue_state_change ue_state_change_msg = 15; flex_control_delegation control_delegation_msg = 16; flex_agent_reconfiguration agent_reconfiguration_msg = 17; + flex_rrc_triggering rrc_triggering = 18; } } @@ -163,6 +164,13 @@ message flex_dl_mac_config { repeated flex_pdcch_ofdm_sym_count ofdm_sym = 6; // OFDM symbol count for each CC } +message flex_rrc_triggering { + + optional flex_header header = 1; + optional string rrc_trigger = 2; +} + + // // UE state change message // diff --git a/openair2/ENB_APP/MESSAGES/V2/header.proto b/openair2/ENB_APP/MESSAGES/V2/header.proto index dfd5ea6c99..468dcd201e 100644 --- a/openair2/ENB_APP/MESSAGES/V2/header.proto +++ b/openair2/ENB_APP/MESSAGES/V2/header.proto @@ -39,5 +39,7 @@ enum flex_type { // Control delegation messages FLPT_DELEGATE_CONTROL = 15; FLPT_RECONFIGURE_AGENT = 16; + FLPT_RRC_TRIGGERING = 17; + } diff --git a/openair2/ENB_APP/MESSAGES/V2/stats_common.proto b/openair2/ENB_APP/MESSAGES/V2/stats_common.proto index 080883ea97..cce36df00a 100644 --- a/openair2/ENB_APP/MESSAGES/V2/stats_common.proto +++ b/openair2/ENB_APP/MESSAGES/V2/stats_common.proto @@ -181,3 +181,63 @@ message flex_noise_interference_report { optional int32 p0_nominal_pucch = 4; } +// +// RRC Primitives +// +message flex_rrc_measurements { + // Measurement identifier. + optional int32 measid = 1; + // Primary Cell Reference Signal Received Power (RSRP). + optional int32 pcell_rsrp = 2; + // Primary Cell Reference Signal Received Quality (RSRQ). + optional int32 pcell_rsrq = 3; + // Neighboring cells measurements performed by UE. + optional flex_neigh_cells_measurements neigh_meas = 4; +} + +message flex_neigh_cells_measurements { + // Neighboring EUTRA cells measurements. + repeated flex_eutra_measurements eutra_meas = 1; +} + +message flex_eutra_measurements { + // Physical Cell identifier. + optional int32 phys_cell_id = 1; + // EUTRA Cell Global Identity (CGI) measurement. + optional flex_eutra_cgi_measurements cgi_meas = 2; + // EUTRA nearby cell reference signal measurement. + optional flex_eutra_ref_signal_meas meas_result = 3; +} + +message flex_eutra_cgi_measurements { + // EUTRA Cell Global Identity (CGI). + optional flex_cell_global_eutra_id cgi = 1; + // Tracking area code of the neighbor cell. + optional uint32 tracking_area_code = 2; + // Public land mobile network identifiers of neighbor cell. + repeated flex_plmn_identity plmn_id = 3; +} + +message flex_cell_global_eutra_id { + // Public land mobile network identifier of neighbor cell. + optional flex_plmn_identity plmn_id = 1; + // Cell identifier of neighbor cell. + optional uint32 cell_id = 2; +} + +message flex_plmn_identity { + // Mobile Network Code (MNC). + repeated uint32 mnc = 1; + // Mobile Country Code (MCC). + repeated uint32 mcc = 2; + // tracking area code + repeated uint32 tac = 3; +} + +message flex_eutra_ref_signal_meas { + // Neighboring Cell Reference Signal Received Power (RSRP). + optional int32 rsrp = 1; + // Neighboring Cell Reference Signal Received Quality (RSRQ). + optional int32 rsrq = 2; + +} diff --git a/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto b/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto index 1b1567dda1..48360f6f68 100644 --- a/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto +++ b/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto @@ -46,6 +46,7 @@ message flex_ue_stats_report { optional flex_dl_cqi_report dl_cqi_report = 7; optional flex_paging_buffer_report pbr = 8; optional flex_ul_cqi_report ul_cqi_report = 9; + optional flex_rrc_measurements rrc_measurements = 10; } // @@ -76,11 +77,12 @@ enum flex_cell_stats_type { // Flags for UE-related statistics enum flex_ue_stats_type { FLUST_BSR = 1; - FLUST_PRH = 2; + FLUST_PHR = 2; FLUST_RLC_BS = 4; FLUST_MAC_CE_BS = 8; FLUST_DL_CQI = 16; FLUST_PBS = 32; FLUST_UL_CQI = 64; // To be extended with more types of stats -} \ No newline at end of file + FLUST_RRC_MEASUREMENTS = 65536; +} diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 153c89b3e2..09d7495a69 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -98,6 +98,8 @@ #define ENB_CONFIG_STRING_EUTRA_BAND "eutra_band" #define ENB_CONFIG_STRING_DOWNLINK_FREQUENCY "downlink_frequency" #define ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET "uplink_frequency_offset" +#define ENB_CONFIG_STRING_RRC_REPORT_CONFIG_AMOUNT "report_amount" +#define ENB_CONFIG_STRING_RRC_REPORT_CONFIG_INTERVAL "report_interval" #define ENB_CONFIG_STRING_NID_CELL "Nid_cell" #define ENB_CONFIG_STRING_N_RB_DL "N_RB_DL" @@ -165,7 +167,7 @@ #define ENB_CONFIG_STRING_UETIMERS_N310 "ue_TimersAndConstants_n310" #define ENB_CONFIG_STRING_UETIMERS_N311 "ue_TimersAndConstants_n311" #define ENB_CONFIG_STRING_UE_TRANSMISSION_MODE "ue_TransmissionMode" - +#define ENB_CONFIG_STRING_RRC_CONFIG "rrc_config" #define ENB_CONFIG_STRING_SRB1 "srb1_parameters" #define ENB_CONFIG_STRING_SRB1_TIMER_POLL_RETRANSMIT "timer_poll_retransmit" #define ENB_CONFIG_STRING_SRB1_TIMER_REORDERING "timer_reordering" @@ -456,6 +458,10 @@ void enb_config_display(void) printf( "\tue_TransmissionMode for CC %d:\t%ld:\n",j,enb_properties.properties[i]->ue_TransmissionMode[j]); + printf( "\n\tRRC Report Config: \n"); + printf( "\n\t Report interval \t%ld: ", enb_properties.properties[i]->rrc_report_interval); + printf( "\n\t Report amount \t%ld: \n", enb_properties.properties[i]->rrc_report_amount); + } for (j=0; j < enb_properties.properties[i]->num_otg_elements; j++) { @@ -545,6 +551,7 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) config_setting_t *setting_enb = NULL; config_setting_t *setting_otg = NULL; config_setting_t *subsetting_otg = NULL; + config_setting_t *setting_rrc = NULL; int parse_errors = 0; int num_enb_properties = 0; int enb_properties_index = 0; @@ -651,7 +658,8 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) libconfig_int srb1_max_retx_threshold = 0; libconfig_int my_int; - + const char* rrc_report_amount = NULL; + const char* rrc_report_interval = NULL; char* if_name = NULL; char* ipv4 = NULL; @@ -1968,6 +1976,75 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) } } + + setting_rrc = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_RRC_CONFIG); + if (setting_rrc != NULL) { + + if (!(config_setting_lookup_string(setting_rrc, ENB_CONFIG_STRING_RRC_REPORT_CONFIG_AMOUNT, &rrc_report_amount) + && config_setting_lookup_string(setting_rrc, ENB_CONFIG_STRING_RRC_REPORT_CONFIG_INTERVAL, &rrc_report_interval))) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d, rrc_report_amount and rrc_reporyt_interval !\n", + lib_config_file_name_pP, i); + + if (strcmp(rrc_report_amount, "r1") == 0) { + enb_properties.properties[enb_properties_index]->rrc_report_amount = ReportConfigEUTRA__reportAmount_r1; + } else if (strcmp(rrc_report_amount, "r2") == 0) { + enb_properties.properties[enb_properties_index]->rrc_report_amount = ReportConfigEUTRA__reportAmount_r2; + }else if (strcmp(rrc_report_amount, "r4") == 0) { + enb_properties.properties[enb_properties_index]->rrc_report_amount = ReportConfigEUTRA__reportAmount_r4; + }else if (strcmp(rrc_report_amount, "r8") == 0) { + enb_properties.properties[enb_properties_index]->rrc_report_amount = ReportConfigEUTRA__reportAmount_r8; + }else if (strcmp(rrc_report_amount, "r16") == 0) { + enb_properties.properties[enb_properties_index]->rrc_report_amount = ReportConfigEUTRA__reportAmount_r16; + }else if (strcmp(rrc_report_amount, "r32") == 0) { + enb_properties.properties[enb_properties_index]->rrc_report_amount = ReportConfigEUTRA__reportAmount_r32; + }else if (strcmp(rrc_report_amount, "r64") == 0) { + enb_properties.properties[enb_properties_index]->rrc_report_amount = ReportConfigEUTRA__reportAmount_r64; + }else if (strcmp(rrc_report_amount, "infinity") == 0) { + enb_properties.properties[enb_properties_index]->rrc_report_amount = ReportConfigEUTRA__reportAmount_infinity; + }else{ + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for report_amount choice: r1, r2, r4, r8, r16, r32, r64, infinity !\n", + lib_config_file_name_pP, i,rrc_report_amount); + } + + if (strcmp(rrc_report_interval, "120ms") == 0) { + enb_properties.properties[enb_properties_index]->rrc_report_interval = ReportInterval_ms120; + } else if (strcmp(rrc_report_interval, "240ms") == 0) { + enb_properties.properties[enb_properties_index]->rrc_report_interval = ReportInterval_ms240; + }else if (strcmp(rrc_report_interval, "480ms") == 0) { + enb_properties.properties[enb_properties_index]->rrc_report_interval = ReportInterval_ms480; + }else if (strcmp(rrc_report_interval, "640ms") == 0) { + enb_properties.properties[enb_properties_index]->rrc_report_interval = ReportInterval_ms640; + }else if (strcmp(rrc_report_interval, "1024ms") == 0) { + enb_properties.properties[enb_properties_index]->rrc_report_interval = ReportInterval_ms1024; + }else if (strcmp(rrc_report_interval, "2048ms") == 0) { + enb_properties.properties[enb_properties_index]->rrc_report_interval = ReportInterval_ms2048; + }else if (strcmp(rrc_report_interval, "5120ms") == 0) { + enb_properties.properties[enb_properties_index]->rrc_report_interval = ReportInterval_ms5120; + }else if (strcmp(rrc_report_interval, "10240ms") == 0) { + enb_properties.properties[enb_properties_index]->rrc_report_interval = ReportInterval_ms10240; + }else if (strcmp(rrc_report_interval, "1min") == 0) { + enb_properties.properties[enb_properties_index]->rrc_report_interval = ReportInterval_min1; + }else if (strcmp(rrc_report_interval, "6min") == 0) { + enb_properties.properties[enb_properties_index]->rrc_report_interval = ReportInterval_min6; + }else if (strcmp(rrc_report_interval, "12min") == 0) { + enb_properties.properties[enb_properties_index]->rrc_report_interval = ReportInterval_min12; + }else if (strcmp(rrc_report_interval, "30min") == 0) { + enb_properties.properties[enb_properties_index]->rrc_report_interval = ReportInterval_min30; + } else if (strcmp(rrc_report_interval, "60min") == 0) { + enb_properties.properties[enb_properties_index]->rrc_report_interval = ReportInterval_min60; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for report_interval choice: 120ms, 240ms, 480ms, 640ms, 1024ms, 2048ms, 5120ms, 10240ms, 1min, 6min, 12", + lib_config_file_name_pP, i,rrc_report_interval); + } + + } else { + enb_properties.properties[enb_properties_index]->rrc_report_interval = ReportInterval_ms120; + enb_properties.properties[enb_properties_index]->rrc_report_amount = ReportConfigEUTRA__reportAmount_r1; + } + setting_srb1 = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_SRB1); if (setting_srb1 != NULL) { diff --git a/openair2/ENB_APP/enb_config.h b/openair2/ENB_APP/enb_config.h index a508a82e1f..094360749b 100644 --- a/openair2/ENB_APP/enb_config.h +++ b/openair2/ENB_APP/enb_config.h @@ -214,6 +214,10 @@ typedef struct Enb_properties_s { long srb1_poll_pdu; long srb1_poll_byte; long srb1_max_retx_threshold; + + long rrc_report_amount; + long rrc_report_interval; + /* Nb of MME to connect to */ uint8_t nb_mme; /* List of MME to connect to */ diff --git a/openair2/ENB_APP/flexran_agent.c b/openair2/ENB_APP/flexran_agent.c index 0dcacd4b81..d96076df83 100644 --- a/openair2/ENB_APP/flexran_agent.c +++ b/openair2/ENB_APP/flexran_agent.c @@ -21,27 +21,16 @@ /*! \file flexran_agent.h * \brief top level flexran agent receive thread and itti task - * \author Xenofon Foukas and Navid Nikaein - * \date 2016 + * \author Xenofon Foukas and Navid Nikaein and shahab SHARIAT BAGHERI + * \date 2017 * \version 0.1 */ -#include "flexran_agent_common.h" -#include "log.h" #include "flexran_agent.h" -#include "flexran_agent_mac_defs.h" -#include "flexran_agent_mac.h" -#include "flexran_agent_mac_internal.h" - -#include "flexran_agent_extern.h" - -#include "assertions.h" - -#include "flexran_agent_net_comm.h" -#include "flexran_agent_async.h" #include + //#define TEST_TIMER flexran_agent_instance_t flexran_agent[NUM_MAX_ENB]; @@ -264,8 +253,8 @@ int flexran_agent_start(mid_t mod_id, const Enb_properties_array_t* enb_properti *flexran_agent_register_channel(mod_id, channel, FLEXRAN_AGENT_MAC); */ - /*Initialize the continuous MAC stats update mechanism*/ - flexran_agent_init_cont_mac_stats_update(mod_id); + /*Initialize the continuous stats update mechanism*/ + flexran_agent_init_cont_stats_update(mod_id); new_thread(receive_thread, &flexran_agent[mod_id]); @@ -275,6 +264,9 @@ int flexran_agent_start(mid_t mod_id, const Enb_properties_array_t* enb_properti AGENT_MAC_xface *mac_agent_xface = (AGENT_MAC_xface *) malloc(sizeof(AGENT_MAC_xface)); flexran_agent_register_mac_xface(mod_id, mac_agent_xface); + AGENT_RRC_xface *rrc_agent_xface = (AGENT_MAC_xface *) malloc(sizeof(AGENT_MAC_xface)); + flexran_agent_register_rrc_xface(mod_id, rrc_agent_xface); + /* * initilize a timer */ diff --git a/openair2/ENB_APP/flexran_agent.h b/openair2/ENB_APP/flexran_agent.h index 21ea21aafc..aec4f004a8 100644 --- a/openair2/ENB_APP/flexran_agent.h +++ b/openair2/ENB_APP/flexran_agent.h @@ -22,15 +22,23 @@ /*! \file flexran_agent.h * \brief top level flexran agent * \author Navid Nikaein and Xenofon Foukas - * \date 2016 + * \date 2017 * \version 0.1 */ #ifndef FLEXRAN_AGENT_H_ #define FLEXRAN_AGENT_H_ -#include "enb_config.h" // for enb properties #include "flexran_agent_common.h" +#include "flexran_agent_async.h" +#include "flexran_agent_extern.h" +#include "flexran_agent_timer.h" +#include "flexran_agent_defs.h" + +#include "log.h" +#include "assertions.h" + +#include "enb_config.h" // for enb properties /* Initiation and termination of the eNodeB agent */ diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index f2d00145a0..7d9cfe685c 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -21,8 +21,8 @@ /*! \file flexran_agent_common.c * \brief common primitives for all agents - * \author Xenofon Foukas, Mohamed Kassem and Navid Nikaein - * \date 2016 + * \author Xenofon Foukas, Mohamed Kassem and Navid Nikaein, shahab SHARIAT BAGHERI + * \date 2017 * \version 0.1 */ @@ -41,10 +41,6 @@ #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" #include "rrc_eNB_UE_context.h" -void * enb[NUM_MAX_ENB]; -void * enb_ue[NUM_MAX_ENB]; -void * enb_rrc[NUM_MAX_ENB]; - /* * message primitives */ @@ -344,19 +340,6 @@ int flexran_agent_destroy_lc_config_reply(Protocol__FlexranMessage *msg) { return -1; } -int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg) { - if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_STATE_CHANGE_MSG) - goto error; - free(msg->ue_state_change_msg->header); - //TODO: Free the contents of the UE config structure - free(msg->ue_state_change_msg); - free(msg); - return 0; - - error: - //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); - return -1; -} int flexran_agent_destroy_enb_config_request(Protocol__FlexranMessage *msg) { if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REQUEST_MSG) @@ -442,1082 +425,6 @@ int flexran_agent_destroy_agent_reconfiguration(Protocol__FlexranMessage *msg) { } -/* - * get generic info from RAN - */ - -void flexran_set_enb_vars(mid_t mod_id, ran_name_t ran){ - - switch (ran){ - case RAN_LTE_OAI : - enb[mod_id] = (void *)&eNB_mac_inst[mod_id]; - enb_ue[mod_id] = (void *)&eNB_mac_inst[mod_id].UE_list; - enb_rrc[mod_id] = (void *)&eNB_rrc_inst[mod_id]; - break; - default : - goto error; - } - - return; - - error: - LOG_E(FLEXRAN_AGENT, "unknown RAN name %d\n", ran); -} - -int flexran_get_current_time_ms (mid_t mod_id, int subframe_flag){ - - if (subframe_flag == 1){ - return ((eNB_MAC_INST *)enb[mod_id])->frame*10 + ((eNB_MAC_INST *)enb[mod_id])->subframe; - }else { - return ((eNB_MAC_INST *)enb[mod_id])->frame*10; - } - -} - -unsigned int flexran_get_current_frame (mid_t mod_id) { - - // #warning "SFN will not be in [0-1023] when oaisim is used" - return ((eNB_MAC_INST *)enb[mod_id])->frame; - -} - -unsigned int flexran_get_current_system_frame_num(mid_t mod_id) { - return (flexran_get_current_frame(mod_id) %1024); -} - -unsigned int flexran_get_current_subframe (mid_t mod_id) { - - return ((eNB_MAC_INST *)enb[mod_id])->subframe; - -} - -uint16_t flexran_get_sfn_sf (mid_t mod_id) { - - frame_t frame; - sub_frame_t subframe; - uint16_t sfn_sf, frame_mask, sf_mask; - - frame = (frame_t) flexran_get_current_system_frame_num(mod_id); - subframe = (sub_frame_t) flexran_get_current_subframe(mod_id); - frame_mask = ((1<<12) - 1); - sf_mask = ((1<<4) - 1); - sfn_sf = (subframe & sf_mask) | ((frame & frame_mask) << 4); - - return sfn_sf; -} - -uint16_t flexran_get_future_sfn_sf (mid_t mod_id, int ahead_of_time) { - - frame_t frame; - sub_frame_t subframe; - uint16_t sfn_sf, frame_mask, sf_mask; - - frame = (frame_t) flexran_get_current_system_frame_num(mod_id); - subframe = (sub_frame_t) flexran_get_current_subframe(mod_id); - - subframe = ((subframe + ahead_of_time) % 10); - - if (subframe < flexran_get_current_subframe(mod_id)) { - frame = (frame + 1) % 1024; - } - - int additional_frames = ahead_of_time / 10; - frame = (frame + additional_frames) % 1024; - - frame_mask = ((1<<12) - 1); - sf_mask = ((1<<4) - 1); - sfn_sf = (subframe & sf_mask) | ((frame & frame_mask) << 4); - - return sfn_sf; -} - -int flexran_get_num_ues (mid_t mod_id){ - - return ((UE_list_t *)enb_ue[mod_id])->num_UEs; -} - -int flexran_get_ue_crnti (mid_t mod_id, mid_t ue_id) { - - return UE_RNTI(mod_id, ue_id); -} - -int flexran_get_ue_bsr (mid_t mod_id, mid_t ue_id, lcid_t lcid) { - - return ((UE_list_t *)enb_ue[mod_id])->UE_template[UE_PCCID(mod_id,ue_id)][ue_id].bsr_info[lcid]; -} - -int flexran_get_ue_phr (mid_t mod_id, mid_t ue_id) { - - return ((UE_list_t *)enb_ue[mod_id])->UE_template[UE_PCCID(mod_id,ue_id)][ue_id].phr_info; -} - -int flexran_get_ue_wcqi (mid_t mod_id, mid_t ue_id) { - LTE_eNB_UE_stats *eNB_UE_stats = NULL; - eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, 0, UE_RNTI(mod_id, ue_id)); - return eNB_UE_stats->DL_cqi[0]; - - // return ((UE_list_t *)enb_ue[mod_id])->eNB_UE_stats[UE_PCCID(mod_id,ue_id)][ue_id].dl_cqi; -} - -int flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) { - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - uint16_t frame = (uint16_t) flexran_get_current_frame(mod_id); - mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id,frame,ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0); - return rlc_status.bytes_in_buffer; -} - -int flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) { - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - uint16_t frame = (uint16_t) flexran_get_current_frame(mod_id); - mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, ENB_FLAG_YES, MBMS_FLAG_NO, channel_id, 0); - return rlc_status.head_sdu_creation_time; -} - -short flexran_get_TA(mid_t mod_id, mid_t ue_id, int CC_id) { - - UE_list_t *UE_list=&eNB_mac_inst[mod_id].UE_list; - int rnti; - - rnti = flexran_get_ue_crnti(mod_id, ue_id); - - LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti); - //ue_sched_ctl->ta_timer = 20; // wait 20 subframes before taking TA measurement from PHY - switch (PHY_vars_eNB_g[mod_id][CC_id]->frame_parms.N_RB_DL) { - case 6: - return eNB_UE_stats->timing_advance_update; - case 15: - return eNB_UE_stats->timing_advance_update/2; - case 25: - return eNB_UE_stats->timing_advance_update/4; - case 50: - return eNB_UE_stats->timing_advance_update/8; - case 75: - return eNB_UE_stats->timing_advance_update/12; - case 100: - if (PHY_vars_eNB_g[mod_id][CC_id]->frame_parms.threequarter_fs == 0) { - return eNB_UE_stats->timing_advance_update/16; - } else { - return eNB_UE_stats->timing_advance_update/12; - } - default: - return 0; - } -} - -void flexran_update_TA(mid_t mod_id, mid_t ue_id, int CC_id) { - - UE_list_t *UE_list=&eNB_mac_inst[mod_id].UE_list; - UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[ue_id]; - - if (ue_sched_ctl->ta_timer == 0) { - - // WE SHOULD PROTECT the eNB_UE_stats with a mutex here ... - // LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti); - //ue_sched_ctl->ta_timer = 20; // wait 20 subframes before taking TA measurement from PHY - ue_sched_ctl->ta_update = flexran_get_TA(mod_id, ue_id, CC_id); - - // clear the update in case PHY does not have a new measurement after timer expiry - // eNB_UE_stats->timing_advance_update = 0; - } else { - ue_sched_ctl->ta_timer--; - ue_sched_ctl->ta_update = 0; // don't trigger a timing advance command - } -} - -int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id,int CC_id) { - - UE_list_t *UE_list = &eNB_mac_inst[mod_id].UE_list; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id,CC_id,rnti); - - if (eNB_UE_stats == NULL) { - return 0; - } - - if (flexran_get_TA(mod_id, ue_id, CC_id) != 0) { - return PROTOCOL__FLEX_CE_TYPE__FLPCET_TA; - } else { - return 0; - } - -} - -int flexran_get_active_CC(mid_t mod_id, mid_t ue_id) { - return ((UE_list_t *)enb_ue[mod_id])->numactiveCCs[ue_id]; -} - -int flexran_get_current_RI(mid_t mod_id, mid_t ue_id, int CC_id) { - LTE_eNB_UE_stats *eNB_UE_stats = NULL; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - - eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id,CC_id,rnti); - - if (eNB_UE_stats == NULL) { - return 0; - } - - return eNB_UE_stats[CC_id].rank; -} - -int flexran_get_tpc(mid_t mod_id, mid_t ue_id) { - LTE_eNB_UE_stats *eNB_UE_stats = NULL; - int32_t normalized_rx_power, target_rx_power; - int tpc = 1; - - int pCCid = UE_PCCID(mod_id,ue_id); - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - - eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, pCCid, rnti); - - target_rx_power = mac_xface->get_target_pusch_rx_power(mod_id,pCCid); - - if (eNB_UE_stats == NULL) { - normalized_rx_power = target_rx_power; - } else if (eNB_UE_stats->UL_rssi != NULL) { - normalized_rx_power = eNB_UE_stats->UL_rssi[0]; - } else { - normalized_rx_power = target_rx_power; - } - - if (normalized_rx_power>(target_rx_power+1)) { - tpc = 0; //-1 - } else if (normalized_rx_power<(target_rx_power-1)) { - tpc = 2; //+1 - } else { - tpc = 1; //0 - } - return tpc; -} - -int flexran_get_harq(const mid_t mod_id, - const uint8_t CC_id, - const mid_t ue_id, - const int frame, - const uint8_t subframe, - uint8_t *id, - uint8_t *round) { //flag_id_status = 0 then id, else status - /*TODO: Add int TB in function parameters to get the status of the second TB. This can be done to by editing in - * get_ue_active_harq_pid function in line 272 file: phy_procedures_lte_eNB.c to add - * DLSCH_ptr = PHY_vars_eNB_g[Mod_id][CC_id]->dlsch_eNB[(uint32_t)UE_id][1];*/ - - uint8_t harq_pid; - uint8_t harq_round; - - - uint16_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - - mac_xface->get_ue_active_harq_pid(mod_id,CC_id,rnti,frame,subframe,&harq_pid,&harq_round,openair_harq_DL); - - *id = harq_pid; - *round = harq_round; - /* if (round > 0) { */ - /* *status = 1; */ - /* } else { */ - /* *status = 0; */ - /* } */ - - /* return 0; */ - return *round; -} - -int flexran_get_p0_pucch_dbm(mid_t mod_id, mid_t ue_id, int CC_id) { - LTE_eNB_UE_stats *eNB_UE_stats = NULL; - uint32_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - - eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti); - - if (eNB_UE_stats == NULL) { - return -1; - } - - // if(eNB_UE_stats->Po_PUCCH_update == 1) { - return eNB_UE_stats->Po_PUCCH_dBm; - //} - //else - // return -1; -} - -int flexran_get_p0_nominal_pucch(mid_t mod_id, int CC_id) { - int32_t pucch_rx_received = mac_xface->get_target_pucch_rx_power(mod_id, CC_id); - return pucch_rx_received; -} - -int flexran_get_p0_pucch_status(mid_t mod_id, mid_t ue_id, int CC_id) { - LTE_eNB_UE_stats *eNB_UE_stats = NULL; - uint32_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - - eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti); - return eNB_UE_stats->Po_PUCCH_update; -} - -int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, int CC_id) { - LTE_eNB_UE_stats *eNB_UE_stats = NULL; - uint32_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - - eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti); - eNB_UE_stats->Po_PUCCH_update = 0; - - return 0; -} - - -/* - * ************************************ - * Get Messages for eNB Configuration Reply - * ************************************ - */ - -int flexran_get_hopping_offset(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->pusch_config_common.pusch_HoppingOffset; -} - -int flexran_get_hopping_mode(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->pusch_config_common.hoppingMode; -} - -int flexran_get_n_SB(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->pusch_config_common.n_SB; -} - -int flexran_get_enable64QAM(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->pusch_config_common.enable64QAM; -} - -int flexran_get_phich_duration(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->phich_config_common.phich_duration; -} - -int flexran_get_phich_resource(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - if(frame_parms->phich_config_common.phich_resource == oneSixth) - return 0; - else if(frame_parms->phich_config_common.phich_resource == half) - return 1; - else if(frame_parms->phich_config_common.phich_resource == one) - return 2; - else if(frame_parms->phich_config_common.phich_resource == two) - return 3; - - return -1; -} - -int flexran_get_n1pucch_an(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->pucch_config_common.n1PUCCH_AN; -} - -int flexran_get_nRB_CQI(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->pucch_config_common.nRB_CQI; -} - -int flexran_get_deltaPUCCH_Shift(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->pucch_config_common.deltaPUCCH_Shift; -} - -int flexran_get_prach_ConfigIndex(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex; -} - -int flexran_get_prach_FreqOffset(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset; -} - -int flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->maxHARQ_Msg3Tx; -} - -int flexran_get_ul_cyclic_prefix_length(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->Ncp_UL; -} - -int flexran_get_dl_cyclic_prefix_length(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->Ncp; -} - -int flexran_get_cell_id(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->Nid_cell; -} - -int flexran_get_srs_BandwidthConfig(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->soundingrs_ul_config_common.srs_BandwidthConfig; -} - -int flexran_get_srs_SubframeConfig(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->soundingrs_ul_config_common.srs_SubframeConfig; -} - -int flexran_get_srs_MaxUpPts(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->soundingrs_ul_config_common.srs_MaxUpPts; -} - -int flexran_get_N_RB_DL(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->N_RB_DL; -} - -int flexran_get_N_RB_UL(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->N_RB_UL; -} - -int flexran_get_N_RBG(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->N_RBG; -} - -int flexran_get_subframe_assignment(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->tdd_config; -} - -int flexran_get_special_subframe_assignment(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->tdd_config_S; -} - -int flexran_get_ra_ResponseWindowSize(mid_t mod_id, int CC_id) { - return enb_config_get()->properties[mod_id]->rach_raResponseWindowSize[CC_id]; -} - -int flexran_get_mac_ContentionResolutionTimer(mid_t mod_id, int CC_id) { - return enb_config_get()->properties[mod_id]->rach_macContentionResolutionTimer[CC_id]; -} - -int flexran_get_duplex_mode(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - if(frame_parms->frame_type == TDD) - return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD; - else if (frame_parms->frame_type == FDD) - return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_FDD; - - return -1; -} - -long flexran_get_si_window_length(mid_t mod_id, int CC_id) { - return ((eNB_RRC_INST *)enb_rrc[mod_id])->carrier[CC_id].sib1->si_WindowLength; -} - -int flexran_get_sib1_length(mid_t mod_id, int CC_id) { - return ((eNB_RRC_INST *)enb_rrc[mod_id])->carrier[CC_id].sizeof_SIB1; -} - -int flexran_get_num_pdcch_symb(mid_t mod_id, int CC_id) { - /* TODO: This should return the number of PDCCH symbols initially used by the cell CC_id */ - return 0; - //(PHY_vars_UE_g[mod_id][CC_id]->lte_ue_pdcch_vars[mod_id]->num_pdcch_symbols); -} - - - -/* - * ************************************ - * Get Messages for UE Configuration Reply - * ************************************ - */ - - -int flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.mac_MainConfig != NULL) { - return ue_context_p->ue_context.mac_MainConfig->timeAlignmentTimerDedicated; - } else { - return -1; - } - } else { - return -1; - } -} - -int flexran_get_meas_gap_config(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.measGapConfig != NULL) { - if(ue_context_p->ue_context.measGapConfig->present == MeasGapConfig_PR_setup) { - if (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present == MeasGapConfig__setup__gapOffset_PR_gp0) { - return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_GP1; - } else if (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present == MeasGapConfig__setup__gapOffset_PR_gp1) { - return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_GP2; - } else { - return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF; - } - } - } - } - return -1; -} - - -int flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.measGapConfig != NULL){ - if(ue_context_p->ue_context.measGapConfig->present == MeasGapConfig_PR_setup) { - if (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present == MeasGapConfig__setup__gapOffset_PR_gp0) { - return ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.choice.gp0; - } else if (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present == MeasGapConfig__setup__gapOffset_PR_gp1) { - return ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.choice.gp0; - } - } - } - } - return -1; -} - -int flexran_get_ue_aggregated_max_bitrate_dl (mid_t mod_id, mid_t ue_id) { - return ((UE_list_t *)enb_ue[mod_id])->UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateDL; -} - -int flexran_get_ue_aggregated_max_bitrate_ul (mid_t mod_id, mid_t ue_id) { - return ((UE_list_t *)enb_ue[mod_id])->UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateUL; -} - -int flexran_get_half_duplex(mid_t ue_id) { - // TODO - //int halfduplex = 0; - //int bands_to_scan = ((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count; - //for (int i =0; i < bands_to_scan; i++){ - //if(((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->halfDuplex > 0) - // halfduplex = 1; - //} - //return halfduplex; - return 0; -} - -int flexran_get_intra_sf_hopping(mid_t ue_id) { - //TODO:Get proper value - //temp = (((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->featureGroupIndicators->buf); - //return (0 & ( 1 << (31))); - return 0; -} - -int flexran_get_type2_sb_1(mid_t ue_id) { - //TODO:Get proper value - //uint8_t temp = 0; - //temp = (((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->featureGroupIndicators->buf); - //return (temp & ( 1 << (11))); - return 0; -} - -int flexran_get_ue_category(mid_t ue_id) { - //TODO:Get proper value - //return (((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->ue_Category); - return 0; -} - -int flexran_get_res_alloc_type1(mid_t ue_id) { - //TODO:Get proper value - //uint8_t temp = 0; - //temp = (((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->featureGroupIndicators->buf); - //return (temp & ( 1 << (30))); - return 0; -} - -int flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ - return ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode; - } else { - return -1; - } - } else { - return -1; - } -} - -int flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.mac_MainConfig != NULL){ - return ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config->ttiBundling; - } else { - return -1; - } - } - else { - return -1; - } -} - -int flexran_get_maxHARQ_TX(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.mac_MainConfig != NULL){ - return *ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config->maxHARQ_Tx; - } - } - return -1; -} - -int flexran_get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ - return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_ACK_Index; - } else { - return -1; - } - } else { - return -1; - } -} - -int flexran_get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ - return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index; - } else { - return -1; - } - } else { - return -1; - } -} - -int flexran_get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ - return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index; - } else { - return -1; - } - } - else { - return -1; - } -} - -int flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ - if (ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic != NULL) { - return ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.simultaneousAckNackAndCQI; - } - } - } - return -1; -} - -int flexran_get_ack_nack_simultaneous_trans(mid_t mod_id,mid_t ue_id) { - return (&eNB_rrc_inst[mod_id])->carrier[0].sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; -} - -int flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ - return *ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic; - } - } - return -1; -} - -int flexran_get_tdd_ack_nack_feedback(mid_t mod_id, mid_t ue_id) { - // TODO: This needs fixing - return -1; - - /* struct rrc_eNB_ue_context_s* ue_context_p = NULL; */ - /* uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); */ - - /* ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); */ - - /* if(ue_context_p != NULL) { */ - /* if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ */ - /* return ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode; */ - /* } else { */ - /* return -1; */ - /* } */ - /* } else { */ - /* return -1; */ - /* } */ -} - -int flexran_get_ack_nack_repetition_factor(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ - return ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->ackNackRepetition.choice.setup.repetitionFactor; - } else { - return -1; - } - } else { - return -1; - } -} - -int flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id) { - //TODO: need to double check - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.mac_MainConfig != NULL){ - if(ue_context_p->ue_context.mac_MainConfig->ext2 != NULL){ - long val = (*(ue_context_p->ue_context.mac_MainConfig->ext2->mac_MainConfig_v1020->extendedBSR_Sizes_r10)); - if (val > 0) { - return 1; - } - } - } - } - return -1; -} - -int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ - if(ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.choice.setup == AntennaInfoDedicated__ue_TransmitAntennaSelection__setup_closedLoop) { - return 2; - } else if(ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.choice.setup == AntennaInfoDedicated__ue_TransmitAntennaSelection__setup_openLoop) { - return 1; - } else { - return 0; - } - } else { - return -1; - } - } else { - return -1; - } -} - -int flexran_get_lcg(mid_t ue_id, mid_t lc_id) { - if (UE_mac_inst == NULL) { - return -1; - } - if(UE_mac_inst[ue_id].logicalChannelConfig[lc_id] != NULL) { - return *UE_mac_inst[ue_id].logicalChannelConfig[lc_id]->ul_SpecificParameters->logicalChannelGroup; - } else { - return -1; - } -} - -int flexran_get_direction(mid_t ue_id, mid_t lc_id) { - /*TODO: fill with the value for the rest of LCID*/ - if(lc_id == DCCH || lc_id == DCCH1) { - return 2; - } else if(lc_id == DTCH) { - return 1; - } else { - return -1; - } -} - -int flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_change) { - int size; - Protocol__FlexranMessage *msg; - Protocol__FlexHeader *header; - void *data; - int priority = 0; - - int xid = 0; - - if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_UE_STATE_CHANGE, &header) != 0) - goto error; - - Protocol__FlexUeStateChange *ue_state_change_msg; - ue_state_change_msg = malloc(sizeof(Protocol__FlexUeStateChange)); - if(ue_state_change_msg == NULL) { - goto error; - } - protocol__flex_ue_state_change__init(ue_state_change_msg); - ue_state_change_msg->has_type = 1; - ue_state_change_msg->type = state_change; - - Protocol__FlexUeConfig *config; - config = malloc(sizeof(Protocol__FlexUeConfig)); - if (config == NULL) { - goto error; - } - protocol__flex_ue_config__init(config); - if (state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED) { - // Simply set the rnti of the UE - config->has_rnti = 1; - config->rnti = rnti; - } else if (state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_UPDATED - || state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED) { - int i = find_UE_id(mod_id, rnti); - config->has_rnti = 1; - config->rnti = rnti; - if(flexran_get_time_alignment_timer(mod_id,i) != -1) { - config->time_alignment_timer = flexran_get_time_alignment_timer(mod_id,i); - config->has_time_alignment_timer = 1; - } - if(flexran_get_meas_gap_config(mod_id,i) != -1){ - config->meas_gap_config_pattern = flexran_get_meas_gap_config(mod_id,i); - config->has_meas_gap_config_pattern = 1; - } - if(config->has_meas_gap_config_pattern == 1 && - config->meas_gap_config_pattern != PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF) { - config->meas_gap_config_sf_offset = flexran_get_meas_gap_config_offset(mod_id,i); - config->has_meas_gap_config_sf_offset = 1; - } - //TODO: Set the SPS configuration (Optional) - //Not supported for now, so we do not set it - - //TODO: Set the SR configuration (Optional) - //We do not set it for now - - //TODO: Set the CQI configuration (Optional) - //We do not set it for now - - if(flexran_get_ue_transmission_mode(mod_id,i) != -1) { - config->transmission_mode = flexran_get_ue_transmission_mode(mod_id,i); - config->has_transmission_mode = 1; - } - - config->ue_aggregated_max_bitrate_ul = flexran_get_ue_aggregated_max_bitrate_ul(mod_id,i); - config->has_ue_aggregated_max_bitrate_ul = 1; - - config->ue_aggregated_max_bitrate_dl = flexran_get_ue_aggregated_max_bitrate_dl(mod_id,i); - config->has_ue_aggregated_max_bitrate_dl = 1; - - //TODO: Set the UE capabilities - Protocol__FlexUeCapabilities *c_capabilities; - c_capabilities = malloc(sizeof(Protocol__FlexUeCapabilities)); - protocol__flex_ue_capabilities__init(c_capabilities); - //TODO: Set half duplex (FDD operation) - c_capabilities->has_half_duplex = 0; - c_capabilities->half_duplex = 1;//flexran_get_half_duplex(i); - //TODO: Set intra-frame hopping flag - c_capabilities->has_intra_sf_hopping = 0; - c_capabilities->intra_sf_hopping = 1;//flexran_get_intra_sf_hopping(i); - //TODO: Set support for type 2 hopping with n_sb > 1 - c_capabilities->has_type2_sb_1 = 0; - c_capabilities->type2_sb_1 = 1;//flexran_get_type2_sb_1(i); - //TODO: Set ue category - c_capabilities->has_ue_category = 0; - c_capabilities->ue_category = 1;//flexran_get_ue_category(i); - //TODO: Set UE support for resource allocation type 1 - c_capabilities->has_res_alloc_type1 = 0; - c_capabilities->res_alloc_type1 = 1;//flexran_get_res_alloc_type1(i); - //Set the capabilites to the message - config->capabilities = c_capabilities; - - if(flexran_get_ue_transmission_antenna(mod_id,i) != -1) { - config->has_ue_transmission_antenna = 1; - config->ue_transmission_antenna = flexran_get_ue_transmission_antenna(mod_id,i); - } - - if(flexran_get_tti_bundling(mod_id,i) != -1) { - config->has_tti_bundling = 1; - config->tti_bundling = flexran_get_tti_bundling(mod_id,i); - } - - if(flexran_get_maxHARQ_TX(mod_id,i) != -1){ - config->has_max_harq_tx = 1; - config->max_harq_tx = flexran_get_maxHARQ_TX(mod_id,i); - } - - if(flexran_get_beta_offset_ack_index(mod_id,i) != -1) { - config->has_beta_offset_ack_index = 1; - config->beta_offset_ack_index = flexran_get_beta_offset_ack_index(mod_id,i); - } - - if(flexran_get_beta_offset_ri_index(mod_id,i) != -1) { - config->has_beta_offset_ri_index = 1; - config->beta_offset_ri_index = flexran_get_beta_offset_ri_index(mod_id,i); - } - - if(flexran_get_beta_offset_cqi_index(mod_id,i) != -1) { - config->has_beta_offset_cqi_index = 1; - config->beta_offset_cqi_index = flexran_get_beta_offset_cqi_index(mod_id,i); - } - - if(flexran_get_ack_nack_simultaneous_trans(mod_id,i) != -1) { - config->has_ack_nack_simultaneous_trans = 1; - config->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id,i); - } - - if(flexran_get_simultaneous_ack_nack_cqi(mod_id,i) != -1) { - config->has_simultaneous_ack_nack_cqi = 1; - config->simultaneous_ack_nack_cqi = flexran_get_simultaneous_ack_nack_cqi(mod_id,i); - } - - if(flexran_get_aperiodic_cqi_rep_mode(mod_id,i) != -1) { - config->has_aperiodic_cqi_rep_mode = 1; - int mode = flexran_get_aperiodic_cqi_rep_mode(mod_id,i); - if (mode > 4) { - config->aperiodic_cqi_rep_mode = PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_NONE; - } else { - config->aperiodic_cqi_rep_mode = mode; - } - } - - if(flexran_get_tdd_ack_nack_feedback(mod_id, i) != -1) { - config->has_tdd_ack_nack_feedback = 1; - config->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback(mod_id,i); - } - - if(flexran_get_ack_nack_repetition_factor(mod_id, i) != -1) { - config->has_ack_nack_repetition_factor = 1; - config->ack_nack_repetition_factor = flexran_get_ack_nack_repetition_factor(mod_id,i); - } - - if(flexran_get_extended_bsr_size(mod_id, i) != -1) { - config->has_extended_bsr_size = 1; - config->extended_bsr_size = flexran_get_extended_bsr_size(mod_id,i); - } - - config->has_pcell_carrier_index = 1; - config->pcell_carrier_index = UE_PCCID(mod_id, i); - //TODO: Set carrier aggregation support (boolean) - config->has_ca_support = 0; - config->ca_support = 0; - if(config->has_ca_support){ - //TODO: Set cross carrier scheduling support (boolean) - config->has_cross_carrier_sched_support = 1; - config->cross_carrier_sched_support = 0; - //TODO: Set secondary cells configuration - // We do not set it for now. No carrier aggregation support - - //TODO: Set deactivation timer for secondary cell - config->has_scell_deactivation_timer = 0; - config->scell_deactivation_timer = 0; - } - } else if (state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_MOVED) { - // TODO: Not supported for now. Leave blank - } - - ue_state_change_msg->config = config; - msg = malloc(sizeof(Protocol__FlexranMessage)); - if (msg == NULL) { - goto error; - } - protocol__flexran_message__init(msg); - msg->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_STATE_CHANGE_MSG; - msg->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE; - msg->ue_state_change_msg = ue_state_change_msg; - - data = flexran_agent_pack_message(msg, &size); - /*Send sr info using the MAC channel of the eNB*/ - if (flexran_agent_msg_send(mod_id, FLEXRAN_AGENT_DEFAULT, data, size, priority)) { - goto error; - } - - LOG_D(FLEXRAN_AGENT,"sent message with size %d\n", size); - return 0; - error: - LOG_D(FLEXRAN_AGENT, "Could not send UE state message\n"); - return -1; -} - - int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { @@ -2138,191 +1045,38 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F } +int flexran_agent_rrc_measurement(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { -/* - * timer primitives - */ + protocol_ctxt_t ctxt; -//struct flexran_agent_map agent_map; -flexran_agent_timer_instance_t timer_instance; -int agent_timer_init = 0; -err_code_t flexran_agent_init_timer(void){ + Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; + Protocol__FlexRrcTriggering *triggering = input->rrc_triggering; + + agent_reconf_rrc *reconf_param = malloc(sizeof(agent_reconf_rrc)); - LOG_I(FLEXRAN_AGENT, "init RB tree\n"); - if (!agent_timer_init) { - RB_INIT(&timer_instance.flexran_agent_head); - agent_timer_init = 1; + + reconf_param->trigger_policy = triggering->rrc_trigger; + + struct rrc_eNB_ue_context_s *ue_context_p = NULL; + + RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(eNB_rrc_inst[mod_id].rrc_ue_head)){ + + + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, mod_id, ENB_FLAG_YES, ue_context_p->ue_context.rnti, flexran_get_current_frame(mod_id), flexran_get_current_subframe (mod_id), mod_id); + + flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt, ue_context_p, 0, reconf_param); + } - - return PROTOCOL__FLEXRAN_ERR__NO_ERR; -} - -RB_GENERATE(flexran_agent_map, flexran_agent_timer_element_s, entry, flexran_agent_compare_timer); - -/* The timer_id might not be the best choice for the comparison */ -int flexran_agent_compare_timer(struct flexran_agent_timer_element_s *a, struct flexran_agent_timer_element_s *b){ - - if (a->timer_id < b->timer_id) return -1; - if (a->timer_id > b->timer_id) return 1; - - // equal timers + + + *msg = NULL; return 0; } -err_code_t flexran_agent_create_timer(uint32_t interval_sec, - uint32_t interval_usec, - agent_id_t agent_id, - instance_t instance, - uint32_t timer_type, - xid_t xid, - flexran_agent_timer_callback_t cb, - void* timer_args, - long *timer_id){ - - struct flexran_agent_timer_element_s *e = calloc(1, sizeof(*e)); - DevAssert(e != NULL); - -//uint32_t timer_id; - int ret=-1; - - if ((interval_sec == 0) && (interval_usec == 0 )) - return TIMER_NULL; - - if (timer_type >= FLEXRAN_AGENT_TIMER_TYPE_MAX) - return TIMER_TYPE_INVALIDE; - - if (timer_type == FLEXRAN_AGENT_TIMER_TYPE_ONESHOT){ - ret = timer_setup(interval_sec, - interval_usec, - TASK_FLEXRAN_AGENT, - instance, - TIMER_ONE_SHOT, - timer_args, - timer_id); + +int flexran_agent_destroy_rrc_measurement(Protocol__FlexranMessage *msg){ - e->type = TIMER_ONE_SHOT; - } - else if (timer_type == FLEXRAN_AGENT_TIMER_TYPE_PERIODIC ){ - ret = timer_setup(interval_sec, - interval_usec, - TASK_FLEXRAN_AGENT, - instance, - TIMER_PERIODIC, - timer_args, - timer_id); - - e->type = TIMER_PERIODIC; - } - - if (ret < 0 ) { - return TIMER_SETUP_FAILED; - } - - e->agent_id = agent_id; - e->instance = instance; - e->state = FLEXRAN_AGENT_TIMER_STATE_ACTIVE; - e->timer_id = *timer_id; - e->xid = xid; - e->timer_args = timer_args; - e->cb = cb; - /*element should be a real pointer*/ - RB_INSERT(flexran_agent_map, &timer_instance.flexran_agent_head, e); - - LOG_I(FLEXRAN_AGENT,"Created a new timer with id 0x%lx for agent %d, instance %d \n", - e->timer_id, e->agent_id, e->instance); - - return 0; -} - -err_code_t flexran_agent_destroy_timer(long timer_id){ - - struct flexran_agent_timer_element_s *e = get_timer_entry(timer_id); - - if (e != NULL ) { - RB_REMOVE(flexran_agent_map, &timer_instance.flexran_agent_head, e); - flexran_agent_destroy_flexran_message(e->timer_args->msg); - free(e); - } - - if (timer_remove(timer_id) < 0 ) - goto error; - - return 0; - - error: - LOG_E(FLEXRAN_AGENT, "timer can't be removed\n"); - return TIMER_REMOVED_FAILED ; -} - -err_code_t flexran_agent_destroy_timer_by_task_id(xid_t xid) { - struct flexran_agent_timer_element_s *e = NULL; - long timer_id; - RB_FOREACH(e, flexran_agent_map, &timer_instance.flexran_agent_head) { - if (e->xid == xid) { - timer_id = e->timer_id; - RB_REMOVE(flexran_agent_map, &timer_instance.flexran_agent_head, e); - flexran_agent_destroy_flexran_message(e->timer_args->msg); - free(e); - if (timer_remove(timer_id) < 0 ) { - goto error; - } - } - } - return 0; - - error: - LOG_E(FLEXRAN_AGENT, "timer can't be removed\n"); - return TIMER_REMOVED_FAILED ; -} - -err_code_t flexran_agent_destroy_timers(void){ - - struct flexran_agent_timer_element_s *e = NULL; - - RB_FOREACH(e, flexran_agent_map, &timer_instance.flexran_agent_head) { - RB_REMOVE(flexran_agent_map, &timer_instance.flexran_agent_head, e); - timer_remove(e->timer_id); - flexran_agent_destroy_flexran_message(e->timer_args->msg); - free(e); - } - - return 0; - -} - -void flexran_agent_sleep_until(struct timespec *ts, int delay) { - ts->tv_nsec += delay; - if(ts->tv_nsec >= 1000*1000*1000){ - ts->tv_nsec -= 1000*1000*1000; - ts->tv_sec++; - } - clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, ts, NULL); } -err_code_t flexran_agent_stop_timer(long timer_id){ - - struct flexran_agent_timer_element_s *e=NULL; - struct flexran_agent_timer_element_s search; - memset(&search, 0, sizeof(struct flexran_agent_timer_element_s)); - search.timer_id = timer_id; - e = RB_FIND(flexran_agent_map, &timer_instance.flexran_agent_head, &search); - - if (e != NULL ) { - e->state = FLEXRAN_AGENT_TIMER_STATE_STOPPED; - } - - timer_remove(timer_id); - - return 0; -} - -struct flexran_agent_timer_element_s * get_timer_entry(long timer_id) { - - struct flexran_agent_timer_element_s search; - memset(&search, 0, sizeof(struct flexran_agent_timer_element_s)); - search.timer_id = timer_id; - - return RB_FIND(flexran_agent_map, &timer_instance.flexran_agent_head, &search); -} diff --git a/openair2/ENB_APP/flexran_agent_common.h b/openair2/ENB_APP/flexran_agent_common.h index abe5a05b44..4f2b9c71bb 100644 --- a/openair2/ENB_APP/flexran_agent_common.h +++ b/openair2/ENB_APP/flexran_agent_common.h @@ -21,8 +21,8 @@ /*! \file flexran_agent_common.h * \brief common message primitves and utilities - * \author Xenofon Foukas, Mohamed Kassem and Navid Nikaein - * \date 2016 + * \author Xenofon Foukas, Mohamed Kassem and Navid Nikaein and shahab SHARIAT BAGHERI + * \date 2017 * \version 0.1 */ @@ -60,6 +60,19 @@ typedef int (*flexran_agent_message_destruction_callback)( Protocol__FlexranMessage *msg ); +typedef struct { + + uint8_t is_initialized; + volatile uint8_t cont_update; + xid_t xid; + Protocol__FlexranMessage *stats_req; + Protocol__FlexranMessage *prev_stats_reply; + + pthread_mutex_t *mutex; +} stats_updates_context_t; + +stats_updates_context_t stats_context[NUM_MAX_ENB]; + /********************************** * FlexRAN protocol messages helper * functions and generic handlers @@ -116,10 +129,6 @@ int flexran_agent_destroy_ue_config_request(Protocol__FlexranMessage *msg); /* TODO: Need to define and implement destructor */ int flexran_agent_destroy_lc_config_request(Protocol__FlexranMessage *msg); -/* UE state change message constructor and destructor */ -int flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_change); -int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg); - /* Control delegation message constructor and destructor */ int flexran_agent_control_delegation(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg); int flexran_agent_destroy_control_delegation(Protocol__FlexranMessage *msg); @@ -128,6 +137,11 @@ int flexran_agent_destroy_control_delegation(Protocol__FlexranMessage *msg); int flexran_agent_reconfiguration(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg); int flexran_agent_destroy_agent_reconfiguration(Protocol__FlexranMessage *msg); +/* rrc triggering measurement message constructor and destructor */ +int flexran_agent_rrc_measurement(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg); +int flexran_agent_destroy_rrc_measurement(Protocol__FlexranMessage *msg); + + /* FlexRAN protocol message dispatcher function */ Protocol__FlexranMessage* flexran_agent_handle_message (mid_t mod_id, uint8_t *data, @@ -136,367 +150,22 @@ Protocol__FlexranMessage* flexran_agent_handle_message (mid_t mod_id, /* Function to be used to send a message to a dispatcher once the appropriate event is triggered. */ Protocol__FlexranMessage *flexran_agent_handle_timed_task(void *args); +/*Top level Statistics hanlder*/ +int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg); +/* Function to be used to handle reply message . */ +int flexran_agent_stats_reply(mid_t enb_id, xid_t xid, const report_config_t *report_config, Protocol__FlexranMessage **msg); +/* Statistics request protocol message constructor and destructor */ +int flexran_agent_stats_request(mid_t mod_id, xid_t xid, const stats_request_config_t *report_config, Protocol__FlexranMessage **msg); +int flexran_agent_destroy_stats_request(Protocol__FlexranMessage *msg); -/**************************** - * get generic info from RAN - ****************************/ +int flexran_agent_stats_request(mid_t mod_id, xid_t xid, const stats_request_config_t *report_config, Protocol__FlexranMessage **msg); +int flexran_agent_destroy_stats_request(Protocol__FlexranMessage *msg); + +err_code_t flexran_agent_enable_cont_stats_update(mid_t mod_id, xid_t xid, stats_request_config_t *stats_req) ; -void flexran_set_enb_vars(mid_t mod_id, ran_name_t ran); - -int flexran_get_current_time_ms (mid_t mod_id, int subframe_flag); - -/*Return the current frame number - *Could be using implementation specific numbering of frames - */ -unsigned int flexran_get_current_frame(mid_t mod_id); - -/*Return the current SFN (0-1023)*/ -unsigned int flexran_get_current_system_frame_num(mid_t mod_id); - -unsigned int flexran_get_current_subframe(mid_t mod_id); - -/*Return the frame and subframe number in compact 16-bit format. - Bits 0-3 subframe, rest for frame. Required by FlexRAN protocol*/ -uint16_t flexran_get_sfn_sf (mid_t mod_id); - -/* Return a future frame and subframe number that is ahead_of_time - subframes later in compact 16-bit format. Bits 0-3 subframe, - rest for frame */ -uint16_t flexran_get_future_sfn_sf(mid_t mod_id, int ahead_of_time); - -/* Return the number of attached UEs */ -int flexran_get_num_ues(mid_t mod_id); - -/* Get the rnti of a UE with id ue_id */ -int flexran_get_ue_crnti (mid_t mod_id, mid_t ue_id); - -/* Get the RLC buffer status report of a ue for a designated - logical channel id */ -int flexran_get_ue_bsr (mid_t mod_id, mid_t ue_id, lcid_t lcid); - -/* Get power headroom of UE with id ue_id */ -int flexran_get_ue_phr (mid_t mod_id, mid_t ue_id); - -/* Get the UE wideband CQI */ -int flexran_get_ue_wcqi (mid_t mod_id, mid_t ue_id); - -/* Get the transmission queue size for a UE with a channel_id logical channel id */ -int flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id); - -/* Get the head of line delay for a UE with a channel_id logical channel id */ -int flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id); - -/* Check the status of the timing advance for a UE */ -short flexran_get_TA(mid_t mod_id, mid_t ue_id, int CC_id); - -/* Update the timing advance status (find out whether a timing advance command is required) */ -void flexran_update_TA(mid_t mod_id, mid_t ue_id, int CC_id); - -/* Return timing advance MAC control element for a designated cell and UE */ -int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id, int CC_id); - -/* Get the number of active component carriers for a specific UE */ -int flexran_get_active_CC(mid_t mod_id, mid_t ue_id); - -/* Get the rank indicator for a designated cell and UE */ -int flexran_get_current_RI(mid_t mod_id, mid_t ue_id, int CC_id); - -/* See TS 36.213, section 10.1 */ -int flexran_get_n1pucch_an(mid_t mod_id, int CC_id); - -/* See TS 36.211, section 5.4 */ -int flexran_get_nRB_CQI(mid_t mod_id, int CC_id); - -/* See TS 36.211, section 5.4 */ -int flexran_get_deltaPUCCH_Shift(mid_t mod_id, int CC_id); - -/* See TS 36.211, section 5.7.1 */ -int flexran_get_prach_ConfigIndex(mid_t mod_id, int CC_id); - -/* See TS 36.211, section 5.7.1 */ -int flexran_get_prach_FreqOffset(mid_t mod_id, int CC_id); - -/* See TS 36.321 */ -int flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, int CC_id); - -/* Get the length of the UL cyclic prefix */ -int flexran_get_ul_cyclic_prefix_length(mid_t mod_id, int CC_id); - -/* Get the length of the DL cyclic prefix */ -int flexran_get_dl_cyclic_prefix_length(mid_t mod_id, int CC_id); - -/* Get the physical cell id of a cell */ -int flexran_get_cell_id(mid_t mod_id, int CC_id); - -/* See TS 36.211, section 5.5.3.2 */ -int flexran_get_srs_BandwidthConfig(mid_t mod_id, int CC_id); - -/* See TS 36.211, table 5.5.3.3-1 and 2 */ -int flexran_get_srs_SubframeConfig(mid_t mod_id, int CC_id); - -/* Boolean value. See TS 36.211, - section 5.5.3.2. TDD only */ -int flexran_get_srs_MaxUpPts(mid_t mod_id, int CC_id); - -/* Get number of DL resource blocks */ -int flexran_get_N_RB_DL(mid_t mod_id, int CC_id); - -/* Get number of UL resource blocks */ -int flexran_get_N_RB_UL(mid_t mod_id, int CC_id); - -/* Get number of resource block groups */ -int flexran_get_N_RBG(mid_t mod_id, int CC_id); - -/* Get DL/UL subframe assignment. TDD only */ -int flexran_get_subframe_assignment(mid_t mod_id, int CC_id); - -/* TDD only. See TS 36.211, table 4.2.1 */ -int flexran_get_special_subframe_assignment(mid_t mod_id, int CC_id); - -/* Get the duration of the random access response window in subframes */ -int flexran_get_ra_ResponseWindowSize(mid_t mod_id, int CC_id); - -/* Get timer used for random access */ -int flexran_get_mac_ContentionResolutionTimer(mid_t mod_id, int CC_id); - -/* Get type of duplex mode (FDD/TDD) */ -int flexran_get_duplex_mode(mid_t mod_id, int CC_id); - -/* Get the SI window length */ -long flexran_get_si_window_length(mid_t mod_id, int CC_id); - -/* Get the number of PDCCH symbols configured for the cell */ -int flexran_get_num_pdcch_symb(mid_t mod_id, int CC_id); - -/* See TS 36.213, sec 5.1.1.1 */ -int flexran_get_tpc(mid_t mod_id, mid_t ue_id); - -/* Get the first available HARQ process for a specific cell and UE during - a designated frame and subframe. Returns 0 for success. The id and the - status of the HARQ process are stored in id and status respectively */ -int flexran_get_harq(const mid_t mod_id, const uint8_t CC_id, const mid_t ue_id, - const int frame, const uint8_t subframe, unsigned char *id, unsigned char *round); - -/* Uplink power control management*/ -int flexran_get_p0_pucch_dbm(mid_t mod_id, mid_t ue_id, int CC_id); - -int flexran_get_p0_nominal_pucch(mid_t mod_id, int CC_id); - -int flexran_get_p0_pucch_status(mid_t mod_id, mid_t ue_id, int CC_id); - -int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, int CC_id); - - -/* - * ************************************ - * Get Messages for UE Configuration Reply - * ************************************ - */ - -/* Get timer in subframes. Controls the synchronization - status of the UE, not the actual timing - advance procedure. See TS 36.321 */ -int flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id); - -/* Get measurement gap configuration. See TS 36.133 */ -int flexran_get_meas_gap_config(mid_t mod_id, mid_t ue_id); - -/* Get measurement gap configuration offset if applicable */ -int flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id); - -/* DL aggregated bit-rate of non-gbr bearer - per UE. See TS 36.413 */ -int flexran_get_ue_aggregated_max_bitrate_dl (mid_t mod_id, mid_t ue_id); - -/* UL aggregated bit-rate of non-gbr bearer - per UE. See TS 36.413 */ -int flexran_get_ue_aggregated_max_bitrate_ul (mid_t mod_id, mid_t ue_id); - -/* Only half-duplex support. FDD - operation. Boolean value */ -int flexran_get_half_duplex(mid_t ue_id); - -/* Support of intra-subframe hopping. - Boolean value */ -int flexran_get_intra_sf_hopping(mid_t ue_id); - -/* UE support for type 2 hopping with - n_sb>1 */ -int flexran_get_type2_sb_1(mid_t ue_id); - -/* Get the UE category */ -int flexran_get_ue_category(mid_t ue_id); - -/* UE support for resource allocation - type 1 */ -int flexran_get_res_alloc_type1(mid_t ue_id); - -/* Get UE transmission mode */ -int flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id); - -/* Boolean value. See TS 36.321 */ -int flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id); - -/* The max HARQ retransmission for UL. - See TS 36.321 */ -int flexran_get_maxHARQ_TX(mid_t mod_id, mid_t ue_id); - -/* See TS 36.213 */ -int flexran_get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id); - -/* See TS 36.213 */ -int flexran_get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id); - -/* See TS 36.213 */ -int flexran_get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id); - -/* Boolean. See TS36.213, Section 10.1 */ -int flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id); - -/* Boolean. See TS 36.213, Section 8.2 */ -int flexran_get_ack_nack_simultaneous_trans(mid_t mod_id,mid_t ue_id); - -/* Get aperiodic CQI report mode */ -int flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id); - -/* Get ACK/NACK feedback mode. TDD only */ -int flexran_get_tdd_ack_nack_feedback(mid_t mod_id, mid_t ue_id); - -/* See TS36.213, section 10.1 */ -int flexran_get_ack_nack_repetition_factor(mid_t mod_id, mid_t ue_id); - -/* Boolean. Extended buffer status report size */ -int flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id); - -/* Get number of UE transmission antennas */ -int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id); - -/* Get logical channel group of a channel with id lc_id */ -int flexran_get_lcg(mid_t ue_id, mid_t lc_id); - -/* Get direction of logical channel with id lc_id */ -int flexran_get_direction(mid_t ue_id, mid_t lc_id); - -/******************* - * timer primitves - *******************/ - -#define TIMER_NULL -1 -#define TIMER_TYPE_INVALIDE -2 -#define TIMER_SETUP_FAILED -3 -#define TIMER_REMOVED_FAILED -4 -#define TIMER_ELEMENT_NOT_FOUND -5 - - -/* Type of the callback executed when the timer expired */ -typedef Protocol__FlexranMessage *(*flexran_agent_timer_callback_t)(void*); - -typedef enum { - /* oneshot timer: */ - FLEXRAN_AGENT_TIMER_TYPE_ONESHOT = 0x0, - - /* periodic timer */ - FLEXRAN_AGENT_TIMER_TYPE_PERIODIC = 0x1, - - /* Inactive state: initial state for any timer. */ - FLEXRAN_AGENT_TIMER_TYPE_EVENT_DRIVEN = 0x2, - - /* Max number of states available */ - FLEXRAN_AGENT_TIMER_TYPE_MAX, -} flexran_agent_timer_type_t; - -typedef enum { - /* Inactive state: initial state for any timer. */ - FLEXRAN_AGENT_TIMER_STATE_INACTIVE = 0x0, - - /* Inactive state: initial state for any timer. */ - FLEXRAN_AGENT_TIMER_STATE_ACTIVE = 0x1, - - /* Inactive state: initial state for any timer. */ - FLEXRAN_AGENT_TIMER_STATE_STOPPED = 0x2, - - /* Max number of states available */ - FLEXRAN_AGENT_TIMER_STATE_MAX, -} flexran_agent_timer_state_t; - -typedef struct flexran_agent_timer_args_s{ - mid_t mod_id; - Protocol__FlexranMessage *msg; -} flexran_agent_timer_args_t; - - - -typedef struct flexran_agent_timer_element_s{ - RB_ENTRY(flexran_agent_timer_element_s) entry; - - agent_id_t agent_id; - instance_t instance; - - flexran_agent_timer_type_t type; - flexran_agent_timer_state_t state; - - uint32_t interval_sec; - uint32_t interval_usec; - - long timer_id; /* Timer id returned by the timer API*/ - xid_t xid; /*The id of the task as received by the controller - message*/ - - flexran_agent_timer_callback_t cb; - flexran_agent_timer_args_t *timer_args; - -} flexran_agent_timer_element_t; - -typedef struct flexran_agent_timer_instance_s{ - RB_HEAD(flexran_agent_map, flexran_agent_timer_element_s) flexran_agent_head; -}flexran_agent_timer_instance_t; - - -err_code_t flexran_agent_init_timer(void); - -/* Create a timer for some agent related event with id xid. Will store the id - of the generated timer in timer_id */ -err_code_t flexran_agent_create_timer(uint32_t interval_sec, - uint32_t interval_usec, - agent_id_t agent_id, - instance_t instance, - uint32_t timer_type, - xid_t xid, - flexran_agent_timer_callback_t cb, - void* timer_args, - long *timer_id); - -/* Destroy all existing timers */ -err_code_t flexran_agent_destroy_timers(void); - -/* Destroy the timer with the given timer_id */ -err_code_t flexran_agent_destroy_timer(long timer_id); - -/* Destroy the timer for task with id xid */ -err_code_t flexran_agent_destroy_timer_by_task_id(xid_t xid); - -/* Stop a timer */ -err_code_t flexran_agent_stop_timer(long timer_id); - -/* Restart the given timer */ -err_code_t flexran_agent_restart_timer(long *timer_id); - -/* Find the timer with the given timer_id */ -struct flexran_agent_timer_element_s * get_timer_entry(long timer_id); - -/* Obtain the protocol message stored in the given expired timer */ -Protocol__FlexranMessage * flexran_agent_process_timeout(long timer_id, void* timer_args); - -/* Comparator function comparing two timers. Decides the ordering of the timers */ -int flexran_agent_compare_timer(struct flexran_agent_timer_element_s *a, struct flexran_agent_timer_element_s *b); - -/*Specify a delay in nanoseconds to timespec and sleep until then*/ -void flexran_agent_sleep_until(struct timespec *ts, int delay); - -/* RB_PROTOTYPE is for .h files */ -RB_PROTOTYPE(flexran_agent_map, flexran_agent_timer_element_s, entry, flexran_agent_compare_timer); +int flexran_agent_stats_request(mid_t mod_id, xid_t xid, const stats_request_config_t *report_config, Protocol__FlexranMessage **msg); #endif diff --git a/openair2/ENB_APP/flexran_agent_defs.h b/openair2/ENB_APP/flexran_agent_defs.h index d60510b0c7..0b8822a949 100644 --- a/openair2/ENB_APP/flexran_agent_defs.h +++ b/openair2/ENB_APP/flexran_agent_defs.h @@ -21,8 +21,8 @@ /*! \file flexran_agent_defs.h * \brief FlexRAN agent common definitions - * \author Navid Nikaein and Xenofon Foukas - * \date 2016 + * \author Navid Nikaein and Xenofon Foukas and shahab SHARIAT BAGHERI + * \date 2017 * \version 0.1 */ #ifndef FLEXRAN_AGENT_DEFS_H_ @@ -102,6 +102,38 @@ typedef uint8_t lcid_t; typedef int32_t err_code_t; +/*---------Timer Enums --------- */ + +typedef enum { + /* oneshot timer: */ + FLEXRAN_AGENT_TIMER_TYPE_ONESHOT = 0, + + /* periodic timer */ + FLEXRAN_AGENT_TIMER_TYPE_PERIODIC = 1, + + /* Inactive state: initial state for any timer. */ + FLEXRAN_AGENT_TIMER_TYPE_EVENT_DRIVEN = 2, + + /* Max number of states available */ + FLEXRAN_AGENT_TIMER_TYPE_MAX, +} flexran_agent_timer_type_t; + + +typedef enum { + /* Inactive state: initial state for any timer. */ + FLEXRAN_AGENT_TIMER_STATE_INACTIVE = 0x0, + + /* Inactive state: initial state for any timer. */ + FLEXRAN_AGENT_TIMER_STATE_ACTIVE = 0x1, + + /* Inactive state: initial state for any timer. */ + FLEXRAN_AGENT_TIMER_STATE_STOPPED = 0x2, + + /* Max number of states available */ + FLEXRAN_AGENT_TIMER_STATE_MAX, +} flexran_agent_timer_state_t; + + typedef struct { /* general info */ @@ -116,6 +148,53 @@ typedef struct { } flexran_agent_info_t; + +/* +rrc triggering + */ + + +typedef struct { + char * trigger_policy; + uint32_t report_interval; + uint32_t report_amount; + +} agent_reconf_rrc; + + +/* These structs will be used to give + instructions for the type of stats reports + we need to create */ + + +typedef struct { + uint16_t ue_rnti; + uint32_t ue_report_flags; /* Indicates the report elements + required for this UE id. See + FlexRAN specification 1.2.4.2 */ +} ue_report_type_t; + +typedef struct { + uint16_t cc_id; + uint32_t cc_report_flags; /* Indicates the report elements + required for this CC index. See + FlexRAN specification 1.2.4.3 */ +} cc_report_type_t; + +typedef struct { + int nr_ue; + ue_report_type_t *ue_report_type; + int nr_cc; + cc_report_type_t *cc_report_type; +} report_config_t; + +typedef struct stats_request_config_s{ + uint8_t report_type; + uint8_t report_frequency; + uint16_t period; /*In number of subframes*/ + report_config_t *config; +} stats_request_config_t; + typedef struct { mid_t enb_id; flexran_agent_info_t agent_info; diff --git a/openair2/ENB_APP/flexran_agent_extern.h b/openair2/ENB_APP/flexran_agent_extern.h index 4a04d5d3a6..4df984e1a0 100644 --- a/openair2/ENB_APP/flexran_agent_extern.h +++ b/openair2/ENB_APP/flexran_agent_extern.h @@ -20,9 +20,9 @@ */ /*! \file ENB_APP/extern.h - * \brief FlexRAN agent - mac interface primitives - * \author Xenofon Foukas - * \date 2016 + * \brief FlexRAN agent - Extern VSF xfaces + * \author Xenofon Foukas and shahab SHARIAT BAGHERI + * \date 2017 * \version 0.1 * \mail x.foukas@sms.ed.ac.uk */ @@ -30,9 +30,9 @@ #ifndef __FLEXRAN_AGENT_EXTERN_H__ #define __FLEXRAN_AGENT_EXTERN_H__ -#include "flexran_agent_defs.h" +// #include "flexran_agent_defs.h" #include "flexran_agent_mac_defs.h" - +#include "flexran_agent_rrc_defs.h" //extern msg_context_t shared_ctxt[NUM_MAX_ENB][FLEXRAN_AGENT_MAX]; @@ -45,6 +45,12 @@ extern AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB]; /* Flag indicating whether the VSFs for the MAC control module have been registered */ extern unsigned int mac_agent_registered[NUM_MAX_ENB]; +/* Control module interface for the communication of the RRC Control Module with the agent */ +extern AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB]; + +/* Flag indicating whether the VSFs for the RRC control module have been registered */ +extern unsigned int rrc_agent_registered[NUM_MAX_ENB]; + /* Requried to know which UEs had a harq updated over some subframe */ extern int harq_pid_updated[NUMBER_OF_UE_MAX][8]; extern int harq_pid_round[NUMBER_OF_UE_MAX][8]; diff --git a/openair2/ENB_APP/flexran_agent_handler.c b/openair2/ENB_APP/flexran_agent_handler.c index 29a1c1000c..b57039bec5 100644 --- a/openair2/ENB_APP/flexran_agent_handler.c +++ b/openair2/ENB_APP/flexran_agent_handler.c @@ -21,14 +21,16 @@ /*! \file flexran_agent_handler.c * \brief FlexRAN agent tx and rx message handler - * \author Xenofon Foukas and Navid Nikaein - * \date 2016 + * \author Xenofon Foukas and Navid Nikaein and shahab SHARIAT BAGHERI + * \date 2017 * \version 0.1 */ - +#include "flexran_agent_defs.h" #include "flexran_agent_common.h" #include "flexran_agent_mac.h" +#include "flexran_agent_rrc.h" +#include "flexran_agent_timer.h" #include "log.h" #include "assertions.h" @@ -37,7 +39,7 @@ flexran_agent_message_decoded_callback agent_messages_callback[][3] = { {flexran_agent_hello, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_HELLO_MSG*/ {flexran_agent_echo_reply, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REQUEST_MSG*/ {0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REPLY_MSG*/ //Must add handler when receiving echo reply - {flexran_agent_mac_handle_stats, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REQUEST_MSG*/ + {flexran_agent_handle_stats, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REQUEST_MSG*/ {0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REPLY_MSG*/ {0, 0, 0}, /*PROTOCOK__FLEXRAN_MESSAGE__MSG_SF_TRIGGER_MSG*/ {0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_UL_SR_INFO_MSG*/ @@ -51,13 +53,14 @@ flexran_agent_message_decoded_callback agent_messages_callback[][3] = { {0, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_STATE_CHANGE_MSG*/ {flexran_agent_control_delegation, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_CONTROL_DELEGATION_MSG*/ {flexran_agent_reconfiguration, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_AGENT_RECONFIGURATION_MSG*/ + {flexran_agent_rrc_measurement, 0, 0}, /*PROTOCOL__FLEXRAN_MESSAGE__MSG_RRC_TRIGGERING_MSG*/ }; flexran_agent_message_destruction_callback message_destruction_callback[] = { flexran_agent_destroy_hello, flexran_agent_destroy_echo_request, flexran_agent_destroy_echo_reply, - flexran_agent_mac_destroy_stats_request, + flexran_agent_destroy_stats_request, flexran_agent_mac_destroy_stats_reply, flexran_agent_mac_destroy_sf_trigger, flexran_agent_mac_destroy_sr_info, @@ -93,7 +96,7 @@ Protocol__FlexranMessage* flexran_agent_handle_message (mid_t mod_id, err_code= PROTOCOL__FLEXRAN_ERR__MSG_DECODING; goto error; } - + printf("==================> %d %d \n", decoded_message->msg_case, decoded_message->msg_dir); if ((decoded_message->msg_case > sizeof(agent_messages_callback) / (3 * sizeof(flexran_agent_message_decoded_callback))) || (decoded_message->msg_dir > PROTOCOL__FLEXRAN_DIRECTION__UNSUCCESSFUL_OUTCOME)){ err_code= PROTOCOL__FLEXRAN_ERR__MSG_NOT_HANDLED; @@ -187,3 +190,568 @@ Protocol__FlexranMessage* flexran_agent_process_timeout(long timer_id, void* tim err_code_t flexran_agent_destroy_flexran_message(Protocol__FlexranMessage *msg) { return ((*message_destruction_callback[msg->msg_case-1])(msg)); } + + +/* + Top Level Statistics Report + + */ + + + +int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg){ + + // TODO: Must deal with sanitization of input + // TODO: Must check if RNTIs and cell ids of the request actually exist + // TODO: Must resolve conflicts among stats requests + + int i; + err_code_t err_code; + xid_t xid; + uint32_t usec_interval, sec_interval; + + //TODO: We do not deal with multiple CCs at the moment and eNB id is 0 + int enb_id = mod_id; + + //eNB_MAC_INST *eNB = &eNB_mac_inst[enb_id]; + //UE_list_t *eNB_UE_list= &eNB->UE_list; + + report_config_t report_config; + + uint32_t ue_flags = 0; + uint32_t c_flags = 0; + + Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; + + Protocol__FlexStatsRequest *stats_req = input->stats_request_msg; + xid = (stats_req->header)->xid; + + // Check the type of request that is made + switch(stats_req->body_case) { + case PROTOCOL__FLEX_STATS_REQUEST__BODY_COMPLETE_STATS_REQUEST: ; + Protocol__FlexCompleteStatsRequest *comp_req = stats_req->complete_stats_request; + if (comp_req->report_frequency == PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_OFF) { + /*Disable both periodic and continuous updates*/ + // flexran_agent_disable_cont_stats_update(mod_id); + flexran_agent_destroy_timer_by_task_id(xid); + *msg = NULL; + return 0; + } else { //One-off, periodical or continuous reporting + //Set the proper flags + ue_flags = comp_req->ue_report_flags; + c_flags = comp_req->cell_report_flags; + //Create a list of all eNB RNTIs and cells + + //Set the number of UEs and create list with their RNTIs stats configs + report_config.nr_ue = flexran_get_num_ues(mod_id); //eNB_UE_list->num_UEs + report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t) * report_config.nr_ue); + if (report_config.ue_report_type == NULL) { + // TODO: Add appropriate error code + err_code = -100; + goto error; + } + for (i = 0; i < report_config.nr_ue; i++) { + report_config.ue_report_type[i].ue_rnti = flexran_get_ue_crnti(enb_id, i); //eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,i)][i].crnti; + report_config.ue_report_type[i].ue_report_flags = ue_flags; + } + //Set the number of CCs and create a list with the cell stats configs + report_config.nr_cc = MAX_NUM_CCs; + report_config.cc_report_type = (cc_report_type_t *) malloc(sizeof(cc_report_type_t) * report_config.nr_cc); + if (report_config.cc_report_type == NULL) { + // TODO: Add appropriate error code + err_code = -100; + goto error; + } + for (i = 0; i < report_config.nr_cc; i++) { + //TODO: Must fill in the proper cell ids + report_config.cc_report_type[i].cc_id = i; + report_config.cc_report_type[i].cc_report_flags = c_flags; + } + /* Check if request was periodical */ + if (comp_req->report_frequency == PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_PERIODICAL) { + /* Create a one off flexran message as an argument for the periodical task */ + Protocol__FlexranMessage *timer_msg; + stats_request_config_t request_config; + request_config.report_type = PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS; + request_config.report_frequency = PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_ONCE; + request_config.period = 0; + /* Need to make sure that the ue flags are saved (Bug) */ + if (report_config.nr_ue == 0) { + report_config.nr_ue = 1; + report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t)); + if (report_config.ue_report_type == NULL) { + // TODO: Add appropriate error code + err_code = -100; + goto error; + } + report_config.ue_report_type[0].ue_rnti = 0; // Dummy value + report_config.ue_report_type[0].ue_report_flags = ue_flags; + } + request_config.config = &report_config; + flexran_agent_stats_request(enb_id, xid, &request_config, &timer_msg); + /* Create a timer */ + long timer_id = 0; + flexran_agent_timer_args_t *timer_args; + timer_args = malloc(sizeof(flexran_agent_timer_args_t)); + memset (timer_args, 0, sizeof(flexran_agent_timer_args_t)); + timer_args->mod_id = enb_id; + timer_args->msg = timer_msg; + /*Convert subframes to usec time*/ + usec_interval = 1000*comp_req->sf; + sec_interval = 0; + /*add seconds if required*/ + if (usec_interval >= 1000*1000) { + sec_interval = usec_interval/(1000*1000); + usec_interval = usec_interval%(1000*1000); + } + flexran_agent_create_timer(sec_interval, usec_interval, FLEXRAN_AGENT_DEFAULT, enb_id, FLEXRAN_AGENT_TIMER_TYPE_PERIODIC, xid, flexran_agent_handle_timed_task,(void*) timer_args, &timer_id); + } else if (comp_req->report_frequency == PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_CONTINUOUS) { + /*If request was for continuous updates, disable the previous configuration and + set up a new one*/ + // flexran_agent_disable_cont_stats_update(mod_id); + stats_request_config_t request_config; + request_config.report_type = PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS; + request_config.report_frequency = PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_ONCE; + request_config.period = 0; + /* Need to make sure that the ue flags are saved (Bug) */ + if (report_config.nr_ue == 0) { + report_config.nr_ue = 1; + report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t)); + if (report_config.ue_report_type == NULL) { + // TODO: Add appropriate error code + err_code = -100; + goto error; + } + report_config.ue_report_type[0].ue_rnti = 0; // Dummy value + report_config.ue_report_type[0].ue_report_flags = ue_flags; + } + request_config.config = &report_config; + flexran_agent_enable_cont_stats_update(enb_id, xid, &request_config); + } + } + break; + case PROTOCOL__FLEX_STATS_REQUEST__BODY_CELL_STATS_REQUEST:; + Protocol__FlexCellStatsRequest *cell_req = stats_req->cell_stats_request; + // UE report config will be blank + report_config.nr_ue = 0; + report_config.ue_report_type = NULL; + report_config.nr_cc = cell_req->n_cell; + report_config.cc_report_type = (cc_report_type_t *) malloc(sizeof(cc_report_type_t) * report_config.nr_cc); + if (report_config.cc_report_type == NULL) { + // TODO: Add appropriate error code + err_code = -100; + goto error; + } + for (i = 0; i < report_config.nr_cc; i++) { + //TODO: Must fill in the proper cell ids + report_config.cc_report_type[i].cc_id = cell_req->cell[i]; + report_config.cc_report_type[i].cc_report_flags = cell_req->flags; + } + break; + case PROTOCOL__FLEX_STATS_REQUEST__BODY_UE_STATS_REQUEST:; + Protocol__FlexUeStatsRequest *ue_req = stats_req->ue_stats_request; + // Cell report config will be blank + report_config.nr_cc = 0; + report_config.cc_report_type = NULL; + report_config.nr_ue = ue_req->n_rnti; + report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t) * report_config.nr_ue); + if (report_config.ue_report_type == NULL) { + // TODO: Add appropriate error code + err_code = -100; + goto error; + } + for (i = 0; i < report_config.nr_ue; i++) { + report_config.ue_report_type[i].ue_rnti = ue_req->rnti[i]; + report_config.ue_report_type[i].ue_report_flags = ue_req->flags; + } + break; + default: + //TODO: Add appropriate error code + err_code = -100; + goto error; + } + + if (flexran_agent_stats_reply(enb_id, xid, &report_config, msg )){ + err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; + goto error; + } + + free(report_config.ue_report_type); + free(report_config.cc_report_type); + + return 0; + + error : + LOG_E(FLEXRAN_AGENT, "errno %d occured\n", err_code); + return err_code; +} + +/* + Top level reply + */ + +int flexran_agent_stats_reply(mid_t enb_id, xid_t xid, const report_config_t *report_config, Protocol__FlexranMessage **msg){ + + Protocol__FlexHeader *header; + err_code_t err_code; + int i; + + if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_STATS_REPLY, &header) != 0) + goto error; + + + Protocol__FlexStatsReply *stats_reply_msg; + + stats_reply_msg = malloc(sizeof(Protocol__FlexStatsReply)); + + if (stats_reply_msg == NULL) + goto error; + + protocol__flex_stats_reply__init(stats_reply_msg); + stats_reply_msg->header = header; + + stats_reply_msg->n_ue_report = report_config->nr_ue; + stats_reply_msg->n_cell_report = report_config->nr_cc; + + // UE report + + Protocol__FlexUeStatsReport **ue_report; + + + ue_report = malloc(sizeof(Protocol__FlexUeStatsReport *) * report_config->nr_ue); + if (ue_report == NULL) + goto error; + + for (i = 0; i < report_config->nr_ue; i++) { + + ue_report[i] = malloc(sizeof(Protocol__FlexUeStatsReport)); + protocol__flex_ue_stats_report__init(ue_report[i]); + ue_report[i]->rnti = report_config->ue_report_type[i].ue_rnti; + ue_report[i]->has_rnti = 1; + ue_report[i]->flags = report_config->ue_report_type[i].ue_report_flags; + ue_report[i]->has_flags = 1; + + } + + // cell rpoert + + Protocol__FlexCellStatsReport **cell_report; + + + cell_report = malloc(sizeof(Protocol__FlexCellStatsReport *) * report_config->nr_cc); + if (cell_report == NULL) + goto error; + + for (i = 0; i < report_config->nr_cc; i++) { + + cell_report[i] = malloc(sizeof(Protocol__FlexCellStatsReport)); + if(cell_report[i] == NULL) + goto error; + + protocol__flex_cell_stats_report__init(cell_report[i]); + cell_report[i]->carrier_index = report_config->cc_report_type[i].cc_id; + cell_report[i]->has_carrier_index = 1; + cell_report[i]->flags = report_config->cc_report_type[i].cc_report_flags; + cell_report[i]->has_flags = 1; + + } + + /* + MAC reply split + */ + + + if (flexran_agent_mac_stats_reply(enb_id, report_config, ue_report, cell_report) < 0 ) { + err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; + goto error; + } + + + stats_reply_msg->cell_report = cell_report; + stats_reply_msg->ue_report = ue_report; + + *msg = malloc(sizeof(Protocol__FlexranMessage)); + if(*msg == NULL) + goto error; + protocol__flexran_message__init(*msg); + (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REPLY_MSG; + (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME; + (*msg)->stats_reply_msg = stats_reply_msg; + + return 0; + +error : + LOG_E(FLEXRAN_AGENT, "errno %d occured\n", err_code); + return err_code; + +} + +/* + Top Level Request + */ + +int flexran_agent_stats_request(mid_t mod_id, + xid_t xid, + const stats_request_config_t *report_config, + Protocol__FlexranMessage **msg) { + Protocol__FlexHeader *header; + int i; + + Protocol__FlexStatsRequest *stats_request_msg; + stats_request_msg = malloc(sizeof(Protocol__FlexStatsRequest)); + if(stats_request_msg == NULL) + goto error; + protocol__flex_stats_request__init(stats_request_msg); + + if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_STATS_REQUEST, &header) != 0) + goto error; + + stats_request_msg->header = header; + + stats_request_msg->type = report_config->report_type; + stats_request_msg->has_type = 1; + + switch (report_config->report_type) { + case PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS: + stats_request_msg->body_case = PROTOCOL__FLEX_STATS_REQUEST__BODY_COMPLETE_STATS_REQUEST; + Protocol__FlexCompleteStatsRequest *complete_stats; + complete_stats = malloc(sizeof(Protocol__FlexCompleteStatsRequest)); + if(complete_stats == NULL) + goto error; + protocol__flex_complete_stats_request__init(complete_stats); + complete_stats->report_frequency = report_config->report_frequency; + complete_stats->has_report_frequency = 1; + complete_stats->sf = report_config->period; + complete_stats->has_sf = 1; + complete_stats->has_cell_report_flags = 1; + complete_stats->has_ue_report_flags = 1; + if (report_config->config->nr_cc > 0) { + complete_stats->cell_report_flags = report_config->config->cc_report_type[0].cc_report_flags; + } + if (report_config->config->nr_ue > 0) { + complete_stats->ue_report_flags = report_config->config->ue_report_type[0].ue_report_flags; + } + stats_request_msg->complete_stats_request = complete_stats; + break; + case PROTOCOL__FLEX_STATS_TYPE__FLST_CELL_STATS: + stats_request_msg->body_case = PROTOCOL__FLEX_STATS_REQUEST__BODY_CELL_STATS_REQUEST; + Protocol__FlexCellStatsRequest *cell_stats; + cell_stats = malloc(sizeof(Protocol__FlexCellStatsRequest)); + if(cell_stats == NULL) + goto error; + protocol__flex_cell_stats_request__init(cell_stats); + cell_stats->n_cell = report_config->config->nr_cc; + cell_stats->has_flags = 1; + if (cell_stats->n_cell > 0) { + uint32_t *cells; + cells = (uint32_t *) malloc(sizeof(uint32_t)*cell_stats->n_cell); + for (i = 0; i < cell_stats->n_cell; i++) { + cells[i] = report_config->config->cc_report_type[i].cc_id; + } + cell_stats->cell = cells; + cell_stats->flags = report_config->config->cc_report_type[i].cc_report_flags; + } + stats_request_msg->cell_stats_request = cell_stats; + break; + case PROTOCOL__FLEX_STATS_TYPE__FLST_UE_STATS: + stats_request_msg->body_case = PROTOCOL__FLEX_STATS_REQUEST__BODY_UE_STATS_REQUEST; + Protocol__FlexUeStatsRequest *ue_stats; + ue_stats = malloc(sizeof(Protocol__FlexUeStatsRequest)); + if(ue_stats == NULL) + goto error; + protocol__flex_ue_stats_request__init(ue_stats); + ue_stats->n_rnti = report_config->config->nr_ue; + ue_stats->has_flags = 1; + if (ue_stats->n_rnti > 0) { + uint32_t *ues; + ues = (uint32_t *) malloc(sizeof(uint32_t)*ue_stats->n_rnti); + for (i = 0; i < ue_stats->n_rnti; i++) { + ues[i] = report_config->config->ue_report_type[i].ue_rnti; + } + ue_stats->rnti = ues; + ue_stats->flags = report_config->config->ue_report_type[i].ue_report_flags; + } + stats_request_msg->ue_stats_request = ue_stats; + break; + default: + goto error; + } + *msg = malloc(sizeof(Protocol__FlexranMessage)); + if(*msg == NULL) + goto error; + protocol__flexran_message__init(*msg); + (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REQUEST_MSG; + (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE; + (*msg)->stats_request_msg = stats_request_msg; + return 0; + + error: + // TODO: Need to make proper error handling + if (header != NULL) + free(header); + if (stats_request_msg != NULL) + free(stats_request_msg); + if(*msg != NULL) + free(*msg); + //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); + return -1; +} + +int flexran_agent_destroy_stats_request(Protocol__FlexranMessage *msg) { + if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REQUEST_MSG) + goto error; + free(msg->stats_request_msg->header); + if (msg->stats_request_msg->body_case == PROTOCOL__FLEX_STATS_REQUEST__BODY_CELL_STATS_REQUEST) { + free(msg->stats_request_msg->cell_stats_request->cell); + } + if (msg->stats_request_msg->body_case == PROTOCOL__FLEX_STATS_REQUEST__BODY_UE_STATS_REQUEST) { + free(msg->stats_request_msg->ue_stats_request->rnti); + } + free(msg->stats_request_msg); + free(msg); + return 0; + + error: + //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); + return -1; +} + +/* + Top Level Update + */ + +void flexran_agent_send_update_stats(mid_t mod_id) { + + Protocol__FlexranMessage *current_report = NULL; + void *data; + int size; + err_code_t err_code; + int priority = 0; + + if (pthread_mutex_lock(stats_context[mod_id].mutex)) { + goto error; + } + + if (stats_context[mod_id].cont_update == 1) { + + /*Create a fresh report with the required flags*/ + err_code = flexran_agent_handle_stats(mod_id, (void *) stats_context[mod_id].stats_req, ¤t_report); + if (err_code < 0) { + goto error; + } + } + /* /\*TODO:Check if a previous reports exists and if yes, generate a report */ + /* *that is the diff between the old and the new report, */ + /* *respecting the thresholds. Otherwise send the new report*\/ */ + /* if (stats_context[mod_id].prev_stats_reply != NULL) { */ + + /* msg = flexran_agent_generate_diff_mac_stats_report(current_report, stats_context[mod_id].prev_stats_reply); */ + + /* /\*Destroy the old stats*\/ */ + /* flexran_agent_destroy_flexran_message(stats_context[mod_id].prev_stats_reply); */ + /* } */ + /* /\*Use the current report for future comparissons*\/ */ + /* stats_context[mod_id].prev_stats_reply = current_report; */ + + + if (pthread_mutex_unlock(stats_context[mod_id].mutex)) { + goto error; + } + + if (current_report != NULL){ + data=flexran_agent_pack_message(current_report, &size); + /*Send any stats updates using the MAC channel of the eNB*/ + if (flexran_agent_msg_send(mod_id, FLEXRAN_AGENT_MAC, data, size, priority)) { + err_code = PROTOCOL__FLEXRAN_ERR__MSG_ENQUEUING; + goto error; + } + + LOG_D(FLEXRAN_AGENT,"sent message with size %d\n", size); + return; + } + error: + LOG_D(FLEXRAN_AGENT, "Could not send sf trigger message\n"); +} + +err_code_t flexran_agent_disable_cont_stats_update(mid_t mod_id) { + /*Disable the continuous updates for the MAC*/ + if (pthread_mutex_lock(stats_context[mod_id].mutex)) { + goto error; + } + stats_context[mod_id].cont_update = 0; + stats_context[mod_id].xid = 0; + if (stats_context[mod_id].stats_req != NULL) { + flexran_agent_destroy_flexran_message(stats_context[mod_id].stats_req); + } + if (stats_context[mod_id].prev_stats_reply != NULL) { + flexran_agent_destroy_flexran_message(stats_context[mod_id].prev_stats_reply); + } + if (pthread_mutex_unlock(stats_context[mod_id].mutex)) { + goto error; + } + return 0; + + error: + LOG_E(FLEXRAN_AGENT, "stats_context for eNB %d is not initialized\n", mod_id); + return -1; + +} + +err_code_t flexran_agent_enable_cont_stats_update(mid_t mod_id, + xid_t xid, stats_request_config_t *stats_req) { + + if (pthread_mutex_lock(stats_context[mod_id].mutex)) { + goto error; + } + + Protocol__FlexranMessage *req_msg; + + flexran_agent_stats_request(mod_id, xid, stats_req, &req_msg); + stats_context[mod_id].stats_req = req_msg; + stats_context[mod_id].prev_stats_reply = NULL; + + stats_context[mod_id].cont_update = 1; + stats_context[mod_id].xid = xid; + + if (pthread_mutex_unlock(stats_context[mod_id].mutex)) { + goto error; + } + return 0; + + error: + LOG_E(FLEXRAN_AGENT, "stats_context for eNB %d is not initialized\n", mod_id); + return -1; +} + + +err_code_t flexran_agent_init_cont_stats_update(mid_t mod_id) { + + + /*Initially the continuous update is set to false*/ + stats_context[mod_id].cont_update = 0; + stats_context[mod_id].is_initialized = 1; + stats_context[mod_id].stats_req = NULL; + stats_context[mod_id].prev_stats_reply = NULL; + stats_context[mod_id].mutex = calloc(1, sizeof(pthread_mutex_t)); + if (stats_context[mod_id].mutex == NULL) + goto error; + if (pthread_mutex_init(stats_context[mod_id].mutex, NULL)) + goto error;; + + return 0; + + error: + return -1; +} + +err_code_t flexran_agent_destroy_cont_stats_update(mid_t mod_id) { + + stats_context[mod_id].cont_update = 0; + stats_context[mod_id].is_initialized = 0; + flexran_agent_destroy_flexran_message(stats_context[mod_id].stats_req); + flexran_agent_destroy_flexran_message(stats_context[mod_id].prev_stats_reply); + free(stats_context[mod_id].mutex); + + // mac_agent_registered[mod_id] = 0; + return 1; +} \ No newline at end of file diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c new file mode 100644 index 0000000000..17a53c7eb0 --- /dev/null +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -0,0 +1,929 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file flexran_agent_ran_api.c + * \brief FlexRAN RAN API abstraction + * \author shahab SHARIAT BAGHERI + * \date 2017 + * \version 0.1 + */ + +#include "flexran_agent_ran_api.h" + + +/* + * get generic info from RAN + */ + + + +void * enb[NUM_MAX_ENB]; +void * enb_ue[NUM_MAX_ENB]; +void * enb_rrc[NUM_MAX_ENB]; + +void flexran_set_enb_vars(mid_t mod_id, ran_name_t ran){ + + switch (ran){ + case RAN_LTE_OAI : + enb[mod_id] = (void *)&eNB_mac_inst[mod_id]; + enb_ue[mod_id] = (void *)&eNB_mac_inst[mod_id].UE_list; + enb_rrc[mod_id] = (void *)&eNB_rrc_inst[mod_id]; + break; + default : + goto error; + } + + return; + + error: + LOG_E(FLEXRAN_AGENT, "unknown RAN name %d\n", ran); +} + +int flexran_get_current_time_ms (mid_t mod_id, int subframe_flag){ + + if (subframe_flag == 1){ + return ((eNB_MAC_INST *)enb[mod_id])->frame*10 + ((eNB_MAC_INST *)enb[mod_id])->subframe; + }else { + return ((eNB_MAC_INST *)enb[mod_id])->frame*10; + } + +} + +unsigned int flexran_get_current_frame (mid_t mod_id) { + + // #warning "SFN will not be in [0-1023] when oaisim is used" + return ((eNB_MAC_INST *)enb[mod_id])->frame; + +} + +unsigned int flexran_get_current_system_frame_num(mid_t mod_id) { + return (flexran_get_current_frame(mod_id) %1024); +} + +unsigned int flexran_get_current_subframe (mid_t mod_id) { + + return ((eNB_MAC_INST *)enb[mod_id])->subframe; + +} + +uint16_t flexran_get_sfn_sf (mid_t mod_id) { + + frame_t frame; + sub_frame_t subframe; + uint16_t sfn_sf, frame_mask, sf_mask; + + frame = (frame_t) flexran_get_current_system_frame_num(mod_id); + subframe = (sub_frame_t) flexran_get_current_subframe(mod_id); + frame_mask = ((1<<12) - 1); + sf_mask = ((1<<4) - 1); + sfn_sf = (subframe & sf_mask) | ((frame & frame_mask) << 4); + + return sfn_sf; +} + +uint16_t flexran_get_future_sfn_sf (mid_t mod_id, int ahead_of_time) { + + frame_t frame; + sub_frame_t subframe; + uint16_t sfn_sf, frame_mask, sf_mask; + + frame = (frame_t) flexran_get_current_system_frame_num(mod_id); + subframe = (sub_frame_t) flexran_get_current_subframe(mod_id); + + subframe = ((subframe + ahead_of_time) % 10); + + if (subframe < flexran_get_current_subframe(mod_id)) { + frame = (frame + 1) % 1024; + } + + int additional_frames = ahead_of_time / 10; + frame = (frame + additional_frames) % 1024; + + frame_mask = ((1<<12) - 1); + sf_mask = ((1<<4) - 1); + sfn_sf = (subframe & sf_mask) | ((frame & frame_mask) << 4); + + return sfn_sf; +} + +int flexran_get_num_ues (mid_t mod_id){ + + return ((UE_list_t *)enb_ue[mod_id])->num_UEs; +} + +int flexran_get_ue_crnti (mid_t mod_id, mid_t ue_id) { + + return UE_RNTI(mod_id, ue_id); +} + +int flexran_get_ue_bsr (mid_t mod_id, mid_t ue_id, lcid_t lcid) { + + return ((UE_list_t *)enb_ue[mod_id])->UE_template[UE_PCCID(mod_id,ue_id)][ue_id].bsr_info[lcid]; +} + +int flexran_get_ue_phr (mid_t mod_id, mid_t ue_id) { + + return ((UE_list_t *)enb_ue[mod_id])->UE_template[UE_PCCID(mod_id,ue_id)][ue_id].phr_info; +} + +int flexran_get_ue_wcqi (mid_t mod_id, mid_t ue_id) { + LTE_eNB_UE_stats *eNB_UE_stats = NULL; + eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, 0, UE_RNTI(mod_id, ue_id)); + return eNB_UE_stats->DL_cqi[0]; + + // return ((UE_list_t *)enb_ue[mod_id])->eNB_UE_stats[UE_PCCID(mod_id,ue_id)][ue_id].dl_cqi; +} + +int flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) { + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + uint16_t frame = (uint16_t) flexran_get_current_frame(mod_id); + mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id,frame,ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0); + return rlc_status.bytes_in_buffer; +} + +int flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) { + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + uint16_t frame = (uint16_t) flexran_get_current_frame(mod_id); + mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, ENB_FLAG_YES, MBMS_FLAG_NO, channel_id, 0); + return rlc_status.head_sdu_creation_time; +} + +short flexran_get_TA(mid_t mod_id, mid_t ue_id, int CC_id) { + + UE_list_t *UE_list=&eNB_mac_inst[mod_id].UE_list; + int rnti; + + rnti = flexran_get_ue_crnti(mod_id, ue_id); + + LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti); + //ue_sched_ctl->ta_timer = 20; // wait 20 subframes before taking TA measurement from PHY + switch (PHY_vars_eNB_g[mod_id][CC_id]->frame_parms.N_RB_DL) { + case 6: + return eNB_UE_stats->timing_advance_update; + case 15: + return eNB_UE_stats->timing_advance_update/2; + case 25: + return eNB_UE_stats->timing_advance_update/4; + case 50: + return eNB_UE_stats->timing_advance_update/8; + case 75: + return eNB_UE_stats->timing_advance_update/12; + case 100: + if (PHY_vars_eNB_g[mod_id][CC_id]->frame_parms.threequarter_fs == 0) { + return eNB_UE_stats->timing_advance_update/16; + } else { + return eNB_UE_stats->timing_advance_update/12; + } + default: + return 0; + } +} + +int flexran_get_ue_pmi(mid_t mod_id){ + + /*Xenofon to check this*/ + + return 0; +} + + +void flexran_update_TA(mid_t mod_id, mid_t ue_id, int CC_id) { + + UE_list_t *UE_list=&eNB_mac_inst[mod_id].UE_list; + UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[ue_id]; + + if (ue_sched_ctl->ta_timer == 0) { + + // WE SHOULD PROTECT the eNB_UE_stats with a mutex here ... + // LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti); + //ue_sched_ctl->ta_timer = 20; // wait 20 subframes before taking TA measurement from PHY + ue_sched_ctl->ta_update = flexran_get_TA(mod_id, ue_id, CC_id); + + // clear the update in case PHY does not have a new measurement after timer expiry + // eNB_UE_stats->timing_advance_update = 0; + } else { + ue_sched_ctl->ta_timer--; + ue_sched_ctl->ta_update = 0; // don't trigger a timing advance command + } +} + +int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id,int CC_id) { + + UE_list_t *UE_list = &eNB_mac_inst[mod_id].UE_list; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id,CC_id,rnti); + + if (eNB_UE_stats == NULL) { + return 0; + } + + if (flexran_get_TA(mod_id, ue_id, CC_id) != 0) { + return PROTOCOL__FLEX_CE_TYPE__FLPCET_TA; + } else { + return 0; + } + +} + +int flexran_get_active_CC(mid_t mod_id, mid_t ue_id) { + return ((UE_list_t *)enb_ue[mod_id])->numactiveCCs[ue_id]; +} + +int flexran_get_current_RI(mid_t mod_id, mid_t ue_id, int CC_id) { + LTE_eNB_UE_stats *eNB_UE_stats = NULL; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + + eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id,CC_id,rnti); + + if (eNB_UE_stats == NULL) { + return 0; + } + + return eNB_UE_stats[CC_id].rank; +} + +int flexran_get_tpc(mid_t mod_id, mid_t ue_id) { + LTE_eNB_UE_stats *eNB_UE_stats = NULL; + int32_t normalized_rx_power, target_rx_power; + int tpc = 1; + + int pCCid = UE_PCCID(mod_id,ue_id); + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + + eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, pCCid, rnti); + + target_rx_power = mac_xface->get_target_pusch_rx_power(mod_id,pCCid); + + if (eNB_UE_stats == NULL) { + normalized_rx_power = target_rx_power; + } else if (eNB_UE_stats->UL_rssi != NULL) { + normalized_rx_power = eNB_UE_stats->UL_rssi[0]; + } else { + normalized_rx_power = target_rx_power; + } + + if (normalized_rx_power>(target_rx_power+1)) { + tpc = 0; //-1 + } else if (normalized_rx_power<(target_rx_power-1)) { + tpc = 2; //+1 + } else { + tpc = 1; //0 + } + return tpc; +} + +int flexran_get_harq(const mid_t mod_id, + const uint8_t CC_id, + const mid_t ue_id, + const int frame, + const uint8_t subframe, + uint8_t *id, + uint8_t *round) { //flag_id_status = 0 then id, else status + /*TODO: Add int TB in function parameters to get the status of the second TB. This can be done to by editing in + * get_ue_active_harq_pid function in line 272 file: phy_procedures_lte_eNB.c to add + * DLSCH_ptr = PHY_vars_eNB_g[Mod_id][CC_id]->dlsch_eNB[(uint32_t)UE_id][1];*/ + + uint8_t harq_pid; + uint8_t harq_round; + + + uint16_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + + mac_xface->get_ue_active_harq_pid(mod_id,CC_id,rnti,frame,subframe,&harq_pid,&harq_round,openair_harq_DL); + + *id = harq_pid; + *round = harq_round; + /* if (round > 0) { */ + /* *status = 1; */ + /* } else { */ + /* *status = 0; */ + /* } */ + + /* return 0; */ + return *round; +} + +int flexran_get_p0_pucch_dbm(mid_t mod_id, mid_t ue_id, int CC_id) { + LTE_eNB_UE_stats *eNB_UE_stats = NULL; + uint32_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + + eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti); + + if (eNB_UE_stats == NULL) { + return -1; + } + + // if(eNB_UE_stats->Po_PUCCH_update == 1) { + return eNB_UE_stats->Po_PUCCH_dBm; + //} + //else + // return -1; +} + +int flexran_get_p0_nominal_pucch(mid_t mod_id, int CC_id) { + int32_t pucch_rx_received = mac_xface->get_target_pucch_rx_power(mod_id, CC_id); + return pucch_rx_received; +} + +int flexran_get_p0_pucch_status(mid_t mod_id, mid_t ue_id, int CC_id) { + LTE_eNB_UE_stats *eNB_UE_stats = NULL; + uint32_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + + eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti); + return eNB_UE_stats->Po_PUCCH_update; +} + +int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, int CC_id) { + LTE_eNB_UE_stats *eNB_UE_stats = NULL; + uint32_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + + eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti); + eNB_UE_stats->Po_PUCCH_update = 0; + + return 0; +} + + +/* + * ************************************ + * Get Messages for eNB Configuration Reply + * ************************************ + */ + +int flexran_get_hopping_offset(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + return frame_parms->pusch_config_common.pusch_HoppingOffset; +} + +int flexran_get_hopping_mode(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + return frame_parms->pusch_config_common.hoppingMode; +} + +int flexran_get_n_SB(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + return frame_parms->pusch_config_common.n_SB; +} + +int flexran_get_enable64QAM(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + return frame_parms->pusch_config_common.enable64QAM; +} + +int flexran_get_phich_duration(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + return frame_parms->phich_config_common.phich_duration; +} + +int flexran_get_phich_resource(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + if(frame_parms->phich_config_common.phich_resource == oneSixth) + return 0; + else if(frame_parms->phich_config_common.phich_resource == half) + return 1; + else if(frame_parms->phich_config_common.phich_resource == one) + return 2; + else if(frame_parms->phich_config_common.phich_resource == two) + return 3; + + return -1; +} + +int flexran_get_n1pucch_an(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + return frame_parms->pucch_config_common.n1PUCCH_AN; +} + +int flexran_get_nRB_CQI(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + return frame_parms->pucch_config_common.nRB_CQI; +} + +int flexran_get_deltaPUCCH_Shift(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + return frame_parms->pucch_config_common.deltaPUCCH_Shift; +} + +int flexran_get_prach_ConfigIndex(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + return frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex; +} + +int flexran_get_prach_FreqOffset(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + return frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset; +} + +int flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + return frame_parms->maxHARQ_Msg3Tx; +} + +int flexran_get_ul_cyclic_prefix_length(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + return frame_parms->Ncp_UL; +} + +int flexran_get_dl_cyclic_prefix_length(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + return frame_parms->Ncp; +} + +int flexran_get_cell_id(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + return frame_parms->Nid_cell; +} + +int flexran_get_srs_BandwidthConfig(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + return frame_parms->soundingrs_ul_config_common.srs_BandwidthConfig; +} + +int flexran_get_srs_SubframeConfig(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + return frame_parms->soundingrs_ul_config_common.srs_SubframeConfig; +} + +int flexran_get_srs_MaxUpPts(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + return frame_parms->soundingrs_ul_config_common.srs_MaxUpPts; +} + +int flexran_get_N_RB_DL(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + return frame_parms->N_RB_DL; +} + +int flexran_get_N_RB_UL(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + return frame_parms->N_RB_UL; +} + +int flexran_get_N_RBG(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + return frame_parms->N_RBG; +} + +int flexran_get_subframe_assignment(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + return frame_parms->tdd_config; +} + +int flexran_get_special_subframe_assignment(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + return frame_parms->tdd_config_S; +} + +int flexran_get_ra_ResponseWindowSize(mid_t mod_id, int CC_id) { + return enb_config_get()->properties[mod_id]->rach_raResponseWindowSize[CC_id]; +} + +int flexran_get_mac_ContentionResolutionTimer(mid_t mod_id, int CC_id) { + return enb_config_get()->properties[mod_id]->rach_macContentionResolutionTimer[CC_id]; +} + +int flexran_get_duplex_mode(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + if(frame_parms->frame_type == TDD) + return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD; + else if (frame_parms->frame_type == FDD) + return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_FDD; + + return -1; +} + +long flexran_get_si_window_length(mid_t mod_id, int CC_id) { + return ((eNB_RRC_INST *)enb_rrc[mod_id])->carrier[CC_id].sib1->si_WindowLength; +} + +int flexran_get_sib1_length(mid_t mod_id, int CC_id) { + return ((eNB_RRC_INST *)enb_rrc[mod_id])->carrier[CC_id].sizeof_SIB1; +} + +int flexran_get_num_pdcch_symb(mid_t mod_id, int CC_id) { + /* TODO: This should return the number of PDCCH symbols initially used by the cell CC_id */ + return 0; + //(PHY_vars_UE_g[mod_id][CC_id]->lte_ue_pdcch_vars[mod_id]->num_pdcch_symbols); +} + + + +/* + * ************************************ + * Get Messages for UE Configuration Reply + * ************************************ + */ + + +int flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id) { + struct rrc_eNB_ue_context_s* ue_context_p = NULL; + uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); + if(ue_context_p != NULL) { + if(ue_context_p->ue_context.mac_MainConfig != NULL) { + return ue_context_p->ue_context.mac_MainConfig->timeAlignmentTimerDedicated; + } else { + return -1; + } + } else { + return -1; + } +} + +int flexran_get_meas_gap_config(mid_t mod_id, mid_t ue_id) { + struct rrc_eNB_ue_context_s* ue_context_p = NULL; + uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); + if(ue_context_p != NULL) { + if(ue_context_p->ue_context.measGapConfig != NULL) { + if(ue_context_p->ue_context.measGapConfig->present == MeasGapConfig_PR_setup) { + if (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present == MeasGapConfig__setup__gapOffset_PR_gp0) { + return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_GP1; + } else if (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present == MeasGapConfig__setup__gapOffset_PR_gp1) { + return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_GP2; + } else { + return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF; + } + } + } + } + return -1; +} + + +int flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id) { + struct rrc_eNB_ue_context_s* ue_context_p = NULL; + uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); + + if(ue_context_p != NULL) { + if(ue_context_p->ue_context.measGapConfig != NULL){ + if(ue_context_p->ue_context.measGapConfig->present == MeasGapConfig_PR_setup) { + if (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present == MeasGapConfig__setup__gapOffset_PR_gp0) { + return ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.choice.gp0; + } else if (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present == MeasGapConfig__setup__gapOffset_PR_gp1) { + return ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.choice.gp0; + } + } + } + } + return -1; +} + +int flexran_get_ue_aggregated_max_bitrate_dl (mid_t mod_id, mid_t ue_id) { + return ((UE_list_t *)enb_ue[mod_id])->UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateDL; +} + +int flexran_get_ue_aggregated_max_bitrate_ul (mid_t mod_id, mid_t ue_id) { + return ((UE_list_t *)enb_ue[mod_id])->UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateUL; +} + +int flexran_get_half_duplex(mid_t ue_id) { + // TODO + //int halfduplex = 0; + //int bands_to_scan = ((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count; + //for (int i =0; i < bands_to_scan; i++){ + //if(((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->halfDuplex > 0) + // halfduplex = 1; + //} + //return halfduplex; + return 0; +} + +int flexran_get_intra_sf_hopping(mid_t ue_id) { + //TODO:Get proper value + //temp = (((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->featureGroupIndicators->buf); + //return (0 & ( 1 << (31))); + return 0; +} + +int flexran_get_type2_sb_1(mid_t ue_id) { + //TODO:Get proper value + //uint8_t temp = 0; + //temp = (((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->featureGroupIndicators->buf); + //return (temp & ( 1 << (11))); + return 0; +} + +int flexran_get_ue_category(mid_t ue_id) { + //TODO:Get proper value + //return (((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->ue_Category); + return 0; +} + +int flexran_get_res_alloc_type1(mid_t ue_id) { + //TODO:Get proper value + //uint8_t temp = 0; + //temp = (((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->featureGroupIndicators->buf); + //return (temp & ( 1 << (30))); + return 0; +} + +int flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id) { + struct rrc_eNB_ue_context_s* ue_context_p = NULL; + uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); + + if(ue_context_p != NULL) { + if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ + return ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode; + } else { + return -1; + } + } else { + return -1; + } +} + +int flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id) { + struct rrc_eNB_ue_context_s* ue_context_p = NULL; + uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); + if(ue_context_p != NULL) { + if(ue_context_p->ue_context.mac_MainConfig != NULL){ + return ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config->ttiBundling; + } else { + return -1; + } + } + else { + return -1; + } +} + +int flexran_get_maxHARQ_TX(mid_t mod_id, mid_t ue_id) { + struct rrc_eNB_ue_context_s* ue_context_p = NULL; + uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); + if(ue_context_p != NULL) { + if(ue_context_p->ue_context.mac_MainConfig != NULL){ + return *ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config->maxHARQ_Tx; + } + } + return -1; +} + +int flexran_get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id) { + struct rrc_eNB_ue_context_s* ue_context_p = NULL; + uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); + if(ue_context_p != NULL) { + if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ + return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_ACK_Index; + } else { + return -1; + } + } else { + return -1; + } +} + +int flexran_get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id) { + struct rrc_eNB_ue_context_s* ue_context_p = NULL; + uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); + if(ue_context_p != NULL) { + if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ + return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index; + } else { + return -1; + } + } else { + return -1; + } +} + +int flexran_get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id) { + struct rrc_eNB_ue_context_s* ue_context_p = NULL; + uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); + if(ue_context_p != NULL) { + if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ + return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index; + } else { + return -1; + } + } + else { + return -1; + } +} + +int flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id) { + struct rrc_eNB_ue_context_s* ue_context_p = NULL; + uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); + if(ue_context_p != NULL) { + if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ + if (ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic != NULL) { + return ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.simultaneousAckNackAndCQI; + } + } + } + return -1; +} + +int flexran_get_ack_nack_simultaneous_trans(mid_t mod_id,mid_t ue_id) { + return (&eNB_rrc_inst[mod_id])->carrier[0].sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; +} + +int flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id) { + struct rrc_eNB_ue_context_s* ue_context_p = NULL; + uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); + + if(ue_context_p != NULL) { + if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ + return *ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic; + } + } + return -1; +} + +int flexran_get_tdd_ack_nack_feedback(mid_t mod_id, mid_t ue_id) { + // TODO: This needs fixing + return -1; + + /* struct rrc_eNB_ue_context_s* ue_context_p = NULL; */ + /* uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); */ + + /* ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); */ + + /* if(ue_context_p != NULL) { */ + /* if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ */ + /* return ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode; */ + /* } else { */ + /* return -1; */ + /* } */ + /* } else { */ + /* return -1; */ + /* } */ +} + +int flexran_get_ack_nack_repetition_factor(mid_t mod_id, mid_t ue_id) { + struct rrc_eNB_ue_context_s* ue_context_p = NULL; + uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); + if(ue_context_p != NULL) { + if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ + return ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->ackNackRepetition.choice.setup.repetitionFactor; + } else { + return -1; + } + } else { + return -1; + } +} + +int flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id) { + //TODO: need to double check + struct rrc_eNB_ue_context_s* ue_context_p = NULL; + uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); + if(ue_context_p != NULL) { + if(ue_context_p->ue_context.mac_MainConfig != NULL){ + if(ue_context_p->ue_context.mac_MainConfig->ext2 != NULL){ + long val = (*(ue_context_p->ue_context.mac_MainConfig->ext2->mac_MainConfig_v1020->extendedBSR_Sizes_r10)); + if (val > 0) { + return 1; + } + } + } + } + return -1; +} + +int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id) { + struct rrc_eNB_ue_context_s* ue_context_p = NULL; + uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); + + if(ue_context_p != NULL) { + if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ + if(ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.choice.setup == AntennaInfoDedicated__ue_TransmitAntennaSelection__setup_closedLoop) { + return 2; + } else if(ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.choice.setup == AntennaInfoDedicated__ue_TransmitAntennaSelection__setup_openLoop) { + return 1; + } else { + return 0; + } + } else { + return -1; + } + } else { + return -1; + } +} + +int flexran_get_lcg(mid_t ue_id, mid_t lc_id) { + if (UE_mac_inst == NULL) { + return -1; + } + if(UE_mac_inst[ue_id].logicalChannelConfig[lc_id] != NULL) { + return *UE_mac_inst[ue_id].logicalChannelConfig[lc_id]->ul_SpecificParameters->logicalChannelGroup; + } else { + return -1; + } +} + +int flexran_get_direction(mid_t ue_id, mid_t lc_id) { + /*TODO: fill with the value for the rest of LCID*/ + if(lc_id == DCCH || lc_id == DCCH1) { + return 2; + } else if(lc_id == DTCH) { + return 1; + } else { + return -1; + } +} + +int flexran_get_antenna_ports(mid_t mod_id, int CC_id){ + + LTE_DL_FRAME_PARMS *frame_parms; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + return frame_parms->nb_antenna_ports_eNB; + +} \ No newline at end of file diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h new file mode 100644 index 0000000000..12962a1f9d --- /dev/null +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -0,0 +1,290 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file flexran_agent_ran_api.h + * \brief FlexRAN RAN API abstraction header + * \author shahab SHARIAT BAGHERI + * \date 2017 + * \version 0.1 + */ + +#include +#include + +#include "flexran_agent_common.h" +#include "flexran_agent_common_internal.h" +#include "flexran_agent_extern.h" +#include "flexran_agent_defs.h" + + +#include "enb_config.h" +#include "LAYER2/MAC/extern.h" +#include "LAYER2/RLC/rlc.h" +#include "SCHED/defs.h" +#include "RRC/LITE/extern.h" +#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" +#include "RRC/LITE/rrc_eNB_UE_context.h" +#include "PHY/extern.h" +#include "log.h" + +/**************************** + * get generic info from RAN + ****************************/ + +void flexran_set_enb_vars(mid_t mod_id, ran_name_t ran); + +int flexran_get_current_time_ms (mid_t mod_id, int subframe_flag); + +/*Return the current frame number + *Could be using implementation specific numbering of frames + */ +unsigned int flexran_get_current_frame(mid_t mod_id); + +/*Return the current SFN (0-1023)*/ +unsigned int flexran_get_current_system_frame_num(mid_t mod_id); + +unsigned int flexran_get_current_subframe(mid_t mod_id); + +/*Return the frame and subframe number in compact 16-bit format. + Bits 0-3 subframe, rest for frame. Required by FlexRAN protocol*/ +uint16_t flexran_get_sfn_sf (mid_t mod_id); + +/* Return a future frame and subframe number that is ahead_of_time + subframes later in compact 16-bit format. Bits 0-3 subframe, + rest for frame */ +uint16_t flexran_get_future_sfn_sf(mid_t mod_id, int ahead_of_time); + +/* Return the number of attached UEs */ +int flexran_get_num_ues(mid_t mod_id); + +/* Get the rnti of a UE with id ue_id */ +int flexran_get_ue_crnti (mid_t mod_id, mid_t ue_id); + +/* Get the RLC buffer status report of a ue for a designated + logical channel id */ +int flexran_get_ue_bsr (mid_t mod_id, mid_t ue_id, lcid_t lcid); + +/* Get power headroom of UE with id ue_id */ +int flexran_get_ue_phr (mid_t mod_id, mid_t ue_id); + +/* Get the UE wideband CQI */ +int flexran_get_ue_wcqi (mid_t mod_id, mid_t ue_id); + +/* Get the transmission queue size for a UE with a channel_id logical channel id */ +int flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id); + +/* Get the head of line delay for a UE with a channel_id logical channel id */ +int flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id); + +/* Check the status of the timing advance for a UE */ +short flexran_get_TA(mid_t mod_id, mid_t ue_id, int CC_id); + +/* Update the timing advance status (find out whether a timing advance command is required) */ +void flexran_update_TA(mid_t mod_id, mid_t ue_id, int CC_id); + +/* Return timing advance MAC control element for a designated cell and UE */ +int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id, int CC_id); + +/* Get the number of active component carriers for a specific UE */ +int flexran_get_active_CC(mid_t mod_id, mid_t ue_id); + +/* Get the rank indicator for a designated cell and UE */ +int flexran_get_current_RI(mid_t mod_id, mid_t ue_id, int CC_id); + +/* See TS 36.213, section 10.1 */ +int flexran_get_n1pucch_an(mid_t mod_id, int CC_id); + +/* See TS 36.211, section 5.4 */ +int flexran_get_nRB_CQI(mid_t mod_id, int CC_id); + +/* See TS 36.211, section 5.4 */ +int flexran_get_deltaPUCCH_Shift(mid_t mod_id, int CC_id); + +/* See TS 36.211, section 5.7.1 */ +int flexran_get_prach_ConfigIndex(mid_t mod_id, int CC_id); + +/* See TS 36.211, section 5.7.1 */ +int flexran_get_prach_FreqOffset(mid_t mod_id, int CC_id); + +/* See TS 36.321 */ +int flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, int CC_id); + +/* Get the length of the UL cyclic prefix */ +int flexran_get_ul_cyclic_prefix_length(mid_t mod_id, int CC_id); + +/* Get the length of the DL cyclic prefix */ +int flexran_get_dl_cyclic_prefix_length(mid_t mod_id, int CC_id); + +/* Get the physical cell id of a cell */ +int flexran_get_cell_id(mid_t mod_id, int CC_id); + +/* See TS 36.211, section 5.5.3.2 */ +int flexran_get_srs_BandwidthConfig(mid_t mod_id, int CC_id); + +/* See TS 36.211, table 5.5.3.3-1 and 2 */ +int flexran_get_srs_SubframeConfig(mid_t mod_id, int CC_id); + +/* Boolean value. See TS 36.211, + section 5.5.3.2. TDD only */ +int flexran_get_srs_MaxUpPts(mid_t mod_id, int CC_id); + +/* Get number of DL resource blocks */ +int flexran_get_N_RB_DL(mid_t mod_id, int CC_id); + +/* Get number of UL resource blocks */ +int flexran_get_N_RB_UL(mid_t mod_id, int CC_id); + +/* Get number of resource block groups */ +int flexran_get_N_RBG(mid_t mod_id, int CC_id); + +/* Get DL/UL subframe assignment. TDD only */ +int flexran_get_subframe_assignment(mid_t mod_id, int CC_id); + +/* TDD only. See TS 36.211, table 4.2.1 */ +int flexran_get_special_subframe_assignment(mid_t mod_id, int CC_id); + +/* Get the duration of the random access response window in subframes */ +int flexran_get_ra_ResponseWindowSize(mid_t mod_id, int CC_id); + +/* Get timer used for random access */ +int flexran_get_mac_ContentionResolutionTimer(mid_t mod_id, int CC_id); + +/* Get type of duplex mode (FDD/TDD) */ +int flexran_get_duplex_mode(mid_t mod_id, int CC_id); + +/* Get the SI window length */ +long flexran_get_si_window_length(mid_t mod_id, int CC_id); + +/* Get the number of PDCCH symbols configured for the cell */ +int flexran_get_num_pdcch_symb(mid_t mod_id, int CC_id); + +int flexran_get_antenna_ports(mid_t mod_id, int CC_id); + +/* See TS 36.213, sec 5.1.1.1 */ +int flexran_get_tpc(mid_t mod_id, mid_t ue_id); + +int flexran_get_ue_pmi(mid_t mod_id); + +/* Get the first available HARQ process for a specific cell and UE during + a designated frame and subframe. Returns 0 for success. The id and the + status of the HARQ process are stored in id and status respectively */ +int flexran_get_harq(const mid_t mod_id, const uint8_t CC_id, const mid_t ue_id, + const int frame, const uint8_t subframe, unsigned char *id, unsigned char *round); + +/* Uplink power control management*/ +int flexran_get_p0_pucch_dbm(mid_t mod_id, mid_t ue_id, int CC_id); + +int flexran_get_p0_nominal_pucch(mid_t mod_id, int CC_id); + +int flexran_get_p0_pucch_status(mid_t mod_id, mid_t ue_id, int CC_id); + +int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, int CC_id); + + +/* + * ************************************ + * Get Messages for UE Configuration Reply + * ************************************ + */ + +/* Get timer in subframes. Controls the synchronization + status of the UE, not the actual timing + advance procedure. See TS 36.321 */ +int flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id); + +/* Get measurement gap configuration. See TS 36.133 */ +int flexran_get_meas_gap_config(mid_t mod_id, mid_t ue_id); + +/* Get measurement gap configuration offset if applicable */ +int flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id); + +/* DL aggregated bit-rate of non-gbr bearer + per UE. See TS 36.413 */ +int flexran_get_ue_aggregated_max_bitrate_dl (mid_t mod_id, mid_t ue_id); + +/* UL aggregated bit-rate of non-gbr bearer + per UE. See TS 36.413 */ +int flexran_get_ue_aggregated_max_bitrate_ul (mid_t mod_id, mid_t ue_id); + +/* Only half-duplex support. FDD + operation. Boolean value */ +int flexran_get_half_duplex(mid_t ue_id); + +/* Support of intra-subframe hopping. + Boolean value */ +int flexran_get_intra_sf_hopping(mid_t ue_id); + +/* UE support for type 2 hopping with + n_sb>1 */ +int flexran_get_type2_sb_1(mid_t ue_id); + +/* Get the UE category */ +int flexran_get_ue_category(mid_t ue_id); + +/* UE support for resource allocation + type 1 */ +int flexran_get_res_alloc_type1(mid_t ue_id); + +/* Get UE transmission mode */ +int flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id); + +/* Boolean value. See TS 36.321 */ +int flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id); + +/* The max HARQ retransmission for UL. + See TS 36.321 */ +int flexran_get_maxHARQ_TX(mid_t mod_id, mid_t ue_id); + +/* See TS 36.213 */ +int flexran_get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id); + +/* See TS 36.213 */ +int flexran_get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id); + +/* See TS 36.213 */ +int flexran_get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id); + +/* Boolean. See TS36.213, Section 10.1 */ +int flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id); + +/* Boolean. See TS 36.213, Section 8.2 */ +int flexran_get_ack_nack_simultaneous_trans(mid_t mod_id,mid_t ue_id); + +/* Get aperiodic CQI report mode */ +int flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id); + +/* Get ACK/NACK feedback mode. TDD only */ +int flexran_get_tdd_ack_nack_feedback(mid_t mod_id, mid_t ue_id); + +/* See TS36.213, section 10.1 */ +int flexran_get_ack_nack_repetition_factor(mid_t mod_id, mid_t ue_id); + +/* Boolean. Extended buffer status report size */ +int flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id); + +/* Get number of UE transmission antennas */ +int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id); + +/* Get logical channel group of a channel with id lc_id */ +int flexran_get_lcg(mid_t ue_id, mid_t lc_id); + +/* Get direction of logical channel with id lc_id */ +int flexran_get_direction(mid_t ue_id, mid_t lc_id); \ No newline at end of file diff --git a/openair2/ENB_APP/flexran_agent_timer.c b/openair2/ENB_APP/flexran_agent_timer.c new file mode 100644 index 0000000000..f5436e4d01 --- /dev/null +++ b/openair2/ENB_APP/flexran_agent_timer.c @@ -0,0 +1,217 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file flexran_agent_timer.c + * \brief FlexRAN Timer + * \author shahab SHARIAT BAGHERI + * \date 2017 + * \version 0.1 + */ + +/* + * timer primitives + */ + +#include "flexran_agent_timer.h" + +//struct flexran_agent_map agent_map; +flexran_agent_timer_instance_t timer_instance; +int agent_timer_init = 0; +err_code_t flexran_agent_init_timer(void){ + + LOG_I(FLEXRAN_AGENT, "init RB tree\n"); + if (!agent_timer_init) { + RB_INIT(&timer_instance.flexran_agent_head); + agent_timer_init = 1; + } + + return PROTOCOL__FLEXRAN_ERR__NO_ERR; +} + +RB_GENERATE(flexran_agent_map, flexran_agent_timer_element_s, entry, flexran_agent_compare_timer); + +/* The timer_id might not be the best choice for the comparison */ +int flexran_agent_compare_timer(struct flexran_agent_timer_element_s *a, struct flexran_agent_timer_element_s *b){ + + if (a->timer_id < b->timer_id) return -1; + if (a->timer_id > b->timer_id) return 1; + + // equal timers + return 0; +} + +err_code_t flexran_agent_create_timer(uint32_t interval_sec, + uint32_t interval_usec, + agent_id_t agent_id, + instance_t instance, + uint32_t timer_type, + xid_t xid, + flexran_agent_timer_callback_t cb, + void* timer_args, + long *timer_id){ + + struct flexran_agent_timer_element_s *e = calloc(1, sizeof(*e)); + DevAssert(e != NULL); + +//uint32_t timer_id; + int ret=-1; + + if ((interval_sec == 0) && (interval_usec == 0 )) + return TIMER_NULL; + + if (timer_type >= FLEXRAN_AGENT_TIMER_TYPE_MAX) + return TIMER_TYPE_INVALIDE; + + if (timer_type == FLEXRAN_AGENT_TIMER_TYPE_ONESHOT){ + ret = timer_setup(interval_sec, + interval_usec, + TASK_FLEXRAN_AGENT, + instance, + TIMER_ONE_SHOT, + timer_args, + timer_id); + + e->type = TIMER_ONE_SHOT; + } + else if (timer_type == FLEXRAN_AGENT_TIMER_TYPE_PERIODIC ){ + ret = timer_setup(interval_sec, + interval_usec, + TASK_FLEXRAN_AGENT, + instance, + TIMER_PERIODIC, + timer_args, + timer_id); + + e->type = TIMER_PERIODIC; + } + + if (ret < 0 ) { + return TIMER_SETUP_FAILED; + } + + e->agent_id = agent_id; + e->instance = instance; + e->state = FLEXRAN_AGENT_TIMER_STATE_ACTIVE; + e->timer_id = *timer_id; + e->xid = xid; + e->timer_args = timer_args; + e->cb = cb; + /*element should be a real pointer*/ + RB_INSERT(flexran_agent_map, &timer_instance.flexran_agent_head, e); + + LOG_I(FLEXRAN_AGENT,"Created a new timer with id 0x%lx for agent %d, instance %d \n", + e->timer_id, e->agent_id, e->instance); + + return 0; +} + +err_code_t flexran_agent_destroy_timer(long timer_id){ + + struct flexran_agent_timer_element_s *e = get_timer_entry(timer_id); + + if (e != NULL ) { + RB_REMOVE(flexran_agent_map, &timer_instance.flexran_agent_head, e); + flexran_agent_destroy_flexran_message(e->timer_args->msg); + free(e); + } + + if (timer_remove(timer_id) < 0 ) + goto error; + + return 0; + + error: + LOG_E(FLEXRAN_AGENT, "timer can't be removed\n"); + return TIMER_REMOVED_FAILED ; +} + +err_code_t flexran_agent_destroy_timer_by_task_id(xid_t xid) { + struct flexran_agent_timer_element_s *e = NULL; + long timer_id; + RB_FOREACH(e, flexran_agent_map, &timer_instance.flexran_agent_head) { + if (e->xid == xid) { + timer_id = e->timer_id; + RB_REMOVE(flexran_agent_map, &timer_instance.flexran_agent_head, e); + flexran_agent_destroy_flexran_message(e->timer_args->msg); + free(e); + if (timer_remove(timer_id) < 0 ) { + goto error; + } + } + } + return 0; + + error: + LOG_E(FLEXRAN_AGENT, "timer can't be removed\n"); + return TIMER_REMOVED_FAILED ; +} + +err_code_t flexran_agent_destroy_timers(void){ + + struct flexran_agent_timer_element_s *e = NULL; + + RB_FOREACH(e, flexran_agent_map, &timer_instance.flexran_agent_head) { + RB_REMOVE(flexran_agent_map, &timer_instance.flexran_agent_head, e); + timer_remove(e->timer_id); + flexran_agent_destroy_flexran_message(e->timer_args->msg); + free(e); + } + + return 0; + +} + +void flexran_agent_sleep_until(struct timespec *ts, int delay) { + ts->tv_nsec += delay; + if(ts->tv_nsec >= 1000*1000*1000){ + ts->tv_nsec -= 1000*1000*1000; + ts->tv_sec++; + } + clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, ts, NULL); +} + + +err_code_t flexran_agent_stop_timer(long timer_id){ + + struct flexran_agent_timer_element_s *e=NULL; + struct flexran_agent_timer_element_s search; + memset(&search, 0, sizeof(struct flexran_agent_timer_element_s)); + search.timer_id = timer_id; + + e = RB_FIND(flexran_agent_map, &timer_instance.flexran_agent_head, &search); + + if (e != NULL ) { + e->state = FLEXRAN_AGENT_TIMER_STATE_STOPPED; + } + + timer_remove(timer_id); + + return 0; +} + +struct flexran_agent_timer_element_s * get_timer_entry(long timer_id) { + + struct flexran_agent_timer_element_s search; + memset(&search, 0, sizeof(struct flexran_agent_timer_element_s)); + search.timer_id = timer_id; + + return RB_FIND(flexran_agent_map, &timer_instance.flexran_agent_head, &search); +} diff --git a/openair2/ENB_APP/flexran_agent_timer.h b/openair2/ENB_APP/flexran_agent_timer.h new file mode 100644 index 0000000000..86e0d07825 --- /dev/null +++ b/openair2/ENB_APP/flexran_agent_timer.h @@ -0,0 +1,133 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file flexran_agent_timer.h + * \brief FlexRAN Timer header + * \author shahab SHARIAT BAGHERI + * \date 2017 + * \version 0.1 + */ + +#include +#include + +#include "flexran_agent_common.h" +#include "flexran_agent_common_internal.h" +#include "flexran_agent_extern.h" +#include "flexran_agent_defs.h" + + +# include "tree.h" +# include "intertask_interface.h" +# include "timer.h" + + + +/******************* + * timer primitves + *******************/ + +#define TIMER_NULL -1 +#define TIMER_TYPE_INVALIDE -2 +#define TIMER_SETUP_FAILED -3 +#define TIMER_REMOVED_FAILED -4 +#define TIMER_ELEMENT_NOT_FOUND -5 + + +/* Type of the callback executed when the timer expired */ +typedef Protocol__FlexranMessage *(*flexran_agent_timer_callback_t)(void*); + + +typedef struct flexran_agent_timer_args_s{ + mid_t mod_id; + Protocol__FlexranMessage *msg; +} flexran_agent_timer_args_t; + + +typedef struct flexran_agent_timer_element_s{ + RB_ENTRY(flexran_agent_timer_element_s) entry; + + agent_id_t agent_id; + instance_t instance; + + flexran_agent_timer_type_t type; + flexran_agent_timer_state_t state; + + uint32_t interval_sec; + uint32_t interval_usec; + + long timer_id; /* Timer id returned by the timer API*/ + xid_t xid; /*The id of the task as received by the controller + message*/ + + flexran_agent_timer_callback_t cb; + flexran_agent_timer_args_t *timer_args; + +} flexran_agent_timer_element_t; + +typedef struct flexran_agent_timer_instance_s{ + RB_HEAD(flexran_agent_map, flexran_agent_timer_element_s) flexran_agent_head; +}flexran_agent_timer_instance_t; + + +err_code_t flexran_agent_init_timer(void); + +/* Create a timer for some agent related event with id xid. Will store the id + of the generated timer in timer_id */ +err_code_t flexran_agent_create_timer(uint32_t interval_sec, + uint32_t interval_usec, + agent_id_t agent_id, + instance_t instance, + uint32_t timer_type, + xid_t xid, + flexran_agent_timer_callback_t cb, + void* timer_args, + long *timer_id); + +/* Destroy all existing timers */ +err_code_t flexran_agent_destroy_timers(void); + +/* Destroy the timer with the given timer_id */ +err_code_t flexran_agent_destroy_timer(long timer_id); + +/* Destroy the timer for task with id xid */ +err_code_t flexran_agent_destroy_timer_by_task_id(xid_t xid); + +/* Stop a timer */ +err_code_t flexran_agent_stop_timer(long timer_id); + +/* Restart the given timer */ +err_code_t flexran_agent_restart_timer(long *timer_id); + +/* Find the timer with the given timer_id */ +struct flexran_agent_timer_element_s * get_timer_entry(long timer_id); + +/* Obtain the protocol message stored in the given expired timer */ +Protocol__FlexranMessage * flexran_agent_process_timeout(long timer_id, void* timer_args); + +/* Comparator function comparing two timers. Decides the ordering of the timers */ +int flexran_agent_compare_timer(struct flexran_agent_timer_element_s *a, struct flexran_agent_timer_element_s *b); + +/*Specify a delay in nanoseconds to timespec and sleep until then*/ +void flexran_agent_sleep_until(struct timespec *ts, int delay); + +/* RB_PROTOTYPE is for .h files */ +RB_PROTOTYPE(flexran_agent_map, flexran_agent_timer_element_s, entry, flexran_agent_compare_timer); diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 6509471124..b75a3e7e8e 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -158,8 +158,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, //mac_remove_ue(module_idP, i, frameP, subframeP); //Inform the controller about the UE deactivation. Should be moved to RRC agent in the future #if defined(FLEXRAN_AGENT_SB_IF) - if (mac_agent_registered[module_idP]) { - agent_mac_xface[module_idP]->flexran_agent_notify_ue_state_change(module_idP, + if (rrc_agent_registered[module_idP]) { + agent_rrc_xface[module_idP]->flexran_agent_notify_ue_state_change(module_idP, rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); } @@ -1082,15 +1082,15 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, for (CC_id=0;CC_idflexran_agent_send_update_mac_stats(module_idP); - } -#endif -#endif - + // if (mac_agent_registered[module_idP]) { + // agent_mac_xface[module_idP]->flexran_agent_send_update_mac_stats(module_idP); + // } +// #endif +// #endif +flexran_agent_send_update_stats(module_idP); /* int dummy=0; for (i=0; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 56ede260e8..01edbb87cf 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -180,6 +180,10 @@ uint8_t find_active_UEs(module_id_t module_idP,int CC_id){ } */ +int UE_BSR (uint8_t mod_id, uint8_t ue_id, uint8_t lcid) { + + return eNB_mac_inst[mod_id].UE_list.UE_template[UE_PCCID(mod_id,ue_id)][ue_id].bsr_info[lcid]; +} // get aggregation (L) form phy for a give UE unsigned char get_aggregation (uint8_t bw_index, uint8_t cqi, uint8_t dci_fmt) @@ -304,6 +308,12 @@ printf("MAC: cannot add new UE for rnti %x\n", rntiP); return(-1); } +int CC_id_rnti_downlink (uint8_t mod_id, int CC_index, uint16_t ue_rnti) { + + return eNB_mac_inst[mod_id].UE_list.ordered_CCids[CC_index][ue_rnti]; +} + + //------------------------------------------------------------------------------ int rrc_mac_remove_ue(module_id_t mod_idP,rnti_t rntiP) //------------------------------------------------------------------------------ diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index da9d93c19a..6247548bcc 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -1899,7 +1899,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportAmount = ReportConfigEUTRA__reportAmount_infinity; ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A1); - + if (ho_state == 1 /*HO_MEASURMENT */ ) { LOG_I(RRC, "[eNB %d] frame %d: requesting A2, A3, A4, A5, and A6 event reporting\n", ctxt_pP->module_id, ctxt_pP->frame); @@ -2159,6 +2159,598 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons } +//----------------------------------------------------------------------------- +void +flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_t* const ue_context_pP, + const uint8_t ho_state, + agent_reconf_rrc * trig_param + ) +//----------------------------------------------------------------------------- +{ + uint8_t buffer[RRC_BUF_SIZE]; + uint16_t size; + int i; + + // configure SRB1/SRB2, PhysicalConfigDedicated, MAC_MainConfig for UE + eNB_RRC_INST* rrc_inst = &eNB_rrc_inst[ctxt_pP->module_id]; + struct PhysicalConfigDedicated** physicalConfigDedicated = &ue_context_pP->ue_context.physicalConfigDedicated; + + struct SRB_ToAddMod *SRB2_config = NULL; + struct SRB_ToAddMod__rlc_Config *SRB2_rlc_config = NULL; + struct SRB_ToAddMod__logicalChannelConfig *SRB2_lchan_config = NULL; + struct LogicalChannelConfig__ul_SpecificParameters + *SRB2_ul_SpecificParameters = NULL; + SRB_ToAddModList_t* SRB_configList = ue_context_pP->ue_context.SRB_configList; + SRB_ToAddModList_t **SRB_configList2 = NULL; + + struct DRB_ToAddMod *DRB_config = NULL; + struct RLC_Config *DRB_rlc_config = NULL; + struct PDCP_Config *DRB_pdcp_config = NULL; + struct PDCP_Config__rlc_AM *PDCP_rlc_AM = NULL; + struct PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL; + struct LogicalChannelConfig *DRB_lchan_config = NULL; + struct LogicalChannelConfig__ul_SpecificParameters + *DRB_ul_SpecificParameters = NULL; + DRB_ToAddModList_t** DRB_configList = &ue_context_pP->ue_context.DRB_configList; + DRB_ToAddModList_t** DRB_configList2 = NULL; + MAC_MainConfig_t *mac_MainConfig = NULL; + MeasObjectToAddModList_t *MeasObj_list = NULL; + MeasObjectToAddMod_t *MeasObj = NULL; + ReportConfigToAddModList_t *ReportConfig_list = NULL; + ReportConfigToAddMod_t *ReportConfig_per, *ReportConfig_A1, + *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5; + MeasIdToAddModList_t *MeasId_list = NULL; + MeasIdToAddMod_t *MeasId0, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5; +#if Rel10 + long *sr_ProhibitTimer_r9 = NULL; + // uint8_t sCellIndexToAdd = rrc_find_free_SCell_index(enb_mod_idP, ue_mod_idP, 1); + //uint8_t sCellIndexToAdd = 0; +#endif + + long *logicalchannelgroup, *logicalchannelgroup_drb; + long *maxHARQ_Tx, *periodicBSR_Timer; + + RSRP_Range_t *rsrp = NULL; + struct MeasConfig__speedStatePars *Sparams = NULL; + QuantityConfig_t *quantityConfig = NULL; + CellsToAddMod_t *CellToAdd = NULL; + CellsToAddModList_t *CellsToAddModList = NULL; + struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL; + DedicatedInfoNAS_t *dedicatedInfoNas = NULL; + /* for no gcc warnings */ + (void)dedicatedInfoNas; + + C_RNTI_t *cba_RNTI = NULL; + + uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id); //Transaction_id, + +#ifdef CBA + //struct PUSCH_CBAConfigDedicated_vlola *pusch_CBAConfigDedicated_vlola; + uint8_t *cba_RNTI_buf; + cba_RNTI = CALLOC(1, sizeof(C_RNTI_t)); + cba_RNTI_buf = CALLOC(1, 2 * sizeof(uint8_t)); + cba_RNTI->buf = cba_RNTI_buf; + cba_RNTI->size = 2; + cba_RNTI->bits_unused = 0; + + // associate UEs to the CBa groups as a function of their UE id + if (rrc_inst->num_active_cba_groups) { + cba_RNTI->buf[0] = rrc_inst->cba_rnti[ue_mod_idP % rrc_inst->num_active_cba_groups] & 0xff; + cba_RNTI->buf[1] = 0xff; + LOG_D(RRC, + "[eNB %d] Frame %d: cba_RNTI = %x in group %d is attribued to UE %d\n", + enb_mod_idP, frameP, + rrc_inst->cba_rnti[ue_mod_idP % rrc_inst->num_active_cba_groups], + ue_mod_idP % rrc_inst->num_active_cba_groups, ue_mod_idP); + } else { + cba_RNTI->buf[0] = 0x0; + cba_RNTI->buf[1] = 0x0; + LOG_D(RRC, "[eNB %d] Frame %d: no cba_RNTI is configured for UE %d\n", enb_mod_idP, frameP, ue_mod_idP); + } + +#endif + + T(T_ENB_RRC_CONNECTION_RECONFIGURATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + + // Configure SRB2 + /// SRB2 + SRB_configList2=&ue_context_pP->ue_context.SRB_configList2[xid]; + if (*SRB_configList2) { + free(*SRB_configList2); + } + *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2)); + memset(*SRB_configList2, 0, sizeof(**SRB_configList2)); + SRB2_config = CALLOC(1, sizeof(*SRB2_config)); + + SRB2_config->srb_Identity = 2; + SRB2_rlc_config = CALLOC(1, sizeof(*SRB2_rlc_config)); + SRB2_config->rlc_Config = SRB2_rlc_config; + + SRB2_rlc_config->present = SRB_ToAddMod__rlc_Config_PR_explicitValue; + SRB2_rlc_config->choice.explicitValue.present = RLC_Config_PR_am; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = T_PollRetransmit_ms15; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = PollPDU_p8; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = PollByte_kB1000; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = UL_AM_RLC__maxRetxThreshold_t32; + SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = T_Reordering_ms35; + SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = T_StatusProhibit_ms10; + + SRB2_lchan_config = CALLOC(1, sizeof(*SRB2_lchan_config)); + SRB2_config->logicalChannelConfig = SRB2_lchan_config; + + SRB2_lchan_config->present = SRB_ToAddMod__logicalChannelConfig_PR_explicitValue; + + SRB2_ul_SpecificParameters = CALLOC(1, sizeof(*SRB2_ul_SpecificParameters)); + + SRB2_ul_SpecificParameters->priority = 3; // let some priority for SRB1 and dedicated DRBs + SRB2_ul_SpecificParameters->prioritisedBitRate = + LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + SRB2_ul_SpecificParameters->bucketSizeDuration = + LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + + // LCG for CCCH and DCCH is 0 as defined in 36331 + logicalchannelgroup = CALLOC(1, sizeof(long)); + *logicalchannelgroup = 0; + + SRB2_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup; + + SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters = SRB2_ul_SpecificParameters; + // this list has the configuration for SRB1 and SRB2 + ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config); + // this list has only the configuration for SRB2 + ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config); + + // Configure DRB + //*DRB_configList = CALLOC(1, sizeof(*DRB_configList)); + // list for all the configured DRB + if (*DRB_configList) { + free(*DRB_configList); + } + *DRB_configList = CALLOC(1, sizeof(**DRB_configList)); + memset(*DRB_configList, 0, sizeof(**DRB_configList)); + + // list for the configured DRB for a this xid + DRB_configList2=&ue_context_pP->ue_context.DRB_configList2[xid]; + if (*DRB_configList2) { + free(*DRB_configList2); + } + *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2)); + memset(*DRB_configList2, 0, sizeof(**DRB_configList2)); + + + /// DRB + DRB_config = CALLOC(1, sizeof(*DRB_config)); + + DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long)); + *(DRB_config->eps_BearerIdentity) = 5L; // LW set to first value, allowed value 5..15, value : x+4 + // DRB_config->drb_Identity = (DRB_Identity_t) 1; //allowed values 1..32 + // NN: this is the 1st DRB for this ue, so set it to 1 + DRB_config->drb_Identity = (DRB_Identity_t) 1; // (ue_mod_idP+1); //allowed values 1..32, value: x + DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long)); + *(DRB_config->logicalChannelIdentity) = (long)3; // value : x+2 + DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config)); + DRB_config->rlc_Config = DRB_rlc_config; + +#ifdef RRC_DEFAULT_RAB_IS_AM + DRB_rlc_config->present = RLC_Config_PR_am; + DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = T_PollRetransmit_ms50; + DRB_rlc_config->choice.am.ul_AM_RLC.pollPDU = PollPDU_p16; + DRB_rlc_config->choice.am.ul_AM_RLC.pollByte = PollByte_kBinfinity; + DRB_rlc_config->choice.am.ul_AM_RLC.maxRetxThreshold = UL_AM_RLC__maxRetxThreshold_t8; + DRB_rlc_config->choice.am.dl_AM_RLC.t_Reordering = T_Reordering_ms35; + DRB_rlc_config->choice.am.dl_AM_RLC.t_StatusProhibit = T_StatusProhibit_ms25; +#else + DRB_rlc_config->present = RLC_Config_PR_um_Bi_Directional; + DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = SN_FieldLength_size10; +#ifdef CBA + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = T_Reordering_ms5;//T_Reordering_ms25; +#else + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = T_Reordering_ms35; +#endif +#endif + + DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); + DRB_config->pdcp_Config = DRB_pdcp_config; + DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); + *DRB_pdcp_config->discardTimer = PDCP_Config__discardTimer_infinity; + DRB_pdcp_config->rlc_AM = NULL; + DRB_pdcp_config->rlc_UM = NULL; + + /* avoid gcc warnings */ + (void)PDCP_rlc_AM; + (void)PDCP_rlc_UM; + +#ifdef RRC_DEFAULT_RAB_IS_AM // EXMIMO_IOT + PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM)); + DRB_pdcp_config->rlc_AM = PDCP_rlc_AM; + PDCP_rlc_AM->statusReportRequired = FALSE; +#else + PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM)); + DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; + PDCP_rlc_UM->pdcp_SN_Size = PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; +#endif + DRB_pdcp_config->headerCompression.present = PDCP_Config__headerCompression_PR_notUsed; + + DRB_lchan_config = CALLOC(1, sizeof(*DRB_lchan_config)); + DRB_config->logicalChannelConfig = DRB_lchan_config; + DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters)); + DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters; + + DRB_ul_SpecificParameters->priority = 12; // lower priority than srb1, srb2 and other dedicated bearer + DRB_ul_SpecificParameters->prioritisedBitRate =LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; + //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + DRB_ul_SpecificParameters->bucketSizeDuration = + LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + + // LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM) + logicalchannelgroup_drb = CALLOC(1, sizeof(long)); + *logicalchannelgroup_drb = 1; + DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; + + ASN_SEQUENCE_ADD(&(*DRB_configList)->list, DRB_config); + ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config); + + //ue_context_pP->ue_context.DRB_configList2[0] = &(*DRB_configList); + + mac_MainConfig = CALLOC(1, sizeof(*mac_MainConfig)); + // ue_context_pP->ue_context.mac_MainConfig = mac_MainConfig; + + mac_MainConfig->ul_SCH_Config = CALLOC(1, sizeof(*mac_MainConfig->ul_SCH_Config)); + + maxHARQ_Tx = CALLOC(1, sizeof(long)); + *maxHARQ_Tx = MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; + mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx; + periodicBSR_Timer = CALLOC(1, sizeof(long)); + *periodicBSR_Timer = PeriodicBSR_Timer_r12_sf64; + mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer; + mac_MainConfig->ul_SCH_Config->retxBSR_Timer = RetxBSR_Timer_r12_sf320; + mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE + + mac_MainConfig->timeAlignmentTimerDedicated = TimeAlignmentTimer_infinity; + + mac_MainConfig->drx_Config = NULL; + + mac_MainConfig->phr_Config = CALLOC(1, sizeof(*mac_MainConfig->phr_Config)); + + mac_MainConfig->phr_Config->present = MAC_MainConfig__phr_Config_PR_setup; + mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; // sf20 = 20 subframes + + mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; // sf20 = 20 subframes + + mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; // Value dB1 =1 dB, dB3 = 3 dB + +#ifdef Rel10 + sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long)); + *sr_ProhibitTimer_r9 = 0; // SR tx on PUCCH, Value in number of SR period(s). Value 0 = no timer for SR, Value 2= 2*SR + mac_MainConfig->ext1 = CALLOC(1, sizeof(struct MAC_MainConfig__ext1)); + mac_MainConfig->ext1->sr_ProhibitTimer_r9 = sr_ProhibitTimer_r9; + //sps_RA_ConfigList_rlola = NULL; +#endif + + //change the transmission mode for the primary component carrier + //TODO: add codebook subset restriction here + //TODO: change TM for secondary CC in SCelltoaddmodlist + if (*physicalConfigDedicated) { + if ((*physicalConfigDedicated)->antennaInfo) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.transmissionMode = rrc_inst->configuration.ue_TransmissionMode[0]; + LOG_D(RRC,"Setting transmission mode to %ld+1\n",rrc_inst->configuration.ue_TransmissionMode[0]); + if (rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm3) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= + CALLOC(1,sizeof(AntennaInfoDedicated__codebookSubsetRestriction_PR)); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = + AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm3; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf= MALLOC(1); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf[0] = 0xc0; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.size=1; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.bits_unused=6; + } + else if (rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm4) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= + CALLOC(1,sizeof(AntennaInfoDedicated__codebookSubsetRestriction_PR)); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = + AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm4; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf= MALLOC(1); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf[0] = 0xfc; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.size=1; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.bits_unused=2; + + } + else if (rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm5) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= + CALLOC(1,sizeof(AntennaInfoDedicated__codebookSubsetRestriction_PR)); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = + AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm5; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf= MALLOC(1); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf[0] = 0xf0; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.size=1; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.bits_unused=4; + } + else if (rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm6) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= + CALLOC(1,sizeof(AntennaInfoDedicated__codebookSubsetRestriction_PR)); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = + AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm6; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf= MALLOC(1); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf[0] = 0xf0; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.size=1; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.bits_unused=4; + } + } + else { + LOG_E(RRC,"antenna_info not present in physical_config_dedicated. Not reconfiguring!\n"); + } + if ((*physicalConfigDedicated)->cqi_ReportConfig) { + if ((rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm4) || + (rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm5) || + (rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm6)) { + //feedback mode needs to be set as well + //TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable + printf("setting cqi reporting mode to rm31\n"); +#if defined(Rel10) || defined(Rel14) + *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=CQI_ReportModeAperiodic_rm31; +#else + *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=CQI_ReportConfig__cqi_ReportModeAperiodic_rm31; // HLC CQI, no PMI +#endif + } + } + else { + LOG_E(RRC,"cqi_ReportConfig not present in physical_config_dedicated. Not reconfiguring!\n"); + } + } + else { + LOG_E(RRC,"physical_config_dedicated not present in RRCConnectionReconfiguration. Not reconfiguring!\n"); + } + + // Measurement ID list + MeasId_list = CALLOC(1, sizeof(*MeasId_list)); + memset((void *)MeasId_list, 0, sizeof(*MeasId_list)); + + MeasId0 = CALLOC(1, sizeof(*MeasId0)); + MeasId0->measId = 1; + MeasId0->measObjectId = 1; + MeasId0->reportConfigId = 1; + ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId0); + + /* + * Add one EUTRA Measurement Object + */ + + MeasObj_list = CALLOC(1, sizeof(*MeasObj_list)); + memset((void *)MeasObj_list, 0, sizeof(*MeasObj_list)); + + // Configure MeasObject + + MeasObj = CALLOC(1, sizeof(*MeasObj)); + memset((void *)MeasObj, 0, sizeof(*MeasObj)); + + MeasObj->measObjectId = 1; + MeasObj->measObject.present = MeasObjectToAddMod__measObject_PR_measObjectEUTRA; + MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 3350; //band 7, 2.68GHz + //MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 36090; //band 33, 1.909GHz + MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = AllowedMeasBandwidth_mbw25; + MeasObj->measObject.choice.measObjectEUTRA.presenceAntennaPort1 = 1; + MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf = CALLOC(1, sizeof(uint8_t)); + MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf[0] = 0; + MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.size = 1; + MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.bits_unused = 6; + MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = NULL; // Default is 15 or 0dB + + MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList = + (CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList)); + + CellsToAddModList = MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList; + + // Add adjacent cell lists (6 per eNB) + for (i = 0; i < 6; i++) { + CellToAdd = (CellsToAddMod_t *) CALLOC(1, sizeof(*CellToAdd)); + CellToAdd->cellIndex = i + 1; + CellToAdd->physCellId = get_adjacent_cell_id(ctxt_pP->module_id, i); + CellToAdd->cellIndividualOffset = Q_OffsetRange_dB0; + + ASN_SEQUENCE_ADD(&CellsToAddModList->list, CellToAdd); + } + + ASN_SEQUENCE_ADD(&MeasObj_list->list, MeasObj); + // rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measObjectToAddModList = MeasObj_list; + + // Report Configurations for periodical, A1-A5 events + + /* RRC Strategy Measurement */ + + + if (strcmp("one_shot", trig_param->trigger_policy) == 0){ + + trig_param->report_interval = 0; + trig_param->report_amount = 0; + + } + + else if (strcmp("event_driven", trig_param->trigger_policy) == 0){ + + trig_param->report_interval = 6; + trig_param->report_amount = 2; + + } + + else if (strcmp("periodical", trig_param->trigger_policy) == 0){ + + trig_param->report_interval = 1; + trig_param->report_amount = 7; + + } + + else { + + LOG_E(FLEXRAN_AGENT, "There is something wrong on RRC agent!"); + } + + + + ReportConfig_list = CALLOC(1, sizeof(*ReportConfig_list)); + + ReportConfig_per = CALLOC(1, sizeof(*ReportConfig_per)); + + // Periodical Measurement Report + + ReportConfig_per->reportConfigId = 1; + ReportConfig_per->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; + + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.present = + ReportConfigEUTRA__triggerType_PR_periodical; + + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.choice.periodical.purpose = + ReportConfigEUTRA__triggerType__periodical__purpose_reportStrongestCells; + + // ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger = TimeToTrigger_ms40; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerQuantity = ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportInterval = trig_param->report_interval ;//ReportInterval_ms2048; // RRC counter frame- ms1024 is 1ms + + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportAmount = trig_param->report_amount; //ReportConfigEUTRA__reportAmount_r2; // put r1 to see once, r2 for 2 times and ... + + + ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_per); + + + + quantityConfig = CALLOC(1, sizeof(*quantityConfig)); + memset((void *)quantityConfig, 0, sizeof(*quantityConfig)); + quantityConfig->quantityConfigEUTRA = CALLOC(1, sizeof(struct QuantityConfigEUTRA)); + memset((void *)quantityConfig->quantityConfigEUTRA, 0, sizeof(*quantityConfig->quantityConfigEUTRA)); + quantityConfig->quantityConfigCDMA2000 = NULL; + quantityConfig->quantityConfigGERAN = NULL; + quantityConfig->quantityConfigUTRA = NULL; + quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = + CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP))); + quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = + CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ))); + *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = FilterCoefficient_fc4; + *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = FilterCoefficient_fc4; + + +#if defined(ENABLE_ITTI) + /* Initialize NAS list */ + dedicatedInfoNASList = CALLOC(1, sizeof(struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); + + /* Add all NAS PDUs to the list */ + for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) { + if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) { + dedicatedInfoNas = CALLOC(1, sizeof(DedicatedInfoNAS_t)); + memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t)); + OCTET_STRING_fromBuf(dedicatedInfoNas, + (char*)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer, + ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length); + ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas); + } + + /* TODO parameters yet to process ... */ + // { + // ue_context_pP->ue_context.e_rab[i].param.qos; + // ue_context_pP->ue_context.e_rab[i].param.sgw_addr; + // ue_context_pP->ue_context.e_rab[i].param.gtp_teid; + // } + + /* TODO should test if e RAB are Ok before! */ + ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE; + LOG_D(RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", + i, ue_context_pP->ue_context.e_rab[i].status, "E_RAB_STATUS_DONE"); + } + + /* If list is empty free the list and reset the address */ + if (dedicatedInfoNASList->list.count == 0) { + free(dedicatedInfoNASList); + dedicatedInfoNASList = NULL; + } + +#endif + + memset(buffer, 0, RRC_BUF_SIZE); + + size = do_RRCConnectionReconfiguration(ctxt_pP, + buffer, + xid, //Transaction_id, + (SRB_ToAddModList_t*)NULL, // SRB_configList + (DRB_ToAddModList_t*)NULL, + (DRB_ToReleaseList_t*)NULL, // DRB2_list, + (struct SPS_Config*)NULL, // *sps_Config, + (struct PhysicalConfigDedicated*)*physicalConfigDedicated, +// #ifdef EXMIMO_IOT +// NULL, NULL, NULL,NULL, +// #else + (MeasObjectToAddModList_t*)MeasObj_list, + (ReportConfigToAddModList_t*)ReportConfig_list, + (QuantityConfig_t*)quantityConfig, + (MeasIdToAddModList_t*)MeasId_list, +// #endif + (MAC_MainConfig_t*)mac_MainConfig, + (MeasGapConfig_t*)NULL, + (MobilityControlInfo_t*)NULL, + (struct MeasConfig__speedStatePars*)Sparams, + (RSRP_Range_t*)rsrp, + (C_RNTI_t*)cba_RNTI, + (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList +#if defined(Rel10) || defined(Rel14) + , (SCellToAddMod_r10_t*)NULL +#endif + ); + +#ifdef RRC_MSG_PRINT + LOG_F(RRC,"[MSG] RRC Connection Reconfiguration\n"); + for (i = 0; i < size; i++) { + LOG_F(RRC,"%02x ", ((uint8_t*)buffer)[i]); + } + LOG_F(RRC,"\n"); + //////////////////////////////////////// +#endif + +#if defined(ENABLE_ITTI) + + /* Free all NAS PDUs */ + for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) { + if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) { + /* Free the NAS PDU buffer and invalidate it */ + free(ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer); + ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer = NULL; + } + } + +#endif + + LOG_I(RRC, + "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCConnectionReconfiguration (bytes %d, UE id %x)\n", + ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); + + LOG_D(RRC, + "[FRAME %05d][RRC_eNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", + ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_eNB_mui, ctxt_pP->module_id, DCCH); + + MSC_LOG_TX_MESSAGE( + MSC_RRC_ENB, + MSC_RRC_UE, + buffer, + size, + MSC_AS_TIME_FMT" rrcConnectionReconfiguration UE %x MUI %d size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_context.rnti, + rrc_eNB_mui, + size); + + rrc_data_req( + ctxt_pP, + DCCH, + rrc_eNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); +} + + + //----------------------------------------------------------------------------- int @@ -2246,41 +2838,41 @@ rrc_eNB_process_MeasurementReport( ) //----------------------------------------------------------------------------- { - T(T_ENB_RRC_MEASUREMENT_REPORT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + // T(T_ENB_RRC_MEASUREMENT_REPORT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + // T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - LOG_I(RRC, "[eNB %d] Frame %d: Process Measurement Report From UE %x (Measurement Id %d)\n", - ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rnti, (int)measResults2->measId); + // LOG_I(RRC, "[eNB %d] Frame %d: Process Measurement Report From UE %x (Measurement Id %d)\n", + // ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rnti, (int)measResults2->measId); - if (measResults2->measResultNeighCells->choice.measResultListEUTRA.list.count > 0) { - LOG_I(RRC, "Physical Cell Id %d\n", - (int)measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]->physCellId); - LOG_I(RRC, "RSRP of Target %d\n", - (int)*(measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]-> - measResult.rsrpResult)); - LOG_I(RRC, "RSRQ of Target %d\n", - (int)*(measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]-> - measResult.rsrqResult)); - } + // if (measResults2->measResultNeighCells->choice.measResultListEUTRA.list.count > 0) { + // LOG_I(RRC, "Physical Cell Id %d\n", + // (int)measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]->physCellId); + // LOG_I(RRC, "RSRP of Target %d\n", + // (int)*(measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]-> + // measResult.rsrpResult)); + // LOG_I(RRC, "RSRQ of Target %d\n", + // (int)*(measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]-> + // measResult.rsrqResult)); + // } -#if defined(Rel10) || defined(Rel14) +// #if defined(Rel10) || defined(Rel14) LOG_I(RRC, "RSRP of Source %ld\n", measResults2->measResultPCell.rsrpResult); LOG_I(RRC, "RSRQ of Source %ld\n", measResults2->measResultPCell.rsrqResult); -#else - LOG_I(RRC, "RSRP of Source %d\n", measResults2->measResultServCell.rsrpResult); - LOG_I(RRC, "RSRQ of Source %d\n", measResults2->measResultServCell.rsrqResult); -#endif +// #else + // LOG_I(RRC, "RSRP of Source %d\n", measResults2->measResultServCell.rsrpResult); + // LOG_I(RRC, "RSRQ of Source %d\n", measResults2->measResultServCell.rsrqResult); +// #endif - if (ue_context_pP->ue_context.handover_info->ho_prepare != 0xF0) { - rrc_eNB_generate_HandoverPreparationInformation(ctxt_pP, - ue_context_pP, - measResults2->measResultNeighCells->choice. - measResultListEUTRA.list.array[0]->physCellId); - } else { - LOG_D(RRC, "[eNB %d] Frame %d: Ignoring MeasReport from UE %x as Handover is in progress... \n", ctxt_pP->module_id, ctxt_pP->frame, - ctxt_pP->rnti); - } + // if (ue_context_pP->ue_context.handover_info->ho_prepare != 0xF0) { + // rrc_eNB_generate_HandoverPreparationInformation(ctxt_pP, + // ue_context_pP, + // measResults2->measResultNeighCells->choice. + // measResultListEUTRA.list.array[0]->physCellId); + // } else { + // LOG_D(RRC, "[eNB %d] Frame %d: Ignoring MeasReport from UE %x as Handover is in progress... \n", ctxt_pP->module_id, ctxt_pP->frame, + // ctxt_pP->rnti); + // } //Look for IP address of the target eNB //Send Handover Request -> target eNB @@ -4501,6 +5093,13 @@ rrc_eNB_decode_dcch( ue_context_p, &ul_dcch_msg->message.choice.c1.choice.measurementReport. criticalExtensions.choice.c1.choice.measurementReport_r8.measResults); + #if defined(FLEXRAN_AGENT_SB_IF) + + if (rrc_agent_registered[ctxt_pP->module_id]) { + agent_rrc_xface[ctxt_pP->eNB_index]->flexran_trigger_rrc_measurements (ctxt_pP->module_id, &ul_dcch_msg->message.choice.c1.choice.measurementReport.criticalExtensions.choice.c1.choice.measurementReport_r8.measResults); + } +#endif + break; case UL_DCCH_MessageType__c1_PR_rrcConnectionReconfigurationComplete: @@ -4553,8 +5152,8 @@ rrc_eNB_decode_dcch( #if defined(FLEXRAN_AGENT_SB_IF) //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future - if (mac_agent_registered[ctxt_pP->module_id]) { - agent_mac_xface[ctxt_pP->eNB_index]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, + if (rrc_agent_registered[ctxt_pP->module_id]) { + agent_rrc_xface[ctxt_pP->eNB_index]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, ue_context_p->ue_id_rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_UPDATED); } @@ -4657,8 +5256,8 @@ rrc_eNB_decode_dcch( #if defined(FLEXRAN_AGENT_SB_IF) //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future - if (mac_agent_registered[ctxt_pP->module_id]) { - agent_mac_xface[ctxt_pP->eNB_index]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, + if (rrc_agent_registered[ctxt_pP->module_id]) { + agent_rrc_xface[ctxt_pP->eNB_index]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, ue_context_p->ue_id_rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED); } From 714ad4d774a665bc288425d47dcf2ba2f9e2d7cc Mon Sep 17 00:00:00 2001 From: shahab SHARIATBAGHERI Date: Wed, 5 Apr 2017 16:48:21 +0200 Subject: [PATCH 005/195] Warning Decreasing --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 15 +++++++------- .../CONTROL_MODULES/RRC/flexran_agent_rrc.c | 16 +++++++-------- .../CONTROL_MODULES/RRC/flexran_agent_rrc.h | 6 +++--- .../RRC/flexran_agent_rrc_defs.h | 4 +++- openair2/ENB_APP/flexran_agent.c | 2 +- openair2/ENB_APP/flexran_agent.h | 5 ++++- openair2/ENB_APP/flexran_agent_common.c | 1 + openair2/ENB_APP/flexran_agent_common.h | 14 ++++++------- openair2/ENB_APP/flexran_agent_handler.c | 5 +++-- openair2/ENB_APP/flexran_agent_ran_api.c | 20 ++++++++++++++----- openair2/ENB_APP/flexran_agent_ran_api.h | 13 +++++++++++- .../MAC/flexran_agent_scheduler_dlsch_ue.c | 2 +- .../flexran_agent_scheduler_dlsch_ue_remote.c | 2 +- openair2/RRC/LITE/rrc_eNB.c | 6 +++--- 14 files changed, 70 insertions(+), 41 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 01df6248f1..ba69308553 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -32,6 +32,7 @@ #include "flexran_agent_mac_internal.h" #include "flexran_agent_net_comm.h" #include "flexran_agent_timer.h" +#include "flexran_agent_ran_api.h" #include "LAYER2/MAC/proto.h" #include "LAYER2/MAC/flexran_agent_mac_proto.h" @@ -63,7 +64,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, // Protocol__FlexHeader *header; int i, j, k; - int cc_id = 0; + // int cc_id = 0; int enb_id = mod_id; /* Allocate memory for list of UE reports */ @@ -141,11 +142,11 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, /* Check flag for creation of MAC CE buffer status report */ if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_CE_BS) { // TODO: Fill in the actual MAC CE buffer status report - ue_report[i]->pending_mac_ces = (flexran_get_MAC_CE_bitmap_TA(enb_id,i,0) | (0 << 1) | (0 << 2) - | (0 << 3)) & 15; /* Use as bitmap. Set one or more of the; /* Use as bitmap. Set one or more of the - PROTOCOL__FLEX_CE_TYPE__FLPCET_ values - found in stats_common.pb-c.h. See - flex_ce_type in FlexRAN specification */ + ue_report[i]->pending_mac_ces = (flexran_get_MAC_CE_bitmap_TA(enb_id,i,0) | (0 << 1) | (0 << 2) | (0 << 3)) & 15; + // Use as bitmap. Set one or more of the; /* Use as bitmap. Set one or more of the + // PROTOCOL__FLEX_CE_TYPE__FLPCET_ values + // found in stats_common.pb-c.h. See + // flex_ce_type in FlexRAN specification ue_report[i]->has_pending_mac_ces = 1; } @@ -213,7 +214,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, goto error; protocol__flex_csi_p11__init(csi11); - csi11->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + csi11->wb_cqi = flexran_get_ue_wcqi (enb_id, i); // According To spec 36.213 if (flexran_get_antenna_ports(enb_id, j) == 2 && csi_reports[j]->ri == 1) { diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c index 9475b06643..d48d12d670 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c @@ -61,12 +61,12 @@ void flexran_agent_init_rrc_agent(mid_t mod_id) { -int flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_change) { +void flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_change) { int size; Protocol__FlexranMessage *msg; Protocol__FlexHeader *header; void *data; - int priority; + int priority = 0; err_code_t err_code; int xid = 0; @@ -258,7 +258,7 @@ int flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_cha LOG_D(FLEXRAN_AGENT,"sent message with size %d\n", size); return; error: - LOG_D(FLEXRAN_AGENT, "Could not send UE state message\n"); + LOG_E(FLEXRAN_AGENT, "Could not send UE state message becasue of %d \n",err_code); } @@ -278,10 +278,10 @@ int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg) { } /* this is called by RRC as a part of rrc xface . The controller previously requested this*/ -int flexran_trigger_rrc_measurements (mid_t mod_id, MeasResults_t* measResults) { +void flexran_trigger_rrc_measurements (mid_t mod_id, MeasResults_t* measResults) { // int i, m, k; - int priority; + int priority = 0; // Warning Preventing void *data; int size; err_code_t err_code; @@ -618,16 +618,16 @@ int flexran_trigger_rrc_measurements (mid_t mod_id, MeasResults_t* measResults) LOG_I(FLEXRAN_AGENT,"RRC Trigger is done \n"); - return 0; + return; error: - LOG_E(RRC, "Error triggering RRC measurements message!"); + LOG_E(FLEXRAN_AGENT, "Could not send UE state message becasue of %d \n",err_code); /* Free the measurement report received from UE. */ // ASN_STRUCT_FREE(asn_DEF_MeasResults, p->meas); /* Free the params. */ // free(p); - return -1; + // return -1; } diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h index 17b58dac93..aa210f9d41 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h @@ -41,7 +41,7 @@ #include "flexran.pb-c.h" #include "stats_messages.pb-c.h" #include "stats_common.pb-c.h" -#include "MeasResults.h" + #include "flexran_agent_common.h" #include "flexran_agent_rrc_defs.h" @@ -51,7 +51,7 @@ void flexran_agent_init_rrc_agent(mid_t mod_id); /* UE state change message constructor and destructor */ -int flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_change); +void flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_change); int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg); @@ -63,7 +63,7 @@ int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg); // void flexran_agent_send_update_rrc_stats(mid_t mod_id); /* this is called by RRC as a part of rrc xface . The controller previously requested this*/ -int flexran_trigger_rrc_measurements (mid_t mod_id, MeasResults_t *); +void flexran_trigger_rrc_measurements (mid_t mod_id, MeasResults_t *); /*Register technology specific interface callbacks*/ int flexran_agent_register_rrc_xface(mid_t mod_id, AGENT_RRC_xface *xface); diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h index 10fc4ba254..679bc4d623 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h @@ -38,9 +38,11 @@ #ifndef __FLEXRAN_AGENT_RRC_PRIMITIVES_H__ #define __FLEXRAN_AGENT_RRC_PRIMITIVES_H__ +#include "PHY/extern.h" #include "flexran_agent_defs.h" #include "flexran.pb-c.h" #include "header.pb-c.h" +#include "MeasResults.h" #define RINGBUFFER_SIZE 100 @@ -55,7 +57,7 @@ typedef struct { void (*flexran_agent_notify_ue_state_change)(mid_t mod_id, uint32_t rnti, uint32_t state_change); - void (*flexran_trigger_rrc_measurements)(mid_t mod_id, MeasResults_t* measResults) + void (*flexran_trigger_rrc_measurements)(mid_t mod_id, MeasResults_t* measResults); } AGENT_RRC_xface; diff --git a/openair2/ENB_APP/flexran_agent.c b/openair2/ENB_APP/flexran_agent.c index d96076df83..ec984cfa8b 100644 --- a/openair2/ENB_APP/flexran_agent.c +++ b/openair2/ENB_APP/flexran_agent.c @@ -264,7 +264,7 @@ int flexran_agent_start(mid_t mod_id, const Enb_properties_array_t* enb_properti AGENT_MAC_xface *mac_agent_xface = (AGENT_MAC_xface *) malloc(sizeof(AGENT_MAC_xface)); flexran_agent_register_mac_xface(mod_id, mac_agent_xface); - AGENT_RRC_xface *rrc_agent_xface = (AGENT_MAC_xface *) malloc(sizeof(AGENT_MAC_xface)); + AGENT_RRC_xface *rrc_agent_xface = (AGENT_RRC_xface *) malloc(sizeof(AGENT_RRC_xface)); flexran_agent_register_rrc_xface(mod_id, rrc_agent_xface); /* diff --git a/openair2/ENB_APP/flexran_agent.h b/openair2/ENB_APP/flexran_agent.h index aec4f004a8..0ef48e2105 100644 --- a/openair2/ENB_APP/flexran_agent.h +++ b/openair2/ENB_APP/flexran_agent.h @@ -34,7 +34,10 @@ #include "flexran_agent_extern.h" #include "flexran_agent_timer.h" #include "flexran_agent_defs.h" - +#include "flexran_agent_net_comm.h" +#include "flexran_agent_ran_api.h" +#include "flexran_agent_mac.h" +#include "flexran_agent_rrc.h" #include "log.h" #include "assertions.h" diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index 7d9cfe685c..27364a7eaa 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -33,6 +33,7 @@ #include "flexran_agent_common_internal.h" #include "flexran_agent_extern.h" #include "flexran_agent_net_comm.h" +#include "flexran_agent_ran_api.h" #include "PHY/extern.h" #include "log.h" diff --git a/openair2/ENB_APP/flexran_agent_common.h b/openair2/ENB_APP/flexran_agent_common.h index 4f2b9c71bb..d96712622f 100644 --- a/openair2/ENB_APP/flexran_agent_common.h +++ b/openair2/ENB_APP/flexran_agent_common.h @@ -37,7 +37,8 @@ #include "flexran.pb-c.h" #include "stats_messages.pb-c.h" #include "stats_common.pb-c.h" - +#include "flexran_agent_ran_api.h" +#include "flexran_agent_net_comm.h" #include "flexran_agent_defs.h" #include "enb_config.h" @@ -156,16 +157,15 @@ int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__Flexr /* Function to be used to handle reply message . */ int flexran_agent_stats_reply(mid_t enb_id, xid_t xid, const report_config_t *report_config, Protocol__FlexranMessage **msg); -/* Statistics request protocol message constructor and destructor */ +/* Top level Statistics request protocol message constructor and destructor */ int flexran_agent_stats_request(mid_t mod_id, xid_t xid, const stats_request_config_t *report_config, Protocol__FlexranMessage **msg); int flexran_agent_destroy_stats_request(Protocol__FlexranMessage *msg); -int flexran_agent_stats_request(mid_t mod_id, xid_t xid, const stats_request_config_t *report_config, Protocol__FlexranMessage **msg); -int flexran_agent_destroy_stats_request(Protocol__FlexranMessage *msg); - +err_code_t flexran_agent_init_cont_stats_update(mid_t mod_id); + +void flexran_agent_send_update_stats(mid_t mod_id); + err_code_t flexran_agent_enable_cont_stats_update(mid_t mod_id, xid_t xid, stats_request_config_t *stats_req) ; -int flexran_agent_stats_request(mid_t mod_id, xid_t xid, const stats_request_config_t *report_config, Protocol__FlexranMessage **msg); - #endif diff --git a/openair2/ENB_APP/flexran_agent_handler.c b/openair2/ENB_APP/flexran_agent_handler.c index b57039bec5..84948d1eee 100644 --- a/openair2/ENB_APP/flexran_agent_handler.c +++ b/openair2/ENB_APP/flexran_agent_handler.c @@ -31,6 +31,7 @@ #include "flexran_agent_mac.h" #include "flexran_agent_rrc.h" #include "flexran_agent_timer.h" +#include "flexran_agent_ran_api.h" #include "log.h" #include "assertions.h" @@ -96,7 +97,7 @@ Protocol__FlexranMessage* flexran_agent_handle_message (mid_t mod_id, err_code= PROTOCOL__FLEXRAN_ERR__MSG_DECODING; goto error; } - printf("==================> %d %d \n", decoded_message->msg_case, decoded_message->msg_dir); + //printf("==================> %d %d \n", decoded_message->msg_case, decoded_message->msg_dir); if ((decoded_message->msg_case > sizeof(agent_messages_callback) / (3 * sizeof(flexran_agent_message_decoded_callback))) || (decoded_message->msg_dir > PROTOCOL__FLEXRAN_DIRECTION__UNSUCCESSFUL_OUTCOME)){ err_code= PROTOCOL__FLEXRAN_ERR__MSG_NOT_HANDLED; @@ -754,4 +755,4 @@ err_code_t flexran_agent_destroy_cont_stats_update(mid_t mod_id) { // mac_agent_registered[mod_id] = 0; return 1; -} \ No newline at end of file +} diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 17a53c7eb0..dd3e8a4bcb 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -152,11 +152,21 @@ int flexran_get_ue_wcqi (mid_t mod_id, mid_t ue_id) { // return ((UE_list_t *)enb_ue[mod_id])->eNB_UE_stats[UE_PCCID(mod_id,ue_id)][ue_id].dl_cqi; } -int flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) { +int flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id, char * buffer_status) { rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); uint16_t frame = (uint16_t) flexran_get_current_frame(mod_id); - mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id,frame,ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0); - return rlc_status.bytes_in_buffer; + mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id,frame,ENB_FLAG_YES,MBMS_FLAG_NO,channel_id,0); + + if (strcmp(buffer_status, "bytes_buffer")){ + return rlc_status.bytes_in_buffer; + } else if(strcmp(buffer_status, "pdu_buffer")) { + return rlc_status.pdus_in_buffer; + } + /* else if (strcmp(buffer_status, "head_line")){ */ + + /* return rlc_status.head_sdu_remaining_size_to_send; */ + + /* } */ } int flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) { @@ -168,7 +178,7 @@ int flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_i short flexran_get_TA(mid_t mod_id, mid_t ue_id, int CC_id) { - UE_list_t *UE_list=&eNB_mac_inst[mod_id].UE_list; + // UE_list_t *UE_list=&eNB_mac_inst[mod_id].UE_list; int rnti; rnti = flexran_get_ue_crnti(mod_id, ue_id); @@ -227,7 +237,7 @@ void flexran_update_TA(mid_t mod_id, mid_t ue_id, int CC_id) { int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id,int CC_id) { - UE_list_t *UE_list = &eNB_mac_inst[mod_id].UE_list; + // UE_list_t *UE_list = &eNB_mac_inst[mod_id].UE_list; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id,CC_id,rnti); diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 12962a1f9d..4a893a4c96 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -89,7 +89,7 @@ int flexran_get_ue_phr (mid_t mod_id, mid_t ue_id); int flexran_get_ue_wcqi (mid_t mod_id, mid_t ue_id); /* Get the transmission queue size for a UE with a channel_id logical channel id */ -int flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id); +int flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id, char * buffer_status); /* Get the head of line delay for a UE with a channel_id logical channel id */ int flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id); @@ -198,6 +198,17 @@ int flexran_get_p0_pucch_status(mid_t mod_id, mid_t ue_id, int CC_id); int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, int CC_id); +int flexran_get_hopping_mode(mid_t mod_id, int CC_id); + +int flexran_get_hopping_offset(mid_t mod_id, int CC_id); + +int flexran_get_n_SB(mid_t mod_id, int CC_id); + +int flexran_get_phich_resource(mid_t mod_id, int CC_id); + +int flexran_get_enable64QAM(mid_t mod_id, int CC_id); + +int flexran_get_phich_duration(mid_t mod_id, int CC_id); /* * ************************************ diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c index 00027f04ce..953de903c4 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c @@ -50,7 +50,7 @@ #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" #include "ENB_APP/flexran_agent_defs.h" - +#include "flexran_agent_ran_api.h" #include "pdcp.h" #include "header.pb-c.h" diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue_remote.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue_remote.c index 7dec8d0c56..bff461acc7 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue_remote.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue_remote.c @@ -30,7 +30,7 @@ */ #include "flexran_agent_common_internal.h" - +#include "flexran_agent_ran_api.h" #include "flexran_agent_scheduler_dlsch_ue_remote.h" #include "LAYER2/MAC/defs.h" diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index 6247548bcc..1f2bf2d262 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -2198,10 +2198,10 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt MeasObjectToAddModList_t *MeasObj_list = NULL; MeasObjectToAddMod_t *MeasObj = NULL; ReportConfigToAddModList_t *ReportConfig_list = NULL; - ReportConfigToAddMod_t *ReportConfig_per, *ReportConfig_A1, - *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5; + ReportConfigToAddMod_t *ReportConfig_per;//, *ReportConfig_A1, + // *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5; MeasIdToAddModList_t *MeasId_list = NULL; - MeasIdToAddMod_t *MeasId0, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5; + MeasIdToAddMod_t *MeasId0; //, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5; #if Rel10 long *sr_ProhibitTimer_r9 = NULL; // uint8_t sCellIndexToAdd = rrc_find_free_SCell_index(enb_mod_idP, ue_mod_idP, 1); From 77c4d3742f884039d7d228b05cf36e5fc2ca269d Mon Sep 17 00:00:00 2001 From: shahab SHARIATBAGHERI Date: Fri, 7 Apr 2017 11:28:51 +0200 Subject: [PATCH 006/195] Wanring Preventing remote-sch --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 10 +++++----- .../CONTROL_MODULES/MAC/flexran_agent_mac_defs.h | 6 +++--- .../CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h | 2 +- openair2/ENB_APP/flexran_agent_common.h | 2 +- openair2/ENB_APP/flexran_agent_handler.c | 4 ++-- openair2/ENB_APP/flexran_agent_ran_api.c | 16 +++------------- openair2/ENB_APP/flexran_agent_ran_api.h | 2 +- 7 files changed, 16 insertions(+), 26 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index ba69308553..d22633a818 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -115,11 +115,11 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, protocol__flex_rlc_bsr__init(rlc_reports[j]); rlc_reports[j]->lc_id = j+1; rlc_reports[j]->has_lc_id = 1; - rlc_reports[j]->tx_queue_size = flexran_get_tx_queue_size(enb_id, i, j + 1, "bytes_buffer"); + rlc_reports[j]->tx_queue_size = flexran_get_tx_queue_size(enb_id, i, j + 1); rlc_reports[j]->has_tx_queue_size = 1; //TODO:Set tx queue head of line delay in ms - rlc_reports[j]->tx_queue_hol_delay = flexran_get_tx_queue_size(enb_id, i, j + 1, "head_line"); + rlc_reports[j]->tx_queue_hol_delay = flexran_get_hol_delay(enb_id, i, j + 1); rlc_reports[j]->has_tx_queue_hol_delay = 1; //TODO:Set retransmission queue size in bytes rlc_reports[j]->retransmission_queue_size = 10; @@ -128,7 +128,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, rlc_reports[j]->retransmission_queue_hol_delay = 100; rlc_reports[j]->has_retransmission_queue_hol_delay = 0; //TODO DONE:Set current size of the pending message in bytes - rlc_reports[j]->status_pdu_size = flexran_get_hol_delay(enb_id, i, j + 1); + rlc_reports[j]->status_pdu_size = flexran_get_tx_queue_size(enb_id, i, j + 1); rlc_reports[j]->has_status_pdu_size = 1; } @@ -1174,8 +1174,8 @@ int flexran_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { xface->flexran_agent_send_sr_info = flexran_agent_send_sr_info; xface->flexran_agent_send_sf_trigger = flexran_agent_send_sf_trigger; //xface->flexran_agent_send_update_mac_stats = flexran_agent_send_update_mac_stats; - xface->flexran_agent_schedule_ue_spec = flexran_schedule_ue_spec_default; - //xface->flexran_agent_schedule_ue_spec = flexran_schedule_ue_spec_remote; + // xface->flexran_agent_schedule_ue_spec = flexran_schedule_ue_spec_default; + xface->flexran_agent_schedule_ue_spec = flexran_schedule_ue_spec_remote; xface->flexran_agent_get_pending_dl_mac_config = flexran_agent_get_pending_dl_mac_config; xface->dl_scheduler_loaded_lib = NULL; diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h index 9ec8594f88..8354223123 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h @@ -48,7 +48,7 @@ typedef struct { /// Send to the controller all the mac stat updates that occured during this subframe /// based on the stats request configuration - void (*flexran_agent_send_update_mac_stats)(mid_t mod_id); + // void (*flexran_agent_send_update_mac_stats)(mid_t mod_id); /// Provide to the scheduler a pending dl_mac_config message void (*flexran_agent_get_pending_dl_mac_config)(mid_t mod_id, @@ -63,8 +63,8 @@ typedef struct { /// Notify the controller for a state change of a particular UE, by sending the proper /// UE state change message (ACTIVATION, DEACTIVATION, HANDOVER) - int (*flexran_agent_notify_ue_state_change)(mid_t mod_id, uint32_t rnti, - uint8_t state_change); + // int (*flexran_agent_notify_ue_state_change)(mid_t mod_id, uint32_t rnti, + // uint8_t state_change); void *dl_scheduler_loaded_lib; diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h index 679bc4d623..95fbf3bed0 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h @@ -54,7 +54,7 @@ typedef struct { /// Notify the controller for a state change of a particular UE, by sending the proper /// UE state change message (ACTIVATION, DEACTIVATION, HANDOVER) - void (*flexran_agent_notify_ue_state_change)(mid_t mod_id, uint32_t rnti, + int (*flexran_agent_notify_ue_state_change)(mid_t mod_id, uint32_t rnti, uint32_t state_change); void (*flexran_trigger_rrc_measurements)(mid_t mod_id, MeasResults_t* measResults); diff --git a/openair2/ENB_APP/flexran_agent_common.h b/openair2/ENB_APP/flexran_agent_common.h index d96712622f..8fd62a0524 100644 --- a/openair2/ENB_APP/flexran_agent_common.h +++ b/openair2/ENB_APP/flexran_agent_common.h @@ -166,6 +166,6 @@ err_code_t flexran_agent_init_cont_stats_update(mid_t mod_id); void flexran_agent_send_update_stats(mid_t mod_id); err_code_t flexran_agent_enable_cont_stats_update(mid_t mod_id, xid_t xid, stats_request_config_t *stats_req) ; - +err_code_t flexran_agent_disable_cont_stats_update(mid_t mod_id); #endif diff --git a/openair2/ENB_APP/flexran_agent_handler.c b/openair2/ENB_APP/flexran_agent_handler.c index 84948d1eee..fc2ed135c8 100644 --- a/openair2/ENB_APP/flexran_agent_handler.c +++ b/openair2/ENB_APP/flexran_agent_handler.c @@ -97,7 +97,7 @@ Protocol__FlexranMessage* flexran_agent_handle_message (mid_t mod_id, err_code= PROTOCOL__FLEXRAN_ERR__MSG_DECODING; goto error; } - //printf("==================> %d %d \n", decoded_message->msg_case, decoded_message->msg_dir); + // printf("==================> %d %d \n", decoded_message->msg_case, decoded_message->msg_dir); if ((decoded_message->msg_case > sizeof(agent_messages_callback) / (3 * sizeof(flexran_agent_message_decoded_callback))) || (decoded_message->msg_dir > PROTOCOL__FLEXRAN_DIRECTION__UNSUCCESSFUL_OUTCOME)){ err_code= PROTOCOL__FLEXRAN_ERR__MSG_NOT_HANDLED; @@ -309,7 +309,7 @@ int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__Flexr } else if (comp_req->report_frequency == PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_CONTINUOUS) { /*If request was for continuous updates, disable the previous configuration and set up a new one*/ - // flexran_agent_disable_cont_stats_update(mod_id); + flexran_agent_disable_cont_stats_update(mod_id); stats_request_config_t request_config; request_config.report_type = PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS; request_config.report_frequency = PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_ONCE; diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index dd3e8a4bcb..59ccb67293 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -152,21 +152,11 @@ int flexran_get_ue_wcqi (mid_t mod_id, mid_t ue_id) { // return ((UE_list_t *)enb_ue[mod_id])->eNB_UE_stats[UE_PCCID(mod_id,ue_id)][ue_id].dl_cqi; } -int flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id, char * buffer_status) { +int flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) { rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); uint16_t frame = (uint16_t) flexran_get_current_frame(mod_id); - mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id,frame,ENB_FLAG_YES,MBMS_FLAG_NO,channel_id,0); - - if (strcmp(buffer_status, "bytes_buffer")){ - return rlc_status.bytes_in_buffer; - } else if(strcmp(buffer_status, "pdu_buffer")) { - return rlc_status.pdus_in_buffer; - } - /* else if (strcmp(buffer_status, "head_line")){ */ - - /* return rlc_status.head_sdu_remaining_size_to_send; */ - - /* } */ + mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id,frame,ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0); + return rlc_status.bytes_in_buffer; } int flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) { diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 4a893a4c96..8a7d6dbaf7 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -89,7 +89,7 @@ int flexran_get_ue_phr (mid_t mod_id, mid_t ue_id); int flexran_get_ue_wcqi (mid_t mod_id, mid_t ue_id); /* Get the transmission queue size for a UE with a channel_id logical channel id */ -int flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id, char * buffer_status); +int flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id); /* Get the head of line delay for a UE with a channel_id logical channel id */ int flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id); From 14fb9e2ba201790e3c741501594e930248e66e09 Mon Sep 17 00:00:00 2001 From: Xenofon Foukas Date: Tue, 11 Apr 2017 08:58:20 +0000 Subject: [PATCH 007/195] Changed default scheduler to local --- openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index d22633a818..63dba00d7c 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -1174,8 +1174,8 @@ int flexran_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { xface->flexran_agent_send_sr_info = flexran_agent_send_sr_info; xface->flexran_agent_send_sf_trigger = flexran_agent_send_sf_trigger; //xface->flexran_agent_send_update_mac_stats = flexran_agent_send_update_mac_stats; - // xface->flexran_agent_schedule_ue_spec = flexran_schedule_ue_spec_default; - xface->flexran_agent_schedule_ue_spec = flexran_schedule_ue_spec_remote; + xface->flexran_agent_schedule_ue_spec = flexran_schedule_ue_spec_default; + //xface->flexran_agent_schedule_ue_spec = flexran_schedule_ue_spec_remote; xface->flexran_agent_get_pending_dl_mac_config = flexran_agent_get_pending_dl_mac_config; xface->dl_scheduler_loaded_lib = NULL; From e36c5b6024d02e497c2196978a03025104db1a1e Mon Sep 17 00:00:00 2001 From: Xenofon Foukas Date: Tue, 11 Apr 2017 09:28:22 +0000 Subject: [PATCH 008/195] Fixed compilation errors when compiling without agent enabled --- openair2/LAYER2/MAC/eNB_scheduler.c | 11 ++++++----- openair2/RRC/LITE/rrc_eNB.c | 3 ++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index b75a3e7e8e..2bea6e1f1f 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -1082,15 +1082,16 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, for (CC_id=0;CC_idflexran_agent_send_update_mac_stats(module_idP); // } -// #endif -// #endif -flexran_agent_send_update_stats(module_idP); +#endif +#endif + /* int dummy=0; for (i=0; diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index 1f2bf2d262..53616d334d 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -2158,6 +2158,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons PDCP_TRANSMISSION_MODE_CONTROL); } +#if defined(FLEXRAN_AGENT_SB_IF) //----------------------------------------------------------------------------- void @@ -2749,7 +2750,7 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt PDCP_TRANSMISSION_MODE_CONTROL); } - +#endif //----------------------------------------------------------------------------- From e3df5d3de55f8966c7eba3c9c24e3438b228ea86 Mon Sep 17 00:00:00 2001 From: Xenofon Foukas Date: Tue, 11 Apr 2017 11:46:34 +0000 Subject: [PATCH 009/195] Fixed warnings and bugs --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 4 +++- .../RRC/flexran_agent_rrc_defs.h | 4 ++-- openair2/ENB_APP/flexran_agent_common.c | 3 ++- openair2/LAYER2/MAC/proto.h | 1 + openair2/RRC/LITE/proto.h | 17 +++++++++++++++++ openair2/RRC/LITE/rrc_eNB.c | 3 --- 6 files changed, 25 insertions(+), 7 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 63dba00d7c..73ae74a32f 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -214,7 +214,9 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, goto error; protocol__flex_csi_p11__init(csi11); - csi11->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + csi11->wb_cqi = malloc(sizeof(csi11->wb_cqi)); + csi11->n_wb_cqi = 1; + csi11->wb_cqi[0] = flexran_get_ue_wcqi (enb_id, i); // According To spec 36.213 if (flexran_get_antenna_ports(enb_id, j) == 2 && csi_reports[j]->ri == 1) { diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h index 95fbf3bed0..ad1375171e 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h @@ -54,8 +54,8 @@ typedef struct { /// Notify the controller for a state change of a particular UE, by sending the proper /// UE state change message (ACTIVATION, DEACTIVATION, HANDOVER) - int (*flexran_agent_notify_ue_state_change)(mid_t mod_id, uint32_t rnti, - uint32_t state_change); + void (*flexran_agent_notify_ue_state_change)(mid_t mod_id, uint32_t rnti, + uint8_t state_change); void (*flexran_trigger_rrc_measurements)(mid_t mod_id, MeasResults_t* measResults); diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index d67eb8b6a7..78d3a75ec7 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -1075,7 +1075,8 @@ int flexran_agent_rrc_measurement(mid_t mod_id, const void *params, Protocol__Fl int flexran_agent_destroy_rrc_measurement(Protocol__FlexranMessage *msg){ - + // TODO + return 0; } diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/proto.h index ea264f1bfd..16f2d186ea 100644 --- a/openair2/LAYER2/MAC/proto.h +++ b/openair2/LAYER2/MAC/proto.h @@ -539,6 +539,7 @@ void sort_ue_ul (module_id_t module_idP,int frameP, sub_frame_t subframeP); void assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subframeP,uint16_t *first_rb); void adjust_bsr_info(int buffer_occupancy, uint16_t TBS, UE_TEMPLATE *UE_template); int phy_stats_exist(module_id_t Mod_id, int rnti); +void sort_UEs (module_id_t Mod_idP, int frameP, sub_frame_t subframeP); /*! \fn UE_L2_state_t ue_scheduler(const module_id_t module_idP,const frame_t frameP, const sub_frame_t subframe, const lte_subframe_t direction,const uint8_t eNB_index) \brief UE scheduler where all the ue background tasks are done. This function performs the following: 1) Trigger PDCP every 5ms 2) Call RRC for link status return to PHY3) Perform SR/BSR procedures for scheduling feedback 4) Perform PHR procedures. diff --git a/openair2/RRC/LITE/proto.h b/openair2/RRC/LITE/proto.h index 8433980be4..20bc99ab79 100644 --- a/openair2/RRC/LITE/proto.h +++ b/openair2/RRC/LITE/proto.h @@ -33,6 +33,10 @@ #include "RRC/LITE/defs.h" +#if defined(FLEXRAN_AGENT_SB_IF) +#include "flexran_agent_extern.h" +#endif + //main.c int rrc_init_global_param(void); int L3_xface_init(void); @@ -254,6 +258,19 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration( const uint8_t ho_state ); + +#if defined(FLEXRAN_AGENT_SB_IF) + +void +flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_t* const ue_context_pP, + const uint8_t ho_state, + agent_reconf_rrc * trig_param + ); + +#endif + void rrc_eNB_generate_dedeicatedRRCConnectionReconfiguration( const protocol_ctxt_t* const ctxt_pP, diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index 53616d334d..11628a80b6 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -93,9 +93,6 @@ #include "SIMULATION/TOOLS/defs.h" // for taus -#if defined(FLEXRAN_AGENT_SB_IF) -#include "flexran_agent_extern.h" -#endif //#define XER_PRINT #ifdef PHY_EMUL From 3bd3bedcd2d60bad25f79970bfc6f56b9f18f698 Mon Sep 17 00:00:00 2001 From: Xenofon Foukas Date: Tue, 11 Apr 2017 13:25:08 +0000 Subject: [PATCH 010/195] Fixed ue state change notification functionality for deactivation of UEs --- openair2/RRC/LITE/L2_interface.c | 11 +++++++++++ openair2/RRC/LITE/rrc_eNB.c | 16 ++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/openair2/RRC/LITE/L2_interface.c b/openair2/RRC/LITE/L2_interface.c index 64734cac9a..6a64d7811e 100644 --- a/openair2/RRC/LITE/L2_interface.c +++ b/openair2/RRC/LITE/L2_interface.c @@ -52,6 +52,10 @@ extern UE_MAC_INST *UE_mac_inst; # include "intertask_interface.h" #endif +#if defined(FLEXRAN_AGENT_SB_IF) +#include "flexran_agent_extern.h" +#endif + //#define RRC_DATA_REQ_DEBUG #define DEBUG_RRC 1 @@ -734,6 +738,13 @@ void mac_eNB_rrc_ul_failure(const module_id_t Mod_instP, else { LOG_W(RRC,"Frame %d, Subframe %d: UL failure: UE %x unknown \n",frameP,subframeP,rntiP); } +#if defined(FLEXRAN_AGENT_SB_IF) + if (rrc_agent_registered[Mod_instP]) { + agent_rrc_xface[Mod_instP]->flexran_agent_notify_ue_state_change(Mod_instP, + rntiP, + PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); + } +#endif rrc_mac_remove_ue(Mod_instP,rntiP); } diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index 11628a80b6..6fbdd645ed 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -829,6 +829,15 @@ rrc_eNB_free_UE(const module_id_t enb_mod_idP,const struct rrc_eNB_ue_context_s* #endif #endif +#if defined(FLEXRAN_AGENT_SB_IF) + if (rrc_agent_registered[enb_mod_idP]) { + agent_rrc_xface[enb_mod_idP]->flexran_agent_notify_ue_state_change(enb_mod_idP, + rnti, + PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); + } +#endif + + rrc_mac_remove_ue(enb_mod_idP,rnti); rrc_rlc_remove_ue(&ctxt); pdcp_remove_UE(&ctxt); @@ -4885,6 +4894,13 @@ rrc_eNB_decode_ccch( } else { // no context available +#if defined(FLEXRAN_AGENT_SB_IF) + if (rrc_agent_registered[ctxt_pP->module_id]) { + agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, + ctxt_pP->rnti, + PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); + } +#endif LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Can't create new context for UE random UE identity (0x%" PRIx64 ")\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), random_value); From 169f33464e91d43410447b34dc21f5fbd31ec241 Mon Sep 17 00:00:00 2001 From: shahab SHARIATBAGHERI Date: Tue, 18 Apr 2017 18:13:42 +0200 Subject: [PATCH 011/195] Uplink Agent Mac function --- cmake_targets/CMakeLists.txt | 1 + .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 1 + .../MAC/flexran_agent_mac_defs.h | 4 + openair2/LAYER2/MAC/eNB_scheduler.c | 183 +- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 2 +- openair2/LAYER2/MAC/flexran_agent_mac_proto.h | 8 + .../MAC/flexran_agent_scheduler_ulsch_ue.c | 1673 +++++++++++++++++ 7 files changed, 1868 insertions(+), 4 deletions(-) create mode 100644 openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 5413014fbf..192590e20f 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1207,6 +1207,7 @@ if (FLEXRAN_AGENT_SB_IF) set (MAC_SRC ${MAC_SRC} ${MAC_DIR}/flexran_agent_scheduler_dlsch_ue.c + ${MAC_DIR}/flexran_agent_scheduler_ulsch_ue.c ${MAC_DIR}/flexran_agent_scheduler_dataplane.c ${MAC_DIR}/flexran_agent_scheduler_dlsch_ue_remote.c ) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 73ae74a32f..405837061a 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -1177,6 +1177,7 @@ int flexran_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { xface->flexran_agent_send_sf_trigger = flexran_agent_send_sf_trigger; //xface->flexran_agent_send_update_mac_stats = flexran_agent_send_update_mac_stats; xface->flexran_agent_schedule_ue_spec = flexran_schedule_ue_spec_default; + xface->flexran_agent_schedule_ul_spec = flexran_agent_schedule_ulsch_ue_spec; //xface->flexran_agent_schedule_ue_spec = flexran_schedule_ue_spec_remote; xface->flexran_agent_get_pending_dl_mac_config = flexran_agent_get_pending_dl_mac_config; diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h index 8354223123..ab6bf57417 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h @@ -61,6 +61,10 @@ typedef struct { int *mbsfn_flag, Protocol__FlexranMessage **dl_info); + void (*flexran_agent_schedule_ul_spec)(mid_t module_idP, uint32_t frameP, unsigned char cooperation_flag, + uint32_t subframeP, + unsigned char sched_subframe); + /// Notify the controller for a state change of a particular UE, by sending the proper /// UE state change message (ACTIVATION, DEACTIVATION, HANDOVER) // int (*flexran_agent_notify_ue_state_change)(mid_t mod_id, uint32_t rnti, diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 2bea6e1f1f..7250d66f07 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -382,11 +382,26 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, if (mac_xface->frame_parms->frame_type == FDD) { //FDD +#ifndef FLEXRAN_AGENT_SB_IF schedule_ulsch(module_idP,frameP,cooperation_flag,0,4);//,calibration_flag); +#else + if (mac_agent_registered[module_idP]){ + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + } + +#endif + } else if ((mac_xface->frame_parms->tdd_config == 0) || //TDD (mac_xface->frame_parms->tdd_config == 3) || (mac_xface->frame_parms->tdd_config == 6)) { +#ifndef FLEXRAN_AGENT_SB_IF schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4);//,calibration_flag); +#else + if (mac_agent_registered[module_idP]){ + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + } + +#endif } #ifndef FLEXRAN_AGENT_SB_IF schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); @@ -418,14 +433,31 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, switch (mac_xface->frame_parms->tdd_config) { case 0: case 1: - schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7); +#ifndef FLEXRAN_AGENT_SB_IF + schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7);//,calibration_flag); +#else + +if (mac_agent_registered[module_idP]){ + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + } + +#endif #ifndef FLEXRAN_AGENT_SB_IF fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); #endif break; case 6: +#ifndef FLEXRAN_AGENT_SB_IF schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8); +#else + + if (mac_agent_registered[module_idP]){ + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + } + +#endif + #ifndef FLEXRAN_AGENT_SB_IF fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); #endif @@ -435,7 +467,16 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, break; } } else { //FDD +#ifndef FLEXRAN_AGENT_SB_IF schedule_ulsch(module_idP,frameP,cooperation_flag,1,5); +#else + +if (mac_agent_registered[module_idP]){ + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + } + +#endif + #ifndef FLEXRAN_AGENT_SB_IF schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); @@ -465,7 +506,16 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, // TDD, nothing // FDD, normal UL/DLSCH if (mac_xface->frame_parms->frame_type == FDD) { //FDD +#ifndef FLEXRAN_AGENT_SB_IF schedule_ulsch(module_idP,frameP,cooperation_flag,2,6); +#else + + if (mac_agent_registered[module_idP]){ + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + } + +#endif + #ifndef FLEXRAN_AGENT_SB_IF schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); @@ -498,7 +548,15 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, if (mac_xface->frame_parms->frame_type == TDD) { switch (mac_xface->frame_parms->tdd_config) { case 2: +#ifndef FLEXRAN_AGENT_SB_IF schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7); +#else + +if (mac_agent_registered[module_idP]){ + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + } + +#endif // no break here! case 5: @@ -528,8 +586,16 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, break; } } else { //FDD - +#ifndef FLEXRAN_AGENT_SB_IF schedule_ulsch(module_idP,frameP,cooperation_flag,3,7); +#else + +if (mac_agent_registered[module_idP]){ + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + } + +#endif + #ifndef FLEXRAN_AGENT_SB_IF schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); @@ -563,7 +629,15 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, switch (mac_xface->frame_parms->tdd_config) { case 1: // schedule_RA(module_idP,frameP,subframeP); +#ifndef FLEXRAN_AGENT_SB_IF schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8); +#else + +if (mac_agent_registered[module_idP]){ + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + } + +#endif // no break here! case 2: @@ -600,8 +674,16 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, } } else { if (mac_xface->frame_parms->frame_type == FDD) { //FDD - +#ifndef FLEXRAN_AGENT_SB_IF schedule_ulsch(module_idP, frameP, cooperation_flag, 4, 8); +#else + +if (mac_agent_registered[module_idP]){ + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + } + +#endif + #ifndef FLEXRAN_AGENT_SB_IF schedule_ue_spec(module_idP, frameP, subframeP, mbsfn_status); fill_DLSCH_dci(module_idP, frameP, subframeP, mbsfn_status); @@ -637,7 +719,16 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, //schedule_RA(module_idP,frameP,subframeP,5); if (mac_xface->frame_parms->frame_type == FDD) { schedule_RA(module_idP,frameP,subframeP,1); +#ifndef FLEXRAN_AGENT_SB_IF schedule_ulsch(module_idP,frameP,cooperation_flag,5,9); +#else + +if (mac_agent_registered[module_idP]){ + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + } + +#endif + #ifndef FLEXRAN_AGENT_SB_IF schedule_ue_spec(module_idP, frameP, subframeP, mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); @@ -700,7 +791,15 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, break; case 1: +#ifndef FLEXRAN_AGENT_SB_IF schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2); +#else + +if (mac_agent_registered[module_idP]){ + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + } + +#endif // schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); #ifndef FLEXRAN_AGENT_SB_IF fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); @@ -708,7 +807,15 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, break; case 6: +#ifndef FLEXRAN_AGENT_SB_IF schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3); +#else + +if (mac_agent_registered[module_idP]){ + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + } + +#endif // schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); #ifndef FLEXRAN_AGENT_SB_IF fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); @@ -767,7 +874,16 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, break; } } else { //FDD +#ifndef FLEXRAN_AGENT_SB_IF schedule_ulsch(module_idP,frameP,cooperation_flag,6,0); +#else + +if (mac_agent_registered[module_idP]){ + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + } + +#endif + #ifndef FLEXRAN_AGENT_SB_IF schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); @@ -850,7 +966,16 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, break; } } else { //FDD +#ifndef FLEXRAN_AGENT_SB_IF schedule_ulsch(module_idP,frameP,cooperation_flag,7,1); +#else + +if (mac_agent_registered[module_idP]){ + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + } + +#endif + #ifndef FLEXRAN_AGENT_SB_IF schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); @@ -888,7 +1013,16 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, case 5: // schedule_RA(module_idP,subframeP); +#ifndef FLEXRAN_AGENT_SB_IF schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2); +#else + +if (mac_agent_registered[module_idP]){ + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + } + +#endif + #ifndef FLEXRAN_AGENT_SB_IF schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); @@ -915,7 +1049,16 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, break; } } else { //FDD +#ifndef FLEXRAN_AGENT_SB_IF schedule_ulsch(module_idP,frameP,cooperation_flag,8,2); +#else + +if (mac_agent_registered[module_idP]){ + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + } + +#endif + #ifndef FLEXRAN_AGENT_SB_IF schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); @@ -946,7 +1089,15 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, if (mac_xface->frame_parms->frame_type == TDD) { switch (mac_xface->frame_parms->tdd_config) { case 1: +#ifndef FLEXRAN_AGENT_SB_IF schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3); +#else + +if (mac_agent_registered[module_idP]){ + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + } + +#endif schedule_RA(module_idP,frameP,subframeP,7); // 7 = Msg3 subframeP, not #ifndef FLEXRAN_AGENT_SB_IF schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); @@ -972,7 +1123,16 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, case 3: case 4: +#ifndef FLEXRAN_AGENT_SB_IF schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3); +#else + +if (mac_agent_registered[module_idP]){ + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + } + +#endif + #ifndef FLEXRAN_AGENT_SB_IF schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); @@ -996,7 +1156,15 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, break; case 6: +#ifndef FLEXRAN_AGENT_SB_IF schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4); +#else + +if (mac_agent_registered[module_idP]){ + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + } + +#endif //schedule_RA(module_idP,frameP,subframeP); #ifndef FLEXRAN_AGENT_SB_IF schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); @@ -1049,7 +1217,16 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, break; } } else { //FDD +#ifndef FLEXRAN_AGENT_SB_IF schedule_ulsch(module_idP,frameP,cooperation_flag,9,3); +#else + +if (mac_agent_registered[module_idP]){ + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + } + +#endif + #ifndef FLEXRAN_AGENT_SB_IF schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 6d0044b346..585d9c2c1c 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -885,7 +885,7 @@ abort(); rb_table_index=UE_template->pre_allocated_rb_table_index_ul; } else { mcs=10;//cmin (10, openair_daq_vars.target_ue_ul_mcs); - rb_table_index=5; // for PHR + rb_table_index=13; // for PHR } UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs; diff --git a/openair2/LAYER2/MAC/flexran_agent_mac_proto.h b/openair2/LAYER2/MAC/flexran_agent_mac_proto.h index a3ff3b6a4a..8a9d5971e3 100644 --- a/openair2/LAYER2/MAC/flexran_agent_mac_proto.h +++ b/openair2/LAYER2/MAC/flexran_agent_mac_proto.h @@ -168,6 +168,14 @@ void _dlsch_scheduler_pre_processor_allocate (module_id_t Mod_id, void flexran_schedule_ue_spec_default(mid_t mod_id, uint32_t frame, uint32_t subframe, int *mbsfn_flag, Protocol__FlexranMessage **dl_info); +/* + Uplink scheduler used by MAC agent +*/ + +void flexran_agent_schedule_ulsch_ue_spec(module_id_t module_idP, frame_t frameP, unsigned char cooperation_flag, + sub_frame_t subframeP, + unsigned char sched_subframe); + /* * Data plane function for applying the DL decisions of the scheduler */ diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c new file mode 100644 index 0000000000..2abd09024b --- /dev/null +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c @@ -0,0 +1,1673 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file eNB_scheduler_ulsch.c + * \brief FlexRAN eNB procedures for the ULSCH transport channel + * \author shahab SHARIAT BAGHERI + * \date 2017 + * \version 1.0 + * @ingroup _mac + + */ + +#include "assertions.h" +#include "PHY/defs.h" +#include "PHY/extern.h" + +#include "SCHED/defs.h" +#include "SCHED/extern.h" + +#include "LAYER2/MAC/defs.h" +#include "LAYER2/MAC/proto.h" +#include "LAYER2/MAC/extern.h" +#include "UTIL/LOG/log.h" +#include "UTIL/LOG/vcd_signal_dumper.h" +#include "UTIL/OPT/opt.h" +#include "OCG.h" +#include "OCG_extern.h" + +#include "RRC/LITE/extern.h" +#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" + +//#include "LAYER2/MAC/pre_processor.c" +#include "pdcp.h" + +#if defined(ENABLE_ITTI) +# include "intertask_interface.h" +#endif + +#include "T.h" + +// #define ENABLE_MAC_PAYLOAD_DEBUG +// #define DEBUG_eNB_SCHEDULER 1 + +// // This table holds the allowable PRB sizes for ULSCH transmissions +// uint8_t rb_table[33] = {1,2,3,4,5,6,8,9,10,12,15,16,18,20,24,25,27,30,32,36,40,45,48,50,54,60,72,75,80,81,90,96,100}; + +// void rx_sdu(const module_id_t enb_mod_idP, +// const int CC_idP, +// const frame_t frameP, +// const sub_frame_t subframeP, +// const rnti_t rntiP, +// uint8_t *sduP, +// const uint16_t sdu_lenP, +// const int harq_pidP, +// uint8_t *msg3_flagP) +// { + +// unsigned char rx_ces[MAX_NUM_CE],num_ce,num_sdu,i,*payload_ptr; +// unsigned char rx_lcids[NB_RB_MAX]; +// unsigned short rx_lengths[NB_RB_MAX]; +// int UE_id = find_UE_id(enb_mod_idP,rntiP); +// int ii,j; +// eNB_MAC_INST *eNB = &eNB_mac_inst[enb_mod_idP]; +// UE_list_t *UE_list= &eNB->UE_list; +// int crnti_rx=0; +// int old_buffer_info; + +// start_meas(&eNB->rx_ulsch_sdu); + +// if ((UE_id > NUMBER_OF_UE_MAX) || (UE_id == -1) ) +// for(ii=0; iiUE_sched_ctrl[UE_id].ul_scheduled &= (~(1<UE_sched_ctrl[UE_id].ul_inactivity_timer=0; +// UE_list->UE_sched_ctrl[UE_id].ul_failure_timer =0; +// UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= (~(1<UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { +// UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync=0; +// mac_eNB_rrc_ul_in_sync(enb_mod_idP,CC_idP,frameP,subframeP,UE_RNTI(enb_mod_idP,UE_id)); +// } +// } + + +// payload_ptr = parse_ulsch_header(sduP,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,sdu_lenP); + +// T(T_ENB_MAC_UE_UL_PDU, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP), +// T_INT(harq_pidP), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu)); +// T(T_ENB_MAC_UE_UL_PDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP), +// T_INT(harq_pidP), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu), T_BUFFER(sduP, sdu_lenP)); + +// eNB->eNB_stats[CC_idP].ulsch_bytes_rx=sdu_lenP; +// eNB->eNB_stats[CC_idP].total_ulsch_bytes_rx+=sdu_lenP; +// eNB->eNB_stats[CC_idP].total_ulsch_pdus_rx+=1; +// // control element +// for (i=0; iUE_template[CC_idP][UE_id].phr_info = (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET; +// LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received PHR PH = %d (db)\n", +// enb_mod_idP, CC_idP, rx_ces[i], UE_list->UE_template[CC_idP][UE_id].phr_info); +// UE_list->UE_template[CC_idP][UE_id].phr_info_configured=1; +// UE_list->UE_sched_ctrl[UE_id].phr_received = 1; +// } +// payload_ptr+=sizeof(POWER_HEADROOM_CMD); +// break; + +// case CRNTI: +// UE_id = find_UE_id(enb_mod_idP,(((uint16_t)payload_ptr[0])<<8) + payload_ptr[1]); +// LOG_I(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n", +// frameP,subframeP,enb_mod_idP, CC_idP, rx_ces[i], i,num_ce,(((uint16_t)payload_ptr[0])<<8) + payload_ptr[1],UE_id); +// if (UE_id!=-1) { +// UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer=0; +// UE_list->UE_sched_ctrl[UE_id].ul_failure_timer=0; +// if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { +// UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync=0; +// mac_eNB_rrc_ul_in_sync(enb_mod_idP,CC_idP,frameP,subframeP,(((uint16_t)payload_ptr[0])<<8) + payload_ptr[1]); +// } +// } +// crnti_rx=1; +// payload_ptr+=2; + +// if (msg3_flagP != NULL) { +// *msg3_flagP = 0; +// } +// break; + +// case TRUNCATED_BSR: +// case SHORT_BSR: { +// uint8_t lcgid; +// lcgid = (payload_ptr[0] >> 6); + +// LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", +// enb_mod_idP, CC_idP, rx_ces[i], lcgid, payload_ptr[0] & 0x3f); + +// if (crnti_rx==1) +// LOG_I(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", +// enb_mod_idP, CC_idP, rx_ces[i], lcgid, payload_ptr[0] & 0x3f); +// if (UE_id != -1) { + +// UE_list->UE_template[CC_idP][UE_id].bsr_info[lcgid] = (payload_ptr[0] & 0x3f); + +// // update buffer info + +// UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[lcgid]]; + +// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid]; + +// PHY_vars_eNB_g[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP*10)+subframeP] = (payload_ptr[0] & 0x3f); +// if (UE_id == UE_list->head) +// VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR,PHY_vars_eNB_g[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP*10)+subframeP]); +// if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0 ) { +// UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid]=frameP; +// } +// if (mac_eNB_get_rrc_status(enb_mod_idP,UE_RNTI(enb_mod_idP,UE_id)) < RRC_CONNECTED) +// LOG_I(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : ul_total_buffer = %d (lcg increment %d)\n", +// enb_mod_idP, CC_idP, rx_ces[i], UE_list->UE_template[CC_idP][UE_id].ul_total_buffer, +// UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid]); +// } +// else { + +// } +// payload_ptr += 1;//sizeof(SHORT_BSR); // fixme +// } +// break; + +// case LONG_BSR: +// if (UE_id != -1) { +// UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] = ((payload_ptr[0] & 0xFC) >> 2); +// UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] = +// ((payload_ptr[0] & 0x03) << 4) | ((payload_ptr[1] & 0xF0) >> 4); +// UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] = +// ((payload_ptr[1] & 0x0F) << 2) | ((payload_ptr[2] & 0xC0) >> 6); +// UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] = (payload_ptr[2] & 0x3F); + +// // update buffer info +// old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0]; +// UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0]]; + +// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer+= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0]; +// if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info) +// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info; +// else +// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0; + +// old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1]; +// UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1]]; +// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer+= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1]; +// if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info) +// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info; +// else +// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0; + +// old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2]; +// UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2]]; +// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer+= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2]; +// if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info) +// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info; +// else +// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0; + +// old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]; +// UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3]]; +// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer+= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]; +// if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info) +// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info; +// else +// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0; + +// LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = " +// "%u LCGID2 = %u LCGID3 = %u\n", +// enb_mod_idP, CC_idP, +// rx_ces[i], +// UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0], +// UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1], +// UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2], +// UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3]); +// if (crnti_rx==1) +// LOG_I(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = " +// "%u LCGID2 = %u LCGID3 = %u\n", +// enb_mod_idP, CC_idP, +// rx_ces[i], +// UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0], +// UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1], +// UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2], +// UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3]); + +// if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] == 0 ) { +// UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=0; +// } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] == 0) { +// UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=frameP; +// } + +// if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] == 0 ) { +// UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=0; +// } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] == 0) { +// UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=frameP; +// } + +// if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] == 0 ) { +// UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2]=0; +// } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] == 0) { +// UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2]=frameP; +// } + +// if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] == 0 ) { +// UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3]= 0; +// } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] == 0) { +// UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3]=frameP; + +// } +// } + +// payload_ptr += 3;////sizeof(LONG_BSR); +// break; + +// default: +// LOG_E(MAC, "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", enb_mod_idP, CC_idP, rx_ces[i]); +// break; +// } +// } + +// for (i=0; i CCCH_PAYLOAD_SIZE_MAX) { +// LOG_E(MAC, "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d), dropping packet\n", +// enb_mod_idP, CC_idP, frameP, rx_lengths[i], CCCH_PAYLOAD_SIZE_MAX); +// break; +// } +// LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH: %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n", +// enb_mod_idP,CC_idP,frameP, +// payload_ptr[0],payload_ptr[1],payload_ptr[2],payload_ptr[3],payload_ptr[4], payload_ptr[5], rntiP); +// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC,1); +// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC,0); +// for (ii=0; iicommon_channels[CC_idP].RA_template[ii].rnti, rntiP, +// eNB->common_channels[CC_idP].RA_template[ii].RA_active); + +// if ((eNB->common_channels[CC_idP].RA_template[ii].rnti==rntiP) && +// (eNB->common_channels[CC_idP].RA_template[ii].RA_active==TRUE)) { + +// //payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len); + +// if (UE_id < 0) { +// memcpy(&eNB->common_channels[CC_idP].RA_template[ii].cont_res_id[0],payload_ptr,6); +// LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %ld\n", +// enb_mod_idP,CC_idP,frameP,rx_lengths[i],payload_ptr-sduP); + +// if ((UE_id=add_new_ue(enb_mod_idP,CC_idP,eNB->common_channels[CC_idP].RA_template[ii].rnti,harq_pidP)) == -1 ) { +// mac_xface->macphy_exit("[MAC][eNB] Max user count reached\n"); +// // kill RA procedure +// } else +// LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n", +// enb_mod_idP,CC_idP,frameP,eNB->common_channels[CC_idP].RA_template[ii].rnti,UE_id); +// } else { +// LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n", +// enb_mod_idP,CC_idP,frameP,UE_id,rx_lengths[i],payload_ptr-sduP); +// // kill RA procedure +// } + +// if (Is_rrc_registered == 1) +// mac_rrc_data_ind( +// enb_mod_idP, +// CC_idP, +// frameP,subframeP, +// rntiP, +// CCCH, +// (uint8_t*)payload_ptr, +// rx_lengths[i], +// ENB_FLAG_YES, +// enb_mod_idP, +// 0); + + +// if (num_ce >0) { // handle msg3 which is not RRCConnectionRequest +// // process_ra_message(msg3,num_ce,rx_lcids,rx_ces); +// } + +// eNB->common_channels[CC_idP].RA_template[ii].generate_Msg4 = 1; +// eNB->common_channels[CC_idP].RA_template[ii].wait_ack_Msg4 = 0; + +// } // if process is active +// } // loop on RA processes + +// break ; + +// case DCCH : +// case DCCH1 : +// // if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){ + + +// #if defined(ENABLE_MAC_PAYLOAD_DEBUG) +// LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP)); +// for (j=0; j<32; j++) { +// LOG_T(MAC,"%x ",payload_ptr[j]); +// } +// LOG_T(MAC,"\n"); +// #endif + +// if (UE_id != -1) { +// // adjust buffer occupancy of the correponding logical channel group +// if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) +// UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; +// else +// UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0; + +// LOG_D(MAC,"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DCCH, received %d bytes form UE %d on LCID %d \n", +// enb_mod_idP,CC_idP,frameP, rx_lengths[i], UE_id, rx_lcids[i]); + +// mac_rlc_data_ind( +// enb_mod_idP, +// rntiP, +// enb_mod_idP, +// frameP, +// ENB_FLAG_YES, +// MBMS_FLAG_NO, +// rx_lcids[i], +// (char *)payload_ptr, +// rx_lengths[i], +// 1, +// NULL);//(unsigned int*)crc_status); +// UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]]+=1; +// UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]]+=rx_lengths[i]; +// } /* UE_id != -1 */ + +// // } +// break; + +// // all the DRBS +// case DTCH: +// default : + +// #if defined(ENABLE_MAC_PAYLOAD_DEBUG) +// LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP)); +// for (j=0; j<32; j++) { +// LOG_T(MAC,"%x ",payload_ptr[j]); +// } +// LOG_T(MAC,"\n"); +// #endif +// if (rx_lcids[i] < NB_RB_MAX ) { +// LOG_D(MAC,"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n", +// enb_mod_idP,CC_idP,frameP, rx_lengths[i], UE_id, rx_lcids[i]); + +// if (UE_id != -1) { +// // adjust buffer occupancy of the correponding logical channel group +// LOG_D(MAC,"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d, removing from LCGID %ld, %d\n", +// enb_mod_idP,CC_idP,frameP, rx_lengths[i], UE_id,rx_lcids[i], +// UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]], +// UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]]); + +// if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) +// UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; +// else +// UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0; +// if ((rx_lengths[i] 0) ) { // MAX SIZE OF transport block +// mac_rlc_data_ind( +// enb_mod_idP, +// rntiP, +// enb_mod_idP, +// frameP, +// ENB_FLAG_YES, +// MBMS_FLAG_NO, +// rx_lcids[i], +// (char *)payload_ptr, +// rx_lengths[i], +// 1, +// NULL);//(unsigned int*)crc_status); + +// UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]]+=1; +// UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]]+=rx_lengths[i]; +// } +// else { /* rx_length[i] */ +// UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx+=1; +// LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ", +// enb_mod_idP, CC_idP, frameP, rx_lcids[i], UE_id); +// } +// } +// else {/*(UE_id != -1*/ +// LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ", +// enb_mod_idP, CC_idP, frameP, rx_lcids[i], UE_id); +// } +// } + +// break; +// } + +// payload_ptr+=rx_lengths[i]; +// } + +// /* NN--> FK: we could either check the payload, or use a phy helper to detect a false msg3 */ +// if ((num_sdu == 0) && (num_ce==0)) { +// if (UE_id != -1) +// UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx+=1; + +// if (msg3_flagP != NULL) { +// if( *msg3_flagP == 1 ) { +// LOG_N(MAC,"[eNB %d] CC_id %d frame %d : false msg3 detection: signal phy to canceling RA and remove the UE\n", enb_mod_idP, CC_idP, frameP); +// *msg3_flagP=0; +// } +// } +// } else { +// if (UE_id != -1) { +// UE_list->eNB_UE_stats[CC_idP][UE_id].pdu_bytes_rx=sdu_lenP; +// UE_list->eNB_UE_stats[CC_idP][UE_id].total_pdu_bytes_rx+=sdu_lenP; +// UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_pdus_rx+=1; +// } +// } + +// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,0); +// stop_meas(&eNB->rx_ulsch_sdu); +// } + +void _ulsch_scheduler_pre_processor(module_id_t module_idP, + int frameP, + sub_frame_t subframeP, + uint16_t *first_rb) +{ + + int16_t i; + uint16_t UE_id,n,r; + uint8_t CC_id, round, harq_pid; + uint16_t nb_allocated_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX],total_allocated_rbs[MAX_NUM_CCs],average_rbs_per_user[MAX_NUM_CCs]; + int16_t total_remaining_rbs[MAX_NUM_CCs]; + uint16_t max_num_ue_to_be_scheduled=0,total_ue_count=0; + rnti_t rnti= -1; + UE_list_t *UE_list = &eNB_mac_inst[module_idP].UE_list; + UE_TEMPLATE *UE_template = 0; + LTE_DL_FRAME_PARMS *frame_parms = 0; + + + //LOG_I(MAC,"assign max mcs min rb\n"); + // maximize MCS and then allocate required RB according to the buffer occupancy with the limit of max available UL RB + assign_max_mcs_min_rb(module_idP,frameP, subframeP, first_rb); + + //LOG_I(MAC,"sort ue \n"); + // sort ues + sort_ue_ul (module_idP,frameP, subframeP); + + + // we need to distribute RBs among UEs + // step1: reset the vars + for (CC_id=0; CC_idhead_ul; i>=0; i=UE_list->next_ul[i]) { + nb_allocated_rbs[CC_id][i]=0; + } + } + + //LOG_I(MAC,"step2 \n"); + // step 2: calculate the average rb per UE + total_ue_count =0; + max_num_ue_to_be_scheduled=0; + + for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) { + + rnti = UE_RNTI(module_idP,i); + + if (rnti==NOT_A_RNTI) + continue; + + if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) + continue; + + if (!phy_stats_exist(module_idP, rnti)) + continue; + + UE_id = i; + + for (n=0; nnumactiveULCCs[UE_id]; n++) { + // This is the actual CC_id in the list + CC_id = UE_list->ordered_ULCCids[n][UE_id]; + UE_template = &UE_list->UE_template[CC_id][UE_id]; + average_rbs_per_user[CC_id]=0; + frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id); + + if (UE_template->pre_allocated_nb_rb_ul > 0) { + total_ue_count+=1; + } + /* + if((mac_xface->get_nCCE_max(module_idP,CC_id,3,subframeP) - nCCE_to_be_used[CC_id]) > (1<N_RB_UL-first_rb[CC_id]+1; + } else if( (total_ue_count <= (frame_parms->N_RB_DL-first_rb[CC_id])) && + (total_ue_count <= max_num_ue_to_be_scheduled)) { + average_rbs_per_user[CC_id] = (uint16_t) floor((frame_parms->N_RB_UL-first_rb[CC_id])/total_ue_count); + } else if (max_num_ue_to_be_scheduled > 0 ) { + average_rbs_per_user[CC_id] = (uint16_t) floor((frame_parms->N_RB_UL-first_rb[CC_id])/max_num_ue_to_be_scheduled); + } else { + average_rbs_per_user[CC_id]=1; + LOG_W(MAC,"[eNB %d] frame %d subframe %d: UE %d CC %d: can't get average rb per user (should not be here)\n", + module_idP,frameP,subframeP,UE_id,CC_id); + } + } + } + if (total_ue_count > 0) + LOG_D(MAC,"[eNB %d] Frame %d subframe %d: total ue to be scheduled %d/%d\n", + module_idP, frameP, subframeP,total_ue_count, max_num_ue_to_be_scheduled); + + //LOG_D(MAC,"step3\n"); + + // step 3: assigne RBS + for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) { + rnti = UE_RNTI(module_idP,i); + + if (rnti==NOT_A_RNTI) + continue; + if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) + continue; + if (!phy_stats_exist(module_idP, rnti)) + continue; + + UE_id = i; + + for (n=0; nnumactiveULCCs[UE_id]; n++) { + // This is the actual CC_id in the list + CC_id = UE_list->ordered_ULCCids[n][UE_id]; + + mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL); + + if(round>0) { + nb_allocated_rbs[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb_ul[harq_pid]; + } else { + nb_allocated_rbs[CC_id][UE_id] = cmin(UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul, average_rbs_per_user[CC_id]); + } + + total_allocated_rbs[CC_id]+= nb_allocated_rbs[CC_id][UE_id]; + + } + } + + // step 4: assigne the remaining RBs and set the pre_allocated rbs accordingly + for(r=0; r<2; r++) { + + for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) { + rnti = UE_RNTI(module_idP,i); + + if (rnti==NOT_A_RNTI) + continue; + if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) + continue; + if (!phy_stats_exist(module_idP, rnti)) + continue; + + UE_id = i; + + for (n=0; nnumactiveULCCs[UE_id]; n++) { + // This is the actual CC_id in the list + CC_id = UE_list->ordered_ULCCids[n][UE_id]; + UE_template = &UE_list->UE_template[CC_id][UE_id]; + frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id); + total_remaining_rbs[CC_id]=frame_parms->N_RB_UL - first_rb[CC_id] - total_allocated_rbs[CC_id]; + + if (total_ue_count == 1 ) { + total_remaining_rbs[CC_id]+=1; + } + + if ( r == 0 ) { + while ( (UE_template->pre_allocated_nb_rb_ul > 0 ) && + (nb_allocated_rbs[CC_id][UE_id] < UE_template->pre_allocated_nb_rb_ul) && + (total_remaining_rbs[CC_id] > 0)) { + nb_allocated_rbs[CC_id][UE_id] = cmin(nb_allocated_rbs[CC_id][UE_id]+1,UE_template->pre_allocated_nb_rb_ul); + total_remaining_rbs[CC_id]--; + total_allocated_rbs[CC_id]++; + } + } else { + UE_template->pre_allocated_nb_rb_ul= nb_allocated_rbs[CC_id][UE_id]; + LOG_D(MAC,"******************UL Scheduling Information for UE%d CC_id %d ************************\n",UE_id, CC_id); + LOG_D(MAC,"[eNB %d] total RB allocated for UE%d CC_id %d = %d\n", module_idP, UE_id, CC_id, UE_template->pre_allocated_nb_rb_ul); + } + } + } + } + + for (CC_id=0; CC_idget_lte_frame_parms(module_idP,CC_id); + + if (total_allocated_rbs[CC_id]>0) { + LOG_D(MAC,"[eNB %d] total RB allocated for all UEs = %d/%d\n", module_idP, total_allocated_rbs[CC_id], frame_parms->N_RB_UL - first_rb[CC_id]); + } + } +} + + + +// uint32_t bytes_to_bsr_index(int32_t nbytes) +// { + +// uint32_t i=0; + +// if (nbytes<0) { +// return(0); +// } + +// while ((iE == 0) { +// not_done = 0; +// } + +// lcid = ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID; + +// if (lcid < EXTENDED_POWER_HEADROOM) { +// if (not_done==0) { // last MAC SDU, length is implicit +// mac_header_ptr++; +// length = tb_length-(mac_header_ptr-mac_header)-ce_len; + +// for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++) { +// length -= rx_lengths[num_sdu_cnt]; +// } +// } else { +// if (((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F == 0) { +// length = ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L; +// mac_header_ptr += 2;//sizeof(SCH_SUBHEADER_SHORT); +// } else { // F = 1 +// length = ((((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB & 0x7f ) << 8 ) | (((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB & 0xff); +// mac_header_ptr += 3;//sizeof(SCH_SUBHEADER_LONG); +// } +// } + +// LOG_D(MAC,"[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n", +// num_sdus,lcid,tb_length, length,mac_header_ptr-mac_header); +// rx_lcids[num_sdus] = lcid; +// rx_lengths[num_sdus] = length; +// num_sdus++; +// } else { // This is a control element subheader POWER_HEADROOM, BSR and CRNTI +// if (lcid == SHORT_PADDING) { +// mac_header_ptr++; +// } else { +// rx_ces[num_ces] = lcid; +// num_ces++; +// mac_header_ptr++; + +// if (lcid==LONG_BSR) { +// ce_len+=3; +// } else if (lcid==CRNTI) { +// ce_len+=2; +// } else if ((lcid==POWER_HEADROOM) || (lcid==TRUNCATED_BSR)|| (lcid== SHORT_BSR)) { +// ce_len++; +// } else { +// LOG_E(MAC,"unknown CE %d \n", lcid); +// mac_xface->macphy_exit("unknown CE"); +// } +// } +// } +// } + +// *num_ce = num_ces; +// *num_sdu = num_sdus; + +// return(mac_header_ptr); +// } + + +void flexran_agent_schedule_ulsch_ue_spec(module_id_t module_idP, + frame_t frameP, + unsigned char cooperation_flag, + sub_frame_t subframeP, + unsigned char sched_subframe) { + + + + uint16_t first_rb[MAX_NUM_CCs],i; + int CC_id; + eNB_MAC_INST *eNB=&eNB_mac_inst[module_idP]; + + start_meas(&eNB->schedule_ulsch); + + + for (CC_id=0; CC_idcommon_channels[CC_id].RA_template[i].RA_active == TRUE) && + (eNB->common_channels[CC_id].RA_template[i].generate_rar == 0) && + (eNB->common_channels[CC_id].RA_template[i].generate_Msg4 == 0) && + (eNB->common_channels[CC_id].RA_template[i].wait_ack_Msg4 == 0) && + (eNB->common_channels[CC_id].RA_template[i].Msg3_subframe == sched_subframe)) { + first_rb[CC_id]++; + eNB->common_channels[CC_id].RA_template[i].Msg3_subframe = -1; + break; + } + } + + /* + if (mac_xface->is_prach_subframe(&(mac_xface->lte_frame_parms),frameP,subframeP)) { + first_rb[CC_id] = (mac_xface->get_prach_prb_offset(&(mac_xface->lte_frame_parms), + */ + + } + + flexran_agent_schedule_ulsch_rnti(module_idP, cooperation_flag, frameP, subframeP, sched_subframe,first_rb); + +// #ifdef CBA + // schedule_ulsch_cba_rnti(module_idP, cooperation_flag, frameP, subframeP, sched_subframe, first_rb); +// #endif + + + stop_meas(&eNB->schedule_ulsch); + +} + + + +void flexran_agent_schedule_ulsch_rnti(module_id_t module_idP, + unsigned char cooperation_flag, + frame_t frameP, + sub_frame_t subframeP, + unsigned char sched_subframe, + uint16_t *first_rb) +{ + + int UE_id; + uint8_t aggregation = 2; + rnti_t rnti = -1; + uint8_t round = 0; + uint8_t harq_pid = 0; + void *ULSCH_dci = NULL; + LTE_eNB_UE_stats *eNB_UE_stats = NULL; + DCI_PDU *DCI_pdu; + uint8_t status = 0; + uint8_t rb_table_index = -1; + uint16_t TBS = 0; + // int32_t buffer_occupancy=0; + uint32_t cqi_req,cshift,ndi,mcs=0,rballoc,tpc; + int32_t normalized_rx_power, target_rx_power=-90; + static int32_t tpc_accumulated=0; + + int n,CC_id = 0; + eNB_MAC_INST *eNB=&eNB_mac_inst[module_idP]; + UE_list_t *UE_list=&eNB->UE_list; + UE_TEMPLATE *UE_template; + UE_sched_ctrl *UE_sched_ctrl; + + // int rvidx_tab[4] = {0,2,3,1}; + LTE_DL_FRAME_PARMS *frame_parms; + int drop_ue=0; + + // LOG_I(MAC,"entering ulsch preprocesor\n"); + + _ulsch_scheduler_pre_processor(module_idP, + frameP, + subframeP, + first_rb); + + // LOG_I(MAC,"exiting ulsch preprocesor\n"); + + // loop over all active UEs + for (UE_id=UE_list->head_ul; UE_id>=0; UE_id=UE_list->next_ul[UE_id]) { + + // don't schedule if Msg4 is not received yet + if (UE_list->UE_template[UE_PCCID(module_idP,UE_id)][UE_id].configured==FALSE) { + LOG_I(MAC,"[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n", + module_idP,frameP,subframeP,UE_id); + continue; + } + + rnti = UE_RNTI(module_idP,UE_id); + + if (rnti==NOT_A_RNTI) { + LOG_W(MAC,"[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n", module_idP,frameP,subframeP,UE_id); + continue; + } + + /* let's drop the UE if get_eNB_UE_stats returns NULL when calling it with any of the UE's active UL CCs */ + /* TODO: refine? */ + drop_ue = 0; + for (n=0; nnumactiveULCCs[UE_id]; n++) { + CC_id = UE_list->ordered_ULCCids[n][UE_id]; + if (mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti) == NULL) { + LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: no PHY context\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id); + drop_ue = 1; + break; + } + } + if (drop_ue == 1) { +/* we can't come here, ulsch_scheduler_pre_processor won't put in the list a UE with no PHY context */ +abort(); + /* TODO: this is a hack. Sometimes the UE has no PHY context but + * is still present in the MAC with 'ul_failure_timer' = 0 and + * 'ul_out_of_sync' = 0. It seems wrong and the UE stays there forever. Let's + * start an UL out of sync procedure in this case. + * The root cause of this problem has to be found and corrected. + * In the meantime, this hack... + */ + if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 0 && + UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0) { + LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: UE in weird state, let's put it 'out of sync'\n", + module_idP,frameP,subframeP,UE_id,rnti,CC_id); + // inform RRC of failure and clear timer + mac_eNB_rrc_ul_failure(module_idP,CC_id,frameP,subframeP,rnti); + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer=0; + UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync=1; + } + continue; + } + + // loop over all active UL CC_ids for this UE + for (n=0; nnumactiveULCCs[UE_id]; n++) { + // This is the actual CC_id in the list + CC_id = UE_list->ordered_ULCCids[n][UE_id]; + frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id); + eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti); + + aggregation=get_aggregation(get_bw_index(module_idP,CC_id), + eNB_UE_stats->DL_cqi[0], + format0); + + if (CCE_allocation_infeasible(module_idP,CC_id,0,subframeP,aggregation,rnti)) { + LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: not enough nCCE\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id); + continue; // break; + } else{ + LOG_D(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d mode %s: aggregation level %d\n", + module_idP,frameP,subframeP,UE_id,rnti,CC_id, mode_string[eNB_UE_stats->mode], 1<mode == PUSCH) { // ue has a ulsch channel + + DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu; + UE_template = &UE_list->UE_template[CC_id][UE_id]; + UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id]; + + if (mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL) == -1 ) { + LOG_W(MAC,"[eNB %d] Scheduler Frame %d, subframeP %d: candidate harq_pid from PHY for UE %d CC %d RNTI %x\n", + module_idP,frameP,subframeP, UE_id, CC_id, rnti); + continue; + } else + LOG_T(MAC,"[eNB %d] Frame %d, subframeP %d, UE %d CC %d : got harq pid %d round %d (rnti %x,mode %s)\n", + module_idP,frameP,subframeP,UE_id,CC_id, harq_pid, round,rnti,mode_string[eNB_UE_stats->mode]); + + PHY_vars_eNB_g[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->ul_total_buffer; + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO,PHY_vars_eNB_g[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP]); + if (((UE_is_to_be_scheduled(module_idP,CC_id,UE_id)>0)) || (round>0))// || ((frameP%10)==0)) + // if there is information on bsr of DCCH, DTCH or if there is UL_SR, or if there is a packet to retransmit, or we want to schedule a periodic feedback every 10 frames + { + LOG_D(MAC,"[eNB %d][PUSCH] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d)\n", + module_idP,frameP,subframeP,UE_id,rnti,round,UE_template->ul_SR, + UE_sched_ctrl->ul_inactivity_timer, + UE_sched_ctrl->ul_failure_timer); + // reset the scheduling request + UE_template->ul_SR = 0; + status = mac_eNB_get_rrc_status(module_idP,rnti); + if (status < RRC_CONNECTED) + cqi_req = 0; + else if (UE_sched_ctrl->cqi_req_timer>30) { + cqi_req = 1; + UE_sched_ctrl->cqi_req_timer=0; + } + else + cqi_req = 0; + + //power control + //compute the expected ULSCH RX power (for the stats) + + // this is the normalized RX power and this should be constant (regardless of mcs + normalized_rx_power = eNB_UE_stats->UL_rssi[0]; + target_rx_power = mac_xface->get_target_pusch_rx_power(module_idP,CC_id); + + // this assumes accumulated tpc + // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out + int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame*10+UE_template->pusch_tpc_tx_subframe; + if (((framex10psubframe+10)<=(frameP*10+subframeP)) || //normal case + ((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=10)))) //frame wrap-around + { + UE_template->pusch_tpc_tx_frame=frameP; + UE_template->pusch_tpc_tx_subframe=subframeP; + if (normalized_rx_power>(target_rx_power+1)) { + tpc = 0; //-1 + tpc_accumulated--; + } else if (normalized_rx_power<(target_rx_power-1)) { + tpc = 2; //+1 + tpc_accumulated++; + } else { + tpc = 1; //0 + } + } else { + tpc = 1; //0 + } + + if (tpc!=1) { + LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", + module_idP,frameP,subframeP,harq_pid,tpc, + tpc_accumulated,normalized_rx_power,target_rx_power); + } + + // new transmission + if (round==0) { + + ndi = 1-UE_template->oldNDI_UL[harq_pid]; + UE_template->oldNDI_UL[harq_pid]=ndi; + UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power=normalized_rx_power; + UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power=target_rx_power; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=UE_template->pre_assigned_mcs_ul; + mcs = UE_template->pre_assigned_mcs_ul;//cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS + if (UE_template->pre_allocated_rb_table_index_ul >=0) { + rb_table_index=UE_template->pre_allocated_rb_table_index_ul; + } else { + mcs=10;//cmin (10, openair_daq_vars.target_ue_ul_mcs); + rb_table_index=5; // for PHR + } + + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs; + // buffer_occupancy = UE_template->ul_total_buffer; + + while (((rb_table[rb_table_index]>(frame_parms->N_RB_UL-1-first_rb[CC_id])) || + (rb_table[rb_table_index]>45)) && + (rb_table_index>0)) { + rb_table_index--; + } + + TBS = mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]); + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=rb_table[rb_table_index]; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS=TBS; + // buffer_occupancy -= TBS; + rballoc = mac_xface->computeRIV(frame_parms->N_RB_UL, + first_rb[CC_id], + rb_table[rb_table_index]); + + T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), T_INT(mcs), T_INT(first_rb[CC_id]), T_INT(rb_table[rb_table_index]), + T_INT(TBS), T_INT(ndi)); + + if (mac_eNB_get_rrc_status(module_idP,rnti) < RRC_CONNECTED) + LOG_I(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n", + module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,mcs, + first_rb[CC_id],rb_table[rb_table_index], + rb_table_index,TBS,harq_pid); + + // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB) + // increment for next UE allocation + first_rb[CC_id]+=rb_table[rb_table_index]; + //store for possible retransmission + UE_template->nb_rb_ul[harq_pid] = rb_table[rb_table_index]; + UE_sched_ctrl->ul_scheduled |= (1<head) + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED,UE_sched_ctrl->ul_scheduled); + + // adjust total UL buffer status by TBS, wait for UL sdus to do final update + LOG_D(MAC,"[eNB %d] CC_id %d UE %d/%x : adjusting ul_total_buffer, old %d, TBS %d\n", module_idP,CC_id,UE_id,rnti,UE_template->ul_total_buffer,TBS); + if (UE_template->ul_total_buffer > TBS) + UE_template->ul_total_buffer -= TBS; + else + UE_template->ul_total_buffer = 0; + LOG_D(MAC,"ul_total_buffer, new %d\n", UE_template->ul_total_buffer); + // Cyclic shift for DM RS + cshift = 0;// values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1) + + if (frame_parms->frame_type == TDD) { + switch (frame_parms->N_RB_UL) { + case 6: + ULSCH_dci = UE_template->ULSCH_DCI[harq_pid]; + + ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->type = 0; + ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->hopping = 0; + ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->rballoc = rballoc; + ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->mcs = mcs; + ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->ndi = ndi; + ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->TPC = tpc; + ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->cshift = cshift; + ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->padding = 0; + ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->dai = UE_template->DAI_ul[sched_subframe]; + ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req = cqi_req; + + add_ue_spec_dci(DCI_pdu, + ULSCH_dci, + rnti, + sizeof(DCI0_1_5MHz_TDD_1_6_t), + aggregation, + sizeof_DCI0_1_5MHz_TDD_1_6_t, + format0, + 0); + break; + + default: + case 25: + ULSCH_dci = UE_template->ULSCH_DCI[harq_pid]; + + ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->type = 0; + ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->hopping = 0; + ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->rballoc = rballoc; + ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->mcs = mcs; + ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->ndi = ndi; + ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->TPC = tpc; + ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->cshift = cshift; + ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->padding = 0; + ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->dai = UE_template->DAI_ul[sched_subframe]; + ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req = cqi_req; + + add_ue_spec_dci(DCI_pdu, + ULSCH_dci, + rnti, + sizeof(DCI0_5MHz_TDD_1_6_t), + aggregation, + sizeof_DCI0_5MHz_TDD_1_6_t, + format0, + 0); + break; + + case 50: + ULSCH_dci = UE_template->ULSCH_DCI[harq_pid]; + + ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->type = 0; + ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->hopping = 0; + ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->rballoc = rballoc; + ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->mcs = mcs; + ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->ndi = ndi; + ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->TPC = tpc; + ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->cshift = cshift; + ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->padding = 0; + ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->dai = UE_template->DAI_ul[sched_subframe]; + ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req = cqi_req; + + add_ue_spec_dci(DCI_pdu, + ULSCH_dci, + rnti, + sizeof(DCI0_10MHz_TDD_1_6_t), + aggregation, + sizeof_DCI0_10MHz_TDD_1_6_t, + format0, + 0); + break; + + case 100: + ULSCH_dci = UE_template->ULSCH_DCI[harq_pid]; + + ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->type = 0; + ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->hopping = 0; + ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->rballoc = rballoc; + ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->mcs = mcs; + ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->ndi = ndi; + ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->TPC = tpc; + ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->cshift = cshift; + ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->padding = 0; + ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->dai = UE_template->DAI_ul[sched_subframe]; + ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req = cqi_req; + + add_ue_spec_dci(DCI_pdu, + ULSCH_dci, + rnti, + sizeof(DCI0_20MHz_TDD_1_6_t), + aggregation, + sizeof_DCI0_20MHz_TDD_1_6_t, + format0, + 0); + break; + } + } // TDD + else { //FDD + switch (frame_parms->N_RB_UL) { + case 25: + default: + + ULSCH_dci = UE_template->ULSCH_DCI[harq_pid]; + + ((DCI0_5MHz_FDD_t *)ULSCH_dci)->type = 0; + ((DCI0_5MHz_FDD_t *)ULSCH_dci)->hopping = 0; + ((DCI0_5MHz_FDD_t *)ULSCH_dci)->rballoc = rballoc; + ((DCI0_5MHz_FDD_t *)ULSCH_dci)->mcs = mcs; + ((DCI0_5MHz_FDD_t *)ULSCH_dci)->ndi = ndi; + ((DCI0_5MHz_FDD_t *)ULSCH_dci)->TPC = tpc; + ((DCI0_5MHz_FDD_t *)ULSCH_dci)->cshift = cshift; + ((DCI0_5MHz_FDD_t *)ULSCH_dci)->padding = 0; + ((DCI0_5MHz_FDD_t *)ULSCH_dci)->cqi_req = cqi_req; + + add_ue_spec_dci(DCI_pdu, + ULSCH_dci, + rnti, + sizeof(DCI0_5MHz_FDD_t), + aggregation, + sizeof_DCI0_5MHz_FDD_t, + format0, + 0); + break; + + case 6: + ULSCH_dci = UE_template->ULSCH_DCI[harq_pid]; + + ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->type = 0; + ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->hopping = 0; + ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->rballoc = rballoc; + ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->mcs = mcs; + ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->ndi = ndi; + ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->TPC = tpc; + ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->cshift = cshift; + ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->padding = 0; + ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->cqi_req = cqi_req; + + add_ue_spec_dci(DCI_pdu, + ULSCH_dci, + rnti, + sizeof(DCI0_1_5MHz_FDD_t), + aggregation, + sizeof_DCI0_1_5MHz_FDD_t, + format0, + 0); + break; + + case 50: + ULSCH_dci = UE_template->ULSCH_DCI[harq_pid]; + + ((DCI0_10MHz_FDD_t *)ULSCH_dci)->type = 0; + ((DCI0_10MHz_FDD_t *)ULSCH_dci)->hopping = 0; + ((DCI0_10MHz_FDD_t *)ULSCH_dci)->rballoc = rballoc; + ((DCI0_10MHz_FDD_t *)ULSCH_dci)->mcs = mcs; + ((DCI0_10MHz_FDD_t *)ULSCH_dci)->ndi = ndi; + ((DCI0_10MHz_FDD_t *)ULSCH_dci)->TPC = tpc; + ((DCI0_10MHz_FDD_t *)ULSCH_dci)->padding = 0; + ((DCI0_10MHz_FDD_t *)ULSCH_dci)->cshift = cshift; + ((DCI0_10MHz_FDD_t *)ULSCH_dci)->cqi_req = cqi_req; + + add_ue_spec_dci(DCI_pdu, + ULSCH_dci, + rnti, + sizeof(DCI0_10MHz_FDD_t), + aggregation, + sizeof_DCI0_10MHz_FDD_t, + format0, + 0); + break; + + case 100: + ULSCH_dci = UE_template->ULSCH_DCI[harq_pid]; + + ((DCI0_20MHz_FDD_t *)ULSCH_dci)->type = 0; + ((DCI0_20MHz_FDD_t *)ULSCH_dci)->hopping = 0; + ((DCI0_20MHz_FDD_t *)ULSCH_dci)->rballoc = rballoc; + ((DCI0_20MHz_FDD_t *)ULSCH_dci)->mcs = mcs; + ((DCI0_20MHz_FDD_t *)ULSCH_dci)->ndi = ndi; + ((DCI0_20MHz_FDD_t *)ULSCH_dci)->TPC = tpc; + ((DCI0_20MHz_FDD_t *)ULSCH_dci)->padding = 0; + ((DCI0_20MHz_FDD_t *)ULSCH_dci)->cshift = cshift; + ((DCI0_20MHz_FDD_t *)ULSCH_dci)->cqi_req = cqi_req; + + add_ue_spec_dci(DCI_pdu, + ULSCH_dci, + rnti, + sizeof(DCI0_20MHz_FDD_t), + aggregation, + sizeof_DCI0_20MHz_FDD_t, + format0, + 0); + break; + + } + } + + + add_ue_ulsch_info(module_idP, + CC_id, + UE_id, + subframeP, + S_UL_SCHEDULED); + + LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP,CC_id,frameP,subframeP,UE_id); +#ifdef DEBUG + dump_dci(frame_parms, &DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci-1]); +#endif + + } + else { + T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), T_INT(mcs), T_INT(first_rb[CC_id]), T_INT(rb_table[rb_table_index]), + T_INT(round)); + + LOG_D(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d,round %d)\n", + module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,mcs, + first_rb[CC_id],rb_table[rb_table_index], + rb_table_index,TBS,harq_pid,round); + }/* + else if (round > 0) { //we schedule a retransmission + + ndi = UE_template->oldNDI_UL[harq_pid]; + + if ((round&3)==0) { + mcs = openair_daq_vars.target_ue_ul_mcs; + } else { + mcs = rvidx_tab[round&3] + 28; //not correct for round==4! + + } + + LOG_I(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE retransmission (mcs %d, first rb %d, nb_rb %d, harq_pid %d, round %d)\n", + module_idP,UE_id,rnti,CC_id,frameP,subframeP,mcs, + first_rb[CC_id],UE_template->nb_rb_ul[harq_pid], + harq_pid, round); + + rballoc = mac_xface->computeRIV(frame_parms->N_RB_UL, + first_rb[CC_id], + UE_template->nb_rb_ul[harq_pid]); + first_rb[CC_id]+=UE_template->nb_rb_ul[harq_pid]; // increment for next UE allocation + + UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission_rx+=1; + UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx_rx=UE_template->nb_rb_ul[harq_pid]; + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=UE_template->nb_rb_ul[harq_pid]; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=mcs; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs; + } + */ + + } // UE_is_to_be_scheduled + } // UE is in PUSCH + } // loop over UE_id + } // loop of CC_id +} + +// #ifdef CBA +// void schedule_ulsch_cba_rnti(module_id_t module_idP, unsigned char cooperation_flag, frame_t frameP, sub_frame_t subframeP, unsigned char sched_subframe, uint16_t *first_rb) +// { + +// eNB_MAC_INST *eNB = &eNB_mac_inst[module_idP]; +// UE_list_t *UE_list=&eNB->UE_list; +// //UE_TEMPLATE *UE_template; +// void *ULSCH_dci = NULL; +// DCI_PDU *DCI_pdu; +// uint8_t CC_id=0; +// uint8_t rb_table_index=0, aggregation=2; +// uint32_t rballoc; +// uint8_t cba_group, cba_resources; +// uint8_t required_rbs[NUM_MAX_CBA_GROUP]; +// int8_t num_cba_resources[NUM_MAX_CBA_GROUP];// , weight[NUM_MAX_CBA_GROUP] +// // the following vars should become a vector [MAX_NUM_CCs] +// LTE_DL_FRAME_PARMS *frame_parms; +// int8_t available_rbs=0; +// uint8_t remaining_rbs=0; +// uint8_t allocated_rbs=0; +// uint8_t total_UEs=UE_list->num_UEs; +// uint8_t active_UEs[NUM_MAX_CBA_GROUP]; +// uint8_t total_groups=eNB_mac_inst[module_idP].common_channels[CC_id].num_active_cba_groups; +// int min_rb_unit=2; +// uint8_t cba_policy=CBA_ES; +// int UE_id; +// uint8_t mcs[NUM_MAX_CBA_GROUP]; +// uint32_t total_cba_resources=0; +// uint32_t total_rbs=0; +// // We compute the weight of each group and initialize some variables + +// // loop over all active UEs +// // for (UE_id=UE_list->head_ul;UE_id>=0;UE_id=UE_list->next_ul[UE_id]) { + +// for (cba_group=0; cba_groupget_lte_frame_parms(module_idP,CC_id); +// available_rbs=frame_parms->N_RB_DL-1-first_rb[CC_id]; +// remaining_rbs=available_rbs; +// total_groups=eNB_mac_inst[module_idP].common_channels[CC_id].num_active_cba_groups; +// min_rb_unit=get_min_rb_unit(module_idP,CC_id); + +// if (available_rbs < min_rb_unit ) +// continue; + +// // remove this condition later +// // cba group template uses the exisitng UE template, and thus if a UE +// // is scheduled, the correspodning group can't be used for CBA +// // this can be fixed later +// if (total_groups > 0) { +// DCI_pdu = &eNB_mac_inst[module_idP].common_channels[CC_id].DCI_pdu; + +// for (cba_group=0; +// (cba_group (1<head_ul; UE_id>=0; UE_id=UE_list->next_ul[UE_id]) { +// if (UE_RNTI(module_idP,UE_id)==NOT_A_RNTI) +// continue; + +// // simple UE identity based grouping +// if ((UE_id % total_groups) == cba_group) { // this could be simplifed to active_UEs[UE_id % total_groups]++; +// if ((mac_eNB_get_rrc_status(module_idP,rnti) > RRC_CONNECTED) && +// (UE_is_to_be_scheduled(module_idP,CC_id,UE_id) == 0)) { +// active_UEs[cba_group]++; +// } +// } + +// if (UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul <= 2) { +// mcs[cba_group]= 8; // apply fixed scheduling +// } else if ((UE_id % total_groups) == cba_group) { +// mcs[cba_group]= cmin(mcs[cba_group],UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul); +// } +// } + +// mcs[cba_group]= mcs[cba_group];//cmin(mcs[cba_group],openair_daq_vars.target_ue_ul_mcs); + +// if (available_rbs < min_rb_unit ) +// break; + +// // If the group needs some resource +// // determine the total number of allocations (one or multiple DCIs): to be refined +// if ((active_UEs[cba_group] > 0) && (eNB_mac_inst[module_idP].common_channels[CC_id].cba_rnti[cba_group] != 0)) { +// // to be refined in case of : total_UEs >> weight[cba_group]*available_rbs + +// switch(cba_policy) { +// case CBA_ES: +// required_rbs[cba_group] = (uint8_t)floor(available_rbs/total_groups); // allocate equally among groups +// num_cba_resources[cba_group]=1; +// break; + +// // can't have more than one allocation for the same group/UE +// /* case CBA_ES_S: +// required_rbs[cba_group] = (uint8_t)floor(available_rbs/total_groups); // allocate equally among groups +// if (required_rbs[cba_group] > min_rb_unit) +// num_cba_resources[cba_group]=(uint8_t)(required_rbs[cba_group]/ min_rb_unit); +// break;*/ +// case CBA_PF: +// required_rbs[cba_group] = (uint8_t)floor((active_UEs[cba_group]*available_rbs)/total_UEs); +// num_cba_resources[cba_group]=1; +// break; +// /* case CBA_PF_S: +// required_rbs[cba_group] = (uint8_t)ceil((active_UEs[cba_group]*available_rbs)/total_UEs); +// if (required_rbs[cba_group] > min_rb_unit) +// num_cba_resources[cba_group]=(uint8_t) floor(required_rbs[cba_group] / min_rb_unit); +// break;*/ + +// default: +// LOG_W(MAC,"unknown CBA policy\n"); +// break; +// } + +// total_cba_resources+=num_cba_resources[cba_group]; +// total_rbs+=required_rbs[cba_group]; + +// /* while ((remaining_rbs < required_rbs[cba_group]) && +// (required_rbs[cba_group] > 0) && +// (required_rbs[cba_group] < min_rb_unit )) +// required_rbs[cba_group]--; +// */ + +// /* +// while (rb_table[rb_table_index] < required_rbs[cba_group]) +// rb_table_index++; + +// while (rb_table[rb_table_index] > remaining_rbs ) +// rb_table_index--; + +// remaining_rbs-=rb_table[rb_table_index]; +// required_rbs[cba_group]=rb_table[rb_table_index]; +// */ +// // num_cba_resources[cba_group]=1; + +// } +// } + +// // phase 2 reduce the number of cba allocations among the groups +// cba_group=0; + +// if (total_cba_resources <= 0) { +// return; +// } + +// // increase rb if any left: to be done +// cba_group=0; + +// while (total_rbs < available_rbs - 1 ) { +// required_rbs[cba_group%total_groups]++; +// total_rbs++; +// cba_group++; +// } + +// // phase 3: +// for (cba_group=0; cba_group remaining_rbs ) { +// rb_table_index--; +// } + +// remaining_rbs-=rb_table[rb_table_index]; +// allocated_rbs=rb_table[rb_table_index]; + +// rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_UL, +// first_rb[CC_id], +// rb_table[rb_table_index]); + +// first_rb[CC_id]+=rb_table[rb_table_index]; +// LOG_N(MAC, +// "[eNB %d] CC_id %d Frame %d, subframeP %d: schedule CBA access %d rnti %x, total/required/allocated/remaining rbs (%d/%d/%d/%d), mcs %d, rballoc %d\n", +// module_idP, CC_id, frameP, subframeP, cba_group,eNB_mac_inst[module_idP].common_channels[CC_id].cba_rnti[cba_group], +// available_rbs, required_rbs[cba_group], allocated_rbs, remaining_rbs, +// mcs[cba_group],rballoc); + +// switch (frame_parms->N_RB_UL) { +// case 6: +// mac_xface->macphy_exit("[MAC][eNB] CBA RB=6 not supported \n"); +// break; + +// case 25: +// if (frame_parms->frame_type == TDD) { +// ULSCH_dci = UE_list->UE_template[CC_id][cba_group].ULSCH_DCI[0]; + +// ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->type = 0; +// ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->hopping = 0; +// ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->rballoc = rballoc; +// ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->mcs = mcs[cba_group]; +// ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->ndi = 1; +// ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->TPC = 1;//tpc; +// ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->cshift = cba_group; +// ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->dai = UE_list->UE_template[CC_id][cba_group].DAI_ul[sched_subframe]; +// ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req = 1; + +// //add_ue_spec_dci +// add_common_dci(DCI_pdu, +// ULSCH_dci, +// eNB_mac_inst[module_idP].common_channels[CC_id].cba_rnti[cba_group], +// sizeof(DCI0_5MHz_TDD_1_6_t), +// aggregation, +// sizeof_DCI0_5MHz_TDD_1_6_t, +// format0, +// 0); +// } else { +// ULSCH_dci = UE_list->UE_template[CC_id][cba_group].ULSCH_DCI[0]; + +// ((DCI0_5MHz_FDD_t *)ULSCH_dci)->type = 0; +// ((DCI0_5MHz_FDD_t *)ULSCH_dci)->hopping = 0; +// ((DCI0_5MHz_FDD_t *)ULSCH_dci)->rballoc = rballoc; +// ((DCI0_5MHz_FDD_t *)ULSCH_dci)->mcs = mcs[cba_group]; +// ((DCI0_5MHz_FDD_t *)ULSCH_dci)->ndi = 1; +// ((DCI0_5MHz_FDD_t *)ULSCH_dci)->TPC = 1;//tpc; +// ((DCI0_5MHz_FDD_t *)ULSCH_dci)->cshift = cba_group; +// ((DCI0_5MHz_FDD_t *)ULSCH_dci)->cqi_req = 1; + +// //add_ue_spec_dci +// add_common_dci(DCI_pdu, +// ULSCH_dci, +// eNB_mac_inst[module_idP].common_channels[CC_id].cba_rnti[cba_group], +// sizeof(DCI0_5MHz_FDD_t), +// aggregation, +// sizeof_DCI0_5MHz_FDD_t, +// format0, +// 0); +// } + +// LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for CBA group %d, RB 25 format 0\n", module_idP,CC_id,frameP,subframeP,cba_group); +// break; + +// case 50: +// if (frame_parms->frame_type == TDD) { +// ULSCH_dci = UE_list->UE_template[CC_id][cba_group].ULSCH_DCI[0]; + +// ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->type = 0; +// ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->hopping = 0; +// ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->rballoc = rballoc; +// ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->mcs = mcs[cba_group]; +// ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->ndi = 1; +// ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->TPC = 1;//tpc; +// ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->cshift = cba_group; +// ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->dai = UE_list->UE_template[CC_id][cba_group].DAI_ul[sched_subframe]; +// ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req = 1; + +// //add_ue_spec_dci +// add_common_dci(DCI_pdu, +// ULSCH_dci, +// eNB_mac_inst[module_idP].common_channels[CC_id].cba_rnti[cba_group], +// sizeof(DCI0_10MHz_TDD_1_6_t), +// aggregation, +// sizeof_DCI0_10MHz_TDD_1_6_t, +// format0, +// 0); +// } else { +// ULSCH_dci = UE_list->UE_template[CC_id][cba_group].ULSCH_DCI[0]; + +// ((DCI0_10MHz_FDD_t *)ULSCH_dci)->type = 0; +// ((DCI0_10MHz_FDD_t *)ULSCH_dci)->hopping = 0; +// ((DCI0_10MHz_FDD_t *)ULSCH_dci)->rballoc = rballoc; +// ((DCI0_10MHz_FDD_t *)ULSCH_dci)->mcs = mcs[cba_group]; +// ((DCI0_10MHz_FDD_t *)ULSCH_dci)->ndi = 1; +// ((DCI0_10MHz_FDD_t *)ULSCH_dci)->TPC = 1;//tpc; +// ((DCI0_10MHz_FDD_t *)ULSCH_dci)->cshift = cba_group; +// ((DCI0_10MHz_FDD_t *)ULSCH_dci)->cqi_req = 1; + +// //add_ue_spec_dci +// add_common_dci(DCI_pdu, +// ULSCH_dci, +// eNB_mac_inst[module_idP].common_channels[CC_id].cba_rnti[cba_group], +// sizeof(DCI0_10MHz_FDD_t), +// aggregation, +// sizeof_DCI0_10MHz_FDD_t, +// format0, +// 0); +// } + +// LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for CBA group %d, RB 50 format 0\n", module_idP,CC_id,frameP,subframeP,cba_group); +// break; + +// case 100: +// mac_xface->macphy_exit("[MAC][eNB] CBA RB=100 not supported \n"); +// break; + +// default: +// break; +// } + +// // break;// for the moment only schedule one +// } +// } +// } +// } +// } +// #endif From 5ce9858d63bf3c0f210816dd999b607aa37e57b3 Mon Sep 17 00:00:00 2001 From: shahab SHARIATBAGHERI Date: Fri, 21 Apr 2017 13:22:20 +0200 Subject: [PATCH 012/195] uplink scheduling --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 33 +++++++++++++++ openair2/ENB_APP/MESSAGES/V2/flexran.proto | 4 +- openair2/ENB_APP/MESSAGES/V2/header.proto | 11 ++--- openair2/LAYER2/MAC/eNB_scheduler.c | 40 +++++++++---------- .../MAC/flexran_agent_scheduler_ulsch_ue.c | 6 +++ 5 files changed, 67 insertions(+), 27 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 405837061a..cd81abca3f 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -1044,6 +1044,39 @@ int flexran_agent_mac_destroy_dl_config(Protocol__FlexranMessage *msg) { return -1; } +int flexran_agent_mac_create_empty_ul_config(mid_t mod_id, Protocol__FlexranMessage **msg) { + + int xid = 0; + Protocol__FlexHeader *header; + if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_UL_MAC_CONFIG, &header) != 0) + goto error; + + Protocol__FlexUlMacConfig *ul_mac_config_msg; + ul_mac_config_msg = malloc(sizeof(Protocol__FlexUlMacConfig)); + if (ul_mac_config_msg == NULL) { + goto error; + } + protocol__flex_ul_mac_config__init(ul_mac_config_msg); + + ul_mac_config_msg->header = header; + ul_mac_config_msg->has_sfn_sf = 1; + ul_mac_config_msg->sfn_sf = flexran_get_sfn_sf(mod_id); + + *msg = malloc(sizeof(Protocol__FlexranMessage)); + if(*msg == NULL) + goto error; + protocol__flexran_message__init(*msg); + (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_UL_MAC_CONFIG_MSG; + (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE; + (*msg)->ul_mac_config_msg = ul_mac_config_msg; + + return 0; + + error: + return -1; +} + + void flexran_agent_get_pending_dl_mac_config(mid_t mod_id, Protocol__FlexranMessage **msg) { struct lfds700_misc_prng_state ls; diff --git a/openair2/ENB_APP/MESSAGES/V2/flexran.proto b/openair2/ENB_APP/MESSAGES/V2/flexran.proto index caee626a73..01728bb268 100644 --- a/openair2/ENB_APP/MESSAGES/V2/flexran.proto +++ b/openair2/ENB_APP/MESSAGES/V2/flexran.proto @@ -24,12 +24,12 @@ message flexran_message { flex_ue_config_reply ue_config_reply_msg = 11; flex_lc_config_request lc_config_request_msg = 12; flex_lc_config_reply lc_config_reply_msg = 13; - flex_dl_mac_config dl_mac_config_msg = 14; - flex_ul_mac_config ul_mac_config_msg = 19; + flex_dl_mac_config dl_mac_config_msg = 14; flex_ue_state_change ue_state_change_msg = 15; flex_control_delegation control_delegation_msg = 16; flex_agent_reconfiguration agent_reconfiguration_msg = 17; flex_rrc_triggering rrc_triggering = 18; + flex_ul_mac_config ul_mac_config_msg = 19; } } diff --git a/openair2/ENB_APP/MESSAGES/V2/header.proto b/openair2/ENB_APP/MESSAGES/V2/header.proto index 468dcd201e..1650030e32 100644 --- a/openair2/ENB_APP/MESSAGES/V2/header.proto +++ b/openair2/ENB_APP/MESSAGES/V2/header.proto @@ -32,14 +32,15 @@ enum flex_type { //Controller command messages FLPT_DL_MAC_CONFIG = 13; - + FLPT_UL_MAC_CONFIG = 14 + ; // UE state change messages - FLPT_UE_STATE_CHANGE = 14; + FLPT_UE_STATE_CHANGE = 15; // Control delegation messages - FLPT_DELEGATE_CONTROL = 15; - FLPT_RECONFIGURE_AGENT = 16; - FLPT_RRC_TRIGGERING = 17; + FLPT_DELEGATE_CONTROL = 16; + FLPT_RECONFIGURE_AGENT = 17; + FLPT_RRC_TRIGGERING = 18; } diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 7250d66f07..56052b050a 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -398,7 +398,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4);//,calibration_flag); #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,4); } #endif @@ -438,7 +438,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,7); } #endif @@ -453,7 +453,7 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,8); } #endif @@ -472,7 +472,7 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,1,5); } #endif @@ -511,7 +511,7 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,2,6); } #endif @@ -553,7 +553,7 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,7); } #endif @@ -591,7 +591,7 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,3,7); } #endif @@ -634,7 +634,7 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,8); } #endif @@ -679,7 +679,7 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,4,8); } #endif @@ -724,7 +724,7 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,5,9); } #endif @@ -796,7 +796,7 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,2); } #endif @@ -812,7 +812,7 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,3); } #endif @@ -879,7 +879,7 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,6,0); } #endif @@ -971,7 +971,7 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,7,1); } #endif @@ -1018,7 +1018,7 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,2); } #endif @@ -1054,7 +1054,7 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,8,2); } #endif @@ -1094,7 +1094,7 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,3); } #endif @@ -1128,7 +1128,7 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,3); } #endif @@ -1161,7 +1161,7 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,4); } #endif @@ -1222,7 +1222,7 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,9,3); } #endif diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c index 2abd09024b..a45f81fdaa 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c @@ -790,6 +790,7 @@ void flexran_agent_schedule_ulsch_ue_spec(module_id_t module_idP, unsigned char sched_subframe) { +// flexran_agent_mac_create_empty_ul_config(module_idP, ul_info); uint16_t first_rb[MAX_NUM_CCs],i; int CC_id; @@ -884,6 +885,11 @@ void flexran_agent_schedule_ulsch_rnti(module_id_t module_idP, // LOG_I(MAC,"entering ulsch preprocesor\n"); + + + + + _ulsch_scheduler_pre_processor(module_idP, frameP, subframeP, From fdac4d178be4b250787a5779d2da700128627aa2 Mon Sep 17 00:00:00 2001 From: shahab SHARIATBAGHERI Date: Sat, 22 Apr 2017 12:43:04 +0200 Subject: [PATCH 013/195] uplink harq api --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 39 +++++ .../CONTROL_MODULES/MAC/flexran_agent_mac.h | 4 + .../MAC/flexran_agent_mac_defs.h | 2 +- openair2/ENB_APP/MESSAGES/V2/flexran.proto | 4 +- openair2/ENB_APP/MESSAGES/V2/header.proto | 13 +- openair2/ENB_APP/flexran_agent_ran_api.c | 20 ++- openair2/ENB_APP/flexran_agent_ran_api.h | 2 +- openair2/LAYER2/MAC/eNB_scheduler.c | 147 +++++++++++++----- openair2/LAYER2/MAC/flexran_agent_mac_proto.h | 4 +- .../MAC/flexran_agent_scheduler_dataplane.c | 12 +- .../MAC/flexran_agent_scheduler_dlsch_ue.c | 6 +- .../MAC/flexran_agent_scheduler_ulsch_ue.c | 13 +- 12 files changed, 191 insertions(+), 75 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index cd81abca3f..db9af62eac 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -1077,6 +1077,45 @@ int flexran_agent_mac_create_empty_ul_config(mid_t mod_id, Protocol__FlexranMess } +int flexran_agent_mac_destroy_ul_config(Protocol__FlexranMessage *msg) { + int i,j, k; + if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_UL_MAC_CONFIG_MSG) + goto error; + + Protocol__FlexUlDci *ul_dci; + + free(msg->ul_mac_config_msg->header); + for (i = 0; i < msg->ul_mac_config_msg->n_ul_ue_data; i++) { + // TODO uplink rlc ... + // free(msg->ul_mac_config_msg->dl_ue_data[i]->ce_bitmap); + // for (j = 0; j < msg->ul_mac_config_msg->ul_ue_data[i]->n_rlc_pdu; j++) { + // for (k = 0; k < msg->ul_mac_config_msg->ul_ue_data[i]->rlc_pdu[j]->n_rlc_pdu_tb; k++) { + // free(msg->ul_mac_config_msg->dl_ue_data[i]->rlc_pdu[j]->rlc_pdu_tb[k]); + // } + // free(msg->ul_mac_config_msg->ul_ue_data[i]->rlc_pdu[j]->rlc_pdu_tb); + // free(msg->ul_mac_config_msg->ul_ue_data[i]->rlc_pdu[j]); + // } + // free(msg->ul_mac_config_msg->ul_ue_data[i]->rlc_pdu); + ul_dci = msg->ul_mac_config_msg->ul_ue_data[i]->ul_dci; + // free(dl_dci->tbs_size); + // free(ul_dci->mcs); + // free(ul_dci->ndi); + // free(ul_dci->rv); + // free(ul_dci); + free(msg->ul_mac_config_msg->ul_ue_data[i]); + } + free(msg->ul_mac_config_msg->ul_ue_data); + + free(msg->ul_mac_config_msg); + free(msg); + + return 0; + + error: + return -1; +} + + void flexran_agent_get_pending_dl_mac_config(mid_t mod_id, Protocol__FlexranMessage **msg) { struct lfds700_misc_prng_state ls; diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h index d2db860ce4..0dcee577f5 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h @@ -57,6 +57,10 @@ int flexran_agent_mac_destroy_stats_reply(Protocol__FlexranMessage *msg); int flexran_agent_mac_create_empty_dl_config(mid_t mod_id, Protocol__FlexranMessage **msg); int flexran_agent_mac_destroy_dl_config(Protocol__FlexranMessage *msg); +/* UL MAC scheduling decision protocol message constructor (empty command) and destructor */ +int flexran_agent_mac_create_empty_ul_config(mid_t mod_id, Protocol__FlexranMessage **msg); +int flexran_agent_mac_destroy_ul_config(Protocol__FlexranMessage *msg); + int flexran_agent_mac_handle_dl_mac_config(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg); diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h index ab6bf57417..49ef7f0fb7 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h @@ -63,7 +63,7 @@ typedef struct { void (*flexran_agent_schedule_ul_spec)(mid_t module_idP, uint32_t frameP, unsigned char cooperation_flag, uint32_t subframeP, - unsigned char sched_subframe); + unsigned char sched_subframe, Protocol__FlexranMessage **ul_info); /// Notify the controller for a state change of a particular UE, by sending the proper /// UE state change message (ACTIVATION, DEACTIVATION, HANDOVER) diff --git a/openair2/ENB_APP/MESSAGES/V2/flexran.proto b/openair2/ENB_APP/MESSAGES/V2/flexran.proto index 01728bb268..8ebfc7df8b 100644 --- a/openair2/ENB_APP/MESSAGES/V2/flexran.proto +++ b/openair2/ENB_APP/MESSAGES/V2/flexran.proto @@ -168,8 +168,8 @@ message flex_dl_mac_config { message flex_ul_mac_config { optional flex_header header = 1; - optional uint32 sfn_sf = 2; - repeated flex_ul_data ul_ue_data = 3; + optional uint32 sfn_sf = 2; + repeated flex_ul_data ul_ue_data = 3; } diff --git a/openair2/ENB_APP/MESSAGES/V2/header.proto b/openair2/ENB_APP/MESSAGES/V2/header.proto index 1650030e32..79d541200c 100644 --- a/openair2/ENB_APP/MESSAGES/V2/header.proto +++ b/openair2/ENB_APP/MESSAGES/V2/header.proto @@ -32,15 +32,14 @@ enum flex_type { //Controller command messages FLPT_DL_MAC_CONFIG = 13; - FLPT_UL_MAC_CONFIG = 14 - ; + // UE state change messages - FLPT_UE_STATE_CHANGE = 15; + FLPT_UE_STATE_CHANGE = 14; // Control delegation messages - FLPT_DELEGATE_CONTROL = 16; - FLPT_RECONFIGURE_AGENT = 17; - FLPT_RRC_TRIGGERING = 18; - + FLPT_DELEGATE_CONTROL = 15; + FLPT_RECONFIGURE_AGENT = 16; + FLPT_RRC_TRIGGERING = 17; + FLPT_UL_MAC_CONFIG = 18; } diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 9602b041c3..334dd3cb9a 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -299,8 +299,9 @@ int flexran_get_harq(const mid_t mod_id, const mid_t ue_id, const int frame, const uint8_t subframe, - uint8_t *id, - uint8_t *round) { //flag_id_status = 0 then id, else status + uint8_t *pid, + uint8_t *round, + const uint8_t harq_flag) { //flag_id_status = 0 then id, else status /*TODO: Add int TB in function parameters to get the status of the second TB. This can be done to by editing in * get_ue_active_harq_pid function in line 272 file: phy_procedures_lte_eNB.c to add * DLSCH_ptr = PHY_vars_eNB_g[Mod_id][CC_id]->dlsch_eNB[(uint32_t)UE_id][1];*/ @@ -310,10 +311,21 @@ int flexran_get_harq(const mid_t mod_id, uint16_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + if (harq_flag == openair_harq_DL){ - mac_xface->get_ue_active_harq_pid(mod_id,CC_id,rnti,frame,subframe,&harq_pid,&harq_round,openair_harq_DL); + mac_xface->get_ue_active_harq_pid(mod_id,CC_id,rnti,frame,subframe,&harq_pid,&harq_round,openair_harq_DL); - *id = harq_pid; + } else if (harq_flag == openair_harq_UL){ + + mac_xface->get_ue_active_harq_pid(mod_id,CC_id,rnti,frame,subframe,&harq_pid,&round,openair_harq_UL); + } + else { + + LOG_W(FLEXRAN_AGENT,"harq_flag is not recongnized"); + } + + + *pid = harq_pid; *round = harq_round; /* if (round > 0) { */ /* *status = 1; */ diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 8a7d6dbaf7..e80ed44ce9 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -187,7 +187,7 @@ int flexran_get_ue_pmi(mid_t mod_id); a designated frame and subframe. Returns 0 for success. The id and the status of the HARQ process are stored in id and status respectively */ int flexran_get_harq(const mid_t mod_id, const uint8_t CC_id, const mid_t ue_id, - const int frame, const uint8_t subframe, unsigned char *id, unsigned char *round); + const int frame, const uint8_t subframe, unsigned char *id, unsigned char *round,const uint8_t harq_flag); /* Uplink power control management*/ int flexran_get_p0_pucch_dbm(mid_t mod_id, mid_t ue_id, int CC_id); diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 56052b050a..bf69d7c8ef 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -386,8 +386,10 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, schedule_ulsch(module_idP,frameP,cooperation_flag,0,4);//,calibration_flag); #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4, &msg); } + + flexran_agent_mac_destroy_ul_config(msg); #endif @@ -398,8 +400,10 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4);//,calibration_flag); #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,4); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,4, &msg); } + + flexran_agent_mac_destroy_ul_config(msg); #endif } @@ -415,7 +419,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, mbsfn_status, &msg); - flexran_apply_dl_scheduling_decisions(module_idP, + flexran_apply_scheduling_decisions(module_idP, frameP, subframeP, mbsfn_status, @@ -438,9 +442,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,7); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,7, &msg); } + + flexran_agent_mac_destroy_ul_config(msg); + #endif #ifndef FLEXRAN_AGENT_SB_IF fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); @@ -453,9 +460,11 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,8); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,8, &msg); } + flexran_agent_mac_destroy_ul_config(msg); + #endif #ifndef FLEXRAN_AGENT_SB_IF @@ -472,9 +481,12 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,1,5); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,1,5, &msg); } + + flexran_agent_mac_destroy_ul_config(msg); + #endif #ifndef FLEXRAN_AGENT_SB_IF @@ -489,7 +501,7 @@ if (mac_agent_registered[module_idP]){ mbsfn_status, &msg); - flexran_apply_dl_scheduling_decisions(module_idP, + flexran_apply_scheduling_decisions(module_idP, frameP, subframeP, mbsfn_status, @@ -511,9 +523,13 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,2,6); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,2,6, &msg); } + + + flexran_agent_mac_destroy_ul_config(msg); + #endif #ifndef FLEXRAN_AGENT_SB_IF @@ -528,7 +544,7 @@ if (mac_agent_registered[module_idP]){ mbsfn_status, &msg); - flexran_apply_dl_scheduling_decisions(module_idP, + flexran_apply_scheduling_decisions(module_idP, frameP, subframeP, mbsfn_status, @@ -553,9 +569,12 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,7); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,7, &msg); } + + flexran_agent_mac_destroy_ul_config(msg); + #endif // no break here! @@ -572,7 +591,7 @@ if (mac_agent_registered[module_idP]){ mbsfn_status, &msg); - flexran_apply_dl_scheduling_decisions(module_idP, + flexran_apply_scheduling_decisions(module_idP, frameP, subframeP, mbsfn_status, @@ -591,9 +610,13 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,3,7); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,3,7, &msg); } + + + flexran_agent_mac_destroy_ul_config(msg); + #endif #ifndef FLEXRAN_AGENT_SB_IF @@ -608,7 +631,7 @@ if (mac_agent_registered[module_idP]){ mbsfn_status, &msg); - flexran_apply_dl_scheduling_decisions(module_idP, + flexran_apply_scheduling_decisions(module_idP, frameP, subframeP, mbsfn_status, @@ -634,9 +657,12 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,8); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,8, &msg); } + + flexran_agent_mac_destroy_ul_config(msg); + #endif // no break here! @@ -659,7 +685,7 @@ if (mac_agent_registered[module_idP]){ mbsfn_status, &msg); - flexran_apply_dl_scheduling_decisions(module_idP, + flexran_apply_scheduling_decisions(module_idP, frameP, subframeP, mbsfn_status, @@ -679,9 +705,12 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,4,8); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,4,8, &msg); } + + flexran_agent_mac_destroy_ul_config(msg); + #endif #ifndef FLEXRAN_AGENT_SB_IF @@ -696,7 +725,7 @@ if (mac_agent_registered[module_idP]){ mbsfn_status, &msg); - flexran_apply_dl_scheduling_decisions(module_idP, + flexran_apply_scheduling_decisions(module_idP, frameP, subframeP, mbsfn_status, @@ -724,9 +753,12 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,5,9); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,5,9, &msg); } + + flexran_agent_mac_destroy_ul_config(msg); + #endif #ifndef FLEXRAN_AGENT_SB_IF @@ -741,7 +773,7 @@ if (mac_agent_registered[module_idP]){ mbsfn_status, &msg); - flexran_apply_dl_scheduling_decisions(module_idP, + flexran_apply_scheduling_decisions(module_idP, frameP, subframeP, mbsfn_status, @@ -768,7 +800,7 @@ if (mac_agent_registered[module_idP]){ mbsfn_status, &msg); - flexran_apply_dl_scheduling_decisions(module_idP, + flexran_apply_scheduling_decisions(module_idP, frameP, subframeP, mbsfn_status, @@ -796,9 +828,12 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,2); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,2, &msg); } + + flexran_agent_mac_destroy_ul_config(msg); + #endif // schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); #ifndef FLEXRAN_AGENT_SB_IF @@ -812,9 +847,12 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,3); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,3, &msg); } + + flexran_agent_mac_destroy_ul_config(msg); + #endif // schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); #ifndef FLEXRAN_AGENT_SB_IF @@ -836,7 +874,7 @@ if (mac_agent_registered[module_idP]){ mbsfn_status, &msg); - flexran_apply_dl_scheduling_decisions(module_idP, + flexran_apply_scheduling_decisions(module_idP, frameP, subframeP, mbsfn_status, @@ -860,7 +898,7 @@ if (mac_agent_registered[module_idP]){ mbsfn_status, &msg); - flexran_apply_dl_scheduling_decisions(module_idP, + flexran_apply_scheduling_decisions(module_idP, frameP, subframeP, mbsfn_status, @@ -879,9 +917,12 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,6,0); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,6,0, &msg); } + + flexran_agent_mac_destroy_ul_config(msg); + #endif #ifndef FLEXRAN_AGENT_SB_IF @@ -896,7 +937,7 @@ if (mac_agent_registered[module_idP]){ mbsfn_status, &msg); - flexran_apply_dl_scheduling_decisions(module_idP, + flexran_apply_scheduling_decisions(module_idP, frameP, subframeP, mbsfn_status, @@ -929,7 +970,7 @@ if (mac_agent_registered[module_idP]){ mbsfn_status, &msg); - flexran_apply_dl_scheduling_decisions(module_idP, + flexran_apply_scheduling_decisions(module_idP, frameP, subframeP, mbsfn_status, @@ -952,7 +993,7 @@ if (mac_agent_registered[module_idP]){ mbsfn_status, &msg); - flexran_apply_dl_scheduling_decisions(module_idP, + flexran_apply_scheduling_decisions(module_idP, frameP, subframeP, mbsfn_status, @@ -971,9 +1012,12 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,7,1); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,7,1, &msg); } + + flexran_agent_mac_destroy_ul_config(msg); + #endif #ifndef FLEXRAN_AGENT_SB_IF @@ -988,7 +1032,7 @@ if (mac_agent_registered[module_idP]){ mbsfn_status, &msg); - flexran_apply_dl_scheduling_decisions(module_idP, + flexran_apply_scheduling_decisions(module_idP, frameP, subframeP, mbsfn_status, @@ -1018,9 +1062,11 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,2); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,2, &msg); } + flexran_agent_mac_destroy_ul_config(msg); + #endif #ifndef FLEXRAN_AGENT_SB_IF @@ -1035,7 +1081,7 @@ if (mac_agent_registered[module_idP]){ mbsfn_status, &msg); - flexran_apply_dl_scheduling_decisions(module_idP, + flexran_apply_scheduling_decisions(module_idP, frameP, subframeP, mbsfn_status, @@ -1054,9 +1100,12 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,8,2); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,8,2, &msg); } + + flexran_agent_mac_destroy_ul_config(msg); + #endif #ifndef FLEXRAN_AGENT_SB_IF @@ -1071,7 +1120,7 @@ if (mac_agent_registered[module_idP]){ mbsfn_status, &msg); - flexran_apply_dl_scheduling_decisions(module_idP, + flexran_apply_scheduling_decisions(module_idP, frameP, subframeP, mbsfn_status, @@ -1094,9 +1143,12 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,3); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,3, &msg); } + + flexran_agent_mac_destroy_ul_config(msg); + #endif schedule_RA(module_idP,frameP,subframeP,7); // 7 = Msg3 subframeP, not #ifndef FLEXRAN_AGENT_SB_IF @@ -1111,7 +1163,7 @@ if (mac_agent_registered[module_idP]){ mbsfn_status, &msg); - flexran_apply_dl_scheduling_decisions(module_idP, + flexran_apply_scheduling_decisions(module_idP, frameP, subframeP, mbsfn_status, @@ -1128,9 +1180,12 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,3); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,3, &msg); } + + flexran_agent_mac_destroy_ul_config(msg); + #endif #ifndef FLEXRAN_AGENT_SB_IF @@ -1145,7 +1200,7 @@ if (mac_agent_registered[module_idP]){ mbsfn_status, &msg); - flexran_apply_dl_scheduling_decisions(module_idP, + flexran_apply_scheduling_decisions(module_idP, frameP, subframeP, mbsfn_status, @@ -1161,9 +1216,12 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,4); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,subframeP,4, &msg); } + + flexran_agent_mac_destroy_ul_config(msg); + #endif //schedule_RA(module_idP,frameP,subframeP); #ifndef FLEXRAN_AGENT_SB_IF @@ -1178,7 +1236,7 @@ if (mac_agent_registered[module_idP]){ mbsfn_status, &msg); - flexran_apply_dl_scheduling_decisions(module_idP, + flexran_apply_scheduling_decisions(module_idP, frameP, subframeP, mbsfn_status, @@ -1203,7 +1261,7 @@ if (mac_agent_registered[module_idP]){ mbsfn_status, &msg); - flexran_apply_dl_scheduling_decisions(module_idP, + flexran_apply_scheduling_decisions(module_idP, frameP, subframeP, mbsfn_status, @@ -1222,9 +1280,12 @@ if (mac_agent_registered[module_idP]){ #else if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,9,3); + agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,9,3, &msg); } + + flexran_agent_mac_destroy_ul_config(msg); + #endif #ifndef FLEXRAN_AGENT_SB_IF @@ -1239,7 +1300,7 @@ if (mac_agent_registered[module_idP]){ mbsfn_status, &msg); - flexran_apply_dl_scheduling_decisions(module_idP, + flexran_apply_scheduling_decisions(module_idP, frameP, subframeP, mbsfn_status, diff --git a/openair2/LAYER2/MAC/flexran_agent_mac_proto.h b/openair2/LAYER2/MAC/flexran_agent_mac_proto.h index 8a9d5971e3..7b5c402b61 100644 --- a/openair2/LAYER2/MAC/flexran_agent_mac_proto.h +++ b/openair2/LAYER2/MAC/flexran_agent_mac_proto.h @@ -174,12 +174,12 @@ void flexran_schedule_ue_spec_default(mid_t mod_id, uint32_t frame, uint32_t sub void flexran_agent_schedule_ulsch_ue_spec(module_id_t module_idP, frame_t frameP, unsigned char cooperation_flag, sub_frame_t subframeP, - unsigned char sched_subframe); + unsigned char sched_subframe, Protocol__FlexranMessage **ul_info); /* * Data plane function for applying the DL decisions of the scheduler */ -void flexran_apply_dl_scheduling_decisions(mid_t mod_id, uint32_t frame, uint32_t subframe, int *mbsfn_flag, +void flexran_apply_scheduling_decisions(mid_t mod_id, uint32_t frame, uint32_t subframe, int *mbsfn_flag, Protocol__FlexranMessage *dl_scheduling_info); /* diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dataplane.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_dataplane.c index 38f39e50e1..ba5aadcb5b 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dataplane.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_dataplane.c @@ -59,28 +59,28 @@ #include "SIMULATION/TOOLS/defs.h" // for taus -void flexran_apply_dl_scheduling_decisions(mid_t mod_id, +void flexran_apply_scheduling_decisions(mid_t mod_id, uint32_t frame, uint32_t subframe, int *mbsfn_flag, Protocol__FlexranMessage *dl_scheduling_info) { - Protocol__FlexDlMacConfig *mac_config = dl_scheduling_info->dl_mac_config_msg; + Protocol__FlexDlMacConfig *mac_dl_config = dl_scheduling_info->dl_mac_config_msg; // Check if there is anything to schedule for random access - if (mac_config->n_dl_rar > 0) { + if (mac_dl_config->n_dl_rar > 0) { /*TODO: call the random access data plane function*/ } // Check if there is anything to schedule for paging/broadcast - if (mac_config->n_dl_broadcast > 0) { + if (mac_dl_config->n_dl_broadcast > 0) { /*TODO: call the broadcast/paging data plane function*/ } // Check if there is anything to schedule for the UEs - if (mac_config->n_dl_ue_data > 0) { + if (mac_dl_config->n_dl_ue_data > 0) { flexran_apply_ue_spec_scheduling_decisions(mod_id, frame, subframe, mbsfn_flag, - mac_config->n_dl_ue_data, mac_config->dl_ue_data); + mac_dl_config->n_dl_ue_data, mac_dl_config->dl_ue_data); } } diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c index 81c18a26c0..fc3906ab6f 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c @@ -526,7 +526,7 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id, CC_id = UE_list->ordered_CCids[ii][UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; ue_sched_ctl->max_allowed_rbs[CC_id]=nb_rbs_allowed_slice[CC_id][slice_id]; - flexran_get_harq(Mod_id, CC_id, UE_id, frameP, subframeP, &harq_pid, &round); + flexran_get_harq(Mod_id, CC_id, UE_id, frameP, subframeP, &harq_pid, &round, openair_harq_DL); // if there is no available harq_process, skip the UE if (UE_list->UE_sched_ctrl[UE_id].harq_pid[CC_id]<0) @@ -640,7 +640,7 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id, for (ii=0; iiordered_CCids[ii][UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - flexran_get_harq(Mod_id, CC_id, UE_id, frameP, subframeP, &harq_pid, &round); + flexran_get_harq(Mod_id, CC_id, UE_id, frameP, subframeP, &harq_pid, &round, openair_harq_DL); rnti = UE_RNTI(Mod_id,UE_id); // LOG_D(MAC,"UE %d rnti 0x\n", UE_id, rnti ); @@ -1096,7 +1096,7 @@ flexran_schedule_ue_spec_common(mid_t mod_id, dl_data[num_ues_added]->serv_cell_index = CC_id; nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id]; - flexran_get_harq(mod_id, CC_id, UE_id, frame, subframe, &harq_pid, &round); + flexran_get_harq(mod_id, CC_id, UE_id, frame, subframe, &harq_pid, &round, openair_harq_DL); sdu_length_total=0; mcs = cqi_to_mcs[flexran_get_ue_wcqi(mod_id, UE_id)]; // LOG_I(FLEXRAN_AGENT, "The MCS is %d\n", mcs); diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c index a45f81fdaa..604a428d9c 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c @@ -615,8 +615,8 @@ void _ulsch_scheduler_pre_processor(module_id_t module_idP, // This is the actual CC_id in the list CC_id = UE_list->ordered_ULCCids[n][UE_id]; - mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL); - + // mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL); + flexran_get_harq(module_idP, CC_id, UE_id, frameP, subframeP, &harq_pid, &round, openair_harq_UL); if(round>0) { nb_allocated_rbs[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb_ul[harq_pid]; } else { @@ -787,10 +787,11 @@ void flexran_agent_schedule_ulsch_ue_spec(module_id_t module_idP, frame_t frameP, unsigned char cooperation_flag, sub_frame_t subframeP, - unsigned char sched_subframe) { + unsigned char sched_subframe, + Protocol__FlexranMessage **ul_info) { -// flexran_agent_mac_create_empty_ul_config(module_idP, ul_info); +flexran_agent_mac_create_empty_ul_config(module_idP, ul_info); uint16_t first_rb[MAX_NUM_CCs],i; int CC_id; @@ -907,7 +908,7 @@ void flexran_agent_schedule_ulsch_rnti(module_id_t module_idP, continue; } - rnti = UE_RNTI(module_idP,UE_id); + rnti = flexran_get_ue_crnti(module_idP, UE_id); if (rnti==NOT_A_RNTI) { LOG_W(MAC,"[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n", module_idP,frameP,subframeP,UE_id); @@ -973,7 +974,7 @@ abort(); UE_template = &UE_list->UE_template[CC_id][UE_id]; UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id]; - if (mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL) == -1 ) { + if (flexran_get_harq(module_idP, CC_id, UE_id, frameP, subframeP, &harq_pid, &round, openair_harq_UL) == -1 ) { LOG_W(MAC,"[eNB %d] Scheduler Frame %d, subframeP %d: candidate harq_pid from PHY for UE %d CC %d RNTI %x\n", module_idP,frameP,subframeP, UE_id, CC_id, rnti); continue; From 57129bc0af65ac764741ca1042d916a74f56600a Mon Sep 17 00:00:00 2001 From: shahab SHARIATBAGHERI Date: Tue, 25 Apr 2017 18:19:47 +0200 Subject: [PATCH 014/195] Uplink Slicing --- openair2/ENB_APP/flexran_agent_ran_api.c | 15 +++++++++ .../MAC/flexran_agent_scheduler_dlsch_ue.c | 12 +++++++ .../MAC/flexran_agent_scheduler_ulsch_ue.c | 31 +++++++++++++------ 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 334dd3cb9a..ae304d1e26 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -655,6 +655,21 @@ int flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id) { return -1; } + +int flexran_get_rrc_status(const mid_t mod_id, const rnti_t rntiP){ + + struct rrc_eNB_ue_context_s* ue_context_p = NULL; + + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); + + if (ue_context_p != NULL) { + return(ue_context_p->ue_context.Status); + } else { + return RRC_INACTIVE; + } + +} + int flexran_get_ue_aggregated_max_bitrate_dl (mid_t mod_id, mid_t ue_id) { return ((UE_list_t *)enb_ue[mod_id])->UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateDL; } diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c index fc3906ab6f..aec093e88a 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c @@ -742,7 +742,9 @@ flexran_schedule_ue_spec_default(mid_t mod_id, if ((n_active_slices > 0) && (n_active_slices <= MAX_NUM_SLICES)) { LOG_N(MAC,"[eNB %d]frame %d subframe %d: number of active slices has changed: %d-->%d\n", mod_id, frame, subframe, n_active_slices_current, n_active_slices); + n_active_slices_current = n_active_slices; + } else { LOG_W(MAC,"invalid number of slices %d, revert to the previous value %d\n",n_active_slices, n_active_slices_current); n_active_slices = n_active_slices_current; @@ -756,18 +758,22 @@ flexran_schedule_ue_spec_default(mid_t mod_id, total_slice_percentage=total_slice_percentage - slice_percentage_current[i] + slice_percentage[i]; LOG_N(MAC,"[eNB %d][SLICE %d] frame %d subframe %d: total percentage %f, slice RB percentage has changed: %f-->%f\n", mod_id, i, frame, subframe, total_slice_percentage, slice_percentage_current[i], slice_percentage[i]); + slice_percentage_current[i] = slice_percentage[i]; + } else { LOG_W(MAC,"[eNB %d][SLICE %d] invalid total RB share (%f->%f), revert the previous value (%f->%f)\n", mod_id,i, total_slice_percentage, total_slice_percentage - slice_percentage_current[i] + slice_percentage[i], slice_percentage[i],slice_percentage_current[i]); + slice_percentage[i]= slice_percentage_current[i]; } } else { LOG_W(MAC,"[eNB %d][SLICE %d] invalid slice RB share, revert the previous value (%f->%f)\n",mod_id, i, slice_percentage[i],slice_percentage_current[i]); + slice_percentage[i]= slice_percentage_current[i]; } @@ -778,10 +784,14 @@ flexran_schedule_ue_spec_default(mid_t mod_id, if ((slice_maxmcs[i] >= 0) && (slice_maxmcs[i] < 29)){ LOG_N(MAC,"[eNB %d][SLICE %d] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", mod_id, i, frame, subframe, slice_maxmcs_current[i], slice_maxmcs[i]); + slice_maxmcs_current[i] = slice_maxmcs[i]; + } else { LOG_W(MAC,"[eNB %d][SLICE %d] invalid slice max mcs %d, revert the previous value %d\n",mod_id, i, slice_percentage[i],slice_percentage[i]); + slice_maxmcs[i]= slice_maxmcs_current[i]; + } } @@ -789,7 +799,9 @@ flexran_schedule_ue_spec_default(mid_t mod_id, if (update_dl_scheduler_current[i] != update_dl_scheduler[i]){ LOG_N(MAC,"[eNB %d][SLICE %d] frame %d subframe %d: DL scheduler for this slice is updated: %s \n", mod_id, i, frame, subframe, dl_scheduler_type[i]); + update_dl_scheduler_current[i] = update_dl_scheduler[i]; + } // Run each enabled slice-specific schedulers one by one diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c index 604a428d9c..001f284938 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c @@ -59,6 +59,12 @@ // #define ENABLE_MAC_PAYLOAD_DEBUG // #define DEBUG_eNB_SCHEDULER 1 + +// RB share for each slice for past and current time +float slice_percentage_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; +float slice_percentage_current_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; + + // // This table holds the allowable PRB sizes for ULSCH transmissions // uint8_t rb_table[33] = {1,2,3,4,5,6,8,9,10,12,15,16,18,20,24,25,27,30,32,36,40,45,48,50,54,60,72,75,80,81,90,96,100}; @@ -500,6 +506,7 @@ // } void _ulsch_scheduler_pre_processor(module_id_t module_idP, + int slice_id, int frameP, sub_frame_t subframeP, uint16_t *first_rb) @@ -515,7 +522,8 @@ void _ulsch_scheduler_pre_processor(module_id_t module_idP, UE_list_t *UE_list = &eNB_mac_inst[module_idP].UE_list; UE_TEMPLATE *UE_template = 0; LTE_DL_FRAME_PARMS *frame_parms = 0; - + + uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES]; //LOG_I(MAC,"assign max mcs min rb\n"); // maximize MCS and then allocate required RB according to the buffer occupancy with the limit of max available UL RB @@ -576,15 +584,17 @@ void _ulsch_scheduler_pre_processor(module_id_t module_idP, max_num_ue_to_be_scheduled+=1; + nb_rbs_allowed_slice[CC_id][slice_id] = flexran_nb_rbs_allowed_slice(slice_percentage_uplink[slice_id], flexran_get_N_RB_UL(module_idP, CC_id)); + if (total_ue_count == 0) { average_rbs_per_user[CC_id] = 0; } else if (total_ue_count == 1 ) { // increase the available RBs, special case, - average_rbs_per_user[CC_id] = frame_parms->N_RB_UL-first_rb[CC_id]+1; - } else if( (total_ue_count <= (frame_parms->N_RB_DL-first_rb[CC_id])) && + average_rbs_per_user[CC_id] = nb_rbs_allowed_slice[CC_id][slice_id]-first_rb[CC_id]+1; + } else if( (total_ue_count <= (nb_rbs_allowed_slice[CC_id][slice_id]-first_rb[CC_id])) && (total_ue_count <= max_num_ue_to_be_scheduled)) { - average_rbs_per_user[CC_id] = (uint16_t) floor((frame_parms->N_RB_UL-first_rb[CC_id])/total_ue_count); + average_rbs_per_user[CC_id] = (uint16_t) floor((nb_rbs_allowed_slice[CC_id][slice_id]-first_rb[CC_id])/total_ue_count); } else if (max_num_ue_to_be_scheduled > 0 ) { - average_rbs_per_user[CC_id] = (uint16_t) floor((frame_parms->N_RB_UL-first_rb[CC_id])/max_num_ue_to_be_scheduled); + average_rbs_per_user[CC_id] = (uint16_t) floor((nb_rbs_allowed_slice[CC_id][slice_id]-first_rb[CC_id])/max_num_ue_to_be_scheduled); } else { average_rbs_per_user[CC_id]=1; LOG_W(MAC,"[eNB %d] frame %d subframe %d: UE %d CC %d: can't get average rb per user (should not be here)\n", @@ -648,7 +658,7 @@ void _ulsch_scheduler_pre_processor(module_id_t module_idP, CC_id = UE_list->ordered_ULCCids[n][UE_id]; UE_template = &UE_list->UE_template[CC_id][UE_id]; frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id); - total_remaining_rbs[CC_id]=frame_parms->N_RB_UL - first_rb[CC_id] - total_allocated_rbs[CC_id]; + total_remaining_rbs[CC_id]=nb_rbs_allowed_slice[CC_id][slice_id] - first_rb[CC_id] - total_allocated_rbs[CC_id]; if (total_ue_count == 1 ) { total_remaining_rbs[CC_id]+=1; @@ -675,7 +685,7 @@ void _ulsch_scheduler_pre_processor(module_id_t module_idP, frame_parms= mac_xface->get_lte_frame_parms(module_idP,CC_id); if (total_allocated_rbs[CC_id]>0) { - LOG_D(MAC,"[eNB %d] total RB allocated for all UEs = %d/%d\n", module_idP, total_allocated_rbs[CC_id], frame_parms->N_RB_UL - first_rb[CC_id]); + LOG_D(MAC,"[eNB %d] total RB allocated for all UEs = %d/%d\n", module_idP, total_allocated_rbs[CC_id], nb_rbs_allowed_slice[CC_id][slice_id] - first_rb[CC_id]); } } } @@ -888,10 +898,11 @@ void flexran_agent_schedule_ulsch_rnti(module_id_t module_idP, - + int slice_id = 0; _ulsch_scheduler_pre_processor(module_idP, + slice_id, frameP, subframeP, first_rb); @@ -993,7 +1004,9 @@ abort(); UE_sched_ctrl->ul_failure_timer); // reset the scheduling request UE_template->ul_SR = 0; - status = mac_eNB_get_rrc_status(module_idP,rnti); + // status = mac_eNB_get_rrc_status(module_idP,rnti); + status = flexran_get_rrc_status(module_idP, rnti); + if (status < RRC_CONNECTED) cqi_req = 0; else if (UE_sched_ctrl->cqi_req_timer>30) { From 897c8da299615016c7e9ac6320883423465a0de0 Mon Sep 17 00:00:00 2001 From: Xenofon Foukas Date: Wed, 26 Apr 2017 07:50:04 +0000 Subject: [PATCH 015/195] Fixed size of arrays for RSRP and RSRQ measurements --- openair2/RRC/LITE/extern.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/RRC/LITE/extern.h b/openair2/RRC/LITE/extern.h index d4c8192a95..7934690563 100644 --- a/openair2/RRC/LITE/extern.h +++ b/openair2/RRC/LITE/extern.h @@ -93,8 +93,8 @@ extern uint16_t N310[8]; extern uint16_t N311[8]; extern uint32_t T304[8]; extern uint32_t timeToTrigger_ms[16]; -extern float RSRP_meas_mapping[100]; -extern float RSRQ_meas_mapping[33]; +extern float RSRP_meas_mapping[98]; +extern float RSRQ_meas_mapping[35]; #endif From b9b45c4ac030ef54f210aa37c066e7ccb5ffac86 Mon Sep 17 00:00:00 2001 From: shahab SHARIATBAGHERI Date: Wed, 26 Apr 2017 19:15:39 +0200 Subject: [PATCH 016/195] uplink primitives --- openair2/LAYER2/MAC/flexran_agent_mac_proto.h | 18 ++ .../MAC/flexran_agent_scheduler_ulsch_ue.c | 160 +++++++++++++++++- 2 files changed, 176 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/MAC/flexran_agent_mac_proto.h b/openair2/LAYER2/MAC/flexran_agent_mac_proto.h index 7b5c402b61..fbb8a11950 100644 --- a/openair2/LAYER2/MAC/flexran_agent_mac_proto.h +++ b/openair2/LAYER2/MAC/flexran_agent_mac_proto.h @@ -117,6 +117,8 @@ int flexran_slice_member(int UE_id, int flexran_slice_maxmcs(int slice_id) ; +/* Downlink Primitivies */ + void _store_dlsch_buffer (module_id_t Mod_id, int slice_id, frame_t frameP, @@ -131,6 +133,22 @@ void _assign_rbs_required (module_id_t Mod_id, uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES], int min_rb_unit[MAX_NUM_CCs]); + +/* Uplink Primitivies */ + +// void _sort_ue_ul (module_id_t module_idP,int frameP, sub_frame_t subframeP); + +void _assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subframeP, uint16_t *first_rb); + + +void _ulsch_scheduler_pre_processor(module_id_t module_idP, + int slice_id, + uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES], + int frameP, + sub_frame_t subframeP, + uint16_t *first_rb); + + void _dlsch_scheduler_pre_processor (module_id_t Mod_id, int slice_id, frame_t frameP, diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c index 001f284938..849dc30869 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c @@ -65,6 +65,10 @@ float slice_percentage_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; float slice_percentage_current_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; +uint16_t flexran_nb_rbs_allowed_slice_uplink(float rb_percentage, int total_rbs){ + return (uint16_t) floor(rb_percentage * total_rbs); +} + // // This table holds the allowable PRB sizes for ULSCH transmissions // uint8_t rb_table[33] = {1,2,3,4,5,6,8,9,10,12,15,16,18,20,24,25,27,30,32,36,40,45,48,50,54,60,72,75,80,81,90,96,100}; @@ -505,6 +509,158 @@ float slice_percentage_current_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; // stop_meas(&eNB->rx_ulsch_sdu); // } + + +// void _sort_ue_ul (module_id_t module_idP,int frameP, sub_frame_t subframeP) +// { +// int i; +// int list[NUMBER_OF_UE_MAX]; +// int list_size = 0; +// int rnti; +// struct sort_ue_ul_params params = { module_idP, frameP, subframeP }; + +// UE_list_t *UE_list = &eNB_mac_inst[module_idP].UE_list; + +// for (i = 0; i < NUMBER_OF_UE_MAX; i++) { +// rnti = UE_RNTI(module_idP, i); +// if (rnti == NOT_A_RNTI) +// continue; +// if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) +// continue; +// if (!phy_stats_exist(module_idP, rnti)) +// continue; +// list[list_size] = i; +// list_size++; +// } + +// qsort_r(list, list_size, sizeof(int), ue_ul_compare, ¶ms); + +// if (list_size) { +// for (i = 0; i < list_size-1; i++) +// UE_list->next_ul[list[i]] = list[i+1]; +// UE_list->next_ul[list[list_size-1]] = -1; +// UE_list->head_ul = list[0]; +// } else { +// UE_list->head_ul = -1; +// } + +// } + + + +void _assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subframeP, uint16_t *first_rb) +{ + + int i; + uint16_t n,UE_id; + uint8_t CC_id; + rnti_t rnti = -1; + int mcs; + int rb_table_index=0,tbs,tx_power; + eNB_MAC_INST *eNB = &eNB_mac_inst[module_idP]; + UE_list_t *UE_list = &eNB->UE_list; + + UE_TEMPLATE *UE_template; + LTE_DL_FRAME_PARMS *frame_parms; + + + for (i = 0; i < NUMBER_OF_UE_MAX; i++) { + if (UE_list->active[i] != TRUE) continue; + + rnti = UE_RNTI(module_idP,i); + + if (rnti==NOT_A_RNTI) + continue; + if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) + continue; + if (!phy_stats_exist(module_idP, rnti)) + continue; + + if (UE_list->UE_sched_ctrl[i].phr_received == 1) + mcs = 20; // if we've received the power headroom information the UE, we can go to maximum mcs + else + mcs = 10; // otherwise, limit to QPSK PUSCH + + UE_id = i; + + for (n=0; nnumactiveULCCs[UE_id]; n++) { + // This is the actual CC_id in the list + CC_id = UE_list->ordered_ULCCids[n][UE_id]; + + if (CC_id >= MAX_NUM_CCs) { + LOG_E( MAC, "CC_id %u should be < %u, loop n=%u < numactiveULCCs[%u]=%u", + CC_id, + MAX_NUM_CCs, + n, + UE_id, + UE_list->numactiveULCCs[UE_id]); + } + + AssertFatal( CC_id < MAX_NUM_CCs, "CC_id %u should be < %u, loop n=%u < numactiveULCCs[%u]=%u", + CC_id, + MAX_NUM_CCs, + n, + UE_id, + UE_list->numactiveULCCs[UE_id]); + frame_parms=mac_xface->get_lte_frame_parms(module_idP,CC_id); + UE_template = &UE_list->UE_template[CC_id][UE_id]; + + // if this UE has UL traffic + if (UE_template->ul_total_buffer > 0 ) { + + tbs = mac_xface->get_TBS_UL(mcs,3); // 1 or 2 PRB with cqi enabled does not work well! + // fixme: set use_srs flag + tx_power= mac_xface->estimate_ue_tx_power(tbs,rb_table[rb_table_index],0,frame_parms->Ncp,0); + + while ((((UE_template->phr_info - tx_power) < 0 ) || (tbs > UE_template->ul_total_buffer))&& + (mcs > 3)) { + // LOG_I(MAC,"UE_template->phr_info %d tx_power %d mcs %d\n", UE_template->phr_info,tx_power, mcs); + mcs--; + tbs = mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]); + tx_power = mac_xface->estimate_ue_tx_power(tbs,rb_table[rb_table_index],0,frame_parms->Ncp,0); // fixme: set use_srs + } + + while ((tbs < UE_template->ul_total_buffer) && + (rb_table[rb_table_index]<(frame_parms->N_RB_UL-first_rb[CC_id])) && + ((UE_template->phr_info - tx_power) > 0) && + (rb_table_index < 32 )) { + // LOG_I(MAC,"tbs %d ul buffer %d rb table %d max ul rb %d\n", tbs, UE_template->ul_total_buffer, rb_table[rb_table_index], frame_parms->N_RB_UL-first_rb[CC_id]); + rb_table_index++; + tbs = mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]); + tx_power = mac_xface->estimate_ue_tx_power(tbs,rb_table[rb_table_index],0,frame_parms->Ncp,0); + } + + UE_template->ue_tx_power = tx_power; + + if (rb_table[rb_table_index]>(frame_parms->N_RB_UL-first_rb[CC_id]-1)) { + rb_table_index--; + } + + // 1 or 2 PRB with cqi enabled does not work well! + if (rb_table[rb_table_index]<3) { + rb_table_index=2; //3PRB + } + + UE_template->pre_assigned_mcs_ul=mcs; + UE_template->pre_allocated_rb_table_index_ul=rb_table_index; + UE_template->pre_allocated_nb_rb_ul= rb_table[rb_table_index]; + LOG_D(MAC,"[eNB %d] frame %d subframe %d: for UE %d CC %d: pre-assigned mcs %d, pre-allocated rb_table[%d]=%d RBs (phr %d, tx power %d)\n", + module_idP, frameP, subframeP, UE_id, CC_id, + UE_template->pre_assigned_mcs_ul, + UE_template->pre_allocated_rb_table_index_ul, + UE_template->pre_allocated_nb_rb_ul, + UE_template->phr_info,tx_power); + } else { + UE_template->pre_allocated_rb_table_index_ul=-1; + UE_template->pre_allocated_nb_rb_ul=0; + } + } + } +} + + + + void _ulsch_scheduler_pre_processor(module_id_t module_idP, int slice_id, int frameP, @@ -527,7 +683,7 @@ void _ulsch_scheduler_pre_processor(module_id_t module_idP, //LOG_I(MAC,"assign max mcs min rb\n"); // maximize MCS and then allocate required RB according to the buffer occupancy with the limit of max available UL RB - assign_max_mcs_min_rb(module_idP,frameP, subframeP, first_rb); + _assign_max_mcs_min_rb(module_idP,frameP, subframeP, first_rb); //LOG_I(MAC,"sort ue \n"); // sort ues @@ -584,7 +740,7 @@ void _ulsch_scheduler_pre_processor(module_id_t module_idP, max_num_ue_to_be_scheduled+=1; - nb_rbs_allowed_slice[CC_id][slice_id] = flexran_nb_rbs_allowed_slice(slice_percentage_uplink[slice_id], flexran_get_N_RB_UL(module_idP, CC_id)); + nb_rbs_allowed_slice[CC_id][slice_id] = flexran_nb_rbs_allowed_slice_uplink(slice_percentage_uplink[slice_id], flexran_get_N_RB_UL(module_idP, CC_id)); if (total_ue_count == 0) { average_rbs_per_user[CC_id] = 0; From eee0c1b84b896a6085211a01927f13e4c1a4f1d9 Mon Sep 17 00:00:00 2001 From: shahab SHARIATBAGHERI Date: Thu, 27 Apr 2017 09:29:00 +0200 Subject: [PATCH 017/195] uplink percentage --- openair2/LAYER2/MAC/flexran_agent_mac_proto.h | 5 ++--- .../MAC/flexran_agent_scheduler_ulsch_ue.c | 22 ++++++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/openair2/LAYER2/MAC/flexran_agent_mac_proto.h b/openair2/LAYER2/MAC/flexran_agent_mac_proto.h index fbb8a11950..186ccf1287 100644 --- a/openair2/LAYER2/MAC/flexran_agent_mac_proto.h +++ b/openair2/LAYER2/MAC/flexran_agent_mac_proto.h @@ -138,12 +138,11 @@ void _assign_rbs_required (module_id_t Mod_id, // void _sort_ue_ul (module_id_t module_idP,int frameP, sub_frame_t subframeP); -void _assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subframeP, uint16_t *first_rb); +void _assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, sub_frame_t subframeP, uint16_t *first_rb); void _ulsch_scheduler_pre_processor(module_id_t module_idP, - int slice_id, - uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES], + int slice_id, int frameP, sub_frame_t subframeP, uint16_t *first_rb); diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c index 849dc30869..333cc275c2 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c @@ -65,6 +65,8 @@ float slice_percentage_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; float slice_percentage_current_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; + uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES]; + uint16_t flexran_nb_rbs_allowed_slice_uplink(float rb_percentage, int total_rbs){ return (uint16_t) floor(rb_percentage * total_rbs); } @@ -548,7 +550,7 @@ uint16_t flexran_nb_rbs_allowed_slice_uplink(float rb_percentage, int total_rbs) -void _assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subframeP, uint16_t *first_rb) +void _assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, sub_frame_t subframeP, uint16_t *first_rb) { int i; @@ -621,7 +623,7 @@ void _assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subfr } while ((tbs < UE_template->ul_total_buffer) && - (rb_table[rb_table_index]<(frame_parms->N_RB_UL-first_rb[CC_id])) && + (rb_table[rb_table_index]<(nb_rbs_allowed_slice[CC_id][slice_id]-first_rb[CC_id])) && ((UE_template->phr_info - tx_power) > 0) && (rb_table_index < 32 )) { // LOG_I(MAC,"tbs %d ul buffer %d rb table %d max ul rb %d\n", tbs, UE_template->ul_total_buffer, rb_table[rb_table_index], frame_parms->N_RB_UL-first_rb[CC_id]); @@ -632,7 +634,7 @@ void _assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subfr UE_template->ue_tx_power = tx_power; - if (rb_table[rb_table_index]>(frame_parms->N_RB_UL-first_rb[CC_id]-1)) { + if (rb_table[rb_table_index]>(nb_rbs_allowed_slice[CC_id][slice_id]-first_rb[CC_id]-1)) { rb_table_index--; } @@ -662,7 +664,7 @@ void _assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subfr void _ulsch_scheduler_pre_processor(module_id_t module_idP, - int slice_id, + int slice_id, int frameP, sub_frame_t subframeP, uint16_t *first_rb) @@ -679,11 +681,11 @@ void _ulsch_scheduler_pre_processor(module_id_t module_idP, UE_TEMPLATE *UE_template = 0; LTE_DL_FRAME_PARMS *frame_parms = 0; - uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES]; + //LOG_I(MAC,"assign max mcs min rb\n"); // maximize MCS and then allocate required RB according to the buffer occupancy with the limit of max available UL RB - _assign_max_mcs_min_rb(module_idP,frameP, subframeP, first_rb); + _assign_max_mcs_min_rb(module_idP, slice_id, frameP, subframeP, first_rb); //LOG_I(MAC,"sort ue \n"); // sort ues @@ -1056,9 +1058,9 @@ void flexran_agent_schedule_ulsch_rnti(module_id_t module_idP, int slice_id = 0; - + _ulsch_scheduler_pre_processor(module_idP, - slice_id, + slice_id, frameP, subframeP, first_rb); @@ -1225,7 +1227,7 @@ abort(); UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs; // buffer_occupancy = UE_template->ul_total_buffer; - while (((rb_table[rb_table_index]>(frame_parms->N_RB_UL-1-first_rb[CC_id])) || + while (((rb_table[rb_table_index]>(nb_rbs_allowed_slice[CC_id][slice_id]-1-first_rb[CC_id])) || (rb_table[rb_table_index]>45)) && (rb_table_index>0)) { rb_table_index--; @@ -1235,7 +1237,7 @@ abort(); UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=rb_table[rb_table_index]; UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS=TBS; // buffer_occupancy -= TBS; - rballoc = mac_xface->computeRIV(frame_parms->N_RB_UL, + rballoc = mac_xface->computeRIV(nb_rbs_allowed_slice[CC_id][slice_id], first_rb[CC_id], rb_table[rb_table_index]); From 689eae92ee2f83d88f33d4f8393c8197f9e6fc63 Mon Sep 17 00:00:00 2001 From: shahab SHARIATBAGHERI Date: Wed, 10 May 2017 13:11:09 +0200 Subject: [PATCH 018/195] Fix Bug dl scheduler --- openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c index 81c18a26c0..0bde8c965b 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c @@ -284,7 +284,7 @@ void _assign_rbs_required (module_id_t Mod_id, nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id]; if (nb_rbs_required[CC_id][UE_id] > nb_rbs_allowed_slice[CC_id][slice_id]) { - TBS = mac_xface->get_TBS_DL(flexran_get_ue_wcqi(Mod_id, UE_id), nb_rbs_allowed_slice[CC_id][slice_id]); + TBS = mac_xface->get_TBS_DL(cqi_to_mcs[flexran_get_ue_wcqi(Mod_id, UE_id)], nb_rbs_allowed_slice[CC_id][slice_id]); nb_rbs_required[CC_id][UE_id] = nb_rbs_allowed_slice[CC_id][slice_id]; break; } From 5de045b8027c6ac4f027bc8c6ad6f4ff2c8f7270 Mon Sep 17 00:00:00 2001 From: shahab SHARIATBAGHERI Date: Thu, 18 May 2017 15:25:10 +0200 Subject: [PATCH 019/195] Uplink slices --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 4 +- openair2/LAYER2/MAC/flexran_agent_mac_proto.h | 6 +- .../MAC/flexran_agent_scheduler_dlsch_ue.c | 14 +- .../MAC/flexran_agent_scheduler_ulsch_ue.c | 1052 ++--------------- 4 files changed, 141 insertions(+), 935 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index db9af62eac..f17fb9a1ba 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -1248,8 +1248,8 @@ int flexran_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { xface->flexran_agent_send_sr_info = flexran_agent_send_sr_info; xface->flexran_agent_send_sf_trigger = flexran_agent_send_sf_trigger; //xface->flexran_agent_send_update_mac_stats = flexran_agent_send_update_mac_stats; - xface->flexran_agent_schedule_ue_spec = flexran_schedule_ue_spec_default; - xface->flexran_agent_schedule_ul_spec = flexran_agent_schedule_ulsch_ue_spec; + xface->flexran_agent_schedule_ue_spec = flexran_schedule_ue_dl_spec_default; + xface->flexran_agent_schedule_ul_spec = flexran_schedule_ue_ul_spec_default; //xface->flexran_agent_schedule_ue_spec = flexran_schedule_ue_spec_remote; xface->flexran_agent_get_pending_dl_mac_config = flexran_agent_get_pending_dl_mac_config; diff --git a/openair2/LAYER2/MAC/flexran_agent_mac_proto.h b/openair2/LAYER2/MAC/flexran_agent_mac_proto.h index 186ccf1287..c2d28b33f7 100644 --- a/openair2/LAYER2/MAC/flexran_agent_mac_proto.h +++ b/openair2/LAYER2/MAC/flexran_agent_mac_proto.h @@ -51,7 +51,7 @@ typedef void (*slice_scheduler)(module_id_t mod_id, /* * top level flexran scheduler used by the eNB scheduler */ -void flexran_schedule_ue_spec_default(mid_t mod_id, +void flexran_schedule_ue_dl_spec_default(mid_t mod_id, uint32_t frame, uint32_t subframe, int *mbsfn_flag, @@ -102,7 +102,7 @@ flexran_schedule_ue_spec_be(mid_t mod_id, * common flexran scheduler function */ void -flexran_schedule_ue_spec_common(mid_t mod_id, +flexran_schedule_ue_dl_spec_common(mid_t mod_id, int slice_id, uint32_t frame, uint32_t subframe, @@ -182,7 +182,7 @@ void _dlsch_scheduler_pre_processor_allocate (module_id_t Mod_id, /* * Default scheduler used by the eNB agent */ -void flexran_schedule_ue_spec_default(mid_t mod_id, uint32_t frame, uint32_t subframe, +void flexran_schedule_ue_dl_spec_default(mid_t mod_id, uint32_t frame, uint32_t subframe, int *mbsfn_flag, Protocol__FlexranMessage **dl_info); /* diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c index aec093e88a..cfb14af641 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c @@ -709,12 +709,12 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id, #define SF05_LIMIT 1 /* - * Main scheduling functions to support slicing + * Main Downlink Slicing * */ void -flexran_schedule_ue_spec_default(mid_t mod_id, +flexran_schedule_ue_dl_spec_default(mid_t mod_id, uint32_t frame, uint32_t subframe, int *mbsfn_flag, @@ -876,7 +876,7 @@ flexran_schedule_ue_spec_embb(mid_t mod_id, Protocol__FlexranMessage **dl_info) { - flexran_schedule_ue_spec_common(mod_id, + flexran_schedule_ue_dl_spec_common(mod_id, slice_id, frame, subframe, @@ -894,7 +894,7 @@ flexran_schedule_ue_spec_urllc(mid_t mod_id, Protocol__FlexranMessage **dl_info) { - flexran_schedule_ue_spec_common(mod_id, + flexran_schedule_ue_spec_dl_common(mod_id, slice_id, frame, subframe, @@ -913,7 +913,7 @@ flexran_schedule_ue_spec_mmtc(mid_t mod_id, { - flexran_schedule_ue_spec_common(mod_id, + flexran_schedule_ue_dl_spec_common(mod_id, slice_id, frame, subframe, @@ -932,7 +932,7 @@ flexran_schedule_ue_spec_be(mid_t mod_id, { - flexran_schedule_ue_spec_common(mod_id, + flexran_schedule_ue_dl_spec_common(mod_id, slice_id, frame, subframe, @@ -943,7 +943,7 @@ flexran_schedule_ue_spec_be(mid_t mod_id, //------------------------------------------------------------------------------ void -flexran_schedule_ue_spec_common(mid_t mod_id, +flexran_schedule_ue_dl_spec_common(mid_t mod_id, int slice_id, uint32_t frame, uint32_t subframe, diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c index 333cc275c2..20e1c67366 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c @@ -67,488 +67,17 @@ float slice_percentage_current_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES]; +int update_ul_scheduler[MAX_NUM_SLICES] = {1, 1, 1, 1}; +int update_ul_scheduler_current[MAX_NUM_SLICES] = {1, 1, 1, 1}; + +// name of available scheduler +char *ul_scheduler_type[MAX_NUM_SLICES] = {"flexran_schedule_ue_ul_spec_embb"}; + + uint16_t flexran_nb_rbs_allowed_slice_uplink(float rb_percentage, int total_rbs){ return (uint16_t) floor(rb_percentage * total_rbs); } -// // This table holds the allowable PRB sizes for ULSCH transmissions -// uint8_t rb_table[33] = {1,2,3,4,5,6,8,9,10,12,15,16,18,20,24,25,27,30,32,36,40,45,48,50,54,60,72,75,80,81,90,96,100}; - -// void rx_sdu(const module_id_t enb_mod_idP, -// const int CC_idP, -// const frame_t frameP, -// const sub_frame_t subframeP, -// const rnti_t rntiP, -// uint8_t *sduP, -// const uint16_t sdu_lenP, -// const int harq_pidP, -// uint8_t *msg3_flagP) -// { - -// unsigned char rx_ces[MAX_NUM_CE],num_ce,num_sdu,i,*payload_ptr; -// unsigned char rx_lcids[NB_RB_MAX]; -// unsigned short rx_lengths[NB_RB_MAX]; -// int UE_id = find_UE_id(enb_mod_idP,rntiP); -// int ii,j; -// eNB_MAC_INST *eNB = &eNB_mac_inst[enb_mod_idP]; -// UE_list_t *UE_list= &eNB->UE_list; -// int crnti_rx=0; -// int old_buffer_info; - -// start_meas(&eNB->rx_ulsch_sdu); - -// if ((UE_id > NUMBER_OF_UE_MAX) || (UE_id == -1) ) -// for(ii=0; iiUE_sched_ctrl[UE_id].ul_scheduled &= (~(1<UE_sched_ctrl[UE_id].ul_inactivity_timer=0; -// UE_list->UE_sched_ctrl[UE_id].ul_failure_timer =0; -// UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= (~(1<UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { -// UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync=0; -// mac_eNB_rrc_ul_in_sync(enb_mod_idP,CC_idP,frameP,subframeP,UE_RNTI(enb_mod_idP,UE_id)); -// } -// } - - -// payload_ptr = parse_ulsch_header(sduP,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,sdu_lenP); - -// T(T_ENB_MAC_UE_UL_PDU, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP), -// T_INT(harq_pidP), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu)); -// T(T_ENB_MAC_UE_UL_PDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP), -// T_INT(harq_pidP), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu), T_BUFFER(sduP, sdu_lenP)); - -// eNB->eNB_stats[CC_idP].ulsch_bytes_rx=sdu_lenP; -// eNB->eNB_stats[CC_idP].total_ulsch_bytes_rx+=sdu_lenP; -// eNB->eNB_stats[CC_idP].total_ulsch_pdus_rx+=1; -// // control element -// for (i=0; iUE_template[CC_idP][UE_id].phr_info = (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET; -// LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received PHR PH = %d (db)\n", -// enb_mod_idP, CC_idP, rx_ces[i], UE_list->UE_template[CC_idP][UE_id].phr_info); -// UE_list->UE_template[CC_idP][UE_id].phr_info_configured=1; -// UE_list->UE_sched_ctrl[UE_id].phr_received = 1; -// } -// payload_ptr+=sizeof(POWER_HEADROOM_CMD); -// break; - -// case CRNTI: -// UE_id = find_UE_id(enb_mod_idP,(((uint16_t)payload_ptr[0])<<8) + payload_ptr[1]); -// LOG_I(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n", -// frameP,subframeP,enb_mod_idP, CC_idP, rx_ces[i], i,num_ce,(((uint16_t)payload_ptr[0])<<8) + payload_ptr[1],UE_id); -// if (UE_id!=-1) { -// UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer=0; -// UE_list->UE_sched_ctrl[UE_id].ul_failure_timer=0; -// if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { -// UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync=0; -// mac_eNB_rrc_ul_in_sync(enb_mod_idP,CC_idP,frameP,subframeP,(((uint16_t)payload_ptr[0])<<8) + payload_ptr[1]); -// } -// } -// crnti_rx=1; -// payload_ptr+=2; - -// if (msg3_flagP != NULL) { -// *msg3_flagP = 0; -// } -// break; - -// case TRUNCATED_BSR: -// case SHORT_BSR: { -// uint8_t lcgid; -// lcgid = (payload_ptr[0] >> 6); - -// LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", -// enb_mod_idP, CC_idP, rx_ces[i], lcgid, payload_ptr[0] & 0x3f); - -// if (crnti_rx==1) -// LOG_I(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", -// enb_mod_idP, CC_idP, rx_ces[i], lcgid, payload_ptr[0] & 0x3f); -// if (UE_id != -1) { - -// UE_list->UE_template[CC_idP][UE_id].bsr_info[lcgid] = (payload_ptr[0] & 0x3f); - -// // update buffer info - -// UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[lcgid]]; - -// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid]; - -// PHY_vars_eNB_g[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP*10)+subframeP] = (payload_ptr[0] & 0x3f); -// if (UE_id == UE_list->head) -// VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR,PHY_vars_eNB_g[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP*10)+subframeP]); -// if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0 ) { -// UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid]=frameP; -// } -// if (mac_eNB_get_rrc_status(enb_mod_idP,UE_RNTI(enb_mod_idP,UE_id)) < RRC_CONNECTED) -// LOG_I(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : ul_total_buffer = %d (lcg increment %d)\n", -// enb_mod_idP, CC_idP, rx_ces[i], UE_list->UE_template[CC_idP][UE_id].ul_total_buffer, -// UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid]); -// } -// else { - -// } -// payload_ptr += 1;//sizeof(SHORT_BSR); // fixme -// } -// break; - -// case LONG_BSR: -// if (UE_id != -1) { -// UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] = ((payload_ptr[0] & 0xFC) >> 2); -// UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] = -// ((payload_ptr[0] & 0x03) << 4) | ((payload_ptr[1] & 0xF0) >> 4); -// UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] = -// ((payload_ptr[1] & 0x0F) << 2) | ((payload_ptr[2] & 0xC0) >> 6); -// UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] = (payload_ptr[2] & 0x3F); - -// // update buffer info -// old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0]; -// UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0]]; - -// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer+= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0]; -// if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info) -// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info; -// else -// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0; - -// old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1]; -// UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1]]; -// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer+= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1]; -// if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info) -// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info; -// else -// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0; - -// old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2]; -// UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2]]; -// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer+= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2]; -// if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info) -// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info; -// else -// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0; - -// old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]; -// UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3]]; -// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer+= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]; -// if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info) -// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info; -// else -// UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0; - -// LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = " -// "%u LCGID2 = %u LCGID3 = %u\n", -// enb_mod_idP, CC_idP, -// rx_ces[i], -// UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0], -// UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1], -// UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2], -// UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3]); -// if (crnti_rx==1) -// LOG_I(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = " -// "%u LCGID2 = %u LCGID3 = %u\n", -// enb_mod_idP, CC_idP, -// rx_ces[i], -// UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0], -// UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1], -// UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2], -// UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3]); - -// if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] == 0 ) { -// UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=0; -// } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] == 0) { -// UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=frameP; -// } - -// if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] == 0 ) { -// UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=0; -// } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] == 0) { -// UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=frameP; -// } - -// if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] == 0 ) { -// UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2]=0; -// } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] == 0) { -// UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2]=frameP; -// } - -// if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] == 0 ) { -// UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3]= 0; -// } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] == 0) { -// UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3]=frameP; - -// } -// } - -// payload_ptr += 3;////sizeof(LONG_BSR); -// break; - -// default: -// LOG_E(MAC, "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", enb_mod_idP, CC_idP, rx_ces[i]); -// break; -// } -// } - -// for (i=0; i CCCH_PAYLOAD_SIZE_MAX) { -// LOG_E(MAC, "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d), dropping packet\n", -// enb_mod_idP, CC_idP, frameP, rx_lengths[i], CCCH_PAYLOAD_SIZE_MAX); -// break; -// } -// LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH: %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n", -// enb_mod_idP,CC_idP,frameP, -// payload_ptr[0],payload_ptr[1],payload_ptr[2],payload_ptr[3],payload_ptr[4], payload_ptr[5], rntiP); -// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC,1); -// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC,0); -// for (ii=0; iicommon_channels[CC_idP].RA_template[ii].rnti, rntiP, -// eNB->common_channels[CC_idP].RA_template[ii].RA_active); - -// if ((eNB->common_channels[CC_idP].RA_template[ii].rnti==rntiP) && -// (eNB->common_channels[CC_idP].RA_template[ii].RA_active==TRUE)) { - -// //payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len); - -// if (UE_id < 0) { -// memcpy(&eNB->common_channels[CC_idP].RA_template[ii].cont_res_id[0],payload_ptr,6); -// LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %ld\n", -// enb_mod_idP,CC_idP,frameP,rx_lengths[i],payload_ptr-sduP); - -// if ((UE_id=add_new_ue(enb_mod_idP,CC_idP,eNB->common_channels[CC_idP].RA_template[ii].rnti,harq_pidP)) == -1 ) { -// mac_xface->macphy_exit("[MAC][eNB] Max user count reached\n"); -// // kill RA procedure -// } else -// LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n", -// enb_mod_idP,CC_idP,frameP,eNB->common_channels[CC_idP].RA_template[ii].rnti,UE_id); -// } else { -// LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n", -// enb_mod_idP,CC_idP,frameP,UE_id,rx_lengths[i],payload_ptr-sduP); -// // kill RA procedure -// } - -// if (Is_rrc_registered == 1) -// mac_rrc_data_ind( -// enb_mod_idP, -// CC_idP, -// frameP,subframeP, -// rntiP, -// CCCH, -// (uint8_t*)payload_ptr, -// rx_lengths[i], -// ENB_FLAG_YES, -// enb_mod_idP, -// 0); - - -// if (num_ce >0) { // handle msg3 which is not RRCConnectionRequest -// // process_ra_message(msg3,num_ce,rx_lcids,rx_ces); -// } - -// eNB->common_channels[CC_idP].RA_template[ii].generate_Msg4 = 1; -// eNB->common_channels[CC_idP].RA_template[ii].wait_ack_Msg4 = 0; - -// } // if process is active -// } // loop on RA processes - -// break ; - -// case DCCH : -// case DCCH1 : -// // if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){ - - -// #if defined(ENABLE_MAC_PAYLOAD_DEBUG) -// LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP)); -// for (j=0; j<32; j++) { -// LOG_T(MAC,"%x ",payload_ptr[j]); -// } -// LOG_T(MAC,"\n"); -// #endif - -// if (UE_id != -1) { -// // adjust buffer occupancy of the correponding logical channel group -// if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) -// UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; -// else -// UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0; - -// LOG_D(MAC,"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DCCH, received %d bytes form UE %d on LCID %d \n", -// enb_mod_idP,CC_idP,frameP, rx_lengths[i], UE_id, rx_lcids[i]); - -// mac_rlc_data_ind( -// enb_mod_idP, -// rntiP, -// enb_mod_idP, -// frameP, -// ENB_FLAG_YES, -// MBMS_FLAG_NO, -// rx_lcids[i], -// (char *)payload_ptr, -// rx_lengths[i], -// 1, -// NULL);//(unsigned int*)crc_status); -// UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]]+=1; -// UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]]+=rx_lengths[i]; -// } /* UE_id != -1 */ - -// // } -// break; - -// // all the DRBS -// case DTCH: -// default : - -// #if defined(ENABLE_MAC_PAYLOAD_DEBUG) -// LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP)); -// for (j=0; j<32; j++) { -// LOG_T(MAC,"%x ",payload_ptr[j]); -// } -// LOG_T(MAC,"\n"); -// #endif -// if (rx_lcids[i] < NB_RB_MAX ) { -// LOG_D(MAC,"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n", -// enb_mod_idP,CC_idP,frameP, rx_lengths[i], UE_id, rx_lcids[i]); - -// if (UE_id != -1) { -// // adjust buffer occupancy of the correponding logical channel group -// LOG_D(MAC,"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d, removing from LCGID %ld, %d\n", -// enb_mod_idP,CC_idP,frameP, rx_lengths[i], UE_id,rx_lcids[i], -// UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]], -// UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]]); - -// if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) -// UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; -// else -// UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0; -// if ((rx_lengths[i] 0) ) { // MAX SIZE OF transport block -// mac_rlc_data_ind( -// enb_mod_idP, -// rntiP, -// enb_mod_idP, -// frameP, -// ENB_FLAG_YES, -// MBMS_FLAG_NO, -// rx_lcids[i], -// (char *)payload_ptr, -// rx_lengths[i], -// 1, -// NULL);//(unsigned int*)crc_status); - -// UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]]+=1; -// UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]]+=rx_lengths[i]; -// } -// else { /* rx_length[i] */ -// UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx+=1; -// LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ", -// enb_mod_idP, CC_idP, frameP, rx_lcids[i], UE_id); -// } -// } -// else {/*(UE_id != -1*/ -// LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ", -// enb_mod_idP, CC_idP, frameP, rx_lcids[i], UE_id); -// } -// } - -// break; -// } - -// payload_ptr+=rx_lengths[i]; -// } - -// /* NN--> FK: we could either check the payload, or use a phy helper to detect a false msg3 */ -// if ((num_sdu == 0) && (num_ce==0)) { -// if (UE_id != -1) -// UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx+=1; - -// if (msg3_flagP != NULL) { -// if( *msg3_flagP == 1 ) { -// LOG_N(MAC,"[eNB %d] CC_id %d frame %d : false msg3 detection: signal phy to canceling RA and remove the UE\n", enb_mod_idP, CC_idP, frameP); -// *msg3_flagP=0; -// } -// } -// } else { -// if (UE_id != -1) { -// UE_list->eNB_UE_stats[CC_idP][UE_id].pdu_bytes_rx=sdu_lenP; -// UE_list->eNB_UE_stats[CC_idP][UE_id].total_pdu_bytes_rx+=sdu_lenP; -// UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_pdus_rx+=1; -// } -// } - -// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,0); -// stop_meas(&eNB->rx_ulsch_sdu); -// } - - - -// void _sort_ue_ul (module_id_t module_idP,int frameP, sub_frame_t subframeP) -// { -// int i; -// int list[NUMBER_OF_UE_MAX]; -// int list_size = 0; -// int rnti; -// struct sort_ue_ul_params params = { module_idP, frameP, subframeP }; - -// UE_list_t *UE_list = &eNB_mac_inst[module_idP].UE_list; - -// for (i = 0; i < NUMBER_OF_UE_MAX; i++) { -// rnti = UE_RNTI(module_idP, i); -// if (rnti == NOT_A_RNTI) -// continue; -// if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) -// continue; -// if (!phy_stats_exist(module_idP, rnti)) -// continue; -// list[list_size] = i; -// list_size++; -// } - -// qsort_r(list, list_size, sizeof(int), ue_ul_compare, ¶ms); - -// if (list_size) { -// for (i = 0; i < list_size-1; i++) -// UE_list->next_ul[list[i]] = list[i+1]; -// UE_list->next_ul[list[list_size-1]] = -1; -// UE_list->head_ul = list[0]; -// } else { -// UE_list->head_ul = -1; -// } - -// } - - void _assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, sub_frame_t subframeP, uint16_t *first_rb) { @@ -565,7 +94,7 @@ void _assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, su UE_TEMPLATE *UE_template; LTE_DL_FRAME_PARMS *frame_parms; - + for (i = 0; i < NUMBER_OF_UE_MAX; i++) { if (UE_list->active[i] != TRUE) continue; @@ -606,7 +135,7 @@ void _assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, su UE_list->numactiveULCCs[UE_id]); frame_parms=mac_xface->get_lte_frame_parms(module_idP,CC_id); UE_template = &UE_list->UE_template[CC_id][UE_id]; - + nb_rbs_allowed_slice[CC_id][UE_id] = flexran_nb_rbs_allowed_slice_uplink(slice_percentage_uplink[UE_id], flexran_get_N_RB_UL(module_idP, CC_id)); // if this UE has UL traffic if (UE_template->ul_total_buffer > 0 ) { @@ -623,7 +152,7 @@ void _assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, su } while ((tbs < UE_template->ul_total_buffer) && - (rb_table[rb_table_index]<(nb_rbs_allowed_slice[CC_id][slice_id]-first_rb[CC_id])) && + (rb_table[rb_table_index]<(nb_rbs_allowed_slice[CC_id][UE_id]-first_rb[CC_id])) && ((UE_template->phr_info - tx_power) > 0) && (rb_table_index < 32 )) { // LOG_I(MAC,"tbs %d ul buffer %d rb table %d max ul rb %d\n", tbs, UE_template->ul_total_buffer, rb_table[rb_table_index], frame_parms->N_RB_UL-first_rb[CC_id]); @@ -634,7 +163,7 @@ void _assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, su UE_template->ue_tx_power = tx_power; - if (rb_table[rb_table_index]>(nb_rbs_allowed_slice[CC_id][slice_id]-first_rb[CC_id]-1)) { + if (rb_table[rb_table_index]>(nb_rbs_allowed_slice[CC_id][UE_id]-first_rb[CC_id]-1)) { rb_table_index--; } @@ -674,13 +203,14 @@ void _ulsch_scheduler_pre_processor(module_id_t module_idP, uint16_t UE_id,n,r; uint8_t CC_id, round, harq_pid; uint16_t nb_allocated_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX],total_allocated_rbs[MAX_NUM_CCs],average_rbs_per_user[MAX_NUM_CCs]; + uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES]; int16_t total_remaining_rbs[MAX_NUM_CCs]; uint16_t max_num_ue_to_be_scheduled=0,total_ue_count=0; rnti_t rnti= -1; UE_list_t *UE_list = &eNB_mac_inst[module_idP].UE_list; UE_TEMPLATE *UE_template = 0; LTE_DL_FRAME_PARMS *frame_parms = 0; - + UE_sched_ctrl *ue_sched_ctl; //LOG_I(MAC,"assign max mcs min rb\n"); @@ -742,15 +272,15 @@ void _ulsch_scheduler_pre_processor(module_id_t module_idP, max_num_ue_to_be_scheduled+=1; - nb_rbs_allowed_slice[CC_id][slice_id] = flexran_nb_rbs_allowed_slice_uplink(slice_percentage_uplink[slice_id], flexran_get_N_RB_UL(module_idP, CC_id)); + nb_rbs_allowed_slice[CC_id][UE_id] = flexran_nb_rbs_allowed_slice_uplink(slice_percentage_uplink[UE_id], flexran_get_N_RB_UL(module_idP, CC_id)); if (total_ue_count == 0) { average_rbs_per_user[CC_id] = 0; } else if (total_ue_count == 1 ) { // increase the available RBs, special case, - average_rbs_per_user[CC_id] = nb_rbs_allowed_slice[CC_id][slice_id]-first_rb[CC_id]+1; - } else if( (total_ue_count <= (nb_rbs_allowed_slice[CC_id][slice_id]-first_rb[CC_id])) && + average_rbs_per_user[CC_id] = nb_rbs_allowed_slice[CC_id][i]-first_rb[CC_id]+1; + } else if( (total_ue_count <= (nb_rbs_allowed_slice[CC_id][i]-first_rb[CC_id])) && (total_ue_count <= max_num_ue_to_be_scheduled)) { - average_rbs_per_user[CC_id] = (uint16_t) floor((nb_rbs_allowed_slice[CC_id][slice_id]-first_rb[CC_id])/total_ue_count); + average_rbs_per_user[CC_id] = (uint16_t) floor((nb_rbs_allowed_slice[CC_id][i]-first_rb[CC_id])/total_ue_count); } else if (max_num_ue_to_be_scheduled > 0 ) { average_rbs_per_user[CC_id] = (uint16_t) floor((nb_rbs_allowed_slice[CC_id][slice_id]-first_rb[CC_id])/max_num_ue_to_be_scheduled); } else { @@ -782,7 +312,8 @@ void _ulsch_scheduler_pre_processor(module_id_t module_idP, for (n=0; nnumactiveULCCs[UE_id]; n++) { // This is the actual CC_id in the list CC_id = UE_list->ordered_ULCCids[n][UE_id]; - + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + ue_sched_ctl->max_allowed_rbs[CC_id]=nb_rbs_allowed_slice[CC_id][UE_id]; // mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL); flexran_get_harq(module_idP, CC_id, UE_id, frameP, subframeP, &harq_pid, &round, openair_harq_UL); if(round>0) { @@ -814,9 +345,9 @@ void _ulsch_scheduler_pre_processor(module_id_t module_idP, for (n=0; nnumactiveULCCs[UE_id]; n++) { // This is the actual CC_id in the list CC_id = UE_list->ordered_ULCCids[n][UE_id]; - UE_template = &UE_list->UE_template[CC_id][UE_id]; + UE_template = &UE_list->UE_template[CC_id][UE_id]; frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id); - total_remaining_rbs[CC_id]=nb_rbs_allowed_slice[CC_id][slice_id] - first_rb[CC_id] - total_allocated_rbs[CC_id]; + total_remaining_rbs[CC_id]=nb_rbs_allowed_slice[CC_id][UE_id] - first_rb[CC_id] - total_allocated_rbs[CC_id]; if (total_ue_count == 1 ) { total_remaining_rbs[CC_id]+=1; @@ -848,110 +379,114 @@ void _ulsch_scheduler_pre_processor(module_id_t module_idP, } } +/* + * Main Uplink Slicing + * + */ + +void +flexran_schedule_ue_ul_spec_default(mid_t mod_id, + uint32_t frame, + uint32_t subframe, + int *mbsfn_flag, + Protocol__FlexranMessage **dl_info) +//------------------------------------------------------------------------------ +{ + int i=0; + + flexran_agent_mac_create_empty_ul_config(module_idP, ul_info); + + for (i = 0; i < n_active_slices; i++) { + + // Load any updated functions + if (update_dl_scheduler[i] > 0 ) { + slice_sched[i] = dlsym(NULL, dl_scheduler_type[i]); + update_dl_scheduler[i] = 0; + update_dl_scheduler_current[i] = 0; + slice_percentage_current[i]= slice_percentage[i]; + total_slice_percentage+=slice_percentage[i]; + LOG_N(MAC,"update dl scheduler slice %d\n", i); + } + + // check if the number of slices has changed, and log + if (n_active_slices_current != n_active_slices ){ + if ((n_active_slices > 0) && (n_active_slices <= MAX_NUM_SLICES)) { + LOG_N(MAC,"[eNB %d]frame %d subframe %d: number of active slices has changed: %d-->%d\n", + mod_id, frame, subframe, n_active_slices_current, n_active_slices); + + n_active_slices_current = n_active_slices; + + } else { + LOG_W(MAC,"invalid number of slices %d, revert to the previous value %d\n",n_active_slices, n_active_slices_current); + n_active_slices = n_active_slices_current; + } + } + + // check if the slice rb share has changed, and log the console + if (slice_percentage_current[i] != slice_percentage[i]){ + if ((slice_percentage[i] >= 0.0) && (slice_percentage[i] <= 1.0)){ + if ((total_slice_percentage - slice_percentage_current[i] + slice_percentage[i]) <= 1.0) { + total_slice_percentage=total_slice_percentage - slice_percentage_current[i] + slice_percentage[i]; + LOG_N(MAC,"[eNB %d][SLICE %d] frame %d subframe %d: total percentage %f, slice RB percentage has changed: %f-->%f\n", + mod_id, i, frame, subframe, total_slice_percentage, slice_percentage_current[i], slice_percentage[i]); + + slice_percentage_current[i] = slice_percentage[i]; + + } else { + LOG_W(MAC,"[eNB %d][SLICE %d] invalid total RB share (%f->%f), revert the previous value (%f->%f)\n", + mod_id,i, + total_slice_percentage, + total_slice_percentage - slice_percentage_current[i] + slice_percentage[i], + slice_percentage[i],slice_percentage_current[i]); + + slice_percentage[i]= slice_percentage_current[i]; + + } + } else { + LOG_W(MAC,"[eNB %d][SLICE %d] invalid slice RB share, revert the previous value (%f->%f)\n",mod_id, i, slice_percentage[i],slice_percentage_current[i]); + + slice_percentage[i]= slice_percentage_current[i]; + + } + } + + // check if a new scheduler, and log the console + if (update_dl_scheduler_current[i] != update_dl_scheduler[i]){ + LOG_N(MAC,"[eNB %d][SLICE %d] frame %d subframe %d: DL scheduler for this slice is updated: %s \n", + mod_id, i, frame, subframe, dl_scheduler_type[i]); + + update_dl_scheduler_current[i] = update_dl_scheduler[i]; + + } + + // Run each enabled slice-specific schedulers one by one + //LOG_N(MAC,"[eNB %d]frame %d subframe %d slice %d: calling the scheduler\n", mod_id, frame, subframe,i); + slice_sched[i](mod_id, i, frame, subframe, mbsfn_flag,dl_info); + + } + +} + +void +flexran_schedule_ue_ul_spec_embb(mid_t mod_id, + frame_t frameP, + unsigned char cooperation_flag, + uint32_t subframe, + unsigned char sched_subframe, + Protocol__FlexranMessage **ul_info) + +{ + flexran_agent_schedule_ulsch_ue_spec(mod_id, + frame, + cooperation_flag, + subframe, + sched_subframe, + ul_info); + +} -// uint32_t bytes_to_bsr_index(int32_t nbytes) -// { - -// uint32_t i=0; - -// if (nbytes<0) { -// return(0); -// } - -// while ((iE == 0) { -// not_done = 0; -// } - -// lcid = ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID; - -// if (lcid < EXTENDED_POWER_HEADROOM) { -// if (not_done==0) { // last MAC SDU, length is implicit -// mac_header_ptr++; -// length = tb_length-(mac_header_ptr-mac_header)-ce_len; - -// for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++) { -// length -= rx_lengths[num_sdu_cnt]; -// } -// } else { -// if (((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F == 0) { -// length = ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L; -// mac_header_ptr += 2;//sizeof(SCH_SUBHEADER_SHORT); -// } else { // F = 1 -// length = ((((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB & 0x7f ) << 8 ) | (((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB & 0xff); -// mac_header_ptr += 3;//sizeof(SCH_SUBHEADER_LONG); -// } -// } - -// LOG_D(MAC,"[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n", -// num_sdus,lcid,tb_length, length,mac_header_ptr-mac_header); -// rx_lcids[num_sdus] = lcid; -// rx_lengths[num_sdus] = length; -// num_sdus++; -// } else { // This is a control element subheader POWER_HEADROOM, BSR and CRNTI -// if (lcid == SHORT_PADDING) { -// mac_header_ptr++; -// } else { -// rx_ces[num_ces] = lcid; -// num_ces++; -// mac_header_ptr++; - -// if (lcid==LONG_BSR) { -// ce_len+=3; -// } else if (lcid==CRNTI) { -// ce_len+=2; -// } else if ((lcid==POWER_HEADROOM) || (lcid==TRUNCATED_BSR)|| (lcid== SHORT_BSR)) { -// ce_len++; -// } else { -// LOG_E(MAC,"unknown CE %d \n", lcid); -// mac_xface->macphy_exit("unknown CE"); -// } -// } -// } -// } - -// *num_ce = num_ces; -// *num_sdu = num_sdus; - -// return(mac_header_ptr); -// } - - -void flexran_agent_schedule_ulsch_ue_spec(module_id_t module_idP, +void flexran_agent_schedule_ulsch_ue_spec(mid_t module_idP, frame_t frameP, unsigned char cooperation_flag, sub_frame_t subframeP, @@ -959,8 +494,6 @@ void flexran_agent_schedule_ulsch_ue_spec(module_id_t module_idP, Protocol__FlexranMessage **ul_info) { -flexran_agent_mac_create_empty_ul_config(module_idP, ul_info); - uint16_t first_rb[MAX_NUM_CCs],i; int CC_id; eNB_MAC_INST *eNB=&eNB_mac_inst[module_idP]; @@ -1007,11 +540,6 @@ flexran_agent_mac_create_empty_ul_config(module_idP, ul_info); flexran_agent_schedule_ulsch_rnti(module_idP, cooperation_flag, frameP, subframeP, sched_subframe,first_rb); -// #ifdef CBA - // schedule_ulsch_cba_rnti(module_idP, cooperation_flag, frameP, subframeP, sched_subframe, first_rb); -// #endif - - stop_meas(&eNB->schedule_ulsch); } @@ -1227,7 +755,7 @@ abort(); UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs; // buffer_occupancy = UE_template->ul_total_buffer; - while (((rb_table[rb_table_index]>(nb_rbs_allowed_slice[CC_id][slice_id]-1-first_rb[CC_id])) || + while (((rb_table[rb_table_index]>(nb_rbs_allowed_slice[CC_id][UE_id]-1-first_rb[CC_id])) || (rb_table[rb_table_index]>45)) && (rb_table_index>0)) { rb_table_index--; @@ -1237,7 +765,7 @@ abort(); UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=rb_table[rb_table_index]; UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS=TBS; // buffer_occupancy -= TBS; - rballoc = mac_xface->computeRIV(nb_rbs_allowed_slice[CC_id][slice_id], + rballoc = mac_xface->computeRIV(frame_parms->N_RB_UL, first_rb[CC_id], rb_table[rb_table_index]); @@ -1527,325 +1055,3 @@ abort(); } // loop of CC_id } -// #ifdef CBA -// void schedule_ulsch_cba_rnti(module_id_t module_idP, unsigned char cooperation_flag, frame_t frameP, sub_frame_t subframeP, unsigned char sched_subframe, uint16_t *first_rb) -// { - -// eNB_MAC_INST *eNB = &eNB_mac_inst[module_idP]; -// UE_list_t *UE_list=&eNB->UE_list; -// //UE_TEMPLATE *UE_template; -// void *ULSCH_dci = NULL; -// DCI_PDU *DCI_pdu; -// uint8_t CC_id=0; -// uint8_t rb_table_index=0, aggregation=2; -// uint32_t rballoc; -// uint8_t cba_group, cba_resources; -// uint8_t required_rbs[NUM_MAX_CBA_GROUP]; -// int8_t num_cba_resources[NUM_MAX_CBA_GROUP];// , weight[NUM_MAX_CBA_GROUP] -// // the following vars should become a vector [MAX_NUM_CCs] -// LTE_DL_FRAME_PARMS *frame_parms; -// int8_t available_rbs=0; -// uint8_t remaining_rbs=0; -// uint8_t allocated_rbs=0; -// uint8_t total_UEs=UE_list->num_UEs; -// uint8_t active_UEs[NUM_MAX_CBA_GROUP]; -// uint8_t total_groups=eNB_mac_inst[module_idP].common_channels[CC_id].num_active_cba_groups; -// int min_rb_unit=2; -// uint8_t cba_policy=CBA_ES; -// int UE_id; -// uint8_t mcs[NUM_MAX_CBA_GROUP]; -// uint32_t total_cba_resources=0; -// uint32_t total_rbs=0; -// // We compute the weight of each group and initialize some variables - -// // loop over all active UEs -// // for (UE_id=UE_list->head_ul;UE_id>=0;UE_id=UE_list->next_ul[UE_id]) { - -// for (cba_group=0; cba_groupget_lte_frame_parms(module_idP,CC_id); -// available_rbs=frame_parms->N_RB_DL-1-first_rb[CC_id]; -// remaining_rbs=available_rbs; -// total_groups=eNB_mac_inst[module_idP].common_channels[CC_id].num_active_cba_groups; -// min_rb_unit=get_min_rb_unit(module_idP,CC_id); - -// if (available_rbs < min_rb_unit ) -// continue; - -// // remove this condition later -// // cba group template uses the exisitng UE template, and thus if a UE -// // is scheduled, the correspodning group can't be used for CBA -// // this can be fixed later -// if (total_groups > 0) { -// DCI_pdu = &eNB_mac_inst[module_idP].common_channels[CC_id].DCI_pdu; - -// for (cba_group=0; -// (cba_group (1<head_ul; UE_id>=0; UE_id=UE_list->next_ul[UE_id]) { -// if (UE_RNTI(module_idP,UE_id)==NOT_A_RNTI) -// continue; - -// // simple UE identity based grouping -// if ((UE_id % total_groups) == cba_group) { // this could be simplifed to active_UEs[UE_id % total_groups]++; -// if ((mac_eNB_get_rrc_status(module_idP,rnti) > RRC_CONNECTED) && -// (UE_is_to_be_scheduled(module_idP,CC_id,UE_id) == 0)) { -// active_UEs[cba_group]++; -// } -// } - -// if (UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul <= 2) { -// mcs[cba_group]= 8; // apply fixed scheduling -// } else if ((UE_id % total_groups) == cba_group) { -// mcs[cba_group]= cmin(mcs[cba_group],UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul); -// } -// } - -// mcs[cba_group]= mcs[cba_group];//cmin(mcs[cba_group],openair_daq_vars.target_ue_ul_mcs); - -// if (available_rbs < min_rb_unit ) -// break; - -// // If the group needs some resource -// // determine the total number of allocations (one or multiple DCIs): to be refined -// if ((active_UEs[cba_group] > 0) && (eNB_mac_inst[module_idP].common_channels[CC_id].cba_rnti[cba_group] != 0)) { -// // to be refined in case of : total_UEs >> weight[cba_group]*available_rbs - -// switch(cba_policy) { -// case CBA_ES: -// required_rbs[cba_group] = (uint8_t)floor(available_rbs/total_groups); // allocate equally among groups -// num_cba_resources[cba_group]=1; -// break; - -// // can't have more than one allocation for the same group/UE -// /* case CBA_ES_S: -// required_rbs[cba_group] = (uint8_t)floor(available_rbs/total_groups); // allocate equally among groups -// if (required_rbs[cba_group] > min_rb_unit) -// num_cba_resources[cba_group]=(uint8_t)(required_rbs[cba_group]/ min_rb_unit); -// break;*/ -// case CBA_PF: -// required_rbs[cba_group] = (uint8_t)floor((active_UEs[cba_group]*available_rbs)/total_UEs); -// num_cba_resources[cba_group]=1; -// break; -// /* case CBA_PF_S: -// required_rbs[cba_group] = (uint8_t)ceil((active_UEs[cba_group]*available_rbs)/total_UEs); -// if (required_rbs[cba_group] > min_rb_unit) -// num_cba_resources[cba_group]=(uint8_t) floor(required_rbs[cba_group] / min_rb_unit); -// break;*/ - -// default: -// LOG_W(MAC,"unknown CBA policy\n"); -// break; -// } - -// total_cba_resources+=num_cba_resources[cba_group]; -// total_rbs+=required_rbs[cba_group]; - -// /* while ((remaining_rbs < required_rbs[cba_group]) && -// (required_rbs[cba_group] > 0) && -// (required_rbs[cba_group] < min_rb_unit )) -// required_rbs[cba_group]--; -// */ - -// /* -// while (rb_table[rb_table_index] < required_rbs[cba_group]) -// rb_table_index++; - -// while (rb_table[rb_table_index] > remaining_rbs ) -// rb_table_index--; - -// remaining_rbs-=rb_table[rb_table_index]; -// required_rbs[cba_group]=rb_table[rb_table_index]; -// */ -// // num_cba_resources[cba_group]=1; - -// } -// } - -// // phase 2 reduce the number of cba allocations among the groups -// cba_group=0; - -// if (total_cba_resources <= 0) { -// return; -// } - -// // increase rb if any left: to be done -// cba_group=0; - -// while (total_rbs < available_rbs - 1 ) { -// required_rbs[cba_group%total_groups]++; -// total_rbs++; -// cba_group++; -// } - -// // phase 3: -// for (cba_group=0; cba_group remaining_rbs ) { -// rb_table_index--; -// } - -// remaining_rbs-=rb_table[rb_table_index]; -// allocated_rbs=rb_table[rb_table_index]; - -// rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_UL, -// first_rb[CC_id], -// rb_table[rb_table_index]); - -// first_rb[CC_id]+=rb_table[rb_table_index]; -// LOG_N(MAC, -// "[eNB %d] CC_id %d Frame %d, subframeP %d: schedule CBA access %d rnti %x, total/required/allocated/remaining rbs (%d/%d/%d/%d), mcs %d, rballoc %d\n", -// module_idP, CC_id, frameP, subframeP, cba_group,eNB_mac_inst[module_idP].common_channels[CC_id].cba_rnti[cba_group], -// available_rbs, required_rbs[cba_group], allocated_rbs, remaining_rbs, -// mcs[cba_group],rballoc); - -// switch (frame_parms->N_RB_UL) { -// case 6: -// mac_xface->macphy_exit("[MAC][eNB] CBA RB=6 not supported \n"); -// break; - -// case 25: -// if (frame_parms->frame_type == TDD) { -// ULSCH_dci = UE_list->UE_template[CC_id][cba_group].ULSCH_DCI[0]; - -// ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->type = 0; -// ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->hopping = 0; -// ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->rballoc = rballoc; -// ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->mcs = mcs[cba_group]; -// ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->ndi = 1; -// ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->TPC = 1;//tpc; -// ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->cshift = cba_group; -// ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->dai = UE_list->UE_template[CC_id][cba_group].DAI_ul[sched_subframe]; -// ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req = 1; - -// //add_ue_spec_dci -// add_common_dci(DCI_pdu, -// ULSCH_dci, -// eNB_mac_inst[module_idP].common_channels[CC_id].cba_rnti[cba_group], -// sizeof(DCI0_5MHz_TDD_1_6_t), -// aggregation, -// sizeof_DCI0_5MHz_TDD_1_6_t, -// format0, -// 0); -// } else { -// ULSCH_dci = UE_list->UE_template[CC_id][cba_group].ULSCH_DCI[0]; - -// ((DCI0_5MHz_FDD_t *)ULSCH_dci)->type = 0; -// ((DCI0_5MHz_FDD_t *)ULSCH_dci)->hopping = 0; -// ((DCI0_5MHz_FDD_t *)ULSCH_dci)->rballoc = rballoc; -// ((DCI0_5MHz_FDD_t *)ULSCH_dci)->mcs = mcs[cba_group]; -// ((DCI0_5MHz_FDD_t *)ULSCH_dci)->ndi = 1; -// ((DCI0_5MHz_FDD_t *)ULSCH_dci)->TPC = 1;//tpc; -// ((DCI0_5MHz_FDD_t *)ULSCH_dci)->cshift = cba_group; -// ((DCI0_5MHz_FDD_t *)ULSCH_dci)->cqi_req = 1; - -// //add_ue_spec_dci -// add_common_dci(DCI_pdu, -// ULSCH_dci, -// eNB_mac_inst[module_idP].common_channels[CC_id].cba_rnti[cba_group], -// sizeof(DCI0_5MHz_FDD_t), -// aggregation, -// sizeof_DCI0_5MHz_FDD_t, -// format0, -// 0); -// } - -// LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for CBA group %d, RB 25 format 0\n", module_idP,CC_id,frameP,subframeP,cba_group); -// break; - -// case 50: -// if (frame_parms->frame_type == TDD) { -// ULSCH_dci = UE_list->UE_template[CC_id][cba_group].ULSCH_DCI[0]; - -// ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->type = 0; -// ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->hopping = 0; -// ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->rballoc = rballoc; -// ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->mcs = mcs[cba_group]; -// ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->ndi = 1; -// ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->TPC = 1;//tpc; -// ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->cshift = cba_group; -// ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->dai = UE_list->UE_template[CC_id][cba_group].DAI_ul[sched_subframe]; -// ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req = 1; - -// //add_ue_spec_dci -// add_common_dci(DCI_pdu, -// ULSCH_dci, -// eNB_mac_inst[module_idP].common_channels[CC_id].cba_rnti[cba_group], -// sizeof(DCI0_10MHz_TDD_1_6_t), -// aggregation, -// sizeof_DCI0_10MHz_TDD_1_6_t, -// format0, -// 0); -// } else { -// ULSCH_dci = UE_list->UE_template[CC_id][cba_group].ULSCH_DCI[0]; - -// ((DCI0_10MHz_FDD_t *)ULSCH_dci)->type = 0; -// ((DCI0_10MHz_FDD_t *)ULSCH_dci)->hopping = 0; -// ((DCI0_10MHz_FDD_t *)ULSCH_dci)->rballoc = rballoc; -// ((DCI0_10MHz_FDD_t *)ULSCH_dci)->mcs = mcs[cba_group]; -// ((DCI0_10MHz_FDD_t *)ULSCH_dci)->ndi = 1; -// ((DCI0_10MHz_FDD_t *)ULSCH_dci)->TPC = 1;//tpc; -// ((DCI0_10MHz_FDD_t *)ULSCH_dci)->cshift = cba_group; -// ((DCI0_10MHz_FDD_t *)ULSCH_dci)->cqi_req = 1; - -// //add_ue_spec_dci -// add_common_dci(DCI_pdu, -// ULSCH_dci, -// eNB_mac_inst[module_idP].common_channels[CC_id].cba_rnti[cba_group], -// sizeof(DCI0_10MHz_FDD_t), -// aggregation, -// sizeof_DCI0_10MHz_FDD_t, -// format0, -// 0); -// } - -// LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for CBA group %d, RB 50 format 0\n", module_idP,CC_id,frameP,subframeP,cba_group); -// break; - -// case 100: -// mac_xface->macphy_exit("[MAC][eNB] CBA RB=100 not supported \n"); -// break; - -// default: -// break; -// } - -// // break;// for the moment only schedule one -// } -// } -// } -// } -// } -// #endif From 5c7377e1c090bd0e51cf53efde597e98f2c1008c Mon Sep 17 00:00:00 2001 From: shahab SHARIATBAGHERI Date: Thu, 18 May 2017 17:21:07 +0200 Subject: [PATCH 020/195] Fix bug header --- openair2/LAYER2/MAC/flexran_agent_mac_proto.h | 17 +++- .../MAC/flexran_agent_scheduler_dlsch_ue.c | 12 +-- .../MAC/flexran_agent_scheduler_ulsch_ue.c | 88 +++++++++++-------- 3 files changed, 71 insertions(+), 46 deletions(-) diff --git a/openair2/LAYER2/MAC/flexran_agent_mac_proto.h b/openair2/LAYER2/MAC/flexran_agent_mac_proto.h index c2d28b33f7..5fc53fece6 100644 --- a/openair2/LAYER2/MAC/flexran_agent_mac_proto.h +++ b/openair2/LAYER2/MAC/flexran_agent_mac_proto.h @@ -39,13 +39,19 @@ /* * slice specific scheduler */ -typedef void (*slice_scheduler)(module_id_t mod_id, +typedef void (*slice_scheduler_dl)(module_id_t mod_id, int slice_id, uint32_t frame, uint32_t subframe, int *mbsfn_flag, Protocol__FlexranMessage **dl_info); +typedef void (*slice_scheduler_ul)(module_id_t mod_id, + frame_t frame, + unsigned char cooperation_flag, + uint32_t subframe, + unsigned char sched_subframe, + Protocol__FlexranMessage **ul_info); /* @@ -109,6 +115,15 @@ flexran_schedule_ue_dl_spec_common(mid_t mod_id, int *mbsfn_flag, Protocol__FlexranMessage **dl_info); +void +flexran_schedule_ue_ul_spec_default(mid_t mod_id, + uint32_t frame, + uint32_t cooperation_flag, + int subframe, + unsigned char sched_subframe, + Protocol__FlexranMessage **ul_info); + + uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, int total_rbs); diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c index cfb14af641..b30cb5f491 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c @@ -88,8 +88,8 @@ typedef enum { // number of active slices for past and current time -int n_active_slices = 1; -int n_active_slices_current = 1; +static int n_active_slices = 1; +static int n_active_slices_current = 1; // ue to slice mapping int slicing_strategy = UEID_TO_SLICEID; @@ -115,7 +115,7 @@ char *dl_scheduler_type[MAX_NUM_SLICES] = {"flexran_schedule_ue_spec_embb", }; // pointer to the slice specific scheduler -slice_scheduler slice_sched[MAX_NUM_SLICES] = {0}; +slice_scheduler_dl slice_sched_dl[MAX_NUM_SLICES] = {0}; /** @@ -729,7 +729,7 @@ flexran_schedule_ue_dl_spec_default(mid_t mod_id, // Load any updated functions if (update_dl_scheduler[i] > 0 ) { - slice_sched[i] = dlsym(NULL, dl_scheduler_type[i]); + slice_sched_dl[i] = dlsym(NULL, dl_scheduler_type[i]); update_dl_scheduler[i] = 0; update_dl_scheduler_current[i] = 0; slice_percentage_current[i]= slice_percentage[i]; @@ -806,7 +806,7 @@ flexran_schedule_ue_dl_spec_default(mid_t mod_id, // Run each enabled slice-specific schedulers one by one //LOG_N(MAC,"[eNB %d]frame %d subframe %d slice %d: calling the scheduler\n", mod_id, frame, subframe,i); - slice_sched[i](mod_id, i, frame, subframe, mbsfn_flag,dl_info); + slice_sched_dl[i](mod_id, i, frame, subframe, mbsfn_flag,dl_info); } @@ -894,7 +894,7 @@ flexran_schedule_ue_spec_urllc(mid_t mod_id, Protocol__FlexranMessage **dl_info) { - flexran_schedule_ue_spec_dl_common(mod_id, + flexran_schedule_ue_dl_spec_common(mod_id, slice_id, frame, subframe, diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c index 20e1c67366..9a9ecbb1e5 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c @@ -35,6 +35,7 @@ #include "SCHED/defs.h" #include "SCHED/extern.h" +#include "LAYER2/MAC/flexran_agent_mac_proto.h" #include "LAYER2/MAC/defs.h" #include "LAYER2/MAC/proto.h" #include "LAYER2/MAC/extern.h" @@ -56,22 +57,30 @@ #include "T.h" -// #define ENABLE_MAC_PAYLOAD_DEBUG -// #define DEBUG_eNB_SCHEDULER 1 +/* number of active slices for past and current time*/ +static int n_active_slices = 1; +static int n_active_slices_current = 1; - -// RB share for each slice for past and current time -float slice_percentage_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; +/* RB share for each slice for past and current time*/ +float slice_percentage_uplink[MAX_NUM_SLICES] = {0.8, 0.2, 0.0, 0.0}; float slice_percentage_current_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; +float total_slice_percentage_uplink = 0; - - uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES]; - +/*resource blocks allowed*/ +static uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES]; +/*Slice Update */ int update_ul_scheduler[MAX_NUM_SLICES] = {1, 1, 1, 1}; int update_ul_scheduler_current[MAX_NUM_SLICES] = {1, 1, 1, 1}; -// name of available scheduler -char *ul_scheduler_type[MAX_NUM_SLICES] = {"flexran_schedule_ue_ul_spec_embb"}; + /* Slice Function Pointer */ +slice_scheduler_ul slice_sched_ul[MAX_NUM_SLICES] = {0}; + +/* name of available scheduler*/ +char *ul_scheduler_type[MAX_NUM_SLICES] = {"flexran_schedule_ue_ul_spec_embb", + "flexran_schedule_ue_ul_spec_urllc", + "flexran_schedule_ue_ul_spec_mmtc", + "flexran_schedule_ue_ul_spec_be" // best effort +}; uint16_t flexran_nb_rbs_allowed_slice_uplink(float rb_percentage, int total_rbs){ @@ -387,25 +396,26 @@ void _ulsch_scheduler_pre_processor(module_id_t module_idP, void flexran_schedule_ue_ul_spec_default(mid_t mod_id, uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage **dl_info) + uint32_t cooperation_flag, + int subframe, + unsigned char sched_subframe, + Protocol__FlexranMessage **ul_info) //------------------------------------------------------------------------------ { int i=0; - flexran_agent_mac_create_empty_ul_config(module_idP, ul_info); + flexran_agent_mac_create_empty_ul_config(mod_id, ul_info); for (i = 0; i < n_active_slices; i++) { // Load any updated functions - if (update_dl_scheduler[i] > 0 ) { - slice_sched[i] = dlsym(NULL, dl_scheduler_type[i]); - update_dl_scheduler[i] = 0; - update_dl_scheduler_current[i] = 0; - slice_percentage_current[i]= slice_percentage[i]; - total_slice_percentage+=slice_percentage[i]; - LOG_N(MAC,"update dl scheduler slice %d\n", i); + if (update_ul_scheduler[i] > 0 ) { + slice_sched_ul[i] = dlsym(NULL, ul_scheduler_type[i]); + update_ul_scheduler[i] = 0; + update_ul_scheduler_current[i] = 0; + slice_percentage_current_uplink[i]= slice_percentage_uplink[i]; + total_slice_percentage_uplink+=slice_percentage_uplink[i]; + LOG_N(MAC,"update ul scheduler slice %d\n", i); } // check if the number of slices has changed, and log @@ -423,45 +433,45 @@ flexran_schedule_ue_ul_spec_default(mid_t mod_id, } // check if the slice rb share has changed, and log the console - if (slice_percentage_current[i] != slice_percentage[i]){ - if ((slice_percentage[i] >= 0.0) && (slice_percentage[i] <= 1.0)){ - if ((total_slice_percentage - slice_percentage_current[i] + slice_percentage[i]) <= 1.0) { - total_slice_percentage=total_slice_percentage - slice_percentage_current[i] + slice_percentage[i]; + if (slice_percentage_current_uplink[i] != slice_percentage_uplink[i]){ + if ((slice_percentage_uplink[i] >= 0.0) && (slice_percentage_uplink[i] <= 1.0)){ + if ((total_slice_percentage_uplink - slice_percentage_current_uplink[i] + slice_percentage_uplink[i]) <= 1.0) { + total_slice_percentage_uplink=total_slice_percentage_uplink - slice_percentage_current_uplink[i] + slice_percentage_uplink[i]; LOG_N(MAC,"[eNB %d][SLICE %d] frame %d subframe %d: total percentage %f, slice RB percentage has changed: %f-->%f\n", - mod_id, i, frame, subframe, total_slice_percentage, slice_percentage_current[i], slice_percentage[i]); + mod_id, i, frame, subframe, total_slice_percentage_uplink, slice_percentage_current_uplink[i], slice_percentage_uplink[i]); - slice_percentage_current[i] = slice_percentage[i]; + slice_percentage_current_uplink[i] = slice_percentage_uplink[i]; } else { LOG_W(MAC,"[eNB %d][SLICE %d] invalid total RB share (%f->%f), revert the previous value (%f->%f)\n", mod_id,i, - total_slice_percentage, - total_slice_percentage - slice_percentage_current[i] + slice_percentage[i], - slice_percentage[i],slice_percentage_current[i]); + total_slice_percentage_uplink, + total_slice_percentage_uplink - slice_percentage_current_uplink[i] + slice_percentage_uplink[i], + slice_percentage_uplink[i],slice_percentage_current_uplink[i]); - slice_percentage[i]= slice_percentage_current[i]; + slice_percentage_uplink[i]= slice_percentage_current_uplink[i]; } } else { - LOG_W(MAC,"[eNB %d][SLICE %d] invalid slice RB share, revert the previous value (%f->%f)\n",mod_id, i, slice_percentage[i],slice_percentage_current[i]); + LOG_W(MAC,"[eNB %d][SLICE %d] invalid slice RB share, revert the previous value (%f->%f)\n",mod_id, i, slice_percentage_uplink[i],slice_percentage_current_uplink[i]); - slice_percentage[i]= slice_percentage_current[i]; + slice_percentage_uplink[i]= slice_percentage_current_uplink[i]; } } // check if a new scheduler, and log the console - if (update_dl_scheduler_current[i] != update_dl_scheduler[i]){ + if (update_ul_scheduler_current[i] != update_ul_scheduler[i]){ LOG_N(MAC,"[eNB %d][SLICE %d] frame %d subframe %d: DL scheduler for this slice is updated: %s \n", - mod_id, i, frame, subframe, dl_scheduler_type[i]); + mod_id, i, frame, subframe, ul_scheduler_type[i]); - update_dl_scheduler_current[i] = update_dl_scheduler[i]; + update_ul_scheduler_current[i] = update_ul_scheduler[i]; } // Run each enabled slice-specific schedulers one by one //LOG_N(MAC,"[eNB %d]frame %d subframe %d slice %d: calling the scheduler\n", mod_id, frame, subframe,i); - slice_sched[i](mod_id, i, frame, subframe, mbsfn_flag,dl_info); + slice_sched_ul[i](mod_id, frame, cooperation_flag, subframe, sched_subframe,ul_info); } @@ -469,7 +479,7 @@ flexran_schedule_ue_ul_spec_default(mid_t mod_id, void flexran_schedule_ue_ul_spec_embb(mid_t mod_id, - frame_t frameP, + frame_t frame, unsigned char cooperation_flag, uint32_t subframe, unsigned char sched_subframe, @@ -583,7 +593,7 @@ void flexran_agent_schedule_ulsch_rnti(module_id_t module_idP, // LOG_I(MAC,"entering ulsch preprocesor\n"); - + /*TODO*/ int slice_id = 0; From 042a16d1f60c18487990a1f8ade9f48a76f2bb9d Mon Sep 17 00:00:00 2001 From: shahab SHARIATBAGHERI Date: Thu, 18 May 2017 17:26:08 +0200 Subject: [PATCH 021/195] Fix percentage --- openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c index 9a9ecbb1e5..2abc6438c1 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c @@ -62,7 +62,7 @@ static int n_active_slices = 1; static int n_active_slices_current = 1; /* RB share for each slice for past and current time*/ -float slice_percentage_uplink[MAX_NUM_SLICES] = {0.8, 0.2, 0.0, 0.0}; +float slice_percentage_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; float slice_percentage_current_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; float total_slice_percentage_uplink = 0; From 2e2b07ef9e4a4517f32153d1e47a876ad6d26d97 Mon Sep 17 00:00:00 2001 From: shahab SHARIATBAGHERI Date: Mon, 22 May 2017 19:19:28 +0200 Subject: [PATCH 022/195] push update load --- openair2/ENB_APP/flexran_agent_common.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index 78d3a75ec7..fe70a62ec8 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -26,8 +26,9 @@ * \version 0.1 */ -#include +#include #include +#include #include "flexran_agent_common.h" #include "flexran_agent_common_internal.h" @@ -386,13 +387,15 @@ int flexran_agent_control_delegation(mid_t mod_id, const void *params, Protocol_ Protocol__FlexControlDelegation *control_delegation_msg = input->control_delegation_msg; // struct timespec vartime = timer_start(); - + int status; //Write the payload lib into a file in the cache and load the lib char lib_name[120]; char target[512]; snprintf(lib_name, sizeof(lib_name), "/%s.so", control_delegation_msg->name); strcpy(target, local_cache); strcat(target, lib_name); + + status = mkdir(local_cache, S_IRWXU | S_IRWXG | S_IRWXO); FILE *f; f = fopen(target, "wb"); From 8458c8fcf82a401ceba3c9d58f8000d09f6cd8a0 Mon Sep 17 00:00:00 2001 From: shahab SHARIAT BAGHERI Date: Tue, 23 May 2017 23:46:31 +0200 Subject: [PATCH 023/195] uplink mac parser --- .../MAC/flexran_agent_mac_internal.c | 5 ++++- .../MAC/flexran_agent_scheduler_dlsch_ue.c | 4 ++-- .../MAC/flexran_agent_scheduler_ulsch_ue.c | 18 +++++++++--------- openair2/RRC/LITE/extern.h | 4 ++-- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index 66efafae55..13b63b1494 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -607,7 +607,10 @@ int parse_mac_config(mid_t mod_id, yaml_parser_t *parser) { } else if (strcmp((char *) event.data.scalar.value, "ul_scheduler") == 0) { // Call the proper handler LOG_D(ENB_APP, "This is for the ul_scheduler subsystem\n"); - goto error; + if (parse_dl_scheduler_config(mod_id, parser) == -1) { + LOG_D(ENB_APP, "An error occured\n"); + goto error; + } // TODO } else if (strcmp((char *) event.data.scalar.value, "ra_scheduler") == 0) { // Call the proper handler diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c index b30cb5f491..fce24223b5 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c @@ -88,8 +88,8 @@ typedef enum { // number of active slices for past and current time -static int n_active_slices = 1; -static int n_active_slices_current = 1; +int n_active_slices = 1; +int n_active_slices_current = 1; // ue to slice mapping int slicing_strategy = UEID_TO_SLICEID; diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c index 2abc6438c1..d8f9fe8e63 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c @@ -58,8 +58,8 @@ #include "T.h" /* number of active slices for past and current time*/ -static int n_active_slices = 1; -static int n_active_slices_current = 1; +int n_active_slices_uplink = 1; +int n_active_slices_uplink_current = 1; /* RB share for each slice for past and current time*/ float slice_percentage_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; @@ -406,7 +406,7 @@ flexran_schedule_ue_ul_spec_default(mid_t mod_id, flexran_agent_mac_create_empty_ul_config(mod_id, ul_info); - for (i = 0; i < n_active_slices; i++) { + for (i = 0; i < n_active_slices_uplink; i++) { // Load any updated functions if (update_ul_scheduler[i] > 0 ) { @@ -419,16 +419,16 @@ flexran_schedule_ue_ul_spec_default(mid_t mod_id, } // check if the number of slices has changed, and log - if (n_active_slices_current != n_active_slices ){ - if ((n_active_slices > 0) && (n_active_slices <= MAX_NUM_SLICES)) { + if (n_active_slices_uplink_current != n_active_slices_uplink ){ + if ((n_active_slices_uplink > 0) && (n_active_slices_uplink <= MAX_NUM_SLICES)) { LOG_N(MAC,"[eNB %d]frame %d subframe %d: number of active slices has changed: %d-->%d\n", - mod_id, frame, subframe, n_active_slices_current, n_active_slices); + mod_id, frame, subframe, n_active_slices_uplink_current, n_active_slices_uplink); - n_active_slices_current = n_active_slices; + n_active_slices_uplink_current = n_active_slices_uplink; } else { - LOG_W(MAC,"invalid number of slices %d, revert to the previous value %d\n",n_active_slices, n_active_slices_current); - n_active_slices = n_active_slices_current; + LOG_W(MAC,"invalid number of slices %d, revert to the previous value %d\n",n_active_slices_uplink, n_active_slices_uplink_current); + n_active_slices_uplink = n_active_slices_uplink_current; } } diff --git a/openair2/RRC/LITE/extern.h b/openair2/RRC/LITE/extern.h index d4c8192a95..7934690563 100644 --- a/openair2/RRC/LITE/extern.h +++ b/openair2/RRC/LITE/extern.h @@ -93,8 +93,8 @@ extern uint16_t N310[8]; extern uint16_t N311[8]; extern uint32_t T304[8]; extern uint32_t timeToTrigger_ms[16]; -extern float RSRP_meas_mapping[100]; -extern float RSRQ_meas_mapping[33]; +extern float RSRP_meas_mapping[98]; +extern float RSRQ_meas_mapping[35]; #endif From 1ecdcba33a88c56f9eceb62621f094a93daac80d Mon Sep 17 00:00:00 2001 From: shahab SHARIATBAGHERI Date: Thu, 8 Jun 2017 18:36:25 +0200 Subject: [PATCH 024/195] uplink VSF --- cmake_targets/CMakeLists.txt | 3 + .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 4 +- .../MAC/flexran_agent_mac_defs.h | 4 +- .../MAC/flexran_agent_mac_internal.c | 107 +++++++++++++++++- .../MAC/flexran_agent_mac_internal.h | 4 + .../MAC/flexran_agent_scheduler_dlsch_ue.c | 38 +++---- .../MAC/flexran_agent_scheduler_ulsch_ue.c | 72 ++++++------ 7 files changed, 174 insertions(+), 58 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 192590e20f..a04915bb53 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1231,6 +1231,9 @@ if (FLEXRAN_AGENT_SB_IF) add_library(default_sched SHARED ${MAC_DIR}/flexran_agent_scheduler_dlsch_ue.c) add_library(remote_sched SHARED ${MAC_DIR}/flexran_agent_scheduler_dlsch_ue_remote.c) +add_library(default_ul_sched SHARED ${MAC_DIR}/flexran_agent_scheduler_ulsch_ue.c) + + endif() # L3 Libs diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index f17fb9a1ba..512be68669 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -1254,7 +1254,7 @@ int flexran_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { xface->flexran_agent_get_pending_dl_mac_config = flexran_agent_get_pending_dl_mac_config; xface->dl_scheduler_loaded_lib = NULL; - + xface->ul_scheduler_loaded_lib = NULL; mac_agent_registered[mod_id] = 1; agent_mac_xface[mod_id] = xface; @@ -1272,7 +1272,7 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { xface->dl_scheduler_loaded_lib = NULL; - + xface->ul_scheduler_loaded_lib = NULL; mac_agent_registered[mod_id] = 0; agent_mac_xface[mod_id] = NULL; diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h index 49ef7f0fb7..362c50f13c 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h @@ -62,8 +62,7 @@ typedef struct { void (*flexran_agent_schedule_ul_spec)(mid_t module_idP, uint32_t frameP, unsigned char cooperation_flag, - uint32_t subframeP, - unsigned char sched_subframe, Protocol__FlexranMessage **ul_info); + uint32_t subframeP, unsigned char sched_subframe, Protocol__FlexranMessage **ul_info); /// Notify the controller for a state change of a particular UE, by sending the proper /// UE state change message (ACTIVATION, DEACTIVATION, HANDOVER) @@ -72,6 +71,7 @@ typedef struct { void *dl_scheduler_loaded_lib; + void *ul_scheduler_loaded_lib; /*TODO: Fill in with the rest of the MAC layer technology specific callbacks (UL/DL scheduling, RACH info etc)*/ } AGENT_MAC_xface; diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index 13b63b1494..68b82713e6 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -607,7 +607,7 @@ int parse_mac_config(mid_t mod_id, yaml_parser_t *parser) { } else if (strcmp((char *) event.data.scalar.value, "ul_scheduler") == 0) { // Call the proper handler LOG_D(ENB_APP, "This is for the ul_scheduler subsystem\n"); - if (parse_dl_scheduler_config(mod_id, parser) == -1) { + if (parse_ul_scheduler_config(mod_id, parser) == -1) { LOG_D(ENB_APP, "An error occured\n"); goto error; } @@ -703,6 +703,56 @@ int parse_dl_scheduler_config(mid_t mod_id, yaml_parser_t *parser) { return -1; } +int parse_ul_scheduler_config(mid_t mod_id, yaml_parser_t *parser) { + + yaml_event_t event; + + int done = 0; + int mapping_started = 0; + + while (!done) { + + if (!yaml_parser_parse(parser, &event)) + goto error; + + switch (event.type) { + // We are expecting a mapping (behavior and parameters) + case YAML_MAPPING_START_EVENT: + LOG_D(ENB_APP, "The mapping of the subsystem started\n"); + mapping_started = 1; + break; + case YAML_MAPPING_END_EVENT: + LOG_D(ENB_APP, "The mapping of the subsystem ended\n"); + mapping_started = 0; + break; + case YAML_SCALAR_EVENT: + if (!mapping_started) { + goto error; + } + // Check what key needs to be set + if (strcmp((char *) event.data.scalar.value, "parameters") == 0) { + LOG_D(ENB_APP, "Now it is time to set the parameters for this subsystem\n"); + if (parse_ul_scheduler_parameters(mod_id, parser) == -1) { + goto error; + } + } + break; + default: + goto error; + } + + done = (event.type == YAML_MAPPING_END_EVENT); + yaml_event_delete(&event); + } + + return 0; + + error: + yaml_event_delete(&event); + return -1; +} + + int parse_dl_scheduler_parameters(mid_t mod_id, yaml_parser_t *parser) { yaml_event_t event; @@ -758,6 +808,61 @@ int parse_dl_scheduler_parameters(mid_t mod_id, yaml_parser_t *parser) { return -1; } +int parse_ul_scheduler_parameters(mid_t mod_id, yaml_parser_t *parser) { + yaml_event_t event; + + void *param; + + int done = 0; + int mapping_started = 0; + + while (!done) { + + if (!yaml_parser_parse(parser, &event)) + goto error; + + switch (event.type) { + // We are expecting a mapping of parameters + case YAML_MAPPING_START_EVENT: + LOG_D(ENB_APP, "The mapping of the parameters started\n"); + mapping_started = 1; + break; + case YAML_MAPPING_END_EVENT: + LOG_D(ENB_APP, "The mapping of the parameters ended\n"); + mapping_started = 0; + break; + case YAML_SCALAR_EVENT: + if (!mapping_started) { + goto error; + } + // Check what key needs to be set + if (mac_agent_registered[mod_id]) { + LOG_D(ENB_APP, "Setting parameter %s\n", event.data.scalar.value); + param = dlsym(agent_mac_xface[mod_id]->ul_scheduler_loaded_lib, + (char *) event.data.scalar.value); + if (param == NULL) { + goto error; + } + apply_parameter_modification(param, parser); + } else { + goto error; + } + break; + default: + goto error; + } + + done = (event.type == YAML_MAPPING_END_EVENT); + yaml_event_delete(&event); + } + + return 0; + + error: + yaml_event_delete(&event); + return -1; +} + int load_dl_scheduler_function(mid_t mod_id, const char *function_name) { void *lib; diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h index 9a7d4a8555..95f6934e56 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h @@ -101,6 +101,10 @@ int parse_dl_scheduler_config(mid_t mod_id, yaml_parser_t *parser); int parse_dl_scheduler_parameters(mid_t mod_id, yaml_parser_t *parser); +int parse_ul_scheduler_config(mid_t mod_id, yaml_parser_t *parser); + +int parse_ul_scheduler_parameters(mid_t mod_id, yaml_parser_t *parser); + int load_dl_scheduler_function(mid_t mod_id, const char *function_name); #endif /*FLEXRAN_AGENT_MAC_INTERNAL_H_*/ diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c index fce24223b5..ade4b77c14 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c @@ -88,16 +88,16 @@ typedef enum { // number of active slices for past and current time -int n_active_slices = 1; -int n_active_slices_current = 1; +int n_active_slices = 2; +int n_active_slices_current = 2; // ue to slice mapping int slicing_strategy = UEID_TO_SLICEID; int slicing_strategy_current = UEID_TO_SLICEID; // RB share for each slice for past and current time -float slice_percentage[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; -float slice_percentage_current[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; +float slice_percentage[MAX_NUM_SLICES] = {0.5, 0.5, 0.0, 0.0}; +float slice_percentage_current[MAX_NUM_SLICES] = {0.5, 0.5, 0.0, 0.0}; float total_slice_percentage = 0; // MAX MCS for each slice for past and current time @@ -753,30 +753,30 @@ flexran_schedule_ue_dl_spec_default(mid_t mod_id, // check if the slice rb share has changed, and log the console if (slice_percentage_current[i] != slice_percentage[i]){ - if ((slice_percentage[i] >= 0.0) && (slice_percentage[i] <= 1.0)){ - if ((total_slice_percentage - slice_percentage_current[i] + slice_percentage[i]) <= 1.0) { - total_slice_percentage=total_slice_percentage - slice_percentage_current[i] + slice_percentage[i]; + // if ((slice_percentage[i] >= 0.0) && (slice_percentage[i] <= 1.0)){ + // if ((total_slice_percentage - slice_percentage_current[i] + slice_percentage[i]) <= 1.0) { + // total_slice_percentage=total_slice_percentage - slice_percentage_current[i] + slice_percentage[i]; LOG_N(MAC,"[eNB %d][SLICE %d] frame %d subframe %d: total percentage %f, slice RB percentage has changed: %f-->%f\n", mod_id, i, frame, subframe, total_slice_percentage, slice_percentage_current[i], slice_percentage[i]); slice_percentage_current[i] = slice_percentage[i]; - } else { - LOG_W(MAC,"[eNB %d][SLICE %d] invalid total RB share (%f->%f), revert the previous value (%f->%f)\n", - mod_id,i, - total_slice_percentage, - total_slice_percentage - slice_percentage_current[i] + slice_percentage[i], - slice_percentage[i],slice_percentage_current[i]); + // } else { + // LOG_W(MAC,"[eNB %d][SLICE %d] invalid total RB share (%f->%f), revert the previous value (%f->%f)\n", + // mod_id,i, + // total_slice_percentage, + // total_slice_percentage - slice_percentage_current[i] + slice_percentage[i], + // slice_percentage[i],slice_percentage_current[i]); - slice_percentage[i]= slice_percentage_current[i]; + // slice_percentage[i]= slice_percentage_current[i]; - } - } else { - LOG_W(MAC,"[eNB %d][SLICE %d] invalid slice RB share, revert the previous value (%f->%f)\n",mod_id, i, slice_percentage[i],slice_percentage_current[i]); + // } + // } else { + // LOG_W(MAC,"[eNB %d][SLICE %d] invalid slice RB share, revert the previous value (%f->%f)\n",mod_id, i, slice_percentage[i],slice_percentage_current[i]); - slice_percentage[i]= slice_percentage_current[i]; + // slice_percentage[i]= slice_percentage_current[i]; - } + // } } // check if the slice max MCS, and log the console diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c index d8f9fe8e63..b0e7272e9d 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c @@ -58,16 +58,16 @@ #include "T.h" /* number of active slices for past and current time*/ -int n_active_slices_uplink = 1; -int n_active_slices_uplink_current = 1; +int n_active_slices_uplink = 2; +int n_active_slices_uplink_current = 2; /* RB share for each slice for past and current time*/ -float slice_percentage_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; -float slice_percentage_current_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; +float slice_percentage_uplink[MAX_NUM_SLICES] = {0.5, 0.5, 0.0, 0.0}; +float slice_percentage_current_uplink[MAX_NUM_SLICES] = {0.5, 0.5, 0.0, 0.0}; float total_slice_percentage_uplink = 0; /*resource blocks allowed*/ -static uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES]; +uint16_t nb_rbs_allowed_slice_uplink[MAX_NUM_CCs][MAX_NUM_SLICES]; /*Slice Update */ int update_ul_scheduler[MAX_NUM_SLICES] = {1, 1, 1, 1}; int update_ul_scheduler_current[MAX_NUM_SLICES] = {1, 1, 1, 1}; @@ -144,7 +144,7 @@ void _assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, su UE_list->numactiveULCCs[UE_id]); frame_parms=mac_xface->get_lte_frame_parms(module_idP,CC_id); UE_template = &UE_list->UE_template[CC_id][UE_id]; - nb_rbs_allowed_slice[CC_id][UE_id] = flexran_nb_rbs_allowed_slice_uplink(slice_percentage_uplink[UE_id], flexran_get_N_RB_UL(module_idP, CC_id)); + nb_rbs_allowed_slice_uplink[CC_id][UE_id] = flexran_nb_rbs_allowed_slice_uplink(slice_percentage_uplink[UE_id], flexran_get_N_RB_UL(module_idP, CC_id)); // if this UE has UL traffic if (UE_template->ul_total_buffer > 0 ) { @@ -161,7 +161,7 @@ void _assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, su } while ((tbs < UE_template->ul_total_buffer) && - (rb_table[rb_table_index]<(nb_rbs_allowed_slice[CC_id][UE_id]-first_rb[CC_id])) && + (rb_table[rb_table_index]<(nb_rbs_allowed_slice_uplink[CC_id][UE_id]-first_rb[CC_id])) && ((UE_template->phr_info - tx_power) > 0) && (rb_table_index < 32 )) { // LOG_I(MAC,"tbs %d ul buffer %d rb table %d max ul rb %d\n", tbs, UE_template->ul_total_buffer, rb_table[rb_table_index], frame_parms->N_RB_UL-first_rb[CC_id]); @@ -172,7 +172,7 @@ void _assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, su UE_template->ue_tx_power = tx_power; - if (rb_table[rb_table_index]>(nb_rbs_allowed_slice[CC_id][UE_id]-first_rb[CC_id]-1)) { + if (rb_table[rb_table_index]>(nb_rbs_allowed_slice_uplink[CC_id][UE_id]-first_rb[CC_id]-1)) { rb_table_index--; } @@ -212,7 +212,7 @@ void _ulsch_scheduler_pre_processor(module_id_t module_idP, uint16_t UE_id,n,r; uint8_t CC_id, round, harq_pid; uint16_t nb_allocated_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX],total_allocated_rbs[MAX_NUM_CCs],average_rbs_per_user[MAX_NUM_CCs]; - uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES]; + uint16_t nb_rbs_allowed_slice_uplink[MAX_NUM_CCs][MAX_NUM_SLICES]; int16_t total_remaining_rbs[MAX_NUM_CCs]; uint16_t max_num_ue_to_be_scheduled=0,total_ue_count=0; rnti_t rnti= -1; @@ -281,17 +281,17 @@ void _ulsch_scheduler_pre_processor(module_id_t module_idP, max_num_ue_to_be_scheduled+=1; - nb_rbs_allowed_slice[CC_id][UE_id] = flexran_nb_rbs_allowed_slice_uplink(slice_percentage_uplink[UE_id], flexran_get_N_RB_UL(module_idP, CC_id)); + nb_rbs_allowed_slice_uplink[CC_id][UE_id] = flexran_nb_rbs_allowed_slice_uplink(slice_percentage_uplink[UE_id], flexran_get_N_RB_UL(module_idP, CC_id)); if (total_ue_count == 0) { average_rbs_per_user[CC_id] = 0; } else if (total_ue_count == 1 ) { // increase the available RBs, special case, - average_rbs_per_user[CC_id] = nb_rbs_allowed_slice[CC_id][i]-first_rb[CC_id]+1; - } else if( (total_ue_count <= (nb_rbs_allowed_slice[CC_id][i]-first_rb[CC_id])) && + average_rbs_per_user[CC_id] = nb_rbs_allowed_slice_uplink[CC_id][i]-first_rb[CC_id]+1; + } else if( (total_ue_count <= (nb_rbs_allowed_slice_uplink[CC_id][i]-first_rb[CC_id])) && (total_ue_count <= max_num_ue_to_be_scheduled)) { - average_rbs_per_user[CC_id] = (uint16_t) floor((nb_rbs_allowed_slice[CC_id][i]-first_rb[CC_id])/total_ue_count); + average_rbs_per_user[CC_id] = (uint16_t) floor((nb_rbs_allowed_slice_uplink[CC_id][i]-first_rb[CC_id])/total_ue_count); } else if (max_num_ue_to_be_scheduled > 0 ) { - average_rbs_per_user[CC_id] = (uint16_t) floor((nb_rbs_allowed_slice[CC_id][slice_id]-first_rb[CC_id])/max_num_ue_to_be_scheduled); + average_rbs_per_user[CC_id] = (uint16_t) floor((nb_rbs_allowed_slice_uplink[CC_id][i]-first_rb[CC_id])/max_num_ue_to_be_scheduled); } else { average_rbs_per_user[CC_id]=1; LOG_W(MAC,"[eNB %d] frame %d subframe %d: UE %d CC %d: can't get average rb per user (should not be here)\n", @@ -322,7 +322,7 @@ void _ulsch_scheduler_pre_processor(module_id_t module_idP, // This is the actual CC_id in the list CC_id = UE_list->ordered_ULCCids[n][UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - ue_sched_ctl->max_allowed_rbs[CC_id]=nb_rbs_allowed_slice[CC_id][UE_id]; + ue_sched_ctl->max_allowed_rbs[CC_id]=nb_rbs_allowed_slice_uplink[CC_id][UE_id]; // mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL); flexran_get_harq(module_idP, CC_id, UE_id, frameP, subframeP, &harq_pid, &round, openair_harq_UL); if(round>0) { @@ -356,7 +356,7 @@ void _ulsch_scheduler_pre_processor(module_id_t module_idP, CC_id = UE_list->ordered_ULCCids[n][UE_id]; UE_template = &UE_list->UE_template[CC_id][UE_id]; frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id); - total_remaining_rbs[CC_id]=nb_rbs_allowed_slice[CC_id][UE_id] - first_rb[CC_id] - total_allocated_rbs[CC_id]; + total_remaining_rbs[CC_id]=nb_rbs_allowed_slice_uplink[CC_id][UE_id] - first_rb[CC_id] - total_allocated_rbs[CC_id]; if (total_ue_count == 1 ) { total_remaining_rbs[CC_id]+=1; @@ -383,7 +383,7 @@ void _ulsch_scheduler_pre_processor(module_id_t module_idP, frame_parms= mac_xface->get_lte_frame_parms(module_idP,CC_id); if (total_allocated_rbs[CC_id]>0) { - LOG_D(MAC,"[eNB %d] total RB allocated for all UEs = %d/%d\n", module_idP, total_allocated_rbs[CC_id], nb_rbs_allowed_slice[CC_id][slice_id] - first_rb[CC_id]); + LOG_D(MAC,"[eNB %d] total RB allocated for all UEs = %d/%d\n", module_idP, total_allocated_rbs[CC_id], nb_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id]); } } } @@ -434,30 +434,30 @@ flexran_schedule_ue_ul_spec_default(mid_t mod_id, // check if the slice rb share has changed, and log the console if (slice_percentage_current_uplink[i] != slice_percentage_uplink[i]){ - if ((slice_percentage_uplink[i] >= 0.0) && (slice_percentage_uplink[i] <= 1.0)){ - if ((total_slice_percentage_uplink - slice_percentage_current_uplink[i] + slice_percentage_uplink[i]) <= 1.0) { - total_slice_percentage_uplink=total_slice_percentage_uplink - slice_percentage_current_uplink[i] + slice_percentage_uplink[i]; + // if ((slice_percentage_uplink[i] >= 0.0) && (slice_percentage_uplink[i] <= 1.0)){ + // if ((total_slice_percentage_uplink - slice_percentage_current_uplink[i] + slice_percentage_uplink[i]) <= 1.0) { + // total_slice_percentage_uplink=total_slice_percentage_uplink - slice_percentage_current_uplink[i] + slice_percentage_uplink[i]; LOG_N(MAC,"[eNB %d][SLICE %d] frame %d subframe %d: total percentage %f, slice RB percentage has changed: %f-->%f\n", mod_id, i, frame, subframe, total_slice_percentage_uplink, slice_percentage_current_uplink[i], slice_percentage_uplink[i]); slice_percentage_current_uplink[i] = slice_percentage_uplink[i]; - } else { - LOG_W(MAC,"[eNB %d][SLICE %d] invalid total RB share (%f->%f), revert the previous value (%f->%f)\n", - mod_id,i, - total_slice_percentage_uplink, - total_slice_percentage_uplink - slice_percentage_current_uplink[i] + slice_percentage_uplink[i], - slice_percentage_uplink[i],slice_percentage_current_uplink[i]); + // } else { + // LOG_W(MAC,"[eNB %d][SLICE %d] invalid total RB share (%f->%f), revert the previous value (%f->%f)\n", + // mod_id,i, + // total_slice_percentage_uplink, + // total_slice_percentage_uplink - slice_percentage_current_uplink[i] + slice_percentage_uplink[i], + // slice_percentage_uplink[i],slice_percentage_current_uplink[i]); - slice_percentage_uplink[i]= slice_percentage_current_uplink[i]; + // slice_percentage_uplink[i]= slice_percentage_current_uplink[i]; - } - } else { - LOG_W(MAC,"[eNB %d][SLICE %d] invalid slice RB share, revert the previous value (%f->%f)\n",mod_id, i, slice_percentage_uplink[i],slice_percentage_current_uplink[i]); + // } + // } else { + // LOG_W(MAC,"[eNB %d][SLICE %d] invalid slice RB share, revert the previous value (%f->%f)\n",mod_id, i, slice_percentage_uplink[i],slice_percentage_current_uplink[i]); - slice_percentage_uplink[i]= slice_percentage_current_uplink[i]; + // slice_percentage_uplink[i]= slice_percentage_current_uplink[i]; - } + // } } // check if a new scheduler, and log the console @@ -471,9 +471,13 @@ flexran_schedule_ue_ul_spec_default(mid_t mod_id, // Run each enabled slice-specific schedulers one by one //LOG_N(MAC,"[eNB %d]frame %d subframe %d slice %d: calling the scheduler\n", mod_id, frame, subframe,i); - slice_sched_ul[i](mod_id, frame, cooperation_flag, subframe, sched_subframe,ul_info); + + + } + + slice_sched_ul[0](mod_id, frame, cooperation_flag, subframe, sched_subframe,ul_info); } @@ -765,7 +769,7 @@ abort(); UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs; // buffer_occupancy = UE_template->ul_total_buffer; - while (((rb_table[rb_table_index]>(nb_rbs_allowed_slice[CC_id][UE_id]-1-first_rb[CC_id])) || + while (((rb_table[rb_table_index]>(nb_rbs_allowed_slice_uplink[CC_id][UE_id]-1-first_rb[CC_id])) || (rb_table[rb_table_index]>45)) && (rb_table_index>0)) { rb_table_index--; From f7e376ed5f5e05c6f3e4f678520cee1982dc5a5b Mon Sep 17 00:00:00 2001 From: Xenofon Foukas Date: Fri, 14 Jul 2017 12:52:51 +0300 Subject: [PATCH 025/195] Added support of FlexRAN agent compilation for oaisim with S1 enabled --- cmake_targets/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 8f90141618..7c9855b29a 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1846,12 +1846,12 @@ add_executable(oaisim target_include_directories(oaisim PUBLIC ${OPENAIR_TARGETS}/SIMU/USER) target_link_libraries (oaisim -Wl,-ldl,--start-group - RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB GTPV1U SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${MSC_LIB} L2 ${RAL_LIB} LIB_NAS_UE SIMU SIMU_ETH SECU_OSA ${ITTI_LIB} ${MIH_LIB} + RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB GTPV1U SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${MSC_LIB} L2 ${RAL_LIB} LIB_NAS_UE SIMU SIMU_ETH SECU_OSA ${ITTI_LIB} ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 -Wl,--end-group ) target_link_libraries (oaisim ${LIBXML2_LIBRARIES} ${LAPACK_LIBRARIES}) target_link_libraries (oaisim pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp - ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${OPENPGM_LIBRARIES}) + ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${OPENPGM_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) #Force link with forms, regardless XFORMS option target_link_libraries (oaisim forms) target_link_libraries (oaisim ${T_LIB}) From e51d8d3fd73d35fff38fd5306c011d2a68b4f001 Mon Sep 17 00:00:00 2001 From: Anta Huang Date: Thu, 20 Jul 2017 13:24:16 +0200 Subject: [PATCH 026/195] Add the slice_maxmcs_uplink to flexran agent ulsch --- openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c index b0e7272e9d..86bb2407b6 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c @@ -66,6 +66,10 @@ float slice_percentage_uplink[MAX_NUM_SLICES] = {0.5, 0.5, 0.0, 0.0}; float slice_percentage_current_uplink[MAX_NUM_SLICES] = {0.5, 0.5, 0.0, 0.0}; float total_slice_percentage_uplink = 0; +// MAX MCS for each slice for past and current time +int slice_maxmcs_uplink[MAX_NUM_SLICES] = {16, 16, 16, 16}; +int slice_maxmcs_current_uplink[MAX_NUM_SLICES] = {28, 28, 28, 28}; + /*resource blocks allowed*/ uint16_t nb_rbs_allowed_slice_uplink[MAX_NUM_CCs][MAX_NUM_SLICES]; /*Slice Update */ From 9e7e57de74fd06ac02023a4097435cd9c1be05a8 Mon Sep 17 00:00:00 2001 From: shahab SHARIATBAGHERI Date: Tue, 25 Jul 2017 19:12:42 +0200 Subject: [PATCH 027/195] DL Fixed Bug get TBS --- .../MAC/flexran_agent_scheduler_dlsch_ue.c | 550 +++++++++--------- 1 file changed, 280 insertions(+), 270 deletions(-) diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c index ade4b77c14..e47adc4fdb 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c @@ -284,7 +284,7 @@ void _assign_rbs_required (module_id_t Mod_id, nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id]; if (nb_rbs_required[CC_id][UE_id] > nb_rbs_allowed_slice[CC_id][slice_id]) { - TBS = mac_xface->get_TBS_DL(flexran_get_ue_wcqi(Mod_id, UE_id), nb_rbs_allowed_slice[CC_id][slice_id]); + TBS = mac_xface->get_TBS_DL(cqi_to_mcs[flexran_get_ue_wcqi(Mod_id, UE_id)], nb_rbs_allowed_slice[CC_id][slice_id]); nb_rbs_required[CC_id][UE_id] = nb_rbs_allowed_slice[CC_id][slice_id]; break; } @@ -495,7 +495,7 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id, } } - // Store the DLSCH buffer for each logical channel + /* Store the DLSCH buffer for each logical channel for each UE */ _store_dlsch_buffer (Mod_id,slice_id,frameP,subframeP); // Calculate the number of RBs required by each UE on the basis of logical channel's buffer @@ -1044,9 +1044,10 @@ flexran_schedule_ue_dl_spec_common(mid_t mod_id, ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; if (eNB_UE_stats==NULL) { - LOG_D(MAC,"[eNB] Cannot find eNB_UE_stats\n"); - // mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n"); - continue; + + LOG_D(MAC,"[eNB] Cannot find eNB_UE_stats\n"); + // mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n"); + continue; } if (flexran_slice_member(UE_id, slice_id) == 0) @@ -1062,28 +1063,29 @@ flexran_schedule_ue_dl_spec_common(mid_t mod_id, case 1: case 2: case 7: - aggregation = get_aggregation(get_bw_index(mod_id,CC_id), + aggregation = get_aggregation(get_bw_index(mod_id,CC_id), eNB_UE_stats->DL_cqi[0], format1); - break; + break; case 3: - aggregation = get_aggregation(get_bw_index(mod_id,CC_id), + aggregation = get_aggregation(get_bw_index(mod_id,CC_id), eNB_UE_stats->DL_cqi[0], format2A); - break; + break; default: - LOG_W(MAC,"Unsupported transmission mode %d\n", mac_xface->get_transmission_mode(mod_id,CC_id,rnti)); - aggregation = 2; + LOG_W(MAC,"Unsupported transmission mode %d\n", mac_xface->get_transmission_mode(mod_id,CC_id,rnti)); + aggregation = 2; } if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated CCE_allocation_infeasible(mod_id, CC_id, 0, subframe, aggregation, rnti)) { - LOG_D(MAC,"[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n", - mod_id, frame, UE_id, CC_id); - //if(mac_xface->get_transmission_mode(module_idP,rnti)==5) - continue; //to next user (there might be rbs availiable for other UEs in TM5 - // else - // break; + + LOG_D(MAC,"[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n", + mod_id, frame, UE_id, CC_id); + //if(mac_xface->get_transmission_mode(module_idP,rnti)==5) + continue; //to next user (there might be rbs availiable for other UEs in TM5 + // else + // break; } if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { @@ -1106,26 +1108,28 @@ flexran_schedule_ue_dl_spec_common(mid_t mod_id, dl_data[num_ues_added]->n_rlc_pdu = 0; dl_data[num_ues_added]->has_serv_cell_index = 1; dl_data[num_ues_added]->serv_cell_index = CC_id; - - nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id]; + flexran_get_harq(mod_id, CC_id, UE_id, frame, subframe, &harq_pid, &round, openair_harq_DL); sdu_length_total=0; mcs = cqi_to_mcs[flexran_get_ue_wcqi(mod_id, UE_id)]; // LOG_I(FLEXRAN_AGENT, "The MCS is %d\n", mcs); mcs = cmin(mcs,flexran_slice_maxmcs(slice_id)); -#ifdef EXMIMO +// #ifdef EXMIMO - if (mac_xface->get_transmission_mode(mod_id, CC_id, rnti) == 5) { - mcs = cqi_to_mcs[flexran_get_ue_wcqi(mod_id, UE_id)]; - mcs = cmin(mcs,16); - } +// if (mac_xface->get_transmission_mode(mod_id, CC_id, rnti) == 5) { +// mcs = cqi_to_mcs[flexran_get_ue_wcqi(mod_id, UE_id)]; +// mcs = cmin(mcs,16); +// } -#endif +// #endif + /*Get pre available resource blocks based on buffers*/ + nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id]; // initializing the rb allocation indicator for each UE for(j = 0; j < flexran_get_N_RBG(mod_id, CC_id); j++) { - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = 0; - rballoc_sub[j] = 0; + + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = 0; + rballoc_sub[j] = 0; } /* LOG_D(MAC,"[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n", */ @@ -1146,72 +1150,74 @@ flexran_schedule_ue_dl_spec_common(mid_t mod_id, /* process retransmission */ if (round > 0) { - LOG_D(FLEXRAN_AGENT, "There was a retransmission just now and the round was %d\n", round); + LOG_D(FLEXRAN_AGENT, "There was a retransmission just now and the round was %d\n", round); - if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { - UE_list->UE_template[CC_id][UE_id].DAI++; - update_ul_dci(mod_id, CC_id, rnti, UE_list->UE_template[CC_id][UE_id].DAI); - LOG_D(MAC,"DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n", - CC_id, subframe,UE_id,UE_list->UE_template[CC_id][UE_id].DAI); - } + if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { + UE_list->UE_template[CC_id][UE_id].DAI++; + update_ul_dci(mod_id, CC_id, rnti, UE_list->UE_template[CC_id][UE_id].DAI); + LOG_D(MAC,"DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n", + CC_id, subframe,UE_id,UE_list->UE_template[CC_id][UE_id].DAI); + } - mcs = UE_list->UE_template[CC_id][UE_id].mcs[harq_pid]; + mcs = UE_list->UE_template[CC_id][UE_id].mcs[harq_pid]; - // get freq_allocation - nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - - /*TODO: Must add this to FlexRAN agent API */ - dci_tbs = mac_xface->get_TBS_DL(mcs, nb_rb); + // get freq_allocation + nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + + /*TODO: Must add this to FlexRAN agent API */ + dci_tbs = mac_xface->get_TBS_DL(mcs, nb_rb); - if (nb_rb <= nb_available_rb) { - - if(nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { - for(j = 0; j < flexran_get_N_RBG(mod_id, CC_id); j++) { // for indicating the rballoc for each sub-band - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - } - } else { - nb_rb_temp = nb_rb; - j = 0; + if (nb_rb <= nb_available_rb) { + + if(nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { + for(j = 0; j < flexran_get_N_RBG(mod_id, CC_id); j++) { // for indicating the rballoc for each sub-band + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + } + } else { + nb_rb_temp = nb_rb; + j = 0; - while((nb_rb_temp > 0) && (j < flexran_get_N_RBG(mod_id, CC_id))) { - if(ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - - if((j == flexran_get_N_RBG(mod_id, CC_id) - 1) && - ((flexran_get_N_RB_DL(mod_id, CC_id) == 25)|| - (flexran_get_N_RB_DL(mod_id, CC_id) == 50))) { - nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]+1; - } else { - nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; - } - } - j = j + 1; - } - } + while((nb_rb_temp > 0) && (j < flexran_get_N_RBG(mod_id, CC_id))) { + if(ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + + if((j == flexran_get_N_RBG(mod_id, CC_id) - 1) && + ((flexran_get_N_RB_DL(mod_id, CC_id) == 25)|| + (flexran_get_N_RB_DL(mod_id, CC_id) == 50))) { + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]+1; + } else { + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; + } + } + j = j + 1; + } + } - nb_available_rb -= nb_rb; - PHY_vars_eNB_g[mod_id][CC_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; - PHY_vars_eNB_g[mod_id][CC_id]->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; - - for(j=0; j < flexran_get_N_RBG(mod_id, CC_id); j++) { - PHY_vars_eNB_g[mod_id][CC_id]->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; - rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; - } + nb_available_rb -= nb_rb; + PHY_vars_eNB_g[mod_id][CC_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; + PHY_vars_eNB_g[mod_id][CC_id]->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; + + for(j=0; j < flexran_get_N_RBG(mod_id, CC_id); j++) { + PHY_vars_eNB_g[mod_id][CC_id]->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; + rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; + } - // Keep the old NDI, do not toggle - ndi = UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; - tpc = UE_list->UE_template[CC_id][UE_id].oldTPC[harq_pid]; - UE_list->UE_template[CC_id][UE_id].mcs[harq_pid] = mcs; + // Keep the old NDI, do not toggle + ndi = UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + tpc = UE_list->UE_template[CC_id][UE_id].oldTPC[harq_pid]; + UE_list->UE_template[CC_id][UE_id].mcs[harq_pid] = mcs; - ue_has_transmission = 1; - num_ues_added++; - } else { - LOG_D(MAC,"[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n", - mod_id, frame, CC_id, UE_id); - ue_has_transmission = 0; - } - //End of retransmission - } else { /* This is a potentially new SDU opportunity */ + ue_has_transmission = 1; + num_ues_added++; + } else { + LOG_D(MAC,"[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n", + mod_id, frame, CC_id, UE_id); + ue_has_transmission = 0; + } + //End of retransmission + } + + else { /* This is a potentially new SDU opportunity */ rlc_status.bytes_in_buffer = 0; // Now check RLC information to compute number of required RBs // get maximum TBS size for RLC request @@ -1265,11 +1271,14 @@ flexran_schedule_ue_dl_spec_common(mid_t mod_id, //Fill in as much as possible data_to_request = cmin(dci_tbs - ta_len - header_len - sdu_length_total, rlc_status.bytes_in_buffer); LOG_D(FLEXRAN_AGENT, "Will request %d bytes from channel %d\n", data_to_request, j); + if (data_to_request < 128) { //The header will be one byte less - header_len--; - header_len_last = 2; - } else { - header_len_last = 3; + header_len--; + header_len_last = 2; + } + else { + + header_len_last = 3; } /* if (j == 1 || j == 2) { data_to_request+=0; @@ -1364,7 +1373,8 @@ flexran_schedule_ue_dl_spec_common(mid_t mod_id, for(j = 0; j < flexran_get_N_RBG(mod_id, CC_id); j++) { // for indicating the rballoc for each sub-band UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; } - } else { + } + else { nb_rb_temp = nb_rb; j = 0; LOG_D(MAC, "[TEST]Will only partially fill the bitmap\n"); @@ -1412,12 +1422,12 @@ flexran_schedule_ue_dl_spec_common(mid_t mod_id, UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb; - if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { - UE_list->UE_template[CC_id][UE_id].DAI++; - // printf("DAI update: subframeP %d: UE %d, DAI %d\n",subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].DAI); + // if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { + // UE_list->UE_template[CC_id][UE_id].DAI++; + // // printf("DAI update: subframeP %d: UE %d, DAI %d\n",subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].DAI); //#warning only for 5MHz channel - update_ul_dci(mod_id, CC_id, rnti, UE_list->UE_template[CC_id][UE_id].DAI); - } + // update_ul_dci(mod_id, CC_id, rnti, UE_list->UE_template[CC_id][UE_id].DAI); + // } // do PUCCH power control // this is the normalized RX power @@ -1475,189 +1485,189 @@ flexran_schedule_ue_dl_spec_common(mid_t mod_id, ue_has_transmission = 0; } } // End of new scheduling - + // If we has transmission or retransmission if (ue_has_transmission) { - switch (mac_xface->get_transmission_mode(mod_id, CC_id, rnti)) { - case 1: - case 2: - default: - dl_dci->has_res_alloc = 1; - dl_dci->res_alloc = 0; - dl_dci->has_vrb_format = 1; - dl_dci->vrb_format = PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; - dl_dci->has_format = 1; - dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1; - dl_dci->has_rb_bitmap = 1; - dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, rballoc_sub); - dl_dci->has_rb_shift = 1; - dl_dci->rb_shift = 0; - dl_dci->n_ndi = 1; - dl_dci->ndi = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); - dl_dci->ndi[0] = ndi; - dl_dci->n_rv = 1; - dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); - dl_dci->rv[0] = round & 3; - dl_dci->has_tpc = 1; - dl_dci->tpc = tpc; - dl_dci->n_mcs = 1; - dl_dci->mcs = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_mcs); - dl_dci->mcs[0] = mcs; - dl_dci->n_tbs_size = 1; - dl_dci->tbs_size = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_tbs_size); - dl_dci->tbs_size[0] = dci_tbs; - if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { - dl_dci->has_dai = 1; - dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; - } - break; - case 3: - dl_dci->has_res_alloc = 1; - dl_dci->res_alloc = 0; - dl_dci->has_vrb_format = 1; - dl_dci->vrb_format = PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; - dl_dci->has_format = 1; - dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A; - dl_dci->has_rb_bitmap = 1; - dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, rballoc_sub); - dl_dci->has_rb_shift = 1; - dl_dci->rb_shift = 0; - dl_dci->n_ndi = 2; - dl_dci->ndi = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); - dl_dci->ndi[0] = ndi; - dl_dci->ndi[1] = ndi; - dl_dci->n_rv = 2; - dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); - dl_dci->rv[0] = round & 3; - dl_dci->rv[1] = round & 3; - dl_dci->has_tpc = 1; - dl_dci->tpc = tpc; - dl_dci->n_mcs = 2; - dl_dci->mcs = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_mcs); - dl_dci->mcs[0] = mcs; - dl_dci->mcs[1] = mcs; - dl_dci->n_tbs_size = 2; - dl_dci->tbs_size = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_tbs_size); - dl_dci->tbs_size[0] = dci_tbs; - dl_dci->tbs_size[1] = dci_tbs; - if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { - dl_dci->has_dai = 1; - dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; - } - break; - case 4: - dl_dci->has_res_alloc = 1; - dl_dci->res_alloc = 0; - dl_dci->has_vrb_format = 1; - dl_dci->vrb_format = PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; - dl_dci->has_format = 1; - dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A; - dl_dci->has_rb_bitmap = 1; - dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, rballoc_sub); - dl_dci->has_rb_shift = 1; - dl_dci->rb_shift = 0; - dl_dci->n_ndi = 2; - dl_dci->ndi = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); - dl_dci->ndi[0] = ndi; - dl_dci->ndi[1] = ndi; - dl_dci->n_rv = 2; - dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); - dl_dci->rv[0] = round & 3; - dl_dci->rv[1] = round & 3; - dl_dci->has_tpc = 1; - dl_dci->tpc = tpc; - dl_dci->n_mcs = 2; - dl_dci->mcs = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_mcs); - dl_dci->mcs[0] = mcs; - dl_dci->mcs[1] = mcs; - dl_dci->n_tbs_size = 2; - dl_dci->tbs_size = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_tbs_size); - dl_dci->tbs_size[0] = dci_tbs; - dl_dci->tbs_size[1] = dci_tbs; - if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { - dl_dci->has_dai = 1; - dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; - } - break; - case 5: - dl_dci->has_res_alloc = 1; - dl_dci->res_alloc = 0; - dl_dci->has_vrb_format = 1; - dl_dci->vrb_format = PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; - dl_dci->has_format = 1; - dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D; - dl_dci->has_rb_bitmap = 1; - dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, rballoc_sub); - dl_dci->has_rb_shift = 1; - dl_dci->rb_shift = 0; - dl_dci->n_ndi = 1; - dl_dci->ndi[0] = ndi; - dl_dci->n_rv = 1; - dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); - dl_dci->rv[0] = round & 3; - dl_dci->has_tpc = 1; - dl_dci->tpc = tpc; - dl_dci->n_mcs = 1; - dl_dci->mcs = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_mcs); - dl_dci->mcs[0] = mcs; - dl_dci->n_tbs_size = 1; - dl_dci->tbs_size = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_tbs_size); - dl_dci->tbs_size[0] = dci_tbs; - if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { - dl_dci->has_dai = 1; - dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; - } - - if(ue_sched_ctl->dl_pow_off[CC_id] == 2) { - ue_sched_ctl->dl_pow_off[CC_id] = 1; - } - - dl_dci->has_dl_power_offset = 1; - dl_dci->dl_power_offset = ue_sched_ctl->dl_pow_off[CC_id]; - dl_dci->has_precoding_info = 1; - dl_dci->precoding_info = 5; // Is this right?? - - break; - case 6: - dl_dci->has_res_alloc = 1; - dl_dci->res_alloc = 0; - dl_dci->has_vrb_format = 1; - dl_dci->vrb_format = PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; - dl_dci->has_format = 1; - dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D; - dl_dci->has_rb_bitmap = 1; - dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, rballoc_sub); - dl_dci->has_rb_shift = 1; - dl_dci->rb_shift = 0; - dl_dci->n_ndi = 1; - dl_dci->ndi = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); - dl_dci->ndi[0] = ndi; - dl_dci->n_rv = 1; - dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); - dl_dci->rv[0] = round & 3; - dl_dci->has_tpc = 1; - dl_dci->tpc = tpc; - dl_dci->n_mcs = 1; - dl_dci->mcs = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_mcs); - dl_dci->mcs[0] = mcs; - if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { - dl_dci->has_dai = 1; - dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; - } + switch (mac_xface->get_transmission_mode(mod_id, CC_id, rnti)) { + case 1: + case 2: + default: + dl_dci->has_res_alloc = 1; + dl_dci->res_alloc = 0; + dl_dci->has_vrb_format = 1; + dl_dci->vrb_format = PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; + dl_dci->has_format = 1; + dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1; + dl_dci->has_rb_bitmap = 1; + dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, rballoc_sub); + dl_dci->has_rb_shift = 1; + dl_dci->rb_shift = 0; + dl_dci->n_ndi = 1; + dl_dci->ndi = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); + dl_dci->ndi[0] = ndi; + dl_dci->n_rv = 1; + dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); + dl_dci->rv[0] = round & 3; + dl_dci->has_tpc = 1; + dl_dci->tpc = tpc; + dl_dci->n_mcs = 1; + dl_dci->mcs = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_mcs); + dl_dci->mcs[0] = mcs; + dl_dci->n_tbs_size = 1; + dl_dci->tbs_size = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_tbs_size); + dl_dci->tbs_size[0] = dci_tbs; + if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { + dl_dci->has_dai = 1; + dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + } + break; + case 3: + dl_dci->has_res_alloc = 1; + dl_dci->res_alloc = 0; + dl_dci->has_vrb_format = 1; + dl_dci->vrb_format = PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; + dl_dci->has_format = 1; + dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A; + dl_dci->has_rb_bitmap = 1; + dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, rballoc_sub); + dl_dci->has_rb_shift = 1; + dl_dci->rb_shift = 0; + dl_dci->n_ndi = 2; + dl_dci->ndi = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); + dl_dci->ndi[0] = ndi; + dl_dci->ndi[1] = ndi; + dl_dci->n_rv = 2; + dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); + dl_dci->rv[0] = round & 3; + dl_dci->rv[1] = round & 3; + dl_dci->has_tpc = 1; + dl_dci->tpc = tpc; + dl_dci->n_mcs = 2; + dl_dci->mcs = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_mcs); + dl_dci->mcs[0] = mcs; + dl_dci->mcs[1] = mcs; + dl_dci->n_tbs_size = 2; + dl_dci->tbs_size = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_tbs_size); + dl_dci->tbs_size[0] = dci_tbs; + dl_dci->tbs_size[1] = dci_tbs; + if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { + dl_dci->has_dai = 1; + dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + } + break; + case 4: + dl_dci->has_res_alloc = 1; + dl_dci->res_alloc = 0; + dl_dci->has_vrb_format = 1; + dl_dci->vrb_format = PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; + dl_dci->has_format = 1; + dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A; + dl_dci->has_rb_bitmap = 1; + dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, rballoc_sub); + dl_dci->has_rb_shift = 1; + dl_dci->rb_shift = 0; + dl_dci->n_ndi = 2; + dl_dci->ndi = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); + dl_dci->ndi[0] = ndi; + dl_dci->ndi[1] = ndi; + dl_dci->n_rv = 2; + dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); + dl_dci->rv[0] = round & 3; + dl_dci->rv[1] = round & 3; + dl_dci->has_tpc = 1; + dl_dci->tpc = tpc; + dl_dci->n_mcs = 2; + dl_dci->mcs = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_mcs); + dl_dci->mcs[0] = mcs; + dl_dci->mcs[1] = mcs; + dl_dci->n_tbs_size = 2; + dl_dci->tbs_size = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_tbs_size); + dl_dci->tbs_size[0] = dci_tbs; + dl_dci->tbs_size[1] = dci_tbs; + if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { + dl_dci->has_dai = 1; + dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + } + break; + case 5: + dl_dci->has_res_alloc = 1; + dl_dci->res_alloc = 0; + dl_dci->has_vrb_format = 1; + dl_dci->vrb_format = PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; + dl_dci->has_format = 1; + dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D; + dl_dci->has_rb_bitmap = 1; + dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, rballoc_sub); + dl_dci->has_rb_shift = 1; + dl_dci->rb_shift = 0; + dl_dci->n_ndi = 1; + dl_dci->ndi[0] = ndi; + dl_dci->n_rv = 1; + dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); + dl_dci->rv[0] = round & 3; + dl_dci->has_tpc = 1; + dl_dci->tpc = tpc; + dl_dci->n_mcs = 1; + dl_dci->mcs = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_mcs); + dl_dci->mcs[0] = mcs; + dl_dci->n_tbs_size = 1; + dl_dci->tbs_size = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_tbs_size); + dl_dci->tbs_size[0] = dci_tbs; + if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { + dl_dci->has_dai = 1; + dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + } + + if(ue_sched_ctl->dl_pow_off[CC_id] == 2) { + ue_sched_ctl->dl_pow_off[CC_id] = 1; + } + + dl_dci->has_dl_power_offset = 1; + dl_dci->dl_power_offset = ue_sched_ctl->dl_pow_off[CC_id]; + dl_dci->has_precoding_info = 1; + dl_dci->precoding_info = 5; // Is this right?? + + break; + case 6: + dl_dci->has_res_alloc = 1; + dl_dci->res_alloc = 0; + dl_dci->has_vrb_format = 1; + dl_dci->vrb_format = PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; + dl_dci->has_format = 1; + dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D; + dl_dci->has_rb_bitmap = 1; + dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, rballoc_sub); + dl_dci->has_rb_shift = 1; + dl_dci->rb_shift = 0; + dl_dci->n_ndi = 1; + dl_dci->ndi = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); + dl_dci->ndi[0] = ndi; + dl_dci->n_rv = 1; + dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); + dl_dci->rv[0] = round & 3; + dl_dci->has_tpc = 1; + dl_dci->tpc = tpc; + dl_dci->n_mcs = 1; + dl_dci->mcs = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_mcs); + dl_dci->mcs[0] = mcs; + if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { + dl_dci->has_dai = 1; + dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + } - dl_dci->has_dl_power_offset = 1; - dl_dci->dl_power_offset = ue_sched_ctl->dl_pow_off[CC_id]; - dl_dci->has_precoding_info = 1; - dl_dci->precoding_info = 5; // Is this right?? - break; - } + dl_dci->has_dl_power_offset = 1; + dl_dci->dl_power_offset = ue_sched_ctl->dl_pow_off[CC_id]; + dl_dci->has_precoding_info = 1; + dl_dci->precoding_info = 5; // Is this right?? + break; + } } - if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { + // if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { /* TODO */ //set_ul_DAI(mod_id, UE_id, CC_id, frame, subframe, frame_parms); - } + // } } // UE_id loop } // CC_id loop From 8e5b17404787e09decc13d2d649993610a394c7f Mon Sep 17 00:00:00 2001 From: shahab SHARIATBAGHERI Date: Fri, 4 Aug 2017 16:02:17 +0200 Subject: [PATCH 028/195] merge to 68 --- .../LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c | 8 ++++---- .../LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c index e47adc4fdb..02fe873144 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c @@ -88,16 +88,16 @@ typedef enum { // number of active slices for past and current time -int n_active_slices = 2; -int n_active_slices_current = 2; +int n_active_slices = 1; +int n_active_slices_current = 1; // ue to slice mapping int slicing_strategy = UEID_TO_SLICEID; int slicing_strategy_current = UEID_TO_SLICEID; // RB share for each slice for past and current time -float slice_percentage[MAX_NUM_SLICES] = {0.5, 0.5, 0.0, 0.0}; -float slice_percentage_current[MAX_NUM_SLICES] = {0.5, 0.5, 0.0, 0.0}; +float slice_percentage[MAX_NUM_SLICES] = {1.0, 1.0, 0.0, 0.0}; +float slice_percentage_current[MAX_NUM_SLICES] = {1.0, 1.0, 0.0, 0.0}; float total_slice_percentage = 0; // MAX MCS for each slice for past and current time diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c index 86bb2407b6..4038ae518b 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c @@ -58,12 +58,12 @@ #include "T.h" /* number of active slices for past and current time*/ -int n_active_slices_uplink = 2; -int n_active_slices_uplink_current = 2; +int n_active_slices_uplink = 1; +int n_active_slices_uplink_current = 1; /* RB share for each slice for past and current time*/ -float slice_percentage_uplink[MAX_NUM_SLICES] = {0.5, 0.5, 0.0, 0.0}; -float slice_percentage_current_uplink[MAX_NUM_SLICES] = {0.5, 0.5, 0.0, 0.0}; +float slice_percentage_uplink[MAX_NUM_SLICES] = {1.0, 1.0, 0.0, 0.0}; +float slice_percentage_current_uplink[MAX_NUM_SLICES] = {1.0, 1.0, 0.0, 0.0}; float total_slice_percentage_uplink = 0; // MAX MCS for each slice for past and current time @@ -477,11 +477,11 @@ flexran_schedule_ue_ul_spec_default(mid_t mod_id, //LOG_N(MAC,"[eNB %d]frame %d subframe %d slice %d: calling the scheduler\n", mod_id, frame, subframe,i); - + slice_sched_ul[i](mod_id, frame, cooperation_flag, subframe, sched_subframe,ul_info); } - slice_sched_ul[0](mod_id, frame, cooperation_flag, subframe, sched_subframe,ul_info); + } From d12f55d2ed2c3b55d5dd140c130708fd5854a482 Mon Sep 17 00:00:00 2001 From: shahab SHARIATBAGHERI Date: Fri, 4 Aug 2017 16:22:57 +0200 Subject: [PATCH 029/195] add operating downlink frequency --- openair2/ENB_APP/MESSAGES/V2/config_messages.proto | 1 + openair2/ENB_APP/flexran_agent_common.c | 4 ++++ openair2/ENB_APP/flexran_agent_ran_api.c | 8 ++++++++ openair2/ENB_APP/flexran_agent_ran_api.h | 5 ++++- 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto index 441e193569..c21fee213b 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto @@ -38,6 +38,7 @@ message flex_cell_config { optional uint32 srs_mac_up_pts = 32; // Boolean value. See TS 36.211, section 5.5.3.2. TDD only optional uint32 enable_64QAM = 33; // One of the FLEQ_* enum values optional uint32 carrier_index = 34; // Carrier component index + optional uint32 op_dl_freq = 35; // operating downlink frequency } message flex_ue_config { diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index fe70a62ec8..4067145dfd 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -1013,6 +1013,10 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F cell_conf[i]->srs_mac_up_pts = flexran_get_srs_MaxUpPts(enb_id,i); cell_conf[i]->has_srs_mac_up_pts = 1; + + cell_conf[i]->op_dl_freq = flexran_agent_get_operating_dl_freq (0); + cell_conf[i]->has_op_dl_freq = 1; + if (flexran_get_enable64QAM(enb_id,i) == 0) { cell_conf[i]->enable_64qam = PROTOCOL__FLEX_QAM__FLEQ_MOD_16QAM; } else if(flexran_get_enable64QAM(enb_id,i) == 1) { diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index ae304d1e26..685a3bf57e 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -956,3 +956,11 @@ int flexran_get_antenna_ports(mid_t mod_id, int CC_id){ return frame_parms->nb_antenna_ports_eNB; } + + +float flexran_agent_get_operating_dl_freq (mid_t cc_id) { + const Enb_properties_array_t* enb_properties = enb_config_get(); + return (enb_properties->properties[0]->downlink_frequency[cc_id] / 1000000); +} + + diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index e80ed44ce9..ed2a2a1fd5 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -298,4 +298,7 @@ int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id); int flexran_get_lcg(mid_t ue_id, mid_t lc_id); /* Get direction of logical channel with id lc_id */ -int flexran_get_direction(mid_t ue_id, mid_t lc_id); \ No newline at end of file +int flexran_get_direction(mid_t ue_id, mid_t lc_id); + +/*Gety downlink frequency*/ +float flexran_agent_get_operating_dl_freq (mid_t cc_id); \ No newline at end of file From 3cc3762ed9d63b6e5bec5c0ea3c29d1c852992be Mon Sep 17 00:00:00 2001 From: shahab SHARIATBAGHERI Date: Fri, 4 Aug 2017 16:27:15 +0200 Subject: [PATCH 030/195] carrier index --- openair2/ENB_APP/flexran_agent_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index 4067145dfd..df350e5d69 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -1014,7 +1014,7 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F cell_conf[i]->has_srs_mac_up_pts = 1; - cell_conf[i]->op_dl_freq = flexran_agent_get_operating_dl_freq (0); + cell_conf[i]->op_dl_freq = flexran_agent_get_operating_dl_freq (i); cell_conf[i]->has_op_dl_freq = 1; if (flexran_get_enable64QAM(enb_id,i) == 0) { From 863e9404fcbe4610e53f6539ca444cf90320c51f Mon Sep 17 00:00:00 2001 From: Anta Huang Date: Fri, 4 Aug 2017 17:42:32 +0200 Subject: [PATCH 031/195] Add additional cell config info to flexran API and message --- .../ENB_APP/MESSAGES/V2/config_messages.proto | 4 ++++ openair2/ENB_APP/flexran_agent_common.c | 16 +++++++++++-- openair2/ENB_APP/flexran_agent_ran_api.c | 23 +++++++++++++++++-- openair2/ENB_APP/flexran_agent_ran_api.h | 16 +++++++++++-- 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto index c21fee213b..f19de4923f 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto @@ -39,6 +39,10 @@ message flex_cell_config { optional uint32 enable_64QAM = 33; // One of the FLEQ_* enum values optional uint32 carrier_index = 34; // Carrier component index optional uint32 op_dl_freq = 35; // operating downlink frequency + optional uint32 op_ul_freq = 36; // operating uplink frequency + optional uint32 op_eutra_band= 37; // operating band + optional int32 op_dl_pdsch_power = 38; // operating downlink power + optional int32 op_ul_pusch_power = 39; // operating uplink power } message flex_ue_config { diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index df350e5d69..d71e9496c8 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -1013,10 +1013,22 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F cell_conf[i]->srs_mac_up_pts = flexran_get_srs_MaxUpPts(enb_id,i); cell_conf[i]->has_srs_mac_up_pts = 1; - - cell_conf[i]->op_dl_freq = flexran_agent_get_operating_dl_freq (i); + cell_conf[i]->op_dl_freq = flexran_agent_get_operating_dl_freq (enb_id,i); cell_conf[i]->has_op_dl_freq = 1; + cell_conf[i]->op_ul_freq = flexran_agent_get_operating_ul_freq (enb_id, i); + cell_conf[i]->has_op_ul_freq = 1; + + cell_conf[i]->op_eutra_band = flexran_agent_get_operating_eutra_band (enb_id,i); + cell_conf[i]->has_op_eutra_band = 1; + + cell_conf[i]->op_dl_pdsch_power = flexran_agent_get_operating_pdsch_refpower(enb_id, i); + cell_conf[i]->has_op_dl_pdsch_power = 1; + + cell_conf[i]->op_ul_pusch_power = flexran_agent_get_operating_pusch_p0 (enb_id,i); + cell_conf[i]->has_op_ul_pusch_power = 1; + + if (flexran_get_enable64QAM(enb_id,i) == 0) { cell_conf[i]->enable_64qam = PROTOCOL__FLEX_QAM__FLEQ_MOD_16QAM; } else if(flexran_get_enable64QAM(enb_id,i) == 1) { diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 685a3bf57e..10b667e916 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -958,9 +958,28 @@ int flexran_get_antenna_ports(mid_t mod_id, int CC_id){ } -float flexran_agent_get_operating_dl_freq (mid_t cc_id) { +float flexran_agent_get_operating_dl_freq (mid_t mod_id, int cc_id) { const Enb_properties_array_t* enb_properties = enb_config_get(); - return (enb_properties->properties[0]->downlink_frequency[cc_id] / 1000000); + return (enb_properties->properties[mod_id]->downlink_frequency[cc_id] / 1000000); +} + +float flexran_agent_get_operating_ul_freq (mid_t mod_id, int cc_id) { + const Enb_properties_array_t* enb_properties = enb_config_get(); + return ((enb_properties->properties[mod_id] ->downlink_frequency[cc_id] + enb_properties->properties[0]->uplink_frequency_offset[cc_id]) / 1000000); +} + +int flexran_agent_get_operating_eutra_band (mid_t mod_id, int cc_id) { + const Enb_properties_array_t* enb_properties = enb_config_get(); + return enb_properties->properties[mod_id]->eutra_band[cc_id]; +} +int flexran_agent_get_operating_pdsch_refpower (mid_t mod_id, int cc_id) { + const Enb_properties_array_t* enb_properties = enb_config_get(); + return enb_properties->properties[mod_id]->pdsch_referenceSignalPower[cc_id]; +} +int flexran_agent_get_operating_pusch_p0 (mid_t mod_id, int cc_id) { + const Enb_properties_array_t* enb_properties = enb_config_get(); + return enb_properties->properties[mod_id]->pusch_p0_Nominal[cc_id]; } + diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index ed2a2a1fd5..668c0e6ba0 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -300,5 +300,17 @@ int flexran_get_lcg(mid_t ue_id, mid_t lc_id); /* Get direction of logical channel with id lc_id */ int flexran_get_direction(mid_t ue_id, mid_t lc_id); -/*Gety downlink frequency*/ -float flexran_agent_get_operating_dl_freq (mid_t cc_id); \ No newline at end of file +/*Get downlink frequency*/ +float flexran_agent_get_operating_dl_freq (mid_t mod_id, int cc_id); + +/*Get uplink frequency*/ +float flexran_agent_get_operating_ul_freq (mid_t mod_id, int cc_id); + +/*Get eutra band*/ +int flexran_agent_get_operating_eutra_band (mid_t mod_id, int cc_id); + +/*Get downlink ref signal power*/ +int flexran_agent_get_operating_pdsch_refpower (mid_t mod_id, int cc_id); + +/*Get uplink power*/ +int flexran_agent_get_operating_pusch_p0 (mid_t mod_id, int cc_id); From 1e857d5ba5a22789a9e302487905dc908ffe5a71 Mon Sep 17 00:00:00 2001 From: Anta Huang Date: Fri, 4 Aug 2017 18:19:38 +0200 Subject: [PATCH 032/195] Update the naming of cell config parameters --- .../ENB_APP/MESSAGES/V2/config_messages.proto | 10 +++++----- openair2/ENB_APP/flexran_agent_common.c | 20 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto index f19de4923f..1be6f7f43a 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto @@ -38,11 +38,11 @@ message flex_cell_config { optional uint32 srs_mac_up_pts = 32; // Boolean value. See TS 36.211, section 5.5.3.2. TDD only optional uint32 enable_64QAM = 33; // One of the FLEQ_* enum values optional uint32 carrier_index = 34; // Carrier component index - optional uint32 op_dl_freq = 35; // operating downlink frequency - optional uint32 op_ul_freq = 36; // operating uplink frequency - optional uint32 op_eutra_band= 37; // operating band - optional int32 op_dl_pdsch_power = 38; // operating downlink power - optional int32 op_ul_pusch_power = 39; // operating uplink power + optional uint32 dl_freq = 35; // operating downlink frequency + optional uint32 ul_freq = 36; // operating uplink frequency + optional uint32 eutra_band= 37; // operating band + optional int32 dl_pdsch_power = 38; // operating downlink power + optional int32 ul_pusch_power = 39; // operating uplink power } message flex_ue_config { diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index d71e9496c8..e3f96c05dc 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -1013,20 +1013,20 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F cell_conf[i]->srs_mac_up_pts = flexran_get_srs_MaxUpPts(enb_id,i); cell_conf[i]->has_srs_mac_up_pts = 1; - cell_conf[i]->op_dl_freq = flexran_agent_get_operating_dl_freq (enb_id,i); - cell_conf[i]->has_op_dl_freq = 1; + cell_conf[i]->dl_freq = flexran_agent_get_operating_dl_freq (enb_id,i); + cell_conf[i]->has_dl_freq = 1; - cell_conf[i]->op_ul_freq = flexran_agent_get_operating_ul_freq (enb_id, i); - cell_conf[i]->has_op_ul_freq = 1; + cell_conf[i]->ul_freq = flexran_agent_get_operating_ul_freq (enb_id, i); + cell_conf[i]->has_ul_freq = 1; - cell_conf[i]->op_eutra_band = flexran_agent_get_operating_eutra_band (enb_id,i); - cell_conf[i]->has_op_eutra_band = 1; + cell_conf[i]->eutra_band = flexran_agent_get_operating_eutra_band (enb_id,i); + cell_conf[i]->has_eutra_band = 1; - cell_conf[i]->op_dl_pdsch_power = flexran_agent_get_operating_pdsch_refpower(enb_id, i); - cell_conf[i]->has_op_dl_pdsch_power = 1; + cell_conf[i]->dl_pdsch_power = flexran_agent_get_operating_pdsch_refpower(enb_id, i); + cell_conf[i]->has_dl_pdsch_power = 1; - cell_conf[i]->op_ul_pusch_power = flexran_agent_get_operating_pusch_p0 (enb_id,i); - cell_conf[i]->has_op_ul_pusch_power = 1; + cell_conf[i]->ul_pusch_power = flexran_agent_get_operating_pusch_p0 (enb_id,i); + cell_conf[i]->has_ul_pusch_power = 1; if (flexran_get_enable64QAM(enb_id,i) == 0) { From 4d3689a56c0184d4f4697d443bbbca89172c3099 Mon Sep 17 00:00:00 2001 From: shahab SHARIAT BAGHERI Date: Wed, 9 Aug 2017 13:42:50 +0200 Subject: [PATCH 033/195] warning reducing --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 10 +++++----- .../CONTROL_MODULES/MAC/flexran_agent_mac_defs.h | 7 ++++--- openair2/ENB_APP/flexran_agent_common.c | 5 +++++ openair2/ENB_APP/flexran_agent_ran_api.c | 2 +- openair2/ENB_APP/flexran_agent_ran_api.h | 3 +++ openair2/LAYER2/MAC/flexran_agent_mac_proto.h | 9 +++++++++ .../MAC/flexran_agent_scheduler_dlsch_ue.c | 4 ++-- .../MAC/flexran_agent_scheduler_ulsch_ue.c | 16 ++++++++++++---- 8 files changed, 41 insertions(+), 15 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 512be68669..60cdba76aa 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -1078,11 +1078,11 @@ int flexran_agent_mac_create_empty_ul_config(mid_t mod_id, Protocol__FlexranMess int flexran_agent_mac_destroy_ul_config(Protocol__FlexranMessage *msg) { - int i,j, k; + int i; //,j, k; if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_UL_MAC_CONFIG_MSG) goto error; - Protocol__FlexUlDci *ul_dci; + // Protocol__FlexUlDci *ul_dci; free(msg->ul_mac_config_msg->header); for (i = 0; i < msg->ul_mac_config_msg->n_ul_ue_data; i++) { @@ -1096,13 +1096,13 @@ int flexran_agent_mac_destroy_ul_config(Protocol__FlexranMessage *msg) { // free(msg->ul_mac_config_msg->ul_ue_data[i]->rlc_pdu[j]); // } // free(msg->ul_mac_config_msg->ul_ue_data[i]->rlc_pdu); - ul_dci = msg->ul_mac_config_msg->ul_ue_data[i]->ul_dci; + // ul_dci = msg->ul_mac_config_msg->ul_ue_data[i]->ul_dci; // free(dl_dci->tbs_size); // free(ul_dci->mcs); // free(ul_dci->ndi); // free(ul_dci->rv); // free(ul_dci); - free(msg->ul_mac_config_msg->ul_ue_data[i]); + // free(msg->ul_mac_config_msg->ul_ue_data[i]); } free(msg->ul_mac_config_msg->ul_ue_data); @@ -1269,7 +1269,7 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { //xface->flexran_agent_send_update_mac_stats = NULL; xface->flexran_agent_schedule_ue_spec = NULL; xface->flexran_agent_get_pending_dl_mac_config = NULL; - + xface->flexran_agent_schedule_ul_spec = NULL; xface->dl_scheduler_loaded_lib = NULL; xface->ul_scheduler_loaded_lib = NULL; diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h index 362c50f13c..10347f5587 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h @@ -60,9 +60,10 @@ typedef struct { void (*flexran_agent_schedule_ue_spec)(mid_t mod_id, uint32_t frame, uint32_t subframe, int *mbsfn_flag, Protocol__FlexranMessage **dl_info); - - void (*flexran_agent_schedule_ul_spec)(mid_t module_idP, uint32_t frameP, unsigned char cooperation_flag, - uint32_t subframeP, unsigned char sched_subframe, Protocol__FlexranMessage **ul_info); + /// Run the UE UL scheduler and fill the Protocol__FlexranMessage. Assumes that + + void (*flexran_agent_schedule_ul_spec)(mid_t module_idP, uint32_t frameP, uint32_t cooperation_flag, + int subframeP, unsigned char sched_subframe, Protocol__FlexranMessage **ul_info); /// Notify the controller for a state change of a particular UE, by sending the proper /// UE state change message (ACTIVATION, DEACTIVATION, HANDOVER) diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index e3f96c05dc..e56ebdfd22 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -397,6 +397,11 @@ int flexran_agent_control_delegation(mid_t mod_id, const void *params, Protocol_ status = mkdir(local_cache, S_IRWXU | S_IRWXG | S_IRWXO); + if (status < 0){ + + LOG_W(ENB_APP, "Couldn't create local cache!"); + } + FILE *f; f = fopen(target, "wb"); fwrite(control_delegation_msg->payload.data, control_delegation_msg->payload.len, 1, f); diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 10b667e916..a22b6cb061 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -317,7 +317,7 @@ int flexran_get_harq(const mid_t mod_id, } else if (harq_flag == openair_harq_UL){ - mac_xface->get_ue_active_harq_pid(mod_id,CC_id,rnti,frame,subframe,&harq_pid,&round,openair_harq_UL); + mac_xface->get_ue_active_harq_pid(mod_id,CC_id,rnti,frame,subframe,&harq_pid,round,openair_harq_UL); } else { diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 668c0e6ba0..33def5e09a 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -314,3 +314,6 @@ int flexran_agent_get_operating_pdsch_refpower (mid_t mod_id, int cc_id); /*Get uplink power*/ int flexran_agent_get_operating_pusch_p0 (mid_t mod_id, int cc_id); + +/*RRC status flexRAN*/ +int flexran_get_rrc_status(const mid_t mod_id, const rnti_t rntiP); \ No newline at end of file diff --git a/openair2/LAYER2/MAC/flexran_agent_mac_proto.h b/openair2/LAYER2/MAC/flexran_agent_mac_proto.h index 5fc53fece6..59bef52dba 100644 --- a/openair2/LAYER2/MAC/flexran_agent_mac_proto.h +++ b/openair2/LAYER2/MAC/flexran_agent_mac_proto.h @@ -163,6 +163,15 @@ void _ulsch_scheduler_pre_processor(module_id_t module_idP, uint16_t *first_rb); +void flexran_agent_schedule_ulsch_rnti(module_id_t module_idP, + unsigned char cooperation_flag, + frame_t frameP, + sub_frame_t subframeP, + unsigned char sched_subframe, + uint16_t *first_rb); + +/* Downlink Primitives */ + void _dlsch_scheduler_pre_processor (module_id_t Mod_id, int slice_id, frame_t frameP, diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c index 02fe873144..601310d67a 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c @@ -788,7 +788,7 @@ flexran_schedule_ue_dl_spec_default(mid_t mod_id, slice_maxmcs_current[i] = slice_maxmcs[i]; } else { - LOG_W(MAC,"[eNB %d][SLICE %d] invalid slice max mcs %d, revert the previous value %d\n",mod_id, i, slice_percentage[i],slice_percentage[i]); + // LOG_W(MAC,"[eNB %d][SLICE %d] invalid slice max mcs %d, revert the previous value %d\n",mod_id, i, slice_maxmcs[i],slice_percentage[i]); slice_maxmcs[i]= slice_maxmcs_current[i]; @@ -1253,7 +1253,7 @@ flexran_schedule_ue_dl_spec_common(mid_t mod_id, header_len += 3; // Need to see if we have space for data from this channel if (dci_tbs - ta_len - header_len - sdu_length_total > 0) { - LOG_D(MAC, "[TEST]Requested %d bytes from RLC buffer on channel %d during first call\n", dci_tbs-ta_len-header_len); + LOG_D(MAC, "[TEST]Requested %d bytes from RLC buffer on channel %d during first call\n", dci_tbs-ta_len-header_len, j); //If we have space, we need to see how much data we can request at most (if any available) rlc_status = mac_rlc_status_ind(mod_id, rnti, diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c index 4038ae518b..5b31c11681 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c @@ -49,14 +49,22 @@ #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" //#include "LAYER2/MAC/pre_processor.c" +#include "ENB_APP/flexran_agent_defs.h" +#include "flexran_agent_ran_api.h" #include "pdcp.h" +#include "header.pb-c.h" +#include "flexran.pb-c.h" +#include "flexran_agent_mac.h" + #if defined(ENABLE_ITTI) # include "intertask_interface.h" #endif #include "T.h" +#include + /* number of active slices for past and current time*/ int n_active_slices_uplink = 1; int n_active_slices_uplink_current = 1; @@ -222,7 +230,7 @@ void _ulsch_scheduler_pre_processor(module_id_t module_idP, rnti_t rnti= -1; UE_list_t *UE_list = &eNB_mac_inst[module_idP].UE_list; UE_TEMPLATE *UE_template = 0; - LTE_DL_FRAME_PARMS *frame_parms = 0; + // LTE_DL_FRAME_PARMS *frame_parms; //Not used yet UE_sched_ctrl *ue_sched_ctl; @@ -272,7 +280,7 @@ void _ulsch_scheduler_pre_processor(module_id_t module_idP, CC_id = UE_list->ordered_ULCCids[n][UE_id]; UE_template = &UE_list->UE_template[CC_id][UE_id]; average_rbs_per_user[CC_id]=0; - frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id); + // frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id); if (UE_template->pre_allocated_nb_rb_ul > 0) { total_ue_count+=1; @@ -359,7 +367,7 @@ void _ulsch_scheduler_pre_processor(module_id_t module_idP, // This is the actual CC_id in the list CC_id = UE_list->ordered_ULCCids[n][UE_id]; UE_template = &UE_list->UE_template[CC_id][UE_id]; - frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id); + // frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id); total_remaining_rbs[CC_id]=nb_rbs_allowed_slice_uplink[CC_id][UE_id] - first_rb[CC_id] - total_allocated_rbs[CC_id]; if (total_ue_count == 1 ) { @@ -384,7 +392,7 @@ void _ulsch_scheduler_pre_processor(module_id_t module_idP, } for (CC_id=0; CC_idget_lte_frame_parms(module_idP,CC_id); + // frame_parms= mac_xface->get_lte_frame_parms(module_idP,CC_id); if (total_allocated_rbs[CC_id]>0) { LOG_D(MAC,"[eNB %d] total RB allocated for all UEs = %d/%d\n", module_idP, total_allocated_rbs[CC_id], nb_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id]); From c3adbb954510cb0b9eb22e5c58ba4ab7558b6a1c Mon Sep 17 00:00:00 2001 From: shahab SHARIAT BAGHERI Date: Wed, 9 Aug 2017 22:46:42 +0200 Subject: [PATCH 034/195] warnings --- openair2/ENB_APP/flexran_agent_net_comm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/ENB_APP/flexran_agent_net_comm.c b/openair2/ENB_APP/flexran_agent_net_comm.c index 6e39d6089f..f8e350d6a9 100644 --- a/openair2/ENB_APP/flexran_agent_net_comm.c +++ b/openair2/ENB_APP/flexran_agent_net_comm.c @@ -118,7 +118,7 @@ int flexran_agent_create_channel(void *channel_info, /*element should be a real pointer*/ RB_INSERT(flexran_agent_channel_map, &channel_instance.flexran_agent_head, channel); - LOG_I(FLEXRAN_AGENT,"Created a new channel with id 0x%lx\n", channel->channel_id); + LOG_I(FLEXRAN_AGENT,"Created a new channel with id %d \n", channel->channel_id); return channel_id; } From e996f5d0f5a83255e3741866dfb991098154ba9b Mon Sep 17 00:00:00 2001 From: Navid Nikaein Date: Fri, 17 Nov 2017 16:53:58 +0100 Subject: [PATCH 035/195] Add new RAN APIs form SMA app based on the initial eNb config file --- .../ENB_APP/flexran_agent_common_internal.c | 163 +++++++++++++++++- .../ENB_APP/flexran_agent_common_internal.h | 8 +- openair2/ENB_APP/flexran_agent_ran_api.c | 139 ++++++++++++--- openair2/ENB_APP/flexran_agent_ran_api.h | 25 ++- 4 files changed, 303 insertions(+), 32 deletions(-) diff --git a/openair2/ENB_APP/flexran_agent_common_internal.c b/openair2/ENB_APP/flexran_agent_common_internal.c index e735b2748b..fca73894c5 100644 --- a/openair2/ENB_APP/flexran_agent_common_internal.c +++ b/openair2/ENB_APP/flexran_agent_common_internal.c @@ -21,8 +21,8 @@ /*! \file flexran_agent_common_internal.c * \brief internal functions for common message primitves and utilities - * \author Xenofon Foukas - * \date 2016 + * \author Xenofon Foukas and N. Nikaein + * \date 2017 * \version 0.1 */ @@ -31,6 +31,7 @@ #include "flexran_agent_common_internal.h" #include "flexran_agent_mac_internal.h" +extern volatile int reconfigure_enb; int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy_length) { @@ -64,7 +65,17 @@ int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy break; case YAML_SCALAR_EVENT: // Check the system name and call the proper handler - if (strcmp((char *) event.data.scalar.value, "mac") == 0) { + // Check the system name and call the proper handler + if (strcmp((char *) event.data.scalar.value, "enb") == 0) { + LOG_I(ENB_APP, "This is intended for the enb system\n"); + // Call the enb handler + if (parse_enb_id(mod_id, &parser) == -1) { + goto error; + } else { // succeful parse and setting + LOG_I(ENB_APP, "Successful parsed config for enb system\n"); + //reconfigure_enb=RECONF_FREQ; + } + } else if (strcmp((char *) event.data.scalar.value, "mac") == 0) { LOG_D(ENB_APP, "This is intended for the mac system\n"); // Call the mac handler if (parse_mac_config(mod_id, &parser) == -1) { @@ -90,8 +101,8 @@ int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy // TODO : Just skip it for now if (skip_system_section(&parser) == -1) { goto error; - } - } else { + } + } else { goto error; } break; @@ -115,6 +126,148 @@ int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy } +int parse_enb_id(mid_t mod_id, yaml_parser_t *parser) { + yaml_event_t event; + + void *param; + char *endptr; + int is_array = 0; + int i = 0; + + int done = 0; + int mapping_started = 0; + + while (!done) { + + if (!yaml_parser_parse(parser, &event)) + goto error; + + switch (event.type) { + // We are expecting a mapping of parameters + case YAML_SEQUENCE_START_EVENT: + is_array = 1; + break; + case YAML_MAPPING_START_EVENT: + LOG_D(ENB_APP, "The mapping of the parameters started\n"); + mapping_started = 1; + break; + case YAML_MAPPING_END_EVENT: + LOG_D(ENB_APP, "The mapping of the parameters ended\n"); + mapping_started = 0; + break; + case YAML_SCALAR_EVENT: + if (!mapping_started) { + goto error; + } + // Check what key needs to be set + // use eNB egistered + if (mac_agent_registered[mod_id]) { + LOG_I(ENB_APP, "Setting parameter for eNB %s\n", event.data.scalar.value); + if (strcmp((char *) event.data.scalar.tag, YAML_INT_TAG) == 0) { // if int + if ((strtol((char *) event.data.scalar.value, &endptr, 10))== mod_id ) { // enb_id == mod_id: right enb instance to be configured + if (parse_enb_config_parameters(mod_id, parser) == -1) { + goto error; + } + } + else{ + goto error; // not the expected type + } + } + } + break; + default: + goto error; + } + + done = (event.type == YAML_MAPPING_END_EVENT); + yaml_event_delete(&event); + } + + return 0; + + error: + yaml_event_delete(&event); + return -1; +} + +int parse_enb_config_parameters(mid_t mod_id, yaml_parser_t *parser) { + yaml_event_t event; + + void *param; + char *endptr; + + int done = 0; + int mapping_started = 0; + + while (!done) { + + if (!yaml_parser_parse(parser, &event)) + goto error; + + switch (event.type) { + // We are expecting a mapping of parameters + case YAML_MAPPING_START_EVENT: + LOG_D(ENB_APP, "The mapping of the parameters started\n"); + mapping_started = 1; + break; + case YAML_MAPPING_END_EVENT: + LOG_D(ENB_APP, "The mapping of the parameters ended\n"); + mapping_started = 0; + break; + case YAML_SCALAR_EVENT: + if (!mapping_started) { + goto error; + } + // Check what key needs to be set + LOG_I(ENB_APP, "Setting parameter %s\n", event.data.scalar.value); + if (strcmp((char *) event.data.scalar.value, "dl_freq") == 0) { + if (!yaml_parser_parse(parser, &event)) + goto error; + flexran_agent_set_operating_dl_freq(mod_id, + 0, + strtol((char *) event.data.scalar.value, &endptr, 10)); + LOG_I(ENB_APP, "Setting parameter value %s\n", event.data.scalar.value); + } else if (strcmp((char *) event.data.scalar.value, "ul_freq_offset") == 0) { + if (!yaml_parser_parse(parser, &event)) + goto error; + flexran_agent_set_operating_ul_freq(mod_id, + 0, + strtol((char *) event.data.scalar.value, &endptr, 10)); + LOG_I(ENB_APP, "Setting parameter value %s\n", event.data.scalar.value); + } else if (strcmp((char *) event.data.scalar.value, "bandwidth") == 0) { + if (!yaml_parser_parse(parser, &event)) + goto error; + flexran_agent_set_operating_bandwidth(mod_id, + 0, + strtol((char *) event.data.scalar.value, &endptr, 10)); + LOG_I(ENB_APP, "Setting parameter value %s\n", event.data.scalar.value); + } else if (strcmp((char *) event.data.scalar.value, "frame_type") == 0) { + if (!yaml_parser_parse(parser, &event)) + goto error; + flexran_agent_set_operating_frame_type (mod_id, + 0, + strtol((char *) event.data.scalar.value, &endptr, 10)); + LOG_I(ENB_APP, "Setting parameter value %s\n", event.data.scalar.value); + }else { // not supported tag + goto error; + } + + break; + default: + goto error; + } + + done = (event.type == YAML_MAPPING_END_EVENT); + yaml_event_delete(&event); + } + + return 0; + + error: + yaml_event_delete(&event); + return -1; +} + int skip_system_section(yaml_parser_t *parser) { yaml_event_t event; diff --git a/openair2/ENB_APP/flexran_agent_common_internal.h b/openair2/ENB_APP/flexran_agent_common_internal.h index c8f78aafe9..2b39025489 100644 --- a/openair2/ENB_APP/flexran_agent_common_internal.h +++ b/openair2/ENB_APP/flexran_agent_common_internal.h @@ -21,8 +21,8 @@ /*! \file flexran_agent_common_internal.h * \brief internal agent functions for common message primitves and utilities - * \author Xenofon Foukas - * \date 2016 + * \author Xenofon Foukas and N. Nikaein + * \date 2017 * \version 0.1 */ @@ -37,6 +37,10 @@ int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy int apply_parameter_modification(void *parameter, yaml_parser_t *parser); +int parse_enb_id(mid_t mod_id, yaml_parser_t *parser); +int parse_enb_config_parameters(mid_t mod_id, yaml_parser_t *parser) ; + + // This can be used when parsing for a specific system that is not yet implmeneted // in order to skip its configuration, without affecting the rest int skip_system_section(yaml_parser_t *parser); diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index a22b6cb061..0d3145e1d2 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -21,7 +21,7 @@ /*! \file flexran_agent_ran_api.c * \brief FlexRAN RAN API abstraction - * \author shahab SHARIAT BAGHERI + * \author N. Nikaein, X. Foukas and S. SHARIAT BAGHERI * \date 2017 * \version 0.1 */ @@ -30,7 +30,7 @@ /* - * get generic info from RAN + * generic info from RAN */ @@ -43,9 +43,15 @@ void flexran_set_enb_vars(mid_t mod_id, ran_name_t ran){ switch (ran){ case RAN_LTE_OAI : - enb[mod_id] = (void *)&eNB_mac_inst[mod_id]; - enb_ue[mod_id] = (void *)&eNB_mac_inst[mod_id].UE_list; - enb_rrc[mod_id] = (void *)&eNB_rrc_inst[mod_id]; + if(eNB_mac_inst == NULL){ + enb[mod_id] = NULL; + enb_ue[mod_id] = NULL; + enb_rrc[mod_id] = NULL; + }else{ + enb[mod_id] = (void *)&eNB_mac_inst[mod_id]; + enb_ue[mod_id] = (void *)&eNB_mac_inst[mod_id].UE_list; + enb_rrc[mod_id] = (void *)&eNB_rrc_inst[mod_id]; + } break; default : goto error; @@ -56,9 +62,20 @@ void flexran_set_enb_vars(mid_t mod_id, ran_name_t ran){ error: LOG_E(FLEXRAN_AGENT, "unknown RAN name %d\n", ran); } +static int mac_xface_not_ready(void); + +static int mac_xface_not_ready(void){ + if (mac_xface == NULL) + return 1; + else { + //printf("max_xface %p %d \n", mac_xface, mac_xface->active); + return 0;// !mac_xface->active; + } +} + int flexran_get_current_time_ms (mid_t mod_id, int subframe_flag){ - + if (enb[mod_id] == NULL) return 0; if (subframe_flag == 1){ return ((eNB_MAC_INST *)enb[mod_id])->frame*10 + ((eNB_MAC_INST *)enb[mod_id])->subframe; }else { @@ -68,7 +85,7 @@ int flexran_get_current_time_ms (mid_t mod_id, int subframe_flag){ } unsigned int flexran_get_current_frame (mid_t mod_id) { - + if (enb[mod_id] == NULL) return 0; // #warning "SFN will not be in [0-1023] when oaisim is used" return ((eNB_MAC_INST *)enb[mod_id])->frame; @@ -79,7 +96,7 @@ unsigned int flexran_get_current_system_frame_num(mid_t mod_id) { } unsigned int flexran_get_current_subframe (mid_t mod_id) { - + if (enb[mod_id] == NULL) return 0; return ((eNB_MAC_INST *)enb[mod_id])->subframe; } @@ -125,7 +142,7 @@ uint16_t flexran_get_future_sfn_sf (mid_t mod_id, int ahead_of_time) { } int flexran_get_num_ues (mid_t mod_id){ - + if (enb_ue[mod_id] == NULL) return 0; return ((UE_list_t *)enb_ue[mod_id])->num_UEs; } @@ -135,17 +152,19 @@ int flexran_get_ue_crnti (mid_t mod_id, mid_t ue_id) { } int flexran_get_ue_bsr (mid_t mod_id, mid_t ue_id, lcid_t lcid) { - + if (enb_ue[mod_id] == NULL) return 0; return ((UE_list_t *)enb_ue[mod_id])->UE_template[UE_PCCID(mod_id,ue_id)][ue_id].bsr_info[lcid]; } int flexran_get_ue_phr (mid_t mod_id, mid_t ue_id) { - + if (enb_ue[mod_id] == NULL) return 0; return ((UE_list_t *)enb_ue[mod_id])->UE_template[UE_PCCID(mod_id,ue_id)][ue_id].phr_info; } int flexran_get_ue_wcqi (mid_t mod_id, mid_t ue_id) { LTE_eNB_UE_stats *eNB_UE_stats = NULL; + if (mac_xface_not_ready()) return 0 ; + eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, 0, UE_RNTI(mod_id, ue_id)); return eNB_UE_stats->DL_cqi[0]; @@ -174,10 +193,11 @@ short flexran_get_TA(mid_t mod_id, mid_t ue_id, int CC_id) { int rnti; rnti = flexran_get_ue_crnti(mod_id, ue_id); + if (mac_xface_not_ready()) return 0 ; LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti); //ue_sched_ctl->ta_timer = 20; // wait 20 subframes before taking TA measurement from PHY - switch (PHY_vars_eNB_g[mod_id][CC_id]->frame_parms.N_RB_DL) { + switch (flexran_get_N_RB_DL(mod_id, CC_id)) { case 6: return eNB_UE_stats->timing_advance_update; case 15: @@ -189,7 +209,7 @@ short flexran_get_TA(mid_t mod_id, mid_t ue_id, int CC_id) { case 75: return eNB_UE_stats->timing_advance_update/12; case 100: - if (PHY_vars_eNB_g[mod_id][CC_id]->frame_parms.threequarter_fs == 0) { + if (flexran_get_threequarter_fs(mod_id, CC_id) == 0) { return eNB_UE_stats->timing_advance_update/16; } else { return eNB_UE_stats->timing_advance_update/12; @@ -232,6 +252,8 @@ int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id,int CC_id) { // UE_list_t *UE_list = &eNB_mac_inst[mod_id].UE_list; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + if (mac_xface_not_ready()) return 0 ; + LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id,CC_id,rnti); if (eNB_UE_stats == NULL) { @@ -247,11 +269,13 @@ int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id,int CC_id) { } int flexran_get_active_CC(mid_t mod_id, mid_t ue_id) { + if (enb_ue[mod_id] == NULL) return 0; return ((UE_list_t *)enb_ue[mod_id])->numactiveCCs[ue_id]; } int flexran_get_current_RI(mid_t mod_id, mid_t ue_id, int CC_id) { LTE_eNB_UE_stats *eNB_UE_stats = NULL; + if (mac_xface_not_ready()) return 0 ; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); @@ -271,6 +295,7 @@ int flexran_get_tpc(mid_t mod_id, mid_t ue_id) { int pCCid = UE_PCCID(mod_id,ue_id); rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + if (mac_xface_not_ready()) return 0 ; eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, pCCid, rnti); @@ -309,6 +334,7 @@ int flexran_get_harq(const mid_t mod_id, uint8_t harq_pid; uint8_t harq_round; + if (mac_xface_not_ready()) return 0 ; uint16_t rnti = flexran_get_ue_crnti(mod_id,ue_id); if (harq_flag == openair_harq_DL){ @@ -340,7 +366,8 @@ int flexran_get_harq(const mid_t mod_id, int flexran_get_p0_pucch_dbm(mid_t mod_id, mid_t ue_id, int CC_id) { LTE_eNB_UE_stats *eNB_UE_stats = NULL; uint32_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - + if (mac_xface_not_ready()) return 0 ; + eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti); if (eNB_UE_stats == NULL) { @@ -355,11 +382,15 @@ int flexran_get_p0_pucch_dbm(mid_t mod_id, mid_t ue_id, int CC_id) { } int flexran_get_p0_nominal_pucch(mid_t mod_id, int CC_id) { + if (mac_xface_not_ready()) return 0 ; + int32_t pucch_rx_received = mac_xface->get_target_pucch_rx_power(mod_id, CC_id); return pucch_rx_received; } int flexran_get_p0_pucch_status(mid_t mod_id, mid_t ue_id, int CC_id) { + if (mac_xface_not_ready()) return 0 ; + LTE_eNB_UE_stats *eNB_UE_stats = NULL; uint32_t rnti = flexran_get_ue_crnti(mod_id,ue_id); @@ -368,6 +399,8 @@ int flexran_get_p0_pucch_status(mid_t mod_id, mid_t ue_id, int CC_id) { } int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, int CC_id) { + if (mac_xface_not_ready()) return 0 ; + LTE_eNB_UE_stats *eNB_UE_stats = NULL; uint32_t rnti = flexran_get_ue_crnti(mod_id,ue_id); @@ -383,9 +416,18 @@ int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, int CC_id) { * Get Messages for eNB Configuration Reply * ************************************ */ +int flexran_get_threequarter_fs(mid_t mod_id, int CC_id) { + LTE_DL_FRAME_PARMS *frame_parms; + if (mac_xface_not_ready()) return 0 ; + + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + return frame_parms->threequarter_fs; +} + int flexran_get_hopping_offset(mid_t mod_id, int CC_id) { LTE_DL_FRAME_PARMS *frame_parms; + if (mac_xface_not_ready()) return 0 ; frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); return frame_parms->pusch_config_common.pusch_HoppingOffset; @@ -393,6 +435,7 @@ int flexran_get_hopping_offset(mid_t mod_id, int CC_id) { int flexran_get_hopping_mode(mid_t mod_id, int CC_id) { LTE_DL_FRAME_PARMS *frame_parms; + if (mac_xface_not_ready()) return 0 ; frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); return frame_parms->pusch_config_common.hoppingMode; @@ -400,6 +443,7 @@ int flexran_get_hopping_mode(mid_t mod_id, int CC_id) { int flexran_get_n_SB(mid_t mod_id, int CC_id) { LTE_DL_FRAME_PARMS *frame_parms; + if (mac_xface_not_ready()) return 0 ; frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); return frame_parms->pusch_config_common.n_SB; @@ -407,6 +451,7 @@ int flexran_get_n_SB(mid_t mod_id, int CC_id) { int flexran_get_enable64QAM(mid_t mod_id, int CC_id) { LTE_DL_FRAME_PARMS *frame_parms; + if (mac_xface_not_ready()) return 0 ; frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); return frame_parms->pusch_config_common.enable64QAM; @@ -414,6 +459,7 @@ int flexran_get_enable64QAM(mid_t mod_id, int CC_id) { int flexran_get_phich_duration(mid_t mod_id, int CC_id) { LTE_DL_FRAME_PARMS *frame_parms; + if (mac_xface_not_ready()) return 0 ; frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); return frame_parms->phich_config_common.phich_duration; @@ -421,6 +467,7 @@ int flexran_get_phich_duration(mid_t mod_id, int CC_id) { int flexran_get_phich_resource(mid_t mod_id, int CC_id) { LTE_DL_FRAME_PARMS *frame_parms; + if (mac_xface_not_ready()) return 0 ; frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); if(frame_parms->phich_config_common.phich_resource == oneSixth) @@ -437,6 +484,7 @@ int flexran_get_phich_resource(mid_t mod_id, int CC_id) { int flexran_get_n1pucch_an(mid_t mod_id, int CC_id) { LTE_DL_FRAME_PARMS *frame_parms; + if (mac_xface_not_ready()) return 0 ; frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); return frame_parms->pucch_config_common.n1PUCCH_AN; @@ -444,6 +492,7 @@ int flexran_get_n1pucch_an(mid_t mod_id, int CC_id) { int flexran_get_nRB_CQI(mid_t mod_id, int CC_id) { LTE_DL_FRAME_PARMS *frame_parms; + if (mac_xface_not_ready()) return 0 ; frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); return frame_parms->pucch_config_common.nRB_CQI; @@ -451,6 +500,7 @@ int flexran_get_nRB_CQI(mid_t mod_id, int CC_id) { int flexran_get_deltaPUCCH_Shift(mid_t mod_id, int CC_id) { LTE_DL_FRAME_PARMS *frame_parms; + if (mac_xface_not_ready()) return 0 ; frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); return frame_parms->pucch_config_common.deltaPUCCH_Shift; @@ -458,6 +508,7 @@ int flexran_get_deltaPUCCH_Shift(mid_t mod_id, int CC_id) { int flexran_get_prach_ConfigIndex(mid_t mod_id, int CC_id) { LTE_DL_FRAME_PARMS *frame_parms; + if (mac_xface_not_ready()) return 0 ; frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); return frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex; @@ -465,6 +516,7 @@ int flexran_get_prach_ConfigIndex(mid_t mod_id, int CC_id) { int flexran_get_prach_FreqOffset(mid_t mod_id, int CC_id) { LTE_DL_FRAME_PARMS *frame_parms; + if (mac_xface_not_ready()) return 0 ; frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); return frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset; @@ -472,6 +524,7 @@ int flexran_get_prach_FreqOffset(mid_t mod_id, int CC_id) { int flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, int CC_id) { LTE_DL_FRAME_PARMS *frame_parms; + if (mac_xface_not_ready()) return 0 ; frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); return frame_parms->maxHARQ_Msg3Tx; @@ -479,6 +532,7 @@ int flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, int CC_id) { int flexran_get_ul_cyclic_prefix_length(mid_t mod_id, int CC_id) { LTE_DL_FRAME_PARMS *frame_parms; + if (mac_xface_not_ready()) return 0 ; frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); return frame_parms->Ncp_UL; @@ -486,7 +540,8 @@ int flexran_get_ul_cyclic_prefix_length(mid_t mod_id, int CC_id) { int flexran_get_dl_cyclic_prefix_length(mid_t mod_id, int CC_id) { LTE_DL_FRAME_PARMS *frame_parms; - + if (mac_xface_not_ready()) return 0 ; + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); return frame_parms->Ncp; } @@ -494,19 +549,23 @@ int flexran_get_dl_cyclic_prefix_length(mid_t mod_id, int CC_id) { int flexran_get_cell_id(mid_t mod_id, int CC_id) { LTE_DL_FRAME_PARMS *frame_parms; + if (mac_xface_not_ready()) return 0; + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); return frame_parms->Nid_cell; } int flexran_get_srs_BandwidthConfig(mid_t mod_id, int CC_id) { LTE_DL_FRAME_PARMS *frame_parms; - + if (mac_xface_not_ready()) return 0 ; + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); return frame_parms->soundingrs_ul_config_common.srs_BandwidthConfig; } int flexran_get_srs_SubframeConfig(mid_t mod_id, int CC_id) { LTE_DL_FRAME_PARMS *frame_parms; + if (mac_xface_not_ready()) return 0 ; frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); return frame_parms->soundingrs_ul_config_common.srs_SubframeConfig; @@ -514,6 +573,7 @@ int flexran_get_srs_SubframeConfig(mid_t mod_id, int CC_id) { int flexran_get_srs_MaxUpPts(mid_t mod_id, int CC_id) { LTE_DL_FRAME_PARMS *frame_parms; + if (mac_xface_not_ready()) return 0 ; frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); return frame_parms->soundingrs_ul_config_common.srs_MaxUpPts; @@ -521,6 +581,7 @@ int flexran_get_srs_MaxUpPts(mid_t mod_id, int CC_id) { int flexran_get_N_RB_DL(mid_t mod_id, int CC_id) { LTE_DL_FRAME_PARMS *frame_parms; + if (mac_xface_not_ready()) return 0 ; frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); return frame_parms->N_RB_DL; @@ -528,6 +589,7 @@ int flexran_get_N_RB_DL(mid_t mod_id, int CC_id) { int flexran_get_N_RB_UL(mid_t mod_id, int CC_id) { LTE_DL_FRAME_PARMS *frame_parms; + if (mac_xface_not_ready()) return 0 ; frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); return frame_parms->N_RB_UL; @@ -535,6 +597,7 @@ int flexran_get_N_RB_UL(mid_t mod_id, int CC_id) { int flexran_get_N_RBG(mid_t mod_id, int CC_id) { LTE_DL_FRAME_PARMS *frame_parms; + if (mac_xface_not_ready()) return 0 ; frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); return frame_parms->N_RBG; @@ -542,6 +605,7 @@ int flexran_get_N_RBG(mid_t mod_id, int CC_id) { int flexran_get_subframe_assignment(mid_t mod_id, int CC_id) { LTE_DL_FRAME_PARMS *frame_parms; + if (mac_xface_not_ready()) return 0 ; frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); return frame_parms->tdd_config; @@ -549,9 +613,10 @@ int flexran_get_subframe_assignment(mid_t mod_id, int CC_id) { int flexran_get_special_subframe_assignment(mid_t mod_id, int CC_id) { LTE_DL_FRAME_PARMS *frame_parms; + if (mac_xface_not_ready()) return 0 ; frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->tdd_config_S; + return (frame_parms == NULL)? 0:frame_parms->tdd_config_S; } int flexran_get_ra_ResponseWindowSize(mid_t mod_id, int CC_id) { @@ -564,8 +629,10 @@ int flexran_get_mac_ContentionResolutionTimer(mid_t mod_id, int CC_id) { int flexran_get_duplex_mode(mid_t mod_id, int CC_id) { LTE_DL_FRAME_PARMS *frame_parms; + if (mac_xface_not_ready()) return 0 ; frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); + if (frame_parms == NULL) return -1; if(frame_parms->frame_type == TDD) return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD; else if (frame_parms->frame_type == FDD) @@ -671,10 +738,12 @@ int flexran_get_rrc_status(const mid_t mod_id, const rnti_t rntiP){ } int flexran_get_ue_aggregated_max_bitrate_dl (mid_t mod_id, mid_t ue_id) { + if (enb_ue[mod_id] == NULL) return 0; return ((UE_list_t *)enb_ue[mod_id])->UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateDL; } int flexran_get_ue_aggregated_max_bitrate_ul (mid_t mod_id, mid_t ue_id) { + if (enb_ue[mod_id] == NULL) return 0; return ((UE_list_t *)enb_ue[mod_id])->UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateUL; } @@ -953,19 +1022,19 @@ int flexran_get_antenna_ports(mid_t mod_id, int CC_id){ LTE_DL_FRAME_PARMS *frame_parms; frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->nb_antenna_ports_eNB; + return (frame_parms == NULL)? 0:frame_parms->nb_antenna_ports_eNB; } -float flexran_agent_get_operating_dl_freq (mid_t mod_id, int cc_id) { +uint32_t flexran_agent_get_operating_dl_freq (mid_t mod_id, int cc_id) { const Enb_properties_array_t* enb_properties = enb_config_get(); return (enb_properties->properties[mod_id]->downlink_frequency[cc_id] / 1000000); } -float flexran_agent_get_operating_ul_freq (mid_t mod_id, int cc_id) { +uint32_t flexran_agent_get_operating_ul_freq (mid_t mod_id, int cc_id) { const Enb_properties_array_t* enb_properties = enb_config_get(); - return ((enb_properties->properties[mod_id] ->downlink_frequency[cc_id] + enb_properties->properties[0]->uplink_frequency_offset[cc_id]) / 1000000); + return ((enb_properties->properties[mod_id]->downlink_frequency[cc_id] + enb_properties->properties[0]->uplink_frequency_offset[cc_id]) / 1000000); } int flexran_agent_get_operating_eutra_band (mid_t mod_id, int cc_id) { @@ -981,5 +1050,33 @@ int flexran_agent_get_operating_pusch_p0 (mid_t mod_id, int cc_id) { return enb_properties->properties[mod_id]->pusch_p0_Nominal[cc_id]; } +void flexran_agent_set_operating_dl_freq (mid_t mod_id, int cc_id, uint32_t dl_freq_mhz) { + + Enb_properties_array_t* enb_properties = enb_config_get(); + enb_properties->properties[mod_id]->downlink_frequency[cc_id]=dl_freq_mhz * 1000000; + /*printf("[ENB_APP] mod id %d ccid %d dl freq %d/%d\n", mod_id, cc_id, dl_freq_mhz, enb_properties->properties[mod_id]->downlink_frequency[cc_id]); */ +} + +void flexran_agent_set_operating_ul_freq (mid_t mod_id, int cc_id, int32_t ul_freq_offset_mhz) { + Enb_properties_array_t* enb_properties = enb_config_get(); + enb_properties->properties[mod_id]->uplink_frequency_offset[cc_id]=ul_freq_offset_mhz * 1000000; +} +//TBD +void flexran_agent_set_operating_eutra_band (mid_t mod_id, int cc_id) { + Enb_properties_array_t* enb_properties = enb_config_get(); + enb_properties->properties[mod_id]->eutra_band[cc_id]=7; +} + +void flexran_agent_set_operating_bandwidth (mid_t mod_id, int cc_id, int bandwidth) { + Enb_properties_array_t* enb_properties = enb_config_get(); + enb_properties->properties[mod_id]->N_RB_DL[cc_id]=bandwidth; +} + +void flexran_agent_set_operating_frame_type (mid_t mod_id, int cc_id, int frame_type) { + Enb_properties_array_t* enb_properties = enb_config_get(); + enb_properties->properties[mod_id]->frame_type[cc_id]=frame_type; +} + + diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 33def5e09a..9f0313c1ca 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -21,7 +21,7 @@ /*! \file flexran_agent_ran_api.h * \brief FlexRAN RAN API abstraction header - * \author shahab SHARIAT BAGHERI + * \author N. Nikaein, X. Foukas and S. SHARIAT BAGHERI * \date 2017 * \version 0.1 */ @@ -198,6 +198,8 @@ int flexran_get_p0_pucch_status(mid_t mod_id, mid_t ue_id, int CC_id); int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, int CC_id); +int flexran_get_threequarter_fs(mid_t mod_id, int CC_id); + int flexran_get_hopping_mode(mid_t mod_id, int CC_id); int flexran_get_hopping_offset(mid_t mod_id, int CC_id); @@ -301,10 +303,10 @@ int flexran_get_lcg(mid_t ue_id, mid_t lc_id); int flexran_get_direction(mid_t ue_id, mid_t lc_id); /*Get downlink frequency*/ -float flexran_agent_get_operating_dl_freq (mid_t mod_id, int cc_id); +uint32_t flexran_agent_get_operating_dl_freq (mid_t mod_id, int cc_id); /*Get uplink frequency*/ -float flexran_agent_get_operating_ul_freq (mid_t mod_id, int cc_id); +uint32_t flexran_agent_get_operating_ul_freq (mid_t mod_id, int cc_id); /*Get eutra band*/ int flexran_agent_get_operating_eutra_band (mid_t mod_id, int cc_id); @@ -315,5 +317,20 @@ int flexran_agent_get_operating_pdsch_refpower (mid_t mod_id, int cc_id); /*Get uplink power*/ int flexran_agent_get_operating_pusch_p0 (mid_t mod_id, int cc_id); +/*set the dl freq */ +void flexran_agent_set_operating_dl_freq (mid_t mod_id, int cc_id, uint32_t dl_freq_mhz); + +/* set the ul freq */ +void flexran_agent_set_operating_ul_freq (mid_t mod_id, int cc_id, int32_t ul_freq_offset_mhz); + +/*set the the band */ +void flexran_agent_set_operating_eutra_band (mid_t mod_id, int cc_id); + +/* set the bandwidth */ +void flexran_agent_set_operating_bandwidth (mid_t mod_id, int cc_id, int bandwidth); + +/*set frame type*/ +void flexran_agent_set_operating_frame_type (mid_t mod_id, int cc_id, int frame_type); + /*RRC status flexRAN*/ -int flexran_get_rrc_status(const mid_t mod_id, const rnti_t rntiP); \ No newline at end of file +int flexran_get_rrc_status(const mid_t mod_id, const rnti_t rntiP); From dc9cada6c2f3841677ce00801f3ec7c3c95fe3b2 Mon Sep 17 00:00:00 2001 From: Navid Nikaein Date: Fri, 8 Dec 2017 18:05:42 +0100 Subject: [PATCH 036/195] Add PDCP stats and update agent and RAN APIs --- cmake_targets/CMakeLists.txt | 2 + .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 2 +- .../CONTROL_MODULES/PDCP/flexran_agent_pdcp.c | 168 ++++++++++ .../CONTROL_MODULES/PDCP/flexran_agent_pdcp.h | 64 ++++ .../PDCP/flexran_agent_pdcp_defs.h | 63 ++++ .../CONTROL_MODULES/RRC/flexran_agent_rrc.c | 314 +++++++----------- .../CONTROL_MODULES/RRC/flexran_agent_rrc.h | 52 ++- .../RRC/flexran_agent_rrc_defs.h | 64 ++-- openair2/ENB_APP/MESSAGES/V2/flexran.proto | 1 + .../ENB_APP/MESSAGES/V2/stats_common.proto | 21 ++ .../ENB_APP/MESSAGES/V2/stats_messages.proto | 6 +- .../ENB_APP/MESSAGES/V2/time_common.proto | 1 + openair2/ENB_APP/flexran_agent.c | 3 + openair2/ENB_APP/flexran_agent.h | 1 + openair2/ENB_APP/flexran_agent_defs.h | 5 + openair2/ENB_APP/flexran_agent_extern.h | 7 + openair2/ENB_APP/flexran_agent_handler.c | 25 +- openair2/ENB_APP/flexran_agent_ran_api.c | 90 +++++ openair2/ENB_APP/flexran_agent_ran_api.h | 55 +++ openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 187 ++++++++--- openair2/LAYER2/PDCP_v10.1.0/pdcp.h | 46 ++- 21 files changed, 880 insertions(+), 297 deletions(-) create mode 100644 openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c create mode 100644 openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h create mode 100644 openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp_defs.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 734bfccf2d..6399f02ef0 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -762,6 +762,7 @@ include_directories("${OPENAIR_DIR}/targets/ARCH/EXMIMO/DEFS") include_directories("${OPENAIR2_DIR}/ENB_APP") include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC") include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/RRC") +include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PDCP") include_directories("${OPENAIR2_DIR}/UTIL/OSA") include_directories("${OPENAIR2_DIR}/UTIL/LFDS/liblfds6.1.1/liblfds611/inc") include_directories("${OPENAIR2_DIR}/UTIL/LFDS/liblfds7.0.0/liblfds700/inc") @@ -852,6 +853,7 @@ if (FLEXRAN_AGENT_SB_IF) ${OPENAIR2_DIR}/ENB_APP/flexran_agent_common_internal.c ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c + ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c ${OPENAIR2_DIR}/ENB_APP/flexran_agent.c ${OPENAIR2_DIR}/ENB_APP/flexran_agent_task_manager.c ${OPENAIR2_DIR}/ENB_APP/flexran_agent_net_comm.c diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 60cdba76aa..736cdb67e0 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -128,7 +128,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, rlc_reports[j]->retransmission_queue_hol_delay = 100; rlc_reports[j]->has_retransmission_queue_hol_delay = 0; //TODO DONE:Set current size of the pending message in bytes - rlc_reports[j]->status_pdu_size = flexran_get_tx_queue_size(enb_id, i, j + 1); + rlc_reports[j]->status_pdu_size = flexran_get_num_pdus_buffer(enb_id , i, j + 1); rlc_reports[j]->has_status_pdu_size = 1; } diff --git a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c new file mode 100644 index 0000000000..ecc40cd89a --- /dev/null +++ b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c @@ -0,0 +1,168 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file flexran_agent_pdcp.c + * \brief FlexRAN agent Control Module PDCP + * \author shahab SHARIAT BAGHERI + * \date 2017 + * \version 0.1 + */ + +#include "flexran_agent_pdcp.h" + + +/*Trigger boolean for PDCP measurement*/ +bool triggered_pdcp = false; +/*Flags showing if a pdcp agent has already been registered*/ +unsigned int pdcp_agent_registered[NUM_MAX_ENB]; + +/*Array containing the Agent-PDCP interfaces*/ +AGENT_PDCP_xface *agent_pdcp_xface[NUM_MAX_ENB]; + +// NUMBER_OF_UE_MAX + +void flexran_agent_pdcp_aggregate_stats(const mid_t mod_id, + const mid_t ue_id, + Protocol__FlexPdcpStats *pdcp_aggr_stats){ + + int lcid=0; + /* only calculate the DRBs */ + //LOG_I(FLEXRAN_AGENT, "enb %d ue %d \n", mod_id, ue_id); + + for (lcid=NUM_MAX_SRB ; lcid < NUM_MAX_SRB + NUM_MAX_DRB; lcid++){ + + pdcp_aggr_stats->pkt_tx += flexran_get_pdcp_tx(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_tx_bytes += flexran_get_pdcp_tx_bytes(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_tx_rate_s += flexran_get_pdcp_tx_rate_s(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_tx_throughput_s += flexran_get_pdcp_tx_throughput_s(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_tx_aiat += flexran_get_pdcp_tx_aiat(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_tx_aiat_s += flexran_get_pdcp_tx_aiat_s(mod_id,ue_id,lcid); + + + pdcp_aggr_stats->pkt_rx += flexran_get_pdcp_rx(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_rx_bytes += flexran_get_pdcp_rx_bytes(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_rx_rate_s += flexran_get_pdcp_rx_rate_s(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_rx_goodput_s += flexran_get_pdcp_rx_goodput_s(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_rx_aiat += flexran_get_pdcp_rx_aiat(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_rx_aiat_s += flexran_get_pdcp_rx_aiat_s(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_rx_oo += flexran_get_pdcp_rx_oo(mod_id,ue_id,lcid); + + } + +} + + +int flexran_agent_pdcp_stats_reply(mid_t mod_id, + const report_config_t *report_config, + Protocol__FlexUeStatsReport **ue_report, + Protocol__FlexCellStatsReport **cell_report) { + + + // Protocol__FlexHeader *header; + int i, j, k; + // int cc_id = 0; + + + /* Allocate memory for list of UE reports */ + if (report_config->nr_ue > 0) { + + for (i = 0; i < report_config->nr_ue; i++) { + + /* Check flag for creation of buffer status report */ + if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PDCP_STATS) { + + Protocol__FlexPdcpStats *pdcp_aggr_stats; + pdcp_aggr_stats = malloc(sizeof(Protocol__FlexPdcpStats)); + if (pdcp_aggr_stats == NULL) + goto error; + protocol__flex_pdcp_stats__init(pdcp_aggr_stats); + + flexran_agent_pdcp_aggregate_stats(mod_id, i, pdcp_aggr_stats); + + pdcp_aggr_stats->has_pkt_tx=1; + pdcp_aggr_stats->has_pkt_tx_bytes =1; + pdcp_aggr_stats->has_pkt_tx_rate_s=1; + pdcp_aggr_stats->has_pkt_tx_throughput_s =1; + pdcp_aggr_stats->has_pkt_tx_aiat =1; + pdcp_aggr_stats->has_pkt_tx_aiat_s =1; + + pdcp_aggr_stats->pkt_tx_sn = flexran_get_pdcp_tx_sn(mod_id, i, DEFAULT_DRB); + pdcp_aggr_stats->has_pkt_tx_sn =1; + + pdcp_aggr_stats->has_pkt_rx =1; + pdcp_aggr_stats->has_pkt_rx_bytes =1; + pdcp_aggr_stats->has_pkt_rx_rate_s =1; + pdcp_aggr_stats->has_pkt_rx_goodput_s =1; + pdcp_aggr_stats->has_pkt_rx_aiat =1; + pdcp_aggr_stats->has_pkt_rx_aiat_s =1; + pdcp_aggr_stats->has_pkt_rx_oo =1; + + pdcp_aggr_stats->pkt_rx_sn = flexran_get_pdcp_rx_sn(mod_id, i, DEFAULT_DRB); + pdcp_aggr_stats->has_pkt_rx_sn =1; + + ue_report[i]->pdcp_stats = pdcp_aggr_stats; + + } + } + } else { + LOG_D(FLEXRAN_AGENT, "no UE\n"); + } + + return 0; + + error: + LOG_W(FLEXRAN_AGENT, "Can't allocate PDCP stats\n"); + + /* if (cell_report != NULL) + free(cell_report); + if (ue_report != NULL) + free(ue_report); + */ + return -1; +} + + + +int flexran_agent_register_pdcp_xface(mid_t mod_id, AGENT_PDCP_xface *xface) { + if (pdcp_agent_registered[mod_id]) { + LOG_E(PDCP, "PDCP agent for eNB %d is already registered\n", mod_id); + return -1; + } + + //xface->flexran_pdcp_stats_measurement = NULL; + + pdcp_agent_registered[mod_id] = 1; + agent_pdcp_xface[mod_id] = xface; + + return 0; +} + +int flexran_agent_unregister_pdcp_xface(mid_t mod_id, AGENT_PDCP_xface *xface) { + + //xface->agent_ctxt = NULL; + //xface->flexran_pdcp_stats_measurement = NULL; + + + pdcp_agent_registered[mod_id] = 0; + agent_pdcp_xface[mod_id] = NULL; + + return 0; +} diff --git a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h new file mode 100644 index 0000000000..a962390c00 --- /dev/null +++ b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h @@ -0,0 +1,64 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file flexran_agent_pdcp.h + * \brief FlexRAN agent Control Module PDCP header + * \author shahab SHARIAT BAGHERI + * \date 2017 + * \version 0.1 + */ + +#ifndef FLEXRAN_AGENT_PDCP_H_ +#define FLEXRAN_AGENT_PDCP_H_ + +#include "header.pb-c.h" +#include "flexran.pb-c.h" +#include "stats_messages.pb-c.h" +#include "stats_common.pb-c.h" + + +#include "flexran_agent_common.h" +#include "flexran_agent_defs.h" +#include "flexran_agent_pdcp_defs.h" +#include "flexran_agent_ran_api.h" + +/********************************** + * FlexRAN agent - technology PDCP API + **********************************/ + +/* Send to the controller all the pdcp stat updates that occured during this subframe*/ +int flexran_agent_pdcp_stats_reply(mid_t mod_id, + const report_config_t *report_config, + Protocol__FlexUeStatsReport **ue_report, + Protocol__FlexCellStatsReport **cell_report); + +/* Get the stats from RAN API and aggregate them per USER*/ +void flexran_agent_pdcp_aggregate_stats(const mid_t mod_id, + const mid_t ue_id, + Protocol__FlexPdcpStats *pdcp_aggr_stats); + +/*Register technology specific interface callbacks*/ +int flexran_agent_register_pdcp_xface(mid_t mod_id, AGENT_PDCP_xface *xface); + +/*Unregister technology specific callbacks*/ +int flexran_agent_unregister_pdcp_xface(mid_t mod_id, AGENT_PDCP_xface*xface); + +#endif diff --git a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp_defs.h b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp_defs.h new file mode 100644 index 0000000000..46bdf744de --- /dev/null +++ b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp_defs.h @@ -0,0 +1,63 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ +#ifndef __FLEXRAN_AGENT_PDCP_PRIMITIVES_H__ +#define __FLEXRAN_AGENT_PDCP_PRIMITIVES_H__ + +#include "flexran_agent_defs.h" +#include "flexran.pb-c.h" +#include "header.pb-c.h" + + /*PDCP aggregated Packet stats */ +/* +typedef struct pdcp_aggr_stats_s { + int32_t rnti; + + int32_t pkt_tx; + int32_t pkt_tx_bytes; + int32_t pkt_tx_sn; + int32_t pkt_tx_rate_s; + int32_t pkt_tx_throughput_s; + int32_t pkt_tx_aiat; + int32_t pkt_tx_aiat_s; + + int32_t pkt_rx; + int32_t pkt_rx_bytes; + int32_t pkt_rx_sn; + int32_t pkt_rx_rate_s; + int32_t pkt_rx_goodput_s; + int32_t pkt_rx_aiat; + int32_t pkt_rx_aiat_s; + int32_t pkt_rx_oo; + + +} pdcp_aggr_stats_t; +*/ + +/* FLEXRAN AGENT-PDCP Interface */ +typedef struct { + + + // PDCP statistics + void (*flexran_pdcp_stats_measurement)(mid_t mod_id, uint16_t rnti, uint16_t seq_num, uint32_t size); + +} AGENT_PDCP_xface; + +#endif diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c index d48d12d670..e70d2a3d97 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c @@ -33,33 +33,15 @@ #include "log.h" +/*Trigger boolean for RRC measurement*/ +bool triggered_rrc = false; -/*Flags showing if a rrc agent has already been registered*/ +/*Flags showing if an rrc agent has already been registered*/ unsigned int rrc_agent_registered[NUM_MAX_ENB]; /*Array containing the Agent-RRC interfaces*/ AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB]; -/* Ringbuffer related structs used for maintaining the dl rrc config messages */ -//message_queue_t *rrc_dl_config_queue; -struct lfds700_misc_prng_state rrc_ps[NUM_MAX_ENB]; -struct lfds700_ringbuffer_element *rrc_dl_config_array[NUM_MAX_ENB]; -struct lfds700_ringbuffer_state rrc_ringbuffer_state[NUM_MAX_ENB]; - - - -void flexran_agent_init_rrc_agent(mid_t mod_id) { - lfds700_misc_library_init_valid_on_current_logical_core(); - lfds700_misc_prng_init(&rrc_ps[mod_id]); - int num_elements = RINGBUFFER_SIZE + 1; - //Allow RINGBUFFER_SIZE messages to be stored in the ringbuffer at any time - rrc_dl_config_array[mod_id] = malloc( sizeof(struct lfds700_ringbuffer_element) * num_elements); - lfds700_ringbuffer_init_valid_on_current_logical_core( &rrc_ringbuffer_state[mod_id], rrc_dl_config_array[mod_id], num_elements, &rrc_ps[mod_id], NULL ); -} - - - - void flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_change) { int size; @@ -280,156 +262,26 @@ int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg) { /* this is called by RRC as a part of rrc xface . The controller previously requested this*/ void flexran_trigger_rrc_measurements (mid_t mod_id, MeasResults_t* measResults) { - // int i, m, k; - int priority = 0; // Warning Preventing - void *data; - int size; - err_code_t err_code; - Protocol__FlexUeStatsReport **ue_report; - Protocol__FlexCellStatsReport **cell_report; - Protocol__FlexStatsReply *stats_reply_msg; - Protocol__FlexranMessage *msg; + int i, m, k; + // int priority = 0; // Warning Preventing + // void *data; + // int size; + err_code_t err_code = -100; + triggered_rrc = true; + int num; - Protocol__FlexHeader *header; - int xid = 0; - int i; + num = flexran_get_num_ues (mod_id); - if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_STATS_REPLY, &header) != 0) - goto error; + meas_stats = malloc(sizeof(rrc_meas_stats) * num); - - - stats_reply_msg = malloc(sizeof(Protocol__FlexStatsReply)); - - if (stats_reply_msg == NULL) - goto error; - - protocol__flex_stats_reply__init(stats_reply_msg); - stats_reply_msg->header = header; - stats_reply_msg->n_ue_report = 1; - stats_reply_msg->n_cell_report = 1; - -/****** LOCK ******************************************************************/ - // pthread_spin_lock(&rrc_meas_t_lock); - - // struct rrc_meas_trigg *ctxt; - // ctxt = rrc_meas_get_trigg(p->rnti, p->meas->measId); - - // pthread_spin_unlock(&rrc_meas_t_lock); -/****** UNLOCK ****************************************************************/ - - // if (ctxt == NULL) { - - // flexran_RRC_meas_reconf(p->rnti, -1, p->meas->measId, NULL, NULL); - // Free the measurement report received from UE. - // ASN_STRUCT_FREE(asn_DEF_MeasResults, p->meas); - // /* Free the params. */ - // free(p); - // return 0; - // } - - - /* Check here whether trigger is registered in agent and then proceed. - */ - // if (em_has_trigger(mod_id, ctxt->t_id, RRC_MEAS_TRIGGER) == 0) { - - // flexran_RRC_meas_reconf(p->rnti, -1, p->meas->measId, NULL, NULL); - // /* Trigger does not exist in agent so remove from wrapper as well. */ - // if (rrc_meas_rem_trigg(ctxt) < 0) { - // goto error; - // } - // } - - - - - /* Set the RNTI of the UE. */ - // repl->rnti = p->rnti; - /* Set the request status. */ - // if (p->reconfig_success == 0) { - // repl->status = STATS_REQ_STATUS__SREQS_FAILURE; - // goto error; - // } - /* Successful outcome. */ - // repl->status = STATS_REQ_STATUS__SREQS_SUCCESS; - /* Set the measurement ID of measurement. */ - // repl->has_measid = 1; - // repl->measid = measResults->measId; - /* Fill the Primary Cell RSRP and RSRQ. */ - // repl->has_pcell_rsrp = 1; - // repl->has_pcell_rsrq = 1; - // #ifdef Rel10 - // repl->has_pcell_rsrp = 1; - // repl->has_pcell_rsrq = 1; - // repl->pcell_rsrp = measResults2->measResultPCell.rsrpResult - 140; - // repl->pcell_rsrq = (measResults2->measResultPCell.rsrqResult)/2 - 20; - - ue_report = malloc(sizeof(Protocol__FlexUeStatsReport *) * 1); - if (ue_report == NULL) - goto error; - - for (i = 0; i < 1; i++) { - - ue_report[i] = malloc(sizeof(Protocol__FlexUeStatsReport)); - if(ue_report[i] == NULL) - goto error; - protocol__flex_ue_stats_report__init(ue_report[i]); - ue_report[i]->rnti = flexran_get_ue_crnti(mod_id, 0); - ue_report[i]->has_rnti = 1; - ue_report[i]->flags = 65536; - ue_report[i]->has_flags = 1; - - } - - cell_report = malloc(sizeof(Protocol__FlexCellStatsReport *) * 1); - if (cell_report == NULL) - goto error; - - for (i = 0; i < 1; i++) { - - cell_report[i] = malloc(sizeof(Protocol__FlexCellStatsReport)); - if(cell_report[i] == NULL) - goto error; - - protocol__flex_cell_stats_report__init(cell_report[i]); - cell_report[i]->carrier_index = 0; //report_config->cc_report_type[i].cc_id; - cell_report[i]->has_carrier_index = 1; - cell_report[i]->flags = 0; // report_config->cc_report_type[i].cc_report_flags; - cell_report[i]->has_flags = 1; - } - - - Protocol__FlexRrcMeasurements *rrc_measurements; - rrc_measurements = malloc(sizeof(Protocol__FlexRrcMeasurements)); - if (rrc_measurements == NULL) - goto error; - protocol__flex_rrc_measurements__init(rrc_measurements); - - rrc_measurements->measid = measResults->measId; - rrc_measurements->has_measid = 1; - - rrc_measurements->pcell_rsrp = measResults->measResultPCell.rsrpResult - 140; - rrc_measurements->has_pcell_rsrp = 1; - - rrc_measurements->pcell_rsrq = (measResults->measResultPCell.rsrqResult)/2 - 20; - rrc_measurements->has_pcell_rsrq = 1 ; - - ue_report[0]->rrc_measurements = rrc_measurements; - - - - - - // #else - // repl->has_pcell_rsrp = 1; - // repl->has_pcell_rsrq = 1; - // repl->pcell_rsrp = RSRP_meas_mapping[meas-> - // measResultServCell.rsrpResult]; - // repl->pcell_rsrq = RSRQ_meas_mapping[meas-> - // measResultServCell.rsrqResult]; - // #endif - - // repl->neigh_meas = NULL; + for (i = 0; i < num; i++){ + meas_stats[i].rnti = flexran_get_ue_crnti(mod_id, i); + meas_stats[i].meas_id = measResults->measId; + meas_stats[i].rsrp = measResults->measResultPCell.rsrpResult - 140; + meas_stats[i].rsrq = (measResults->measResultPCell.rsrqResult)/2 - 20; + + } + // repl->neigh_meas = NULL; // if (meas->measResultNeighCells != NULL) { // /* @@ -595,34 +447,34 @@ void flexran_trigger_rrc_measurements (mid_t mod_id, MeasResults_t* measResults // free(p); - stats_reply_msg->cell_report = cell_report; + // stats_reply_msg->cell_report = cell_report; - stats_reply_msg->ue_report = ue_report; + // stats_reply_msg->ue_report = ue_report; - msg = malloc(sizeof(Protocol__FlexranMessage)); - if(msg == NULL) - goto error; - protocol__flexran_message__init(msg); - msg->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REPLY_MSG; - msg->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME; - msg->stats_reply_msg = stats_reply_msg; + // msg = malloc(sizeof(Protocol__FlexranMessage)); + // if(msg == NULL) + // goto error; + // protocol__flexran_message__init(msg); + // msg->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REPLY_MSG; + // msg->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME; + // msg->stats_reply_msg = stats_reply_msg; - data = flexran_agent_pack_message(msg, &size); + // data = flexran_agent_pack_message(msg, &size); - if (flexran_agent_msg_send(mod_id, FLEXRAN_AGENT_DEFAULT, data, size, priority)) { + // if (flexran_agent_msg_send(mod_id, FLEXRAN_AGENT_DEFAULT, data, size, priority)) { - err_code = PROTOCOL__FLEXRAN_ERR__MSG_ENQUEUING; - goto error; - } + // err_code = PROTOCOL__FLEXRAN_ERR__MSG_ENQUEUING; + // goto error; + // } - LOG_I(FLEXRAN_AGENT,"RRC Trigger is done \n"); + // LOG_I(FLEXRAN_AGENT,"RRC Trigger is done \n"); return; - error: + // error: - LOG_E(FLEXRAN_AGENT, "Could not send UE state message becasue of %d \n",err_code); + // LOG_E(FLEXRAN_AGENT, "Could not send UE state message becasue of %d \n",err_code); /* Free the measurement report received from UE. */ // ASN_STRUCT_FREE(asn_DEF_MeasResults, p->meas); /* Free the params. */ @@ -631,6 +483,98 @@ void flexran_trigger_rrc_measurements (mid_t mod_id, MeasResults_t* measResults } +int flexran_agent_rrc_stats_reply(mid_t mod_id, + const report_config_t *report_config, + Protocol__FlexUeStatsReport **ue_report, + Protocol__FlexCellStatsReport **cell_report) { + + + // Protocol__FlexHeader *header; + int i, j, k; + // int cc_id = 0; + int enb_id = mod_id; + + /* Allocate memory for list of UE reports */ + if (report_config->nr_ue > 0) { + + for (i = 0; i < report_config->nr_ue; i++) { + + /* Check flag for creation of buffer status report */ + if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RRC_MEASUREMENTS) { + + Protocol__FlexRrcMeasurements *rrc_measurements; + rrc_measurements = malloc(sizeof(Protocol__FlexRrcMeasurements)); + if (rrc_measurements == NULL) + goto error; + protocol__flex_rrc_measurements__init(rrc_measurements); + + if (triggered_rrc){ + rrc_measurements->measid = meas_stats[i].meas_id; + rrc_measurements->has_measid = 1; + + rrc_measurements->pcell_rsrp = meas_stats[i].rsrp; + rrc_measurements->has_pcell_rsrp = 1; + + rrc_measurements->pcell_rsrq = meas_stats[i].rsrq; + rrc_measurements->has_pcell_rsrq = 1 ; + + ue_report[i]->rrc_measurements = rrc_measurements; + // triggered_rrc = false; // To be decided later + } + } + } + } + + /* To be extended for RRC layer */ + // if (report_config->nr_cc > 0) { + + + // // Fill in the Cell reports + // for (i = 0; i < report_config->nr_cc; i++) { + + + // /* Check flag for creation of noise and interference report */ + // if(report_config->cc_report_type[i].cc_report_flags & PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE) { + // // TODO: Fill in the actual noise and interference report for this cell + // Protocol__FlexNoiseInterferenceReport *ni_report; + // ni_report = malloc(sizeof(Protocol__FlexNoiseInterferenceReport)); + // if(ni_report == NULL) + // goto error; + // protocol__flex_noise_interference_report__init(ni_report); + // // Current frame and subframe number + // ni_report->sfn_sf = flexran_get_sfn_sf(enb_id); + // ni_report->has_sfn_sf = 1; + // //TODO:Received interference power in dbm + // ni_report->rip = 0; + // ni_report->has_rip = 1; + // //TODO:Thermal noise power in dbm + // ni_report->tnp = 0; + // ni_report->has_tnp = 1; + + // ni_report->p0_nominal_pucch = flexran_get_p0_nominal_pucch(enb_id, 0); + // ni_report->has_p0_nominal_pucch = 1; + // cell_report[i]->noise_inter_report = ni_report; + // } + // } + + + + + // } + + return 0; + + error: + + if (cell_report != NULL) + free(cell_report); + if (ue_report != NULL) + free(ue_report); + + return -1; +} + + int flexran_agent_register_rrc_xface(mid_t mod_id, AGENT_RRC_xface *xface) { if (rrc_agent_registered[mod_id]) { LOG_E(RRC, "RRC agent for eNB %d is already registered\n", mod_id); diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h index aa210f9d41..ae26b41621 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h @@ -1,31 +1,23 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see . - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr - - Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France. - - *******************************************************************************/ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ /*! \file flexran_agent_rrc.h * \brief FlexRAN agent Control Module RRC header @@ -65,6 +57,10 @@ int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg); /* this is called by RRC as a part of rrc xface . The controller previously requested this*/ void flexran_trigger_rrc_measurements (mid_t mod_id, MeasResults_t *); +/* Statistics reply protocol message constructor and destructor */ +int flexran_agent_rrc_stats_reply(mid_t mod_id, const report_config_t *report_config, Protocol__FlexUeStatsReport **ue_report, Protocol__FlexCellStatsReport **cell_report); +int flexran_agent_rrc_destroy_stats_reply(Protocol__FlexranMessage *msg); + /*Register technology specific interface callbacks*/ int flexran_agent_register_rrc_xface(mid_t mod_id, AGENT_RRC_xface *xface); diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h index ad1375171e..a101bab242 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h @@ -1,31 +1,24 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2016 Eurecom +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see . - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr - - Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France. - - *******************************************************************************/ /*! \file flexran_agent_rrc_defs.h * \brief FlexRAN agent - RRC interface primitives @@ -46,11 +39,24 @@ #define RINGBUFFER_SIZE 100 + +typedef struct +{ + int32_t rnti; + int32_t meas_id; + int32_t rsrp; + int32_t rsrq; + + /*To Be Extended*/ +}rrc_meas_stats; + +/* RRC CMI statistics */ +rrc_meas_stats * meas_stats; + + /* FLEXRAN AGENT-RRC Interface */ typedef struct { - /// Inform the controller about the scheduling requests received during the subframe - //void (*flexran_agent_send_update_rrc_stats)(mid_t mod_id); /// Notify the controller for a state change of a particular UE, by sending the proper /// UE state change message (ACTIVATION, DEACTIVATION, HANDOVER) diff --git a/openair2/ENB_APP/MESSAGES/V2/flexran.proto b/openair2/ENB_APP/MESSAGES/V2/flexran.proto index d79051d201..18eb760cc3 100644 --- a/openair2/ENB_APP/MESSAGES/V2/flexran.proto +++ b/openair2/ENB_APP/MESSAGES/V2/flexran.proto @@ -132,6 +132,7 @@ message flex_enb_config_reply { optional flex_header header = 1; optional uint32 eNB_id = 2; // Unique id to distinguish the eNB repeated flex_cell_config cell_config = 3; + optional uint32 device_spec = 4; } message flex_ue_config_request { diff --git a/openair2/ENB_APP/MESSAGES/V2/stats_common.proto b/openair2/ENB_APP/MESSAGES/V2/stats_common.proto index 0d8a565c06..a7d78841a3 100644 --- a/openair2/ENB_APP/MESSAGES/V2/stats_common.proto +++ b/openair2/ENB_APP/MESSAGES/V2/stats_common.proto @@ -242,3 +242,24 @@ message flex_eutra_ref_signal_meas { optional int32 rsrq = 2; } + +message flex_pdcp_stats { + + optional uint32 pkt_tx = 1; + optional uint32 pkt_tx_bytes = 2; + optional uint32 pkt_tx_sn = 3; + optional uint32 pkt_tx_rate_s = 4; + optional uint32 pkt_tx_throughput_s = 5; + optional uint32 pkt_tx_aiat = 7; + optional uint32 pkt_tx_aiat_s = 8; + + optional uint32 pkt_rx = 9; + optional uint32 pkt_rx_bytes = 10; + optional uint32 pkt_rx_sn = 11; + optional uint32 pkt_rx_rate_s = 12; + optional uint32 pkt_rx_goodput_s = 13; + optional uint32 pkt_rx_aiat = 14; + optional uint32 pkt_rx_aiat_s = 15; + optional uint32 pkt_rx_oo = 16; + } + diff --git a/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto b/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto index 1ddb19722b..8cad6f4fbe 100644 --- a/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto +++ b/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto @@ -47,7 +47,8 @@ message flex_ue_stats_report { optional flex_dl_cqi_report dl_cqi_report = 7; optional flex_paging_buffer_report pbr = 8; optional flex_ul_cqi_report ul_cqi_report = 9; - optional flex_rrc_measurements rrc_measurements = 10; + optional flex_rrc_measurements rrc_measurements = 10; + optional flex_pdcp_stats pdcp_stats = 11; } // @@ -84,6 +85,9 @@ enum flex_ue_stats_type { FLUST_DL_CQI = 16; FLUST_PBS = 32; FLUST_UL_CQI = 64; + + FLUST_PDCP_STATS = 1024; // To be changed // To be extended with more types of stats FLUST_RRC_MEASUREMENTS = 65536; + } diff --git a/openair2/ENB_APP/MESSAGES/V2/time_common.proto b/openair2/ENB_APP/MESSAGES/V2/time_common.proto index 8bd2497443..baf0c0e9ae 100644 --- a/openair2/ENB_APP/MESSAGES/V2/time_common.proto +++ b/openair2/ENB_APP/MESSAGES/V2/time_common.proto @@ -26,5 +26,6 @@ message flex_ul_info { optional uint32 reception_status = 3; optional uint32 tpc = 4; optional uint32 serv_cell_index = 5; + optional uint32 rssi = 6; } diff --git a/openair2/ENB_APP/flexran_agent.c b/openair2/ENB_APP/flexran_agent.c index ec984cfa8b..23ac8f02ac 100644 --- a/openair2/ENB_APP/flexran_agent.c +++ b/openair2/ENB_APP/flexran_agent.c @@ -267,6 +267,9 @@ int flexran_agent_start(mid_t mod_id, const Enb_properties_array_t* enb_properti AGENT_RRC_xface *rrc_agent_xface = (AGENT_RRC_xface *) malloc(sizeof(AGENT_RRC_xface)); flexran_agent_register_rrc_xface(mod_id, rrc_agent_xface); + AGENT_PDCP_xface *pdcp_agent_xface = (AGENT_PDCP_xface *) malloc(sizeof(AGENT_PDCP_xface)); + flexran_agent_register_pdcp_xface(mod_id, pdcp_agent_xface); + /* * initilize a timer */ diff --git a/openair2/ENB_APP/flexran_agent.h b/openair2/ENB_APP/flexran_agent.h index 0ef48e2105..f9205c071f 100644 --- a/openair2/ENB_APP/flexran_agent.h +++ b/openair2/ENB_APP/flexran_agent.h @@ -38,6 +38,7 @@ #include "flexran_agent_ran_api.h" #include "flexran_agent_mac.h" #include "flexran_agent_rrc.h" +#include "flexran_agent_pdcp.h" #include "log.h" #include "assertions.h" diff --git a/openair2/ENB_APP/flexran_agent_defs.h b/openair2/ENB_APP/flexran_agent_defs.h index 0b8822a949..040a8192f6 100644 --- a/openair2/ENB_APP/flexran_agent_defs.h +++ b/openair2/ENB_APP/flexran_agent_defs.h @@ -32,11 +32,16 @@ #include #include #include +#include +#include #include "link_manager.h" #define NUM_MAX_ENB 2 +#define NUM_MAX_DRB 8 +#define NUM_MAX_SRB 3 #define NUM_MAX_UE 2048 +#define DEFAULT_DRB 3 #define DEFAULT_FLEXRAN_AGENT_IPv4_ADDRESS "127.0.0.1" #define DEFAULT_FLEXRAN_AGENT_PORT 2210 #define DEFAULT_FLEXRAN_AGENT_CACHE "/mnt/oai_agent_cache" diff --git a/openair2/ENB_APP/flexran_agent_extern.h b/openair2/ENB_APP/flexran_agent_extern.h index 4df984e1a0..a9af552856 100644 --- a/openair2/ENB_APP/flexran_agent_extern.h +++ b/openair2/ENB_APP/flexran_agent_extern.h @@ -33,6 +33,7 @@ // #include "flexran_agent_defs.h" #include "flexran_agent_mac_defs.h" #include "flexran_agent_rrc_defs.h" +#include "flexran_agent_pdcp_defs.h" //extern msg_context_t shared_ctxt[NUM_MAX_ENB][FLEXRAN_AGENT_MAX]; @@ -51,6 +52,12 @@ extern AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB]; /* Flag indicating whether the VSFs for the RRC control module have been registered */ extern unsigned int rrc_agent_registered[NUM_MAX_ENB]; +/* Control module interface for the communication of the RRC Control Module with the agent */ +extern AGENT_PDCP_xface *agent_pdcp_xface[NUM_MAX_ENB]; + +/* Flag indicating whether the VSFs for the RRC control module have been registered */ +extern unsigned int pdcp_agent_registered[NUM_MAX_ENB]; + /* Requried to know which UEs had a harq updated over some subframe */ extern int harq_pid_updated[NUMBER_OF_UE_MAX][8]; extern int harq_pid_round[NUMBER_OF_UE_MAX][8]; diff --git a/openair2/ENB_APP/flexran_agent_handler.c b/openair2/ENB_APP/flexran_agent_handler.c index fc2ed135c8..6ad0b88975 100644 --- a/openair2/ENB_APP/flexran_agent_handler.c +++ b/openair2/ENB_APP/flexran_agent_handler.c @@ -143,7 +143,7 @@ void * flexran_agent_pack_message(Protocol__FlexranMessage *msg, DevAssert(buffer !=NULL); - LOG_D(FLEXRAN_AGENT,"Serilized the enb mac stats reply (size %d)\n", *size); + LOG_D(FLEXRAN_AGENT,"Serilized the eNB-UE stats reply (size %d)\n", *size); return buffer; @@ -457,7 +457,7 @@ int flexran_agent_stats_reply(mid_t enb_id, xid_t xid, const report_config_t *re } - /* + /* MAC reply split */ @@ -467,7 +467,26 @@ int flexran_agent_stats_reply(mid_t enb_id, xid_t xid, const report_config_t *re goto error; } - + /* + RRC reply split + */ + + if (flexran_agent_rrc_stats_reply(enb_id, report_config, ue_report, cell_report) < 0 ) { + err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; + goto error; + } + + + /* + PDCP reply split + */ + + if (flexran_agent_pdcp_stats_reply(enb_id, report_config, ue_report, cell_report) < 0 ) { + err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; + goto error; + } + + stats_reply_msg->cell_report = cell_report; stats_reply_msg->ue_report = ue_report; diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 0d3145e1d2..01f05b1ba5 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -179,6 +179,17 @@ int flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t chann return rlc_status.bytes_in_buffer; } + +int flexran_get_num_pdus_buffer(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) { + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + uint16_t frame = (uint16_t) flexran_get_current_frame(mod_id); + uint16_t subframe = (uint16_t) flexran_get_current_subframe(mod_id); + mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id, frame, subframe, ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0); + return rlc_status.pdus_in_buffer; +} + + + int flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) { rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); uint16_t frame = (uint16_t) flexran_get_current_frame(mod_id); @@ -1077,6 +1088,85 @@ void flexran_agent_set_operating_frame_type (mid_t mod_id, int cc_id, int frame_ enb_properties->properties[mod_id]->frame_type[cc_id]=frame_type; } +/*********** PDCP *************/ + +/*PDCP num tx pdu status flexRAN*/ +uint32_t flexran_get_pdcp_tx(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + if (mod_id <0 || mod_id> MAX_NUM_CCs || ue_id<0 || ue_id> NUMBER_OF_UE_MAX || lcid<0 || lcid>NB_RB_MAX) + return -1; + return Pdcp_stats_tx[mod_id][ue_id][lcid]; +} + +/*PDCP num tx bytes status flexRAN*/ +uint32_t flexran_get_pdcp_tx_bytes(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_tx_bytes[mod_id][ue_id][lcid]; +} + +/*PDCP number of transmit packet / second status flexRAN*/ +uint32_t flexran_get_pdcp_tx_rate_s(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_tx_rate_s[mod_id][ue_id][lcid]; +} + +/*PDCP throughput (bit/s) status flexRAN*/ +uint32_t flexran_get_pdcp_tx_throughput_s(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_tx_throughput_s[mod_id][ue_id][lcid]; +} + +/*PDCP tx sequence number flexRAN*/ +uint32_t flexran_get_pdcp_tx_sn(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_tx_sn[mod_id][ue_id][lcid]; +} + +/*PDCP tx aggregated packet arrival flexRAN*/ +uint32_t flexran_get_pdcp_tx_aiat(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_tx_aiat[mod_id][ue_id][lcid]; +} + +/*PDCP tx aggregated packet arrival flexRAN*/ +uint32_t flexran_get_pdcp_tx_aiat_s(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_tx_aiat_s[mod_id][ue_id][lcid]; +} + + +/*PDCP num rx pdu status flexRAN*/ +uint32_t flexran_get_pdcp_rx(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_rx[mod_id][ue_id][lcid]; +} + +/*PDCP num rx bytes status flexRAN*/ +uint32_t flexran_get_pdcp_rx_bytes(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_rx_bytes[mod_id][ue_id][lcid]; +} + +/*PDCP number of received packet / second flexRAN*/ +uint32_t flexran_get_pdcp_rx_rate_s(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_rx_rate_s[mod_id][ue_id][lcid]; +} + +/*PDCP gootput (bit/s) status flexRAN*/ +uint32_t flexran_get_pdcp_rx_goodput_s(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_rx_goodput_s[mod_id][ue_id][lcid]; +} + +/*PDCP rx sequence number flexRAN*/ +uint32_t flexran_get_pdcp_rx_sn(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_rx_sn[mod_id][ue_id][lcid]; +} + +/*PDCP rx aggregated packet arrival flexRAN*/ +uint32_t flexran_get_pdcp_rx_aiat(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_rx_aiat[mod_id][ue_id][lcid]; +} + +/*PDCP rx aggregated packet arrival flexRAN*/ +uint32_t flexran_get_pdcp_rx_aiat_s(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_rx_aiat_s[mod_id][ue_id][lcid]; +} + +/*PDCP num of received outoforder pdu status flexRAN*/ +uint32_t flexran_get_pdcp_rx_oo(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_rx_outoforder[mod_id][ue_id][lcid]; +} diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 9f0313c1ca..4d84251608 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -39,6 +39,7 @@ #include "LAYER2/MAC/extern.h" #include "LAYER2/RLC/rlc.h" #include "SCHED/defs.h" +#include "pdcp.h" #include "RRC/LITE/extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" #include "RRC/LITE/rrc_eNB_UE_context.h" @@ -91,6 +92,9 @@ int flexran_get_ue_wcqi (mid_t mod_id, mid_t ue_id); /* Get the transmission queue size for a UE with a channel_id logical channel id */ int flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id); +/*Get number of pdus in RLC buffer*/ +int flexran_get_num_pdus_buffer(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id); + /* Get the head of line delay for a UE with a channel_id logical channel id */ int flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id); @@ -334,3 +338,54 @@ void flexran_agent_set_operating_frame_type (mid_t mod_id, int cc_id, int frame_ /*RRC status flexRAN*/ int flexran_get_rrc_status(const mid_t mod_id, const rnti_t rntiP); + + +/***************************** PDCP ***********************/ + +/*PDCP num tx pdu status flexRAN*/ +uint32_t flexran_get_pdcp_tx(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP num tx bytes status flexRAN*/ +uint32_t flexran_get_pdcp_tx_bytes(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP number of transmit packet / second status flexRAN*/ +uint32_t flexran_get_pdcp_tx_rate_s(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP throughput (bit/s) status flexRAN*/ +uint32_t flexran_get_pdcp_tx_throughput_s(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP tx sequence number flexRAN*/ +uint32_t flexran_get_pdcp_tx_sn(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP tx aggregated packet arrival flexRAN*/ +uint32_t flexran_get_pdcp_tx_aiat(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP tx aggregated packet arrival per second flexRAN*/ +uint32_t flexran_get_pdcp_tx_aiat_s(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + + +/*PDCP num rx pdu status flexRAN*/ +uint32_t flexran_get_pdcp_rx(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP num rx bytes status flexRAN*/ +uint32_t flexran_get_pdcp_rx_bytes(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP number of received packet / second flexRAN*/ +uint32_t flexran_get_pdcp_rx_rate_s(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP gootput (bit/s) status flexRAN*/ +uint32_t flexran_get_pdcp_rx_goodput_s(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP rx sequence number flexRAN*/ +uint32_t flexran_get_pdcp_rx_sn(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP rx aggregated packet arrival flexRAN*/ +uint32_t flexran_get_pdcp_rx_aiat(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP rx aggregated packet arrival per second flexRAN*/ +uint32_t flexran_get_pdcp_rx_aiat_s(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + +/*PDCP num of received outoforder pdu status flexRAN*/ +uint32_t flexran_get_pdcp_rx_oo(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); + + diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 8dad83a90a..397a194edf 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -69,6 +69,7 @@ extern int otg_enabled; #endif + //----------------------------------------------------------------------------- /* * If PDCP_UNIT_TEST is set here then data flow between PDCP and RLC is broken @@ -102,6 +103,8 @@ boolean_t pdcp_data_req( hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; + uint8_t rb_offset= (srb_flagP == 0) ? DTCH -1 : 0; + uint16_t pdcp_uid=0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_IN); CHECK_CTXT_ARGS(ctxt_pP); @@ -152,7 +155,7 @@ boolean_t pdcp_data_req( ctxt_pP->configured=TRUE; } - if (ctxt_pP->enb_flag == ENB_FLAG_NO) { + if (ctxt_pP->enb_flag == ENB_FLAG_YES) { start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].data_req); } else { start_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_req); @@ -223,7 +226,7 @@ boolean_t pdcp_data_req( LOG_E(PDCP, PROTOCOL_PDCP_CTXT_FMT" Cannot fill PDU buffer with relevant header fields!\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p)); - if (ctxt_pP->enb_flag == ENB_FLAG_NO) { + if (ctxt_pP->enb_flag == ENB_FLAG_YES) { stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].data_req); } else { stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_req); @@ -241,8 +244,9 @@ boolean_t pdcp_data_req( if (pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer((unsigned char*)pdcp_pdu_p->data, &pdu_header) == FALSE) { LOG_E(PDCP, PROTOCOL_PDCP_CTXT_FMT" Cannot fill PDU buffer with relevant header fields!\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p)); + + if (ctxt_pP->enb_flag == ENB_FLAG_YES) { - if (ctxt_pP->enb_flag == ENB_FLAG_NO) { stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].data_req); } else { stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_req); @@ -264,7 +268,7 @@ boolean_t pdcp_data_req( free_mem_block(pdcp_pdu_p, __func__); - if (ctxt_pP->enb_flag == ENB_FLAG_NO) { + if (ctxt_pP->enb_flag == ENB_FLAG_YES) { stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].data_req); } else { stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_req); @@ -292,7 +296,7 @@ boolean_t pdcp_data_req( (((pdcp_p->cipheringAlgorithm) != 0) || ((pdcp_p->integrityProtAlgorithm) != 0))) { - if (ctxt_pP->enb_flag == ENB_FLAG_NO) { + if (ctxt_pP->enb_flag == ENB_FLAG_YES) { start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].apply_security); } else { start_meas(&UE_pdcp_stats[ctxt_pP->module_id].apply_security); @@ -387,7 +391,7 @@ boolean_t pdcp_data_req( break; } - if (ctxt_pP->enb_flag == ENB_FLAG_NO) { + if (ctxt_pP->enb_flag == ENB_FLAG_YES) { stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].data_req); } else { stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_req); @@ -397,16 +401,45 @@ boolean_t pdcp_data_req( * Control arrives here only if rlc_data_req() returns RLC_OP_STATUS_OK * so we return TRUE afterwards */ - /* - if (rb_id>=DTCH) { - if (ctxt_pP->enb_flag == 1) { - Pdcp_stats_tx[module_id][(rb_id & RAB_OFFSET2 )>> RAB_SHIFT2][(rb_id & RAB_OFFSET)-DTCH]++; - Pdcp_stats_tx_bytes[module_id][(rb_id & RAB_OFFSET2 )>> RAB_SHIFT2][(rb_id & RAB_OFFSET)-DTCH] += sdu_buffer_size; - } else { - Pdcp_stats_tx[module_id][(rb_id & RAB_OFFSET2 )>> RAB_SHIFT2][(rb_id & RAB_OFFSET)-DTCH]++; - Pdcp_stats_tx_bytes[module_id][(rb_id & RAB_OFFSET2 )>> RAB_SHIFT2][(rb_id & RAB_OFFSET)-DTCH] += sdu_buffer_size; - } - }*/ + + for (pdcp_uid=0; pdcp_uid< NUMBER_OF_UE_MAX;pdcp_uid++){ + if (pdcp_p->rnti[pdcp_uid] == ctxt_pP->rnti ) + break; + } + + //LOG_I(PDCP,"ueid %d lcid %d tx seq num %d\n", pdcp_uid, rb_idP+rb_offset, current_sn); + Pdcp_stats_tx[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; + Pdcp_stats_tx_bytes[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=sdu_buffer_sizeP; + Pdcp_stats_tx_sn[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=current_sn; + + if (Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset] < pdcp_frame *10 + pdcp_subframe) { + Pdcp_stats_tx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_frame *10 + pdcp_subframe - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + Pdcp_stats_tx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_frame *10 + pdcp_subframe - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + } + else { + Pdcp_stats_tx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (1024 + pdcp_frame *10 + pdcp_subframe - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + Pdcp_stats_tx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (1024 + pdcp_frame *10 + pdcp_subframe - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + } + + + Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=ctxt_pP->frame*10+ctxt_pP->subframe; + + if (pdcp_frame % 100 == 0 ) { + Pdcp_stats_tx_rate_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]= Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]; + Pdcp_stats_tx_throughput_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=Pdcp_stats_tx_bytes[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]*8/1000; + Pdcp_stats_tx_aiat_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=Pdcp_stats_tx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]; + + Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=0; + Pdcp_stats_tx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=0; + Pdcp_stats_tx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=0; + }else { + Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; + Pdcp_stats_tx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=sdu_buffer_sizeP; + + } + + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_OUT); return ret; @@ -436,6 +469,9 @@ pdcp_data_ind( boolean_t packet_forwarded = FALSE; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; + uint8_t rb_offset= (srb_flagP == 0) ? DTCH -1 :0; + uint16_t pdcp_uid=0; + uint8_t oo_flag=0; #if defined(LINK_ENB_PDCP_TO_GTPV1U) MessageDef *message_p = NULL; uint8_t *gtpu_buffer_p = NULL; @@ -590,6 +626,7 @@ pdcp_data_ind( else LOG_D(PDCP, "Passing piggybacked SDU to RRC ...\n");*/ } else { + oo_flag=1; LOG_W(PDCP, PROTOCOL_PDCP_CTXT_FMT"Incoming PDU has an unexpected sequence number (%d), RX window synchronisation have probably been lost!\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p), @@ -789,6 +826,53 @@ pdcp_data_ind( GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rab_id = rb_id + 4; itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p); packet_forwarded = TRUE; + + /* Print octets of incoming data in hexadecimal form */ + LOG_D(PDCP, "Following content has been received from RLC (%d,%d)(PDCP header has already been removed):\n", + sdu_buffer_sizeP - payload_offset + (int)sizeof(pdcp_data_ind_header_t), + sdu_buffer_sizeP - payload_offset); + //util_print_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset); + //util_flush_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset); + + /* + * Update PDCP statistics + * XXX Following two actions are identical, is there a merge error? + */ + + for (pdcp_uid=0; pdcp_uid< NUMBER_OF_UE_MAX;pdcp_uid++){ + if (pdcp_p->rnti[pdcp_uid] == ctxt_pP->rnti ) + break; + } + + Pdcp_stats_rx[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; + Pdcp_stats_rx_bytes[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=sdu_buffer_sizeP - payload_offset; + + Pdcp_stats_rx_sn[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=sequence_number; + + if (oo_flag == 1 ) + Pdcp_stats_rx_outoforder[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; + + if (Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset] < pdcp_frame * 10 + pdcp_subframe) { + Pdcp_stats_rx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_frame *10 + pdcp_subframe - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(pdcp_frame *10 + pdcp_subframe - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + } else { + Pdcp_stats_rx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (1024 +pdcp_frame * 10 + pdcp_subframe - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(1024 +pdcp_frame * 10 + pdcp_subframe - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + } + Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=pdcp_frame * 10 +pdcp_subframe; + + if (pdcp_frame % 102 == 0) { + Pdcp_stats_rx_rate_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]; + Pdcp_stats_rx_goodput_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=Pdcp_stats_rx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]*8/1023; + Pdcp_stats_rx_aiat_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]= Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]; + + Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=0; + Pdcp_stats_rx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=0; + Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=0; + }else { + Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; + Pdcp_stats_rx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(sdu_buffer_sizeP - payload_offset); + } } #else @@ -842,25 +926,8 @@ pdcp_data_ind( sdu_buffer_sizeP - payload_offset); list_add_tail_eurecom (new_sdu_p, sdu_list_p); - /* Print octets of incoming data in hexadecimal form */ - LOG_D(PDCP, "Following content has been received from RLC (%d,%d)(PDCP header has already been removed):\n", - sdu_buffer_sizeP - payload_offset + (int)sizeof(pdcp_data_ind_header_t), - sdu_buffer_sizeP - payload_offset); - //util_print_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset); - //util_flush_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset); - - /* - * Update PDCP statistics - * XXX Following two actions are identical, is there a merge error? - */ - - /*if (ctxt_pP->enb_flag == 1) { - Pdcp_stats_rx[module_id][(rb_idP & RAB_OFFSET2) >> RAB_SHIFT2][(rb_idP & RAB_OFFSET) - DTCH]++; - Pdcp_stats_rx_bytes[module_id][(rb_idP & RAB_OFFSET2) >> RAB_SHIFT2][(rb_idP & RAB_OFFSET) - DTCH] += sdu_buffer_sizeP; - } else { - Pdcp_stats_rx[module_id][(rb_idP & RAB_OFFSET2) >> RAB_SHIFT2][(rb_idP & RAB_OFFSET) - DTCH]++; - Pdcp_stats_rx_bytes[module_id][(rb_idP & RAB_OFFSET2) >> RAB_SHIFT2][(rb_idP & RAB_OFFSET) - DTCH] += sdu_buffer_sizeP; - }*/ + + } } @@ -891,6 +958,9 @@ pdcp_run ( ) //----------------------------------------------------------------------------- { + + pdcp_frame =ctxt_pP->frame; + pdcp_subframe= ctxt_pP->subframe; #if defined(ENABLE_ITTI) MessageDef *msg_p; const char *msg_name; @@ -1139,7 +1209,7 @@ rrc_pdcp_config_asn1_req ( return TRUE; } else { - LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_ADD key 0x%"PRIx64"\n", + LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_ADD key 0x%"PRIx64"\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p), key); } @@ -1470,12 +1540,19 @@ pdcp_config_req_asn1 ( uint8_t *const kUPenc_pP) //----------------------------------------------------------------------------- { - + int i; switch (actionP) { case CONFIG_ACTION_ADD: DevAssert(pdcp_pP != NULL); if (ctxt_pP->enb_flag == ENB_FLAG_YES) { pdcp_pP->is_ue = FALSE; + for (i=0; i < NUMBER_OF_UE_MAX; i++) { + if (pdcp_pP->rnti[i] != 0 ) continue ; // skip active ues + pdcp_pP->rnti[i]=ctxt_pP->rnti; + pdcp_pP->uid[i]=i; + pdcp_num_ues++; + break; + } //pdcp_eNB_UE_instance_to_rnti[ctxtP->module_id] = ctxt_pP->rnti; pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] = ctxt_pP->rnti; //pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % NUMBER_OF_UE_MAX; @@ -1575,6 +1652,18 @@ pdcp_config_req_asn1 ( lc_idP, rb_idP); + if (ctxt_pP->enb_flag == ENB_FLAG_YES) { + + for (i=0; i < NUMBER_OF_UE_MAX; i++) { + if (pdcp_pP->rnti[i] == ctxt_pP->rnti ) { + pdcp_pP->rnti[i]=0; + pdcp_pP->uid[i]=0; + pdcp_num_ues--; + break; + } + } + } + /* Security keys */ if (pdcp_pP->kUPenc != NULL) { free(pdcp_pP->kUPenc); @@ -1826,13 +1915,14 @@ rrc_pdcp_config_req ( //----------------------------------------------------------------------------- -// TODO PDCP module initialization code might be removed + int pdcp_module_init ( void ) //----------------------------------------------------------------------------- { + #ifdef PDCP_USE_RT_FIFO int ret; @@ -1952,14 +2042,27 @@ void pdcp_layer_init(void) pdcp_input_sdu_remaining_size_to_read=0; memset(Pdcp_stats_tx, 0, sizeof(Pdcp_stats_tx)); + memset(Pdcp_stats_tx_s, 0, sizeof(Pdcp_stats_tx_s)); memset(Pdcp_stats_tx_bytes, 0, sizeof(Pdcp_stats_tx_bytes)); - memset(Pdcp_stats_tx_bytes_last, 0, sizeof(Pdcp_stats_tx_bytes_last)); - memset(Pdcp_stats_tx_rate, 0, sizeof(Pdcp_stats_tx_rate)); + memset(Pdcp_stats_tx_bytes_s, 0, sizeof(Pdcp_stats_tx_bytes_s)); + memset(Pdcp_stats_tx_rate_s, 0, sizeof(Pdcp_stats_tx_rate_s)); + memset(Pdcp_stats_tx_sn, 0, sizeof(Pdcp_stats_tx_sn)); + memset(Pdcp_stats_tx_throughput_s, 0, sizeof(Pdcp_stats_tx_throughput_s)); + memset(Pdcp_stats_tx_aiat, 0, sizeof(Pdcp_stats_tx_aiat)); + memset(Pdcp_stats_tx_iat, 0, sizeof(Pdcp_stats_tx_iat)); + memset(Pdcp_stats_rx, 0, sizeof(Pdcp_stats_rx)); + memset(Pdcp_stats_rx_s, 0, sizeof(Pdcp_stats_rx_s)); memset(Pdcp_stats_rx_bytes, 0, sizeof(Pdcp_stats_rx_bytes)); - memset(Pdcp_stats_rx_bytes_last, 0, sizeof(Pdcp_stats_rx_bytes_last)); - memset(Pdcp_stats_rx_rate, 0, sizeof(Pdcp_stats_rx_rate)); + memset(Pdcp_stats_rx_bytes_s, 0, sizeof(Pdcp_stats_rx_bytes_s)); + memset(Pdcp_stats_rx_rate_s, 0, sizeof(Pdcp_stats_rx_rate_s)); + memset(Pdcp_stats_rx_sn, 0, sizeof(Pdcp_stats_rx_sn)); + memset(Pdcp_stats_rx_goodput_s, 0, sizeof(Pdcp_stats_rx_goodput_s)); + memset(Pdcp_stats_rx_aiat, 0, sizeof(Pdcp_stats_rx_aiat)); + memset(Pdcp_stats_rx_iat, 0, sizeof(Pdcp_stats_rx_iat)); + memset(Pdcp_stats_rx_outoforder, 0, sizeof(Pdcp_stats_rx_outoforder)); + } //----------------------------------------------------------------------------- diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index 94084273d1..fb3e02b299 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -94,15 +94,41 @@ extern int pdcp_instance_cnt; int init_pdcp_thread(void); void cleanup_pdcp_thread(void); +public_pdcp(frame_t pdcp_frame); +public_pdcp(sub_frame_t pdcp_subframe); +public_pdcp(uint16_t pdcp_num_ues); + + +public_pdcp(uint32_t Pdcp_stats_tx_bytes[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_bytes_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_sn[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_rate_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_throughput_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_aiat[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_aiat_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_aiat_tmp_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_iat[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); + +public_pdcp(uint32_t Pdcp_stats_rx[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_bytes[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_bytes_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_sn[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_rate_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_goodput_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_aiat[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_aiat_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_aiat_tmp_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_iat[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_outoforder[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); + + +/*Packet Probing for agent PDCP*/ +//public_pdcp(uint64_t *pdcp_packet_counter); +//public_pdcp(uint64_t *pdcp_size_packet); -public_pdcp(unsigned int Pdcp_stats_tx[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]); -public_pdcp(unsigned int Pdcp_stats_tx_bytes[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]); -public_pdcp(unsigned int Pdcp_stats_tx_bytes_last[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]); -public_pdcp(unsigned int Pdcp_stats_tx_rate[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]); -public_pdcp(unsigned int Pdcp_stats_rx[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]); -public_pdcp(unsigned int Pdcp_stats_rx_bytes[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]); -public_pdcp(unsigned int Pdcp_stats_rx_bytes_last[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]); -public_pdcp(unsigned int Pdcp_stats_rx_rate[NB_MODULES_MAX][NB_CNX_CH][NB_RAB_MAX]); typedef struct pdcp_stats_s { time_stats_t pdcp_run; @@ -125,6 +151,10 @@ typedef struct pdcp_s { boolean_t is_ue; boolean_t is_srb; + // used for eNB stats generation + uint16_t uid[NUMBER_OF_UE_MAX]; // local to pdcp + rnti_t rnti[NUMBER_OF_UE_MAX]; + /* Configured security algorithms */ uint8_t cipheringAlgorithm; uint8_t integrityProtAlgorithm; From 5e20c970e991ca0854bbf0c0754f4b135c0a8ed9 Mon Sep 17 00:00:00 2001 From: shahab Date: Sat, 9 Dec 2017 17:41:06 +0100 Subject: [PATCH 037/195] warning decreasing --- .../CONTROL_MODULES/PDCP/flexran_agent_pdcp.c | 2 +- .../CONTROL_MODULES/RRC/flexran_agent_rrc.c | 8 +++----- openair2/ENB_APP/flexran_agent_async.c | 4 ++-- openair2/ENB_APP/flexran_agent_common_internal.c | 7 ++----- openair2/ENB_APP/flexran_agent_handler.c | 2 +- openair2/ENB_APP/flexran_agent_net_comm.c | 8 ++++---- openair2/ENB_APP/flexran_agent_ran_api.c | 14 ++++---------- openair2/UTIL/ASYNC_IF/ringbuffer_queue.c | 2 +- openair2/UTIL/ASYNC_IF/ringbuffer_queue.h | 2 +- 9 files changed, 19 insertions(+), 30 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c index ecc40cd89a..4aa2e691b9 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c +++ b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c @@ -77,7 +77,7 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id, // Protocol__FlexHeader *header; - int i, j, k; + int i; // int cc_id = 0; diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c index e70d2a3d97..587ac8c263 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c @@ -262,11 +262,11 @@ int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg) { /* this is called by RRC as a part of rrc xface . The controller previously requested this*/ void flexran_trigger_rrc_measurements (mid_t mod_id, MeasResults_t* measResults) { - int i, m, k; + int i; // int priority = 0; // Warning Preventing // void *data; // int size; - err_code_t err_code = -100; + // err_code_t err_code = -100; triggered_rrc = true; int num; @@ -490,9 +490,7 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, // Protocol__FlexHeader *header; - int i, j, k; - // int cc_id = 0; - int enb_id = mod_id; + int i; /* Allocate memory for list of UE reports */ if (report_config->nr_ue > 0) { diff --git a/openair2/ENB_APP/flexran_agent_async.c b/openair2/ENB_APP/flexran_agent_async.c index 978b44929d..7b7bb89d6c 100644 --- a/openair2/ENB_APP/flexran_agent_async.c +++ b/openair2/ENB_APP/flexran_agent_async.c @@ -68,12 +68,12 @@ flexran_agent_async_channel_t * flexran_agent_async_channel_info(mid_t mod_id, c error: LOG_I(FLEXRAN_AGENT,"there was an error\n"); - return 1; + return NULL; } int flexran_agent_async_msg_send(void *data, int size, int priority, void *channel_info) { flexran_agent_async_channel_t *channel; - channel = (flexran_agent_channel_t *)channel_info; + channel = (flexran_agent_async_channel_t *)channel_info; return message_put(channel->send_queue, data, size, priority); } diff --git a/openair2/ENB_APP/flexran_agent_common_internal.c b/openair2/ENB_APP/flexran_agent_common_internal.c index fca73894c5..839fb4c784 100644 --- a/openair2/ENB_APP/flexran_agent_common_internal.c +++ b/openair2/ENB_APP/flexran_agent_common_internal.c @@ -129,10 +129,8 @@ int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy int parse_enb_id(mid_t mod_id, yaml_parser_t *parser) { yaml_event_t event; - void *param; char *endptr; - int is_array = 0; - int i = 0; + // int is_array; int done = 0; int mapping_started = 0; @@ -145,7 +143,7 @@ int parse_enb_id(mid_t mod_id, yaml_parser_t *parser) { switch (event.type) { // We are expecting a mapping of parameters case YAML_SEQUENCE_START_EVENT: - is_array = 1; + // is_array = 1; break; case YAML_MAPPING_START_EVENT: LOG_D(ENB_APP, "The mapping of the parameters started\n"); @@ -193,7 +191,6 @@ int parse_enb_id(mid_t mod_id, yaml_parser_t *parser) { int parse_enb_config_parameters(mid_t mod_id, yaml_parser_t *parser) { yaml_event_t event; - void *param; char *endptr; int done = 0; diff --git a/openair2/ENB_APP/flexran_agent_handler.c b/openair2/ENB_APP/flexran_agent_handler.c index 6ad0b88975..2a36b3e5c8 100644 --- a/openair2/ENB_APP/flexran_agent_handler.c +++ b/openair2/ENB_APP/flexran_agent_handler.c @@ -30,6 +30,7 @@ #include "flexran_agent_common.h" #include "flexran_agent_mac.h" #include "flexran_agent_rrc.h" +#include "flexran_agent_pdcp.h" #include "flexran_agent_timer.h" #include "flexran_agent_ran_api.h" #include "log.h" @@ -97,7 +98,6 @@ Protocol__FlexranMessage* flexran_agent_handle_message (mid_t mod_id, err_code= PROTOCOL__FLEXRAN_ERR__MSG_DECODING; goto error; } - // printf("==================> %d %d \n", decoded_message->msg_case, decoded_message->msg_dir); if ((decoded_message->msg_case > sizeof(agent_messages_callback) / (3 * sizeof(flexran_agent_message_decoded_callback))) || (decoded_message->msg_dir > PROTOCOL__FLEXRAN_DIRECTION__UNSUCCESSFUL_OUTCOME)){ err_code= PROTOCOL__FLEXRAN_ERR__MSG_NOT_HANDLED; diff --git a/openair2/ENB_APP/flexran_agent_net_comm.c b/openair2/ENB_APP/flexran_agent_net_comm.c index f8e350d6a9..d801bbdda5 100644 --- a/openair2/ENB_APP/flexran_agent_net_comm.c +++ b/openair2/ENB_APP/flexran_agent_net_comm.c @@ -141,9 +141,9 @@ int flexran_agent_destroy_channel(int channel_id) { for (i = 0; i < NUM_MAX_ENB; i++) { for (j = 0; j < FLEXRAN_AGENT_MAX; j++) { if (agent_channel[i][j] != NULL) { - if (agent_channel[i][j]->channel_id == e->channel_id) { - agent_channel[i][j] == NULL; - } + if (agent_channel[i][j]->channel_id == e->channel_id) { + free(agent_channel[i][j]); + } } } } @@ -164,7 +164,7 @@ err_code_t flexran_agent_init_channel_container(void) { for (i = 0; i < NUM_MAX_ENB; i++) { for (j = 0; j < FLEXRAN_AGENT_MAX; j++) { - agent_channel[i][j] == NULL; + agent_channel[i][j] = malloc(sizeof(flexran_agent_channel_t)); } } diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 01f05b1ba5..280b9807fd 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -38,6 +38,7 @@ void * enb[NUM_MAX_ENB]; void * enb_ue[NUM_MAX_ENB]; void * enb_rrc[NUM_MAX_ENB]; +Enb_properties_array_t* enb_properties; void flexran_set_enb_vars(mid_t mod_id, ran_name_t ran){ @@ -47,10 +48,12 @@ void flexran_set_enb_vars(mid_t mod_id, ran_name_t ran){ enb[mod_id] = NULL; enb_ue[mod_id] = NULL; enb_rrc[mod_id] = NULL; + enb_properties = NULL; }else{ enb[mod_id] = (void *)&eNB_mac_inst[mod_id]; enb_ue[mod_id] = (void *)&eNB_mac_inst[mod_id].UE_list; enb_rrc[mod_id] = (void *)&eNB_rrc_inst[mod_id]; + enb_properties = (Enb_properties_array_t *) enb_config_get(); } break; default : @@ -1039,52 +1042,43 @@ int flexran_get_antenna_ports(mid_t mod_id, int CC_id){ uint32_t flexran_agent_get_operating_dl_freq (mid_t mod_id, int cc_id) { - const Enb_properties_array_t* enb_properties = enb_config_get(); + return (enb_properties->properties[mod_id]->downlink_frequency[cc_id] / 1000000); } uint32_t flexran_agent_get_operating_ul_freq (mid_t mod_id, int cc_id) { - const Enb_properties_array_t* enb_properties = enb_config_get(); return ((enb_properties->properties[mod_id]->downlink_frequency[cc_id] + enb_properties->properties[0]->uplink_frequency_offset[cc_id]) / 1000000); } int flexran_agent_get_operating_eutra_band (mid_t mod_id, int cc_id) { - const Enb_properties_array_t* enb_properties = enb_config_get(); return enb_properties->properties[mod_id]->eutra_band[cc_id]; } int flexran_agent_get_operating_pdsch_refpower (mid_t mod_id, int cc_id) { - const Enb_properties_array_t* enb_properties = enb_config_get(); return enb_properties->properties[mod_id]->pdsch_referenceSignalPower[cc_id]; } int flexran_agent_get_operating_pusch_p0 (mid_t mod_id, int cc_id) { - const Enb_properties_array_t* enb_properties = enb_config_get(); return enb_properties->properties[mod_id]->pusch_p0_Nominal[cc_id]; } void flexran_agent_set_operating_dl_freq (mid_t mod_id, int cc_id, uint32_t dl_freq_mhz) { - Enb_properties_array_t* enb_properties = enb_config_get(); enb_properties->properties[mod_id]->downlink_frequency[cc_id]=dl_freq_mhz * 1000000; /*printf("[ENB_APP] mod id %d ccid %d dl freq %d/%d\n", mod_id, cc_id, dl_freq_mhz, enb_properties->properties[mod_id]->downlink_frequency[cc_id]); */ } void flexran_agent_set_operating_ul_freq (mid_t mod_id, int cc_id, int32_t ul_freq_offset_mhz) { - Enb_properties_array_t* enb_properties = enb_config_get(); enb_properties->properties[mod_id]->uplink_frequency_offset[cc_id]=ul_freq_offset_mhz * 1000000; } //TBD void flexran_agent_set_operating_eutra_band (mid_t mod_id, int cc_id) { - Enb_properties_array_t* enb_properties = enb_config_get(); enb_properties->properties[mod_id]->eutra_band[cc_id]=7; } void flexran_agent_set_operating_bandwidth (mid_t mod_id, int cc_id, int bandwidth) { - Enb_properties_array_t* enb_properties = enb_config_get(); enb_properties->properties[mod_id]->N_RB_DL[cc_id]=bandwidth; } void flexran_agent_set_operating_frame_type (mid_t mod_id, int cc_id, int frame_type) { - Enb_properties_array_t* enb_properties = enb_config_get(); enb_properties->properties[mod_id]->frame_type[cc_id]=frame_type; } diff --git a/openair2/UTIL/ASYNC_IF/ringbuffer_queue.c b/openair2/UTIL/ASYNC_IF/ringbuffer_queue.c index 047e3f716c..0c4bb1dfbb 100644 --- a/openair2/UTIL/ASYNC_IF/ringbuffer_queue.c +++ b/openair2/UTIL/ASYNC_IF/ringbuffer_queue.c @@ -117,7 +117,7 @@ int message_get(message_queue_t *queue, void **data, int *size, int *priority) { return 0; } -message_queue_t destroy_message_queue(message_queue_t *queue) { +void destroy_message_queue(message_queue_t *queue) { struct lfds700_misc_prng_state ls; message_t *m; diff --git a/openair2/UTIL/ASYNC_IF/ringbuffer_queue.h b/openair2/UTIL/ASYNC_IF/ringbuffer_queue.h index 7dc4637404..bdc5adce99 100644 --- a/openair2/UTIL/ASYNC_IF/ringbuffer_queue.h +++ b/openair2/UTIL/ASYNC_IF/ringbuffer_queue.h @@ -48,6 +48,6 @@ typedef struct { message_queue_t * new_message_queue(int size); int message_put(message_queue_t *queue, void *data, int size, int priority); int message_get(message_queue_t *queue, void **data, int *size, int *priority); -message_queue_t destroy_message_queue(message_queue_t *queue); +void destroy_message_queue(message_queue_t *queue); #endif /* RINGBUFFER_QUEUE_H */ From cd74f4d61b20cfacb71a10cea80ba24f6ad85626 Mon Sep 17 00:00:00 2001 From: shahab SHARIAT BAGHERI Date: Sun, 10 Dec 2017 16:19:27 +0100 Subject: [PATCH 038/195] Message balance --- .../ENB_APP/MESSAGES/V2/config_messages.proto | 2 +- .../MESSAGES/V2/control_delegation.proto | 2 +- .../MESSAGES/V2/controller_commands.proto | 8 +- openair2/ENB_APP/MESSAGES/V2/flexran.proto | 22 +--- openair2/ENB_APP/MESSAGES/V2/header.proto | 3 +- .../ENB_APP/MESSAGES/V2/mac_primitives.proto | 37 ------ .../ENB_APP/MESSAGES/V2/stats_common.proto | 106 +++++++++--------- .../ENB_APP/MESSAGES/V2/stats_messages.proto | 12 +- .../ENB_APP/MESSAGES/V2/time_common.proto | 4 +- openair2/ENB_APP/flexran_agent_common.c | 8 -- 10 files changed, 70 insertions(+), 134 deletions(-) diff --git a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto index 657f362873..995865f1ab 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto @@ -38,7 +38,7 @@ message flex_cell_config { optional uint32 srs_mac_up_pts = 32; // Boolean value. See TS 36.211, section 5.5.3.2. TDD only optional uint32 enable_64QAM = 33; // One of the FLEQ_* enum values optional uint32 carrier_index = 34; // Carrier component index - optional uint32 dl_freq = 35; // operating downlink frequency + optional uint32 dl_freq = 35; // operating downlink frequency optional uint32 ul_freq = 36; // operating uplink frequency optional uint32 eutra_band= 37; // operating band optional int32 dl_pdsch_power = 38; // operating downlink power diff --git a/openair2/ENB_APP/MESSAGES/V2/control_delegation.proto b/openair2/ENB_APP/MESSAGES/V2/control_delegation.proto index 0f7e34de15..ef0eea3bd2 100644 --- a/openair2/ENB_APP/MESSAGES/V2/control_delegation.proto +++ b/openair2/ENB_APP/MESSAGES/V2/control_delegation.proto @@ -3,4 +3,4 @@ package protocol; enum flex_control_delegation_type { FLCDT_MAC_DL_UE_SCHEDULER = 1; // DL UE scheduler delegation -} \ No newline at end of file +} diff --git a/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto b/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto index eeda90b8cb..6f30ea4755 100644 --- a/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto +++ b/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto @@ -4,7 +4,7 @@ package protocol; import "mac_primitives.proto"; // -// Body of UE DL/UL MAC scheduling configuration info +// Body of UE DL MAC scheduling configuration info // message flex_dl_data { @@ -16,12 +16,6 @@ message flex_dl_data { optional uint32 act_deact_ce = 6; //Hex content of MAC CE for Activation/Deactivation in CA } - -message flex_ul_data { - optional uint32 rnti = 1; - optional flex_ul_dci ul_dci = 2; -} - // // Body of the RAR scheduler configuration // diff --git a/openair2/ENB_APP/MESSAGES/V2/flexran.proto b/openair2/ENB_APP/MESSAGES/V2/flexran.proto index 18eb760cc3..45a139b73a 100644 --- a/openair2/ENB_APP/MESSAGES/V2/flexran.proto +++ b/openair2/ENB_APP/MESSAGES/V2/flexran.proto @@ -8,6 +8,7 @@ import "config_messages.proto"; import "controller_commands.proto"; import "control_delegation.proto"; + message flexran_message { optional flexran_direction msg_dir = 100; oneof msg { @@ -24,12 +25,11 @@ message flexran_message { flex_ue_config_reply ue_config_reply_msg = 11; flex_lc_config_request lc_config_request_msg = 12; flex_lc_config_reply lc_config_reply_msg = 13; - flex_dl_mac_config dl_mac_config_msg = 14; + flex_dl_mac_config dl_mac_config_msg = 14; flex_ue_state_change ue_state_change_msg = 15; flex_control_delegation control_delegation_msg = 16; flex_agent_reconfiguration agent_reconfiguration_msg = 17; flex_rrc_triggering rrc_triggering = 18; - flex_ul_mac_config ul_mac_config_msg = 19; } } @@ -166,22 +166,6 @@ message flex_dl_mac_config { repeated flex_pdcch_ofdm_sym_count ofdm_sym = 6; // OFDM symbol count for each CC } - -message flex_ul_mac_config { - optional flex_header header = 1; - optional uint32 sfn_sf = 2; - repeated flex_ul_data ul_ue_data = 3; -} - - -message flex_rrc_triggering { - - optional flex_header header = 1; - optional string rrc_trigger = 2; -} - - - // // UE state change message // @@ -209,7 +193,7 @@ message flex_control_delegation { message flex_agent_reconfiguration { optional flex_header header = 1; - optional string policy = 2; // The policy changes using YAML syntax in string format + optional string policy = 2; // The policy changes using YAML syntax in string format } // Extensions of the echo request and reply diff --git a/openair2/ENB_APP/MESSAGES/V2/header.proto b/openair2/ENB_APP/MESSAGES/V2/header.proto index 4f03e0755e..12110de24e 100644 --- a/openair2/ENB_APP/MESSAGES/V2/header.proto +++ b/openair2/ENB_APP/MESSAGES/V2/header.proto @@ -33,7 +33,7 @@ enum flex_type { //Controller command messages FLPT_DL_MAC_CONFIG = 13; - + // UE state change messages FLPT_UE_STATE_CHANGE = 14; @@ -41,6 +41,5 @@ enum flex_type { FLPT_DELEGATE_CONTROL = 15; FLPT_RECONFIGURE_AGENT = 16; FLPT_RRC_TRIGGERING = 17; - FLPT_UL_MAC_CONFIG = 18; } diff --git a/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto b/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto index a34e9b6eaf..d3acb51318 100644 --- a/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto +++ b/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto @@ -36,37 +36,6 @@ message flex_dl_dci { optional uint32 cif = 27; // CIF for cross-carrier scheduling } -message flex_ul_dci { - optional uint32 rnti = 1; - optional uint32 rb_start = 2; // The start RB allocated to the UE - optional uint32 rb_len = 3; // The number of RBs allocated to the UE - optional uint32 mcs = 4; // Modulation and coding scheme - optional uint32 cyclic_shift2 = 5; // match DCI format 0/4 PDU - optional uint32 freq_hop_flag = 6; // 0 no hopping, 1 hoppping - optional uint32 freq_hop_map = 7; // Frequency hopping bits (0..4) - optional uint32 ndi = 8; // New data indicator - optional uint32 rv = 9; // Redundancy version - optional uint32 harq_pid = 10; // The harq process id - optional uint32 ultx_mode = 11; // A FLULM_* value - optional uint32 tbs_size = 12; // The size of each TBS - optional uint32 n_srs = 13; // Overlap indication with srs - optional uint32 res_alloc = 14; // Type of resource allocation - optional uint32 size = 15; // Size of the ULSCH PDU in bytes for UL Grant. - - optional uint32 dai = 16; // TDD only - -// optional uint32 tb_swap = 17; // Boolean. TB to codeword swap flag - -// optional uint32 pdcch_order = 19; -// optional uint32 preamble_index = 20; // Only valid if pdcch_order = 1 -// optional uint32 prach_mask_index = 21; // Only valid if pdcch_order = 1 - -// optional uint32 tbs_idx = 23; // The TBS index for Format 1A - - - - -} // // Messages related to the creation of RLC PDUs @@ -107,9 +76,3 @@ enum flex_ngap_val { FLNGV_1 = 0; FLNGV_2 = 1; } - -enum flex_mod_type { - FLMOD_QPSK = 2; - FLMOD_16QAM = 4; - FLMOD_64QAM = 6; -} diff --git a/openair2/ENB_APP/MESSAGES/V2/stats_common.proto b/openair2/ENB_APP/MESSAGES/V2/stats_common.proto index a7d78841a3..35550c3733 100644 --- a/openair2/ENB_APP/MESSAGES/V2/stats_common.proto +++ b/openair2/ENB_APP/MESSAGES/V2/stats_common.proto @@ -183,83 +183,87 @@ message flex_noise_interference_report { } // -// RRC Primitives +// RRC Measurements Primitives // + + message flex_rrc_measurements { - // Measurement identifier. - optional int32 measid = 1; - // Primary Cell Reference Signal Received Power (RSRP). - optional int32 pcell_rsrp = 2; - // Primary Cell Reference Signal Received Quality (RSRQ). - optional int32 pcell_rsrq = 3; - // Neighboring cells measurements performed by UE. - optional flex_neigh_cells_measurements neigh_meas = 4; + // Measurement identifier. + optional int32 measid = 1; + // Primary Cell Reference Signal Received Power (RSRP). + optional int32 pcell_rsrp = 2; + // Primary Cell Reference Signal Received Quality (RSRQ). + optional int32 pcell_rsrq = 3; + // Neighboring cells measurements performed by UE. + optional flex_neigh_cells_measurements neigh_meas = 4; } message flex_neigh_cells_measurements { - // Neighboring EUTRA cells measurements. - repeated flex_eutra_measurements eutra_meas = 1; + // Neighboring EUTRA cells measurements. + repeated flex_eutra_measurements eutra_meas = 1; } message flex_eutra_measurements { - // Physical Cell identifier. - optional int32 phys_cell_id = 1; - // EUTRA Cell Global Identity (CGI) measurement. - optional flex_eutra_cgi_measurements cgi_meas = 2; - // EUTRA nearby cell reference signal measurement. - optional flex_eutra_ref_signal_meas meas_result = 3; + // Physical Cell identifier. + optional int32 phys_cell_id = 1; + // EUTRA Cell Global Identity (CGI) measurement. + optional flex_eutra_cgi_measurements cgi_meas = 2; + // EUTRA nearby cell reference signal measurement. + optional flex_eutra_ref_signal_meas meas_result = 3; } message flex_eutra_cgi_measurements { - // EUTRA Cell Global Identity (CGI). - optional flex_cell_global_eutra_id cgi = 1; - // Tracking area code of the neighbor cell. - optional uint32 tracking_area_code = 2; - // Public land mobile network identifiers of neighbor cell. - repeated flex_plmn_identity plmn_id = 3; + // EUTRA Cell Global Identity (CGI). + optional flex_cell_global_eutra_id cgi = 1; + // Tracking area code of the neighbor cell. + optional uint32 tracking_area_code = 2; + // Public land mobile network identifiers of neighbor cell. + repeated flex_plmn_identity plmn_id = 3; } message flex_cell_global_eutra_id { - // Public land mobile network identifier of neighbor cell. - optional flex_plmn_identity plmn_id = 1; - // Cell identifier of neighbor cell. - optional uint32 cell_id = 2; + // Public land mobile network identifier of neighbor cell. + optional flex_plmn_identity plmn_id = 1; + // Cell identifier of neighbor cell. + optional uint32 cell_id = 2; } message flex_plmn_identity { - // Mobile Network Code (MNC). - repeated uint32 mnc = 1; - // Mobile Country Code (MCC). - repeated uint32 mcc = 2; - // tracking area code - repeated uint32 tac = 3; -} + // Mobile Network Code (MNC). + repeated uint32 mnc = 1; + // Mobile Country Code (MCC). + repeated uint32 mcc = 2; + // tracking area code + repeated uint32 tac = 3; +} message flex_eutra_ref_signal_meas { - // Neighboring Cell Reference Signal Received Power (RSRP). - optional int32 rsrp = 1; - // Neighboring Cell Reference Signal Received Quality (RSRQ). - optional int32 rsrq = 2; - + // Neighboring Cell RSRP + optional int32 rsrp = 1; + // Neighboring Cell RSRQ + optional int32 rsrq = 2; } +// +// PDCP Statistics +// + message flex_pdcp_stats { - optional uint32 pkt_tx = 1; - optional uint32 pkt_tx_bytes = 2; - optional uint32 pkt_tx_sn = 3; - optional uint32 pkt_tx_rate_s = 4; + optional uint32 pkt_tx = 1; + optional uint32 pkt_tx_bytes = 2; + optional uint32 pkt_tx_sn = 3; + optional uint32 pkt_tx_rate_s = 4; optional uint32 pkt_tx_throughput_s = 5; - optional uint32 pkt_tx_aiat = 7; + optional uint32 pkt_tx_aiat = 7; optional uint32 pkt_tx_aiat_s = 8; optional uint32 pkt_rx = 9; - optional uint32 pkt_rx_bytes = 10; - optional uint32 pkt_rx_sn = 11; - optional uint32 pkt_rx_rate_s = 12; + optional uint32 pkt_rx_bytes = 10; + optional uint32 pkt_rx_sn = 11; + optional uint32 pkt_rx_rate_s = 12; optional uint32 pkt_rx_goodput_s = 13; - optional uint32 pkt_rx_aiat = 14; + optional uint32 pkt_rx_aiat = 14; optional uint32 pkt_rx_aiat_s = 15; - optional uint32 pkt_rx_oo = 16; - } - + optional uint32 pkt_rx_oo = 16; +} diff --git a/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto b/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto index 8cad6f4fbe..b8126c55f2 100644 --- a/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto +++ b/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto @@ -47,8 +47,8 @@ message flex_ue_stats_report { optional flex_dl_cqi_report dl_cqi_report = 7; optional flex_paging_buffer_report pbr = 8; optional flex_ul_cqi_report ul_cqi_report = 9; - optional flex_rrc_measurements rrc_measurements = 10; - optional flex_pdcp_stats pdcp_stats = 11; + optional flex_rrc_measurements rrc_measurements = 10; + optional flex_pdcp_stats pdcp_stats = 11; } // @@ -85,9 +85,9 @@ enum flex_ue_stats_type { FLUST_DL_CQI = 16; FLUST_PBS = 32; FLUST_UL_CQI = 64; - - FLUST_PDCP_STATS = 1024; // To be changed - // To be extended with more types of stats + + FLUST_PDCP_STATS = 1024; FLUST_RRC_MEASUREMENTS = 65536; - + // To be extended with more types of stats + } diff --git a/openair2/ENB_APP/MESSAGES/V2/time_common.proto b/openair2/ENB_APP/MESSAGES/V2/time_common.proto index baf0c0e9ae..6c0affbe51 100644 --- a/openair2/ENB_APP/MESSAGES/V2/time_common.proto +++ b/openair2/ENB_APP/MESSAGES/V2/time_common.proto @@ -25,7 +25,7 @@ message flex_ul_info { repeated uint32 ul_reception = 2; optional uint32 reception_status = 3; optional uint32 tpc = 4; - optional uint32 serv_cell_index = 5; - optional uint32 rssi = 6; + optional uint32 serv_cell_index = 5; + optional uint32 rssi = 6; } diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index e56ebdfd22..386dd18f1e 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -387,7 +387,6 @@ int flexran_agent_control_delegation(mid_t mod_id, const void *params, Protocol_ Protocol__FlexControlDelegation *control_delegation_msg = input->control_delegation_msg; // struct timespec vartime = timer_start(); - int status; //Write the payload lib into a file in the cache and load the lib char lib_name[120]; char target[512]; @@ -395,13 +394,6 @@ int flexran_agent_control_delegation(mid_t mod_id, const void *params, Protocol_ strcpy(target, local_cache); strcat(target, lib_name); - status = mkdir(local_cache, S_IRWXU | S_IRWXG | S_IRWXO); - - if (status < 0){ - - LOG_W(ENB_APP, "Couldn't create local cache!"); - } - FILE *f; f = fopen(target, "wb"); fwrite(control_delegation_msg->payload.data, control_delegation_msg->payload.len, 1, f); From acd996d2eb555248afefe5cd17fbb0c931e0b3e6 Mon Sep 17 00:00:00 2001 From: shahab Date: Sun, 10 Dec 2017 18:23:21 +0100 Subject: [PATCH 039/195] ul proto msg --- .../MESSAGES/V2/controller_commands.proto | 6 ++++ openair2/ENB_APP/MESSAGES/V2/flexran.proto | 13 ++++++++ openair2/ENB_APP/MESSAGES/V2/header.proto | 1 + .../ENB_APP/MESSAGES/V2/mac_primitives.proto | 32 +++++++++++++++++++ 4 files changed, 52 insertions(+) diff --git a/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto b/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto index 6f30ea4755..29e0723835 100644 --- a/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto +++ b/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto @@ -16,6 +16,12 @@ message flex_dl_data { optional uint32 act_deact_ce = 6; //Hex content of MAC CE for Activation/Deactivation in CA } + +message flex_ul_data { + optional uint32 rnti = 1; + optional flex_ul_dci ul_dci = 2; +} + // // Body of the RAR scheduler configuration // diff --git a/openair2/ENB_APP/MESSAGES/V2/flexran.proto b/openair2/ENB_APP/MESSAGES/V2/flexran.proto index 45a139b73a..b54fc171c6 100644 --- a/openair2/ENB_APP/MESSAGES/V2/flexran.proto +++ b/openair2/ENB_APP/MESSAGES/V2/flexran.proto @@ -30,6 +30,7 @@ message flexran_message { flex_control_delegation control_delegation_msg = 16; flex_agent_reconfiguration agent_reconfiguration_msg = 17; flex_rrc_triggering rrc_triggering = 18; + flex_ul_mac_config ul_mac_config_msg = 19; } } @@ -166,6 +167,18 @@ message flex_dl_mac_config { repeated flex_pdcch_ofdm_sym_count ofdm_sym = 6; // OFDM symbol count for each CC } +message flex_ul_mac_config { + optional flex_header header = 1; + optional uint32 sfn_sf = 2; + repeated flex_ul_data ul_ue_data = 3; +} + +message flex_rrc_triggering { + + optional flex_header header = 1; + optional string rrc_trigger = 2; +} + // // UE state change message // diff --git a/openair2/ENB_APP/MESSAGES/V2/header.proto b/openair2/ENB_APP/MESSAGES/V2/header.proto index 12110de24e..8900b93492 100644 --- a/openair2/ENB_APP/MESSAGES/V2/header.proto +++ b/openair2/ENB_APP/MESSAGES/V2/header.proto @@ -41,5 +41,6 @@ enum flex_type { FLPT_DELEGATE_CONTROL = 15; FLPT_RECONFIGURE_AGENT = 16; FLPT_RRC_TRIGGERING = 17; + FLPT_UL_MAC_CONFIG = 18; } diff --git a/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto b/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto index d3acb51318..bd2b9cbe50 100644 --- a/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto +++ b/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto @@ -34,6 +34,38 @@ message flex_dl_dci { optional uint32 pdcch_power_offset = 25; // DL PDCCH power boosting in dB optional uint32 cif_present = 26; // Boolean. Indication of CIF field optional uint32 cif = 27; // CIF for cross-carrier scheduling +} + +message flex_ul_dci { + optional uint32 rnti = 1; + optional uint32 rb_start = 2; // The start RB allocated to the UE + optional uint32 rb_len = 3; // The number of RBs allocated to the UE + optional uint32 mcs = 4; // Modulation and coding scheme + optional uint32 cyclic_shift2 = 5; // match DCI format 0/4 PDU + optional uint32 freq_hop_flag = 6; // 0 no hopping, 1 hoppping + optional uint32 freq_hop_map = 7; // Frequency hopping bits (0..4) + optional uint32 ndi = 8; // New data indicator + optional uint32 rv = 9; // Redundancy version + optional uint32 harq_pid = 10; // The harq process id + optional uint32 ultx_mode = 11; // A FLULM_* value + optional uint32 tbs_size = 12; // The size of each TBS + optional uint32 n_srs = 13; // Overlap indication with srs + optional uint32 res_alloc = 14; // Type of resource allocation + optional uint32 size = 15; // Size of the ULSCH PDU in bytes for UL Grant. + + optional uint32 dai = 16; // TDD only + +// optional uint32 tb_swap = 17; // Boolean. TB to codeword swap flag + +// optional uint32 pdcch_order = 19; +// optional uint32 preamble_index = 20; // Only valid if pdcch_order = 1 +// optional uint32 prach_mask_index = 21; // Only valid if pdcch_order = 1 + +// optional uint32 tbs_idx = 23; // The TBS index for Format 1A + + + + } From 9601ea66c5f1aa709cccbe4da4627458932a1a66 Mon Sep 17 00:00:00 2001 From: Navid Nikaein Date: Mon, 11 Dec 2017 16:46:22 +0100 Subject: [PATCH 040/195] Update PDCP stats --- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 139 +++++++++++++++------------- openair2/LAYER2/PDCP_v10.1.0/pdcp.h | 2 + 2 files changed, 78 insertions(+), 63 deletions(-) diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 397a194edf..fb4cc0c526 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -409,7 +409,9 @@ boolean_t pdcp_data_req( //LOG_I(PDCP,"ueid %d lcid %d tx seq num %d\n", pdcp_uid, rb_idP+rb_offset, current_sn); Pdcp_stats_tx[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; + Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; Pdcp_stats_tx_bytes[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=sdu_buffer_sizeP; + Pdcp_stats_tx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=sdu_buffer_sizeP; Pdcp_stats_tx_sn[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=current_sn; if (Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset] < pdcp_frame *10 + pdcp_subframe) { @@ -421,22 +423,8 @@ boolean_t pdcp_data_req( Pdcp_stats_tx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (1024 + pdcp_frame *10 + pdcp_subframe - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); } - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=ctxt_pP->frame*10+ctxt_pP->subframe; - if (pdcp_frame % 100 == 0 ) { - Pdcp_stats_tx_rate_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]= Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]; - Pdcp_stats_tx_throughput_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=Pdcp_stats_tx_bytes[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]*8/1000; - Pdcp_stats_tx_aiat_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=Pdcp_stats_tx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]; - - Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=0; - Pdcp_stats_tx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=0; - Pdcp_stats_tx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=0; - }else { - Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; - Pdcp_stats_tx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=sdu_buffer_sizeP; - - } @@ -828,53 +816,43 @@ pdcp_data_ind( packet_forwarded = TRUE; /* Print octets of incoming data in hexadecimal form */ - LOG_D(PDCP, "Following content has been received from RLC (%d,%d)(PDCP header has already been removed):\n", - sdu_buffer_sizeP - payload_offset + (int)sizeof(pdcp_data_ind_header_t), - sdu_buffer_sizeP - payload_offset); - //util_print_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset); - //util_flush_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset); - - /* - * Update PDCP statistics - * XXX Following two actions are identical, is there a merge error? - */ - - for (pdcp_uid=0; pdcp_uid< NUMBER_OF_UE_MAX;pdcp_uid++){ - if (pdcp_p->rnti[pdcp_uid] == ctxt_pP->rnti ) - break; - } - - Pdcp_stats_rx[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; - Pdcp_stats_rx_bytes[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=sdu_buffer_sizeP - payload_offset; - - Pdcp_stats_rx_sn[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=sequence_number; - - if (oo_flag == 1 ) - Pdcp_stats_rx_outoforder[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; - - if (Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset] < pdcp_frame * 10 + pdcp_subframe) { - Pdcp_stats_rx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_frame *10 + pdcp_subframe - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); - Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(pdcp_frame *10 + pdcp_subframe - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); - } else { - Pdcp_stats_rx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (1024 +pdcp_frame * 10 + pdcp_subframe - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); - Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(1024 +pdcp_frame * 10 + pdcp_subframe - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); - } - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=pdcp_frame * 10 +pdcp_subframe; - - if (pdcp_frame % 102 == 0) { - Pdcp_stats_rx_rate_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]; - Pdcp_stats_rx_goodput_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=Pdcp_stats_rx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]*8/1023; - Pdcp_stats_rx_aiat_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]= Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]; - - Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=0; - Pdcp_stats_rx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=0; - Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=0; - }else { - Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; - Pdcp_stats_rx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(sdu_buffer_sizeP - payload_offset); - } + LOG_D(PDCP, "Following content has been received from RLC (%d,%d)(PDCP header has already been removed):\n", + sdu_buffer_sizeP - payload_offset + (int)sizeof(pdcp_data_ind_header_t), + sdu_buffer_sizeP - payload_offset); + //util_print_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset); + //util_flush_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset); + + /* + * Update PDCP statistics + * XXX Following two actions are identical, is there a merge error? + */ + + for (pdcp_uid=0; pdcp_uid< NUMBER_OF_UE_MAX;pdcp_uid++){ + if (pdcp_p->rnti[pdcp_uid] == ctxt_pP->rnti ) + break; + } + + Pdcp_stats_rx[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; + Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; + Pdcp_stats_rx_bytes[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(sdu_buffer_sizeP - payload_offset); + Pdcp_stats_rx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(sdu_buffer_sizeP - payload_offset); + + Pdcp_stats_rx_sn[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=sequence_number; + + if (oo_flag == 1 ) + Pdcp_stats_rx_outoforder[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; + + if (Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset] < pdcp_frame * 10 + pdcp_subframe) { + Pdcp_stats_rx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_frame *10 + pdcp_subframe - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(pdcp_frame *10 + pdcp_subframe - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + } else { + Pdcp_stats_rx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (1024 +pdcp_frame * 10 + pdcp_subframe - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(1024 +pdcp_frame * 10 + pdcp_subframe - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + } + Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=pdcp_frame * 10 +pdcp_subframe; + } - + #else packet_forwarded = FALSE; #endif @@ -951,6 +929,38 @@ pdcp_data_ind( return TRUE; } +void pdcp_update_stats(const protocol_ctxt_t* const ctxt_pP){ + + uint8_t pdcp_uid = 0; + uint8_t rb_id = 0; + + // these stats can be measured for both eNB and UE + if ((pdcp_frame % 102 == 0) && (pdcp_subframe ==0)) { + for (rb_id =0; rb_id < NB_RB_MAX; rb_id ++){ + for (pdcp_uid=0; pdcp_uid< NUMBER_OF_UE_MAX;pdcp_uid++){ + //printf("frame %d and subframe %d \n", pdcp_frame, pdcp_subframe); + // tx stats + Pdcp_stats_tx_rate_s[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_id]; + Pdcp_stats_tx_throughput_s[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_tx_bytes[ctxt_pP->module_id][pdcp_uid][rb_id]*8/1024; + Pdcp_stats_tx_aiat_s[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_tx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_id]; + + Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + Pdcp_stats_tx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + Pdcp_stats_tx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + + // rx stats + Pdcp_stats_rx_rate_s[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_id]; + Pdcp_stats_rx_goodput_s[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_rx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_id]*8/1024; + Pdcp_stats_rx_aiat_s[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_id]; + + Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + Pdcp_stats_rx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + + } + } + } +} //----------------------------------------------------------------------------- void pdcp_run ( @@ -958,9 +968,7 @@ pdcp_run ( ) //----------------------------------------------------------------------------- { - - pdcp_frame =ctxt_pP->frame; - pdcp_subframe= ctxt_pP->subframe; + #if defined(ENABLE_ITTI) MessageDef *msg_p; const char *msg_name; @@ -969,12 +977,17 @@ pdcp_run ( protocol_ctxt_t ctxt; #endif + if (ctxt_pP->enb_flag) { start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].pdcp_run); } else { start_meas(&UE_pdcp_stats[ctxt_pP->module_id].pdcp_run); } + pdcp_frame =ctxt_pP->frame; // 1023 + pdcp_subframe= ctxt_pP->subframe; + pdcp_update_stats(ctxt_pP); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_RUN, VCD_FUNCTION_IN); #if defined(ENABLE_ITTI) diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index fb3e02b299..2f1d15ad5e 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -124,6 +124,8 @@ public_pdcp(uint32_t Pdcp_stats_rx_aiat_tmp_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_ public_pdcp(uint32_t Pdcp_stats_rx_iat[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); public_pdcp(uint32_t Pdcp_stats_rx_outoforder[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(void pdcp_update_perioidical_stats(const protocol_ctxt_t* const ctxt_pP)); + /*Packet Probing for agent PDCP*/ //public_pdcp(uint64_t *pdcp_packet_counter); From 38627c85d063073ae6e88a56d2ec6690a1e5f8c1 Mon Sep 17 00:00:00 2001 From: Navid Nikaein Date: Tue, 12 Dec 2017 10:14:30 +0100 Subject: [PATCH 041/195] Minor fix in the PDCP stats update --- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index fb4cc0c526..7262d6b8d2 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -941,7 +941,8 @@ void pdcp_update_stats(const protocol_ctxt_t* const ctxt_pP){ //printf("frame %d and subframe %d \n", pdcp_frame, pdcp_subframe); // tx stats Pdcp_stats_tx_rate_s[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_id]; - Pdcp_stats_tx_throughput_s[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_tx_bytes[ctxt_pP->module_id][pdcp_uid][rb_id]*8/1024; + // unit: bit/s + Pdcp_stats_tx_throughput_s[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_tx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_id]*8; Pdcp_stats_tx_aiat_s[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_tx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_id]; Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_id]=0; @@ -950,7 +951,7 @@ void pdcp_update_stats(const protocol_ctxt_t* const ctxt_pP){ // rx stats Pdcp_stats_rx_rate_s[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_id]; - Pdcp_stats_rx_goodput_s[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_rx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_id]*8/1024; + Pdcp_stats_rx_goodput_s[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_rx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_id]*8; Pdcp_stats_rx_aiat_s[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_id]; Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_id]=0; From b7a1661855f440ac624a9bf78a544dbba2f573b4 Mon Sep 17 00:00:00 2001 From: Navid Nikaein Date: Tue, 12 Dec 2017 11:57:24 +0100 Subject: [PATCH 042/195] Better management of frame counter and stats in PDCP --- .../CONTROL_MODULES/PDCP/flexran_agent_pdcp.c | 5 +- .../ENB_APP/MESSAGES/V2/stats_common.proto | 2 + openair2/ENB_APP/flexran_agent_ran_api.c | 4 + openair2/ENB_APP/flexran_agent_ran_api.h | 3 + openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 127 ++++++++---------- openair2/LAYER2/PDCP_v10.1.0/pdcp.h | 7 +- 6 files changed, 76 insertions(+), 72 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c index 4aa2e691b9..e4cc520070 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c +++ b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c @@ -21,7 +21,7 @@ /*! \file flexran_agent_pdcp.c * \brief FlexRAN agent Control Module PDCP - * \author shahab SHARIAT BAGHERI + * \author Navid Nikaein and shahab SHARIAT BAGHERI * \date 2017 * \version 0.1 */ @@ -118,6 +118,9 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id, pdcp_aggr_stats->pkt_rx_sn = flexran_get_pdcp_rx_sn(mod_id, i, DEFAULT_DRB); pdcp_aggr_stats->has_pkt_rx_sn =1; + pdcp_aggr_stats->sfn = flexran_get_pdcp_sfn(mod_id); + pdcp_aggr_stats->has_sfn =1; + ue_report[i]->pdcp_stats = pdcp_aggr_stats; } diff --git a/openair2/ENB_APP/MESSAGES/V2/stats_common.proto b/openair2/ENB_APP/MESSAGES/V2/stats_common.proto index 35550c3733..94da9fbd04 100644 --- a/openair2/ENB_APP/MESSAGES/V2/stats_common.proto +++ b/openair2/ENB_APP/MESSAGES/V2/stats_common.proto @@ -266,4 +266,6 @@ message flex_pdcp_stats { optional uint32 pkt_rx_aiat = 14; optional uint32 pkt_rx_aiat_s = 15; optional uint32 pkt_rx_oo = 16; + + optional uint64 sfn=17; } diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 280b9807fd..7a4522e870 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -1083,6 +1083,10 @@ void flexran_agent_set_operating_frame_type (mid_t mod_id, int cc_id, int frame_ } /*********** PDCP *************/ +/*PDCP num tx pdu status flexRAN*/ +uint32_t flexran_get_pdcp_sfn(const mid_t mod_id){ + return Pdcp_sfn[mod_id]; +} /*PDCP num tx pdu status flexRAN*/ uint32_t flexran_get_pdcp_tx(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 4d84251608..bb9592399e 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -342,6 +342,9 @@ int flexran_get_rrc_status(const mid_t mod_id, const rnti_t rntiP); /***************************** PDCP ***********************/ +/*PDCP superframe numberflexRAN*/ +uint32_t flexran_get_pdcp_sfn(const mid_t mod_id); + /*PDCP num tx pdu status flexRAN*/ uint32_t flexran_get_pdcp_tx(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 7262d6b8d2..c561043f4a 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -414,20 +414,10 @@ boolean_t pdcp_data_req( Pdcp_stats_tx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=sdu_buffer_sizeP; Pdcp_stats_tx_sn[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=current_sn; - if (Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset] < pdcp_frame *10 + pdcp_subframe) { - Pdcp_stats_tx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_frame *10 + pdcp_subframe - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); - Pdcp_stats_tx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_frame *10 + pdcp_subframe - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); - } - else { - Pdcp_stats_tx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (1024 + pdcp_frame *10 + pdcp_subframe - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); - Pdcp_stats_tx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (1024 + pdcp_frame *10 + pdcp_subframe - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); - } - - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=ctxt_pP->frame*10+ctxt_pP->subframe; - - - - + Pdcp_stats_tx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (Pdcp_sfn[ctxt_pP->module_id] - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + Pdcp_stats_tx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (Pdcp_sfn[ctxt_pP->module_id] - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=Pdcp_sfn[ctxt_pP->module_id]; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_OUT); return ret; @@ -813,44 +803,7 @@ pdcp_data_ind( GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rnti = ctxt_pP->rnti; GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rab_id = rb_id + 4; itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p); - packet_forwarded = TRUE; - - /* Print octets of incoming data in hexadecimal form */ - LOG_D(PDCP, "Following content has been received from RLC (%d,%d)(PDCP header has already been removed):\n", - sdu_buffer_sizeP - payload_offset + (int)sizeof(pdcp_data_ind_header_t), - sdu_buffer_sizeP - payload_offset); - //util_print_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset); - //util_flush_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset); - - /* - * Update PDCP statistics - * XXX Following two actions are identical, is there a merge error? - */ - - for (pdcp_uid=0; pdcp_uid< NUMBER_OF_UE_MAX;pdcp_uid++){ - if (pdcp_p->rnti[pdcp_uid] == ctxt_pP->rnti ) - break; - } - - Pdcp_stats_rx[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; - Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; - Pdcp_stats_rx_bytes[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(sdu_buffer_sizeP - payload_offset); - Pdcp_stats_rx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(sdu_buffer_sizeP - payload_offset); - - Pdcp_stats_rx_sn[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=sequence_number; - - if (oo_flag == 1 ) - Pdcp_stats_rx_outoforder[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; - - if (Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset] < pdcp_frame * 10 + pdcp_subframe) { - Pdcp_stats_rx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_frame *10 + pdcp_subframe - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); - Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(pdcp_frame *10 + pdcp_subframe - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); - } else { - Pdcp_stats_rx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (1024 +pdcp_frame * 10 + pdcp_subframe - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); - Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(1024 +pdcp_frame * 10 + pdcp_subframe - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); - } - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=pdcp_frame * 10 +pdcp_subframe; - + packet_forwarded = TRUE; } #else @@ -909,6 +862,38 @@ pdcp_data_ind( } } + /* Print octets of incoming data in hexadecimal form */ + LOG_D(PDCP, "Following content has been received from RLC (%d,%d)(PDCP header has already been removed):\n", + sdu_buffer_sizeP - payload_offset + (int)sizeof(pdcp_data_ind_header_t), + sdu_buffer_sizeP - payload_offset); + //util_print_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset); + //util_flush_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset); + + /* + * Update PDCP statistics + * XXX Following two actions are identical, is there a merge error? + */ + + for (pdcp_uid=0; pdcp_uid< NUMBER_OF_UE_MAX;pdcp_uid++){ + if (pdcp_p->rnti[pdcp_uid] == ctxt_pP->rnti ) + break; + } + + Pdcp_stats_rx[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; + Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; + Pdcp_stats_rx_bytes[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(sdu_buffer_sizeP - payload_offset); + Pdcp_stats_rx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(sdu_buffer_sizeP - payload_offset); + + Pdcp_stats_rx_sn[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=sequence_number; + + if (oo_flag == 1 ) + Pdcp_stats_rx_outoforder[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; + + Pdcp_stats_rx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (Pdcp_sfn[ctxt_pP->module_id] - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(Pdcp_sfn[ctxt_pP->module_id] - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=Pdcp_sfn[ctxt_pP->module_id]; + + #if defined(STOP_ON_IP_TRAFFIC_OVERLOAD) else { AssertFatal(0, PROTOCOL_PDCP_CTXT_FMT" PDCP_DATA_IND SDU DROPPED, OUT OF MEMORY \n", @@ -934,16 +919,16 @@ void pdcp_update_stats(const protocol_ctxt_t* const ctxt_pP){ uint8_t pdcp_uid = 0; uint8_t rb_id = 0; - // these stats can be measured for both eNB and UE - if ((pdcp_frame % 102 == 0) && (pdcp_subframe ==0)) { + // these stats are measured for both eNB and UE on per seond basis + if (Pdcp_sfn[ctxt_pP->module_id] % 1000 == 0){ for (rb_id =0; rb_id < NB_RB_MAX; rb_id ++){ for (pdcp_uid=0; pdcp_uid< NUMBER_OF_UE_MAX;pdcp_uid++){ - //printf("frame %d and subframe %d \n", pdcp_frame, pdcp_subframe); + //printf("frame %d and subframe %d \n", Pdcp_frame[ctxt_pP->module_id], Pdcp_subframe[ctxt_pP->module_id]); // tx stats Pdcp_stats_tx_rate_s[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_id]; // unit: bit/s Pdcp_stats_tx_throughput_s[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_tx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_id]*8; - Pdcp_stats_tx_aiat_s[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_tx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_id]; + Pdcp_stats_tx_aiat_s[ctxt_pP->module_id][pdcp_uid][rb_id]=(uint32_t)(Pdcp_stats_tx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_id]/Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_id]); Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_id]=0; Pdcp_stats_tx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_id]=0; @@ -952,7 +937,7 @@ void pdcp_update_stats(const protocol_ctxt_t* const ctxt_pP){ // rx stats Pdcp_stats_rx_rate_s[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_id]; Pdcp_stats_rx_goodput_s[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_rx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_id]*8; - Pdcp_stats_rx_aiat_s[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_id]; + Pdcp_stats_rx_aiat_s[ctxt_pP->module_id][pdcp_uid][rb_id]= (uint32_t)(Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_id]/Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_id]); Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_id]=0; Pdcp_stats_rx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_id]=0; @@ -985,8 +970,9 @@ pdcp_run ( start_meas(&UE_pdcp_stats[ctxt_pP->module_id].pdcp_run); } - pdcp_frame =ctxt_pP->frame; // 1023 - pdcp_subframe= ctxt_pP->subframe; + Pdcp_sfn[ctxt_pP->module_id]++; // range: 0 to 18,446,744,073,709,551,615 + Pdcp_frame[ctxt_pP->module_id]=ctxt_pP->frame; // 1023 + Pdcp_subframe[ctxt_pP->module_id]= ctxt_pP->subframe; pdcp_update_stats(ctxt_pP); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_RUN, VCD_FUNCTION_IN); @@ -1564,9 +1550,9 @@ pdcp_config_req_asn1 ( if (pdcp_pP->rnti[i] != 0 ) continue ; // skip active ues pdcp_pP->rnti[i]=ctxt_pP->rnti; pdcp_pP->uid[i]=i; - pdcp_num_ues++; + Pdcp_num_ues[ctxt_pP->module_id]++; break; - } + } //pdcp_eNB_UE_instance_to_rnti[ctxtP->module_id] = ctxt_pP->rnti; pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] = ctxt_pP->rnti; //pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % NUMBER_OF_UE_MAX; @@ -1669,14 +1655,14 @@ pdcp_config_req_asn1 ( if (ctxt_pP->enb_flag == ENB_FLAG_YES) { for (i=0; i < NUMBER_OF_UE_MAX; i++) { - if (pdcp_pP->rnti[i] == ctxt_pP->rnti ) { - pdcp_pP->rnti[i]=0; - pdcp_pP->uid[i]=0; - pdcp_num_ues--; - break; - } - } + if (pdcp_pP->rnti[i] == ctxt_pP->rnti ) { + pdcp_pP->rnti[i]=0; + pdcp_pP->uid[i]=0; + Pdcp_num_ues[ctxt_pP->module_id]--; + break; + } } + } /* Security keys */ if (pdcp_pP->kUPenc != NULL) { @@ -2055,6 +2041,11 @@ void pdcp_layer_init(void) pdcp_output_header_bytes_to_write=0; pdcp_input_sdu_remaining_size_to_read=0; + memset(Pdcp_sfn, 0, sizeof(Pdcp_sfn)); + memset(Pdcp_frame, 0, sizeof(Pdcp_frame)); + memset(Pdcp_subframe, 0, sizeof(Pdcp_subframe)); + memset(Pdcp_num_ues, 0, sizeof(Pdcp_num_ues)); + memset(Pdcp_stats_tx, 0, sizeof(Pdcp_stats_tx)); memset(Pdcp_stats_tx_s, 0, sizeof(Pdcp_stats_tx_s)); memset(Pdcp_stats_tx_bytes, 0, sizeof(Pdcp_stats_tx_bytes)); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index 2f1d15ad5e..e9f20e0a94 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -94,9 +94,10 @@ extern int pdcp_instance_cnt; int init_pdcp_thread(void); void cleanup_pdcp_thread(void); -public_pdcp(frame_t pdcp_frame); -public_pdcp(sub_frame_t pdcp_subframe); -public_pdcp(uint16_t pdcp_num_ues); +public_pdcp(uint64_t Pdcp_sfn[MAX_NUM_CCs]); +public_pdcp(frame_t Pdcp_frame[MAX_NUM_CCs]); +public_pdcp(sub_frame_t Pdcp_subframe[MAX_NUM_CCs]); +public_pdcp(uint16_t Pdcp_num_ues[MAX_NUM_CCs]); public_pdcp(uint32_t Pdcp_stats_tx_bytes[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); From b74c668ddb032f8148b56ce538efcc2555393a03 Mon Sep 17 00:00:00 2001 From: shahab SHARIAT BAGHERI Date: Tue, 12 Dec 2017 15:57:24 +0100 Subject: [PATCH 043/195] bug zero division for pdcp stats --- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index c561043f4a..6118ddc745 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -928,7 +928,9 @@ void pdcp_update_stats(const protocol_ctxt_t* const ctxt_pP){ Pdcp_stats_tx_rate_s[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_id]; // unit: bit/s Pdcp_stats_tx_throughput_s[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_tx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_id]*8; - Pdcp_stats_tx_aiat_s[ctxt_pP->module_id][pdcp_uid][rb_id]=(uint32_t)(Pdcp_stats_tx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_id]/Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_id]); + if (Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_id] > 0){ + Pdcp_stats_tx_aiat_s[ctxt_pP->module_id][pdcp_uid][rb_id]=(Pdcp_stats_tx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_id]/Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_id]); + } Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_id]=0; Pdcp_stats_tx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_id]=0; @@ -937,7 +939,10 @@ void pdcp_update_stats(const protocol_ctxt_t* const ctxt_pP){ // rx stats Pdcp_stats_rx_rate_s[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_id]; Pdcp_stats_rx_goodput_s[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_rx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_id]*8; - Pdcp_stats_rx_aiat_s[ctxt_pP->module_id][pdcp_uid][rb_id]= (uint32_t)(Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_id]/Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_id]); + + if(Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_id] > 0){ + Pdcp_stats_rx_aiat_s[ctxt_pP->module_id][pdcp_uid][rb_id]= (Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_id]/Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_id]); + } Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_id]=0; Pdcp_stats_rx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_id]=0; From 33696a4e93115d8ee366fb9b9b1164d75cf441a3 Mon Sep 17 00:00:00 2001 From: Navid Nikaein Date: Tue, 12 Dec 2017 20:24:29 +0100 Subject: [PATCH 044/195] *Update RRC RSRP/RSRQ measurement reports for multiple UEs, and add the corresponding RAN APIs *Fix the issue with the PDCP UE ID/RNTI management --- .../CONTROL_MODULES/RRC/flexran_agent_rrc.c | 36 +++---- openair2/ENB_APP/flexran_agent_ran_api.c | 68 +++++++++++++- openair2/ENB_APP/flexran_agent_ran_api.h | 8 ++ openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 93 +++++++++++-------- openair2/LAYER2/PDCP_v10.1.0/pdcp.h | 31 +++++-- openair2/RRC/LITE/L2_interface.c | 4 +- openair2/RRC/LITE/defs.h | 3 +- openair2/RRC/LITE/proto.h | 2 +- openair2/RRC/LITE/rrc_eNB.c | 67 ++++++++----- 9 files changed, 217 insertions(+), 95 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c index 587ac8c263..7a251be78b 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c @@ -276,9 +276,11 @@ void flexran_trigger_rrc_measurements (mid_t mod_id, MeasResults_t* measResults for (i = 0; i < num; i++){ meas_stats[i].rnti = flexran_get_ue_crnti(mod_id, i); - meas_stats[i].meas_id = measResults->measId; - meas_stats[i].rsrp = measResults->measResultPCell.rsrpResult - 140; - meas_stats[i].rsrq = (measResults->measResultPCell.rsrqResult)/2 - 20; + meas_stats[i].meas_id = flexran_get_rrc_pcell_measid(mod_id,i); + meas_stats[i].rsrp = flexran_get_rrc_pcell_rsrp(mod_id,i) - 140; + // measResults->measResultPCell.rsrpResult - 140; + meas_stats[i].rsrq = flexran_get_rrc_pcell_rsrq(mod_id,i)/2 - 20; + // (measResults->measResultPCell.rsrqResult)/2 - 20; } // repl->neigh_meas = NULL; @@ -505,23 +507,21 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, if (rrc_measurements == NULL) goto error; protocol__flex_rrc_measurements__init(rrc_measurements); - - if (triggered_rrc){ - rrc_measurements->measid = meas_stats[i].meas_id; - rrc_measurements->has_measid = 1; - - rrc_measurements->pcell_rsrp = meas_stats[i].rsrp; - rrc_measurements->has_pcell_rsrp = 1; - - rrc_measurements->pcell_rsrq = meas_stats[i].rsrq; - rrc_measurements->has_pcell_rsrq = 1 ; - - ue_report[i]->rrc_measurements = rrc_measurements; - // triggered_rrc = false; // To be decided later - } + + rrc_measurements->measid = flexran_get_rrc_pcell_measid(mod_id,i); + rrc_measurements->has_measid = 1; + + rrc_measurements->pcell_rsrp = flexran_get_rrc_pcell_rsrp(mod_id,i) - 140; + rrc_measurements->has_pcell_rsrp = 1; + + rrc_measurements->pcell_rsrq = flexran_get_rrc_pcell_rsrq(mod_id,i)/2 - 20; + rrc_measurements->has_pcell_rsrq = 1 ; + + ue_report[i]->rrc_measurements = rrc_measurements; + } } - } + } /* To be extended for RRC layer */ // if (report_config->nr_cc > 0) { diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 7a4522e870..17d62ced86 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -1083,9 +1083,9 @@ void flexran_agent_set_operating_frame_type (mid_t mod_id, int cc_id, int frame_ } /*********** PDCP *************/ -/*PDCP num tx pdu status flexRAN*/ +/*PDCP super frame counter flexRAN*/ uint32_t flexran_get_pdcp_sfn(const mid_t mod_id){ - return Pdcp_sfn[mod_id]; + return pdcp_enb[mod_id].sfn; } /*PDCP num tx pdu status flexRAN*/ @@ -1166,5 +1166,67 @@ uint32_t flexran_get_pdcp_rx_oo(const mid_t mod_id, const mid_t ue_id, const lc return Pdcp_stats_rx_outoforder[mod_id][ue_id][lcid]; } +/******************** RRC *****************************/ - +int flexran_get_rrc_pcell_measid(mid_t mod_id, mid_t ue_id) { + struct rrc_eNB_ue_context_s* ue_context_p = NULL; + uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); + if(ue_context_p != NULL) { + if(ue_context_p->ue_context.measResults != NULL) { + return ue_context_p->ue_context.measResults->measId; + } else { + return -1; + } + } else { + return -1; + } +} +int flexran_get_rrc_pcell_rsrp(mid_t mod_id, mid_t ue_id) { + struct rrc_eNB_ue_context_s* ue_context_p = NULL; + uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); + if(ue_context_p != NULL) { + if(ue_context_p->ue_context.measResults != NULL) { + return ue_context_p->ue_context.measResults->measResultPCell.rsrpResult; + } else { + return -1; + } + } else { + return -1; + } +} +int flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id) { + struct rrc_eNB_ue_context_s* ue_context_p = NULL; + uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); + if(ue_context_p != NULL) { + if(ue_context_p->ue_context.measResults != NULL) { + return ue_context_p->ue_context.measResults->measResultPCell.rsrqResult; + } else { + return -1; + } + } else { + return -1; + } +} +/* +void* flexran_get_rrc_ncell_measresult_eutra(mid_t mod_id, mid_t ue_id) { + struct rrc_eNB_ue_context_s* ue_context_p = NULL; + uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); + if(ue_context_p != NULL) { + if(ue_context_p->ue_context.measResults != NULL) { + return &ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA; + } else { + return -1; + } + } else { + return -1; + } +} +*/ diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index bb9592399e..84723be005 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -391,4 +391,12 @@ uint32_t flexran_get_pdcp_rx_aiat_s(const mid_t mod_id, const mid_t ue_id, cons /*PDCP num of received outoforder pdu status flexRAN*/ uint32_t flexran_get_pdcp_rx_oo(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +/*********************RRC**********************/ +/*Get primary cell measuremeant id flexRAN*/ +int flexran_get_rrc_pcell_measid(mid_t mod_id, mid_t ue_id); +/*Get primary cell RSRP measurement flexRAN*/ +int flexran_get_rrc_pcell_rsrp(mid_t mod_id, mid_t ue_id); + +/*Get primary cell RSRQ measurement flexRAN*/ +int flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 6118ddc745..baba5fa39e 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -69,7 +69,6 @@ extern int otg_enabled; #endif - //----------------------------------------------------------------------------- /* * If PDCP_UNIT_TEST is set here then data flow between PDCP and RLC is broken @@ -403,7 +402,7 @@ boolean_t pdcp_data_req( */ for (pdcp_uid=0; pdcp_uid< NUMBER_OF_UE_MAX;pdcp_uid++){ - if (pdcp_p->rnti[pdcp_uid] == ctxt_pP->rnti ) + if (pdcp_enb[ctxt_pP->module_id].rnti[pdcp_uid] == ctxt_pP->rnti ) break; } @@ -414,9 +413,9 @@ boolean_t pdcp_data_req( Pdcp_stats_tx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=sdu_buffer_sizeP; Pdcp_stats_tx_sn[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=current_sn; - Pdcp_stats_tx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (Pdcp_sfn[ctxt_pP->module_id] - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); - Pdcp_stats_tx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (Pdcp_sfn[ctxt_pP->module_id] - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=Pdcp_sfn[ctxt_pP->module_id]; + Pdcp_stats_tx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + Pdcp_stats_tx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=pdcp_enb[ctxt_pP->module_id].sfn; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_OUT); return ret; @@ -875,8 +874,9 @@ pdcp_data_ind( */ for (pdcp_uid=0; pdcp_uid< NUMBER_OF_UE_MAX;pdcp_uid++){ - if (pdcp_p->rnti[pdcp_uid] == ctxt_pP->rnti ) + if (pdcp_enb[ctxt_pP->module_id].rnti[pdcp_uid] == ctxt_pP->rnti ){ break; + } } Pdcp_stats_rx[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; @@ -889,9 +889,9 @@ pdcp_data_ind( if (oo_flag == 1 ) Pdcp_stats_rx_outoforder[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; - Pdcp_stats_rx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (Pdcp_sfn[ctxt_pP->module_id] - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); - Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(Pdcp_sfn[ctxt_pP->module_id] - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=Pdcp_sfn[ctxt_pP->module_id]; + Pdcp_stats_rx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=pdcp_enb[ctxt_pP->module_id].sfn; #if defined(STOP_ON_IP_TRAFFIC_OVERLOAD) @@ -920,10 +920,10 @@ void pdcp_update_stats(const protocol_ctxt_t* const ctxt_pP){ uint8_t rb_id = 0; // these stats are measured for both eNB and UE on per seond basis - if (Pdcp_sfn[ctxt_pP->module_id] % 1000 == 0){ + if (pdcp_enb[ctxt_pP->module_id].sfn % 1000 == 0){ for (rb_id =0; rb_id < NB_RB_MAX; rb_id ++){ for (pdcp_uid=0; pdcp_uid< NUMBER_OF_UE_MAX;pdcp_uid++){ - //printf("frame %d and subframe %d \n", Pdcp_frame[ctxt_pP->module_id], Pdcp_subframe[ctxt_pP->module_id]); + //printf("frame %d and subframe %d \n", pdcp_enb[ctxt_pP->module_id].frame, pdcp_enb[ctxt_pP->module_id].subframe); // tx stats Pdcp_stats_tx_rate_s[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_id]; // unit: bit/s @@ -975,9 +975,9 @@ pdcp_run ( start_meas(&UE_pdcp_stats[ctxt_pP->module_id].pdcp_run); } - Pdcp_sfn[ctxt_pP->module_id]++; // range: 0 to 18,446,744,073,709,551,615 - Pdcp_frame[ctxt_pP->module_id]=ctxt_pP->frame; // 1023 - Pdcp_subframe[ctxt_pP->module_id]= ctxt_pP->subframe; + pdcp_enb[ctxt_pP->module_id].sfn++; // range: 0 to 18,446,744,073,709,551,615 + pdcp_enb[ctxt_pP->module_id].frame=ctxt_pP->frame; // 1023 + pdcp_enb[ctxt_pP->module_id].subframe= ctxt_pP->subframe; pdcp_update_stats(ctxt_pP); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_RUN, VCD_FUNCTION_IN); @@ -1102,6 +1102,28 @@ pdcp_run ( VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_RUN, VCD_FUNCTION_OUT); } +void pdcp_add_UE(const protocol_ctxt_t* const ctxt_pP){ + int i, ue_flag=1, ret=-1;; + for (i=0; i < NUMBER_OF_UE_MAX; i++){ + if (pdcp_enb[ctxt_pP->module_id].rnti[i] == ctxt_pP->rnti) { + ue_flag=-1; + break; + } + } + if (ue_flag == 1 ){ + for (i=0; i < NUMBER_OF_UE_MAX ; i++){ + if (pdcp_enb[ctxt_pP->module_id].rnti[i] == 0 ){ + pdcp_enb[ctxt_pP->module_id].rnti[i]=ctxt_pP->rnti; + pdcp_enb[ctxt_pP->module_id].uid[i]=i; + pdcp_enb[ctxt_pP->module_id].num_ues++; + printf("add new uid is %d %x\n\n", i, ctxt_pP->rnti); + ret=1; + break; + } + } + } + //return ret; +} //----------------------------------------------------------------------------- boolean_t @@ -1115,7 +1137,7 @@ pdcp_remove_UE( hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; - // check and remove SRBs first + // check and remove SRBs first for (srb_id=0; srb_id<2; srb_id++) { key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, srb_id, SRB_FLAG_YES); @@ -1130,6 +1152,19 @@ pdcp_remove_UE( (void)h_rc; /* remove gcc warning "set but not used" */ + // remove ue for pdcp enb inst + for (i=0; i < NUMBER_OF_UE_MAX; i++) { + if (pdcp_enb[ctxt_pP->module_id].rnti[i] == ctxt_pP->rnti ) { + LOG_I(PDCP, "remove uid is %d/%d %x\n", i, + pdcp_enb[ctxt_pP->module_id].uid[i], + pdcp_enb[ctxt_pP->module_id].rnti[i]); + pdcp_enb[ctxt_pP->module_id].uid[i]=0; + pdcp_enb[ctxt_pP->module_id].rnti[i]=0; + pdcp_enb[ctxt_pP->module_id].num_ues--; + break; + } + } + return 1; } @@ -1524,7 +1559,6 @@ rrc_pdcp_config_asn1_req ( return 0; } - //----------------------------------------------------------------------------- boolean_t pdcp_config_req_asn1 ( @@ -1545,19 +1579,14 @@ pdcp_config_req_asn1 ( uint8_t *const kUPenc_pP) //----------------------------------------------------------------------------- { - int i; + switch (actionP) { case CONFIG_ACTION_ADD: DevAssert(pdcp_pP != NULL); if (ctxt_pP->enb_flag == ENB_FLAG_YES) { pdcp_pP->is_ue = FALSE; - for (i=0; i < NUMBER_OF_UE_MAX; i++) { - if (pdcp_pP->rnti[i] != 0 ) continue ; // skip active ues - pdcp_pP->rnti[i]=ctxt_pP->rnti; - pdcp_pP->uid[i]=i; - Pdcp_num_ues[ctxt_pP->module_id]++; - break; - } + pdcp_add_ue(ctxt_pP); + //pdcp_eNB_UE_instance_to_rnti[ctxtP->module_id] = ctxt_pP->rnti; pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] = ctxt_pP->rnti; //pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % NUMBER_OF_UE_MAX; @@ -1658,15 +1687,7 @@ pdcp_config_req_asn1 ( rb_idP); if (ctxt_pP->enb_flag == ENB_FLAG_YES) { - - for (i=0; i < NUMBER_OF_UE_MAX; i++) { - if (pdcp_pP->rnti[i] == ctxt_pP->rnti ) { - pdcp_pP->rnti[i]=0; - pdcp_pP->uid[i]=0; - Pdcp_num_ues[ctxt_pP->module_id]--; - break; - } - } + // pdcp_remove_UE(ctxt_pP); } /* Security keys */ @@ -2046,10 +2067,8 @@ void pdcp_layer_init(void) pdcp_output_header_bytes_to_write=0; pdcp_input_sdu_remaining_size_to_read=0; - memset(Pdcp_sfn, 0, sizeof(Pdcp_sfn)); - memset(Pdcp_frame, 0, sizeof(Pdcp_frame)); - memset(Pdcp_subframe, 0, sizeof(Pdcp_subframe)); - memset(Pdcp_num_ues, 0, sizeof(Pdcp_num_ues)); + memset(pdcp_enb, 0, sizeof(pdcp_enb_t)); + memset(Pdcp_stats_tx, 0, sizeof(Pdcp_stats_tx)); memset(Pdcp_stats_tx_s, 0, sizeof(Pdcp_stats_tx_s)); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index e9f20e0a94..cf3d927051 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -94,11 +94,12 @@ extern int pdcp_instance_cnt; int init_pdcp_thread(void); void cleanup_pdcp_thread(void); +/* public_pdcp(uint64_t Pdcp_sfn[MAX_NUM_CCs]); public_pdcp(frame_t Pdcp_frame[MAX_NUM_CCs]); public_pdcp(sub_frame_t Pdcp_subframe[MAX_NUM_CCs]); public_pdcp(uint16_t Pdcp_num_ues[MAX_NUM_CCs]); - +*/ public_pdcp(uint32_t Pdcp_stats_tx_bytes[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); public_pdcp(uint32_t Pdcp_stats_tx_bytes_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); @@ -131,7 +132,19 @@ public_pdcp(void pdcp_update_perioidical_stats(const protocol_ctxt_t* const ctx /*Packet Probing for agent PDCP*/ //public_pdcp(uint64_t *pdcp_packet_counter); //public_pdcp(uint64_t *pdcp_size_packet); +typedef struct pdcp_enb_s { + // used for eNB stats generation + uint16_t uid[NUMBER_OF_UE_MAX]; + rnti_t rnti[NUMBER_OF_UE_MAX]; + uint16_t num_ues; + + uint64_t sfn; + frame_t frame; + sub_frame_t subframe; + +} pdcp_enb_t; +public_pdcp(pdcp_enb_t pdcp_enb[MAX_NUM_CCs]); typedef struct pdcp_stats_s { time_stats_t pdcp_run; @@ -154,11 +167,7 @@ typedef struct pdcp_s { boolean_t is_ue; boolean_t is_srb; - // used for eNB stats generation - uint16_t uid[NUMBER_OF_UE_MAX]; // local to pdcp - rnti_t rnti[NUMBER_OF_UE_MAX]; - - /* Configured security algorithms */ + /* Configured security algorithms */ uint8_t cipheringAlgorithm; uint8_t integrityProtAlgorithm; @@ -360,9 +369,15 @@ public_pdcp(boolean_t pdcp_config_req_asn1 ( uint8_t *const kRRCint, uint8_t *const kUPenc)); - +/*! \fn void pdcp_add_UE(const protocol_ctxt_t* const ctxt_pP) +* \brief Function (for RRC) to add a new UE in PDCP module +* \param[in] ctxt_pP Running context. +* \return A status about the processing, OK or error code. +*/ +public_pdcp(void pdcp_add_UE(const protocol_ctxt_t* const ctxt_pP)); + /*! \fn boolean_t pdcp_remove_UE(const protocol_ctxt_t* const ctxt_pP) -* \brief Function for RRC to configure a Radio Bearer clear all PDCP resources for a particular UE +* \brief Function for RRC to remove UE from PDCP module hashtable * \param[in] ctxt_pP Running context. * \return A status about the processing, OK or error code. */ diff --git a/openair2/RRC/LITE/L2_interface.c b/openair2/RRC/LITE/L2_interface.c index 6a64d7811e..71616ffd91 100644 --- a/openair2/RRC/LITE/L2_interface.c +++ b/openair2/RRC/LITE/L2_interface.c @@ -597,10 +597,10 @@ rrc_data_ind( rb_id_t DCCH_index = Srb_id; if (ctxt_pP->enb_flag == ENB_FLAG_NO) { - LOG_N(RRC, "[UE %x] Frame %d: received a DCCH %d message on SRB %d with Size %d from eNB %d\n", + LOG_D(RRC, "[UE %x] Frame %d: received a DCCH %d message on SRB %d with Size %d from eNB %d\n", ctxt_pP->module_id, ctxt_pP->frame, DCCH_index,Srb_id,sdu_sizeP, ctxt_pP->eNB_index); } else { - LOG_N(RRC, "[eNB %d] Frame %d: received a DCCH %d message on SRB %d with Size %d from UE %x\n", + LOG_D(RRC, "[eNB %d] Frame %d: received a DCCH %d message on SRB %d with Size %d from UE %x\n", ctxt_pP->module_id, ctxt_pP->frame, DCCH_index, diff --git a/openair2/RRC/LITE/defs.h b/openair2/RRC/LITE/defs.h index 0a2043fd4e..29bc3e3997 100644 --- a/openair2/RRC/LITE/defs.h +++ b/openair2/RRC/LITE/defs.h @@ -374,7 +374,8 @@ typedef struct eNB_RRC_UE_s { SRB_INFO_TABLE_ENTRY Srb2; MeasConfig_t* measConfig; HANDOVER_INFO* handover_info; - + MeasResults_t* measResults; + #if defined(ENABLE_SECURITY) /* KeNB as derived from KASME received from EPC */ uint8_t kenb[32]; diff --git a/openair2/RRC/LITE/proto.h b/openair2/RRC/LITE/proto.h index 20bc99ab79..3b64d2a45c 100644 --- a/openair2/RRC/LITE/proto.h +++ b/openair2/RRC/LITE/proto.h @@ -425,7 +425,7 @@ rrc_eNB_generate_SecurityModeCommand( void rrc_eNB_process_MeasurementReport( const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + rrc_eNB_ue_context_t* ue_context_pP, const MeasResults_t* const measResults2 ); diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index 05e59755c2..aaf12da175 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -2840,32 +2840,56 @@ rrc_eNB_generate_RRCConnectionReconfiguration_SCell( void rrc_eNB_process_MeasurementReport( const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + rrc_eNB_ue_context_t* ue_context_pP, const MeasResults_t* const measResults2 ) //----------------------------------------------------------------------------- { - // T(T_ENB_RRC_MEASUREMENT_REPORT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - // T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + int i=0; + int neighboring_cells=-1; + + T(T_ENB_RRC_MEASUREMENT_REPORT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + if (measResults2 == NULL ) + return; + + if (measResults2->measId > 0 ){ + if (ue_context_pP->ue_context.measResults == NULL) { + ue_context_pP->ue_context.measResults = CALLOC(1, sizeof(MeasResults_t)); + } + ue_context_pP->ue_context.measResults->measId=measResults2->measId; + ue_context_pP->ue_context.measResults->measResultPCell.rsrpResult=measResults2->measResultPCell.rsrpResult; + ue_context_pP->ue_context.measResults->measResultPCell.rsrqResult=measResults2->measResultPCell.rsrqResult; + LOG_D(RRC, "[eNB %d]Frame %d: UE %x (Measurement Id %d): RSRP of Source %ld\n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rnti, (int)measResults2->measId, ue_context_pP->ue_context.measResults->measResultPCell.rsrpResult-140); + LOG_D(RRC, "[eNB %d]Frame %d: UE %x (Measurement Id %d): RSRQ of Source %ld\n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rnti, (int)measResults2->measId, ue_context_pP->ue_context.measResults->measResultPCell.rsrqResult/2 - 20); + } + if (measResults2->measResultNeighCells == NULL) + return; - // LOG_I(RRC, "[eNB %d] Frame %d: Process Measurement Report From UE %x (Measurement Id %d)\n", - // ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rnti, (int)measResults2->measId); - - // if (measResults2->measResultNeighCells->choice.measResultListEUTRA.list.count > 0) { - // LOG_I(RRC, "Physical Cell Id %d\n", - // (int)measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]->physCellId); - // LOG_I(RRC, "RSRP of Target %d\n", - // (int)*(measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]-> - // measResult.rsrpResult)); - // LOG_I(RRC, "RSRQ of Target %d\n", - // (int)*(measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]-> - // measResult.rsrqResult)); - // } + if (measResults2->measResultNeighCells->choice.measResultListEUTRA.list.count > 0) { + neighboring_cells=measResults2->measResultNeighCells->choice.measResultListEUTRA.list.count; + + if (ue_context_pP->ue_context.measResults->measResultNeighCells == NULL) { + + ue_context_pP->ue_context.measResults->measResultNeighCells = CALLOC(1, sizeof(*measResults2->measResultNeighCells)*neighboring_cells); + } + ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count=neighboring_cells; + for (i=0; i < neighboring_cells; i++){ + memcpy (ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i], + measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i], + sizeof(MeasResultListEUTRA_t)); + + LOG_D(RRC, "Physical Cell Id %d\n", + (int)ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->physCellId); + LOG_D(RRC, "RSRP of Target %d\n", + (int)*(ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrpResult)); + LOG_D(RRC, "RSRQ of Target %d\n", + (int)*(ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrqResult)); + } + } // #if defined(Rel10) || defined(Rel14) - LOG_I(RRC, "RSRP of Source %ld\n", measResults2->measResultPCell.rsrpResult); - LOG_I(RRC, "RSRQ of Source %ld\n", measResults2->measResultPCell.rsrqResult); // #else @@ -5109,13 +5133,6 @@ rrc_eNB_decode_dcch( ue_context_p, &ul_dcch_msg->message.choice.c1.choice.measurementReport. criticalExtensions.choice.c1.choice.measurementReport_r8.measResults); - #if defined(FLEXRAN_AGENT_SB_IF) - - if (rrc_agent_registered[ctxt_pP->module_id]) { - agent_rrc_xface[ctxt_pP->eNB_index]->flexran_trigger_rrc_measurements (ctxt_pP->module_id, &ul_dcch_msg->message.choice.c1.choice.measurementReport.criticalExtensions.choice.c1.choice.measurementReport_r8.measResults); - } -#endif - break; case UL_DCCH_MessageType__c1_PR_rrcConnectionReconfigurationComplete: From 49ea4748072f50107d47bf9260003861fb42a896 Mon Sep 17 00:00:00 2001 From: Navid Nikaein Date: Wed, 13 Dec 2017 17:00:33 +0100 Subject: [PATCH 045/195] Fix the compilation issues --- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index baba5fa39e..df85b06d06 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -1136,7 +1136,7 @@ pdcp_remove_UE( DRB_Identity_t drb_id = 0; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; - + int i; // check and remove SRBs first for (srb_id=0; srb_id<2; srb_id++) { @@ -1585,7 +1585,7 @@ pdcp_config_req_asn1 ( DevAssert(pdcp_pP != NULL); if (ctxt_pP->enb_flag == ENB_FLAG_YES) { pdcp_pP->is_ue = FALSE; - pdcp_add_ue(ctxt_pP); + pdcp_add_UE(ctxt_pP); //pdcp_eNB_UE_instance_to_rnti[ctxtP->module_id] = ctxt_pP->rnti; pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] = ctxt_pP->rnti; From 6e6a462dc420def86472dc4e0530c5592437b5ee Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 14 Dec 2017 12:46:38 +0100 Subject: [PATCH 046/195] check whether RRC instance is present in RAN API --- openair2/ENB_APP/flexran_agent_ran_api.c | 73 +++++++++++++++++++++--- 1 file changed, 64 insertions(+), 9 deletions(-) diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 17d62ced86..3ecbf77e11 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -65,17 +65,27 @@ void flexran_set_enb_vars(mid_t mod_id, ran_name_t ran){ error: LOG_E(FLEXRAN_AGENT, "unknown RAN name %d\n", ran); } -static int mac_xface_not_ready(void); -static int mac_xface_not_ready(void){ - if (mac_xface == NULL) +static int mac_xface_not_ready(void) +{ + if (mac_xface == NULL) { return 1; + } else { //printf("max_xface %p %d \n", mac_xface, mac_xface->active); return 0;// !mac_xface->active; } } - + +static int eNB_rrc_inst_not_ready(void) +{ + if (NULL == eNB_rrc_inst) { + return 1; + } + else { + return 0; + } +} int flexran_get_current_time_ms (mid_t mod_id, int subframe_flag){ if (enb[mod_id] == NULL) return 0; @@ -681,6 +691,8 @@ int flexran_get_num_pdcch_symb(mid_t mod_id, int CC_id) { int flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id) { struct rrc_eNB_ue_context_s* ue_context_p = NULL; uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + if (eNB_rrc_inst_not_ready()) return -1; ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); if(ue_context_p != NULL) { @@ -698,6 +710,8 @@ int flexran_get_meas_gap_config(mid_t mod_id, mid_t ue_id) { struct rrc_eNB_ue_context_s* ue_context_p = NULL; uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + if (eNB_rrc_inst_not_ready()) return -1; + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); if(ue_context_p != NULL) { if(ue_context_p->ue_context.measGapConfig != NULL) { @@ -719,6 +733,8 @@ int flexran_get_meas_gap_config(mid_t mod_id, mid_t ue_id) { int flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id) { struct rrc_eNB_ue_context_s* ue_context_p = NULL; uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + if (eNB_rrc_inst_not_ready()) return -1; ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); @@ -741,6 +757,8 @@ int flexran_get_rrc_status(const mid_t mod_id, const rnti_t rntiP){ struct rrc_eNB_ue_context_s* ue_context_p = NULL; + if (eNB_rrc_inst_not_ready()) return -1; + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); if (ue_context_p != NULL) { @@ -805,6 +823,8 @@ int flexran_get_res_alloc_type1(mid_t ue_id) { int flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id) { struct rrc_eNB_ue_context_s* ue_context_p = NULL; uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + if (eNB_rrc_inst_not_ready()) return -1; ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); @@ -822,6 +842,8 @@ int flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id) { int flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id) { struct rrc_eNB_ue_context_s* ue_context_p = NULL; uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + if (eNB_rrc_inst_not_ready()) return -1; ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); if(ue_context_p != NULL) { @@ -839,6 +861,8 @@ int flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id) { int flexran_get_maxHARQ_TX(mid_t mod_id, mid_t ue_id) { struct rrc_eNB_ue_context_s* ue_context_p = NULL; uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + if (eNB_rrc_inst_not_ready()) return -1; ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); if(ue_context_p != NULL) { @@ -852,6 +876,8 @@ int flexran_get_maxHARQ_TX(mid_t mod_id, mid_t ue_id) { int flexran_get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id) { struct rrc_eNB_ue_context_s* ue_context_p = NULL; uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + if (eNB_rrc_inst_not_ready()) return -1; ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); if(ue_context_p != NULL) { @@ -868,6 +894,8 @@ int flexran_get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id) { int flexran_get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id) { struct rrc_eNB_ue_context_s* ue_context_p = NULL; uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + if (eNB_rrc_inst_not_ready()) return -1; ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); if(ue_context_p != NULL) { @@ -884,6 +912,8 @@ int flexran_get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id) { int flexran_get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id) { struct rrc_eNB_ue_context_s* ue_context_p = NULL; uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + if (eNB_rrc_inst_not_ready()) return -1; ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); if(ue_context_p != NULL) { @@ -901,6 +931,8 @@ int flexran_get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id) { int flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id) { struct rrc_eNB_ue_context_s* ue_context_p = NULL; uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + if (eNB_rrc_inst_not_ready()) return -1; ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); if(ue_context_p != NULL) { @@ -914,13 +946,18 @@ int flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id) { } int flexran_get_ack_nack_simultaneous_trans(mid_t mod_id,mid_t ue_id) { - return (&eNB_rrc_inst[mod_id])->carrier[0].sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; + + if (eNB_rrc_inst_not_ready()) return -1; + + return (&eNB_rrc_inst[mod_id])->carrier[0].sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; } int flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id) { struct rrc_eNB_ue_context_s* ue_context_p = NULL; uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - + + if (eNB_rrc_inst_not_ready()) return -1; + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); if(ue_context_p != NULL) { @@ -935,6 +972,8 @@ int flexran_get_tdd_ack_nack_feedback(mid_t mod_id, mid_t ue_id) { // TODO: This needs fixing return -1; + /* if (eNB_rrc_inst_not_ready()) return -1; */ + /* struct rrc_eNB_ue_context_s* ue_context_p = NULL; */ /* uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); */ @@ -954,6 +993,8 @@ int flexran_get_tdd_ack_nack_feedback(mid_t mod_id, mid_t ue_id) { int flexran_get_ack_nack_repetition_factor(mid_t mod_id, mid_t ue_id) { struct rrc_eNB_ue_context_s* ue_context_p = NULL; uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + if (eNB_rrc_inst_not_ready()) return -1; ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); if(ue_context_p != NULL) { @@ -972,6 +1013,8 @@ int flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id) { struct rrc_eNB_ue_context_s* ue_context_p = NULL; uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + if (eNB_rrc_inst_not_ready()) return -1; + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); if(ue_context_p != NULL) { if(ue_context_p->ue_context.mac_MainConfig != NULL){ @@ -989,7 +1032,9 @@ int flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id) { int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id) { struct rrc_eNB_ue_context_s* ue_context_p = NULL; uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - + + if (eNB_rrc_inst_not_ready()) return -1; + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); if(ue_context_p != NULL) { @@ -1035,6 +1080,8 @@ int flexran_get_antenna_ports(mid_t mod_id, int CC_id){ LTE_DL_FRAME_PARMS *frame_parms; + if (mac_xface_not_ready()) return 0; + frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); return (frame_parms == NULL)? 0:frame_parms->nb_antenna_ports_eNB; @@ -1171,6 +1218,8 @@ uint32_t flexran_get_pdcp_rx_oo(const mid_t mod_id, const mid_t ue_id, const lc int flexran_get_rrc_pcell_measid(mid_t mod_id, mid_t ue_id) { struct rrc_eNB_ue_context_s* ue_context_p = NULL; uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + if (eNB_rrc_inst_not_ready()) return -1; ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); if(ue_context_p != NULL) { @@ -1186,7 +1235,9 @@ int flexran_get_rrc_pcell_measid(mid_t mod_id, mid_t ue_id) { int flexran_get_rrc_pcell_rsrp(mid_t mod_id, mid_t ue_id) { struct rrc_eNB_ue_context_s* ue_context_p = NULL; uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - + + if (eNB_rrc_inst_not_ready()) return -1; + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); if(ue_context_p != NULL) { if(ue_context_p->ue_context.measResults != NULL) { @@ -1201,7 +1252,9 @@ int flexran_get_rrc_pcell_rsrp(mid_t mod_id, mid_t ue_id) { int flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id) { struct rrc_eNB_ue_context_s* ue_context_p = NULL; uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - + + if (eNB_rrc_inst_not_ready()) return -1; + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); if(ue_context_p != NULL) { if(ue_context_p->ue_context.measResults != NULL) { @@ -1217,6 +1270,8 @@ int flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id) { void* flexran_get_rrc_ncell_measresult_eutra(mid_t mod_id, mid_t ue_id) { struct rrc_eNB_ue_context_s* ue_context_p = NULL; uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + if (eNB_rrc_inst_not_ready()) return -1; ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); if(ue_context_p != NULL) { From 612ab055d7b97e02503f2f1143ba2092c3a1cd9b Mon Sep 17 00:00:00 2001 From: Navid Nikaein Date: Wed, 6 Dec 2017 12:23:16 +0100 Subject: [PATCH 047/195] Add control logic to reconfigure and start eNB --- openair2/ENB_APP/enb_app.c | 36 ++++- openair2/ENB_APP/enb_config.c | 22 ++- openair2/ENB_APP/enb_config.h | 11 +- .../ENB_APP/flexran_agent_common_internal.c | 9 +- .../LAYER2/MAC/eNB_scheduler_primitives.c | 4 + targets/COMMON/create_tasks.c | 19 ++- targets/COMMON/create_tasks.h | 1 + .../CONF/enb.band7.flexran.usrpb210.conf | 6 +- targets/RT/USER/lte-softmodem.c | 143 ++++++++++++------ 9 files changed, 175 insertions(+), 76 deletions(-) diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index de0d0490aa..4a5981f509 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -55,6 +55,17 @@ extern unsigned char NB_eNB_INST; #endif +extern volatile int node_control_state; + +static void enb_app_wait_reconfig_cmd (void) +{ + LOG_I(ENB_APP, "ENB APP await reconfiguration command\n"); + + while (node_control_state == ENB_WAIT_RECONFIGURATION_CMD) { + usleep(200000); + } + sleep(2); // wait for createing other tasks +} #if defined(ENABLE_ITTI) @@ -270,7 +281,7 @@ static uint32_t eNB_app_register(uint32_t enb_id_start, uint32_t enb_id_end, con /*------------------------------------------------------------------------------*/ void *eNB_app_task(void *args_p) { - const Enb_properties_array_t *enb_properties_p = NULL; + Enb_properties_array_t *enb_properties_p = NULL; #if defined(ENABLE_ITTI) uint32_t enb_nb = 1; /* Default number of eNB is 1 */ uint32_t enb_id_start = 0; @@ -309,19 +320,28 @@ void *eNB_app_task(void *args_p) "Number of eNB is greater than eNB defined in configuration file (%d/%d)!", enb_nb, enb_properties_p->number); +#if defined (FLEXRAN_AGENT_SB_IF) + + for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { + flexran_agent_start(enb_id, enb_properties_p); + } + // wait for config comd from the controller/network app + enb_app_wait_reconfig_cmd(); + + // set again the ran api vars + for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { + printf("\n set again enb vars %d\n", enb_id); + flexran_set_enb_vars(enb_id, RAN_LTE_OAI); + } + +#endif + for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { configure_phy(enb_id, enb_properties_p); configure_rrc(enb_id, enb_properties_p); } -#if defined (FLEXRAN_AGENT_SB_IF) - for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { - printf("\n start enb agent %d\n", enb_id); - flexran_agent_start(enb_id, enb_properties_p); - } -#endif - # if defined(ENABLE_USE_MME) /* Try to register each eNB */ registered_enb = 0; diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 09d7495a69..6282523b55 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -197,6 +197,7 @@ #define ENB_CONFIG_STRING_FLEXRAN_AGENT_IPV4_ADDRESS "FLEXRAN_AGENT_IPV4_ADDRESS" #define ENB_CONFIG_STRING_FLEXRAN_AGENT_PORT "FLEXRAN_AGENT_PORT" #define ENB_CONFIG_STRING_FLEXRAN_AGENT_CACHE "FLEXRAN_AGENT_CACHE" +#define ENB_CONFIG_STRING_FLEXRAN_AGENT_AWAIT_RECONF "FLEXRAN_AGENT_AWAIT_RECONF" #define ENB_CONFIG_STRING_RRH_GW_CONFIG "rrh_gw_config" #define ENB_CONFIG_STRING_RRH_GW_LOCAL_IF_NAME "local_if_name" @@ -351,6 +352,8 @@ void enb_config_display(void) // printf( "\tInterface IP Address: \t%s:\n",enb_properties.properties[i]->flexran_agent_ipv4_address); printf( "\tInterface PORT: \t%d:\n\n",enb_properties.properties[i]->flexran_agent_port); printf( "\tCache directory: \t%s:\n",enb_properties.properties[i]->flexran_agent_cache); + printf( "\teNB Control State: \t%s:\n",(enb_properties.properties[i]->flexran_agent_reconf==0)? "ENB_NORMAL_OPERATION":"ENB_WAIT_RECONFIGURATION_CMD"); + #endif @@ -536,7 +539,7 @@ extern int asn1_xer_print; #else #define libconfig_int int #endif -const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) +Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) { config_t cfg; config_setting_t *setting = NULL; @@ -689,6 +692,8 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) char* flexran_agent_ipv4_address = NULL; libconfig_int flexran_agent_port = 0; char* flexran_agent_cache = NULL; + char* flexran_agent_reconf = NULL; + libconfig_int otg_ue_id = 0; char* otg_app_type = NULL; char* otg_bg_traffic = NULL; @@ -2580,6 +2585,9 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) &flexran_agent_port) && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_CACHE, (const char **)&flexran_agent_cache) + && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_AWAIT_RECONF, + (const char **)&flexran_agent_reconf) + ) ) { enb_properties.properties[enb_properties_index]->flexran_agent_interface_name = strdup(flexran_agent_interface_name); @@ -2590,8 +2598,14 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) IPV4_STR_ADDR_TO_INT_NWBO (address, enb_properties.properties[enb_properties_index]->flexran_agent_ipv4_address, "BAD IP ADDRESS FORMAT FOR eNB Agent !\n" ); } - enb_properties.properties[enb_properties_index]->flexran_agent_port = flexran_agent_port; - enb_properties.properties[enb_properties_index]->flexran_agent_cache = strdup(flexran_agent_cache); + enb_properties.properties[enb_properties_index]->flexran_agent_port = flexran_agent_port; + enb_properties.properties[enb_properties_index]->flexran_agent_cache = strdup(flexran_agent_cache); + if ((strcmp(flexran_agent_reconf, "yes") == 0) || (strcmp(flexran_agent_reconf, "YES") == 0)){ + enb_properties.properties[enb_properties_index]->flexran_agent_reconf = 1; + } else { + enb_properties.properties[enb_properties_index]->flexran_agent_reconf = 0; + } + } } @@ -2885,7 +2899,7 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) } -const Enb_properties_array_t *enb_config_get(void) +Enb_properties_array_t *enb_config_get(void) { return &enb_properties; } diff --git a/openair2/ENB_APP/enb_config.h b/openair2/ENB_APP/enb_config.h index 094360749b..8e914458bf 100644 --- a/openair2/ENB_APP/enb_config.h +++ b/openair2/ENB_APP/enb_config.h @@ -237,6 +237,8 @@ typedef struct Enb_properties_s { in_addr_t flexran_agent_ipv4_address; tcp_udp_port_t flexran_agent_port; char *flexran_agent_cache; + int flexran_agent_reconf; + /* Nb of RRH to connect to */ uint8_t nb_rrh_gw; @@ -276,15 +278,20 @@ typedef struct Enb_properties_s { #endif } Enb_properties_t; +typedef enum { + ENB_NORMAL_OPERATION=0x0, + ENB_WAIT_RECONFIGURATION_CMD=0x1 +} ENB_MODULE_STATE; + typedef struct Enb_properties_array_s { int number; Enb_properties_t *properties[MAX_ENB]; } Enb_properties_array_t; void enb_config_display(void); -const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP); +Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP); -const Enb_properties_array_t *enb_config_get(void); +Enb_properties_array_t *enb_config_get(void); #endif /* ENB_CONFIG_H_ */ /** @} */ diff --git a/openair2/ENB_APP/flexran_agent_common_internal.c b/openair2/ENB_APP/flexran_agent_common_internal.c index 839fb4c784..c883523855 100644 --- a/openair2/ENB_APP/flexran_agent_common_internal.c +++ b/openair2/ENB_APP/flexran_agent_common_internal.c @@ -31,7 +31,7 @@ #include "flexran_agent_common_internal.h" #include "flexran_agent_mac_internal.h" -extern volatile int reconfigure_enb; +extern volatile int node_control_state; int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy_length) { @@ -72,8 +72,8 @@ int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy if (parse_enb_id(mod_id, &parser) == -1) { goto error; } else { // succeful parse and setting - LOG_I(ENB_APP, "Successful parsed config for enb system\n"); - //reconfigure_enb=RECONF_FREQ; + node_control_state= ENB_NORMAL_OPERATION; + LOG_I(ENB_APP, "Successful parsed config for enb system, entering normal state\n"); } } else if (strcmp((char *) event.data.scalar.value, "mac") == 0) { LOG_D(ENB_APP, "This is intended for the mac system\n"); @@ -258,6 +258,9 @@ int parse_enb_config_parameters(mid_t mod_id, yaml_parser_t *parser) { yaml_event_delete(&event); } + /* reflect in RAN API */ + flexran_set_enb_vars(mod_id, RAN_LTE_OAI); + return 0; error: diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 610700f3e8..a678178435 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -131,6 +131,7 @@ int UE_num_active_CC(UE_list_t *listP,int ue_idP) int UE_PCCID(module_id_t mod_idP,int ue_idP) //------------------------------------------------------------------------------ { + if (eNB_mac_inst == NULL) return 0; return(eNB_mac_inst[mod_idP].UE_list.pCC_id[ue_idP]); } @@ -139,6 +140,7 @@ rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP) //------------------------------------------------------------------------------ { + if (eNB_mac_inst == NULL) return 0; rnti_t rnti = eNB_mac_inst[mod_idP].UE_list.UE_template[UE_PCCID(mod_idP,ue_idP)][ue_idP].rnti; if (rnti>0) { @@ -154,6 +156,7 @@ rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP) boolean_t is_UE_active(module_id_t mod_idP, int ue_idP) //------------------------------------------------------------------------------ { + if (eNB_mac_inst == NULL) return 0; return(eNB_mac_inst[mod_idP].UE_list.active[ue_idP]); } @@ -182,6 +185,7 @@ uint8_t find_active_UEs(module_id_t module_idP,int CC_id){ int UE_BSR (uint8_t mod_id, uint8_t ue_id, uint8_t lcid) { + if (eNB_mac_inst == NULL) return 0; return eNB_mac_inst[mod_id].UE_list.UE_template[UE_PCCID(mod_id,ue_id)][ue_id].bsr_info[lcid]; } diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c index c28b9e839c..1ca55b5926 100644 --- a/targets/COMMON/create_tasks.c +++ b/targets/COMMON/create_tasks.c @@ -40,6 +40,17 @@ # endif # include "enb_app.h" +int create_enb_app_task(uint32_t enb_nb) +{ + if (enb_nb > 0) { + if (itti_create_task (TASK_ENB_APP, eNB_app_task, NULL) < 0) { + LOG_E(ENB_APP, "Create task for eNB APP failed\n"); + return -1; + } + } + return 0; +} + int create_tasks(uint32_t enb_nb, uint32_t ue_nb) { itti_wait_ready(1); @@ -48,14 +59,6 @@ int create_tasks(uint32_t enb_nb, uint32_t ue_nb) return -1; } - if (enb_nb > 0) { - /* Last task to create, others task must be ready before its start */ - if (itti_create_task (TASK_ENB_APP, eNB_app_task, NULL) < 0) { - LOG_E(ENB_APP, "Create task for eNB APP failed\n"); - return -1; - } - } - # ifdef OPENAIR2 { diff --git a/targets/COMMON/create_tasks.h b/targets/COMMON/create_tasks.h index 6545f4b9d9..3455b283b5 100644 --- a/targets/COMMON/create_tasks.h +++ b/targets/COMMON/create_tasks.h @@ -27,6 +27,7 @@ extern void *l2l1_task(void *arg); int create_tasks(uint32_t enb_nb, uint32_t ue_nb); +int create_enb_app_task(uint32_t enb_nb); #endif #endif /* CREATE_TASKS_H_ */ diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.flexran.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.flexran.usrpb210.conf index 4ee429f45e..378d932f57 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.flexran.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.flexran.usrpb210.conf @@ -155,10 +155,11 @@ eNBs = NETWORK_CONTROLLER : { - FLEXRAN_AGENT_INTERFACE_NAME = "eth1"; - FLEXRAN_AGENT_IPV4_ADDRESS = "10.0.2.5/30"; + FLEXRAN_AGENT_INTERFACE_NAME = "lo"; + FLEXRAN_AGENT_IPV4_ADDRESS = "127.0.0.1/30"; FLEXRAN_AGENT_PORT = 2210; FLEXRAN_AGENT_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AGENT_AWAIT_RECONF = "no"; }; log_config : @@ -177,6 +178,7 @@ eNBs = pdcp_log_verbosity ="medium"; rrc_log_level ="info"; rrc_log_verbosity ="medium"; + }; } ); diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index a1f3bcb57b..042f77eea7 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -174,6 +174,8 @@ eNB_func_t node_function[MAX_NUM_CCs]; eNB_timing_t node_timing[MAX_NUM_CCs]; int16_t node_synch_ref[MAX_NUM_CCs]; +volatile int16_t node_control_state; + uint32_t target_dl_mcs = 28; //maximum allowed mcs uint32_t target_ul_mcs = 20; uint32_t timing_advance = 0; @@ -232,6 +234,12 @@ threads_t threads= {-1,-1,-1,-1,-1,-1,-1}; */ uint8_t abstraction_flag=0; +/* */ + +/* overrid the enb configuration params*/ +static void reconfigure_enb_params(int enb_id); + + /*---------------------BMC: timespec helpers -----------------------------*/ struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; @@ -1080,11 +1088,20 @@ static void get_options (int argc, char **argv) { "Number of eNB is greater than eNB defined in configuration file %s (%d/%d)!", conf_config_file_name, NB_eNB_INST, enb_properties->number); + NB_eNB_INST=enb_properties->number; + /* Update some simulation parameters */ for (i=0; i < enb_properties->number; i++) { AssertFatal (MAX_NUM_CCs == enb_properties->properties[i]->nb_cc, "lte-softmodem compiled with MAX_NUM_CCs=%d, but only %d CCs configured for eNB %d!", MAX_NUM_CCs, enb_properties->properties[i]->nb_cc, i); + + if (enb_properties->properties[i]->flexran_agent_reconf == 1) { + node_control_state = ENB_WAIT_RECONFIGURATION_CMD; + } else { + node_control_state = ENB_NORMAL_OPERATION; + } + eth_params = (eth_params_t*)malloc(enb_properties->properties[i]->nb_rrh_gw * sizeof(eth_params_t)); memset(eth_params, 0, enb_properties->properties[i]->nb_rrh_gw * sizeof(eth_params_t)); @@ -1133,37 +1150,9 @@ static void get_options (int argc, char **argv) { } - for (CC_id=0; CC_idproperties[i]->cc_node_function[CC_id]; - node_timing[CC_id] = enb_properties->properties[i]->cc_node_timing[CC_id]; - node_synch_ref[CC_id] = enb_properties->properties[i]->cc_node_synch_ref[CC_id]; - - frame_parms[CC_id]->frame_type = enb_properties->properties[i]->frame_type[CC_id]; - frame_parms[CC_id]->tdd_config = enb_properties->properties[i]->tdd_config[CC_id]; - frame_parms[CC_id]->tdd_config_S = enb_properties->properties[i]->tdd_config_s[CC_id]; - frame_parms[CC_id]->Ncp = enb_properties->properties[i]->prefix_type[CC_id]; - - //for (j=0; j < enb_properties->properties[i]->nb_cc; j++ ){ - frame_parms[CC_id]->Nid_cell = enb_properties->properties[i]->Nid_cell[CC_id]; - frame_parms[CC_id]->N_RB_DL = enb_properties->properties[i]->N_RB_DL[CC_id]; - frame_parms[CC_id]->N_RB_UL = enb_properties->properties[i]->N_RB_DL[CC_id]; - frame_parms[CC_id]->nb_antennas_tx = enb_properties->properties[i]->nb_antennas_tx[CC_id]; - frame_parms[CC_id]->nb_antenna_ports_eNB = enb_properties->properties[i]->nb_antenna_ports[CC_id]; - frame_parms[CC_id]->nb_antennas_rx = enb_properties->properties[i]->nb_antennas_rx[CC_id]; - - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex = enb_properties->properties[i]->prach_config_index[CC_id]; - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset = enb_properties->properties[i]->prach_freq_offset[CC_id]; - - frame_parms[CC_id]->mode1_flag = (frame_parms[CC_id]->nb_antenna_ports_eNB == 1) ? 1 : 0; - frame_parms[CC_id]->threequarter_fs = threequarter_fs; - - //} // j - } - - - init_all_otg(0); + init_all_otg(0); g_otg->seed = 0; init_seeds(g_otg->seed); @@ -1206,20 +1195,7 @@ static void get_options (int argc, char **argv) { osa_log_verbosity = enb_properties->properties[i]->osa_log_verbosity; #endif - // adjust the log - for (CC_id=0; CC_idproperties[i]->downlink_frequency[CC_id]; - uplink_frequency_offset[CC_id][k] = enb_properties->properties[i]->uplink_frequency_offset[CC_id]; - rx_gain[CC_id][k] = (double)enb_properties->properties[i]->rx_gain[CC_id]; - tx_gain[CC_id][k] = (double)enb_properties->properties[i]->tx_gain[CC_id]; - } - - printf("Downlink frequency/ uplink offset of CC_id %d set to %ju/%d\n", CC_id, - enb_properties->properties[i]->downlink_frequency[CC_id], - enb_properties->properties[i]->uplink_frequency_offset[CC_id]); - - } // CC_id + }// i //this is needed for phy-test option @@ -1236,6 +1212,57 @@ static void get_options (int argc, char **argv) { } } + +static void reconfigure_enb_params(int enb_id) +{ + int CC_id, k; + const Enb_properties_array_t *enb_properties=enb_config_get(); + + + for (CC_id=0; CC_idproperties[enb_id]->cc_node_function[CC_id]; + node_timing[CC_id] = enb_properties->properties[enb_id]->cc_node_timing[CC_id]; + node_synch_ref[CC_id] = enb_properties->properties[enb_id]->cc_node_synch_ref[CC_id]; + + frame_parms[CC_id]->frame_type = enb_properties->properties[enb_id]->frame_type[CC_id]; + frame_parms[CC_id]->tdd_config = enb_properties->properties[enb_id]->tdd_config[CC_id]; + frame_parms[CC_id]->tdd_config_S = enb_properties->properties[enb_id]->tdd_config_s[CC_id]; + frame_parms[CC_id]->Ncp = enb_properties->properties[enb_id]->prefix_type[CC_id]; + + //for (j=0; j < enb_properties->properties[i]->nb_cc; j++ ){ + frame_parms[CC_id]->Nid_cell = enb_properties->properties[enb_id]->Nid_cell[CC_id]; + frame_parms[CC_id]->N_RB_DL = enb_properties->properties[enb_id]->N_RB_DL[CC_id]; + frame_parms[CC_id]->N_RB_UL = enb_properties->properties[enb_id]->N_RB_DL[CC_id]; + frame_parms[CC_id]->nb_antennas_tx = enb_properties->properties[enb_id]->nb_antennas_tx[CC_id]; + frame_parms[CC_id]->nb_antenna_ports_eNB = enb_properties->properties[enb_id]->nb_antenna_ports[CC_id]; + frame_parms[CC_id]->nb_antennas_rx = enb_properties->properties[enb_id]->nb_antennas_rx[CC_id]; + + frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex = enb_properties->properties[enb_id]->prach_config_index[CC_id]; + frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset = enb_properties->properties[enb_id]->prach_freq_offset[CC_id]; + + frame_parms[CC_id]->mode1_flag = (frame_parms[CC_id]->nb_antenna_ports_eNB == 1) ? 1 : 0; + frame_parms[CC_id]->threequarter_fs = threequarter_fs; + + + for (k = 0 ; k < 4; k++) { + downlink_frequency[CC_id][k] = enb_properties->properties[enb_id]->downlink_frequency[CC_id]; + uplink_frequency_offset[CC_id][k] = enb_properties->properties[enb_id]->uplink_frequency_offset[CC_id]; + rx_gain[CC_id][k] = (double)enb_properties->properties[enb_id]->rx_gain[CC_id]; + tx_gain[CC_id][k] = (double)enb_properties->properties[enb_id]->tx_gain[CC_id]; + } + + printf("Downlink frequency/ uplink offset of CC_id %d set to %ju/%d\n", CC_id, + enb_properties->properties[enb_id]->downlink_frequency[CC_id], + enb_properties->properties[enb_id]->uplink_frequency_offset[CC_id]); + + init_ul_hopping(frame_parms[CC_id]); + init_frame_parms(frame_parms[CC_id],1); + // phy_init_top(frame_parms[CC_id]); + phy_init_lte_top(frame_parms[CC_id]); + } // CC_id +} + #if T_TRACER int T_wait = 1; /* by default we wait for the tracer */ int T_port = 2021; /* default port to listen to to wait for the tracer */ @@ -1395,6 +1422,19 @@ void init_openair0() { } } +/* check the state : either continue or wait for a command to start/stop the eNB + * if needed override the current configuration parameters, such as + * frequencies, bands, power, bandwidth + */ +static void ltesm_wait_reconfig_cmd(void) +{ + LOG_I(ENB_APP, "LTE Softmodem wait reconfiguration command\n"); + + while (node_control_state == ENB_WAIT_RECONFIGURATION_CMD) { + usleep(200000); + } +} + int main( int argc, char **argv ) { int i,j,k,aa,re; #if defined (XFORMS) @@ -1405,6 +1445,8 @@ int main( int argc, char **argv ) { uint8_t abstraction_flag=0; uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2; + PHY_vars_eNB_g=NULL; + #if defined (XFORMS) int ret; #endif @@ -1570,11 +1612,6 @@ int main( int argc, char **argv ) { LOG_I(PHY,"Set nb_rx_antenna %d , nb_tx_antenna %d \n",frame_parms[CC_id]->nb_antennas_rx, frame_parms[CC_id]->nb_antennas_tx); } - - init_ul_hopping(frame_parms[CC_id]); - init_frame_parms(frame_parms[CC_id],1); - // phy_init_top(frame_parms[CC_id]); - phy_init_lte_top(frame_parms[CC_id]); } @@ -1586,6 +1623,14 @@ int main( int argc, char **argv ) { // N_ZC = (prach_fmt <4)?839:139; } + create_enb_app_task(UE_flag ? 0 : 1); + ltesm_wait_reconfig_cmd (); + // reconfigure_enb: 0 for wait, 1 for skip, and other values to reconfigure + for (i=0; (i < NB_eNB_INST && node_control_state == ENB_NORMAL_OPERATION ) ; i++){ + reconfigure_enb_params(i); + printf("[ENB_APP] Reconfigured eNB module %d - continue\n", i); + } + if (UE_flag==1) { NB_UE_INST=1; NB_INST=1; From c62be7a101ce487b329e889e2746c8c94afd880b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 8 Dec 2017 15:28:28 +0100 Subject: [PATCH 048/195] Uniform messages of exiting threads --- common/utils/msc/msc.c | 1 + openair2/ENB_APP/enb_app.c | 1 + openair2/ENB_APP/flexran_agent.c | 1 + openair2/RRC/LITE/rrc_UE.c | 1 + openair2/RRC/LITE/rrc_eNB.c | 1 + openair2/X2AP/x2ap.c | 1 + openair3/GTPV1-U/gtpv1u_eNB.c | 1 + openair3/GTPV1-U/gtpv1u_task.c | 1 + openair3/S1AP/s1ap_eNB.c | 1 + openair3/SCTP/sctp_eNB_task.c | 1 + openair3/TEST/EPC_TEST/play_scenario_s1ap.c | 1 + openair3/UDP/udp_eNB_task.c | 2 +- targets/RT/USER/lte-enb.c | 24 +++++++++++++++++---- targets/RT/USER/lte-softmodem.c | 3 ++- 14 files changed, 34 insertions(+), 6 deletions(-) diff --git a/common/utils/msc/msc.c b/common/utils/msc/msc.c index 7de2a47f98..83f3beb512 100644 --- a/common/utils/msc/msc.c +++ b/common/utils/msc/msc.c @@ -99,6 +99,7 @@ void *msc_task(void *args_p) break; case TERMINATE_MESSAGE: { + fprintf(stderr, " *** Exiting MSC thread\n"); timer_remove(timer_id); msc_end(); itti_exit_task(); diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index 4a5981f509..bada59ffec 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -361,6 +361,7 @@ void *eNB_app_task(void *args_p) switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: + LOG_W(TASK_ENB_APP, " *** Exiting ENB_APP thread\n"); itti_exit_task (); break; diff --git a/openair2/ENB_APP/flexran_agent.c b/openair2/ENB_APP/flexran_agent.c index 23ac8f02ac..8af071527f 100644 --- a/openair2/ENB_APP/flexran_agent.c +++ b/openair2/ENB_APP/flexran_agent.c @@ -74,6 +74,7 @@ void *flexran_agent_task(void *args){ switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: + LOG_W(FLEXRAN_AGENT, " *** Exiting FLEXRAN thread\n"); itti_exit_task (); break; diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c index 6798212fb2..7f0c3a8800 100644 --- a/openair2/RRC/LITE/rrc_UE.c +++ b/openair2/RRC/LITE/rrc_UE.c @@ -4286,6 +4286,7 @@ void *rrc_ue_task( void *args_p ) switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: + LOG_W(RRC, " *** Exiting RRC thread\n"); itti_exit_task (); break; diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index aaf12da175..c441c102e3 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -5621,6 +5621,7 @@ rrc_enb_task( switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: + LOG_W(RRC, " *** Exiting RRC thread\n"); itti_exit_task(); break; diff --git a/openair2/X2AP/x2ap.c b/openair2/X2AP/x2ap.c index 699ad5ddbf..6af71e5ca5 100644 --- a/openair2/X2AP/x2ap.c +++ b/openair2/X2AP/x2ap.c @@ -49,6 +49,7 @@ void *x2ap_task(void *arg) switch (ITTI_MSG_ID(received_msg)) { case TERMINATE_MESSAGE: + X2AP_WARN(" *** Exiting X2AP thread\n"); itti_exit_task(); break; diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c index e273ac0712..d0a3bbd342 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB.c +++ b/openair3/GTPV1-U/gtpv1u_eNB.c @@ -1132,6 +1132,7 @@ void *gtpv1u_eNB_task(void *args) hashtable_destroy (gtpv1u_data_g.teid_mapping); } + LOG_W(GTPU, " *** Exiting GTPU thread\n"); itti_exit_task(); } break; diff --git a/openair3/GTPV1-U/gtpv1u_task.c b/openair3/GTPV1-U/gtpv1u_task.c index f9397f21ca..bea003a655 100644 --- a/openair3/GTPV1-U/gtpv1u_task.c +++ b/openair3/GTPV1-U/gtpv1u_task.c @@ -423,6 +423,7 @@ static void *gtpv1u_thread(void *args) switch (ITTI_MSG_ID(received_message_p)) { case TERMINATE_MESSAGE: { + GTPU_WARN(" *** Exiting GTPU thread\n"); itti_exit_task(); } break; diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index 65b82055a3..b96d9103f4 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -310,6 +310,7 @@ void *s1ap_eNB_task(void *arg) switch (ITTI_MSG_ID(received_msg)) { case TERMINATE_MESSAGE: + S1AP_WARN(" *** Exiting S1AP thread\n"); itti_exit_task(); break; diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c index 1f166af74c..758cbd5aa5 100644 --- a/openair3/SCTP/sctp_eNB_task.c +++ b/openair3/SCTP/sctp_eNB_task.c @@ -841,6 +841,7 @@ void *sctp_eNB_task(void *arg) break; case TERMINATE_MESSAGE: + SCTP_WARN("*** Exiting SCTP thread\n"); itti_exit_task(); break; diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c index f1bbe393be..d2247f70a8 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c @@ -1089,6 +1089,7 @@ void *et_s1ap_eNB_task(void *arg) switch (ITTI_MSG_ID(received_msg)) { case TERMINATE_MESSAGE: + S1AP_WARN("*** Exiting S1AP thread\n"); itti_exit_task(); break; diff --git a/openair3/UDP/udp_eNB_task.c b/openair3/UDP/udp_eNB_task.c index b8b6b897a7..94c5612ec6 100644 --- a/openair3/UDP/udp_eNB_task.c +++ b/openair3/UDP/udp_eNB_task.c @@ -389,7 +389,7 @@ void *udp_eNB_task(void *args_p) break; case TERMINATE_MESSAGE: { - LOG_W(UDP_, "Received TERMINATE_MESSAGE\n"); + LOG_W(UDP_, " *** Exiting UDP thread\n"); itti_exit_task(); } break; diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 5cbe0fe1d4..2223855419 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -643,7 +643,9 @@ static void* eNB_thread_rxtx( void* param ) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); - printf( "Exiting eNB thread RXn_TXnp4\n"); +#ifdef DEBUG_THREADS + printf(" *** Exiting eNB thread RXn_TXnp4\n"); +#endif eNB_thread_rxtx_status = 0; return &eNB_thread_rxtx_status; @@ -907,6 +909,10 @@ static void* eNB_thread_asynch_rxtx( void* param ) { } +#ifdef DEBUG_THREADS + printf(" *** Exiting eNB asynch rxtx thread\n"); +#endif + eNB_thread_asynch_rxtx_status=0; return(&eNB_thread_asynch_rxtx_status); } @@ -1372,6 +1378,10 @@ void *eNB_thread_synch(void *arg) { lte_sync_time_free(); +#ifdef DEBUG_THREADS + printf(" *** Exiting eNB synch thread\n"); +#endif + return NULL; } @@ -1484,7 +1494,9 @@ static void* eNB_thread_FH( void* param ) { rt_sleep_ns(800000LL); } - printf( "Exiting FH thread \n"); +#ifdef DEBUG_THREADS + printf(" *** Exiting FH thread \n"); +#endif eNB_thread_FH_status = 0; return &eNB_thread_FH_status; @@ -1518,7 +1530,9 @@ static void* eNB_thread_prach( void* param ) { if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break; } - printf( "Exiting eNB thread PRACH\n"); +#ifdef DEBUG_THREADS + printf(" *** Exiting eNB thread PRACH\n"); +#endif eNB_thread_prach_status = 0; return &eNB_thread_prach_status; @@ -1688,7 +1702,9 @@ static void* eNB_thread_single( void* param ) { } - printf( "Exiting eNB_single thread \n"); +#ifdef DEBUG_THREADS + printf(" *** Exiting eNB_single thread\n"); +#endif eNB_thread_single_status = 0; return &eNB_thread_single_status; diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 042f77eea7..ed0dd20360 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -558,7 +558,7 @@ void *l2l1_task(void *arg) { break; case TERMINATE_MESSAGE: - printf("received terminate message\n"); + LOG_W(TASK_L2L1, " *** Exiting L2L1 thread\n"); oai_exit=1; itti_exit_task (); break; @@ -579,6 +579,7 @@ void *l2l1_task(void *arg) { switch (ITTI_MSG_ID(message_p)) { case TERMINATE_MESSAGE: + LOG_W(TASK_L2L1, " *** Exiting L2L1 thread\n"); oai_exit=1; itti_exit_task (); break; From c313dff2ad9b37a23458d63f1431197c01d7e842 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 11 Dec 2017 11:32:06 +0100 Subject: [PATCH 049/195] better logging, remove warnings --- openair2/ENB_APP/enb_app.c | 2 +- .../ENB_APP/flexran_agent_common_internal.c | 25 +++++++++---------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index bada59ffec..89e20889cb 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -330,7 +330,7 @@ void *eNB_app_task(void *args_p) // set again the ran api vars for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { - printf("\n set again enb vars %d\n", enb_id); + LOG_I(ENB_APP, "set again enb vars %d\n", enb_id); flexran_set_enb_vars(enb_id, RAN_LTE_OAI); } diff --git a/openair2/ENB_APP/flexran_agent_common_internal.c b/openair2/ENB_APP/flexran_agent_common_internal.c index c883523855..e2ee656b23 100644 --- a/openair2/ENB_APP/flexran_agent_common_internal.c +++ b/openair2/ENB_APP/flexran_agent_common_internal.c @@ -216,35 +216,34 @@ int parse_enb_config_parameters(mid_t mod_id, yaml_parser_t *parser) { goto error; } // Check what key needs to be set - LOG_I(ENB_APP, "Setting parameter %s\n", event.data.scalar.value); if (strcmp((char *) event.data.scalar.value, "dl_freq") == 0) { - if (!yaml_parser_parse(parser, &event)) - goto error; + if (!yaml_parser_parse(parser, &event)) + goto error; flexran_agent_set_operating_dl_freq(mod_id, 0, strtol((char *) event.data.scalar.value, &endptr, 10)); - LOG_I(ENB_APP, "Setting parameter value %s\n", event.data.scalar.value); + LOG_I(ENB_APP, "Setting dl_freq to %s\n", event.data.scalar.value); } else if (strcmp((char *) event.data.scalar.value, "ul_freq_offset") == 0) { - if (!yaml_parser_parse(parser, &event)) - goto error; + if (!yaml_parser_parse(parser, &event)) + goto error; flexran_agent_set_operating_ul_freq(mod_id, 0, strtol((char *) event.data.scalar.value, &endptr, 10)); - LOG_I(ENB_APP, "Setting parameter value %s\n", event.data.scalar.value); + LOG_I(ENB_APP, "Setting ul_freq_offset to %s\n", event.data.scalar.value); } else if (strcmp((char *) event.data.scalar.value, "bandwidth") == 0) { - if (!yaml_parser_parse(parser, &event)) - goto error; + if (!yaml_parser_parse(parser, &event)) + goto error; flexran_agent_set_operating_bandwidth(mod_id, 0, strtol((char *) event.data.scalar.value, &endptr, 10)); - LOG_I(ENB_APP, "Setting parameter value %s\n", event.data.scalar.value); + LOG_I(ENB_APP, "Setting bandwidth to %s\n", event.data.scalar.value); } else if (strcmp((char *) event.data.scalar.value, "frame_type") == 0) { - if (!yaml_parser_parse(parser, &event)) - goto error; + if (!yaml_parser_parse(parser, &event)) + goto error; flexran_agent_set_operating_frame_type (mod_id, 0, strtol((char *) event.data.scalar.value, &endptr, 10)); - LOG_I(ENB_APP, "Setting parameter value %s\n", event.data.scalar.value); + LOG_I(ENB_APP, "Setting frame_type to %s\n", event.data.scalar.value); }else { // not supported tag goto error; } From 1aa5d2930a61fc499b0233758ce7c27950667cdc Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 11 Dec 2017 11:37:10 +0100 Subject: [PATCH 050/195] Handle TERMINATE_MESSAGE in TASK_MAC --- openair2/LAYER2/MAC/eNB_scheduler.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index f46b9deb8d..60a6e22125 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -323,6 +323,11 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, break; #endif + case TERMINATE_MESSAGE: + LOG_W(MAC, "+++ Exiting MAC thread\n"); + itti_exit_task (); + break; + default: LOG_E(MAC, "Received unexpected message %s\n", msg_name); break; From ea65ddad2cb2fa33a6c4eb935a47d20b32bd0274 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 11 Dec 2017 15:31:21 +0100 Subject: [PATCH 051/195] fill PHY_vars_eNB_g in own function --- targets/RT/USER/lte-softmodem.c | 120 ++++++++++++++++++-------------- 1 file changed, 66 insertions(+), 54 deletions(-) diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index ed0dd20360..d36907bba7 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1423,6 +1423,70 @@ void init_openair0() { } } +void fill_PHY_vars_eNB_g(uint8_t abstraction_flag, uint8_t beta_ACK, uint8_t beta_RI, uint8_t beta_CQI) +{ + int CC_id, i, j, k, re; + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + PHY_vars_eNB_g[0][CC_id] = init_lte_eNB(frame_parms[CC_id], + 0, + frame_parms[CC_id]->Nid_cell, + node_function[CC_id], + abstraction_flag); + PHY_vars_eNB_g[0][CC_id]->ue_dl_rb_alloc = 0x1fff; + PHY_vars_eNB_g[0][CC_id]->target_ue_dl_mcs = target_dl_mcs; + PHY_vars_eNB_g[0][CC_id]->ue_ul_nb_rb = 6; + PHY_vars_eNB_g[0][CC_id]->target_ue_ul_mcs = target_ul_mcs; + // initialization for phy-test + for (k = 0; k < NUMBER_OF_UE_MAX; k++) { + PHY_vars_eNB_g[0][CC_id]->transmission_mode[k] = transmission_mode; + if (transmission_mode == 7) + lte_gold_ue_spec_port5(PHY_vars_eNB_g[0][CC_id]->lte_gold_uespec_port5_table[k], + frame_parms[CC_id]->Nid_cell, + 0x1235+k); + } + if ((transmission_mode == 1) || (transmission_mode == 7)) { + for (j = 0; j < frame_parms[CC_id]->nb_antennas_tx; j++) + for (re = 0; re < frame_parms[CC_id]->ofdm_symbol_size; re++) + PHY_vars_eNB_g[0][CC_id]->common_vars.beam_weights[0][0][j][re] = 0x00007fff / frame_parms[CC_id]->nb_antennas_tx; + } + + if (phy_test==1) + PHY_vars_eNB_g[0][CC_id]->mac_enabled = 0; + else + PHY_vars_eNB_g[0][CC_id]->mac_enabled = 1; + + if (PHY_vars_eNB_g[0][CC_id]->mac_enabled == 0) { //set default parameters for testing mode + for (i = 0; i < NUMBER_OF_UE_MAX; i++) { + PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK; + PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index = beta_RI; + PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI; + + PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = i; + PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(i%3); + PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4; + } + } + + compute_prach_seq(&PHY_vars_eNB_g[0][CC_id]->frame_parms.prach_config_common, + PHY_vars_eNB_g[0][CC_id]->frame_parms.frame_type, + PHY_vars_eNB_g[0][CC_id]->X_u); + + + PHY_vars_eNB_g[0][CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0]; + + if (frame_parms[CC_id]->frame_type == FDD) { + PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 0; + } else { + if (frame_parms[CC_id]->N_RB_DL == 100) + PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624; + else if (frame_parms[CC_id]->N_RB_DL == 50) + PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624/2; + else if (frame_parms[CC_id]->N_RB_DL == 25) + PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624/4; + } + } +} + /* check the state : either continue or wait for a command to start/stop the eNB * if needed override the current configuration parameters, such as * frequencies, bands, power, bandwidth @@ -1437,7 +1501,7 @@ static void ltesm_wait_reconfig_cmd(void) } int main( int argc, char **argv ) { - int i,j,k,aa,re; + int i,aa; #if defined (XFORMS) void *status; #endif @@ -1710,59 +1774,7 @@ int main( int argc, char **argv ) { PHY_vars_eNB_g = malloc(sizeof(PHY_VARS_eNB**)); PHY_vars_eNB_g[0] = malloc(sizeof(PHY_VARS_eNB*)); - for (CC_id=0; CC_idNid_cell,node_function[CC_id],abstraction_flag); - PHY_vars_eNB_g[0][CC_id]->ue_dl_rb_alloc=0x1fff; - PHY_vars_eNB_g[0][CC_id]->target_ue_dl_mcs=target_dl_mcs; - PHY_vars_eNB_g[0][CC_id]->ue_ul_nb_rb=6; - PHY_vars_eNB_g[0][CC_id]->target_ue_ul_mcs=target_ul_mcs; - // initialization for phy-test - for (k=0; ktransmission_mode[k] = transmission_mode; - if (transmission_mode==7) - lte_gold_ue_spec_port5(PHY_vars_eNB_g[0][CC_id]->lte_gold_uespec_port5_table[k],frame_parms[CC_id]->Nid_cell,0x1235+k); - } - if ((transmission_mode==1) || (transmission_mode==7)) { - for (j=0; jnb_antennas_tx; j++) - for (re=0; reofdm_symbol_size; re++) - PHY_vars_eNB_g[0][CC_id]->common_vars.beam_weights[0][0][j][re] = 0x00007fff/frame_parms[CC_id]->nb_antennas_tx; - } - - if (phy_test==1) PHY_vars_eNB_g[0][CC_id]->mac_enabled = 0; - else PHY_vars_eNB_g[0][CC_id]->mac_enabled = 1; - - if (PHY_vars_eNB_g[0][CC_id]->mac_enabled == 0) { //set default parameters for testing mode - for (i=0; ipusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK; - PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index = beta_RI; - PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI; - - PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = i; - PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(i%3); - PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4; - } - } - - compute_prach_seq(&PHY_vars_eNB_g[0][CC_id]->frame_parms.prach_config_common, - PHY_vars_eNB_g[0][CC_id]->frame_parms.frame_type, - PHY_vars_eNB_g[0][CC_id]->X_u); - - - PHY_vars_eNB_g[0][CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0]; - - if (frame_parms[CC_id]->frame_type==FDD) { - PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 0; - } else { - if (frame_parms[CC_id]->N_RB_DL == 100) - PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624; - else if (frame_parms[CC_id]->N_RB_DL == 50) - PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624/2; - else if (frame_parms[CC_id]->N_RB_DL == 25) - PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624/4; - } - - } - + fill_PHY_vars_eNB_g(abstraction_flag, beta_ACK, beta_RI, beta_CQI); NB_eNB_INST=1; NB_INST=1; From e88a3cdf469f04b67158625e5a663dc29fad299e Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 12 Dec 2017 10:56:40 +0100 Subject: [PATCH 052/195] bugfix ITTI: clean up in itti_exit_task() - when exiting task, the task is set as "not configured" - this permits to start a task again --- common/utils/itti/intertask_interface.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/common/utils/itti/intertask_interface.c b/common/utils/itti/intertask_interface.c index 28267900af..59209994b6 100644 --- a/common/utils/itti/intertask_interface.c +++ b/common/utils/itti/intertask_interface.c @@ -775,15 +775,19 @@ void itti_mark_task_ready(task_id_t task_id) void itti_exit_task(void) { -#if defined(OAI_EMU) || defined(RTAI) task_id_t task_id = itti_get_current_task_id(); + thread_id_t thread_id = TASK_GET_THREAD_ID(task_id); +#if defined(OAI_EMU) || defined(RTAI) if (task_id > TASK_UNKNOWN) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLE_ITTI_RECV_MSG, __sync_and_and_fetch (&itti_desc.vcd_receive_msg, ~(1L << task_id))); } - #endif + + itti_desc.threads[thread_id].task_state = TASK_STATE_NOT_CONFIGURED; + itti_desc.created_tasks--; + ITTI_DEBUG(ITTI_DEBUG_EXIT, "Thread for task %s (%d) exits\n", itti_get_task_name(task_id), task_id); pthread_exit (NULL); } From c619f6eff76234d2efd14d29e99d8132dd768946 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 12 Dec 2017 10:03:06 +0100 Subject: [PATCH 053/195] Feature: Provide restart for lte-softmodem - {restart,stop}_L1L2() in lte-softmodem.c - add function start_phy_rrc() in enb_app.{c,h}, accessible from outside - will be used to restart PHY and RRC when lte-softmodem is restarted use only one FlexRAN wait function --- openair2/ENB_APP/enb_app.c | 30 ++-- openair2/ENB_APP/enb_app.h | 7 + .../ENB_APP/flexran_agent_common_internal.c | 28 +++- targets/RT/USER/lte-softmodem.c | 133 ++++++++++++++++-- targets/RT/USER/lte-softmodem.h | 3 + 5 files changed, 178 insertions(+), 23 deletions(-) diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index 89e20889cb..be0b88acff 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -57,14 +57,13 @@ extern unsigned char NB_eNB_INST; #endif extern volatile int node_control_state; -static void enb_app_wait_reconfig_cmd (void) +void ltesm_wait_reconfig_cmd(void) { - LOG_I(ENB_APP, "ENB APP await reconfiguration command\n"); - - while (node_control_state == ENB_WAIT_RECONFIGURATION_CMD) { + LOG_I(ENB_APP, "LTE Softmodem wait reconfiguration command\n"); + + while (node_control_state == ENB_WAIT_RECONFIGURATION_CMD) { usleep(200000); } - sleep(2); // wait for createing other tasks } #if defined(ENABLE_ITTI) @@ -202,6 +201,15 @@ static void configure_rrc(uint32_t enb_id, const Enb_properties_array_t *enb_pro itti_send_msg_to_task (TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); } +void enb_app_start_phy_rrc(uint32_t enb_id_start, uint32_t enb_id_end) +{ + Enb_properties_array_t *enb_properties_p = enb_config_get(); + for (uint32_t enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { + configure_phy(enb_id, enb_properties_p); + configure_rrc(enb_id, enb_properties_p); + } +} + /*------------------------------------------------------------------------------*/ # if defined(ENABLE_USE_MME) static uint32_t eNB_app_register(uint32_t enb_id_start, uint32_t enb_id_end, const Enb_properties_array_t *enb_properties) @@ -325,8 +333,10 @@ void *eNB_app_task(void *args_p) for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { flexran_agent_start(enb_id, enb_properties_p); } - // wait for config comd from the controller/network app - enb_app_wait_reconfig_cmd(); + // wait for config comd from the controller/network app plus some time so + // that the other Tasks are in place + ltesm_wait_reconfig_cmd(); + sleep(2); // set again the ran api vars for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { @@ -336,11 +346,7 @@ void *eNB_app_task(void *args_p) #endif - for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { - configure_phy(enb_id, enb_properties_p); - configure_rrc(enb_id, enb_properties_p); - } - + enb_app_start_phy_rrc(enb_id_start, enb_id_end); # if defined(ENABLE_USE_MME) /* Try to register each eNB */ diff --git a/openair2/ENB_APP/enb_app.h b/openair2/ENB_APP/enb_app.h index 8e3c28760b..be5adfbb34 100644 --- a/openair2/ENB_APP/enb_app.h +++ b/openair2/ENB_APP/enb_app.h @@ -30,8 +30,15 @@ #ifndef ENB_APP_H_ #define ENB_APP_H_ +#include void *eNB_app_task(void *args_p); +/* needed for flexran: start PHY and RRC when restarting */ +void enb_app_start_phy_rrc(uint32_t enb_id_start, uint32_t enb_id_end); + +/* wait that FlexRAN left state ENB_WAIT_RECONFIGURATION_CMD */ +void ltesm_wait_reconfig_cmd(void); + #endif /* ENB_APP_H_ */ diff --git a/openair2/ENB_APP/flexran_agent_common_internal.c b/openair2/ENB_APP/flexran_agent_common_internal.c index e2ee656b23..e77557e9ee 100644 --- a/openair2/ENB_APP/flexran_agent_common_internal.c +++ b/openair2/ENB_APP/flexran_agent_common_internal.c @@ -31,8 +31,33 @@ #include "flexran_agent_common_internal.h" #include "flexran_agent_mac_internal.h" + +/* the following is needed to soft-restart the lte-softmodem */ +#include "targets/RT/USER/lte-softmodem.h" +#include "assertions.h" +#include "enb_app.h" extern volatile int node_control_state; +void handle_reconfiguration(mid_t mod_id) +{ + /* NOTE: this function might be extended by using stop_modem() + * to halt the modem so that it can later be resumed */ + + if (ENB_NORMAL_OPERATION != node_control_state) { + node_control_state = ENB_NORMAL_OPERATION; + } else { + if (stop_L1L2(mod_id) < 0 || restart_L1L2(mod_id) < 0) { + LOG_E(ENB_APP, "could not restart, killing lte-softmodem\n"); + /* shutdown the whole lte-softmodem */ + itti_terminate_tasks(TASK_PHY_ENB); + return; + } + + enb_app_start_phy_rrc(mod_id, mod_id+1); + LOG_I(ENB_APP, "lte-softmodem restart succeeded\n"); + } +} + int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy_length) { yaml_parser_t parser; @@ -72,8 +97,7 @@ int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy if (parse_enb_id(mod_id, &parser) == -1) { goto error; } else { // succeful parse and setting - node_control_state= ENB_NORMAL_OPERATION; - LOG_I(ENB_APP, "Successful parsed config for enb system, entering normal state\n"); + handle_reconfiguration(mod_id); } } else if (strcmp((char *) event.data.scalar.value, "mac") == 0) { LOG_D(ENB_APP, "This is intended for the mac system\n"); diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index d36907bba7..b89c82aff4 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1487,19 +1487,129 @@ void fill_PHY_vars_eNB_g(uint8_t abstraction_flag, uint8_t beta_ACK, uint8_t bet } } -/* check the state : either continue or wait for a command to start/stop the eNB - * if needed override the current configuration parameters, such as - * frequencies, bands, power, bandwidth +#if defined(ENABLE_ITTI) && defined(FLEXRAN_AGENT_SB_IF) +/* + * helper function to terminate a certain ITTI task */ -static void ltesm_wait_reconfig_cmd(void) +void terminate_task(task_id_t task_id, mid_t mod_id) { - LOG_I(ENB_APP, "LTE Softmodem wait reconfiguration command\n"); - - while (node_control_state == ENB_WAIT_RECONFIGURATION_CMD) { - usleep(200000); - } + LOG_I(ENB_APP, "sending TERMINATE_MESSAGE to task %s (%d)\n", itti_get_task_name(task_id), task_id); + MessageDef *msg; + msg = itti_alloc_new_message (ENB_APP, TERMINATE_MESSAGE); + itti_send_msg_to_task (task_id, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); } +int stop_L1L2(int enb_id) +{ + int CC_id; + + LOG_W(ENB_APP, "stopping lte-softmodem\n"); + + /* stop trx devices */ + for(CC_id=0; CC_idrfdevice.trx_stop_func) { + LOG_I(ENB_APP, "stopping PHY_vars_eNB_g[0][%d]->rfdevice (via trx_stop_func())\n", CC_id); + PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_stop_func(&PHY_vars_eNB_g[0][CC_id]->rfdevice); + } + if (PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_stop_func) { + LOG_I(ENB_APP, "stopping PHY_vars_eNB_g[0][%d]->ifdevice (via trx_stop_func())\n", CC_id); + PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_stop_func(&PHY_vars_eNB_g[0][CC_id]->ifdevice); + } + } + + /* these tasks need to pick up new configuration */ + terminate_task(TASK_RRC_ENB, enb_id); + terminate_task(TASK_L2L1, enb_id); + oai_exit = 1; + LOG_W(ENB_APP, "calling kill_eNB_proc() for instance %d\n", enb_id); + kill_eNB_proc(enb_id); + /* give some time for all threads */ + sleep(1); + return 0; +} + +/* + * Restart the lte-softmodem. + * This function checks whether we are in ENB_NORMAL_OPERATION (defined by + * FlexRAN). If yes, first stop L1/L2/L3, then resume. + */ +int restart_L1L2(int enb_id) +{ + int i, aa, CC_id; + /* needed for fill_PHY_vars_eNB_g(), defined locally in main(); + * abstraction flag is needed too, but defined both globally and in main () */ + uint8_t beta_ACK = 0, beta_RI = 0, beta_CQI = 2; + /* needed for macphy_init() */ + int eMBMS_active = 0; + + LOG_W(ENB_APP, "restarting lte-softmodem\n"); + + /* block threads */ + sync_var = -1; + oai_exit = 0; + + reconfigure_enb_params(enb_id); /* set frame parameters from configuration */ + + /* PHY_vars_eNB_g will be filled by init_lte_eNB(), so free and + * let the data structure be filled again */ + for (CC_id=0; CC_idframe_parms = frame_parms[0]; + mac_xface->macphy_init(eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL,0,0); + + LOG_I(ENB_APP, "attempting to create ITTI tasks\n"); + if (itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL) < 0) { + LOG_E(RRC, "Create task for RRC eNB failed\n"); + return -1; + } else { + LOG_I(RRC, "Re-created task for RRC eNB successfully\n"); + } + if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) { + LOG_E(PDCP, "Create task for L2L1 failed\n"); + return -1; + } else { + LOG_I(PDCP, "Re-created task for L2L1 successfully\n"); + } + + /* TODO XForms here */ + + printf("Initializing eNB threads\n"); + init_eNB(node_function, node_timing, 1, eth_params, single_thread_flag, wait_for_sync); + for(CC_id=0; CC_idrf_map.card=0; + PHY_vars_eNB_g[0][CC_id]->rf_map.chain=CC_id+chain_offset; + } + + mlockall(MCL_CURRENT | MCL_FUTURE); + + printf("Setting eNB buffer to all-RX\n"); + // Set LSBs for antenna switch (ExpressMIMO) + for (CC_id=0; CC_idhw_timing_advance = 0; + for (i=0; isamples_per_tti*10; i++) + for (aa=0; aanb_antennas_tx; aa++) + PHY_vars_eNB_g[0][CC_id]->common_vars.txdata[0][aa][i] = 0x00010001; + } + + printf("Sending sync to all threads\n"); + + pthread_mutex_lock(&sync_mutex); + sync_var=0; + pthread_cond_broadcast(&sync_cond); + pthread_mutex_unlock(&sync_mutex); + + return 0; +} +#endif + int main( int argc, char **argv ) { int i,aa; #if defined (XFORMS) @@ -1689,7 +1799,12 @@ int main( int argc, char **argv ) { } create_enb_app_task(UE_flag ? 0 : 1); + +#ifdef FLEXRAN_AGENT_SB_IF + /* wait command for flexran agent: only start when configuration received */ ltesm_wait_reconfig_cmd (); +#endif + // reconfigure_enb: 0 for wait, 1 for skip, and other values to reconfigure for (i=0; (i < NB_eNB_INST && node_control_state == ENB_NORMAL_OPERATION ) ; i++){ reconfigure_enb_params(i); diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index 4d9d145c68..a0883c3d59 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -89,4 +89,7 @@ extern void init_fep_thread(PHY_VARS_eNB *, pthread_attr_t *); extern void init_td_thread(PHY_VARS_eNB *, pthread_attr_t *); extern void init_te_thread(PHY_VARS_eNB *, pthread_attr_t *); +extern int stop_L1L2(int enb_id); +extern int restart_L1L2(int enb_id); + #endif From eb2dfa1b70db81fa77df72f2474982af973b0c9f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 12 Dec 2017 16:59:46 +0100 Subject: [PATCH 054/195] kill_eNB_proc(): join all PHY threads --- targets/RT/USER/lte-enb.c | 43 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 2223855419..9bde18df40 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -1754,6 +1754,7 @@ void init_eNB_proc(int inst) { pthread_mutex_init( &proc->mutex_prach, NULL); pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL); pthread_mutex_init( &proc->mutex_synch,NULL); + pthread_mutex_init( &proc->mutex_FH, NULL); pthread_cond_init( &proc->cond_prach, NULL); pthread_cond_init( &proc->cond_FH, NULL); @@ -1862,30 +1863,68 @@ void kill_eNB_proc(int inst) { printf( "Killing TX CC_id %d thread %d\n", CC_id, i ); #endif - proc_rxtx[0].instance_cnt_rxtx = 0; // FIXME data race! - proc_rxtx[1].instance_cnt_rxtx = 0; // FIXME data race! + pthread_mutex_lock(&proc_rxtx[0].mutex_rxtx); + proc_rxtx[0].instance_cnt_rxtx = 0; + pthread_mutex_unlock(&proc_rxtx[0].mutex_rxtx); + pthread_mutex_lock(&proc_rxtx[1].mutex_rxtx); + proc_rxtx[1].instance_cnt_rxtx = 0; + pthread_mutex_unlock(&proc_rxtx[1].mutex_rxtx); + pthread_mutex_lock(&PHY_vars_eNB_g[0][CC_id]->proc.mutex_synch); + PHY_vars_eNB_g[0][CC_id]->proc.instance_cnt_synch = 1; + pthread_mutex_unlock(&PHY_vars_eNB_g[0][CC_id]->proc.mutex_synch); proc->instance_cnt_prach = 0; proc->instance_cnt_FH = 0; pthread_cond_signal( &proc_rxtx[0].cond_rxtx ); pthread_cond_signal( &proc_rxtx[1].cond_rxtx ); pthread_cond_signal( &proc->cond_prach ); pthread_cond_signal( &proc->cond_FH ); + pthread_cond_signal( &proc->cond_asynch_rxtx ); + pthread_cond_signal( &proc->cond_synch ); pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx); +#ifdef DEBUG_THREADS + printf("joining pthread_FH\n"); +#endif pthread_join( proc->pthread_FH, (void**)&status ); pthread_mutex_destroy( &proc->mutex_FH ); pthread_cond_destroy( &proc->cond_FH ); +#ifdef DEBUG_THREADS + printf("joining pthread_prach\n"); +#endif pthread_join( proc->pthread_prach, (void**)&status ); pthread_mutex_destroy( &proc->mutex_prach ); pthread_cond_destroy( &proc->cond_prach ); int i; for (i=0;i<2;i++) { +#ifdef DEBUG_THREADS + printf("joining pthread_rxtx\n"); +#endif pthread_join( proc_rxtx[i].pthread_rxtx, (void**)&status ); pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx ); pthread_cond_destroy( &proc_rxtx[i].cond_rxtx ); } + +#ifdef DEBUG_THREADS + printf("joining pthread_asynch_rxtx\n"); +#endif + pthread_join(proc->pthread_asynch_rxtx, (void**)&status ); + pthread_mutex_destroy(&proc->mutex_asynch_rxtx); + pthread_cond_destroy(&proc->cond_asynch_rxtx); + +#ifdef DEBUG_THREADS + printf("joining pthread_single\n"); +#endif + pthread_join(proc->pthread_single, (void**)&status ); + +#ifdef DEBUG_THREADS + printf("joining pthread_synch\n"); +#endif + pthread_join(proc->pthread_synch, (void**)&status ); + pthread_mutex_destroy(&proc->mutex_synch); + pthread_cond_destroy(&proc->cond_synch); + printf("joined all threads\n"); } } From 730ffc76f4009b8164e17e959ccdf639e3b5631c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 12 Dec 2017 17:00:43 +0100 Subject: [PATCH 055/195] stop_L1L2(): no sleep, better oai_exit handling --- targets/RT/USER/lte-softmodem.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index b89c82aff4..f881441cdb 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1504,6 +1504,7 @@ int stop_L1L2(int enb_id) int CC_id; LOG_W(ENB_APP, "stopping lte-softmodem\n"); + oai_exit = 1; /* stop trx devices */ for(CC_id=0; CC_id Date: Tue, 12 Dec 2017 18:04:25 +0100 Subject: [PATCH 056/195] Fix multiple compilation warnings --- openair2/ENB_APP/enb_config.c | 4 ++-- openair2/ENB_APP/flexran_agent_net_comm.c | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 6282523b55..08de05c144 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -2009,7 +2009,7 @@ Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) enb_properties.properties[enb_properties_index]->rrc_report_amount = ReportConfigEUTRA__reportAmount_infinity; }else{ AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for report_amount choice: r1, r2, r4, r8, r16, r32, r64, infinity !\n", + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for report_amount choice: r1, r2, r4, r8, r16, r32, r64, infinity !\n", lib_config_file_name_pP, i,rrc_report_amount); } @@ -2041,7 +2041,7 @@ Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) enb_properties.properties[enb_properties_index]->rrc_report_interval = ReportInterval_min60; } else { AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for report_interval choice: 120ms, 240ms, 480ms, 640ms, 1024ms, 2048ms, 5120ms, 10240ms, 1min, 6min, 12", + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for report_interval choice: 120ms, 240ms, 480ms, 640ms, 1024ms, 2048ms, 5120ms, 10240ms, 1min, 6min, 12", lib_config_file_name_pP, i,rrc_report_interval); } diff --git a/openair2/ENB_APP/flexran_agent_net_comm.c b/openair2/ENB_APP/flexran_agent_net_comm.c index d801bbdda5..e5f9109871 100644 --- a/openair2/ENB_APP/flexran_agent_net_comm.c +++ b/openair2/ENB_APP/flexran_agent_net_comm.c @@ -141,9 +141,9 @@ int flexran_agent_destroy_channel(int channel_id) { for (i = 0; i < NUM_MAX_ENB; i++) { for (j = 0; j < FLEXRAN_AGENT_MAX; j++) { if (agent_channel[i][j] != NULL) { - if (agent_channel[i][j]->channel_id == e->channel_id) { - free(agent_channel[i][j]); - } + if (agent_channel[i][j]->channel_id == e->channel_id) { + free(agent_channel[i][j]); + } } } } @@ -164,7 +164,9 @@ err_code_t flexran_agent_init_channel_container(void) { for (i = 0; i < NUM_MAX_ENB; i++) { for (j = 0; j < FLEXRAN_AGENT_MAX; j++) { - agent_channel[i][j] = malloc(sizeof(flexran_agent_channel_t)); + agent_channel[i][j] = malloc(sizeof(flexran_agent_channel_t)); + if (!agent_channel[i][j]) + return -1; } } From fea641220b7ca7b76715dc933b95fd0a639d8d48 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 12 Dec 2017 16:54:30 +0100 Subject: [PATCH 057/195] Start FlexRAN agent directly, lock with mutex&condition - lock with mutexes - don't start ENB_APP task, but Agent directly and wait in case of reconfiguration --- openair2/ENB_APP/enb_app.c | 31 +------------- openair2/ENB_APP/enb_app.h | 3 -- .../ENB_APP/flexran_agent_common_internal.c | 15 +++++-- targets/COMMON/create_tasks.c | 19 ++++----- targets/COMMON/create_tasks.h | 1 - targets/RT/USER/lte-softmodem.c | 42 ++++++++++++------- targets/RT/USER/lte-softmodem.h | 7 ++++ 7 files changed, 55 insertions(+), 63 deletions(-) diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index be0b88acff..5fe0f741bf 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -50,21 +50,11 @@ # endif #if defined(FLEXRAN_AGENT_SB_IF) -# include "flexran_agent.h" +# include "targets/RT/USER/lte-softmodem.h" #endif extern unsigned char NB_eNB_INST; #endif -extern volatile int node_control_state; - -void ltesm_wait_reconfig_cmd(void) -{ - LOG_I(ENB_APP, "LTE Softmodem wait reconfiguration command\n"); - - while (node_control_state == ENB_WAIT_RECONFIGURATION_CMD) { - usleep(200000); - } -} #if defined(ENABLE_ITTI) @@ -299,7 +289,6 @@ void *eNB_app_task(void *args_p) uint32_t registered_enb; long enb_register_retry_timer_id; # endif - uint32_t enb_id; MessageDef *msg_p = NULL; const char *msg_name = NULL; instance_t instance; @@ -328,24 +317,6 @@ void *eNB_app_task(void *args_p) "Number of eNB is greater than eNB defined in configuration file (%d/%d)!", enb_nb, enb_properties_p->number); -#if defined (FLEXRAN_AGENT_SB_IF) - - for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { - flexran_agent_start(enb_id, enb_properties_p); - } - // wait for config comd from the controller/network app plus some time so - // that the other Tasks are in place - ltesm_wait_reconfig_cmd(); - sleep(2); - - // set again the ran api vars - for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { - LOG_I(ENB_APP, "set again enb vars %d\n", enb_id); - flexran_set_enb_vars(enb_id, RAN_LTE_OAI); - } - -#endif - enb_app_start_phy_rrc(enb_id_start, enb_id_end); # if defined(ENABLE_USE_MME) diff --git a/openair2/ENB_APP/enb_app.h b/openair2/ENB_APP/enb_app.h index be5adfbb34..441693ab31 100644 --- a/openair2/ENB_APP/enb_app.h +++ b/openair2/ENB_APP/enb_app.h @@ -38,7 +38,4 @@ void *eNB_app_task(void *args_p); /* needed for flexran: start PHY and RRC when restarting */ void enb_app_start_phy_rrc(uint32_t enb_id_start, uint32_t enb_id_end); -/* wait that FlexRAN left state ENB_WAIT_RECONFIGURATION_CMD */ -void ltesm_wait_reconfig_cmd(void); - #endif /* ENB_APP_H_ */ diff --git a/openair2/ENB_APP/flexran_agent_common_internal.c b/openair2/ENB_APP/flexran_agent_common_internal.c index e77557e9ee..c2bd396e36 100644 --- a/openair2/ENB_APP/flexran_agent_common_internal.c +++ b/openair2/ENB_APP/flexran_agent_common_internal.c @@ -36,25 +36,34 @@ #include "targets/RT/USER/lte-softmodem.h" #include "assertions.h" #include "enb_app.h" -extern volatile int node_control_state; void handle_reconfiguration(mid_t mod_id) { /* NOTE: this function might be extended by using stop_modem() * to halt the modem so that it can later be resumed */ + int do_restart = 0; + pthread_mutex_lock(&mutex_node_ctrl); if (ENB_NORMAL_OPERATION != node_control_state) { node_control_state = ENB_NORMAL_OPERATION; + pthread_cond_broadcast(&cond_node_ctrl); } else { + do_restart = 1; + } + pthread_mutex_unlock(&mutex_node_ctrl); + + if (do_restart) { + clock_t start_ms = 1000 * clock(); + /* operator || enforces sequence points */ if (stop_L1L2(mod_id) < 0 || restart_L1L2(mod_id) < 0) { LOG_E(ENB_APP, "could not restart, killing lte-softmodem\n"); /* shutdown the whole lte-softmodem */ itti_terminate_tasks(TASK_PHY_ENB); return; } - enb_app_start_phy_rrc(mod_id, mod_id+1); - LOG_I(ENB_APP, "lte-softmodem restart succeeded\n"); + int diff_ms = (1000 * clock() - start_ms) / CLOCKS_PER_SEC; + LOG_I(ENB_APP, "lte-softmodem restart succeeded in %d ms\n", diff_ms); } } diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c index 1ca55b5926..c28b9e839c 100644 --- a/targets/COMMON/create_tasks.c +++ b/targets/COMMON/create_tasks.c @@ -40,17 +40,6 @@ # endif # include "enb_app.h" -int create_enb_app_task(uint32_t enb_nb) -{ - if (enb_nb > 0) { - if (itti_create_task (TASK_ENB_APP, eNB_app_task, NULL) < 0) { - LOG_E(ENB_APP, "Create task for eNB APP failed\n"); - return -1; - } - } - return 0; -} - int create_tasks(uint32_t enb_nb, uint32_t ue_nb) { itti_wait_ready(1); @@ -59,6 +48,14 @@ int create_tasks(uint32_t enb_nb, uint32_t ue_nb) return -1; } + if (enb_nb > 0) { + /* Last task to create, others task must be ready before its start */ + if (itti_create_task (TASK_ENB_APP, eNB_app_task, NULL) < 0) { + LOG_E(ENB_APP, "Create task for eNB APP failed\n"); + return -1; + } + } + # ifdef OPENAIR2 { diff --git a/targets/COMMON/create_tasks.h b/targets/COMMON/create_tasks.h index 3455b283b5..6545f4b9d9 100644 --- a/targets/COMMON/create_tasks.h +++ b/targets/COMMON/create_tasks.h @@ -27,7 +27,6 @@ extern void *l2l1_task(void *arg); int create_tasks(uint32_t enb_nb, uint32_t ue_nb); -int create_enb_app_task(uint32_t enb_nb); #endif #endif /* CREATE_TASKS_H_ */ diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index f881441cdb..39f40733f2 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -174,8 +174,6 @@ eNB_func_t node_function[MAX_NUM_CCs]; eNB_timing_t node_timing[MAX_NUM_CCs]; int16_t node_synch_ref[MAX_NUM_CCs]; -volatile int16_t node_control_state; - uint32_t target_dl_mcs = 28; //maximum allowed mcs uint32_t target_ul_mcs = 20; uint32_t timing_advance = 0; @@ -234,9 +232,7 @@ threads_t threads= {-1,-1,-1,-1,-1,-1,-1}; */ uint8_t abstraction_flag=0; -/* */ - -/* overrid the enb configuration params*/ +/* override the enb configuration parameters */ static void reconfigure_enb_params(int enb_id); @@ -1097,11 +1093,13 @@ static void get_options (int argc, char **argv) { "lte-softmodem compiled with MAX_NUM_CCs=%d, but only %d CCs configured for eNB %d!", MAX_NUM_CCs, enb_properties->properties[i]->nb_cc, i); +#ifdef FLEXRAN_AGENT_SB_IF if (enb_properties->properties[i]->flexran_agent_reconf == 1) { node_control_state = ENB_WAIT_RECONFIGURATION_CMD; } else { node_control_state = ENB_NORMAL_OPERATION; } +#endif eth_params = (eth_params_t*)malloc(enb_properties->properties[i]->nb_rrh_gw * sizeof(eth_params_t)); memset(eth_params, 0, enb_properties->properties[i]->nb_rrh_gw * sizeof(eth_params_t)); @@ -1796,19 +1794,28 @@ int main( int argc, char **argv ) { // N_ZC = (prach_fmt <4)?839:139; } - create_enb_app_task(UE_flag ? 0 : 1); - #ifdef FLEXRAN_AGENT_SB_IF - /* wait command for flexran agent: only start when configuration received */ - ltesm_wait_reconfig_cmd (); + pthread_mutex_init(&mutex_node_ctrl, NULL); + pthread_cond_init(&cond_node_ctrl, NULL); + + for (i = 0; i < NB_eNB_INST; i++) { + flexran_agent_start(i, enb_config_get()); + } + + LOG_I(ENB_APP, " * Waiting for FlexRAN RTController command *\n"); + pthread_mutex_lock(&mutex_node_ctrl); + while (ENB_NORMAL_OPERATION != node_control_state) + pthread_cond_wait(&cond_node_ctrl, &mutex_node_ctrl); + pthread_mutex_unlock(&mutex_node_ctrl); + + /* reconfigure eNB in case FlexRAN controller applied changes */ + for (i=0; i < NB_eNB_INST; i++){ + LOG_I(ENB_APP, "Reconfigure eNB module %d and FlexRAN eNB variables\n", i); + reconfigure_enb_params(i); + flexran_set_enb_vars(i, RAN_LTE_OAI); + } #endif - // reconfigure_enb: 0 for wait, 1 for skip, and other values to reconfigure - for (i=0; (i < NB_eNB_INST && node_control_state == ENB_NORMAL_OPERATION ) ; i++){ - reconfigure_enb_params(i); - printf("[ENB_APP] Reconfigured eNB module %d - continue\n", i); - } - if (UE_flag==1) { NB_UE_INST=1; NB_INST=1; @@ -2175,6 +2182,10 @@ int main( int argc, char **argv ) { stop_eNB(1); } +#ifdef FLEXRAN_AGENT_SB_IF + pthread_cond_destroy(&cond_node_ctrl); + pthread_mutex_destroy(&mutex_node_ctrl); +#endif pthread_cond_destroy(&sync_cond); pthread_mutex_destroy(&sync_mutex); @@ -2200,5 +2211,6 @@ int main( int argc, char **argv ) { logClean(); + printf("Bye.\n"); return 0; } diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index a0883c3d59..4dbdd2a40a 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -92,4 +92,11 @@ extern void init_te_thread(PHY_VARS_eNB *, pthread_attr_t *); extern int stop_L1L2(int enb_id); extern int restart_L1L2(int enb_id); +#ifdef FLEXRAN_AGENT_SB_IF +#include "flexran_agent.h" // for locking +volatile ENB_MODULE_STATE node_control_state; +pthread_cond_t cond_node_ctrl; +pthread_mutex_t mutex_node_ctrl; +#endif + #endif From f39dd5df1887519ee23257e5347840dc0ba32175 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 13 Dec 2017 14:43:33 +0100 Subject: [PATCH 058/195] bugfix: handle variable start_eNB in restart --- openair2/ENB_APP/flexran_agent_common_internal.c | 3 +++ targets/RT/USER/lte-softmodem.c | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/openair2/ENB_APP/flexran_agent_common_internal.c b/openair2/ENB_APP/flexran_agent_common_internal.c index c2bd396e36..67f4b7371c 100644 --- a/openair2/ENB_APP/flexran_agent_common_internal.c +++ b/openair2/ENB_APP/flexran_agent_common_internal.c @@ -62,6 +62,9 @@ void handle_reconfiguration(mid_t mod_id) return; } enb_app_start_phy_rrc(mod_id, mod_id+1); + MessageDef *msg_p = itti_alloc_new_message(TASK_ENB_APP, INITIALIZE_MESSAGE); + itti_send_msg_to_task(TASK_L2L1, INSTANCE_DEFAULT, msg_p); + int diff_ms = (1000 * clock() - start_ms) / CLOCKS_PER_SEC; LOG_I(ENB_APP, "lte-softmodem restart succeeded in %d ms\n", diff_ms); } diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 39f40733f2..04113ef3ae 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -555,7 +555,8 @@ void *l2l1_task(void *arg) { case TERMINATE_MESSAGE: LOG_W(TASK_L2L1, " *** Exiting L2L1 thread\n"); - oai_exit=1; + oai_exit = 1; + start_eNB = 0; itti_exit_task (); break; From 359e1528dd2c0e20232aac7fad67b6ee14b0c71f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 14 Dec 2017 12:44:16 +0100 Subject: [PATCH 059/195] refactor: FlexRAN reads eNB configuration automatically --- openair2/ENB_APP/flexran_agent.c | 5 +++-- openair2/ENB_APP/flexran_agent.h | 2 +- openair2/ENB_APP/flexran_agent_ran_api.c | 3 +-- targets/RT/USER/lte-softmodem.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/openair2/ENB_APP/flexran_agent.c b/openair2/ENB_APP/flexran_agent.c index 8af071527f..5a399541f5 100644 --- a/openair2/ENB_APP/flexran_agent.c +++ b/openair2/ENB_APP/flexran_agent.c @@ -187,9 +187,10 @@ pthread_t new_thread(void *(*f)(void *), void *b) { } int channel_container_init = 0; -int flexran_agent_start(mid_t mod_id, const Enb_properties_array_t* enb_properties){ - +int flexran_agent_start(mid_t mod_id) +{ int channel_id; + Enb_properties_array_t *enb_properties = enb_config_get(); flexran_set_enb_vars(mod_id, RAN_LTE_OAI); flexran_agent[mod_id].enb_id = mod_id; diff --git a/openair2/ENB_APP/flexran_agent.h b/openair2/ENB_APP/flexran_agent.h index f9205c071f..c1eb997e57 100644 --- a/openair2/ENB_APP/flexran_agent.h +++ b/openair2/ENB_APP/flexran_agent.h @@ -46,7 +46,7 @@ /* Initiation and termination of the eNodeB agent */ -int flexran_agent_start(mid_t mod_id, const Enb_properties_array_t* enb_properties); +int flexran_agent_start(mid_t mod_id); int flexran_agent_stop(mid_t mod_id); /* diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 3ecbf77e11..01c5c472bd 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -44,16 +44,15 @@ void flexran_set_enb_vars(mid_t mod_id, ran_name_t ran){ switch (ran){ case RAN_LTE_OAI : + enb_properties = enb_config_get(); if(eNB_mac_inst == NULL){ enb[mod_id] = NULL; enb_ue[mod_id] = NULL; enb_rrc[mod_id] = NULL; - enb_properties = NULL; }else{ enb[mod_id] = (void *)&eNB_mac_inst[mod_id]; enb_ue[mod_id] = (void *)&eNB_mac_inst[mod_id].UE_list; enb_rrc[mod_id] = (void *)&eNB_rrc_inst[mod_id]; - enb_properties = (Enb_properties_array_t *) enb_config_get(); } break; default : diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 04113ef3ae..cbcf26145b 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1800,7 +1800,7 @@ int main( int argc, char **argv ) { pthread_cond_init(&cond_node_ctrl, NULL); for (i = 0; i < NB_eNB_INST; i++) { - flexran_agent_start(i, enb_config_get()); + flexran_agent_start(i); } LOG_I(ENB_APP, " * Waiting for FlexRAN RTController command *\n"); From d35f52a22847404ffa328091d160f4f1d94e5c37 Mon Sep 17 00:00:00 2001 From: Navid Nikaein Date: Thu, 14 Dec 2017 15:15:00 +0100 Subject: [PATCH 060/195] Add observation window to the PDCP stats --- .../CONTROL_MODULES/PDCP/flexran_agent_pdcp.c | 24 ++--- .../ENB_APP/MESSAGES/V2/stats_common.proto | 12 +-- openair2/ENB_APP/flexran_agent_ran_api.c | 40 +++++--- openair2/ENB_APP/flexran_agent_ran_api.h | 20 ++-- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 95 +++++++++++-------- openair2/LAYER2/PDCP_v10.1.0/pdcp.h | 35 ++++--- 6 files changed, 133 insertions(+), 93 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c index e4cc520070..25ec919127 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c +++ b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c @@ -51,18 +51,18 @@ void flexran_agent_pdcp_aggregate_stats(const mid_t mod_id, pdcp_aggr_stats->pkt_tx += flexran_get_pdcp_tx(mod_id,ue_id,lcid); pdcp_aggr_stats->pkt_tx_bytes += flexran_get_pdcp_tx_bytes(mod_id,ue_id,lcid); - pdcp_aggr_stats->pkt_tx_rate_s += flexran_get_pdcp_tx_rate_s(mod_id,ue_id,lcid); - pdcp_aggr_stats->pkt_tx_throughput_s += flexran_get_pdcp_tx_throughput_s(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_tx_w += flexran_get_pdcp_tx_w(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_tx_bytes_w += flexran_get_pdcp_tx_bytes_w(mod_id,ue_id,lcid); pdcp_aggr_stats->pkt_tx_aiat += flexran_get_pdcp_tx_aiat(mod_id,ue_id,lcid); - pdcp_aggr_stats->pkt_tx_aiat_s += flexran_get_pdcp_tx_aiat_s(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_tx_aiat_w += flexran_get_pdcp_tx_aiat_w(mod_id,ue_id,lcid); pdcp_aggr_stats->pkt_rx += flexran_get_pdcp_rx(mod_id,ue_id,lcid); pdcp_aggr_stats->pkt_rx_bytes += flexran_get_pdcp_rx_bytes(mod_id,ue_id,lcid); - pdcp_aggr_stats->pkt_rx_rate_s += flexran_get_pdcp_rx_rate_s(mod_id,ue_id,lcid); - pdcp_aggr_stats->pkt_rx_goodput_s += flexran_get_pdcp_rx_goodput_s(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_rx_w += flexran_get_pdcp_rx_w(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_rx_bytes_w += flexran_get_pdcp_rx_bytes_w(mod_id,ue_id,lcid); pdcp_aggr_stats->pkt_rx_aiat += flexran_get_pdcp_rx_aiat(mod_id,ue_id,lcid); - pdcp_aggr_stats->pkt_rx_aiat_s += flexran_get_pdcp_rx_aiat_s(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_rx_aiat_w += flexran_get_pdcp_rx_aiat_w(mod_id,ue_id,lcid); pdcp_aggr_stats->pkt_rx_oo += flexran_get_pdcp_rx_oo(mod_id,ue_id,lcid); } @@ -99,20 +99,20 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id, pdcp_aggr_stats->has_pkt_tx=1; pdcp_aggr_stats->has_pkt_tx_bytes =1; - pdcp_aggr_stats->has_pkt_tx_rate_s=1; - pdcp_aggr_stats->has_pkt_tx_throughput_s =1; + pdcp_aggr_stats->has_pkt_tx_w=1; + pdcp_aggr_stats->has_pkt_tx_bytes_w =1; pdcp_aggr_stats->has_pkt_tx_aiat =1; - pdcp_aggr_stats->has_pkt_tx_aiat_s =1; + pdcp_aggr_stats->has_pkt_tx_aiat_w =1; pdcp_aggr_stats->pkt_tx_sn = flexran_get_pdcp_tx_sn(mod_id, i, DEFAULT_DRB); pdcp_aggr_stats->has_pkt_tx_sn =1; pdcp_aggr_stats->has_pkt_rx =1; pdcp_aggr_stats->has_pkt_rx_bytes =1; - pdcp_aggr_stats->has_pkt_rx_rate_s =1; - pdcp_aggr_stats->has_pkt_rx_goodput_s =1; + pdcp_aggr_stats->has_pkt_rx_w =1; + pdcp_aggr_stats->has_pkt_rx_bytes_w =1; pdcp_aggr_stats->has_pkt_rx_aiat =1; - pdcp_aggr_stats->has_pkt_rx_aiat_s =1; + pdcp_aggr_stats->has_pkt_rx_aiat_w =1; pdcp_aggr_stats->has_pkt_rx_oo =1; pdcp_aggr_stats->pkt_rx_sn = flexran_get_pdcp_rx_sn(mod_id, i, DEFAULT_DRB); diff --git a/openair2/ENB_APP/MESSAGES/V2/stats_common.proto b/openair2/ENB_APP/MESSAGES/V2/stats_common.proto index 94da9fbd04..f651195ab1 100644 --- a/openair2/ENB_APP/MESSAGES/V2/stats_common.proto +++ b/openair2/ENB_APP/MESSAGES/V2/stats_common.proto @@ -253,18 +253,18 @@ message flex_pdcp_stats { optional uint32 pkt_tx = 1; optional uint32 pkt_tx_bytes = 2; optional uint32 pkt_tx_sn = 3; - optional uint32 pkt_tx_rate_s = 4; - optional uint32 pkt_tx_throughput_s = 5; + optional uint32 pkt_tx_w = 4; + optional uint32 pkt_tx_bytes_w = 5; optional uint32 pkt_tx_aiat = 7; - optional uint32 pkt_tx_aiat_s = 8; + optional uint32 pkt_tx_aiat_w = 8; optional uint32 pkt_rx = 9; optional uint32 pkt_rx_bytes = 10; optional uint32 pkt_rx_sn = 11; - optional uint32 pkt_rx_rate_s = 12; - optional uint32 pkt_rx_goodput_s = 13; + optional uint32 pkt_rx_w = 12; + optional uint32 pkt_rx_bytes_w = 13; optional uint32 pkt_rx_aiat = 14; - optional uint32 pkt_rx_aiat_s = 15; + optional uint32 pkt_rx_aiat_w = 15; optional uint32 pkt_rx_oo = 16; optional uint64 sfn=17; diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 01c5c472bd..556f018f7c 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -1134,6 +1134,22 @@ uint32_t flexran_get_pdcp_sfn(const mid_t mod_id){ return pdcp_enb[mod_id].sfn; } +/*PDCP super frame counter flexRAN*/ +uint32_t flexran_set_pdcp_tx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window){ + if (obs_window > 0 ) + Pdcp_stats_tx_window_ms[mod_id][ue_id]=obs_window; + else + Pdcp_stats_tx_window_ms[mod_id][ue_id]=1000; +} + +/*PDCP super frame counter flexRAN*/ +uint32_t flexran_set_pdcp_rx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window){ + if (obs_window > 0 ) + Pdcp_stats_rx_window_ms[mod_id][ue_id]=obs_window; + else + Pdcp_stats_rx_window_ms[mod_id][ue_id]=1000; +} + /*PDCP num tx pdu status flexRAN*/ uint32_t flexran_get_pdcp_tx(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ if (mod_id <0 || mod_id> MAX_NUM_CCs || ue_id<0 || ue_id> NUMBER_OF_UE_MAX || lcid<0 || lcid>NB_RB_MAX) @@ -1147,13 +1163,13 @@ uint32_t flexran_get_pdcp_tx_bytes(const mid_t mod_id, const mid_t ue_id, const } /*PDCP number of transmit packet / second status flexRAN*/ -uint32_t flexran_get_pdcp_tx_rate_s(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_tx_rate_s[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_tx_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_tx_w[mod_id][ue_id][lcid]; } /*PDCP throughput (bit/s) status flexRAN*/ -uint32_t flexran_get_pdcp_tx_throughput_s(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_tx_throughput_s[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_tx_bytes_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_tx_bytes_w[mod_id][ue_id][lcid]; } /*PDCP tx sequence number flexRAN*/ @@ -1167,8 +1183,8 @@ uint32_t flexran_get_pdcp_tx_aiat(const mid_t mod_id, const mid_t ue_id, const } /*PDCP tx aggregated packet arrival flexRAN*/ -uint32_t flexran_get_pdcp_tx_aiat_s(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_tx_aiat_s[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_tx_aiat_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_tx_aiat_w[mod_id][ue_id][lcid]; } @@ -1183,13 +1199,13 @@ uint32_t flexran_get_pdcp_rx_bytes(const mid_t mod_id, const mid_t ue_id, const } /*PDCP number of received packet / second flexRAN*/ -uint32_t flexran_get_pdcp_rx_rate_s(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_rx_rate_s[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_rx_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_rx_w[mod_id][ue_id][lcid]; } /*PDCP gootput (bit/s) status flexRAN*/ -uint32_t flexran_get_pdcp_rx_goodput_s(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_rx_goodput_s[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_rx_bytes_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_rx_bytes_w[mod_id][ue_id][lcid]; } /*PDCP rx sequence number flexRAN*/ @@ -1203,8 +1219,8 @@ uint32_t flexran_get_pdcp_rx_aiat(const mid_t mod_id, const mid_t ue_id, const } /*PDCP rx aggregated packet arrival flexRAN*/ -uint32_t flexran_get_pdcp_rx_aiat_s(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ - return Pdcp_stats_rx_aiat_s[mod_id][ue_id][lcid]; +uint32_t flexran_get_pdcp_rx_aiat_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid){ + return Pdcp_stats_rx_aiat_w[mod_id][ue_id][lcid]; } /*PDCP num of received outoforder pdu status flexRAN*/ diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 84723be005..12ca5febea 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -345,6 +345,12 @@ int flexran_get_rrc_status(const mid_t mod_id, const rnti_t rntiP); /*PDCP superframe numberflexRAN*/ uint32_t flexran_get_pdcp_sfn(const mid_t mod_id); +/*PDCP pdcp tx stats window*/ +uint32_t flexran_set_pdcp_tx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window); + +/*PDCP pdcp rx stats window*/ +uint32_t flexran_set_pdcp_rx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window); + /*PDCP num tx pdu status flexRAN*/ uint32_t flexran_get_pdcp_tx(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); @@ -352,10 +358,10 @@ uint32_t flexran_get_pdcp_tx(const mid_t mod_id, const mid_t ue_id, const lcid_ uint32_t flexran_get_pdcp_tx_bytes(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); /*PDCP number of transmit packet / second status flexRAN*/ -uint32_t flexran_get_pdcp_tx_rate_s(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_tx_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); -/*PDCP throughput (bit/s) status flexRAN*/ -uint32_t flexran_get_pdcp_tx_throughput_s(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +/*PDCP pdcp tx bytes in a given window flexRAN*/ +uint32_t flexran_get_pdcp_tx_bytes_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); /*PDCP tx sequence number flexRAN*/ uint32_t flexran_get_pdcp_tx_sn(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); @@ -364,7 +370,7 @@ uint32_t flexran_get_pdcp_tx_sn(const mid_t mod_id, const mid_t ue_id, const lc uint32_t flexran_get_pdcp_tx_aiat(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); /*PDCP tx aggregated packet arrival per second flexRAN*/ -uint32_t flexran_get_pdcp_tx_aiat_s(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_tx_aiat_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); /*PDCP num rx pdu status flexRAN*/ @@ -374,10 +380,10 @@ uint32_t flexran_get_pdcp_rx(const mid_t mod_id, const mid_t ue_id, const lcid_ uint32_t flexran_get_pdcp_rx_bytes(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); /*PDCP number of received packet / second flexRAN*/ -uint32_t flexran_get_pdcp_rx_rate_s(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_rx_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); /*PDCP gootput (bit/s) status flexRAN*/ -uint32_t flexran_get_pdcp_rx_goodput_s(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_rx_bytes_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); /*PDCP rx sequence number flexRAN*/ uint32_t flexran_get_pdcp_rx_sn(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); @@ -386,7 +392,7 @@ uint32_t flexran_get_pdcp_rx_sn(const mid_t mod_id, const mid_t ue_id, const lc uint32_t flexran_get_pdcp_rx_aiat(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); /*PDCP rx aggregated packet arrival per second flexRAN*/ -uint32_t flexran_get_pdcp_rx_aiat_s(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); +uint32_t flexran_get_pdcp_rx_aiat_w(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); /*PDCP num of received outoforder pdu status flexRAN*/ uint32_t flexran_get_pdcp_rx_oo(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index df85b06d06..d74e8552d6 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -408,13 +408,13 @@ boolean_t pdcp_data_req( //LOG_I(PDCP,"ueid %d lcid %d tx seq num %d\n", pdcp_uid, rb_idP+rb_offset, current_sn); Pdcp_stats_tx[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; - Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; + Pdcp_stats_tx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; Pdcp_stats_tx_bytes[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=sdu_buffer_sizeP; - Pdcp_stats_tx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=sdu_buffer_sizeP; + Pdcp_stats_tx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=sdu_buffer_sizeP; Pdcp_stats_tx_sn[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=current_sn; Pdcp_stats_tx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); - Pdcp_stats_tx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + Pdcp_stats_tx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=pdcp_enb[ctxt_pP->module_id].sfn; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_OUT); @@ -880,9 +880,9 @@ pdcp_data_ind( } Pdcp_stats_rx[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; - Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; + Pdcp_stats_rx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; Pdcp_stats_rx_bytes[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(sdu_buffer_sizeP - payload_offset); - Pdcp_stats_rx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(sdu_buffer_sizeP - payload_offset); + Pdcp_stats_rx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(sdu_buffer_sizeP - payload_offset); Pdcp_stats_rx_sn[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=sequence_number; @@ -890,7 +890,7 @@ pdcp_data_ind( Pdcp_stats_rx_outoforder[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; Pdcp_stats_rx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); - Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + Pdcp_stats_rx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=pdcp_enb[ctxt_pP->module_id].sfn; @@ -920,36 +920,45 @@ void pdcp_update_stats(const protocol_ctxt_t* const ctxt_pP){ uint8_t rb_id = 0; // these stats are measured for both eNB and UE on per seond basis - if (pdcp_enb[ctxt_pP->module_id].sfn % 1000 == 0){ - for (rb_id =0; rb_id < NB_RB_MAX; rb_id ++){ - for (pdcp_uid=0; pdcp_uid< NUMBER_OF_UE_MAX;pdcp_uid++){ - //printf("frame %d and subframe %d \n", pdcp_enb[ctxt_pP->module_id].frame, pdcp_enb[ctxt_pP->module_id].subframe); - // tx stats - Pdcp_stats_tx_rate_s[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_id]; + for (rb_id =0; rb_id < NB_RB_MAX; rb_id ++){ + for (pdcp_uid=0; pdcp_uid< NUMBER_OF_UE_MAX;pdcp_uid++){ + //printf("frame %d and subframe %d \n", pdcp_enb[ctxt_pP->module_id].frame, pdcp_enb[ctxt_pP->module_id].subframe); + // tx stats + if (pdcp_enb[ctxt_pP->module_id].sfn % Pdcp_stats_tx_window_ms[ctxt_pP->module_id][pdcp_uid] == 0){ // unit: bit/s - Pdcp_stats_tx_throughput_s[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_tx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_id]*8; - if (Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_id] > 0){ - Pdcp_stats_tx_aiat_s[ctxt_pP->module_id][pdcp_uid][rb_id]=(Pdcp_stats_tx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_id]/Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_id]); - } - - Pdcp_stats_tx_s[ctxt_pP->module_id][pdcp_uid][rb_id]=0; - Pdcp_stats_tx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_id]=0; - Pdcp_stats_tx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + Pdcp_stats_tx_throughput_w[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_tx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]*8; + Pdcp_stats_tx_w[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_tx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]; + Pdcp_stats_tx_bytes_w[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_tx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]; + if (Pdcp_stats_tx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id] > 0){ + Pdcp_stats_tx_aiat_w[ctxt_pP->module_id][pdcp_uid][rb_id]=(Pdcp_stats_tx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]/Pdcp_stats_tx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]); + }else { + Pdcp_stats_tx_aiat_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + } + // reset the tmp vars + Pdcp_stats_tx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + Pdcp_stats_tx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + Pdcp_stats_tx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + } + if (pdcp_enb[ctxt_pP->module_id].sfn % Pdcp_stats_rx_window_ms[ctxt_pP->module_id][pdcp_uid] == 0){ // rx stats - Pdcp_stats_rx_rate_s[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_id]; - Pdcp_stats_rx_goodput_s[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_rx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_id]*8; - - if(Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_id] > 0){ - Pdcp_stats_rx_aiat_s[ctxt_pP->module_id][pdcp_uid][rb_id]= (Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_id]/Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_id]); - } + Pdcp_stats_rx_goodput_w[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_rx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]*8; + Pdcp_stats_rx_w[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_rx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]; + Pdcp_stats_rx_bytes_w[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_rx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]; - Pdcp_stats_rx_s[ctxt_pP->module_id][pdcp_uid][rb_id]=0; - Pdcp_stats_rx_bytes_s[ctxt_pP->module_id][pdcp_uid][rb_id]=0; - Pdcp_stats_rx_aiat_tmp_s[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + if(Pdcp_stats_rx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id] > 0){ + Pdcp_stats_rx_aiat_w[ctxt_pP->module_id][pdcp_uid][rb_id]= (Pdcp_stats_rx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]/Pdcp_stats_rx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]); + } else { + Pdcp_stats_rx_aiat_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + } + // reset the tmp vars + Pdcp_stats_rx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + Pdcp_stats_rx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + Pdcp_stats_rx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; } } + } } //----------------------------------------------------------------------------- @@ -2024,6 +2033,7 @@ void pdcp_layer_init(void) { module_id_t instance; + int i,j; #if defined(Rel10) || defined(Rel14) mbms_session_id_t session_id; mbms_service_id_t service_id; @@ -2070,24 +2080,35 @@ void pdcp_layer_init(void) memset(pdcp_enb, 0, sizeof(pdcp_enb_t)); + memset(Pdcp_stats_tx_window_ms, 0, sizeof(Pdcp_stats_tx_window_ms)); + memset(Pdcp_stats_rx_window_ms, 0, sizeof(Pdcp_stats_rx_window_ms)); + for (i =0; i< MAX_NUM_CCs ; i ++){ + for (j=0; j< NUMBER_OF_UE_MAX;j++){ + Pdcp_stats_tx_window_ms[i][j]=100; + Pdcp_stats_rx_window_ms[i][j]=100; + } + } + memset(Pdcp_stats_tx, 0, sizeof(Pdcp_stats_tx)); - memset(Pdcp_stats_tx_s, 0, sizeof(Pdcp_stats_tx_s)); + memset(Pdcp_stats_tx_w, 0, sizeof(Pdcp_stats_tx_w)); + memset(Pdcp_stats_tx_tmp_w, 0, sizeof(Pdcp_stats_tx_tmp_w)); memset(Pdcp_stats_tx_bytes, 0, sizeof(Pdcp_stats_tx_bytes)); - memset(Pdcp_stats_tx_bytes_s, 0, sizeof(Pdcp_stats_tx_bytes_s)); - memset(Pdcp_stats_tx_rate_s, 0, sizeof(Pdcp_stats_tx_rate_s)); + memset(Pdcp_stats_tx_bytes_w, 0, sizeof(Pdcp_stats_tx_bytes_w)); + memset(Pdcp_stats_tx_bytes_tmp_w, 0, sizeof(Pdcp_stats_tx_bytes_tmp_w)); memset(Pdcp_stats_tx_sn, 0, sizeof(Pdcp_stats_tx_sn)); - memset(Pdcp_stats_tx_throughput_s, 0, sizeof(Pdcp_stats_tx_throughput_s)); + memset(Pdcp_stats_tx_throughput_w, 0, sizeof(Pdcp_stats_tx_throughput_w)); memset(Pdcp_stats_tx_aiat, 0, sizeof(Pdcp_stats_tx_aiat)); memset(Pdcp_stats_tx_iat, 0, sizeof(Pdcp_stats_tx_iat)); memset(Pdcp_stats_rx, 0, sizeof(Pdcp_stats_rx)); - memset(Pdcp_stats_rx_s, 0, sizeof(Pdcp_stats_rx_s)); + memset(Pdcp_stats_rx_w, 0, sizeof(Pdcp_stats_rx_w)); + memset(Pdcp_stats_rx_tmp_w, 0, sizeof(Pdcp_stats_rx_tmp_w)); memset(Pdcp_stats_rx_bytes, 0, sizeof(Pdcp_stats_rx_bytes)); - memset(Pdcp_stats_rx_bytes_s, 0, sizeof(Pdcp_stats_rx_bytes_s)); - memset(Pdcp_stats_rx_rate_s, 0, sizeof(Pdcp_stats_rx_rate_s)); + memset(Pdcp_stats_rx_bytes_w, 0, sizeof(Pdcp_stats_rx_bytes_w)); + memset(Pdcp_stats_rx_bytes_tmp_w, 0, sizeof(Pdcp_stats_rx_bytes_tmp_w)); memset(Pdcp_stats_rx_sn, 0, sizeof(Pdcp_stats_rx_sn)); - memset(Pdcp_stats_rx_goodput_s, 0, sizeof(Pdcp_stats_rx_goodput_s)); + memset(Pdcp_stats_rx_goodput_w, 0, sizeof(Pdcp_stats_rx_goodput_w)); memset(Pdcp_stats_rx_aiat, 0, sizeof(Pdcp_stats_rx_aiat)); memset(Pdcp_stats_rx_iat, 0, sizeof(Pdcp_stats_rx_iat)); memset(Pdcp_stats_rx_outoforder, 0, sizeof(Pdcp_stats_rx_outoforder)); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index cf3d927051..cdd69a8659 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -94,35 +94,32 @@ extern int pdcp_instance_cnt; int init_pdcp_thread(void); void cleanup_pdcp_thread(void); -/* -public_pdcp(uint64_t Pdcp_sfn[MAX_NUM_CCs]); -public_pdcp(frame_t Pdcp_frame[MAX_NUM_CCs]); -public_pdcp(sub_frame_t Pdcp_subframe[MAX_NUM_CCs]); -public_pdcp(uint16_t Pdcp_num_ues[MAX_NUM_CCs]); -*/ - +public_pdcp(uint32_t Pdcp_stats_tx_window_ms[MAX_NUM_CCs][NUMBER_OF_UE_MAX]); public_pdcp(uint32_t Pdcp_stats_tx_bytes[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); -public_pdcp(uint32_t Pdcp_stats_tx_bytes_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_bytes_w[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_bytes_tmp_w[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); public_pdcp(uint32_t Pdcp_stats_tx[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); -public_pdcp(uint32_t Pdcp_stats_tx_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_w[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_tmp_w[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); public_pdcp(uint32_t Pdcp_stats_tx_sn[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); -public_pdcp(uint32_t Pdcp_stats_tx_rate_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); -public_pdcp(uint32_t Pdcp_stats_tx_throughput_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_throughput_w[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); public_pdcp(uint32_t Pdcp_stats_tx_aiat[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); -public_pdcp(uint32_t Pdcp_stats_tx_aiat_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); -public_pdcp(uint32_t Pdcp_stats_tx_aiat_tmp_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_aiat_w[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_tx_aiat_tmp_w[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); public_pdcp(uint32_t Pdcp_stats_tx_iat[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_window_ms[MAX_NUM_CCs][NUMBER_OF_UE_MAX]); public_pdcp(uint32_t Pdcp_stats_rx[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); -public_pdcp(uint32_t Pdcp_stats_rx_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_w[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_tmp_w[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); public_pdcp(uint32_t Pdcp_stats_rx_bytes[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); -public_pdcp(uint32_t Pdcp_stats_rx_bytes_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_bytes_w[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_bytes_tmp_w[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); public_pdcp(uint32_t Pdcp_stats_rx_sn[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); -public_pdcp(uint32_t Pdcp_stats_rx_rate_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); -public_pdcp(uint32_t Pdcp_stats_rx_goodput_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_goodput_w[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); public_pdcp(uint32_t Pdcp_stats_rx_aiat[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); -public_pdcp(uint32_t Pdcp_stats_rx_aiat_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); -public_pdcp(uint32_t Pdcp_stats_rx_aiat_tmp_s[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_aiat_w[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); +public_pdcp(uint32_t Pdcp_stats_rx_aiat_tmp_w[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); public_pdcp(uint32_t Pdcp_stats_rx_iat[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); public_pdcp(uint32_t Pdcp_stats_rx_outoforder[MAX_NUM_CCs][NUMBER_OF_UE_MAX][NB_RB_MAX]); From ccac021050d2754aa4f5591a42c04f95b6223096 Mon Sep 17 00:00:00 2001 From: shahab SHARIAT BAGHERI Date: Thu, 14 Dec 2017 18:34:41 +0100 Subject: [PATCH 061/195] Ue stats bugfix for dynamic reconfiguration --- openair2/ENB_APP/enb_app.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index 5fe0f741bf..98f9ee3682 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -283,6 +283,7 @@ void *eNB_app_task(void *args_p) #if defined(ENABLE_ITTI) uint32_t enb_nb = 1; /* Default number of eNB is 1 */ uint32_t enb_id_start = 0; + uint32_t enb_i; uint32_t enb_id_end = enb_id_start + enb_nb; # if defined(ENABLE_USE_MME) uint32_t register_enb_pending; @@ -318,7 +319,13 @@ void *eNB_app_task(void *args_p) enb_nb, enb_properties_p->number); enb_app_start_phy_rrc(enb_id_start, enb_id_end); - + +#ifdef FLEXRAN_AGENT_SB_IF + for (enb_i = 0; enb_i <1; enb_i ++){ // To be handled for all of current eNB + flexran_set_enb_vars(enb_i, RAN_LTE_OAI); + +} +#endif # if defined(ENABLE_USE_MME) /* Try to register each eNB */ registered_enb = 0; From b049f0c820ad7f09e763ff3e1dc602e3f7cdc663 Mon Sep 17 00:00:00 2001 From: Navid Nikaein Date: Thu, 14 Dec 2017 18:34:41 +0100 Subject: [PATCH 062/195] Ue stats bugfix for dynamic reconfiguration --- openair2/ENB_APP/enb_app.c | 8 +- openair2/ENB_APP/flexran_agent.c | 24 ++- openair2/ENB_APP/flexran_agent.h | 1 + .../MAC/flexran_agent_scheduler_dlsch_ue.c | 153 ++++++++------- .../MAC/flexran_agent_scheduler_ulsch_ue.c | 179 ++++++++++-------- 5 files changed, 209 insertions(+), 156 deletions(-) diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index 5fe0f741bf..d51b0efcd7 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -283,6 +283,7 @@ void *eNB_app_task(void *args_p) #if defined(ENABLE_ITTI) uint32_t enb_nb = 1; /* Default number of eNB is 1 */ uint32_t enb_id_start = 0; + uint32_t enb_i; uint32_t enb_id_end = enb_id_start + enb_nb; # if defined(ENABLE_USE_MME) uint32_t register_enb_pending; @@ -318,7 +319,12 @@ void *eNB_app_task(void *args_p) enb_nb, enb_properties_p->number); enb_app_start_phy_rrc(enb_id_start, enb_id_end); - + +#ifdef FLEXRAN_AGENT_SB_IF + for (enb_i = 0; enb_i <1; enb_i ++){ // To be handled for all of current eNB + flexran_set_enb_vars(enb_i, RAN_LTE_OAI); + } +#endif # if defined(ENABLE_USE_MME) /* Try to register each eNB */ registered_enb = 0; diff --git a/openair2/ENB_APP/flexran_agent.c b/openair2/ENB_APP/flexran_agent.c index 5a399541f5..7cb910ae1a 100644 --- a/openair2/ENB_APP/flexran_agent.c +++ b/openair2/ENB_APP/flexran_agent.c @@ -186,15 +186,9 @@ pthread_t new_thread(void *(*f)(void *), void *b) { return t; } -int channel_container_init = 0; -int flexran_agent_start(mid_t mod_id) -{ - int channel_id; +void flexran_agent_reconfigure(mid_t mod_id){ Enb_properties_array_t *enb_properties = enb_config_get(); - - flexran_set_enb_vars(mod_id, RAN_LTE_OAI); - flexran_agent[mod_id].enb_id = mod_id; - + /* * check the configuration */ @@ -204,7 +198,7 @@ int flexran_agent_start(mid_t mod_id) } else { strcpy(local_cache, DEFAULT_FLEXRAN_AGENT_CACHE); } - + if (enb_properties->properties[mod_id]->flexran_agent_ipv4_address != 0) { inet_ntop(AF_INET, &(enb_properties->properties[mod_id]->flexran_agent_ipv4_address), in_ip, INET_ADDRSTRLEN); } else { @@ -220,6 +214,18 @@ int flexran_agent_start(mid_t mod_id) flexran_agent[mod_id].enb_id, in_ip, in_port); + +} + +int channel_container_init = 0; +int flexran_agent_start(mid_t mod_id) +{ + int channel_id; + + flexran_set_enb_vars(mod_id, RAN_LTE_OAI); + flexran_agent[mod_id].enb_id = mod_id; + + flexran_agent_reconfigure(mod_id); /* * Initialize the channel container diff --git a/openair2/ENB_APP/flexran_agent.h b/openair2/ENB_APP/flexran_agent.h index c1eb997e57..b092e26d53 100644 --- a/openair2/ENB_APP/flexran_agent.h +++ b/openair2/ENB_APP/flexran_agent.h @@ -48,6 +48,7 @@ /* Initiation and termination of the eNodeB agent */ int flexran_agent_start(mid_t mod_id); int flexran_agent_stop(mid_t mod_id); +void flexran_agent_reconfigure(mid_t mod_id); /* * enb agent task mainly wakes up the tx thread for periodic and oneshot messages to the controller diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c index 601310d67a..a04987f07c 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c @@ -96,9 +96,11 @@ int slicing_strategy = UEID_TO_SLICEID; int slicing_strategy_current = UEID_TO_SLICEID; // RB share for each slice for past and current time -float slice_percentage[MAX_NUM_SLICES] = {1.0, 1.0, 0.0, 0.0}; -float slice_percentage_current[MAX_NUM_SLICES] = {1.0, 1.0, 0.0, 0.0}; +float avg_slice_percentage=0.25; +float slice_percentage[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; +float slice_percentage_current[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; float total_slice_percentage = 0; +float total_slice_percentage_current = 0; // MAX MCS for each slice for past and current time int slice_maxmcs[MAX_NUM_SLICES] = {28, 28, 28, 28}; @@ -724,7 +726,23 @@ flexran_schedule_ue_dl_spec_default(mid_t mod_id, int i=0; flexran_agent_mac_create_empty_dl_config(mod_id, dl_info); - + + total_slice_percentage=0; + avg_slice_percentage=1.0/n_active_slices; + + // reset the slice percentage for inactive slices + for (i = n_active_slices; i< MAX_NUM_SLICES; i++) { + slice_percentage[i]=0; + } + for (i = 0; i < n_active_slices; i++) { + if (slice_percentage[i] < 0 ){ + LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %d. resetting to zero", + mod_id, frame, subframe, i, slice_percentage[i]); + slice_percentage[i]=0; + } + total_slice_percentage+=slice_percentage[i]; + } + for (i = 0; i < n_active_slices; i++) { // Load any updated functions @@ -732,84 +750,77 @@ flexran_schedule_ue_dl_spec_default(mid_t mod_id, slice_sched_dl[i] = dlsym(NULL, dl_scheduler_type[i]); update_dl_scheduler[i] = 0; update_dl_scheduler_current[i] = 0; - slice_percentage_current[i]= slice_percentage[i]; - total_slice_percentage+=slice_percentage[i]; LOG_N(MAC,"update dl scheduler slice %d\n", i); } - - // check if the number of slices has changed, and log - if (n_active_slices_current != n_active_slices ){ - if ((n_active_slices > 0) && (n_active_slices <= MAX_NUM_SLICES)) { - LOG_N(MAC,"[eNB %d]frame %d subframe %d: number of active slices has changed: %d-->%d\n", - mod_id, frame, subframe, n_active_slices_current, n_active_slices); - n_active_slices_current = n_active_slices; + if (total_slice_percentage <= 1.0){ // the new total RB share is within the range - } else { - LOG_W(MAC,"invalid number of slices %d, revert to the previous value %d\n",n_active_slices, n_active_slices_current); - n_active_slices = n_active_slices_current; + // check if the number of slices has changed, and log + if (n_active_slices_current != n_active_slices ){ + if ((n_active_slices > 0) && (n_active_slices <= MAX_NUM_SLICES)) { + LOG_N(MAC,"[eNB %d]frame %d subframe %d: number of active DL slices has changed: %d-->%d\n", + mod_id, frame, subframe, n_active_slices_current, n_active_slices); + + n_active_slices_current = n_active_slices; + + } else { + LOG_W(MAC,"invalid number of DL slices %d, revert to the previous value %d\n",n_active_slices, n_active_slices_current); + n_active_slices = n_active_slices_current; + } } - } - - // check if the slice rb share has changed, and log the console - if (slice_percentage_current[i] != slice_percentage[i]){ - // if ((slice_percentage[i] >= 0.0) && (slice_percentage[i] <= 1.0)){ - // if ((total_slice_percentage - slice_percentage_current[i] + slice_percentage[i]) <= 1.0) { - // total_slice_percentage=total_slice_percentage - slice_percentage_current[i] + slice_percentage[i]; - LOG_N(MAC,"[eNB %d][SLICE %d] frame %d subframe %d: total percentage %f, slice RB percentage has changed: %f-->%f\n", - mod_id, i, frame, subframe, total_slice_percentage, slice_percentage_current[i], slice_percentage[i]); - - slice_percentage_current[i] = slice_percentage[i]; - - // } else { - // LOG_W(MAC,"[eNB %d][SLICE %d] invalid total RB share (%f->%f), revert the previous value (%f->%f)\n", - // mod_id,i, - // total_slice_percentage, - // total_slice_percentage - slice_percentage_current[i] + slice_percentage[i], - // slice_percentage[i],slice_percentage_current[i]); - - // slice_percentage[i]= slice_percentage_current[i]; - - // } - // } else { - // LOG_W(MAC,"[eNB %d][SLICE %d] invalid slice RB share, revert the previous value (%f->%f)\n",mod_id, i, slice_percentage[i],slice_percentage_current[i]); - - // slice_percentage[i]= slice_percentage_current[i]; - - // } - } - - // check if the slice max MCS, and log the console - if (slice_maxmcs_current[i] != slice_maxmcs[i]){ - if ((slice_maxmcs[i] >= 0) && (slice_maxmcs[i] < 29)){ - LOG_N(MAC,"[eNB %d][SLICE %d] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", - mod_id, i, frame, subframe, slice_maxmcs_current[i], slice_maxmcs[i]); - - slice_maxmcs_current[i] = slice_maxmcs[i]; - - } else { - // LOG_W(MAC,"[eNB %d][SLICE %d] invalid slice max mcs %d, revert the previous value %d\n",mod_id, i, slice_maxmcs[i],slice_percentage[i]); - - slice_maxmcs[i]= slice_maxmcs_current[i]; - - } - } - - // check if a new scheduler, and log the console - if (update_dl_scheduler_current[i] != update_dl_scheduler[i]){ - LOG_N(MAC,"[eNB %d][SLICE %d] frame %d subframe %d: DL scheduler for this slice is updated: %s \n", - mod_id, i, frame, subframe, dl_scheduler_type[i]); - - update_dl_scheduler_current[i] = update_dl_scheduler[i]; + // check if the slice rb share has changed, and log the console + if (slice_percentage_current[i] != slice_percentage[i]){ // new slice percentage + LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", + mod_id, i, frame, subframe, total_slice_percentage_current, total_slice_percentage, slice_percentage_current[i], slice_percentage[i]); + total_slice_percentage_current= total_slice_percentage; + slice_percentage_current[i] = slice_percentage[i]; + + } + + // check if the slice max MCS, and log the console + if (slice_maxmcs_current[i] != slice_maxmcs[i]){ + if ((slice_maxmcs[i] >= 0) && (slice_maxmcs[i] < 29)){ + LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", + mod_id, i, frame, subframe, slice_maxmcs_current[i], slice_maxmcs[i]); + slice_maxmcs_current[i] = slice_maxmcs[i]; + } else { + LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid slice max mcs %d, revert the previous value %d\n",mod_id, i, slice_maxmcs[i],slice_maxmcs_current[i]); + slice_maxmcs[i]= slice_maxmcs_current[i]; + } + } + + // check if a new scheduler, and log the console + if (update_dl_scheduler_current[i] != update_dl_scheduler[i]){ + LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: DL scheduler for this slice is updated: %s \n", + mod_id, i, frame, subframe, dl_scheduler_type[i]); + update_dl_scheduler_current[i] = update_dl_scheduler[i]; + } + + } else { + // here we can correct the values, e.g. reduce proportionally + + if (n_active_slices == n_active_slices_current){ + LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n", + mod_id,i, + total_slice_percentage_current, total_slice_percentage); + if (slice_percentage[i] >= avg_slice_percentage){ + slice_percentage[i]-=0.1; + total_slice_percentage-=0.1; + } + } else { + LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n", + mod_id,i, + total_slice_percentage_current, total_slice_percentage, + n_active_slices, n_active_slices_current ); + n_active_slices = n_active_slices_current; + slice_percentage[i] = slice_percentage_current[i]; + } } - + // Run each enabled slice-specific schedulers one by one - //LOG_N(MAC,"[eNB %d]frame %d subframe %d slice %d: calling the scheduler\n", mod_id, frame, subframe,i); slice_sched_dl[i](mod_id, i, frame, subframe, mbsfn_flag,dl_info); - } - } uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, int total_rbs){ diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c index 5b31c11681..64f21482fb 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c @@ -21,7 +21,7 @@ /*! \file eNB_scheduler_ulsch.c * \brief FlexRAN eNB procedures for the ULSCH transport channel - * \author shahab SHARIAT BAGHERI + * \author Navid Nikaein and shahab SHARIAT BAGHERI * \date 2017 * \version 1.0 * @ingroup _mac @@ -67,19 +67,21 @@ /* number of active slices for past and current time*/ int n_active_slices_uplink = 1; -int n_active_slices_uplink_current = 1; +int n_active_slices_current_uplink = 1; /* RB share for each slice for past and current time*/ -float slice_percentage_uplink[MAX_NUM_SLICES] = {1.0, 1.0, 0.0, 0.0}; -float slice_percentage_current_uplink[MAX_NUM_SLICES] = {1.0, 1.0, 0.0, 0.0}; +float avg_slice_percentage_uplink=0.25; +float slice_percentage_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; +float slice_percentage_current_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; float total_slice_percentage_uplink = 0; +float total_slice_percentage_current_uplink = 0; // MAX MCS for each slice for past and current time int slice_maxmcs_uplink[MAX_NUM_SLICES] = {16, 16, 16, 16}; -int slice_maxmcs_current_uplink[MAX_NUM_SLICES] = {28, 28, 28, 28}; +int slice_maxmcs_current_uplink[MAX_NUM_SLICES] = {16,16,16,16}; /*resource blocks allowed*/ -uint16_t nb_rbs_allowed_slice_uplink[MAX_NUM_CCs][MAX_NUM_SLICES]; +uint16_t nb_rbs_allowed_slice_uplink[MAX_NUM_CCs][MAX_NUM_SLICES]; /*Slice Update */ int update_ul_scheduler[MAX_NUM_SLICES] = {1, 1, 1, 1}; int update_ul_scheduler_current[MAX_NUM_SLICES] = {1, 1, 1, 1}; @@ -89,9 +91,9 @@ slice_scheduler_ul slice_sched_ul[MAX_NUM_SLICES] = {0}; /* name of available scheduler*/ char *ul_scheduler_type[MAX_NUM_SLICES] = {"flexran_schedule_ue_ul_spec_embb", - "flexran_schedule_ue_ul_spec_urllc", - "flexran_schedule_ue_ul_spec_mmtc", - "flexran_schedule_ue_ul_spec_be" // best effort + "flexran_schedule_ue_ul_spec_embb", + "flexran_schedule_ue_ul_spec_embb", + "flexran_schedule_ue_ul_spec_embb" // best effort }; @@ -418,6 +420,22 @@ flexran_schedule_ue_ul_spec_default(mid_t mod_id, flexran_agent_mac_create_empty_ul_config(mod_id, ul_info); + total_slice_percentage_uplink=0; + avg_slice_percentage_uplink=1.0/n_active_slices_uplink; + + // reset the slice percentage for inactive slices + for (i = n_active_slices_uplink; i< MAX_NUM_SLICES; i++) { + slice_percentage_uplink[i]=0; + } + for (i = 0; i < n_active_slices_uplink; i++) { + if (slice_percentage_uplink[i] < 0 ){ + LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %d. resetting to zero", + mod_id, frame, subframe, i, slice_percentage_uplink[i]); + slice_percentage_uplink[i]=0; + } + total_slice_percentage_uplink+=slice_percentage_uplink[i]; + } + for (i = 0; i < n_active_slices_uplink; i++) { // Load any updated functions @@ -425,89 +443,100 @@ flexran_schedule_ue_ul_spec_default(mid_t mod_id, slice_sched_ul[i] = dlsym(NULL, ul_scheduler_type[i]); update_ul_scheduler[i] = 0; update_ul_scheduler_current[i] = 0; - slice_percentage_current_uplink[i]= slice_percentage_uplink[i]; - total_slice_percentage_uplink+=slice_percentage_uplink[i]; + //slice_percentage_current_uplink[i]= slice_percentage_uplink[i]; + //total_slice_percentage_current_uplink+=slice_percentage_uplink[i]; + //if (total_slice_percentage_current_uplink> 1) + // total_slice_percentage_current_uplink=1; LOG_N(MAC,"update ul scheduler slice %d\n", i); } - - // check if the number of slices has changed, and log - if (n_active_slices_uplink_current != n_active_slices_uplink ){ - if ((n_active_slices_uplink > 0) && (n_active_slices_uplink <= MAX_NUM_SLICES)) { - LOG_N(MAC,"[eNB %d]frame %d subframe %d: number of active slices has changed: %d-->%d\n", - mod_id, frame, subframe, n_active_slices_uplink_current, n_active_slices_uplink); + // the new total RB share is within the range + if (total_slice_percentage_uplink <= 1.0){ - n_active_slices_uplink_current = n_active_slices_uplink; - - } else { - LOG_W(MAC,"invalid number of slices %d, revert to the previous value %d\n",n_active_slices_uplink, n_active_slices_uplink_current); - n_active_slices_uplink = n_active_slices_uplink_current; + // check if the number of slices has changed, and log + if (n_active_slices_current_uplink != n_active_slices_uplink ){ + if ((n_active_slices_uplink > 0) && (n_active_slices_uplink <= MAX_NUM_SLICES)) { + LOG_N(MAC,"[eNB %d]frame %d subframe %d: number of active UL slices has changed: %d-->%d\n", + mod_id, frame, subframe, n_active_slices_current_uplink, n_active_slices_uplink); + + n_active_slices_current_uplink = n_active_slices_uplink; + + } else { + LOG_W(MAC,"invalid number of UL slices %d, revert to the previous value %d\n",n_active_slices_uplink, n_active_slices_current_uplink); + n_active_slices_uplink = n_active_slices_current_uplink; + } } - } // check if the slice rb share has changed, and log the console - if (slice_percentage_current_uplink[i] != slice_percentage_uplink[i]){ - // if ((slice_percentage_uplink[i] >= 0.0) && (slice_percentage_uplink[i] <= 1.0)){ - // if ((total_slice_percentage_uplink - slice_percentage_current_uplink[i] + slice_percentage_uplink[i]) <= 1.0) { - // total_slice_percentage_uplink=total_slice_percentage_uplink - slice_percentage_current_uplink[i] + slice_percentage_uplink[i]; - LOG_N(MAC,"[eNB %d][SLICE %d] frame %d subframe %d: total percentage %f, slice RB percentage has changed: %f-->%f\n", - mod_id, i, frame, subframe, total_slice_percentage_uplink, slice_percentage_current_uplink[i], slice_percentage_uplink[i]); - - slice_percentage_current_uplink[i] = slice_percentage_uplink[i]; - - // } else { - // LOG_W(MAC,"[eNB %d][SLICE %d] invalid total RB share (%f->%f), revert the previous value (%f->%f)\n", - // mod_id,i, - // total_slice_percentage_uplink, - // total_slice_percentage_uplink - slice_percentage_current_uplink[i] + slice_percentage_uplink[i], - // slice_percentage_uplink[i],slice_percentage_current_uplink[i]); - - // slice_percentage_uplink[i]= slice_percentage_current_uplink[i]; - - // } - // } else { - // LOG_W(MAC,"[eNB %d][SLICE %d] invalid slice RB share, revert the previous value (%f->%f)\n",mod_id, i, slice_percentage_uplink[i],slice_percentage_current_uplink[i]); - - // slice_percentage_uplink[i]= slice_percentage_current_uplink[i]; - - // } - } - - // check if a new scheduler, and log the console - if (update_ul_scheduler_current[i] != update_ul_scheduler[i]){ - LOG_N(MAC,"[eNB %d][SLICE %d] frame %d subframe %d: DL scheduler for this slice is updated: %s \n", - mod_id, i, frame, subframe, ul_scheduler_type[i]); - - update_ul_scheduler_current[i] = update_ul_scheduler[i]; + if (slice_percentage_current_uplink[i] != slice_percentage_uplink[i]){ + LOG_N(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", + mod_id, i, frame, subframe, total_slice_percentage_current_uplink, total_slice_percentage_uplink, slice_percentage_current_uplink[i], slice_percentage_uplink[i]); + total_slice_percentage_current_uplink= total_slice_percentage_uplink; + slice_percentage_current_uplink[i] = slice_percentage_uplink[i]; + + } + // check if the slice max MCS, and log the console + if (slice_maxmcs_current_uplink[i] != slice_maxmcs_uplink[i]){ + if ((slice_maxmcs_uplink[i] >= 0) && (slice_maxmcs_uplink[i] <= 16)){ + LOG_N(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", + mod_id, i, frame, subframe, slice_maxmcs_current_uplink[i], slice_maxmcs_uplink[i]); + slice_maxmcs_current_uplink[i] = slice_maxmcs_uplink[i]; + } else { + LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid slice max mcs %d, revert the previous value %d\n",mod_id, i, slice_maxmcs_uplink[i],slice_maxmcs_current_uplink[i]); + slice_maxmcs_uplink[i]= slice_maxmcs_current_uplink[i]; + + } + } + + // check if a new scheduler, and log the console + if (update_ul_scheduler_current[i] != update_ul_scheduler[i]){ + LOG_N(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: UL scheduler for this slice is updated: %s \n", + mod_id, i, frame, subframe, ul_scheduler_type[i]); + + update_ul_scheduler_current[i] = update_ul_scheduler[i]; + } } - + else { + + if (n_active_slices_uplink == n_active_slices_current_uplink){ + LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n", + mod_id,i, + total_slice_percentage_current_uplink, total_slice_percentage_uplink); + if (slice_percentage_uplink[i] > avg_slice_percentage_uplink){ + slice_percentage_uplink[i]-=0.1; + total_slice_percentage_uplink-=0.1; + } + } else { + // here we can correct the values, e.g. reduce proportionally + LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n", + mod_id,i, + total_slice_percentage_current_uplink, total_slice_percentage_uplink, + n_active_slices_uplink, n_active_slices_current_uplink); + n_active_slices_uplink = n_active_slices_current_uplink; + slice_percentage_uplink[i] = slice_percentage_current_uplink[i]; + } + } + // Run each enabled slice-specific schedulers one by one - //LOG_N(MAC,"[eNB %d]frame %d subframe %d slice %d: calling the scheduler\n", mod_id, frame, subframe,i); - - slice_sched_ul[i](mod_id, frame, cooperation_flag, subframe, sched_subframe,ul_info); - } - - - } void flexran_schedule_ue_ul_spec_embb(mid_t mod_id, - frame_t frame, - unsigned char cooperation_flag, - uint32_t subframe, - unsigned char sched_subframe, - Protocol__FlexranMessage **ul_info) - + frame_t frame, + unsigned char cooperation_flag, + uint32_t subframe, + unsigned char sched_subframe, + Protocol__FlexranMessage **ul_info) + { flexran_agent_schedule_ulsch_ue_spec(mod_id, - frame, - cooperation_flag, - subframe, - sched_subframe, - ul_info); + frame, + cooperation_flag, + subframe, + sched_subframe, + ul_info); } From b1acde2007a04995373e4bea44e6d8565cf49a9e Mon Sep 17 00:00:00 2001 From: shahab SHARIAT BAGHERI Date: Thu, 21 Dec 2017 13:55:37 +0100 Subject: [PATCH 063/195] Neighbouring cell RRC measurement + decrease warning --- .../CONTROL_MODULES/RRC/flexran_agent_rrc.c | 110 ++++++++++--- openair2/ENB_APP/flexran_agent_handler.c | 2 +- openair2/ENB_APP/flexran_agent_ran_api.c | 149 ++++++++++++++++-- openair2/ENB_APP/flexran_agent_ran_api.h | 22 ++- openair2/RRC/LITE/rrc_eNB.c | 4 +- 5 files changed, 248 insertions(+), 39 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c index 7a251be78b..6f42d1da97 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c @@ -492,7 +492,7 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, // Protocol__FlexHeader *header; - int i; + int i,j; /* Allocate memory for list of UE reports */ if (report_config->nr_ue > 0) { @@ -501,29 +501,86 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, /* Check flag for creation of buffer status report */ if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RRC_MEASUREMENTS) { - - Protocol__FlexRrcMeasurements *rrc_measurements; - rrc_measurements = malloc(sizeof(Protocol__FlexRrcMeasurements)); - if (rrc_measurements == NULL) - goto error; - protocol__flex_rrc_measurements__init(rrc_measurements); - - rrc_measurements->measid = flexran_get_rrc_pcell_measid(mod_id,i); - rrc_measurements->has_measid = 1; - - rrc_measurements->pcell_rsrp = flexran_get_rrc_pcell_rsrp(mod_id,i) - 140; - rrc_measurements->has_pcell_rsrp = 1; - - rrc_measurements->pcell_rsrq = flexran_get_rrc_pcell_rsrq(mod_id,i)/2 - 20; - rrc_measurements->has_pcell_rsrq = 1 ; - - ue_report[i]->rrc_measurements = rrc_measurements; - + + /*Source Cell*/ + Protocol__FlexRrcMeasurements *rrc_measurements; + rrc_measurements = malloc(sizeof(Protocol__FlexRrcMeasurements)); + if (rrc_measurements == NULL) + goto error; + protocol__flex_rrc_measurements__init(rrc_measurements); + + rrc_measurements->measid = flexran_get_rrc_pcell_measid(mod_id,i); + rrc_measurements->has_measid = 1; + + rrc_measurements->pcell_rsrp = flexran_get_rrc_pcell_rsrp(mod_id,i); + rrc_measurements->has_pcell_rsrp = 1; + + rrc_measurements->pcell_rsrq = flexran_get_rrc_pcell_rsrq(mod_id,i); + rrc_measurements->has_pcell_rsrq = 1 ; + + + /* Target Cell, Neghibouring*/ + Protocol__FlexNeighCellsMeasurements *neigh_meas; + neigh_meas = malloc(sizeof(Protocol__FlexNeighCellsMeasurements)); + if (neigh_meas == NULL) + goto error; + protocol__flex_neigh_cells_measurements__init(neigh_meas); + + + neigh_meas->n_eutra_meas = flexran_get_rrc_num_ncell(mod_id, i); + + Protocol__FlexEutraMeasurements **eutra_meas = NULL; + + if (neigh_meas->n_eutra_meas > 0){ + + eutra_meas = malloc(sizeof(Protocol__FlexEutraMeasurements) * neigh_meas->n_eutra_meas); + if (eutra_meas == NULL) + goto error; + + for (j = 0; j < neigh_meas->n_eutra_meas; j++ ){ + + eutra_meas[j] = malloc(sizeof(Protocol__FlexEutraMeasurements)); + if (eutra_meas[j] == NULL) + goto error; + + protocol__flex_eutra_measurements__init(eutra_meas[j]); + + eutra_meas[j]->phys_cell_id = flexran_get_rrc_neigh_phy_cell_id(mod_id, i, j); + eutra_meas[j]->has_phys_cell_id = 1; + + + /*TODO: Extend for CGI and PLMNID*/ + + Protocol__FlexEutraRefSignalMeas *meas_result; + meas_result = malloc(sizeof(Protocol__FlexEutraRefSignalMeas)); + + protocol__flex_eutra_ref_signal_meas__init(meas_result); + + meas_result->rsrp = flexran_get_rrc_neigh_rsrp(mod_id, i, eutra_meas[j]->phys_cell_id); + meas_result->has_rsrp = 1; + + meas_result->rsrq = flexran_get_rrc_neigh_rsrq(mod_id, i, eutra_meas[j]->phys_cell_id); + meas_result->has_rsrq = 1; + + eutra_meas[j]->meas_result = meas_result; + + } + + neigh_meas->eutra_meas = eutra_meas; + + rrc_measurements->neigh_meas = neigh_meas; + + } + + ue_report[i]->rrc_measurements = rrc_measurements; + } - } + + } + } - /* To be extended for RRC layer */ + /* To be considered for RRC signaling of cell*/ // if (report_config->nr_cc > 0) { @@ -564,6 +621,17 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, error: + for (i = 0; i < report_config->nr_ue; i++){ + + if (ue_report[i]->rrc_measurements->neigh_meas != NULL){ + for (j = 0; j < flexran_get_rrc_num_ncell(mod_id, i); j++){ + + free(ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]); + } + free(ue_report[i]->rrc_measurements->neigh_meas); + } + } + if (cell_report != NULL) free(cell_report); if (ue_report != NULL) diff --git a/openair2/ENB_APP/flexran_agent_handler.c b/openair2/ENB_APP/flexran_agent_handler.c index 2a36b3e5c8..02df1d41dc 100644 --- a/openair2/ENB_APP/flexran_agent_handler.c +++ b/openair2/ENB_APP/flexran_agent_handler.c @@ -756,7 +756,7 @@ err_code_t flexran_agent_init_cont_stats_update(mid_t mod_id) { if (stats_context[mod_id].mutex == NULL) goto error; if (pthread_mutex_init(stats_context[mod_id].mutex, NULL)) - goto error;; + goto error; return 0; diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 556f018f7c..16462b4d40 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -1135,19 +1135,23 @@ uint32_t flexran_get_pdcp_sfn(const mid_t mod_id){ } /*PDCP super frame counter flexRAN*/ -uint32_t flexran_set_pdcp_tx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window){ - if (obs_window > 0 ) +void flexran_set_pdcp_tx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window){ + if (obs_window > 0 ){ Pdcp_stats_tx_window_ms[mod_id][ue_id]=obs_window; - else + } + else{ Pdcp_stats_tx_window_ms[mod_id][ue_id]=1000; + } } /*PDCP super frame counter flexRAN*/ -uint32_t flexran_set_pdcp_rx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window){ - if (obs_window > 0 ) +void flexran_set_pdcp_rx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window){ + if (obs_window > 0 ){ Pdcp_stats_rx_window_ms[mod_id][ue_id]=obs_window; - else + } + else{ Pdcp_stats_rx_window_ms[mod_id][ue_id]=1000; + } } /*PDCP num tx pdu status flexRAN*/ @@ -1256,7 +1260,7 @@ int flexran_get_rrc_pcell_rsrp(mid_t mod_id, mid_t ue_id) { ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); if(ue_context_p != NULL) { if(ue_context_p->ue_context.measResults != NULL) { - return ue_context_p->ue_context.measResults->measResultPCell.rsrpResult; + return RSRP_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrpResult]; } else { return -1; } @@ -1273,7 +1277,7 @@ int flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id) { ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); if(ue_context_p != NULL) { if(ue_context_p->ue_context.measResults != NULL) { - return ue_context_p->ue_context.measResults->measResultPCell.rsrqResult; + return RSRQ_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrqResult]; } else { return -1; } @@ -1281,8 +1285,48 @@ int flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id) { return -1; } } -/* -void* flexran_get_rrc_ncell_measresult_eutra(mid_t mod_id, mid_t ue_id) { + +/*Number of neighbouring cells for specific UE*/ +int flexran_get_rrc_num_ncell(mid_t mod_id, mid_t ue_id) { + struct rrc_eNB_ue_context_s* ue_context_p = NULL; + uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + if (eNB_rrc_inst_not_ready()) return 0; + + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); + if(ue_context_p != NULL) { + + if (ue_context_p->ue_context.measResults != NULL){ + + if(ue_context_p->ue_context.measResults->measResultNeighCells != NULL) { + + if (ue_context_p->ue_context.measResults->measResultNeighCells->present == MeasResults__measResultNeighCells_PR_measResultListEUTRA) { + + return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count; + } + else{ + + return 0; + } + + } else { + + return 0; + } + + } else { + + return 0; + + } + + } else { + return 0; + } + +} + +int flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, int cell_id) { struct rrc_eNB_ue_context_s* ue_context_p = NULL; uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); @@ -1290,8 +1334,88 @@ void* flexran_get_rrc_ncell_measresult_eutra(mid_t mod_id, mid_t ue_id) { ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); if(ue_context_p != NULL) { - if(ue_context_p->ue_context.measResults != NULL) { - return &ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA; + if(ue_context_p->ue_context.measResults->measResultNeighCells != NULL) { + + if (ue_context_p->ue_context.measResults->measResultNeighCells->present == MeasResults__measResultNeighCells_PR_measResultListEUTRA) { + + return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->physCellId; + + } + else { + + return -1; + } + } else { + return -1; + } + } else { + return -1; + } +} + +int flexran_get_rrc_neigh_rsrp(mid_t mod_id, mid_t ue_id, int cell_id) { + struct rrc_eNB_ue_context_s* ue_context_p = NULL; + uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + if (eNB_rrc_inst_not_ready()) return -1; + + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); + if(ue_context_p != NULL) { + + if(ue_context_p->ue_context.measResults->measResultNeighCells != NULL) { + + if (ue_context_p->ue_context.measResults->measResultNeighCells->present == MeasResults__measResultNeighCells_PR_measResultListEUTRA) { + + if (ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult){ + return RSRP_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult)]; + + } + else { + + return 0; + } + + } + else { + + return -1; + } + + } + else { + return -1; + } + + } + else { + return -1; + } +} + +int flexran_get_rrc_neigh_rsrq(mid_t mod_id, mid_t ue_id, int cell_id) { + struct rrc_eNB_ue_context_s* ue_context_p = NULL; + uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); + + if (eNB_rrc_inst_not_ready()) return -1; + + ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); + if(ue_context_p != NULL) { + if(ue_context_p->ue_context.measResults->measResultNeighCells != NULL) { + if (ue_context_p->ue_context.measResults->measResultNeighCells->present == MeasResults__measResultNeighCells_PR_measResultListEUTRA) { + + if (ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult){ + return RSRQ_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult)]; + + } + else { + + return 0; + } + } + else { + + return -1; + } } else { return -1; } @@ -1299,4 +1423,3 @@ void* flexran_get_rrc_ncell_measresult_eutra(mid_t mod_id, mid_t ue_id) { return -1; } } -*/ diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 12ca5febea..05c6817136 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -346,10 +346,10 @@ int flexran_get_rrc_status(const mid_t mod_id, const rnti_t rntiP); uint32_t flexran_get_pdcp_sfn(const mid_t mod_id); /*PDCP pdcp tx stats window*/ -uint32_t flexran_set_pdcp_tx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window); +void flexran_set_pdcp_tx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window); /*PDCP pdcp rx stats window*/ -uint32_t flexran_set_pdcp_rx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window); +void flexran_set_pdcp_rx_stat_window(const mid_t mod_id, const mid_t ue_id, uint16_t obs_window); /*PDCP num tx pdu status flexRAN*/ uint32_t flexran_get_pdcp_tx(const mid_t mod_id, const mid_t ue_id, const lcid_t lcid); @@ -406,3 +406,21 @@ int flexran_get_rrc_pcell_rsrp(mid_t mod_id, mid_t ue_id); /*Get primary cell RSRQ measurement flexRAN*/ int flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id); + +/* Get RRC neighbouring measurement */ +int flexran_get_rrc_num_ncell(mid_t mod_id, mid_t ue_id); + +/*Get physical cell id*/ +int flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, int cell_id); + +/*Get RSRP of neighbouring Cell*/ +int flexran_get_rrc_neigh_rsrp(mid_t mod_id, mid_t ue_id, int cell_id); + +/*Get RSRQ of neighbouring Cell*/ +int flexran_get_rrc_neigh_rsrq(mid_t mod_id, mid_t ue_id, int cell_id); + +/*Get MCC PLMN identity neighbouring Cell*/ +int flexran_get_rrc_neigh_plmn_mcc(mid_t mod_id, mid_t ue_id, int cell_id); + +/*Get MNC PLMN identity neighbouring Cell*/ +int flexran_get_rrc_neigh_plmn_mnc(mid_t mod_id, mid_t ue_id, int cell_id); \ No newline at end of file diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index c441c102e3..c3c1421533 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -2868,13 +2868,13 @@ rrc_eNB_process_MeasurementReport( return; if (measResults2->measResultNeighCells->choice.measResultListEUTRA.list.count > 0) { - neighboring_cells=measResults2->measResultNeighCells->choice.measResultListEUTRA.list.count; + neighboring_cells = measResults2->measResultNeighCells->choice.measResultListEUTRA.list.count; if (ue_context_pP->ue_context.measResults->measResultNeighCells == NULL) { ue_context_pP->ue_context.measResults->measResultNeighCells = CALLOC(1, sizeof(*measResults2->measResultNeighCells)*neighboring_cells); } - ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count=neighboring_cells; + ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count = neighboring_cells; for (i=0; i < neighboring_cells; i++){ memcpy (ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i], measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i], From a09728addba81262300e475a87cacdcf88f21b9b Mon Sep 17 00:00:00 2001 From: shahab SHARIAT BAGHERI Date: Sun, 24 Dec 2017 10:17:18 +0100 Subject: [PATCH 064/195] Warning decreasing --- openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c | 2 +- openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c | 2 +- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c index a04987f07c..e5b0dc61d8 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c @@ -736,7 +736,7 @@ flexran_schedule_ue_dl_spec_default(mid_t mod_id, } for (i = 0; i < n_active_slices; i++) { if (slice_percentage[i] < 0 ){ - LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %d. resetting to zero", + LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero", mod_id, frame, subframe, i, slice_percentage[i]); slice_percentage[i]=0; } diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c index 64f21482fb..86ea61d943 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c @@ -429,7 +429,7 @@ flexran_schedule_ue_ul_spec_default(mid_t mod_id, } for (i = 0; i < n_active_slices_uplink; i++) { if (slice_percentage_uplink[i] < 0 ){ - LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %d. resetting to zero", + LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero", mod_id, frame, subframe, i, slice_percentage_uplink[i]); slice_percentage_uplink[i]=0; } diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index d74e8552d6..08bf37fb94 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -1112,7 +1112,7 @@ pdcp_run ( } void pdcp_add_UE(const protocol_ctxt_t* const ctxt_pP){ - int i, ue_flag=1, ret=-1;; + int i, ue_flag=1; //, ret=-1; to be decied later for (i=0; i < NUMBER_OF_UE_MAX; i++){ if (pdcp_enb[ctxt_pP->module_id].rnti[i] == ctxt_pP->rnti) { ue_flag=-1; @@ -1126,7 +1126,7 @@ void pdcp_add_UE(const protocol_ctxt_t* const ctxt_pP){ pdcp_enb[ctxt_pP->module_id].uid[i]=i; pdcp_enb[ctxt_pP->module_id].num_ues++; printf("add new uid is %d %x\n\n", i, ctxt_pP->rnti); - ret=1; + // ret=1; break; } } From b350f8557e152b1dbab562bd69aa1a661a2379b6 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Sun, 21 Jan 2018 16:58:21 -0800 Subject: [PATCH 065/195] fixes for broken automatic indentation in MAC #1 --- openair2/LAYER2/MAC/config.c | 265 +- openair2/LAYER2/MAC/eNB_scheduler.c | 975 +-- openair2/LAYER2/MAC/eNB_scheduler_RA.c | 790 +- .../LAYER2/MAC/eNB_scheduler_primitives.c | 6848 ++++++++--------- 4 files changed, 3995 insertions(+), 4883 deletions(-) diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index ef37f6b1f3..c67d26ed2f 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -251,7 +251,7 @@ void config_mib(int Mod_idP, cfg->rf_config.dl_channel_bandwidth.value = to_prb(dl_BandwidthP); cfg->rf_config.dl_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG; cfg->num_tlv++; -LOG_E(PHY,"%s() dl_BandwidthP:%d\n", __FUNCTION__, dl_BandwidthP); + LOG_E(PHY,"%s() dl_BandwidthP:%d\n", __FUNCTION__, dl_BandwidthP); cfg->rf_config.ul_channel_bandwidth.value = to_prb(dl_BandwidthP); cfg->rf_config.ul_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG; @@ -306,35 +306,35 @@ LOG_E(PHY,"%s() dl_BandwidthP:%d\n", __FUNCTION__, dl_BandwidthP); LOG_I(MAC, - "%s() NFAPI_CONFIG_REQUEST(num_tlv:%u) DL_BW:%u UL_BW:%u Ncp %d,p_eNB %d,earfcn %d,band %d,phich_resource %u phich_duration %u phich_power_offset %u PSS %d SSS %d PCI %d" + "%s() NFAPI_CONFIG_REQUEST(num_tlv:%u) DL_BW:%u UL_BW:%u Ncp %d,p_eNB %d,earfcn %d,band %d,phich_resource %u phich_duration %u phich_power_offset %u PSS %d SSS %d PCI %d" #ifdef Rel14 - " PBCH repetition %d" + " PBCH repetition %d" #endif - "\n" - ,__FUNCTION__ - ,cfg->num_tlv - ,cfg->rf_config.dl_channel_bandwidth.value - ,cfg->rf_config.ul_channel_bandwidth.value - ,NcpP,p_eNBP - ,cfg->nfapi_config.earfcn.value - ,cfg->nfapi_config.rf_bands.rf_band[0] - ,cfg->phich_config.phich_resource.value - ,cfg->phich_config.phich_duration.value - ,cfg->phich_config.phich_power_offset.value - ,cfg->sch_config.primary_synchronization_signal_epre_eprers.value - ,cfg->sch_config.secondary_synchronization_signal_epre_eprers.value - ,cfg->sch_config.physical_cell_id.value + "\n" + ,__FUNCTION__ +` ,cfg->num_tlv + ,cfg->rf_config.dl_channel_bandwidth.value + ,cfg->rf_config.ul_channel_bandwidth.value + ,NcpP,p_eNBP + ,cfg->nfapi_config.earfcn.value + ,cfg->nfapi_config.rf_bands.rf_band[0] + ,cfg->phich_config.phich_resource.value + ,cfg->phich_config.phich_duration.value + ,cfg->phich_config.phich_power_offset.value + ,cfg->sch_config.primary_synchronization_signal_epre_eprers.value + ,cfg->sch_config.secondary_synchronization_signal_epre_eprers.value + ,cfg->sch_config.physical_cell_id.value #ifdef Rel14 - ,cfg->emtc_config.pbch_repetitions_enable_r13.value + ,cfg->emtc_config.pbch_repetitions_enable_r13.value #endif - ); + ); } void config_sib1(int Mod_idP, int CC_idP, TDD_Config_t * tdd_ConfigP) { - nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; + nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; if (tdd_ConfigP) { //TDD cfg->subframe_config.duplex_mode.value = 0; @@ -434,16 +434,13 @@ config_sib2(int Mod_idP, cfg->pucch_config.n1_pucch_an.tl.tag = NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG; cfg->num_tlv++; - if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled == true) - { + if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled == true) { cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 1; } - else if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled == true) - { + else if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled == true) { cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 2; } - else // No hopping - { + else { cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 0; } cfg->uplink_reference_signal_config.uplink_rs_hopping.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG; @@ -474,10 +471,10 @@ config_sib2(int Mod_idP, if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts) { - cfg->srs_config.max_up_pts.value = 1; + cfg->srs_config.max_up_pts.value = 1; } else { - cfg->srs_config.max_up_pts.value = 0; + cfg->srs_config.max_up_pts.value = 0; } cfg->srs_config.max_up_pts.tl.tag = NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG; cfg->num_tlv++; @@ -819,65 +816,65 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, RC.mac[Mod_idP]->common_channels[CC_idP].sib1_v13ext = sib1_v13ext; } #endif - if (radioResourceConfigCommon != NULL) { - LOG_I(MAC, "[CONFIG]SIB2/3 Contents (partial)\n"); - LOG_I(MAC, "[CONFIG]pusch_config_common.n_SB = %ld\n", - radioResourceConfigCommon-> - pusch_ConfigCommon.pusch_ConfigBasic.n_SB); - LOG_I(MAC, "[CONFIG]pusch_config_common.hoppingMode = %ld\n", - radioResourceConfigCommon-> - pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode); - LOG_I(MAC, - "[CONFIG]pusch_config_common.pusch_HoppingOffset = %ld\n", - radioResourceConfigCommon-> - pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset); - LOG_I(MAC, "[CONFIG]pusch_config_common.enable64QAM = %d\n", - radioResourceConfigCommon-> - pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM); - LOG_I(MAC, - "[CONFIG]pusch_config_common.groupHoppingEnabled = %d\n", - radioResourceConfigCommon-> - pusch_ConfigCommon.ul_ReferenceSignalsPUSCH. - groupHoppingEnabled); - LOG_I(MAC, - "[CONFIG]pusch_config_common.groupAssignmentPUSCH = %ld\n", - radioResourceConfigCommon-> - pusch_ConfigCommon.ul_ReferenceSignalsPUSCH. - groupAssignmentPUSCH); - LOG_I(MAC, - "[CONFIG]pusch_config_common.sequenceHoppingEnabled = %d\n", - radioResourceConfigCommon-> - pusch_ConfigCommon.ul_ReferenceSignalsPUSCH. - sequenceHoppingEnabled); - LOG_I(MAC, "[CONFIG]pusch_config_common.cyclicShift = %ld\n", - radioResourceConfigCommon-> - pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift); + if (radioResourceConfigCommon != NULL) { + LOG_I(MAC, "[CONFIG]SIB2/3 Contents (partial)\n"); + LOG_I(MAC, "[CONFIG]pusch_config_common.n_SB = %ld\n", + radioResourceConfigCommon-> + pusch_ConfigCommon.pusch_ConfigBasic.n_SB); + LOG_I(MAC, "[CONFIG]pusch_config_common.hoppingMode = %ld\n", + radioResourceConfigCommon-> + pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode); + LOG_I(MAC, + "[CONFIG]pusch_config_common.pusch_HoppingOffset = %ld\n", + radioResourceConfigCommon-> + pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset); + LOG_I(MAC, "[CONFIG]pusch_config_common.enable64QAM = %d\n", + radioResourceConfigCommon-> + pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM); + LOG_I(MAC, + "[CONFIG]pusch_config_common.groupHoppingEnabled = %d\n", + radioResourceConfigCommon-> + pusch_ConfigCommon.ul_ReferenceSignalsPUSCH. + groupHoppingEnabled); + LOG_I(MAC, + "[CONFIG]pusch_config_common.groupAssignmentPUSCH = %ld\n", + radioResourceConfigCommon-> + pusch_ConfigCommon.ul_ReferenceSignalsPUSCH. + groupAssignmentPUSCH); + LOG_I(MAC, + "[CONFIG]pusch_config_common.sequenceHoppingEnabled = %d\n", + radioResourceConfigCommon-> + pusch_ConfigCommon.ul_ReferenceSignalsPUSCH. + sequenceHoppingEnabled); + LOG_I(MAC, "[CONFIG]pusch_config_common.cyclicShift = %ld\n", + radioResourceConfigCommon-> + pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift); - AssertFatal(radioResourceConfigCommon-> - rach_ConfigCommon.maxHARQ_Msg3Tx > 0, - "radioResourceconfigCommon %d == 0\n", - (int) radioResourceConfigCommon-> - rach_ConfigCommon.maxHARQ_Msg3Tx); + AssertFatal(radioResourceConfigCommon-> + rach_ConfigCommon.maxHARQ_Msg3Tx > 0, + "radioResourceconfigCommon %d == 0\n", + (int) radioResourceConfigCommon-> + rach_ConfigCommon.maxHARQ_Msg3Tx); - RC.mac[Mod_idP]->common_channels[CC_idP]. - radioResourceConfigCommon = radioResourceConfigCommon; - if (ul_CarrierFreq > 0) - RC.mac[Mod_idP]->common_channels[CC_idP].ul_CarrierFreq = - ul_CarrierFreq; - if (ul_Bandwidth) - RC.mac[Mod_idP]->common_channels[CC_idP].ul_Bandwidth = - *ul_Bandwidth; - else - RC.mac[Mod_idP]->common_channels[CC_idP].ul_Bandwidth = - RC.mac[Mod_idP]->common_channels[CC_idP].mib->message. - dl_Bandwidth; + RC.mac[Mod_idP]->common_channels[CC_idP]. + radioResourceConfigCommon = radioResourceConfigCommon; + if (ul_CarrierFreq > 0) + RC.mac[Mod_idP]->common_channels[CC_idP].ul_CarrierFreq = + ul_CarrierFreq; + if (ul_Bandwidth) + RC.mac[Mod_idP]->common_channels[CC_idP].ul_Bandwidth = + *ul_Bandwidth; + else + RC.mac[Mod_idP]->common_channels[CC_idP].ul_Bandwidth = + RC.mac[Mod_idP]->common_channels[CC_idP].mib->message. + dl_Bandwidth; - config_sib2(Mod_idP, CC_idP, radioResourceConfigCommon, + config_sib2(Mod_idP, CC_idP, radioResourceConfigCommon, #ifdef Rel14 - radioResourceConfigCommon_BR, + radioResourceConfigCommon_BR, #endif - NULL, ul_Bandwidth, additionalSpectrumEmission, - mbsfn_SubframeConfigList); + NULL, ul_Bandwidth, additionalSpectrumEmission, + mbsfn_SubframeConfigList); } } // mib != NULL @@ -888,14 +885,14 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, if (UE_id == -1) { LOG_E(MAC, "%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, - __LINE__, __FUNCTION__); + __LINE__, __FUNCTION__); } else { if (logicalChannelConfig) UE_list-> UE_template[CC_idP][UE_id].lcgidmap [logicalChannelIdentity] = *logicalChannelConfig-> - ul_SpecificParameters->logicalChannelGroup; + ul_SpecificParameters->logicalChannelGroup; else UE_list-> UE_template[CC_idP][UE_id].lcgidmap @@ -920,9 +917,9 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, UE_id = find_UE_id(Mod_idP, rntiP); if (UE_id == -1) LOG_E(MAC, "%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, - __LINE__, __FUNCTION__); + __LINE__, __FUNCTION__); else - config_dedicated_scell(Mod_idP, rntiP, sCellToAddMod_r10); + config_dedicated_scell(Mod_idP, rntiP, sCellToAddMod_r10); } #endif @@ -954,7 +951,7 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, #if defined(Rel10) || defined(Rel14) if (mbsfn_AreaInfoList != NULL) { - // One eNB could be part of multiple mbsfn syc area, this could change over time so reset each time + // One eNB could be part of multiple mbsfn syc area, this could change over time so reset each time LOG_I(MAC,"[eNB %d][CONFIG] Received %d MBSFN Area Info\n", Mod_idP, mbsfn_AreaInfoList->list.count); RC.mac[Mod_idP]->common_channels[0].num_active_mbsfn_area = mbsfn_AreaInfoList->list.count; @@ -966,67 +963,67 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, } } - if (pmch_InfoList != NULL) { + if (pmch_InfoList != NULL) { - // LOG_I(MAC,"DUY: lcid when entering rrc_mac config_req is %02d\n",(pmch_InfoList->list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9)); + // LOG_I(MAC,"DUY: lcid when entering rrc_mac config_req is %02d\n",(pmch_InfoList->list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9)); - LOG_I(MAC, "[CONFIG] Number of PMCH in this MBSFN Area %d\n", - pmch_InfoList->list.count); + LOG_I(MAC, "[CONFIG] Number of PMCH in this MBSFN Area %d\n", + pmch_InfoList->list.count); - for (i = 0; i < pmch_InfoList->list.count; i++) { - RC.mac[Mod_idP]->common_channels[0].pmch_Config[i] = - &pmch_InfoList->list.array[i]->pmch_Config_r9; + for (i = 0; i < pmch_InfoList->list.count; i++) { + RC.mac[Mod_idP]->common_channels[0].pmch_Config[i] = + &pmch_InfoList->list.array[i]->pmch_Config_r9; - LOG_I(MAC, - "[CONFIG] PMCH[%d]: This PMCH stop (sf_AllocEnd_r9) at subframe %ldth\n", - i, - RC.mac[Mod_idP]->common_channels[0]. - pmch_Config[i]->sf_AllocEnd_r9); - LOG_I(MAC, "[CONFIG] PMCH[%d]: mch_Scheduling_Period = %ld\n", - i, - RC.mac[Mod_idP]->common_channels[0]. - pmch_Config[i]->mch_SchedulingPeriod_r9); - LOG_I(MAC, "[CONFIG] PMCH[%d]: dataMCS = %ld\n", i, - RC.mac[Mod_idP]->common_channels[0]. - pmch_Config[i]->dataMCS_r9); + LOG_I(MAC, + "[CONFIG] PMCH[%d]: This PMCH stop (sf_AllocEnd_r9) at subframe %ldth\n", + i, + RC.mac[Mod_idP]->common_channels[0]. + pmch_Config[i]->sf_AllocEnd_r9); + LOG_I(MAC, "[CONFIG] PMCH[%d]: mch_Scheduling_Period = %ld\n", + i, + RC.mac[Mod_idP]->common_channels[0]. + pmch_Config[i]->mch_SchedulingPeriod_r9); + LOG_I(MAC, "[CONFIG] PMCH[%d]: dataMCS = %ld\n", i, + RC.mac[Mod_idP]->common_channels[0]. + pmch_Config[i]->dataMCS_r9); - // MBMS session info list in each MCH - RC.mac[Mod_idP]->common_channels[0].mbms_SessionList[i] = - &pmch_InfoList->list.array[i]->mbms_SessionInfoList_r9; - LOG_I(MAC, "PMCH[%d] Number of session (MTCH) is: %d\n", i, - RC.mac[Mod_idP]->common_channels[0]. - mbms_SessionList[i]->list.count); - } + // MBMS session info list in each MCH + RC.mac[Mod_idP]->common_channels[0].mbms_SessionList[i] = + &pmch_InfoList->list.array[i]->mbms_SessionInfoList_r9; + LOG_I(MAC, "PMCH[%d] Number of session (MTCH) is: %d\n", i, + RC.mac[Mod_idP]->common_channels[0]. + mbms_SessionList[i]->list.count); } } +} #endif - LOG_E(MAC, "%s() %s:%d RC.mac[Mod_idP]->if_inst->PHY_config_req:%p\n", __FUNCTION__, __FILE__, __LINE__, RC.mac[Mod_idP]->if_inst->PHY_config_req); +LOG_E(MAC, "%s() %s:%d RC.mac[Mod_idP]->if_inst->PHY_config_req:%p\n", __FUNCTION__, __FILE__, __LINE__, RC.mac[Mod_idP]->if_inst->PHY_config_req); - // if in nFAPI mode - if ( - (nfapi_mode == 1 || nfapi_mode == 2) && - (RC.mac[Mod_idP]->if_inst->PHY_config_req == NULL) - ) { - while(RC.mac[Mod_idP]->if_inst->PHY_config_req == NULL) { - // DJP AssertFatal(RC.mac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n"); - usleep(100 * 1000); - printf("Waiting for PHY_config_req\n"); - } - } +// if in nFAPI mode +if ( + (nfapi_mode == 1 || nfapi_mode == 2) && + (RC.mac[Mod_idP]->if_inst->PHY_config_req == NULL) + ) { + while(RC.mac[Mod_idP]->if_inst->PHY_config_req == NULL) { + // DJP AssertFatal(RC.mac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n"); + usleep(100 * 1000); + printf("Waiting for PHY_config_req\n"); + } + } - if (radioResourceConfigCommon != NULL) { - PHY_Config_t phycfg; - phycfg.Mod_id = Mod_idP; - phycfg.CC_id = CC_idP; - phycfg.cfg = &RC.mac[Mod_idP]->config[CC_idP]; +if (radioResourceConfigCommon != NULL) { + PHY_Config_t phycfg; + phycfg.Mod_id = Mod_idP; + phycfg.CC_id = CC_idP; + phycfg.cfg = &RC.mac[Mod_idP]->config[CC_idP]; - if (RC.mac[Mod_idP]->if_inst->PHY_config_req) RC.mac[Mod_idP]->if_inst->PHY_config_req(&phycfg); + if (RC.mac[Mod_idP]->if_inst->PHY_config_req) RC.mac[Mod_idP]->if_inst->PHY_config_req(&phycfg); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT); - } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT); + } - return(0); +return(0); } int diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index f03a3961f6..94eacb6e00 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -74,409 +74,282 @@ uint16_t pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 }; void schedule_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { - eNB_MAC_INST *eNB = RC.mac[module_idP]; - UE_list_t *UE_list = &eNB->UE_list; - nfapi_ul_config_request_body_t *ul_req; - int CC_id, UE_id; - COMMON_channels_t *cc = RC.mac[module_idP]->common_channels; - SoundingRS_UL_ConfigCommon_t *soundingRS_UL_ConfigCommon; - struct SoundingRS_UL_ConfigDedicated *soundingRS_UL_ConfigDedicated; - uint8_t TSFC; - uint16_t deltaTSFC; // bitmap - uint8_t srs_SubframeConfig; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &eNB->UE_list; + nfapi_ul_config_request_body_t *ul_req; + int CC_id, UE_id; + COMMON_channels_t *cc = RC.mac[module_idP]->common_channels; + SoundingRS_UL_ConfigCommon_t *soundingRS_UL_ConfigCommon; + struct SoundingRS_UL_ConfigDedicated *soundingRS_UL_ConfigDedicated; + uint8_t TSFC; + uint16_t deltaTSFC; // bitmap + uint8_t srs_SubframeConfig; - // table for TSFC (Period) and deltaSFC (offset) - const uint16_t deltaTSFCTabType1[15][2] = { {1, 1}, {1, 2}, {2, 2}, {1, 5}, {2, 5}, {4, 5}, {8, 5}, {3, 5}, {12, 5}, {1, 10}, {2, 10}, {4, 10}, {8, 10}, {351, 10}, {383, 10} }; // Table 5.5.3.3-2 3GPP 36.211 FDD - const uint16_t deltaTSFCTabType2[14][2] = { {2, 5}, {6, 5}, {10, 5}, {18, 5}, {14, 5}, {22, 5}, {26, 5}, {30, 5}, {70, 10}, {74, 10}, {194, 10}, {326, 10}, {586, 10}, {210, 10} }; // Table 5.5.3.3-2 3GPP 36.211 TDD + // table for TSFC (Period) and deltaSFC (offset) + const uint16_t deltaTSFCTabType1[15][2] = { {1, 1}, {1, 2}, {2, 2}, {1, 5}, {2, 5}, {4, 5}, {8, 5}, {3, 5}, {12, 5}, {1, 10}, {2, 10}, {4, 10}, {8, 10}, {351, 10}, {383, 10} }; // Table 5.5.3.3-2 3GPP 36.211 FDD + const uint16_t deltaTSFCTabType2[14][2] = { {2, 5}, {6, 5}, {10, 5}, {18, 5}, {14, 5}, {22, 5}, {26, 5}, {30, 5}, {70, 10}, {74, 10}, {194, 10}, {326, 10}, {586, 10}, {210, 10} }; // Table 5.5.3.3-2 3GPP 36.211 TDD - uint16_t srsPeriodicity, srsOffset; + uint16_t srsPeriodicity, srsOffset; - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - soundingRS_UL_ConfigCommon = - &cc[CC_id].radioResourceConfigCommon-> - soundingRS_UL_ConfigCommon; - // check if SRS is enabled in this frame/subframe - if (soundingRS_UL_ConfigCommon) { - srs_SubframeConfig = - soundingRS_UL_ConfigCommon->choice.setup. - srs_SubframeConfig; - if (cc[CC_id].tdd_Config == NULL) { // FDD - deltaTSFC = deltaTSFCTabType1[srs_SubframeConfig][0]; - TSFC = deltaTSFCTabType1[srs_SubframeConfig][1]; - } else { // TDD - deltaTSFC = deltaTSFCTabType2[srs_SubframeConfig][0]; - TSFC = deltaTSFCTabType2[srs_SubframeConfig][1]; - } - // Sounding reference signal subframes are the subframes satisfying ns/2 mod TSFC (- deltaTSFC - uint16_t tmp = (subframeP % TSFC); + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + soundingRS_UL_ConfigCommon = &cc[CC_id].radioResourceConfigCommon->soundingRS_UL_ConfigCommon; + // check if SRS is enabled in this frame/subframe + if (soundingRS_UL_ConfigCommon) { + srs_SubframeConfig = soundingRS_UL_ConfigCommon->choice.setup.srs_SubframeConfig; + if (cc[CC_id].tdd_Config == NULL) { // FDD + deltaTSFC = deltaTSFCTabType1[srs_SubframeConfig][0]; + TSFC = deltaTSFCTabType1[srs_SubframeConfig][1]; + } else { // TDD + deltaTSFC = deltaTSFCTabType2[srs_SubframeConfig][0]; + TSFC = deltaTSFCTabType2[srs_SubframeConfig][1]; + } + // Sounding reference signal subframes are the subframes satisfying ns/2 mod TSFC (- deltaTSFC + uint16_t tmp = (subframeP % TSFC); - if ((1 << tmp) & deltaTSFC) { - // This is an SRS subframe, loop over UEs - for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { - if (RC.mac[module_idP]->UE_list.active[UE_id] != TRUE) - continue; - ul_req = - &RC.mac[module_idP]->UL_req[CC_id]. - ul_config_request_body; + if ((1 << tmp) & deltaTSFC) { + // This is an SRS subframe, loop over UEs + for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { + if (RC.mac[module_idP]->UE_list.active[UE_id] != TRUE) continue; + ul_req = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body; + // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet + if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) continue; + AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, + "physicalConfigDedicated is null for UE %d\n", + UE_id); - // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet - if (mac_eNB_get_rrc_status - (module_idP, - UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) - continue; + if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated) != NULL) { + if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) { + get_srs_pos(&cc[CC_id], + soundingRS_UL_ConfigDedicated->choice. + setup.srs_ConfigIndex, + &srsPeriodicity, &srsOffset); + if (((10 * frameP + subframeP) % srsPeriodicity) == srsOffset) { + // Program SRS + ul_req->srs_present = 1; + nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; + memset((void *) ul_config_pdu, 0, + sizeof + (nfapi_ul_config_request_pdu_t)); + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_SRS_PDU_TYPE; + ul_config_pdu->pdu_size = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_srs_pdu)); + ul_config_pdu->srs_pdu.srs_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG; + ul_config_pdu->srs_pdu.srs_pdu_rel8.size = (uint8_t)sizeof(nfapi_ul_config_srs_pdu);; + ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; + ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth; + ul_config_pdu->srs_pdu.srs_pdu_rel8.frequency_domain_position = soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition; + ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth;; + ul_config_pdu->srs_pdu.srs_pdu_rel8.transmission_comb = soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb; + ul_config_pdu->srs_pdu.srs_pdu_rel8.i_srs = soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex; + ul_config_pdu->srs_pdu.srs_pdu_rel8.sounding_reference_cyclic_shift = soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift; + // ul_config_pdu->srs_pdu.srs_pdu_rel10.antenna_port = ;// + // ul_config_pdu->srs_pdu.srs_pdu_rel13.number_of_combs = ;// + RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP; + RC.mac[module_idP]->UL_req[CC_id].header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_req->number_of_pdus++; + } // if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset) + } // if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) + } // if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL) + } // for (UE_id ... + } // if((1<UE_template[CC_id] - [UE_id].physicalConfigDedicated != NULL, - "physicalConfigDedicated is null for UE %d\n", - UE_id); - - if ((soundingRS_UL_ConfigDedicated = - UE_list->UE_template[CC_id] - [UE_id]. - physicalConfigDedicated->soundingRS_UL_ConfigDedicated) - != NULL) { - if (soundingRS_UL_ConfigDedicated->present == - SoundingRS_UL_ConfigDedicated_PR_setup) { - get_srs_pos(&cc[CC_id], - soundingRS_UL_ConfigDedicated->choice. - setup.srs_ConfigIndex, - &srsPeriodicity, &srsOffset); - if (((10 * frameP + - subframeP) % srsPeriodicity) == - srsOffset) { - // Program SRS - ul_req->srs_present = 1; - nfapi_ul_config_request_pdu_t - * ul_config_pdu = - &ul_req-> - ul_config_pdu_list - [ul_req->number_of_pdus]; - memset((void *) ul_config_pdu, 0, - sizeof - (nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = - NFAPI_UL_CONFIG_SRS_PDU_TYPE; - ul_config_pdu->pdu_size = - 2 + (uint8_t) (2 + - sizeof - (nfapi_ul_config_srs_pdu)); - ul_config_pdu->srs_pdu.srs_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG; - ul_config_pdu->srs_pdu.srs_pdu_rel8.size = - (uint8_t) - sizeof(nfapi_ul_config_srs_pdu);; - ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti = - UE_list->UE_template[CC_id][UE_id]. - rnti; - ul_config_pdu->srs_pdu. - srs_pdu_rel8.srs_bandwidth = - soundingRS_UL_ConfigDedicated-> - choice.setup.srs_Bandwidth; - ul_config_pdu->srs_pdu. - srs_pdu_rel8.frequency_domain_position - = - soundingRS_UL_ConfigDedicated-> - choice.setup.freqDomainPosition; - ul_config_pdu->srs_pdu. - srs_pdu_rel8.srs_hopping_bandwidth = - soundingRS_UL_ConfigDedicated-> - choice.setup.srs_HoppingBandwidth;; - ul_config_pdu->srs_pdu. - srs_pdu_rel8.transmission_comb = - soundingRS_UL_ConfigDedicated-> - choice.setup.transmissionComb; - ul_config_pdu->srs_pdu.srs_pdu_rel8.i_srs = - soundingRS_UL_ConfigDedicated-> - choice.setup.srs_ConfigIndex; - ul_config_pdu->srs_pdu. - srs_pdu_rel8.sounding_reference_cyclic_shift - = - soundingRS_UL_ConfigDedicated-> - choice.setup.cyclicShift; - // ul_config_pdu->srs_pdu.srs_pdu_rel10.antenna_port = ;// - // ul_config_pdu->srs_pdu.srs_pdu_rel13.number_of_combs = ;// - RC.mac[module_idP]->UL_req[CC_id].sfn_sf = - (frameP << 4) + subframeP; - RC.mac[module_idP]->UL_req[CC_id].header.message_id = NFAPI_UL_CONFIG_REQUEST; - ul_req->number_of_pdus++; - } // if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset) - } // if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) - } // if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL) - } // for (UE_id ... - } // if((1<UE_list; - COMMON_channels_t *cc; - nfapi_ul_config_request_body_t *ul_req; - int CC_id, UE_id; - struct CQI_ReportPeriodic *cqi_ReportPeriodic; - uint16_t Npd, N_OFFSET_CQI; - int H; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &eNB->UE_list; + COMMON_channels_t *cc; + nfapi_ul_config_request_body_t *ul_req; + int CC_id, UE_id; + struct CQI_ReportPeriodic *cqi_ReportPeriodic; + uint16_t Npd, N_OFFSET_CQI; + int H; - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - cc = &eNB->common_channels[CC_id]; - for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { - if (UE_list->active[UE_id] != TRUE) - continue; + cc = &eNB->common_channels[CC_id]; + for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { + if (UE_list->active[UE_id] != TRUE) + continue; - ul_req = - &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body; + ul_req = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body; - // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet - if (mac_eNB_get_rrc_status - (module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) - continue; + // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet + if (mac_eNB_get_rrc_status(module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) continue; - AssertFatal(UE_list-> - UE_template[CC_id][UE_id].physicalConfigDedicated - != NULL, - "physicalConfigDedicated is null for UE %d\n", - UE_id); + AssertFatal(UE_list-> + UE_template[CC_id][UE_id].physicalConfigDedicated + != NULL, + "physicalConfigDedicated is null for UE %d\n", + UE_id); - if (UE_list-> - UE_template[CC_id][UE_id].physicalConfigDedicated-> - cqi_ReportConfig) { - if ((cqi_ReportPeriodic = - UE_list-> - UE_template[CC_id][UE_id].physicalConfigDedicated-> - cqi_ReportConfig->cqi_ReportPeriodic) != NULL - && (cqi_ReportPeriodic->present != - CQI_ReportPeriodic_PR_release)) { - //Rel8 Periodic CQI/PMI/RI reporting + if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig) { + if ((cqi_ReportPeriodic = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) != NULL + && (cqi_ReportPeriodic->present != CQI_ReportPeriodic_PR_release)) { + //Rel8 Periodic CQI/PMI/RI reporting - get_csi_params(cc, cqi_ReportPeriodic, &Npd, - &N_OFFSET_CQI, &H); + get_csi_params(cc, cqi_ReportPeriodic, &Npd, + &N_OFFSET_CQI, &H); - if ((((frameP * 10) + subframeP) % Npd) == N_OFFSET_CQI) { // CQI opportunity - UE_list->UE_sched_ctrl[UE_id].feedback_cnt[CC_id] = - (((frameP * 10) + subframeP) / Npd) % H; - // Program CQI - nfapi_ul_config_request_pdu_t *ul_config_pdu = - &ul_req->ul_config_pdu_list[ul_req-> - number_of_pdus]; - memset((void *) ul_config_pdu, 0, - sizeof(nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = - NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE; - ul_config_pdu->pdu_size = - 2 + (uint8_t) (2 + - sizeof - (nfapi_ul_config_uci_cqi_pdu)); - ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; - ul_config_pdu->uci_cqi_pdu. - ue_information.ue_information_rel8.rnti = - UE_list->UE_template[CC_id][UE_id].rnti; - ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG; - ul_config_pdu->uci_cqi_pdu. - cqi_information.cqi_information_rel8. - pucch_index = - cqi_ReportPeriodic->choice. - setup.cqi_PUCCH_ResourceIndex; - ul_config_pdu->uci_cqi_pdu. - cqi_information.cqi_information_rel8. - dl_cqi_pmi_size = - get_rel8_dl_cqi_pmi_size - (&UE_list->UE_sched_ctrl[UE_id], CC_id, cc, - get_tmode(module_idP, CC_id, UE_id), - cqi_ReportPeriodic); - ul_req->number_of_pdus++; - ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + if ((((frameP * 10) + subframeP) % Npd) == N_OFFSET_CQI) { // CQI opportunity + UE_list->UE_sched_ctrl[UE_id].feedback_cnt[CC_id] = (((frameP * 10) + subframeP) / Npd) % H; + // Program CQI + nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; + memset((void *) ul_config_pdu, 0, + sizeof(nfapi_ul_config_request_pdu_t)); + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE; + ul_config_pdu->pdu_size = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_uci_cqi_pdu)); + ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; + ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size = get_rel8_dl_cqi_pmi_size(&UE_list->UE_sched_ctrl[UE_id], CC_id, cc, + get_tmode(module_idP, CC_id, UE_id), + cqi_ReportPeriodic); + ul_req->number_of_pdus++; + ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; #if defined(Rel10) || defined(Rel14) - // PUT rel10-13 UCI options here + // PUT rel10-13 UCI options here #endif - } else - if ((cqi_ReportPeriodic->choice.setup. - ri_ConfigIndex) - && ((((frameP * 10) + subframeP) % ((H * Npd) << (*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex / 161))) == N_OFFSET_CQI + (*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex % 161))) { // RI opportunity - // Program RI - nfapi_ul_config_request_pdu_t *ul_config_pdu = - &ul_req->ul_config_pdu_list[ul_req-> - number_of_pdus]; - memset((void *) ul_config_pdu, 0, - sizeof(nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = - NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE; - ul_config_pdu->pdu_size = - 2 + (uint8_t) (2 + - sizeof - (nfapi_ul_config_uci_cqi_pdu)); - ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; - ul_config_pdu->uci_cqi_pdu. - ue_information.ue_information_rel8.rnti = - UE_list->UE_template[CC_id][UE_id].rnti; - ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG; - ul_config_pdu->uci_cqi_pdu. - cqi_information.cqi_information_rel8. - pucch_index = - cqi_ReportPeriodic->choice. - setup.cqi_PUCCH_ResourceIndex; - ul_config_pdu->uci_cqi_pdu. - cqi_information.cqi_information_rel8. - dl_cqi_pmi_size = (cc->p_eNB == 2) ? 1 : 2; - RC.mac[module_idP]->UL_req[CC_id].sfn_sf = - (frameP << 4) + subframeP; - ul_req->number_of_pdus++; - ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - } - - } // if ((cqi_ReportPeriodic = cqi_ReportConfig->cqi_ReportPeriodic)!=NULL) { - } // if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig) - } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { - } // for (CC_id=0; CC_idchoice.setup.ri_ConfigIndex) + && ((((frameP * 10) + subframeP) % ((H * Npd) << (*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex / 161))) == N_OFFSET_CQI + (*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex % 161))) { // RI opportunity + // Program RI + nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; + memset((void *) ul_config_pdu, 0, + sizeof(nfapi_ul_config_request_pdu_t)); + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE; + ul_config_pdu->pdu_size = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_uci_cqi_pdu)); + ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; + ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size = (cc->p_eNB == 2) ? 1 : 2; + RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP; + ul_req->number_of_pdus++; + ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + } + } // if ((cqi_ReportPeriodic = cqi_ReportConfig->cqi_ReportPeriodic)!=NULL) { + } // if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig) + } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { + } // for (CC_id=0; CC_idUE_list; - nfapi_ul_config_request_t *ul_req; - nfapi_ul_config_request_body_t *ul_req_body; - int CC_id; - int UE_id; - SchedulingRequestConfig_t *SRconfig; - int skip_ue; - int is_harq; - nfapi_ul_config_sr_information sr; - int i; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &eNB->UE_list; + nfapi_ul_config_request_t *ul_req; + nfapi_ul_config_request_body_t *ul_req_body; + int CC_id; + int UE_id; + SchedulingRequestConfig_t *SRconfig; + int skip_ue; + int is_harq; + nfapi_ul_config_sr_information sr; + int i; - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - RC.mac[module_idP]->UL_req[CC_id].sfn_sf = - (frameP << 4) + subframeP; + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP; - for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { - if (RC.mac[module_idP]->UE_list.active[UE_id] != TRUE) - continue; + for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { + if (RC.mac[module_idP]->UE_list.active[UE_id] != TRUE) continue; - ul_req = &RC.mac[module_idP]->UL_req[CC_id]; - ul_req_body = &ul_req->ul_config_request_body; + ul_req = &RC.mac[module_idP]->UL_req[CC_id]; + ul_req_body = &ul_req->ul_config_request_body; - // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet - if (mac_eNB_get_rrc_status - (module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) - continue; + // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet + if (mac_eNB_get_rrc_status(module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) continue; - AssertFatal(UE_list-> - UE_template[CC_id][UE_id].physicalConfigDedicated - != NULL, - "physicalConfigDedicated is null for UE %d\n", - UE_id); + AssertFatal(UE_list-> + UE_template[CC_id][UE_id].physicalConfigDedicated!= NULL, + "physicalConfigDedicated is null for UE %d\n", + UE_id); - if ((SRconfig = - UE_list-> - UE_template[CC_id][UE_id].physicalConfigDedicated-> - schedulingRequestConfig) != NULL) { - if (SRconfig->present == SchedulingRequestConfig_PR_setup) { - if (SRconfig->choice.setup.sr_ConfigIndex <= 4) { // 5 ms SR period - if ((subframeP % 5) != - SRconfig->choice.setup.sr_ConfigIndex) - continue; - } else if (SRconfig->choice.setup.sr_ConfigIndex <= 14) { // 10 ms SR period - if (subframeP != - (SRconfig->choice.setup.sr_ConfigIndex - 5)) - continue; - } else if (SRconfig->choice.setup.sr_ConfigIndex <= 34) { // 20 ms SR period - if ((10 * (frameP & 1) + subframeP) != - (SRconfig->choice.setup.sr_ConfigIndex - 15)) - continue; - } else if (SRconfig->choice.setup.sr_ConfigIndex <= 74) { // 40 ms SR period - if ((10 * (frameP & 3) + subframeP) != - (SRconfig->choice.setup.sr_ConfigIndex - 35)) - continue; - } else if (SRconfig->choice.setup.sr_ConfigIndex <= 154) { // 80 ms SR period - if ((10 * (frameP & 7) + subframeP) != - (SRconfig->choice.setup.sr_ConfigIndex - 75)) - continue; - } - } // SRconfig->present == SchedulingRequestConfig_PR_setup) - } // SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig)!=NULL) + if ((SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig) != NULL) { + if (SRconfig->present == SchedulingRequestConfig_PR_setup) { + if (SRconfig->choice.setup.sr_ConfigIndex <= 4) { // 5 ms SR period + if ((subframeP % 5) != SRconfig->choice.setup.sr_ConfigIndex) continue; + } else if (SRconfig->choice.setup.sr_ConfigIndex <= 14) { // 10 ms SR period + if (subframeP != (SRconfig->choice.setup.sr_ConfigIndex - 5)) continue; + } else if (SRconfig->choice.setup.sr_ConfigIndex <= 34) { // 20 ms SR period + if ((10 * (frameP & 1) + subframeP) != (SRconfig->choice.setup.sr_ConfigIndex - 15)) continue; + } else if (SRconfig->choice.setup.sr_ConfigIndex <= 74) { // 40 ms SR period + if ((10 * (frameP & 3) + subframeP) != (SRconfig->choice.setup.sr_ConfigIndex - 35)) continue; + } else if (SRconfig->choice.setup.sr_ConfigIndex <= 154) { // 80 ms SR period + if ((10 * (frameP & 7) + subframeP) != (SRconfig->choice.setup.sr_ConfigIndex - 75)) continue; + } + } // SRconfig->present == SchedulingRequestConfig_PR_setup) + } // SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig)!=NULL) - // if we get here there is some PUCCH1 reception to schedule for SR + // if we get here there is some PUCCH1 reception to schedule for SR - skip_ue = 0; - is_harq = 0; - // check that there is no existing UL grant for ULSCH which overrides the SR - for (i = 0; i < ul_req_body->number_of_pdus; i++) { - if (((ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) || - (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) || - (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) || - (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE)) && - (ul_req_body->ul_config_pdu_list[i].ulsch_pdu.ulsch_pdu_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) { - skip_ue = 1; - break; - } - /* if there is already an HARQ pdu, convert to SR_HARQ */ - else if ((ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) && - (ul_req_body->ul_config_pdu_list[i].uci_harq_pdu.ue_information.ue_information_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) { - is_harq = 1; - break; - } - } + skip_ue = 0; + is_harq = 0; + // check that there is no existing UL grant for ULSCH which overrides the SR + for (i = 0; i < ul_req_body->number_of_pdus; i++) { + if (((ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) || + (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) || + (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) || + (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE)) && + (ul_req_body->ul_config_pdu_list[i].ulsch_pdu.ulsch_pdu_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) { + skip_ue = 1; + break; + } + /* if there is already an HARQ pdu, convert to SR_HARQ */ + else if ((ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) && + (ul_req_body->ul_config_pdu_list[i].uci_harq_pdu.ue_information.ue_information_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) { + is_harq = 1; + break; + } + } - // drop the allocation because ULSCH with handle it with BSR - if (skip_ue == 1) - continue; + // drop the allocation because ULSCH with handle it with BSR + if (skip_ue == 1) continue; - LOG_D(MAC,"Frame %d, Subframe %d : Scheduling SR for UE %d/%x is_harq:%d\n",frameP,subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].rnti, is_harq); + LOG_D(MAC,"Frame %d, Subframe %d : Scheduling SR for UE %d/%x is_harq:%d\n",frameP,subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].rnti, is_harq); - // check Rel10 or Rel8 SR + // check Rel10 or Rel8 SR #if defined(Rel10) || defined(Rel14) - if ((UE_list-> - UE_template[CC_id][UE_id].physicalConfigDedicated->ext2) - && (UE_list-> - UE_template[CC_id][UE_id].physicalConfigDedicated-> - ext2->schedulingRequestConfig_v1020) - && (UE_list-> - UE_template[CC_id][UE_id].physicalConfigDedicated-> - ext2->schedulingRequestConfig_v1020)) { - sr.sr_information_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL10_TAG; - sr.sr_information_rel10.number_of_pucch_resources = 1; - sr.sr_information_rel10.pucch_index_p1 = - *UE_list-> - UE_template[CC_id][UE_id].physicalConfigDedicated-> - ext2-> - schedulingRequestConfig_v1020->sr_PUCCH_ResourceIndexP1_r10; - LOG_D(MAC,"REL10 PUCCH INDEX P1:%d\n", sr.sr_information_rel10.pucch_index_p1); - } else + if ((UE_list-> UE_template[CC_id][UE_id].physicalConfigDedicated->ext2) + && (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020) + && (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020)) { + sr.sr_information_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL10_TAG; + sr.sr_information_rel10.number_of_pucch_resources = 1; + sr.sr_information_rel10.pucch_index_p1 = *UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020->sr_PUCCH_ResourceIndexP1_r10; + LOG_D(MAC,"REL10 PUCCH INDEX P1:%d\n", sr.sr_information_rel10.pucch_index_p1); + } else #endif - { - sr.sr_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL8_TAG; - sr.sr_information_rel8.pucch_index = - UE_list-> - UE_template[CC_id][UE_id].physicalConfigDedicated-> - schedulingRequestConfig->choice.setup. - sr_PUCCH_ResourceIndex; - LOG_D(MAC,"REL8 PUCCH INDEX:%d\n", sr.sr_information_rel8.pucch_index); - } + { + sr.sr_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL8_TAG; + sr.sr_information_rel8.pucch_index = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex; + LOG_D(MAC,"REL8 PUCCH INDEX:%d\n", sr.sr_information_rel8.pucch_index); + } - /* if there is already an HARQ pdu, convert to SR_HARQ */ - if (is_harq) { - nfapi_ul_config_harq_information h = ul_req_body->ul_config_pdu_list[i].uci_harq_pdu.harq_information; - ul_req_body->ul_config_pdu_list[i].pdu_type = NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE; - ul_req_body->ul_config_pdu_list[i].uci_sr_harq_pdu.sr_information = sr; - ul_req_body->ul_config_pdu_list[i].uci_sr_harq_pdu.harq_information = h; - } else { - ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].pdu_type = NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE; - ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; - ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; - ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel11.tl.tag = 0; - ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel13.tl.tag = 0; - ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.sr_information = sr; - ul_req_body->number_of_pdus++; - } /* if (is_harq) */ - ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) - } // for (CC_id=0; CC_idul_config_pdu_list[i].uci_harq_pdu.harq_information; + ul_req_body->ul_config_pdu_list[i].pdu_type = NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE; + ul_req_body->ul_config_pdu_list[i].uci_sr_harq_pdu.sr_information = sr; + ul_req_body->ul_config_pdu_list[i].uci_sr_harq_pdu.harq_information = h; + } else { + ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].pdu_type = NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE; + ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; + ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; + ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel11.tl.tag = 0; + ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel13.tl.tag = 0; + ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.sr_information = sr; + ul_req_body->number_of_pdus++; + } /* if (is_harq) */ + ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) + } // for (CC_id=0; CC_idUE_list; - nfapi_dl_config_request_t *DL_req = &RC.mac[module_idP]->DL_req[0]; - uint16_t rnti = UE_RNTI(module_idP, UE_id); - COMMON_channels_t *cc = RC.mac[module_idP]->common_channels; + UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; + nfapi_dl_config_request_t *DL_req = &RC.mac[module_idP]->DL_req[0]; + uint16_t rnti = UE_RNTI(module_idP, UE_id); + COMMON_channels_t *cc = RC.mac[module_idP]->common_channels; - // check uplink failure - if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 0) && - (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0)) { - LOG_I(MAC, "UE %d rnti %x: UL Failure timer %d \n", UE_id, rnti, - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer); - if (UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent == 0) { - UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 1; + // check uplink failure + if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 0) && + (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0)) { + LOG_I(MAC, "UE %d rnti %x: UL Failure timer %d \n", UE_id, rnti, + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer); + if (UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent == 0) { + UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 1; - // add a format 1A dci for this UE to request an RA procedure (only one UE per subframe) - nfapi_dl_config_request_pdu_t *dl_config_pdu = - &DL_req[CC_id]. - dl_config_request_body.dl_config_pdu_list[DL_req[CC_id]. - dl_config_request_body.number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = - NFAPI_DL_DCI_FORMAT_1A; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = - get_aggregation(get_bw_index(module_idP, CC_id), - UE_list->UE_sched_ctrl[UE_id]. - dl_cqi[CC_id], format1A); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + // add a format 1A dci for this UE to request an RA procedure (only one UE per subframe) + nfapi_dl_config_request_pdu_t *dl_config_pdu = &DL_req[CC_id].dl_config_request_body.dl_config_pdu_list[DL_req[CC_id].dl_config_request_body.number_pdu]; + memset((void *) dl_config_pdu, 0,sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP, CC_id), + UE_list->UE_sched_ctrl[UE_id]. + dl_cqi[CC_id], format1A); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - AssertFatal((cc[CC_id].mib->message.dl_Bandwidth >= 0) - && (cc[CC_id].mib->message.dl_Bandwidth < 6), - "illegal dl_Bandwidth %d\n", - (int) cc[CC_id].mib->message.dl_Bandwidth); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - resource_block_coding = - pdcch_order_table[cc[CC_id].mib->message.dl_Bandwidth]; - DL_req[CC_id].dl_config_request_body.number_dci++; - DL_req[CC_id].dl_config_request_body.number_pdu++; - DL_req[CC_id].dl_config_request_body.tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - LOG_I(MAC, - "UE %d rnti %x: sending PDCCH order for RAPROC (failure timer %d), resource_block_coding %d \n", - UE_id, rnti, - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer, - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.resource_block_coding); - } else { // ra_pdcch_sent==1 - LOG_I(MAC, - "UE %d rnti %x: sent PDCCH order for RAPROC waiting (failure timer %d) \n", - UE_id, rnti, - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer); - if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer % 40) == 0) - UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 0; // resend every 4 frames - } + AssertFatal((cc[CC_id].mib->message.dl_Bandwidth >= 0) && (cc[CC_id].mib->message.dl_Bandwidth < 6), + "illegal dl_Bandwidth %d\n", + (int) cc[CC_id].mib->message.dl_Bandwidth); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = pdcch_order_table[cc[CC_id].mib->message.dl_Bandwidth]; + DL_req[CC_id].dl_config_request_body.number_dci++; + DL_req[CC_id].dl_config_request_body.number_pdu++; + DL_req[CC_id].dl_config_request_body.tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + LOG_I(MAC, + "UE %d rnti %x: sending PDCCH order for RAPROC (failure timer %d), resource_block_coding %d \n", + UE_id, rnti, + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer, + dl_config_pdu->dci_dl_pdu. + dci_dl_pdu_rel8.resource_block_coding); + } else { // ra_pdcch_sent==1 + LOG_I(MAC, + "UE %d rnti %x: sent PDCCH order for RAPROC waiting (failure timer %d) \n", + UE_id, rnti, + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer); + if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer % 40) == 0) UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 0; // resend every 4 frames + } - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer++; - // check threshold - if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 200) { - // inform RRC of failure and clear timer - LOG_I(MAC, - "UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n", - UE_id, rnti); - mac_eNB_rrc_ul_failure(module_idP, CC_id, frameP, subframeP, - rnti); - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 1; - } - } // ul_failure_timer>0 + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer++; + // check threshold + if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 200) { + // inform RRC of failure and clear timer + LOG_I(MAC, + "UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n", + UE_id, rnti); + mac_eNB_rrc_ul_failure(module_idP, CC_id, frameP, subframeP,rnti); + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; + UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 1; + } + } // ul_failure_timer>0 } @@ -564,63 +425,61 @@ void clear_nfapi_information(eNB_MAC_INST * eNB, int CC_idP, frame_t frameP, sub_frame_t subframeP) { - nfapi_dl_config_request_t *DL_req = &eNB->DL_req[0]; - nfapi_ul_config_request_t *UL_req = &eNB->UL_req[0]; - nfapi_hi_dci0_request_t *HI_DCI0_req = &eNB->HI_DCI0_req[0]; - nfapi_tx_request_t *TX_req = &eNB->TX_req[0]; + nfapi_dl_config_request_t *DL_req = &eNB->DL_req[0]; + nfapi_ul_config_request_t *UL_req = &eNB->UL_req[0]; + nfapi_hi_dci0_request_t *HI_DCI0_req = &eNB->HI_DCI0_req[0]; + nfapi_tx_request_t *TX_req = &eNB->TX_req[0]; - eNB->pdu_index[CC_idP] = 0; + eNB->pdu_index[CC_idP] = 0; - if (nfapi_mode==0 || nfapi_mode == 1) { // monolithic or PNF + if (nfapi_mode==0 || nfapi_mode == 1) { // monolithic or PNF - DL_req[CC_idP].dl_config_request_body.number_pdcch_ofdm_symbols = 1; - DL_req[CC_idP].dl_config_request_body.number_dci = 0; - DL_req[CC_idP].dl_config_request_body.number_pdu = 0; - DL_req[CC_idP].dl_config_request_body.number_pdsch_rnti = 0; - DL_req[CC_idP].dl_config_request_body.transmission_power_pcfich = 6000; + DL_req[CC_idP].dl_config_request_body.number_pdcch_ofdm_symbols = 1; + DL_req[CC_idP].dl_config_request_body.number_dci = 0; + DL_req[CC_idP].dl_config_request_body.number_pdu = 0; + DL_req[CC_idP].dl_config_request_body.number_pdsch_rnti = 0; + DL_req[CC_idP].dl_config_request_body.transmission_power_pcfich = 6000; - HI_DCI0_req[CC_idP].hi_dci0_request_body.sfnsf = subframeP + (frameP<<4); - HI_DCI0_req[CC_idP].hi_dci0_request_body.number_of_dci = 0; + HI_DCI0_req[CC_idP].hi_dci0_request_body.sfnsf = subframeP + (frameP<<4); + HI_DCI0_req[CC_idP].hi_dci0_request_body.number_of_dci = 0; - UL_req[CC_idP].ul_config_request_body.number_of_pdus = 0; - UL_req[CC_idP].ul_config_request_body.rach_prach_frequency_resources = 0; // ignored, handled by PHY for now - UL_req[CC_idP].ul_config_request_body.srs_present = 0; // ignored, handled by PHY for now + UL_req[CC_idP].ul_config_request_body.number_of_pdus = 0; + UL_req[CC_idP].ul_config_request_body.rach_prach_frequency_resources = 0; // ignored, handled by PHY for now + UL_req[CC_idP].ul_config_request_body.srs_present = 0; // ignored, handled by PHY for now - TX_req[CC_idP].tx_request_body.number_of_pdus = 0; + TX_req[CC_idP].tx_request_body.number_of_pdus = 0; - } + } } void copy_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { - int CC_id; - eNB_MAC_INST *mac = RC.mac[module_idP]; + int CC_id; + eNB_MAC_INST *mac = RC.mac[module_idP]; - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - nfapi_ul_config_request_t *ul_req_tmp = &mac->UL_req_tmp[CC_id][subframeP]; - nfapi_ul_config_request_t *ul_req = &mac->UL_req[CC_id]; - nfapi_ul_config_request_pdu_t *ul_req_pdu = ul_req->ul_config_request_body.ul_config_pdu_list; + nfapi_ul_config_request_t *ul_req_tmp = &mac->UL_req_tmp[CC_id][subframeP]; + nfapi_ul_config_request_t *ul_req = &mac->UL_req[CC_id]; + nfapi_ul_config_request_pdu_t *ul_req_pdu = ul_req->ul_config_request_body.ul_config_pdu_list; - *ul_req = *ul_req_tmp; + *ul_req = *ul_req_tmp; - // Restore the pointer - ul_req->ul_config_request_body.ul_config_pdu_list = ul_req_pdu; + // Restore the pointer + ul_req->ul_config_request_body.ul_config_pdu_list = ul_req_pdu; + ul_req->sfn_sf = (frameP<<4) + subframeP; + ul_req_tmp->ul_config_request_body.number_of_pdus = 0; - ul_req->sfn_sf = (frameP<<4) + subframeP; - - ul_req_tmp->ul_config_request_body.number_of_pdus = 0; - - if (ul_req->ul_config_request_body.number_of_pdus>0) + if (ul_req->ul_config_request_body.number_of_pdus>0) { LOG_D(PHY, "%s() active NOW (frameP:%d subframeP:%d) pdus:%d\n", __FUNCTION__, frameP, subframeP, ul_req->ul_config_request_body.number_of_pdus); } - memcpy((void*)ul_req->ul_config_request_body.ul_config_pdu_list, - (void*)ul_req_tmp->ul_config_request_body.ul_config_pdu_list, - ul_req->ul_config_request_body.number_of_pdus*sizeof(nfapi_ul_config_request_pdu_t)); + memcpy((void*)ul_req->ul_config_request_body.ul_config_pdu_list, + (void*)ul_req_tmp->ul_config_request_body.ul_config_pdu_list, + ul_req->ul_config_request_body.number_of_pdus*sizeof(nfapi_ul_config_request_pdu_t)); } } @@ -629,133 +488,127 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { - int mbsfn_status[MAX_NUM_CCs]; - protocol_ctxt_t ctxt; + int mbsfn_status[MAX_NUM_CCs]; + protocol_ctxt_t ctxt; - int CC_id, i; //,next_i; - UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; - rnti_t rnti; + int CC_id, i; + UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; + rnti_t rnti; - COMMON_channels_t *cc = RC.mac[module_idP]->common_channels; + COMMON_channels_t *cc = RC.mac[module_idP]->common_channels; #if defined(FLEXRAN_AGENT_SB_IF) - Protocol__FlexranMessage *msg; + Protocol__FlexranMessage *msg; #endif - start_meas(&RC.mac[module_idP]->eNB_scheduler); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, - VCD_FUNCTION_IN); + start_meas(&RC.mac[module_idP]->eNB_scheduler); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, + VCD_FUNCTION_IN); - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - mbsfn_status[CC_id] = 0; + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + mbsfn_status[CC_id] = 0; - // clear vrb_maps - memset(cc[CC_id].vrb_map, 0, 100); - memset(cc[CC_id].vrb_map_UL, 0, 100); + // clear vrb_maps + memset(cc[CC_id].vrb_map, 0, 100); + memset(cc[CC_id].vrb_map_UL, 0, 100); #if defined(Rel10) || defined(Rel14) - cc[CC_id].mcch_active = 0; + cc[CC_id].mcch_active = 0; #endif - RC.mac[module_idP]->frame = frameP; - RC.mac[module_idP]->subframe = subframeP; + RC.mac[module_idP]->frame = frameP; + RC.mac[module_idP]->subframe = subframeP; - clear_nfapi_information(RC.mac[module_idP], CC_id, frameP, - subframeP); + clear_nfapi_information(RC.mac[module_idP], CC_id, frameP,subframeP); + } + + // refresh UE list based on UEs dropped by PHY in previous subframe + for (i = 0; i < NUMBER_OF_UE_MAX; i++) { + if (UE_list->active[i] != TRUE) continue; + + rnti = UE_RNTI(module_idP, i); + CC_id = UE_PCCID(module_idP, i); + + if ((frameP == 0) && (subframeP == 0)) { + LOG_I(MAC, + "UE rnti %x : %s, PHR %d dB DL CQI %d PUSCH SNR %d PUCCH SNR %d\n", + rnti, + UE_list->UE_sched_ctrl[i].ul_out_of_sync == + 0 ? "in synch" : "out of sync", + UE_list->UE_template[CC_id][i].phr_info, + UE_list->UE_sched_ctrl[i].dl_cqi[CC_id], + (UE_list->UE_sched_ctrl[i].pusch_snr[CC_id] - 128) / 2, + (UE_list->UE_sched_ctrl[i].pucch1_snr[CC_id] - 128) / 2); } - // refresh UE list based on UEs dropped by PHY in previous subframe - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { - if (UE_list->active[i] != TRUE) - continue; + RC.eNB[module_idP][CC_id]->pusch_stats_bsr[i][(frameP * 10) + subframeP] = -63; + if (i == UE_list->head) + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME + (VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, + RC.eNB[module_idP][CC_id]-> + pusch_stats_bsr[i][(frameP * 10) + subframeP]); + // increment this, it is cleared when we receive an sdu + RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ul_inactivity_timer++; - rnti = UE_RNTI(module_idP, i); - CC_id = UE_PCCID(module_idP, i); + RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer++; + LOG_D(MAC, "UE %d/%x : ul_inactivity %d, cqi_req %d\n", i, rnti, + RC.mac[module_idP]->UE_list.UE_sched_ctrl[i]. + ul_inactivity_timer, + RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer); + check_ul_failure(module_idP, CC_id, i, frameP, subframeP); + } - if ((frameP == 0) && (subframeP == 0)) { - LOG_I(MAC, - "UE rnti %x : %s, PHR %d dB DL CQI %d PUSCH SNR %d PUCCH SNR %d\n", - rnti, - UE_list->UE_sched_ctrl[i].ul_out_of_sync == - 0 ? "in synch" : "out of sync", - UE_list->UE_template[CC_id][i].phr_info, - UE_list->UE_sched_ctrl[i].dl_cqi[CC_id], - (UE_list->UE_sched_ctrl[i].pusch_snr[CC_id] - 128) / 2, - (UE_list->UE_sched_ctrl[i].pucch1_snr[CC_id] - 128) / 2); - } + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, + NOT_A_RNTI, frameP, subframeP, + module_idP); + pdcp_run(&ctxt); - RC.eNB[module_idP][CC_id]->pusch_stats_bsr[i][(frameP * 10) + - subframeP] = -63; - if (i == UE_list->head) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME - (VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, - RC.eNB[module_idP][CC_id]-> - pusch_stats_bsr[i][(frameP * 10) + subframeP]); - // increment this, it is cleared when we receive an sdu - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ul_inactivity_timer++; - - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer++; - LOG_D(MAC, "UE %d/%x : ul_inactivity %d, cqi_req %d\n", i, rnti, - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i]. - ul_inactivity_timer, - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer); - check_ul_failure(module_idP, CC_id, i, frameP, subframeP); - - } - - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, - NOT_A_RNTI, frameP, subframeP, - module_idP); - pdcp_run(&ctxt); - - rrc_rx_tx(&ctxt, 0, // eNB index, unused in eNB - CC_id); + rrc_rx_tx(&ctxt, 0, CC_id); #if defined(Rel10) || defined(Rel14) - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - if (cc[CC_id].MBMS_flag > 0) { - start_meas(&RC.mac[module_idP]->schedule_mch); - mbsfn_status[CC_id] = - schedule_MBMS(module_idP, CC_id, frameP, subframeP); - stop_meas(&RC.mac[module_idP]->schedule_mch); - } + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + if (cc[CC_id].MBMS_flag > 0) { + start_meas(&RC.mac[module_idP]->schedule_mch); + mbsfn_status[CC_id] = schedule_MBMS(module_idP, CC_id, frameP, subframeP); + stop_meas(&RC.mac[module_idP]->schedule_mch); } + } #endif - // This schedules MIB - if ((subframeP == 0) && (frameP & 3) == 0) - schedule_mib(module_idP, frameP, subframeP); - // This schedules SI for legacy LTE and eMTC starting in subframeP - schedule_SI(module_idP, frameP, subframeP); - // This schedules Random-Access for legacy LTE and eMTC starting in subframeP - schedule_RA(module_idP, frameP, subframeP); - // copy previously scheduled UL resources (ULSCH + HARQ) - copy_ulreq(module_idP, frameP, subframeP); - // This schedules SRS in subframeP - schedule_SRS(module_idP, frameP, subframeP); - // This schedules ULSCH in subframeP (dci0) - schedule_ulsch(module_idP, frameP, subframeP); - // This schedules UCI_SR in subframeP - schedule_SR(module_idP, frameP, subframeP); - // This schedules UCI_CSI in subframeP - schedule_CSI(module_idP, frameP, subframeP); + // This schedules MIB + if ((subframeP == 0) && (frameP & 3) == 0) + schedule_mib(module_idP, frameP, subframeP); + // This schedules SI for legacy LTE and eMTC starting in subframeP + schedule_SI(module_idP, frameP, subframeP); + // This schedules Random-Access for legacy LTE and eMTC starting in subframeP + schedule_RA(module_idP, frameP, subframeP); + // copy previously scheduled UL resources (ULSCH + HARQ) + copy_ulreq(module_idP, frameP, subframeP); + // This schedules SRS in subframeP + schedule_SRS(module_idP, frameP, subframeP); + // This schedules ULSCH in subframeP (dci0) + schedule_ulsch(module_idP, frameP, subframeP); + // This schedules UCI_SR in subframeP + schedule_SR(module_idP, frameP, subframeP); + // This schedules UCI_CSI in subframeP + schedule_CSI(module_idP, frameP, subframeP); - // This schedules DLSCH in subframeP - schedule_ue_spec(module_idP, frameP, subframeP, mbsfn_status); + // This schedules DLSCH in subframeP + schedule_ue_spec(module_idP, frameP, subframeP, mbsfn_status); - // Allocate CCEs for good after scheduling is done + // Allocate CCEs for good after scheduling is done - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) - allocate_CCEs(module_idP, CC_id, subframeP, 0); + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) + allocate_CCEs(module_idP, CC_id, subframeP, 0); - stop_meas(&RC.mac[module_idP]->eNB_scheduler); + stop_meas(&RC.mac[module_idP]->eNB_scheduler); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, - VCD_FUNCTION_OUT); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, + VCD_FUNCTION_OUT); } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index 7b45401b06..3807b1aa61 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -135,48 +135,35 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP, memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; - ul_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = mac->ul_handle++; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = ra->rnti; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = - narrowband_to_first_rb(cc, - ra->msg34_narrowband) + - ra->msg3_first_rb; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = - ra->msg3_nb_rb; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = - 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8. - frequency_hopping_enabled_flag = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = - rvseq[ra->msg3_round]; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = - ((10 * ra->Msg3_frame) + ra->Msg3_subframe) & 7; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = 1; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = - get_TBS_UL(ra->msg3_mcs, ra->msg3_nb_rb); + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = mac->ul_handle++; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = ra->rnti; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = narrowband_to_first_rb(cc, + ra->msg34_narrowband) + ra->msg3_first_rb; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = ra->msg3_nb_rb; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = rvseq[ra->msg3_round]; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = ((10 * ra->Msg3_frame) + ra->Msg3_subframe) & 7; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = 1; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL(ra->msg3_mcs, ra->msg3_nb_rb); // Re13 fields - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type = - ra->rach_resource_type > 2 ? 2 : 1; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13. - total_number_of_repetitions = 1; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number = 1; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13. - initial_transmission_sf_io = - (ra->Msg3_frame * 10) + ra->Msg3_subframe; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type = ra->rach_resource_type > 2 ? 2 : 1; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions = 1; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number = 1; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = (ra->Msg3_frame * 10) + ra->Msg3_subframe; ul_req_body->number_of_pdus++; - ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - ul_req->sfn_sf = ra->Msg3_frame<<4|ra->Msg3_subframe; - ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + ul_req->sfn_sf = ra->Msg3_frame<<4|ra->Msg3_subframe; + ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; } // if (ra->rach_resource_type>0) { else #endif @@ -191,42 +178,32 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP, frameP, subframeP, ra->Msg3_frame, ra->Msg3_subframe, ra->msg3_nb_rb, ra->msg3_first_rb, ra->msg3_round); - ul_config_pdu = - &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; + ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; - memset((void *) ul_config_pdu, 0, - sizeof(nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; - ul_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = mac->ul_handle++; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = ra->rnti; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = - ra->msg3_first_rb; + memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = mac->ul_handle++; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = ra->rnti; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = ra->msg3_first_rb; AssertFatal(ra->msg3_nb_rb > 0, "nb_rb = 0\n"); - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = - ra->msg3_nb_rb; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = - 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8. - frequency_hopping_enabled_flag = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = - rvseq[ra->msg3_round]; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = - subframe2harqpid(cc, ra->Msg3_frame, ra->Msg3_subframe); - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = 1; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = - get_TBS_UL(10, ra->msg3_nb_rb); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = ra->msg3_nb_rb; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = rvseq[ra->msg3_round]; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = subframe2harqpid(cc, ra->Msg3_frame, ra->Msg3_subframe); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = 1; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL(10, ra->msg3_nb_rb); ul_req_body->number_of_pdus++; - ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - ul_req->sfn_sf = ra->Msg3_frame<<4|ra->Msg3_subframe; - ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + ul_req->sfn_sf = ra->Msg3_frame<<4|ra->Msg3_subframe; + ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; // save UL scheduling information for preprocessor for (j = 0; j < ra->msg3_nb_rb; j++) cc->vrb_map_UL[ra->msg3_first_rb + j] = 1; @@ -237,20 +214,19 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP, 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 = - ra->msg3_first_rb; + 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 = ra->msg3_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_pdu->hi_pdu.hi_pdu_rel8.hi_value = 0; hi_dci0_req_body->number_of_hi++; - hi_dci0_req_body->sfnsf = sfnsf_add_subframe(ra->Msg3_frame, ra->Msg3_subframe, 0); - hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; + hi_dci0_req_body->sfnsf = sfnsf_add_subframe(ra->Msg3_frame, ra->Msg3_subframe, 0); + hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; - hi_dci0_req->sfn_sf = sfnsf_add_subframe(ra->Msg3_frame, ra->Msg3_subframe, 4); - hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; + hi_dci0_req->sfn_sf = sfnsf_add_subframe(ra->Msg3_frame, ra->Msg3_subframe, 4); + hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; if (nfapi_mode) { oai_nfapi_hi_dci0_req(hi_dci0_req); @@ -312,11 +288,8 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, if (cc[CC_idP].radioResourceConfigCommon_BR) { - ext4_prach = - cc[CC_idP].radioResourceConfigCommon_BR->ext4-> - prach_ConfigCommon_v1310; - prach_ParametersListCE_r13 = - &ext4_prach->prach_ParametersListCE_r13; + ext4_prach = cc[CC_idP].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310; + prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; switch (prach_ParametersListCE_r13->list.count) { case 4: @@ -348,110 +321,71 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, // rmax from SIB2 information AssertFatal(rmax < 9, "rmax>8!\n"); - rmax = - 1 << p[ra->rach_resource_type - - 1]->mpdcch_NumRepetition_RA_r13; + rmax = 1 << p[ra->rach_resource_type-1]->mpdcch_NumRepetition_RA_r13; // choose r1 by default for RAR (Table 9.1.5-5) rep = 0; // get actual repetition count from Table 9.1.5-3 reps = (rmax <= 8) ? (1 << rep) : (rmax >> (3 - rep)); // get narrowband according to higher-layer config - num_nb = - p[ra->rach_resource_type - - 1]->mpdcch_NarrowbandsToMonitor_r13.list.count; - ra->msg2_narrowband = - *p[ra->rach_resource_type - - 1]->mpdcch_NarrowbandsToMonitor_r13.list.array[ra-> - preamble_index - % num_nb]; - first_rb = - narrowband_to_first_rb(&cc[CC_idP], ra->msg2_narrowband); + num_nb = p[ra->rach_resource_type-1]->mpdcch_NarrowbandsToMonitor_r13.list.count; + ra->msg2_narrowband = *p[ra->rach_resource_type - 1]->mpdcch_NarrowbandsToMonitor_r13.list.array[ra->preamble_index % num_nb]; + first_rb = narrowband_to_first_rb(&cc[CC_idP], ra->msg2_narrowband); if ((ra->msg2_mpdcch_repetition_cnt == 0) && - (mpdcch_sf_condition - (mac, CC_idP, frameP, subframeP, rmax, TYPE2, -1) > 0)) { + (mpdcch_sf_condition(mac, CC_idP, frameP, subframeP, rmax, TYPE2, -1) > 0)) { // MPDCCH configuration for RAR LOG_D(MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming MPDCCH %d repetitions\n", module_idP, frameP, subframeP, reps); - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_mpdcch_pdu)); - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = - (ra->rach_resource_type > 1) ? 11 : 10; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = - ra->msg2_narrowband; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - number_of_prb_pairs = 6; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1; // imposed (9.1.5 in 213) for Type 2 Common search space - AssertFatal(cc[CC_idP]. - sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 - != NULL, + memset((void *) dl_config_pdu, 0,sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_mpdcch_pdu)); + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = (ra->rach_resource_type > 1) ? 11 : 10; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = ra->msg2_narrowband; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1; // imposed (9.1.5 in 213) for Type 2 Common search space + AssertFatal(cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13!= NULL, "cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = - cc[CC_idP].sib1_v13ext-> - bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0; // Note: this should be dynamic - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 16; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 2; // RA-RNTI - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = ra->RA_rnti; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = - (ra->rach_resource_type < 3) ? 1 : 2; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - drms_scrambling_init = cc[CC_idP].physCellId; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - initial_transmission_sf_io = (frameP * 10) + subframeP; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = 6000; // 0dB - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV(6, 0, 6); // Note: still to be checked if it should not be (getRIV(N_RB_DL,first_rb,6)) : Check nFAPI specifications and what is done L1 with this parameter + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0; // Note: this should be dynamic + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 16; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 2; // RA-RNTI + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = ra->RA_rnti; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = (ra->rach_resource_type < 3) ? 1 : 2; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = cc[CC_idP].physCellId; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = 6000; // 0dB + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV(6, 0, 6); // Note: still to be checked if it should not be (getRIV(N_RB_DL,first_rb,6)) : Check nFAPI specifications and what is done L1 with this parameter dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB=3 - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 4; // fix to 4 for now - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = - 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = - 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - harq_resource_offset = 0; - dl_config_pdu->mpdcch_pdu. - mpdcch_pdu_rel13.dci_subframe_repetition_number = rep; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 1; // N1A_PRB=3 (36.212); => 208 bits for mcs=4, choose mcs according t message size TBD - dl_config_pdu->mpdcch_pdu. - mpdcch_pdu_rel13.downlink_assignment_index_length = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - downlink_assignment_index = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - allocate_prach_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.preamble_index = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = - 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = - 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.srs_request = 0; - dl_config_pdu->mpdcch_pdu. - mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag - = 0; - dl_config_pdu->mpdcch_pdu. - mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = 0; - dl_config_pdu->mpdcch_pdu. - mpdcch_pdu_rel13.frequency_hopping_enabled_flag = 0; - dl_config_pdu->mpdcch_pdu. - mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag - = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = - 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding = 0; // this is not needed by OAI L1, but should be filled in - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - number_of_tx_antenna_ports = 1; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 4; // fix to 4 for now + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_resource_offset = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_subframe_repetition_number = rep; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 1; // N1A_PRB=3 (36.212); => 208 bits for mcs=4, choose mcs according t message size TBD + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index_length = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.preamble_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.srs_request = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.frequency_hopping_enabled_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding = 0; // this is not needed by OAI L1, but should be filled in + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports = 1; ra->msg2_mpdcch_repetition_cnt++; dl_req->number_pdu++; dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; @@ -489,65 +423,43 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, ra->state = WAITMSG3; LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG3\n", module_idP, frameP, subframeP); - dl_config_pdu = - &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = - mac->pdu_index[CC_idP]; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->RA_rnti; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - resource_allocation_type = 2; + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0,sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_idP]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->RA_rnti; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - resource_block_coding = getRIV(N_RB_DL, first_rb, 6); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - redundancy_version = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = - 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = - 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - number_of_subbands = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 6); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - ue_category_capacity = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - delta_power_offset_index = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = - (cc->p_eNB == 1) ? 1 : 2; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - num_bf_prb_per_subband = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; // Rel10 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = - cc[CC_idP]. - sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13-> - startSymbolBR_r13; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; // Rel13 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = - (ra->rach_resource_type < 3) ? 1 : 2;; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not SI message - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13. - initial_transmission_sf_io = (10 * frameP) + subframeP; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = - 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (ra->rach_resource_type < 3) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not SI message + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = (10 * frameP) + subframeP; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = 0; dl_req->number_pdu++; mac->DL_req[CC_idP].sfn_sf = (frameP<<4)+subframeP; @@ -567,16 +479,12 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, mac->TX_req[CC_idP].header.message_id = NFAPI_TX_REQUEST; mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + subframeP; TX_req = - &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac-> - TX_req - [CC_idP]. - tx_request_body.number_of_pdus]; + &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac->TX_req[CC_idP].tx_request_body.number_of_pdus]; TX_req->pdu_length = 7; // This should be changed if we have more than 1 preamble TX_req->pdu_index = mac->pdu_index[CC_idP]++; TX_req->num_segments = 1; TX_req->segments[0].segment_length = 7; - TX_req->segments[0].segment_data = - cc[CC_idP].RAR_pdu.payload; + TX_req->segments[0].segment_data = cc[CC_idP].RAR_pdu.payload; mac->TX_req[CC_idP].tx_request_body.number_of_pdus++; } } @@ -597,100 +505,73 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, vrb_map[first_rb + 2] = 1; vrb_map[first_rb + 3] = 1; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); + memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = - NFAPI_DL_DCI_FORMAT_1A; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = - 4; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = ra->RA_rnti; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // RA-RNTI : see Table 4-10 from SCF082 - nFAPI specifications dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - new_data_indicator_1 = 1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - redundancy_version_1 = 0; - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - resource_block_coding = getRIV(N_RB_DL, first_rb, 4); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); // This checks if the above DCI allocation is feasible in current subframe - if (!CCE_allocation_infeasible - (module_idP, CC_idP, 0, subframeP, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level, ra->RA_rnti)) { + if (!CCE_allocation_infeasible(module_idP, CC_idP, 0, subframeP, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, ra->RA_rnti)) { LOG_D(MAC, "Frame %d: Subframe %d : Adding common DCI for RA_RNTI %x\n", frameP, subframeP, ra->RA_rnti); dl_req->number_dci++; dl_req->number_pdu++; - dl_config_pdu = - &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = - mac->pdu_index[CC_idP]; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->RA_rnti; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_idP]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->RA_rnti; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - resource_block_coding = getRIV(N_RB_DL, first_rb, 4); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - redundancy_version = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = - 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = - 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - number_of_subbands = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - ue_category_capacity = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - delta_power_offset_index = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = - (cc->p_eNB == 1) ? 1 : 2; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - num_bf_prb_per_subband = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; dl_req->number_pdu++; mac->DL_req[CC_idP].sfn_sf = frameP<<4 | subframeP; // Program UL processing for Msg3 - get_Msg3alloc(&cc[CC_idP], subframeP, frameP, - &ra->Msg3_frame, &ra->Msg3_subframe); + get_Msg3alloc(&cc[CC_idP], subframeP, frameP,&ra->Msg3_frame, &ra->Msg3_subframe); LOG_D(MAC, "Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n", frameP, subframeP, ra->Msg3_frame, ra->Msg3_subframe); - fill_rar(module_idP, CC_idP, ra, frameP, - cc[CC_idP].RAR_pdu.payload, N_RB_DL, 7); + fill_rar(module_idP, CC_idP, ra, frameP, cc[CC_idP].RAR_pdu.payload, N_RB_DL, 7); add_msg3(module_idP, CC_idP, ra, frameP, subframeP); ra->state = WAITMSG3; LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG3\n", module_idP, frameP, subframeP); @@ -698,10 +579,7 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, // DL request mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + subframeP; TX_req = - &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac-> - TX_req - [CC_idP]. - tx_request_body.number_of_pdus]; + &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac->TX_req[CC_idP].tx_request_body.number_of_pdus]; TX_req->pdu_length = 7; // This should be changed if we have more than 1 preamble TX_req->pdu_index = mac->pdu_index[CC_idP]++; TX_req->num_segments = 1; @@ -759,63 +637,42 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, if (cc[CC_idP].radioResourceConfigCommon_BR) { - ext4_prach = - cc[CC_idP].radioResourceConfigCommon_BR->ext4-> - prach_ConfigCommon_v1310; - ext4_pucch = - cc[CC_idP].radioResourceConfigCommon_BR->ext4-> - pucch_ConfigCommon_v1310; - prach_ParametersListCE_r13 = - &ext4_prach->prach_ParametersListCE_r13; - pucch_N1PUCCH_AN_InfoList_r13 = - ext4_pucch->n1PUCCH_AN_InfoList_r13; - AssertFatal(prach_ParametersListCE_r13 != NULL, - "prach_ParametersListCE_r13 is null\n"); - AssertFatal(pucch_N1PUCCH_AN_InfoList_r13 != NULL, - "pucch_N1PUCCH_AN_InfoList_r13 is null\n"); + ext4_prach = cc[CC_idP].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310; + ext4_pucch = cc[CC_idP].radioResourceConfigCommon_BR->ext4->pucch_ConfigCommon_v1310; + prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; + pucch_N1PUCCH_AN_InfoList_r13 = ext4_pucch->n1PUCCH_AN_InfoList_r13; + AssertFatal(prach_ParametersListCE_r13 != NULL,"prach_ParametersListCE_r13 is null\n"); + AssertFatal(pucch_N1PUCCH_AN_InfoList_r13 != NULL,"pucch_N1PUCCH_AN_InfoList_r13 is null\n"); // check to verify CE-Level compatibility in SIB2_BR - AssertFatal(prach_ParametersListCE_r13->list.count == - pucch_N1PUCCH_AN_InfoList_r13->list.count, + AssertFatal(prach_ParametersListCE_r13->list.count == pucch_N1PUCCH_AN_InfoList_r13->list.count, "prach_ParametersListCE_r13->list.count!= pucch_N1PUCCH_AN_InfoList_r13->list.count\n"); switch (prach_ParametersListCE_r13->list.count) { case 4: p[3] = prach_ParametersListCE_r13->list.array[3]; n1pucchan[3] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[3]; - AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13 - != NULL, + AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level3 shouldn't be NULL\n"); - pucchreps[3] = - (int) (4 << *ext4_pucch-> - pucch_NumRepetitionCE_Msg4_Level3_r13); + pucchreps[3] = (int) (4 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13); case 3: p[2] = prach_ParametersListCE_r13->list.array[2]; n1pucchan[2] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[2]; - AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13 - != NULL, + AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13!= NULL, "pucch_NumRepetitionCE_Msg4_Level2 shouldn't be NULL\n"); - pucchreps[2] = - (int) (4 << *ext4_pucch-> - pucch_NumRepetitionCE_Msg4_Level2_r13); + pucchreps[2] =(int) (4 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13); case 2: p[1] = prach_ParametersListCE_r13->list.array[1]; n1pucchan[1] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[1]; - AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13 - != NULL, + AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level1 shouldn't be NULL\n"); - pucchreps[1] = - (int) (1 << *ext4_pucch-> - pucch_NumRepetitionCE_Msg4_Level1_r13); + pucchreps[1] = (int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level1_r13); case 1: p[0] = prach_ParametersListCE_r13->list.array[0]; n1pucchan[0] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[0]; - AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13 - != NULL, + AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level0 shouldn't be NULL\n"); - pucchreps[0] = - (int) (1 << *ext4_pucch-> - pucch_NumRepetitionCE_Msg4_Level0_r13); + pucchreps[0] =(int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level0_r13); default: AssertFatal(1 == 0, "Illegal count for prach_ParametersListCE_r13 %d\n", @@ -887,80 +744,53 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_mpdcch_pdu)); + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_mpdcch_pdu)); dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = - (ra->rach_resource_type > 1) ? 11 : 10; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = - ra->msg34_narrowband; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - number_of_prb_pairs = 6; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = (ra->rach_resource_type > 1) ? 11 : 10; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = ra->msg34_narrowband; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - mpdcch_tansmission_type = 1; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1; AssertFatal(cc[CC_idP]. sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 != NULL, "cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = - cc[CC_idP].sib1_v13ext-> - bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0; // Note: this should be dynamic dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 16; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 0; // t-C-RNTI dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = ra->RA_rnti; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = - (ra->rach_resource_type < 3) ? 1 : 2; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = (ra->rach_resource_type < 3) ? 1 : 2; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = cc[CC_idP].physCellId; /// Check this is still N_id_cell for type2 common - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - initial_transmission_sf_io = (frameP * 10) + subframeP; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = 6000; // 0dB dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV(6, 0, 6); // check if not getRIV(N_RB_DL,first_rb,6); dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs = 4; // adjust according to size of Msg4, 208 bits with N1A_PRB=3 dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 4; // fix to 4 for now - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = - 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = - 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = - ra->harq_pid; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = ra->harq_pid; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length = 0; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi = 0; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag = 0; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - harq_resource_offset = 0; - dl_config_pdu->mpdcch_pdu. - mpdcch_pdu_rel13.dci_subframe_repetition_number = rep; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_resource_offset = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_subframe_repetition_number = rep; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 1; // N1A_PRB=3; => 208 bits - dl_config_pdu->mpdcch_pdu. - mpdcch_pdu_rel13.downlink_assignment_index_length = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - downlink_assignment_index = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - allocate_prach_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index_length = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag = 0; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.preamble_index = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = - 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = - 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = 0; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.srs_request = 0; - dl_config_pdu->mpdcch_pdu. - mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag - = 0; - dl_config_pdu->mpdcch_pdu. - mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = 0; - dl_config_pdu->mpdcch_pdu. - mpdcch_pdu_rel13.frequency_hopping_enabled_flag = 0; - dl_config_pdu->mpdcch_pdu. - mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag - = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = - 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.frequency_hopping_enabled_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = 0; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding = 0; // this is not needed by OAI L1, but should be filled in - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. - number_of_tx_antenna_ports = 1; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports = 1; ra->msg4_mpdcch_repetition_cnt++; dl_req_body->number_pdu++; dl_req_body->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; @@ -983,8 +813,7 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, AssertFatal(1 == 0, "TDD case not done yet\n"); } } // mpdcch_repetition_count == reps - if ((ra->Msg4_frame == frameP) - && (ra->Msg4_subframe == subframeP)) { + if ((ra->Msg4_frame == frameP) && (ra->Msg4_subframe == subframeP)) { // Program PDSCH @@ -995,62 +824,42 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, AssertFatal(1 == 0, "Msg4 generation not finished for BL/CE UE\n"); - dl_config_pdu = - &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu]; + memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = - mac->pdu_index[CC_idP]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_idP]; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->rnti; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 6); // check that this isn't getRIV(6,0,6) dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - redundancy_version = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = - 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = - 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - number_of_subbands = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = - (cc->p_eNB == 1) ? 1 : 2; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - num_bf_prb_per_subband = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = - cc[CC_idP]. - sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13-> - startSymbolBR_r13; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = - (ra->rach_resource_type < 3) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (ra->rach_resource_type < 3) ? 1 : 2; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not SI message - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13. - initial_transmission_sf_io = (10 * frameP) + subframeP; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = - 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = (10 * frameP) + subframeP; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = 0; dl_req_body->number_pdu++; dl_req_body->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; @@ -1062,18 +871,15 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, lcid = 0; - UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = - 0; + UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = 0; msg4_header = 1 + 6 + 1; // CR header, CR CE, SDU header if ((ra->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) { - msg4_padding = - ra->msg4_TBsize - rrc_sdu_length - msg4_header; + msg4_padding = ra->msg4_TBsize - rrc_sdu_length - msg4_header; msg4_post_padding = 0; } else { msg4_padding = 0; - msg4_post_padding = - ra->msg4_TBsize - rrc_sdu_length - msg4_header - 1; + msg4_post_padding = ra->msg4_TBsize - rrc_sdu_length - msg4_header - 1; } LOG_D(MAC, @@ -1093,10 +899,7 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, msg4_post_padding); memcpy((void *) &mac->UE_list. - DLSCH_pdu[CC_idP][0][(unsigned char) - UE_id].payload[0][(unsigned - char) - offset], + DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0][(unsigned char)offset], &cc[CC_idP].CCCH_pdu.payload[0], rrc_sdu_length); // DL request @@ -1105,17 +908,12 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, mac->TX_req[CC_idP].header.message_id = NFAPI_TX_REQUEST; TX_req = - &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac-> - TX_req - [CC_idP]. - tx_request_body.number_of_pdus]; + &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac->TX_req[CC_idP].tx_request_body.number_of_pdus]; TX_req->pdu_length = rrc_sdu_length; TX_req->pdu_index = mac->pdu_index[CC_idP]++; TX_req->num_segments = 1; TX_req->segments[0].segment_length = rrc_sdu_length; - TX_req->segments[0].segment_data = - mac->UE_list. - DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0]; + TX_req->segments[0].segment_data = mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0]; mac->TX_req[CC_idP].tx_request_body.number_of_pdus++; // Program ACK/NAK for Msg4 PDSCH @@ -1125,44 +923,28 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, AssertFatal(reps > 2, "Have to handle programming of ACK when PDSCH repetitions is > 2\n"); ul_req = &mac->UL_req_tmp[CC_idP][ackNAK_absSF % 10]; - ul_req_body = &ul_req->ul_config_request_body; - ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; + ul_req_body = &ul_req->ul_config_request_body;l_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; - ul_config_pdu->pdu_type = - NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; - ul_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_ul_config_uci_harq_pdu)); + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_uci_harq_pdu)); ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0; // don't know how to use this - ul_config_pdu->uci_harq_pdu. - ue_information.ue_information_rel8.rnti = ra->rnti; + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti = ra->rnti; ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG; - ul_config_pdu->uci_harq_pdu. - ue_information.ue_information_rel13.ue_type = - (ra->rach_resource_type < 3) ? 1 : 2; - ul_config_pdu->uci_harq_pdu. - ue_information.ue_information_rel13.empty_symbols = 0; - ul_config_pdu->uci_harq_pdu.ue_information. - ue_information_rel13.total_number_of_repetitions = - pucchreps[ra->rach_resource_type - 1]; - ul_config_pdu->uci_harq_pdu. - ue_information.ue_information_rel13.repetition_number = - 0; + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.ue_type = (ra->rach_resource_type < 3) ? 1 : 2; + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.empty_symbols = 0; + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.total_number_of_repetitions = pucchreps[ra->rach_resource_type - 1]; + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.repetition_number = 0; ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - ul_req->sfn_sf = sfnsf_add_subframe(ra->Msg3_frame, ra->Msg3_subframe, 4); ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; - LOG_D(MAC,"UL_req_tmp[CC_idP:%d][ackNAK_absSF mod 10:%d] ra->Msg3_frame:%d ra->Msg3_subframe:%d + 4 sfn_sf:%d\n", CC_idP, ackNAK_absSF%10, ra->Msg3_frame, ra->Msg3_subframe, NFAPI_SFNSF2DEC(ul_req->sfn_sf)); // Note need to keep sending this across reptitions!!!! Not really for PUCCH, to ask small-cell forum, we'll see for the other messages, maybe parameters change across repetitions and FAPI has to provide for that if (cc[CC_idP].tdd_Config == NULL) { // FDD case ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel8_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL8_FDD_TAG; - ul_config_pdu->uci_harq_pdu. - harq_information.harq_information_rel8_fdd. - n_pucch_1_0 = - n1pucchan[ra->rach_resource_type - 1]; + ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel8_fdd.n_pucch_1_0 = n1pucchan[ra->rach_resource_type - 1]; // NOTE: How to fill in the rest of the n_pucch_1_0 information 213 Section 10.1.2.1 in the general case // = N_ECCE_q + Delta_ARO + n1pucchan[ce_level] // higher in the MPDCCH configuration, N_ECCE_q is hard-coded to 0, and harq resource offset to 0 => @@ -1182,15 +964,12 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, if (opt_enabled == 1) { trace_pdu(1, (uint8_t *) mac-> - UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) - UE_id].payload - [0], rrc_sdu_length, UE_id, 3, + UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0], rrc_sdu_length, UE_id, 3, UE_RNTI(module_idP, UE_id), mac->frame, mac->subframe, 0, 0); LOG_D(OPT, "[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n", - module_idP, CC_idP, frameP, UE_RNTI(module_idP, - UE_id), + module_idP, CC_idP, frameP, UE_RNTI(module_idP,UE_id), rrc_sdu_length); } } // Msg4 frame/subframe @@ -1253,19 +1032,15 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process, - &dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - resource_block_coding, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - resource_block_coding); + &dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding); AssertFatal(dl_config_pdu->dci_dl_pdu. dci_dl_pdu_rel8.resource_block_coding < 8192, "resource_block_coding %u < 8192\n", dl_config_pdu->dci_dl_pdu. dci_dl_pdu_rel8.resource_block_coding); - if (!CCE_allocation_infeasible - (module_idP, CC_idP, 1, subframeP, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level, ra->rnti)) { + if (!CCE_allocation_infeasible(module_idP, CC_idP, 1, subframeP, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, ra->rnti)) { dl_req_body->number_dci++; dl_req_body->number_pdu++; @@ -1288,21 +1063,17 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, lcid = 0; // put HARQ process round to 0 - if (cc->tdd_Config) - ra->harq_pid = ((frameP * 10) + subframeP) % 10; + if (cc->tdd_Config) ra->harq_pid = ((frameP * 10) + subframeP) % 10; else - ra->harq_pid = ((frameP * 10) + subframeP) & 7; - UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = - 0; + ra->harq_pid = ((frameP * 10) + subframeP) & 7; + UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = 0; if ((ra->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) { - msg4_padding = - ra->msg4_TBsize - rrc_sdu_length - msg4_header; + msg4_padding = ra->msg4_TBsize - rrc_sdu_length - msg4_header; msg4_post_padding = 0; } else { msg4_padding = 0; - msg4_post_padding = - ra->msg4_TBsize - rrc_sdu_length - msg4_header - 1; + msg4_post_padding = ra->msg4_TBsize - rrc_sdu_length - msg4_header - 1; } LOG_D(MAC, @@ -1321,11 +1092,7 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, msg4_padding, // no padding msg4_post_padding); - memcpy((void *) &mac->UE_list. - DLSCH_pdu[CC_idP][0][(unsigned char) - UE_id].payload[0][(unsigned - char) - offset], + memcpy((void *) &mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0][(unsigned char)offset], &cc[CC_idP].CCCH_pdu.payload[0], rrc_sdu_length); // DLSCH Config @@ -1359,9 +1126,7 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, rrc_sdu_length, mac->pdu_index[CC_idP], mac->UE_list. - DLSCH_pdu[CC_idP][0][(unsigned char) - UE_id].payload - [0]); + DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0]); mac->pdu_index[CC_idP]++; dl_req->sfn_sf = mac->TX_req[CC_idP].sfn_sf; @@ -1374,8 +1139,7 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, CC_idP, ra->rnti, (frameP * 10) + subframeP, - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.cce_idx); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), @@ -1387,9 +1151,7 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, if (opt_enabled == 1) { trace_pdu(1, (uint8_t *) mac-> - UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) - UE_id].payload - [0], rrc_sdu_length, UE_id, 3, + UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0], rrc_sdu_length, UE_id, 3, UE_RNTI(module_idP, UE_id), mac->frame, mac->subframe, 0, 0); LOG_D(OPT, @@ -1578,8 +1340,7 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP, LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:IDLE\n", module_idP, frameP, subframeP); UE_id = find_UE_id(module_idP, ra->rnti); DevAssert(UE_id != -1); - mac->UE_list.UE_template[UE_PCCID(module_idP, UE_id)][UE_id]. - configured = TRUE; + mac->UE_list.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured = TRUE; } } @@ -1647,11 +1408,8 @@ initiate_ra_proc(module_id_t module_idP, if (cc->radioResourceConfigCommon_BR && cc->radioResourceConfigCommon_BR->ext4) { - ext4_prach = - cc->radioResourceConfigCommon_BR->ext4-> - prach_ConfigCommon_v1310; - prach_ParametersListCE_r13 = - &ext4_prach->prach_ParametersListCE_r13; + ext4_prach = cc->radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310; + prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; } LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d Initiating RA procedure for preamble index %d\n", @@ -1675,10 +1433,8 @@ initiate_ra_proc(module_id_t module_idP, return; } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); for (i = 0; i < NB_RA_PROC_MAX; i++) { if (ra[i].state == IDLE) { diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 1bffb83d49..9e6b57619e 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -63,210 +63,206 @@ int choose(int n, int k) { - int res = 1; - int res2 = 1; - int i; + int res = 1; + int res2 = 1; + int i; - if (k > n) - return (0); - if (n == k) - return (1); + if (k > n) + return (0); + if (n == k) + return (1); - for (i = n; i > k; i--) - res *= i; - for (i = 2; i <= (n - k); i++) - res2 *= i; + for (i = n; i > k; i--) + res *= i; + for (i = 2; i <= (n - k); i++) + res2 *= i; - return (res / res2); + return (res / res2); } // Patented algorithm from Yang et al, US Patent 2009, "Channel Quality Indexing and Reverse Indexing" void reverse_index(int N, int M, int r, int *v) { - int BaseValue = 0; - int IncreaseValue, ThresholdValue; - int sumV; - int i; + int BaseValue = 0; + int IncreaseValue, ThresholdValue; + int sumV; + int i; - r = choose(N, M) - 1 - r; - memset((void *) v, 0, M * sizeof(int)); + r = choose(N, M) - 1 - r; + memset((void *) v, 0, M * sizeof(int)); - sumV = 0; - i = M; - while (i > 0 && r > 0) { - IncreaseValue = choose(N - M + 1 - sumV - v[i - 1] + i - 2, i - 1); - ThresholdValue = BaseValue + IncreaseValue; - if (r >= ThresholdValue) { - v[i - 1]++; - BaseValue = ThresholdValue; - } else { - r = r - BaseValue; - sumV += v[i - 1]; - i--; - BaseValue = 0; - } + sumV = 0; + i = M; + while (i > 0 && r > 0) { + IncreaseValue = choose(N - M + 1 - sumV - v[i - 1] + i - 2, i - 1); + ThresholdValue = BaseValue + IncreaseValue; + if (r >= ThresholdValue) { + v[i - 1]++; + BaseValue = ThresholdValue; + } else { + r = r - BaseValue; + sumV += v[i - 1]; + i--; + BaseValue = 0; } + } } int to_prb(int dl_Bandwidth) { - int prbmap[6] = { 6, 15, 25, 50, 75, 100 }; + int prbmap[6] = { 6, 15, 25, 50, 75, 100 }; - AssertFatal(dl_Bandwidth < 6, "dl_Bandwidth is 0..5\n"); - return (prbmap[dl_Bandwidth]); + AssertFatal(dl_Bandwidth < 6, "dl_Bandwidth is 0..5\n"); + return (prbmap[dl_Bandwidth]); } int to_rbg(int dl_Bandwidth) { - int rbgmap[6] = { 6, 8, 13, 17, 19, 25 }; + int rbgmap[6] = { 6, 8, 13, 17, 19, 25 }; - AssertFatal(dl_Bandwidth < 6, "dl_Bandwidth is 0..5\n"); - return (rbgmap[dl_Bandwidth]); + AssertFatal(dl_Bandwidth < 6, "dl_Bandwidth is 0..5\n"); + return (rbgmap[dl_Bandwidth]); } int get_phich_resource_times6(COMMON_channels_t * cc) { - int phichmap[4] = { 1, 3, 6, 12 }; - AssertFatal(cc != NULL, "cc is null\n"); - AssertFatal(cc->mib != NULL, "cc->mib is null\n"); - AssertFatal((cc->mib->message.phich_Config.phich_Resource >= 0) && - (cc->mib->message.phich_Config.phich_Resource < 4), - "phich_Resource %d not in 0..3\n", - (int) cc->mib->message.phich_Config.phich_Resource); + int phichmap[4] = { 1, 3, 6, 12 }; + AssertFatal(cc != NULL, "cc is null\n"); + AssertFatal(cc->mib != NULL, "cc->mib is null\n"); + AssertFatal((cc->mib->message.phich_Config.phich_Resource >= 0) && + (cc->mib->message.phich_Config.phich_Resource < 4), + "phich_Resource %d not in 0..3\n", + (int) cc->mib->message.phich_Config.phich_Resource); - return (phichmap[cc->mib->message.phich_Config.phich_Resource]); + return (phichmap[cc->mib->message.phich_Config.phich_Resource]); } uint16_t mac_computeRIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs) { - uint16_t RIV; + uint16_t RIV; - if (Lcrbs <= (1 + (N_RB_DL >> 1))) - RIV = (N_RB_DL * (Lcrbs - 1)) + RBstart; - else - RIV = (N_RB_DL * (N_RB_DL + 1 - Lcrbs)) + (N_RB_DL - 1 - RBstart); + if (Lcrbs <= (1 + (N_RB_DL >> 1))) RIV = (N_RB_DL * (Lcrbs - 1)) + RBstart; + else RIV = (N_RB_DL * (N_RB_DL + 1 - Lcrbs)) + (N_RB_DL - 1 - RBstart); - return (RIV); + return (RIV); } uint8_t getQm(uint8_t mcs) { - if (mcs < 10) - return (2); - else if (mcs < 17) - return (4); - else - return (6); + if (mcs < 10) return (2); + else if (mcs < 17) return (4); + else return (6); } void -get_Msg3alloc(COMMON_channels_t * cc, - sub_frame_t current_subframe, - frame_t current_frame, frame_t * frame, - sub_frame_t * subframe) +get_Msg3alloc(COMMON_channels_t *cc, + sub_frame_t current_subframe, + frame_t current_frame, + frame_t *frame, + sub_frame_t *subframe) { - // Fill in other TDD Configuration!!!! + // Fill in other TDD Configuration!!!! - if (cc->tdd_Config == NULL) { // FDD - *subframe = current_subframe + 6; + if (cc->tdd_Config == NULL) { // FDD + *subframe = current_subframe + 6; - if (*subframe > 9) { - *subframe = *subframe - 10; - *frame = (current_frame + 1) & 1023; - } else { - *frame = current_frame; - } - } else { // TDD - if (cc->tdd_Config->subframeAssignment == 1) { - switch (current_subframe) { - - case 0: - *subframe = 7; - *frame = current_frame; - break; - - case 4: - *subframe = 2; - *frame = (current_frame + 1) & 1023; - break; - - case 5: - *subframe = 2; - *frame = (current_frame + 1) & 1023; - break; - - case 9: - *subframe = 7; - *frame = (current_frame + 1) & 1023; - break; - } - } else if (cc->tdd_Config->subframeAssignment == 3) { - switch (current_subframe) { - - case 0: - case 5: - case 6: - *subframe = 2; - *frame = (current_frame + 1) & 1023; - break; - - case 7: - *subframe = 3; - *frame = (current_frame + 1) & 1023; - break; - - case 8: - *subframe = 4; - *frame = (current_frame + 1) & 1023; - break; - - case 9: - *subframe = 2; - *frame = (current_frame + 2) & 1023; - break; - } - } else if (cc->tdd_Config->subframeAssignment == 4) { - switch (current_subframe) { - - case 0: - case 4: - case 5: - case 6: - *subframe = 2; - *frame = (current_frame + 1) & 1023; - break; - - case 7: - *subframe = 3; - *frame = (current_frame + 1) & 1023; - break; - - case 8: - case 9: - *subframe = 2; - *frame = (current_frame + 2) & 1023; - break; - } - } else if (cc->tdd_Config->subframeAssignment == 5) { - switch (current_subframe) { - - case 0: - case 4: - case 5: - case 6: - *subframe = 2; - *frame = (current_frame + 1) & 1023; - break; - - case 7: - case 8: - case 9: - *subframe = 2; - *frame = (current_frame + 2) & 1023; - break; - } - } + if (*subframe > 9) { + *subframe = *subframe - 10; + *frame = (current_frame + 1) & 1023; + } else { + *frame = current_frame; } + } else { // TDD + if (cc->tdd_Config->subframeAssignment == 1) { + switch (current_subframe) { + + case 0: + *subframe = 7; + *frame = current_frame; + break; + + case 4: + *subframe = 2; + *frame = (current_frame + 1) & 1023; + break; + + case 5: + *subframe = 2; + *frame = (current_frame + 1) & 1023; + break; + + case 9: + *subframe = 7; + *frame = (current_frame + 1) & 1023; + break; + } + } else if (cc->tdd_Config->subframeAssignment == 3) { + switch (current_subframe) { + + case 0: + case 5: + case 6: + *subframe = 2; + *frame = (current_frame + 1) & 1023; + break; + + case 7: + *subframe = 3; + *frame = (current_frame + 1) & 1023; + break; + + case 8: + *subframe = 4; + *frame = (current_frame + 1) & 1023; + break; + + case 9: + *subframe = 2; + *frame = (current_frame + 2) & 1023; + break; + } + } else if (cc->tdd_Config->subframeAssignment == 4) { + switch (current_subframe) { + + case 0: + case 4: + case 5: + case 6: + *subframe = 2; + *frame = (current_frame + 1) & 1023; + break; + + case 7: + *subframe = 3; + *frame = (current_frame + 1) & 1023; + break; + + case 8: + case 9: + *subframe = 2; + *frame = (current_frame + 2) & 1023; + break; + } + } else if (cc->tdd_Config->subframeAssignment == 5) { + switch (current_subframe) { + + case 0: + case 4: + case 5: + case 6: + *subframe = 2; + *frame = (current_frame + 1) & 1023; + break; + + case 7: + case 8: + case 9: + *subframe = 2; + *frame = (current_frame + 2) & 1023; + break; + } + } + } } @@ -277,466 +273,445 @@ get_Msg3allocret(COMMON_channels_t * cc, frame_t current_frame, frame_t * frame, sub_frame_t * subframe) { - if (cc->tdd_Config == NULL) { //FDD - /* always retransmit in n+8 */ - *subframe = current_subframe + 8; + if (cc->tdd_Config == NULL) { //FDD + /* always retransmit in n+8 */ + *subframe = current_subframe + 8; - if (*subframe > 9) { - *subframe = *subframe - 10; - *frame = (current_frame + 1) & 1023; - } else { - *frame = current_frame; - } + if (*subframe > 9) { + *subframe = *subframe - 10; + *frame = (current_frame + 1) & 1023; } else { - if (cc->tdd_Config->subframeAssignment == 1) { - // original PUSCH in 2, PHICH in 6 (S), ret in 2 - // original PUSCH in 3, PHICH in 9, ret in 3 - // original PUSCH in 7, PHICH in 1 (S), ret in 7 - // original PUSCH in 8, PHICH in 4, ret in 8 - *frame = (current_frame + 1) & 1023; - } else if (cc->tdd_Config->subframeAssignment == 3) { - // original PUSCH in 2, PHICH in 8, ret in 2 next frame - // original PUSCH in 3, PHICH in 9, ret in 3 next frame - // original PUSCH in 4, PHICH in 0, ret in 4 next frame - *frame = (current_frame + 1) & 1023; - } else if (cc->tdd_Config->subframeAssignment == 4) { - // original PUSCH in 2, PHICH in 8, ret in 2 next frame - // original PUSCH in 3, PHICH in 9, ret in 3 next frame - *frame = (current_frame + 1) & 1023; - } else if (cc->tdd_Config->subframeAssignment == 5) { - // original PUSCH in 2, PHICH in 8, ret in 2 next frame - *frame = (current_frame + 1) & 1023; - } + *frame = current_frame; } + } else { + if (cc->tdd_Config->subframeAssignment == 1) { + // original PUSCH in 2, PHICH in 6 (S), ret in 2 + // original PUSCH in 3, PHICH in 9, ret in 3 + // original PUSCH in 7, PHICH in 1 (S), ret in 7 + // original PUSCH in 8, PHICH in 4, ret in 8 + *frame = (current_frame + 1) & 1023; + } else if (cc->tdd_Config->subframeAssignment == 3) { + // original PUSCH in 2, PHICH in 8, ret in 2 next frame + // original PUSCH in 3, PHICH in 9, ret in 3 next frame + // original PUSCH in 4, PHICH in 0, ret in 4 next frame + *frame = (current_frame + 1) & 1023; + } else if (cc->tdd_Config->subframeAssignment == 4) { + // original PUSCH in 2, PHICH in 8, ret in 2 next frame + // original PUSCH in 3, PHICH in 9, ret in 3 next frame + *frame = (current_frame + 1) & 1023; + } else if (cc->tdd_Config->subframeAssignment == 5) { + // original PUSCH in 2, PHICH in 8, ret in 2 next frame + *frame = (current_frame + 1) & 1023; + } + } } uint8_t subframe2harqpid(COMMON_channels_t * cc, frame_t frame, sub_frame_t subframe) { - uint8_t ret = 255; + uint8_t ret = 255; - AssertFatal(cc != NULL, "cc is null\n"); - - if (cc->tdd_Config == NULL) { // FDD - ret = (((frame << 1) + subframe) & 7); - } else { - switch (cc->tdd_Config->subframeAssignment) { - case 1: - if ((subframe == 2) || - (subframe == 3) || (subframe == 7) || (subframe == 8)) - switch (subframe) { - case 2: - case 3: - ret = (subframe - 2); - break; - - case 7: - case 8: - ret = (subframe - 5); - break; - - default: - AssertFatal(1 == 0, - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframe, - (int) cc->tdd_Config->subframeAssignment); - break; - } - - break; + AssertFatal(cc != NULL, "cc is null\n"); + if (cc->tdd_Config == NULL) { // FDD + ret = (((frame << 1) + subframe) & 7); + } else { + switch (cc->tdd_Config->subframeAssignment) { + case 1: + if ((subframe == 2) || + (subframe == 3) || (subframe == 7) || (subframe == 8)) + switch (subframe) { case 2: - AssertFatal((subframe == 2) || (subframe == 7), - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframe, - (int) cc->tdd_Config->subframeAssignment); - - ret = (subframe / 7); - break; - case 3: - AssertFatal((subframe > 1) && (subframe < 5), - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframe, - (int) cc->tdd_Config->subframeAssignment); - ret = (subframe - 2); - break; - - case 4: - AssertFatal((subframe > 1) && (subframe < 4), - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframe, - (int) cc->tdd_Config->subframeAssignment); - ret = (subframe - 2); - break; - - case 5: - AssertFatal(subframe == 2, - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframe, - (int) cc->tdd_Config->subframeAssignment); - ret = (subframe - 2); - break; - + ret = (subframe - 2); + break; + case 7: + case 8: + ret = (subframe - 5); + break; default: - AssertFatal(1 == 0, - "subframe2_harq_pid, Unsupported TDD mode %d\n", - (int) cc->tdd_Config->subframeAssignment); + AssertFatal(1 == 0, + "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframe, + (int) cc->tdd_Config->subframeAssignment); + break; } + + break; + + case 2: + AssertFatal((subframe == 2) || (subframe == 7), + "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframe, + (int) cc->tdd_Config->subframeAssignment); + + ret = (subframe / 7); + break; + + case 3: + AssertFatal((subframe > 1) && (subframe < 5), + "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframe, + (int) cc->tdd_Config->subframeAssignment); + ret = (subframe - 2); + break; + + case 4: + AssertFatal((subframe > 1) && (subframe < 4), + "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframe, + (int) cc->tdd_Config->subframeAssignment); + ret = (subframe - 2); + break; + + case 5: + AssertFatal(subframe == 2, + "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframe, + (int) cc->tdd_Config->subframeAssignment); + ret = (subframe - 2); + break; + + default: + AssertFatal(1 == 0, + "subframe2_harq_pid, Unsupported TDD mode %d\n", + (int) cc->tdd_Config->subframeAssignment); } - return ret; + } + return ret; } uint8_t get_Msg3harqpid(COMMON_channels_t * cc, frame_t frame, sub_frame_t current_subframe) { - uint8_t ul_subframe = 0; - uint32_t ul_frame = 0; + uint8_t ul_subframe = 0; + uint32_t ul_frame = 0; - if (cc->tdd_Config == NULL) { // FDD - ul_subframe = - (current_subframe > - 3) ? (current_subframe - 4) : (current_subframe + 6); - ul_frame = (current_subframe > 3) ? ((frame + 1) & 1023) : frame; - } else { - switch (cc->tdd_Config->subframeAssignment) { - case 1: - switch (current_subframe) { - case 9: - case 0: - ul_subframe = 7; - break; - - case 5: - case 7: - ul_subframe = 2; - break; - - } - - break; - - case 3: - switch (current_subframe) { - case 0: - case 5: - case 6: - ul_subframe = 2; - break; - - case 7: - ul_subframe = 3; - break; - - case 8: - ul_subframe = 4; - break; - - case 9: - ul_subframe = 2; - break; - } - - break; - - case 4: - switch (current_subframe) { - case 0: - case 5: - case 6: - case 8: - case 9: - ul_subframe = 2; - break; - - case 7: - ul_subframe = 3; - break; - } - - break; - - case 5: - ul_subframe = 2; - break; - - default: - LOG_E(PHY, - "get_Msg3_harq_pid: Unsupported TDD configuration %d\n", - (int) cc->tdd_Config->subframeAssignment); - AssertFatal(1 == 0, - "get_Msg3_harq_pid: Unsupported TDD configuration"); - break; - } + if (cc->tdd_Config == NULL) { // FDD + ul_subframe = + (current_subframe > + 3) ? (current_subframe - 4) : (current_subframe + 6); + ul_frame = (current_subframe > 3) ? ((frame + 1) & 1023) : frame; + } else { + switch (cc->tdd_Config->subframeAssignment) { + case 1: + switch (current_subframe) { + case 9: + case 0: + ul_subframe = 7; + break; + case 5: + case 7: + ul_subframe = 2; + break; + } + break; + case 3: + switch (current_subframe) { + case 0: + case 5: + case 6: + ul_subframe = 2; + break; + case 7: + ul_subframe = 3; + break; + case 8: + ul_subframe = 4; + break; + case 9: + ul_subframe = 2; + break; + } + break; + case 4: + switch (current_subframe) { + case 0: + case 5: + case 6: + case 8: + case 9: + ul_subframe = 2; + break; + case 7: + ul_subframe = 3; + break; + } + break; + case 5: + ul_subframe = 2; + break; + default: + LOG_E(PHY, + "get_Msg3_harq_pid: Unsupported TDD configuration %d\n", + (int) cc->tdd_Config->subframeAssignment); + AssertFatal(1 == 0, + "get_Msg3_harq_pid: Unsupported TDD configuration"); + break; } + } - return (subframe2harqpid(cc, ul_frame, ul_subframe)); + return (subframe2harqpid(cc, ul_frame, ul_subframe)); } uint32_t pdcchalloc2ulframe(COMMON_channels_t * ccP, uint32_t frame, uint8_t n) { - uint32_t ul_frame; + uint32_t ul_frame; - if ((ccP->tdd_Config) && (ccP->tdd_Config->subframeAssignment == 1) && ((n == 1) || (n == 6))) // tdd_config 0,1 SF 1,5 - ul_frame = (frame + (n == 1 ? 0 : 1)); - else if ((ccP->tdd_Config) && - (ccP->tdd_Config->subframeAssignment == 6) && - ((n == 0) || (n == 1) || (n == 5) || (n == 6))) - ul_frame = (frame + (n >= 5 ? 1 : 0)); - else if ((ccP->tdd_Config) && (ccP->tdd_Config->subframeAssignment == 6) && (n == 9)) // tdd_config 6 SF 9 - ul_frame = (frame + 1); - else - ul_frame = (frame + (n >= 6 ? 1 : 0)); + if ((ccP->tdd_Config) && (ccP->tdd_Config->subframeAssignment == 1) && ((n == 1) || (n == 6))) // tdd_config 0,1 SF 1,5 + ul_frame = (frame + (n == 1 ? 0 : 1)); + else if ((ccP->tdd_Config) && + (ccP->tdd_Config->subframeAssignment == 6) && + ((n == 0) || (n == 1) || (n == 5) || (n == 6))) + ul_frame = (frame + (n >= 5 ? 1 : 0)); + else if ((ccP->tdd_Config) && (ccP->tdd_Config->subframeAssignment == 6) && (n == 9)) // tdd_config 6 SF 9 + ul_frame = (frame + 1); + else + ul_frame = (frame + (n >= 6 ? 1 : 0)); - LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n", frame, n, - ul_frame); - return ul_frame; + LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n", frame, n, + ul_frame); + return ul_frame; } uint8_t pdcchalloc2ulsubframe(COMMON_channels_t * ccP, uint8_t n) { - uint8_t ul_subframe; + uint8_t ul_subframe; - if ((ccP->tdd_Config) && (ccP->tdd_Config->subframeAssignment == 1) && ((n == 1) || (n == 6))) // tdd_config 0,1 SF 1,5 - ul_subframe = ((n + 6) % 10); - else if ((ccP->tdd_Config) && - (ccP->tdd_Config->subframeAssignment == 6) && - ((n == 0) || (n == 1) || (n == 5) || (n == 6))) - ul_subframe = ((n + 7) % 10); - else if ((ccP->tdd_Config) && (ccP->tdd_Config->subframeAssignment == 6) && (n == 9)) // tdd_config 6 SF 9 - ul_subframe = ((n + 5) % 10); - else - ul_subframe = ((n + 4) % 10); + if ((ccP->tdd_Config) && (ccP->tdd_Config->subframeAssignment == 1) && ((n == 1) || (n == 6))) // tdd_config 0,1 SF 1,5 + ul_subframe = ((n + 6) % 10); + else if ((ccP->tdd_Config) && + (ccP->tdd_Config->subframeAssignment == 6) && + ((n == 0) || (n == 1) || (n == 5) || (n == 6))) + ul_subframe = ((n + 7) % 10); + else if ((ccP->tdd_Config) && (ccP->tdd_Config->subframeAssignment == 6) && (n == 9)) // tdd_config 6 SF 9 + ul_subframe = ((n + 5) % 10); + else + ul_subframe = ((n + 4) % 10); - LOG_D(PHY, "subframe %d: PUSCH subframe = %d\n", n, ul_subframe); - return ul_subframe; + LOG_D(PHY, "subframe %d: PUSCH subframe = %d\n", n, ul_subframe); + return ul_subframe; } int is_UL_sf(COMMON_channels_t * ccP, sub_frame_t subframeP) { - // if FDD return dummy value - if (ccP->tdd_Config == NULL) - return (0); - - switch (ccP->tdd_Config->subframeAssignment) { - case 1: - switch (subframeP) { - case 0: - case 4: - case 5: - case 9: - return (0); - break; - - case 2: - case 3: - case 7: - case 8: - return (1); - break; - - default: - return (0); - break; - } - break; - - case 3: - if ((subframeP <= 1) || (subframeP >= 5)) - return (0); - else if ((subframeP > 1) && (subframeP < 5)) - return (1); - else - AssertFatal(1 == 0, "Unknown subframe number\n"); - break; + // if FDD return dummy value + if (ccP->tdd_Config == NULL) + return (0); + switch (ccP->tdd_Config->subframeAssignment) { + case 1: + switch (subframeP) { + case 0: case 4: - if ((subframeP <= 1) || (subframeP >= 4)) - return (0); - else if ((subframeP > 1) && (subframeP < 4)) - return (1); - else - AssertFatal(1 == 0, "Unknown subframe number\n"); - break; - case 5: - if ((subframeP <= 1) || (subframeP >= 3)) - return (0); - else if ((subframeP > 1) && (subframeP < 3)) - return (1); - else - AssertFatal(1 == 0, "Unknown subframe number\n"); - break; - + case 9: + return (0); + break; + case 2: + case 3: + case 7: + case 8: + return (1); + break; default: - AssertFatal(1 == 0, - "subframe %d Unsupported TDD configuration %d\n", - subframeP, (int) ccP->tdd_Config->subframeAssignment); - break; + return (0); + break; } + break; + case 3: + if ((subframeP <= 1) || (subframeP >= 5)) + return (0); + else if ((subframeP > 1) && (subframeP < 5)) + return (1); + else + AssertFatal(1 == 0, "Unknown subframe number\n"); + break; + case 4: + if ((subframeP <= 1) || (subframeP >= 4)) + return (0); + else if ((subframeP > 1) && (subframeP < 4)) + return (1); + else + AssertFatal(1 == 0, "Unknown subframe number\n"); + break; + case 5: + if ((subframeP <= 1) || (subframeP >= 3)) + return (0); + else if ((subframeP > 1) && (subframeP < 3)) + return (1); + else + AssertFatal(1 == 0, "Unknown subframe number\n"); + break; + default: + AssertFatal(1 == 0, + "subframe %d Unsupported TDD configuration %d\n", + subframeP, (int) ccP->tdd_Config->subframeAssignment); + break; + } } uint16_t get_pucch1_absSF(COMMON_channels_t * cc, uint16_t dlsch_absSF) { - uint16_t sf, f, nextf; + uint16_t sf, f, nextf; - if (cc->tdd_Config == NULL) { //FDD n+4 - return ((dlsch_absSF + 4) % 10240); - } else { - sf = dlsch_absSF % 10; - f = dlsch_absSF / 10; - nextf = (f + 1) & 1023; + if (cc->tdd_Config == NULL) { //FDD n+4 + return ((dlsch_absSF + 4) % 10240); + } else { + sf = dlsch_absSF % 10; + f = dlsch_absSF / 10; + nextf = (f + 1) & 1023; - switch (cc->tdd_Config->subframeAssignment) { - case 0: - AssertFatal(1 == 0, "SFA 0 to be filled in now, :-)\n"); - break; - case 1: - if ((sf == 5) || (sf == 6)) - return ((10 * nextf) + 2); // ACK/NAK in SF 2 next frame - else if (sf == 9) - return ((10 * nextf) + 3); // ACK/NAK in SF 3 next frame - else if ((sf == 0) || (sf == 1)) - return ((10 * f) + 2); // ACK/NAK in SF 7 same frame - else - AssertFatal(1 == 0, - "Impossible dlsch subframe %d for TDD configuration 3\n", - sf); - break; - case 2: - if ((sf == 4) || (sf == 5) || (sf == 6) || (sf == 8)) - return ((10 * nextf) + 2); // ACK/NAK in SF 2 next frame - else if (sf == 9) - return ((10 * nextf) + 7); // ACK/NAK in SF 7 next frame - else if ((sf == 0) || (sf == 1) || (sf == 3)) - return ((10 * f) + 7); // ACK/NAK in SF 7 same frame - else - AssertFatal(1 == 0, - "Impossible dlsch subframe %d for TDD configuration 3\n", - sf); - break; - case 3: - if ((sf == 5) || (sf == 6) || (sf == 7) || (sf == 8) - || (sf == 9)) - return ((10 * nextf) + (sf >> 1)); // ACK/NAK in 2,3,4 resp. next frame - else if (sf == 1) - return ((10 * nextf) + 2); // ACK/NAK in 2 next frame - else if (sf == 0) - return ((10 * f) + 4); // ACK/NAK in 4 same frame - else - AssertFatal(1 == 0, - "Impossible dlsch subframe %d for TDD configuration 3\n", - sf); - break; - case 4: - if ((sf == 6) || (sf == 7) || (sf == 8) || (sf == 9)) - return (((10 * nextf) + 3) % 10240); // ACK/NAK in SF 3 next frame - else if ((sf == 0) || (sf == 1) || (sf == 4) || (sf == 5)) - return (((10 * nextf) + 2) % 10240); // ACK/NAK in SF 2 next frame - else - AssertFatal(1 == 0, - "Impossible dlsch subframe %d for TDD configuration 4\n", - sf); - break; - case 5: - if ((sf == 0) || (sf == 1) || (sf == 3) || (sf == 4) - || (sf == 5) || (sf == 6) || (sf == 7) || (sf == 8)) - return (((10 * nextf) + 2) % 10240); // ACK/NAK in SF 3 next frame - else if (sf == 9) - return (((10 * (1 + nextf)) + 2) % 10240); // ACK/NAK in SF 2 next frame - else - AssertFatal(1 == 0, - "Impossible dlsch subframe %d for TDD configuration 5\n", - sf); - break; - case 6: - AssertFatal(1 == 0, "SFA 6 To be filled in now, :-)\n"); - break; - default: - AssertFatal(1 == 0, "Illegal TDD subframe Assigment %d\n", - (int) cc->tdd_Config->subframeAssignment); - break; - } + switch (cc->tdd_Config->subframeAssignment) { + case 0: + AssertFatal(1 == 0, "SFA 0 to be filled in now, :-)\n"); + break; + case 1: + if ((sf == 5) || (sf == 6)) + return ((10 * nextf) + 2); // ACK/NAK in SF 2 next frame + else if (sf == 9) + return ((10 * nextf) + 3); // ACK/NAK in SF 3 next frame + else if ((sf == 0) || (sf == 1)) + return ((10 * f) + 2); // ACK/NAK in SF 7 same frame + else + AssertFatal(1 == 0, + "Impossible dlsch subframe %d for TDD configuration 3\n", + sf); + break; + case 2: + if ((sf == 4) || (sf == 5) || (sf == 6) || (sf == 8)) + return ((10 * nextf) + 2); // ACK/NAK in SF 2 next frame + else if (sf == 9) + return ((10 * nextf) + 7); // ACK/NAK in SF 7 next frame + else if ((sf == 0) || (sf == 1) || (sf == 3)) + return ((10 * f) + 7); // ACK/NAK in SF 7 same frame + else + AssertFatal(1 == 0, + "Impossible dlsch subframe %d for TDD configuration 3\n", + sf); + break; + case 3: + if ((sf == 5) || (sf == 6) || (sf == 7) || (sf == 8) + || (sf == 9)) + return ((10 * nextf) + (sf >> 1)); // ACK/NAK in 2,3,4 resp. next frame + else if (sf == 1) + return ((10 * nextf) + 2); // ACK/NAK in 2 next frame + else if (sf == 0) + return ((10 * f) + 4); // ACK/NAK in 4 same frame + else + AssertFatal(1 == 0, + "Impossible dlsch subframe %d for TDD configuration 3\n", + sf); + break; + case 4: + if ((sf == 6) || (sf == 7) || (sf == 8) || (sf == 9)) + return (((10 * nextf) + 3) % 10240); // ACK/NAK in SF 3 next frame + else if ((sf == 0) || (sf == 1) || (sf == 4) || (sf == 5)) + return (((10 * nextf) + 2) % 10240); // ACK/NAK in SF 2 next frame + else + AssertFatal(1 == 0, + "Impossible dlsch subframe %d for TDD configuration 4\n", + sf); + break; + case 5: + if ((sf == 0) || (sf == 1) || (sf == 3) || (sf == 4) + || (sf == 5) || (sf == 6) || (sf == 7) || (sf == 8)) + return (((10 * nextf) + 2) % 10240); // ACK/NAK in SF 3 next frame + else if (sf == 9) + return (((10 * (1 + nextf)) + 2) % 10240); // ACK/NAK in SF 2 next frame + else + AssertFatal(1 == 0, + "Impossible dlsch subframe %d for TDD configuration 5\n", + sf); + break; + case 6: + AssertFatal(1 == 0, "SFA 6 To be filled in now, :-)\n"); + break; + default: + AssertFatal(1 == 0, "Illegal TDD subframe Assigment %d\n", + (int) cc->tdd_Config->subframeAssignment); + break; } - AssertFatal(1 == 0, "Shouldn't get here\n"); + } + AssertFatal(1 == 0, "Shouldn't get here\n"); } void get_srs_pos(COMMON_channels_t * cc, uint16_t isrs, uint16_t * psrsPeriodicity, uint16_t * psrsOffset) { - if (cc->tdd_Config) { // TDD - AssertFatal(isrs >= 10, "2 ms SRS periodicity not supported"); + if (cc->tdd_Config) { // TDD + AssertFatal(isrs >= 10, "2 ms SRS periodicity not supported"); - if ((isrs > 9) && (isrs < 15)) { - *psrsPeriodicity = 5; - *psrsOffset = isrs - 10; - } - if ((isrs > 14) && (isrs < 25)) { - *psrsPeriodicity = 10; - *psrsOffset = isrs - 15; - } - if ((isrs > 24) && (isrs < 45)) { - *psrsPeriodicity = 20; - *psrsOffset = isrs - 25; - } - if ((isrs > 44) && (isrs < 85)) { - *psrsPeriodicity = 40; - *psrsOffset = isrs - 45; - } - if ((isrs > 84) && (isrs < 165)) { - *psrsPeriodicity = 80; - *psrsOffset = isrs - 85; - } - if ((isrs > 164) && (isrs < 325)) { - *psrsPeriodicity = 160; - *psrsOffset = isrs - 165; - } - if ((isrs > 324) && (isrs < 645)) { - *psrsPeriodicity = 320; - *psrsOffset = isrs - 325; - } - - AssertFatal(isrs <= 644, "Isrs out of range %d>644\n", isrs); - } // TDD - else { // FDD - if (isrs < 2) { - *psrsPeriodicity = 2; - *psrsOffset = isrs; - } - if ((isrs > 1) && (isrs < 7)) { - *psrsPeriodicity = 5; - *psrsOffset = isrs - 2; - } - if ((isrs > 6) && (isrs < 17)) { - *psrsPeriodicity = 10; - *psrsOffset = isrs - 7; - } - if ((isrs > 16) && (isrs < 37)) { - *psrsPeriodicity = 20; - *psrsOffset = isrs - 17; - } - if ((isrs > 36) && (isrs < 77)) { - *psrsPeriodicity = 40; - *psrsOffset = isrs - 37; - } - if ((isrs > 76) && (isrs < 157)) { - *psrsPeriodicity = 80; - *psrsOffset = isrs - 77; - } - if ((isrs > 156) && (isrs < 317)) { - *psrsPeriodicity = 160; - *psrsOffset = isrs - 157; - } - if ((isrs > 316) && (isrs < 637)) { - *psrsPeriodicity = 320; - *psrsOffset = isrs - 317; - } - AssertFatal(isrs <= 636, "Isrs out of range %d>636\n", isrs); + if ((isrs > 9) && (isrs < 15)) { + *psrsPeriodicity = 5; + *psrsOffset = isrs - 10; } + if ((isrs > 14) && (isrs < 25)) { + *psrsPeriodicity = 10; + *psrsOffset = isrs - 15; + } + if ((isrs > 24) && (isrs < 45)) { + *psrsPeriodicity = 20; + *psrsOffset = isrs - 25; + } + if ((isrs > 44) && (isrs < 85)) { + *psrsPeriodicity = 40; + *psrsOffset = isrs - 45; + } + if ((isrs > 84) && (isrs < 165)) { + *psrsPeriodicity = 80; + *psrsOffset = isrs - 85; + } + if ((isrs > 164) && (isrs < 325)) { + *psrsPeriodicity = 160; + *psrsOffset = isrs - 165; + } + if ((isrs > 324) && (isrs < 645)) { + *psrsPeriodicity = 320; + *psrsOffset = isrs - 325; + } + + AssertFatal(isrs <= 644, "Isrs out of range %d>644\n", isrs); + } // TDD + else { // FDD + if (isrs < 2) { + *psrsPeriodicity = 2; + *psrsOffset = isrs; + } + if ((isrs > 1) && (isrs < 7)) { + *psrsPeriodicity = 5; + *psrsOffset = isrs - 2; + } + if ((isrs > 6) && (isrs < 17)) { + *psrsPeriodicity = 10; + *psrsOffset = isrs - 7; + } + if ((isrs > 16) && (isrs < 37)) { + *psrsPeriodicity = 20; + *psrsOffset = isrs - 17; + } + if ((isrs > 36) && (isrs < 77)) { + *psrsPeriodicity = 40; + *psrsOffset = isrs - 37; + } + if ((isrs > 76) && (isrs < 157)) { + *psrsPeriodicity = 80; + *psrsOffset = isrs - 77; + } + if ((isrs > 156) && (isrs < 317)) { + *psrsPeriodicity = 160; + *psrsOffset = isrs - 157; + } + if ((isrs > 316) && (isrs < 637)) { + *psrsPeriodicity = 320; + *psrsOffset = isrs - 317; + } + AssertFatal(isrs <= 636, "Isrs out of range %d>636\n", isrs); + } } void @@ -744,83 +719,83 @@ get_csi_params(COMMON_channels_t * cc, struct CQI_ReportPeriodic *cqi_ReportPeriodic, uint16_t * Npd, uint16_t * N_OFFSET_CQI, int *H) { - uint16_t cqi_PMI_ConfigIndex = - cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex; - uint8_t Jtab[6] = { 0, 2, 2, 3, 4, 4 }; + uint16_t cqi_PMI_ConfigIndex = + cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex; + uint8_t Jtab[6] = { 0, 2, 2, 3, 4, 4 }; - AssertFatal(cqi_ReportPeriodic != NULL, - "cqi_ReportPeriodic is null!\n"); + AssertFatal(cqi_ReportPeriodic != NULL, + "cqi_ReportPeriodic is null!\n"); - if (cc->tdd_Config == NULL) { //FDD - if (cqi_PMI_ConfigIndex <= 1) { // 2 ms CQI_PMI period - *Npd = 2; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex; - } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period - *Npd = 5; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 2; - } else if (cqi_PMI_ConfigIndex <= 16) { // 10ms CQI_PMI period - *Npd = 10; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 7; - } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period - *Npd = 20; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 17; - } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period - *Npd = 40; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 37; - } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period - *Npd = 80; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 77; - } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period - *Npd = 160; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 157; - } else if (cqi_PMI_ConfigIndex > 317) { + if (cc->tdd_Config == NULL) { //FDD + if (cqi_PMI_ConfigIndex <= 1) { // 2 ms CQI_PMI period + *Npd = 2; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex; + } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period + *Npd = 5; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 2; + } else if (cqi_PMI_ConfigIndex <= 16) { // 10ms CQI_PMI period + *Npd = 10; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 7; + } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period + *Npd = 20; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 17; + } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period + *Npd = 40; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 37; + } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period + *Npd = 80; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 77; + } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period + *Npd = 160; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 157; + } else if (cqi_PMI_ConfigIndex > 317) { - if (cqi_PMI_ConfigIndex <= 349) { // 32 ms CQI_PMI period - *Npd = 32; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 318; - } else if (cqi_PMI_ConfigIndex <= 413) { // 64 ms CQI_PMI period - *Npd = 64; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 350; - } else if (cqi_PMI_ConfigIndex <= 541) { // 128 ms CQI_PMI period - *Npd = 128; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 414; - } - } - } else { // TDD - if (cqi_PMI_ConfigIndex == 0) { // all UL subframes - *Npd = 1; - *N_OFFSET_CQI = 0; - } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period - *Npd = 5; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 1; - } else if (cqi_PMI_ConfigIndex <= 16) { // 10ms CQI_PMI period - *Npd = 10; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 6; - } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period - *Npd = 20; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 16; - } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period - *Npd = 40; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 36; - } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period - *Npd = 80; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 76; - } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period - *Npd = 160; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 156; - } + if (cqi_PMI_ConfigIndex <= 349) { // 32 ms CQI_PMI period + *Npd = 32; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 318; + } else if (cqi_PMI_ConfigIndex <= 413) { // 64 ms CQI_PMI period + *Npd = 64; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 350; + } else if (cqi_PMI_ConfigIndex <= 541) { // 128 ms CQI_PMI period + *Npd = 128; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 414; + } } + } else { // TDD + if (cqi_PMI_ConfigIndex == 0) { // all UL subframes + *Npd = 1; + *N_OFFSET_CQI = 0; + } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period + *Npd = 5; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 1; + } else if (cqi_PMI_ConfigIndex <= 16) { // 10ms CQI_PMI period + *Npd = 10; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 6; + } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period + *Npd = 20; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 16; + } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period + *Npd = 40; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 36; + } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period + *Npd = 80; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 76; + } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period + *Npd = 160; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 156; + } + } - // get H - if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic. - present == - CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) - *H = 1 + - (Jtab[cc->mib->message.dl_Bandwidth] * - cqi_ReportPeriodic->choice.setup. - cqi_FormatIndicatorPeriodic.choice.subbandCQI.k); - else - *H = 1; + // get H + if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic. + present == + CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) + *H = 1 + + (Jtab[cc->mib->message.dl_Bandwidth] * + cqi_ReportPeriodic->choice.setup. + cqi_FormatIndicatorPeriodic.choice.subbandCQI.k); + else + *H = 1; } uint8_t @@ -829,127 +804,127 @@ get_dl_cqi_pmi_size_pusch(COMMON_channels_t * cc, uint8_t tmode, CQI_ReportModeAperiodic_t * cqi_ReportModeAperiodic) { - int Ntab[6] = { 0, 4, 7, 9, 10, 13 }; - int N = Ntab[cc->mib->message.dl_Bandwidth]; - int Ltab_uesel[6] = { 0, 6, 9, 13, 15, 18 }; - int L = Ltab_uesel[cc->mib->message.dl_Bandwidth]; + int Ntab[6] = { 0, 4, 7, 9, 10, 13 }; + int N = Ntab[cc->mib->message.dl_Bandwidth]; + int Ltab_uesel[6] = { 0, 6, 9, 13, 15, 18 }; + int L = Ltab_uesel[cc->mib->message.dl_Bandwidth]; - AssertFatal(cqi_ReportModeAperiodic != NULL, - "cqi_ReportPeriodic is null!\n"); + AssertFatal(cqi_ReportModeAperiodic != NULL, + "cqi_ReportPeriodic is null!\n"); - switch (*cqi_ReportModeAperiodic) { - case CQI_ReportModeAperiodic_rm12: - AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 - || tmode == 10, - "Illegal TM (%d) for CQI_ReportModeAperiodic_rm12\n", - tmode); - AssertFatal(cc->p_eNB <= 4, - "only up to 4 antenna ports supported here\n"); - if (ri == 1 && cc->p_eNB == 2) - return (4 + (N << 1)); - else if (ri == 2 && cc->p_eNB == 2) - return (8 + N); - else if (ri == 1 && cc->p_eNB == 4) - return (4 + (N << 2)); - else if (ri > 1 && cc->p_eNB == 4) - return (8 + (N << 2)); - break; - case CQI_ReportModeAperiodic_rm20: - // Table 5.2.2.6.3-1 (36.212) - AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 || tmode == 7 - || tmode == 9 - || tmode == 10, - "Illegal TM (%d) for CQI_ReportModeAperiodic_rm20\n", - tmode); - AssertFatal(tmode != 9 - && tmode != 10, - "TM9/10 will be handled later for CQI_ReportModeAperiodic_rm20\n"); - return (4 + 2 + L); - break; - case CQI_ReportModeAperiodic_rm22: - // Table 5.2.2.6.3-2 (36.212) - AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 - || tmode == 10, - "Illegal TM (%d) for CQI_ReportModeAperiodic_rm22\n", - tmode); - AssertFatal(tmode != 9 - && tmode != 10, - "TM9/10 will be handled later for CQI_ReportModeAperiodic_rm22\n"); - if (ri == 1 && cc->p_eNB == 2) - return (4 + 2 + 0 + 0 + L + 4); - if (ri == 2 && cc->p_eNB == 2) - return (4 + 2 + 4 + 2 + L + 2); - if (ri == 1 && cc->p_eNB == 4) - return (4 + 2 + 0 + 0 + L + 8); - if (ri >= 2 && cc->p_eNB == 4) - return (4 + 2 + 4 + 2 + L + 8); - break; - case CQI_ReportModeAperiodic_rm30: - // Table 5.2.2.6.2-1 (36.212) - AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 || tmode == 7 - || tmode == 8 || tmode == 9 - || tmode == 10, - "Illegal TM (%d) for CQI_ReportModeAperiodic_rm30\n", - tmode); - AssertFatal(tmode != 8 && tmode != 9 - && tmode != 10, - "TM8/9/10 will be handled later for CQI_ReportModeAperiodic_rm30\n"); - return (4 + (N << 1)); - break; - case CQI_ReportModeAperiodic_rm31: - // Table 5.2.2.6.2-2 (36.212) - AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 - || tmode == 10, - "Illegal TM (%d) for CQI_ReportModeAperiodic_rm31\n", - tmode); - AssertFatal(tmode != 8 && tmode != 9 - && tmode != 10, - "TM8/9/10 will be handled later for CQI_ReportModeAperiodic_rm31\n"); - if (ri == 1 && cc->p_eNB == 2) - return (4 + (N << 1) + 0 + 0 + 2); - else if (ri == 2 && cc->p_eNB == 2) - return (4 + (N << 1) + 4 + (N << 1) + 1); - else if (ri == 1 && cc->p_eNB == 4) - return (4 + (N << 1) + 0 + 0 + 4); - else if (ri >= 2 && cc->p_eNB == 4) - return (4 + (N << 1) + 4 + (N << 1) + 4); - break; - case CQI_ReportModeAperiodic_rm32_v1250: - AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 - || tmode == 10, - "Illegal TM (%d) for CQI_ReportModeAperiodic_rm32\n", - tmode); - AssertFatal(1 == 0, - "CQI_ReportModeAperiodic_rm32_v1250 not supported yet\n"); - break; - case CQI_ReportModeAperiodic_rm10_v1310: - // Table 5.2.2.6.1-1F/G (36.212) - if (ri == 1) - return (4); // F - else - return (7); // G - break; - case CQI_ReportModeAperiodic_rm11_v1310: - // Table 5.2.2.6.1-1H (36.212) - AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 - || tmode == 10, - "Illegal TM (%d) for CQI_ReportModeAperiodic_rm11\n", - tmode); - AssertFatal(cc->p_eNB <= 4, - "only up to 4 antenna ports supported here\n"); - if (ri == 1 && cc->p_eNB == 2) - return (4 + 0 + 2); - else if (ri == 2 && cc->p_eNB == 2) - return (4 + 4 + 1); - else if (ri == 1 && cc->p_eNB == 4) - return (4 + 0 + 4); - else if (ri > 1 && cc->p_eNB == 4) - return (4 + 4 + 4); + switch (*cqi_ReportModeAperiodic) { + case CQI_ReportModeAperiodic_rm12: + AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 + || tmode == 10, + "Illegal TM (%d) for CQI_ReportModeAperiodic_rm12\n", + tmode); + AssertFatal(cc->p_eNB <= 4, + "only up to 4 antenna ports supported here\n"); + if (ri == 1 && cc->p_eNB == 2) + return (4 + (N << 1)); + else if (ri == 2 && cc->p_eNB == 2) + return (8 + N); + else if (ri == 1 && cc->p_eNB == 4) + return (4 + (N << 2)); + else if (ri > 1 && cc->p_eNB == 4) + return (8 + (N << 2)); + break; + case CQI_ReportModeAperiodic_rm20: + // Table 5.2.2.6.3-1 (36.212) + AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 || tmode == 7 + || tmode == 9 + || tmode == 10, + "Illegal TM (%d) for CQI_ReportModeAperiodic_rm20\n", + tmode); + AssertFatal(tmode != 9 + && tmode != 10, + "TM9/10 will be handled later for CQI_ReportModeAperiodic_rm20\n"); + return (4 + 2 + L); + break; + case CQI_ReportModeAperiodic_rm22: + // Table 5.2.2.6.3-2 (36.212) + AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 + || tmode == 10, + "Illegal TM (%d) for CQI_ReportModeAperiodic_rm22\n", + tmode); + AssertFatal(tmode != 9 + && tmode != 10, + "TM9/10 will be handled later for CQI_ReportModeAperiodic_rm22\n"); + if (ri == 1 && cc->p_eNB == 2) + return (4 + 2 + 0 + 0 + L + 4); + if (ri == 2 && cc->p_eNB == 2) + return (4 + 2 + 4 + 2 + L + 2); + if (ri == 1 && cc->p_eNB == 4) + return (4 + 2 + 0 + 0 + L + 8); + if (ri >= 2 && cc->p_eNB == 4) + return (4 + 2 + 4 + 2 + L + 8); + break; + case CQI_ReportModeAperiodic_rm30: + // Table 5.2.2.6.2-1 (36.212) + AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 || tmode == 7 + || tmode == 8 || tmode == 9 + || tmode == 10, + "Illegal TM (%d) for CQI_ReportModeAperiodic_rm30\n", + tmode); + AssertFatal(tmode != 8 && tmode != 9 + && tmode != 10, + "TM8/9/10 will be handled later for CQI_ReportModeAperiodic_rm30\n"); + return (4 + (N << 1)); + break; + case CQI_ReportModeAperiodic_rm31: + // Table 5.2.2.6.2-2 (36.212) + AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 + || tmode == 10, + "Illegal TM (%d) for CQI_ReportModeAperiodic_rm31\n", + tmode); + AssertFatal(tmode != 8 && tmode != 9 + && tmode != 10, + "TM8/9/10 will be handled later for CQI_ReportModeAperiodic_rm31\n"); + if (ri == 1 && cc->p_eNB == 2) + return (4 + (N << 1) + 0 + 0 + 2); + else if (ri == 2 && cc->p_eNB == 2) + return (4 + (N << 1) + 4 + (N << 1) + 1); + else if (ri == 1 && cc->p_eNB == 4) + return (4 + (N << 1) + 0 + 0 + 4); + else if (ri >= 2 && cc->p_eNB == 4) + return (4 + (N << 1) + 4 + (N << 1) + 4); + break; + case CQI_ReportModeAperiodic_rm32_v1250: + AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 + || tmode == 10, + "Illegal TM (%d) for CQI_ReportModeAperiodic_rm32\n", + tmode); + AssertFatal(1 == 0, + "CQI_ReportModeAperiodic_rm32_v1250 not supported yet\n"); + break; + case CQI_ReportModeAperiodic_rm10_v1310: + // Table 5.2.2.6.1-1F/G (36.212) + if (ri == 1) + return (4); // F + else + return (7); // G + break; + case CQI_ReportModeAperiodic_rm11_v1310: + // Table 5.2.2.6.1-1H (36.212) + AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 + || tmode == 10, + "Illegal TM (%d) for CQI_ReportModeAperiodic_rm11\n", + tmode); + AssertFatal(cc->p_eNB <= 4, + "only up to 4 antenna ports supported here\n"); + if (ri == 1 && cc->p_eNB == 2) + return (4 + 0 + 2); + else if (ri == 2 && cc->p_eNB == 2) + return (4 + 4 + 1); + else if (ri == 1 && cc->p_eNB == 4) + return (4 + 0 + 4); + else if (ri > 1 && cc->p_eNB == 4) + return (4 + 4 + 4); - break; - } - AssertFatal(1 == 0, "Shouldn't get here\n"); - return (0); + break; + } + AssertFatal(1 == 0, "Shouldn't get here\n"); + return (0); } uint8_t @@ -957,103 +932,84 @@ get_rel8_dl_cqi_pmi_size(UE_sched_ctrl * sched_ctl, int CC_idP, COMMON_channels_t * cc, uint8_t tmode, struct CQI_ReportPeriodic * cqi_ReportPeriodic) { - int no_pmi = 0; - // Ltab[6] = {0,log2(15/4/2),log2(25/4/2),log2(50/6/3),log2(75/8/4),log2(100/8/4)}; + int no_pmi = 0; + // Ltab[6] = {0,log2(15/4/2),log2(25/4/2),log2(50/6/3),log2(75/8/4),log2(100/8/4)}; - uint8_t Ltab[6] = { 0, 1, 2, 2, 2, 2 }; - uint8_t ri = sched_ctl->periodic_ri_received[CC_idP]; + uint8_t Ltab[6] = { 0, 1, 2, 2, 2, 2 }; + uint8_t ri = sched_ctl->periodic_ri_received[CC_idP]; - AssertFatal(cqi_ReportPeriodic != NULL, - "cqi_ReportPeriodic is null!\n"); - AssertFatal(cqi_ReportPeriodic->present != - CQI_ReportPeriodic_PR_NOTHING, - "cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_NOTHING!\n"); - AssertFatal(cqi_ReportPeriodic->choice. - setup.cqi_FormatIndicatorPeriodic.present != - CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING, - "cqi_ReportPeriodic->cqi_FormatIndicatorPeriodic.choice.setup.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING!\n"); + AssertFatal(cqi_ReportPeriodic != NULL, + "cqi_ReportPeriodic is null!\n"); + AssertFatal(cqi_ReportPeriodic->present != CQI_ReportPeriodic_PR_NOTHING, + "cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_NOTHING!\n"); + AssertFatal(cqi_ReportPeriodic->choice. + setup.cqi_FormatIndicatorPeriodic.present != CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING, + "cqi_ReportPeriodic->cqi_FormatIndicatorPeriodic.choice.setup.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING!\n"); - switch (tmode) { - case 1: - case 2: - case 5: - case 6: - case 7: - no_pmi = 1; - break; - default: - no_pmi = 0; - } + switch (tmode) { + case 1: + case 2: + case 5: + case 6: + case 7: + no_pmi = 1; + break; + default: + no_pmi = 0; + } - if ((cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic. - present == - CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_widebandCQI) - || (sched_ctl->feedback_cnt[CC_idP] == 0)) { - // send wideband report every opportunity if wideband reporting mode is selected, else every H opportunities - if (no_pmi == 1) - return (4); - else if ((cc->p_eNB == 2) && (ri == 1)) - return (6); - else if ((cc->p_eNB == 2) && (ri == 2)) - return (8); - else if ((cc->p_eNB == 4) && (ri == 1)) - return (8); - else if ((cc->p_eNB == 4) && (ri == 2)) - return (11); - else - AssertFatal(1 == 0, - "illegal combination p %d, ri %d, no_pmi %d\n", - cc->p_eNB, ri, no_pmi); - } else if (cqi_ReportPeriodic->choice. - setup.cqi_FormatIndicatorPeriodic.present == - CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) - { - if ((no_pmi == 1) || ri == 1) - return (4 + Ltab[cc->mib->message.dl_Bandwidth]); - else - return (7 + Ltab[cc->mib->message.dl_Bandwidth]); - } + if ((cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_widebandCQI) + || (sched_ctl->feedback_cnt[CC_idP] == 0)) { + // send wideband report every opportunity if wideband reporting mode is selected, else every H opportunities + if (no_pmi == 1) return (4); + else if ((cc->p_eNB == 2) && (ri == 1)) return (6); + else if ((cc->p_eNB == 2) && (ri == 2)) return (8); + else if ((cc->p_eNB == 4) && (ri == 1)) return (8); + else if ((cc->p_eNB == 4) && (ri == 2)) return (11); + else + AssertFatal(1 == 0, + "illegal combination p %d, ri %d, no_pmi %d\n", + cc->p_eNB, ri, no_pmi); + } else if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) { + if ((no_pmi == 1) || ri == 1) return (4 + Ltab[cc->mib->message.dl_Bandwidth]); + else return (7 + Ltab[cc->mib->message.dl_Bandwidth]); + } - AssertFatal(1 == 0, - "Shouldn't get here : cqi_ReportPeriodic->present %d\n", - cqi_ReportPeriodic->choice. - setup.cqi_FormatIndicatorPeriodic.present); + AssertFatal(1 == 0, + "Shouldn't get here : cqi_ReportPeriodic->present %d\n", + cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present); } void -fill_nfapi_dl_dci_1A(nfapi_dl_config_request_pdu_t * dl_config_pdu, - uint8_t aggregation_level, - uint16_t rnti, - uint8_t rnti_type, - uint8_t harq_process, - uint8_t tpc, - uint16_t resource_block_coding, - uint8_t mcs, uint8_t ndi, uint8_t rv, - uint8_t vrb_flag) +fill_nfapi_dl_dci_1A(nfapi_dl_config_request_pdu_t *dl_config_pdu, + uint8_t aggregation_level, + uint16_t rnti, + uint8_t rnti_type, + uint8_t harq_process, + uint8_t tpc, + uint16_t resource_block_coding, + uint8_t mcs, + uint8_t ndi, + uint8_t rv, + uint8_t vrb_flag) { - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = - NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = - NFAPI_DL_DCI_FORMAT_1A; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = - aggregation_level; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = rnti_type; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_process; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; // no TPC - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = - resource_block_coding; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = ndi; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = rv; - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = vrb_flag; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = aggregation_level; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = rnti_type; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_process; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = resource_block_coding; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = ndi; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = rv; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = vrb_flag; } void @@ -1061,436 +1017,349 @@ program_dlsch_acknak(module_id_t module_idP, int CC_idP, int UE_idP, frame_t frameP, sub_frame_t subframeP, uint8_t cce_idx) { - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc = eNB->common_channels; - UE_list_t *UE_list = &eNB->UE_list; - rnti_t rnti = UE_RNTI(module_idP, UE_idP); - nfapi_ul_config_request_body_t *ul_req; - nfapi_ul_config_request_pdu_t *ul_config_pdu; - - int use_simultaneous_pucch_pusch = 0; - nfapi_ul_config_ulsch_harq_information *ulsch_harq_information = NULL; - nfapi_ul_config_harq_information *harq_information = NULL; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = eNB->common_channels; + UE_list_t *UE_list = &eNB->UE_list; + rnti_t rnti = UE_RNTI(module_idP, UE_idP); + nfapi_ul_config_request_body_t *ul_req; + nfapi_ul_config_request_pdu_t *ul_config_pdu; + int use_simultaneous_pucch_pusch = 0; + nfapi_ul_config_ulsch_harq_information *ulsch_harq_information = NULL; + nfapi_ul_config_harq_information *harq_information = NULL; #if defined(Rel10) || defined(Rel14) - if ((UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated-> - ext2) - && (UE_list->UE_template[CC_idP][UE_idP]. - physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020) - && (UE_list->UE_template[CC_idP][UE_idP]. - physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020-> - simultaneousPUCCH_PUSCH_r10) - && (*UE_list->UE_template[CC_idP][UE_idP]. - physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020-> - simultaneousPUCCH_PUSCH_r10 == - PUCCH_ConfigDedicated_v1020__simultaneousPUCCH_PUSCH_r10_true)) - use_simultaneous_pucch_pusch = 1; + if ((UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2) + && (UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020) + && (UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020->simultaneousPUCCH_PUSCH_r10) + && (*UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020->simultaneousPUCCH_PUSCH_r10 == PUCCH_ConfigDedicated_v1020__simultaneousPUCCH_PUSCH_r10_true)) + use_simultaneous_pucch_pusch = 1; #endif - // pucch1 and pusch feedback is similar, namely in n+k subframes from now - // This is used in the following "if/else" condition to check if there isn't or is already an UL grant in n+k - int16_t ul_absSF = - get_pucch1_absSF(&cc[CC_idP], subframeP + (10 * frameP)); + // pucch1 and pusch feedback is similar, namely in n+k subframes from now + // This is used in the following "if/else" condition to check if there isn't or is already an UL grant in n+k + int16_t ul_absSF = get_pucch1_absSF(&cc[CC_idP], subframeP + (10 * frameP)); - if ((ul_config_pdu = has_ul_grant(module_idP, CC_idP, - ul_absSF, rnti)) == NULL) { - // no UL grant so - // Program ACK/NAK alone Format 1a/b or 3 + if ((ul_config_pdu = has_ul_grant(module_idP, CC_idP,ul_absSF, rnti)) == NULL) { + // no UL grant so + // Program ACK/NAK alone Format 1a/b or 3 - ul_req = - &RC.mac[module_idP]->UL_req_tmp[CC_idP][ul_absSF % - 10]. - ul_config_request_body; - ul_config_pdu = - &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; - // Do PUCCH - fill_nfapi_uci_acknak(module_idP, - CC_idP, - rnti, (frameP * 10) + subframeP, cce_idx); - } else { - /* there is already an existing UL grant so update it if needed - * on top of some other UL resource (PUSCH,combined SR/CQI/HARQ on PUCCH, etc) - */ - switch (ul_config_pdu->pdu_type) { + ul_req = &RC.mac[module_idP]->UL_req_tmp[CC_idP][ul_absSF %10].ul_config_request_body; + ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; + // Do PUCCH + fill_nfapi_uci_acknak(module_idP, + CC_idP, + rnti, (frameP * 10) + subframeP, cce_idx); + } else { + /* there is already an existing UL grant so update it if needed + * on top of some other UL resource (PUSCH,combined SR/CQI/HARQ on PUCCH, etc) + */ + switch (ul_config_pdu->pdu_type) { + + /* [ulsch] to [ulsch + harq] or [ulsch + harq on pucch] */ + + case NFAPI_UL_CONFIG_ULSCH_PDU_TYPE: + if (use_simultaneous_pucch_pusch == 1) { + // Convert it to an NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE + harq_information = &ul_config_pdu->ulsch_uci_harq_pdu.harq_information; + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE; + LOG_D(MAC, + "Frame %d, Subframe %d: Switched UCI HARQ to ULSCH UCI HARQ\n", + frameP, subframeP); + } else { + // Convert it to an NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE + ulsch_harq_information = &ul_config_pdu->ulsch_harq_pdu.harq_information; + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; + ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; + ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured + ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks; // we don't change the number of resource blocks across retransmissions yet + LOG_D(MAC, + "Frame %d, Subframe %d: Switched UCI HARQ to ULSCH HARQ\n", + frameP, subframeP); + } + break; + case NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE: + AssertFatal(use_simultaneous_pucch_pusch == 1, + "Cannot be NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE, simultaneous_pucch_pusch is active"); + break; + case NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE: + AssertFatal(use_simultaneous_pucch_pusch == 0, + "Cannot be NFAPI_UL_CONFIG_ULSCH_UCI_PDU_TYPE, simultaneous_pucch_pusch is inactive\n"); + break; - /* [ulsch] to [ulsch + harq] or [ulsch + harq on pucch] */ + /* [ulsch + cqi] to [ulsch + cqi + harq] */ - case NFAPI_UL_CONFIG_ULSCH_PDU_TYPE: - if (use_simultaneous_pucch_pusch == 1) { - // Convert it to an NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE - harq_information = - &ul_config_pdu->ulsch_uci_harq_pdu.harq_information; - ul_config_pdu->pdu_type = - NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE; - LOG_D(MAC, - "Frame %d, Subframe %d: Switched UCI HARQ to ULSCH UCI HARQ\n", - frameP, subframeP); - } else { - // Convert it to an NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE - ulsch_harq_information = - &ul_config_pdu->ulsch_harq_pdu.harq_information; - ul_config_pdu->pdu_type = - NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; - ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag=NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; - ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured - ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks; // we don't change the number of resource blocks across retransmissions yet - LOG_D(MAC, - "Frame %d, Subframe %d: Switched UCI HARQ to ULSCH HARQ\n", - frameP, subframeP); - } - break; - case NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE: - AssertFatal(use_simultaneous_pucch_pusch == 1, - "Cannot be NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE, simultaneous_pucch_pusch is active"); - break; - case NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE: - AssertFatal(use_simultaneous_pucch_pusch == 0, - "Cannot be NFAPI_UL_CONFIG_ULSCH_UCI_PDU_TYPE, simultaneous_pucch_pusch is inactive\n"); - break; + case NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE: + // Convert it to an NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE + ulsch_harq_information = &ul_config_pdu->ulsch_cqi_harq_ri_pdu.harq_information; + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; + /* TODO: check this - when converting from nfapi_ul_config_ulsch_cqi_ri_pdu to + * nfapi_ul_config_ulsch_cqi_harq_ri_pdu, shouldn't we copy initial_transmission_parameters + * from the one to the other? + * Those two types are not compatible. 'initial_transmission_parameters' is not at the + * place in both. + */ + ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; + ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured + ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks; // we don't change the number of resource blocks across retransmissions yet + break; + case NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE: + AssertFatal(use_simultaneous_pucch_pusch == 0, + "Cannot be NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE, simultaneous_pucch_pusch is active\n"); + break; - /* [ulsch + cqi] to [ulsch + cqi + harq] */ + /* [ulsch + cqi on pucch] to [ulsch + cqi on pucch + harq on pucch] */ - case NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE: - // Convert it to an NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE - ulsch_harq_information = - &ul_config_pdu->ulsch_cqi_harq_ri_pdu.harq_information; - ul_config_pdu->pdu_type = - NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; - /* TODO: check this - when converting from nfapi_ul_config_ulsch_cqi_ri_pdu to - * nfapi_ul_config_ulsch_cqi_harq_ri_pdu, shouldn't we copy initial_transmission_parameters - * from the one to the other? - * Those two types are not compatible. 'initial_transmission_parameters' is not at the - * place in both. - */ - ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag=NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; - ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured - ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks; // we don't change the number of resource blocks across retransmissions yet - break; - case NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE: - AssertFatal(use_simultaneous_pucch_pusch == 0, - "Cannot be NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE, simultaneous_pucch_pusch is active\n"); - break; + case NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE: + // convert it to an NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE + harq_information = &ul_config_pdu->ulsch_csi_uci_harq_pdu.harq_information; + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE; + break; + case NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE: + AssertFatal(use_simultaneous_pucch_pusch == 1, + "Cannot be NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE, simultaneous_pucch_pusch is inactive\n"); + break; - /* [ulsch + cqi on pucch] to [ulsch + cqi on pucch + harq on pucch] */ + /* [sr] to [sr + harq] */ - case NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE: - // convert it to an NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE - harq_information = - &ul_config_pdu->ulsch_csi_uci_harq_pdu.harq_information; - ul_config_pdu->pdu_type = - NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE; - break; - case NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE: - AssertFatal(use_simultaneous_pucch_pusch == 1, - "Cannot be NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE, simultaneous_pucch_pusch is inactive\n"); - break; - - /* [sr] to [sr + harq] */ - - case NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE: - // convert to NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE; - harq_information = - &ul_config_pdu->uci_sr_harq_pdu.harq_information; - break; - case NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE: - /* nothing to do */ - break; - - /* [cqi] to [cqi + harq] */ - - case NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE: - // convert to NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE - ul_config_pdu->pdu_type = - NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE; - harq_information = - &ul_config_pdu->uci_cqi_harq_pdu.harq_information; - break; - case NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE: - /* nothing to do */ - break; - - /* [cqi + sr] to [cqr + sr + harq] */ - - case NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE: - // convert to NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE - ul_config_pdu->pdu_type = - NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE; - harq_information = - &ul_config_pdu->uci_cqi_sr_harq_pdu.harq_information; - break; - case NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE: - /* nothing to do */ - break; - } + case NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE: + // convert to NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE; + harq_information = &ul_config_pdu->uci_sr_harq_pdu.harq_information; + break; + case NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE: + /* nothing to do */ + break; + /* [cqi] to [cqi + harq] */ + case NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE: + // convert to NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE; + harq_information = &ul_config_pdu->uci_cqi_harq_pdu.harq_information; + break; + case NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE: + /* nothing to do */ + break; + /* [cqi + sr] to [cqr + sr + harq] */ + case NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE: + // convert to NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE; + harq_information = &ul_config_pdu->uci_cqi_sr_harq_pdu.harq_information; + break; + case NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE: + /* nothing to do */ + break; } + } - if (ulsch_harq_information) - fill_nfapi_ulsch_harq_information(module_idP, CC_idP, - rnti, ulsch_harq_information); + if (ulsch_harq_information) fill_nfapi_ulsch_harq_information(module_idP, CC_idP, rnti, ulsch_harq_information); - if (harq_information) - fill_nfapi_harq_information(module_idP, CC_idP, - rnti, - (frameP * 10) + subframeP, - harq_information, cce_idx); + if (harq_information) fill_nfapi_harq_information(module_idP, CC_idP, + rnti, + (frameP * 10) + subframeP, + harq_information, cce_idx); } uint8_t get_V_UL_DAI(module_id_t module_idP, int CC_idP, uint16_t rntiP) { - nfapi_hi_dci0_request_body_t *HI_DCI0_req = - &RC.mac[module_idP]->HI_DCI0_req[CC_idP].hi_dci0_request_body; - nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = - &HI_DCI0_req->hi_dci0_pdu_list[0]; + nfapi_hi_dci0_request_body_t *HI_DCI0_req = &RC.mac[module_idP]->HI_DCI0_req[CC_idP].hi_dci0_request_body; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[0]; - for (int i = 0; i < HI_DCI0_req->number_of_dci; i++) { - if ((hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) && - (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti == rntiP)) - return (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8. - dl_assignment_index); - } - return (4); // this is rule from Section 7.3 in 36.213 + for (int i = 0; i < HI_DCI0_req->number_of_dci; i++) { + if ((hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) && + (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti == rntiP)) + return (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.dl_assignment_index); + } + return (4); // this is rule from Section 7.3 in 36.213 } void -fill_nfapi_ulsch_harq_information(module_id_t module_idP, - int CC_idP, - uint16_t rntiP, - nfapi_ul_config_ulsch_harq_information - * harq_information) +fill_nfapi_ulsch_harq_information(module_id_t module_idP, + int CC_idP, + uint16_t rntiP, + nfapi_ul_config_ulsch_harq_information *harq_information) { - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; - UE_list_t *UE_list = &eNB->UE_list; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; + UE_list_t *UE_list = &eNB->UE_list; - int UE_id = find_UE_id(module_idP, rntiP); + int UE_id = find_UE_id(module_idP, rntiP); - PUSCH_ConfigDedicated_t *puschConfigDedicated; - // PUSCH_ConfigDedicated_v1020_t *puschConfigDedicated_v1020; - // PUSCH_ConfigDedicated_v1130_t *puschConfigDedicated_v1130; - // PUSCH_ConfigDedicated_v1250_t *puschConfigDedicated_v1250; + PUSCH_ConfigDedicated_t *puschConfigDedicated; + // PUSCH_ConfigDedicated_v1020_t *puschConfigDedicated_v1020; + // PUSCH_ConfigDedicated_v1130_t *puschConfigDedicated_v1130; + // PUSCH_ConfigDedicated_v1250_t *puschConfigDedicated_v1250; - AssertFatal(UE_id >= 0, "UE_id cannot be found, impossible\n"); - AssertFatal(UE_list != NULL, "UE_list is null\n"); - AssertFatal(UE_list->UE_template[CC_idP][UE_id]. - physicalConfigDedicated != NULL, - "physicalConfigDedicated for rnti %x is null\n", rntiP); - AssertFatal((puschConfigDedicated = (PUSCH_ConfigDedicated_t *) - UE_list->UE_template[CC_idP][UE_id]. - physicalConfigDedicated->pusch_ConfigDedicated) != NULL, - "physicalConfigDedicated->puschConfigDedicated for rnti %x is null\n", - rntiP); + AssertFatal(UE_id >= 0, "UE_id cannot be found, impossible\n"); + AssertFatal(UE_list != NULL, "UE_list is null\n"); + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, + "physicalConfigDedicated for rnti %x is null\n", rntiP); + AssertFatal((puschConfigDedicated = (PUSCH_ConfigDedicated_t *) + UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pusch_ConfigDedicated) != NULL, + "physicalConfigDedicated->puschConfigDedicated for rnti %x is null\n", + rntiP); #if defined(Rel14) || defined(Rel14) - /* if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext2) puschConfigDedicated_v1020 = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext2->pusch_ConfigDedicated_v1020; - #endif - #ifdef Rel14 - if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext4) puschConfigDedicated_v1130 = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext4->pusch_ConfigDedicated_v1130; - if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext5) puschConfigDedicated_v1250 = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext5->pusch_ConfigDedicated_v1250; - */ + /* if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext2) puschConfigDedicated_v1020 = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext2->pusch_ConfigDedicated_v1020; + #endif + #ifdef Rel14 + if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext4) puschConfigDedicated_v1130 = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext4->pusch_ConfigDedicated_v1130; + if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext5) puschConfigDedicated_v1250 = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext5->pusch_ConfigDedicated_v1250; + */ #endif - harq_information->harq_information_rel10.delta_offset_harq = - puschConfigDedicated->betaOffset_ACK_Index; - AssertFatal(UE_list-> - UE_template[CC_idP][UE_id].physicalConfigDedicated-> - pucch_ConfigDedicated != NULL, - "pucch_ConfigDedicated is null!\n"); - if ((UE_list->UE_template[CC_idP][UE_id]. - physicalConfigDedicated->pucch_ConfigDedicated-> - tdd_AckNackFeedbackMode != NULL) - && (*UE_list->UE_template[CC_idP][UE_id]. - physicalConfigDedicated->pucch_ConfigDedicated-> - tdd_AckNackFeedbackMode == - PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) - harq_information->harq_information_rel10.ack_nack_mode = 1; // multiplexing - else - harq_information->harq_information_rel10.ack_nack_mode = 0; // bundling + harq_information->harq_information_rel10.delta_offset_harq = puschConfigDedicated->betaOffset_ACK_Index; + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL, + "pucch_ConfigDedicated is null!\n"); + if ((UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode != NULL) + && (*UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode == PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) + harq_information->harq_information_rel10.ack_nack_mode = 1; // multiplexing + else + harq_information->harq_information_rel10.ack_nack_mode = 0; // bundling - switch (get_tmode(module_idP, CC_idP, UE_id)) { - case 1: - case 2: - case 5: - case 6: - case 7: - if (cc->tdd_Config == NULL) // FDD - harq_information->harq_information_rel10.harq_size = 1; - else { - if (harq_information->harq_information_rel10.ack_nack_mode == - 1) - harq_information->harq_information_rel10.harq_size = - get_V_UL_DAI(module_idP, CC_idP, rntiP); - else - harq_information->harq_information_rel10.harq_size = 1; - } - break; - default: // for any other TM we need 2 bits harq - if (cc->tdd_Config == NULL) { - harq_information->harq_information_rel10.harq_size = 2; - } else { - if (harq_information->harq_information_rel10.ack_nack_mode == - 1) - harq_information->harq_information_rel10.harq_size = - get_V_UL_DAI(module_idP, CC_idP, rntiP); - else - harq_information->harq_information_rel10.harq_size = 2; - } - break; - } // get Tmode + switch (get_tmode(module_idP, CC_idP, UE_id)) { + case 1: + case 2: + case 5: + case 6: + case 7: + if (cc->tdd_Config == NULL) // FDD + harq_information->harq_information_rel10.harq_size = 1; + else { + if (harq_information->harq_information_rel10.ack_nack_mode == 1) + harq_information->harq_information_rel10.harq_size = get_V_UL_DAI(module_idP, CC_idP, rntiP); + else + harq_information->harq_information_rel10.harq_size = 1; + } + break; + default: // for any other TM we need 2 bits harq + if (cc->tdd_Config == NULL) { + harq_information->harq_information_rel10.harq_size = 2; + } else { + if (harq_information->harq_information_rel10.ack_nack_mode == 1) + harq_information->harq_information_rel10.harq_size = get_V_UL_DAI(module_idP, CC_idP, rntiP); + else + harq_information->harq_information_rel10.harq_size = 2; + } + break; + } // get Tmode } void -fill_nfapi_harq_information(module_id_t module_idP, - int CC_idP, - uint16_t rntiP, - uint16_t absSFP, - nfapi_ul_config_harq_information * - harq_information, uint8_t cce_idxP) +fill_nfapi_harq_information(module_id_t module_idP, + int CC_idP, + uint16_t rntiP, + uint16_t absSFP, + nfapi_ul_config_harq_information *harq_information, + uint8_t cce_idxP) { - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; - UE_list_t *UE_list = &eNB->UE_list; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; + UE_list_t *UE_list = &eNB->UE_list; - int UE_id = find_UE_id(module_idP, rntiP); + int UE_id = find_UE_id(module_idP, rntiP); - AssertFatal(UE_id >= 0, "UE_id cannot be found, impossible\n"); - AssertFatal(UE_list != NULL, "UE_list is null\n"); + AssertFatal(UE_id >= 0, "UE_id cannot be found, impossible\n"); + AssertFatal(UE_list != NULL, "UE_list is null\n"); #if 0 - /* TODO: revisit, don't use Assert, it's perfectly possible to - * have physicalConfigDedicated NULL here - */ - AssertFatal(UE_list->UE_template[CC_idP][UE_id]. - physicalConfigDedicated != NULL, - "physicalConfigDedicated for rnti %x is null\n", rntiP); + /* TODO: revisit, don't use Assert, it's perfectly possible to + * have physicalConfigDedicated NULL here + */ + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, + "physicalConfigDedicated for rnti %x is null\n", rntiP); #endif - harq_information->harq_information_rel11.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL11_TAG; - harq_information->harq_information_rel11.num_ant_ports = 1; + harq_information->harq_information_rel11.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL11_TAG; + harq_information->harq_information_rel11.num_ant_ports = 1; - switch (get_tmode(module_idP, CC_idP, UE_id)) { - case 1: - case 2: - case 5: - case 6: - case 7: - if (cc->tdd_Config != NULL) { - AssertFatal(UE_list-> - UE_template[CC_idP] - [UE_id].physicalConfigDedicated-> - pucch_ConfigDedicated != NULL, - "pucch_ConfigDedicated is null for TDD!\n"); - if ((UE_list-> - UE_template[CC_idP][UE_id].physicalConfigDedicated-> - pucch_ConfigDedicated->tdd_AckNackFeedbackMode != NULL) - && (*UE_list-> - UE_template[CC_idP][UE_id].physicalConfigDedicated-> - pucch_ConfigDedicated->tdd_AckNackFeedbackMode == - PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) - { - harq_information->harq_information_rel10_tdd.harq_size = 2; // 2-bit ACK/NAK - harq_information->harq_information_rel10_tdd.ack_nack_mode = 1; // multiplexing - } else { - harq_information->harq_information_rel10_tdd.harq_size = 1; // 1-bit ACK/NAK - harq_information->harq_information_rel10_tdd.ack_nack_mode = 0; // bundling - } - harq_information->harq_information_rel10_tdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG; - harq_information->harq_information_rel10_tdd.n_pucch_1_0 = - cc->radioResourceConfigCommon->pucch_ConfigCommon. - n1PUCCH_AN + cce_idxP; - harq_information-> - harq_information_rel10_tdd.number_of_pucch_resources = 1; + switch (get_tmode(module_idP, CC_idP, UE_id)) { + case 1: + case 2: + case 5: + case 6: + case 7: + if (cc->tdd_Config != NULL) { + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL, + "pucch_ConfigDedicated is null for TDD!\n"); + if ((UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode != NULL) + && (*UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode == PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) + { + harq_information->harq_information_rel10_tdd.harq_size = 2; // 2-bit ACK/NAK + harq_information->harq_information_rel10_tdd.ack_nack_mode = 1; // multiplexing } else { - harq_information->harq_information_rel9_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG; - harq_information-> - harq_information_rel9_fdd.number_of_pucch_resources = 1; - harq_information->harq_information_rel9_fdd.harq_size = 1; // 1-bit ACK/NAK - harq_information->harq_information_rel9_fdd.n_pucch_1_0 = - cc->radioResourceConfigCommon->pucch_ConfigCommon. - n1PUCCH_AN + cce_idxP; - } - break; - default: // for any other TM we need 2 bits harq - if (cc->tdd_Config != NULL) { - AssertFatal(UE_list-> - UE_template[CC_idP] - [UE_id].physicalConfigDedicated-> - pucch_ConfigDedicated != NULL, - "pucch_ConfigDedicated is null for TDD!\n"); - if ((UE_list-> - UE_template[CC_idP][UE_id].physicalConfigDedicated-> - pucch_ConfigDedicated->tdd_AckNackFeedbackMode != NULL) - && (*UE_list-> - UE_template[CC_idP][UE_id].physicalConfigDedicated-> - pucch_ConfigDedicated->tdd_AckNackFeedbackMode == - PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) - { - harq_information->harq_information_rel10_tdd.ack_nack_mode = 1; // multiplexing - } else { - harq_information->harq_information_rel10_tdd.ack_nack_mode = 0; // bundling - } - harq_information->harq_information_rel10_tdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG; - harq_information->harq_information_rel10_tdd.harq_size = 2; - harq_information->harq_information_rel10_tdd.n_pucch_1_0 = - cc->radioResourceConfigCommon->pucch_ConfigCommon. - n1PUCCH_AN + cce_idxP; - harq_information-> - harq_information_rel10_tdd.number_of_pucch_resources = 1; - } else { - harq_information->harq_information_rel9_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG; - harq_information-> - harq_information_rel9_fdd.number_of_pucch_resources = 1; - harq_information->harq_information_rel9_fdd.ack_nack_mode = 0; // 1a/b - harq_information->harq_information_rel9_fdd.harq_size = 2; - harq_information->harq_information_rel9_fdd.n_pucch_1_0 = - cc->radioResourceConfigCommon->pucch_ConfigCommon. - n1PUCCH_AN + cce_idxP; - } - break; - } // get Tmode + harq_information->harq_information_rel10_tdd.harq_size = 1; // 1-bit ACK/NAK + harq_information->harq_information_rel10_tdd.ack_nack_mode = 0; // bundling + } + harq_information->harq_information_rel10_tdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG; + harq_information->harq_information_rel10_tdd.n_pucch_1_0 = cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP; + harq_information->harq_information_rel10_tdd.number_of_pucch_resources = 1; + } else { + harq_information->harq_information_rel9_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG; + harq_information->harq_information_rel9_fdd.number_of_pucch_resources = 1; + harq_information->harq_information_rel9_fdd.harq_size = 1; // 1-bit ACK/NAK + harq_information->harq_information_rel9_fdd.n_pucch_1_0 = cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP; + } + break; + default: // for any other TM we need 2 bits harq + if (cc->tdd_Config != NULL) { + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL, + "pucch_ConfigDedicated is null for TDD!\n"); + if ((UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode != NULL) + && (*UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode == PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) { + harq_information->harq_information_rel10_tdd.ack_nack_mode = 1; // multiplexing + } else { + harq_information->harq_information_rel10_tdd.ack_nack_mode = 0; // bundling + } + harq_information->harq_information_rel10_tdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG; + harq_information->harq_information_rel10_tdd.harq_size = 2; + harq_information->harq_information_rel10_tdd.n_pucch_1_0 = cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP; + harq_information->harq_information_rel10_tdd.number_of_pucch_resources = 1; + } else { + harq_information->harq_information_rel9_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG; + harq_information->harq_information_rel9_fdd.number_of_pucch_resources = 1; + harq_information->harq_information_rel9_fdd.ack_nack_mode = 0; // 1a/b + harq_information->harq_information_rel9_fdd.harq_size = 2; + harq_information->harq_information_rel9_fdd.n_pucch_1_0 = cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP; + } + break; + } // get Tmode } uint16_t fill_nfapi_uci_acknak(module_id_t module_idP, - int CC_idP, - uint16_t rntiP, uint16_t absSFP, uint8_t cce_idxP) + int CC_idP, + uint16_t rntiP, + uint16_t absSFP, + uint8_t cce_idxP) { - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; + int ackNAK_absSF = get_pucch1_absSF(cc, absSFP); + nfapi_ul_config_request_t *ul_req = &eNB->UL_req_tmp[CC_idP][ackNAK_absSF % 10]; + nfapi_ul_config_request_body_t *ul_req_body = &ul_req->ul_config_request_body; + nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; - int ackNAK_absSF = get_pucch1_absSF(cc, absSFP); - nfapi_ul_config_request_t *ul_req = &eNB->UL_req_tmp[CC_idP][ackNAK_absSF % 10]; - nfapi_ul_config_request_body_t *ul_req_body = &ul_req->ul_config_request_body; - nfapi_ul_config_request_pdu_t *ul_config_pdu = - &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; + memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_uci_harq_pdu)); + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0; // don't know how to use this + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti = rntiP; - memset((void *) ul_config_pdu, 0, - sizeof(nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; - ul_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_ul_config_uci_harq_pdu)); - ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; - ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0; // don't know how to use this - ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti = - rntiP; + fill_nfapi_harq_information(module_idP, CC_idP, + rntiP, + absSFP, + &ul_config_pdu->uci_harq_pdu.harq_information, cce_idxP); + LOG_D(MAC, + "Filled in UCI HARQ request for rnti %x SF %d.%d acknakSF %d.%d, cce_idxP %d-> n1_pucch %d\n", + rntiP, absSFP / 10, absSFP % 10, ackNAK_absSF / 10, + ackNAK_absSF % 10, cce_idxP, + ul_config_pdu->uci_harq_pdu. + harq_information.harq_information_rel9_fdd.n_pucch_1_0); - fill_nfapi_harq_information(module_idP, CC_idP, - rntiP, - absSFP, - &ul_config_pdu->uci_harq_pdu. - harq_information, cce_idxP); - LOG_D(MAC, - "Filled in UCI HARQ request for rnti %x SF %d.%d acknakSF %d.%d, cce_idxP %d-> n1_pucch %d\n", - rntiP, absSFP / 10, absSFP % 10, ackNAK_absSF / 10, - ackNAK_absSF % 10, cce_idxP, - ul_config_pdu->uci_harq_pdu. - harq_information.harq_information_rel9_fdd.n_pucch_1_0); + ul_req_body->number_of_pdus++; + ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_req->sfn_sf = (ackNAK_absSF/10) << 4 | ackNAK_absSF%10; - ul_req_body->number_of_pdus++; - ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - - ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; - ul_req->sfn_sf = (ackNAK_absSF/10) << 4 | ackNAK_absSF%10; - - return (((ackNAK_absSF / 10) << 4) + (ackNAK_absSF % 10)); + return (((ackNAK_absSF / 10) << 4) + (ackNAK_absSF % 10)); } void @@ -1520,192 +1389,133 @@ fill_nfapi_dlsch_config(eNB_MAC_INST * eNB, uint8_t num_bf_prb_per_subband, uint8_t num_bf_vector) { - nfapi_dl_config_request_pdu_t *dl_config_pdu = - &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); + nfapi_dl_config_request_pdu_t *dl_config_pdu = + &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = length; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = pdu_index; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = rnti; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = - resource_allocation_type; - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.virtual_resource_block_assignment_flag = - virtual_resource_block_assignment_flag; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = - resource_block_coding; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = modulation; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = - redundancy_version; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = - transport_blocks; - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = - transport_block_to_codeword_swap_flag; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = - transmission_scheme; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = - number_of_layers; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = - number_of_subbands; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = codebook_index; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = - ue_category_capacity; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = pa; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = - delta_power_offset_index; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = ngap; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = nprb; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = - transmission_mode; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = - num_bf_prb_per_subband; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = num_bf_vector; - dl_req->number_pdu++; + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = length; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = pdu_index; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = rnti; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = resource_allocation_type; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = virtual_resource_block_assignment_flag; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = resource_block_coding; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = modulation; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = redundancy_version; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = transport_blocks; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = transport_block_to_codeword_swap_flag; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = transmission_scheme; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = number_of_layers; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = number_of_subbands; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = codebook_index; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = ue_category_capacity; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = pa; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = delta_power_offset_index; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = ngap; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = nprb; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = transmission_mode; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = num_bf_prb_per_subband; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = num_bf_vector; + dl_req->number_pdu++; } uint16_t -fill_nfapi_tx_req(nfapi_tx_request_body_t * tx_req_body, - uint16_t absSF, uint16_t pdu_length, - uint16_t pdu_index, uint8_t * pdu) +fill_nfapi_tx_req(nfapi_tx_request_body_t *tx_req_body, + uint16_t absSF, + uint16_t pdu_length, + uint16_t pdu_index, + uint8_t *pdu) { - nfapi_tx_request_pdu_t *TX_req = - &tx_req_body->tx_pdu_list[tx_req_body->number_of_pdus]; - LOG_D(MAC, "Filling TX_req %d for pdu length %d\n", - tx_req_body->number_of_pdus, pdu_length); - TX_req->pdu_length = pdu_length; - TX_req->pdu_index = pdu_index; - TX_req->num_segments = 1; - TX_req->segments[0].segment_length = pdu_length; - TX_req->segments[0].segment_data = pdu; - tx_req_body->tl.tag = NFAPI_TX_REQUEST_BODY_TAG; - tx_req_body->number_of_pdus++; + nfapi_tx_request_pdu_t *TX_req = &tx_req_body->tx_pdu_list[tx_req_body->number_of_pdus]; + LOG_D(MAC, "Filling TX_req %d for pdu length %d\n", + tx_req_body->number_of_pdus, pdu_length); - return (((absSF / 10) << 4) + (absSF % 10)); + TX_req->pdu_length = pdu_length; + TX_req->pdu_index = pdu_index; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = pdu_length; + TX_req->segments[0].segment_data = pdu; + tx_req_body->tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + tx_req_body->number_of_pdus++; + + return (((absSF / 10) << 4) + (absSF % 10)); } void -fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t * - ul_config_pdu, uint8_t cqi_req, - COMMON_channels_t * cc, - struct PhysicalConfigDedicated - *physicalConfigDedicated, - uint8_t tmode, uint32_t handle, - uint16_t rnti, - uint8_t resource_block_start, - uint8_t - number_of_resource_blocks, - uint8_t mcs, - uint8_t cyclic_shift_2_for_drms, - uint8_t - frequency_hopping_enabled_flag, - uint8_t frequency_hopping_bits, - uint8_t new_data_indication, - uint8_t redundancy_version, - uint8_t harq_process_number, - uint8_t ul_tx_mode, - uint8_t current_tx_nb, - uint8_t n_srs, uint16_t size) +fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t *ul_config_pdu, + uint8_t cqi_req, + COMMON_channels_t *cc, + struct PhysicalConfigDedicated *physicalConfigDedicated, + uint8_t tmode, + uint32_t handle, + uint16_t rnti, + uint8_t resource_block_start, + uint8_t number_of_resource_blocks, + uint8_t mcs, + uint8_t cyclic_shift_2_for_drms, + uint8_t frequency_hopping_enabled_flag, + uint8_t frequency_hopping_bits, + uint8_t new_data_indication, + uint8_t redundancy_version, + uint8_t harq_process_number, + uint8_t ul_tx_mode, + uint8_t current_tx_nb, + uint8_t n_srs, + uint16_t size) { - memset((void *) ul_config_pdu, 0, - sizeof(nfapi_ul_config_request_pdu_t)); + memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; - ul_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = handle; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = rnti; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = - resource_block_start; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = - number_of_resource_blocks; - if (mcs < 11) - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2; - else if (mcs < 21) - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 4; - else - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 6; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = - cyclic_shift_2_for_drms; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8. - frequency_hopping_enabled_flag = frequency_hopping_enabled_flag; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = - frequency_hopping_bits; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = - new_data_indication; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = - redundancy_version; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = - harq_process_number; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = ul_tx_mode; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = current_tx_nb; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = n_srs; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = size; + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = handle; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = rnti; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = resource_block_start; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = number_of_resource_blocks; + if (mcs < 11) ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2; + else if (mcs < 21) ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 4; + else ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 6; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = cyclic_shift_2_for_drms; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = frequency_hopping_enabled_flag; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = frequency_hopping_bits; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = new_data_indication; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = redundancy_version; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = harq_process_number; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = ul_tx_mode; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = current_tx_nb; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = n_srs; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = size; - if (cqi_req == 1) { - // Add CQI portion - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE; - ul_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_cqi_ri_pdu)); - ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG; - ul_config_pdu->ulsch_cqi_ri_pdu. - cqi_ri_information.cqi_ri_information_rel9.report_type = 1; - ul_config_pdu->ulsch_cqi_ri_pdu. - cqi_ri_information.cqi_ri_information_rel9. - aperiodic_cqi_pmi_ri_report.number_of_cc = 1; - LOG_D(MAC, "report_type %d\n", - ul_config_pdu->ulsch_cqi_ri_pdu. - cqi_ri_information.cqi_ri_information_rel9.report_type); + if (cqi_req == 1) { + // Add CQI portion + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_cqi_ri_pdu)); + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG; + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.report_type = 1; + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.number_of_cc = 1; + LOG_D(MAC, "report_type %d\n",ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.report_type); - if (cc->p_eNB <= 2 - && (tmode == 3 || tmode == 4 || tmode == 8 || tmode == 9 - || tmode == 10)) - ul_config_pdu->ulsch_cqi_ri_pdu. - cqi_ri_information.cqi_ri_information_rel9. - aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 1; - else if (cc->p_eNB <= 2) - ul_config_pdu->ulsch_cqi_ri_pdu. - cqi_ri_information.cqi_ri_information_rel9. - aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 0; - else if (cc->p_eNB == 4) - ul_config_pdu->ulsch_cqi_ri_pdu. - cqi_ri_information.cqi_ri_information_rel9. - aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 2; + if (cc->p_eNB <= 2 + && (tmode == 3 || tmode == 4 || tmode == 8 || tmode == 9 || tmode == 10)) + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 1; + else if (cc->p_eNB <= 2) ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 0; + else if (cc->p_eNB == 4) ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 2; - AssertFatal(physicalConfigDedicated->cqi_ReportConfig != NULL, - "physicalConfigDedicated->cqi_ReportConfig is null!\n"); - AssertFatal(physicalConfigDedicated-> - cqi_ReportConfig->cqi_ReportModeAperiodic != NULL, - "physicalConfigDedicated->cqi_ReportModeAperiodic is null!\n"); - AssertFatal(physicalConfigDedicated->pusch_ConfigDedicated != NULL, - "physicalConfigDedicated->puschConfigDedicated is null!\n"); + AssertFatal(physicalConfigDedicated->cqi_ReportConfig != NULL,"physicalConfigDedicated->cqi_ReportConfig is null!\n"); + AssertFatal(physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic != NULL,"physicalConfigDedicated->cqi_ReportModeAperiodic is null!\n"); + AssertFatal(physicalConfigDedicated->pusch_ConfigDedicated != NULL,"physicalConfigDedicated->puschConfigDedicated is null!\n"); - for (int ri = 0; - ri < - (1 << ul_config_pdu->ulsch_cqi_ri_pdu. - cqi_ri_information.cqi_ri_information_rel9. - aperiodic_cqi_pmi_ri_report.cc[0].ri_size); ri++) - ul_config_pdu->ulsch_cqi_ri_pdu. - cqi_ri_information.cqi_ri_information_rel9. - aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[ri] = - get_dl_cqi_pmi_size_pusch(cc, tmode, 1 + ri, - physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic); + for (int ri = 0; + ri < (1 << ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size); + ri++) + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.periodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[ri] = get_dl_cqi_pmi_size_pusch(cc,tmode,1 + ri,physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic); - ul_config_pdu->ulsch_cqi_ri_pdu. - cqi_ri_information.cqi_ri_information_rel9.delta_offset_cqi = - physicalConfigDedicated->pusch_ConfigDedicated-> - betaOffset_CQI_Index; - ul_config_pdu->ulsch_cqi_ri_pdu. - cqi_ri_information.cqi_ri_information_rel9.delta_offset_ri = - physicalConfigDedicated->pusch_ConfigDedicated-> - betaOffset_RI_Index; - } + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_cqi = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index; + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_ri = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index; + } } #ifdef Rel14 @@ -1717,34 +1527,29 @@ fill_nfapi_ulsch_config_request_emtc(nfapi_ul_config_request_pdu_t * uint16_t repetition_number, uint16_t initial_transmission_sf_io) { - // Re13 fields + // Re13 fields - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type = ue_type; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions = - total_number_of_repetitions; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number = - repetition_number; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = - initial_transmission_sf_io; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type = ue_type; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions = total_number_of_repetitions; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number = repetition_number; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = initial_transmission_sf_io; } int get_numnarrowbands(long dl_Bandwidth) { - int nb_tab[6] = { 1, 2, 4, 8, 12, 16 }; + int nb_tab[6] = { 1, 2, 4, 8, 12, 16 }; - AssertFatal(dl_Bandwidth < 7 - || dl_Bandwidth >= 0, "dl_Bandwidth not in [0..6]\n"); - return (nb_tab[dl_Bandwidth]); + AssertFatal(dl_Bandwidth < 7 || dl_Bandwidth >= 0, "dl_Bandwidth not in [0..6]\n"); + return (nb_tab[dl_Bandwidth]); } int get_numnarrowbandbits(long dl_Bandwidth) { - int nbbits_tab[6] = { 0, 1, 2, 3, 4, 4 }; + int nbbits_tab[6] = { 0, 1, 2, 3, 4, 4 }; - AssertFatal(dl_Bandwidth < 7 - || dl_Bandwidth >= 0, "dl_Bandwidth not in [0..6]\n"); - return (nbbits_tab[dl_Bandwidth]); + AssertFatal(dl_Bandwidth < 7 || dl_Bandwidth >= 0, "dl_Bandwidth not in [0..6]\n"); + return (nbbits_tab[dl_Bandwidth]); } //This implements the frame/subframe condition for first subframe of MPDCCH transmission (Section 9.1.5 36.213, Rel 13/14) @@ -1756,111 +1561,96 @@ mpdcch_sf_condition(eNB_MAC_INST * eNB, int CC_id, frame_t frameP, sub_frame_t subframeP, int rmax, MPDCCH_TYPES_t mpdcch_type, int UE_id) { - struct PRACH_ConfigSIB_v1310 *ext4_prach = - eNB->common_channels[CC_id].radioResourceConfigCommon_BR-> - ext4->prach_ConfigCommon_v1310; + struct PRACH_ConfigSIB_v1310 *ext4_prach = + eNB->common_channels[CC_id].radioResourceConfigCommon_BR-> + ext4->prach_ConfigCommon_v1310; - int T; - EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11; + int T; + EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11; - switch (mpdcch_type) { - case TYPE0: - AssertFatal(1 == 0, "MPDCCH Type 0 not handled yet\n"); - break; - case TYPE1: - AssertFatal(1 == 0, "MPDCCH Type 1 not handled yet\n"); - break; - case TYPE1A: - AssertFatal(1 == 0, "MPDCCH Type 1A not handled yet\n"); - break; - case TYPE2: // RAR - AssertFatal(ext4_prach->mpdcch_startSF_CSS_RA_r13 != NULL, - "mpdcch_startSF_CSS_RA_r13 is null\n"); - AssertFatal(rmax > 0, "rmax is 0!\b"); - if (eNB->common_channels[CC_id].tdd_Config == NULL) //FDD - T = rmax * - startSF_fdd_RA_times2[ext4_prach-> + switch (mpdcch_type) { + case TYPE0: + AssertFatal(1 == 0, "MPDCCH Type 0 not handled yet\n"); + break; + case TYPE1: + AssertFatal(1 == 0, "MPDCCH Type 1 not handled yet\n"); + break; + case TYPE1A: + AssertFatal(1 == 0, "MPDCCH Type 1A not handled yet\n"); + break; + case TYPE2: // RAR + AssertFatal(ext4_prach->mpdcch_startSF_CSS_RA_r13 != NULL, + "mpdcch_startSF_CSS_RA_r13 is null\n"); + AssertFatal(rmax > 0, "rmax is 0!\b"); + if (eNB->common_channels[CC_id].tdd_Config == NULL) //FDD + T = rmax *startSF_fdd_RA_times2[ext4_prach-> mpdcch_startSF_CSS_RA_r13-> choice.fdd_r13] >> 1; - else //TDD - T = rmax * - startSF_tdd_RA[ext4_prach-> + else //TDD + T = rmax *startSF_tdd_RA[ext4_prach-> mpdcch_startSF_CSS_RA_r13->choice.tdd_r13]; - break; - case TYPE2A: - AssertFatal(1 == 0, "MPDCCH Type 2A not handled yet\n"); - break; - case TYPEUESPEC: - epdcch_setconfig_r11 = - eNB->UE_list.UE_template[CC_id][UE_id]. - physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11. - choice.setup.setConfigToAddModList_r11->list.array[0]; + break; + case TYPE2A: + AssertFatal(1 == 0, "MPDCCH Type 2A not handled yet\n"); + break; + case TYPEUESPEC: + epdcch_setconfig_r11 = + eNB->UE_list.UE_template[CC_id][UE_id].physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0]; - AssertFatal(epdcch_setconfig_r11 != NULL, - " epdcch_setconfig_r11 is null for UE specific \n"); - AssertFatal(epdcch_setconfig_r11->ext2 != NULL, - " ext2 doesn't exist in epdcch config ' \n"); + AssertFatal(epdcch_setconfig_r11 != NULL, + " epdcch_setconfig_r11 is null for UE specific \n"); + AssertFatal(epdcch_setconfig_r11->ext2 != NULL, + " ext2 doesn't exist in epdcch config ' \n"); - if (eNB->common_channels[CC_id].tdd_Config == NULL) //FDD - T = rmax * - startSF_fdd_RA_times2[epdcch_setconfig_r11-> - ext2->mpdcch_config_r13->choice. - setup.mpdcch_StartSF_UESS_r13.choice. - fdd_r13] >> 1; - else //TDD - T = rmax * - startSF_tdd_RA[epdcch_setconfig_r11-> - ext2->mpdcch_config_r13->choice. - setup.mpdcch_StartSF_UESS_r13.choice. - tdd_r13]; + if (eNB->common_channels[CC_id].tdd_Config == NULL) //FDD + T = rmax *startSF_fdd_RA_times2[epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_StartSF_UESS_r13.choice.fdd_r13] >> 1; + else //TDD + T = rmax *startSF_tdd_RA[epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_StartSF_UESS_r13.choice.tdd_r13]; + break; + default: + return (0); + } - break; - default: - return (0); - } - - AssertFatal(T > 0, "T is 0!\n"); - if (((10 * frameP) + subframeP) % T == 0) - return (1); - else - return (0); + AssertFatal(T > 0, "T is 0!\n"); + if (((10 * frameP) + subframeP) % T == 0) return (1); + else return (0); } int narrowband_to_first_rb(COMMON_channels_t * cc, int nb_index) { - switch (cc->mib->message.dl_Bandwidth) { - case 0: // 6 PRBs, N_NB=1, i_0=0 - return (0); - break; - case 3: // 50 PRBs, N_NB=8, i_0=1 - return ((int) (1 + (6 * nb_index))); - break; - case 5: // 100 PRBs, N_NB=16, i_0=2 - return ((int) (2 + (6 * nb_index))); - break; - case 1: // 15 PRBs N_NB=2, i_0=1 - if (nb_index > 0) - return (1); - else - return (0); - break; - case 2: // 25 PRBs, N_NB=4, i_0=0 - if (nb_index > 1) - return (1 + (6 * nb_index)); - else - return ((6 * nb_index)); - break; - case 4: // 75 PRBs, N_NB=12, i_0=1 - if (nb_index > 5) - return (2 + (6 * nb_index)); - else - return (1 + (6 * nb_index)); - break; - default: - AssertFatal(1 == 0, "Impossible dl_Bandwidth %d\n", - (int) cc->mib->message.dl_Bandwidth); - break; - } + switch (cc->mib->message.dl_Bandwidth) { + case 0: // 6 PRBs, N_NB=1, i_0=0 + return (0); + break; + case 3: // 50 PRBs, N_NB=8, i_0=1 + return ((int) (1 + (6 * nb_index))); + break; + case 5: // 100 PRBs, N_NB=16, i_0=2 + return ((int) (2 + (6 * nb_index))); + break; + case 1: // 15 PRBs N_NB=2, i_0=1 + if (nb_index > 0) + return (1); + else + return (0); + break; + case 2: // 25 PRBs, N_NB=4, i_0=0 + if (nb_index > 1) + return (1 + (6 * nb_index)); + else + return ((6 * nb_index)); + break; + case 4: // 75 PRBs, N_NB=12, i_0=1 + if (nb_index > 5) + return (2 + (6 * nb_index)); + else + return (1 + (6 * nb_index)); + break; + default: + AssertFatal(1 == 0, "Impossible dl_Bandwidth %d\n", + (int) cc->mib->message.dl_Bandwidth); + break; + } } #endif @@ -1868,23 +1658,23 @@ int narrowband_to_first_rb(COMMON_channels_t * cc, int nb_index) void init_ue_sched_info(void) //------------------------------------------------------------------------------ { - module_id_t i, j, k; + module_id_t i, j, k; - for (i = 0; i < NUMBER_OF_eNB_MAX; i++) { - for (k = 0; k < MAX_NUM_CCs; k++) { - for (j = 0; j < NUMBER_OF_UE_MAX; j++) { - // init DL - eNB_dlsch_info[i][k][j].weight = 0; - eNB_dlsch_info[i][k][j].subframe = 0; - eNB_dlsch_info[i][k][j].serving_num = 0; - eNB_dlsch_info[i][k][j].status = S_DL_NONE; - // init UL - eNB_ulsch_info[i][k][j].subframe = 0; - eNB_ulsch_info[i][k][j].serving_num = 0; - eNB_ulsch_info[i][k][j].status = S_UL_NONE; - } - } + for (i = 0; i < NUMBER_OF_eNB_MAX; i++) { + for (k = 0; k < MAX_NUM_CCs; k++) { + for (j = 0; j < NUMBER_OF_UE_MAX; j++) { + // init DL + eNB_dlsch_info[i][k][j].weight = 0; + eNB_dlsch_info[i][k][j].subframe = 0; + eNB_dlsch_info[i][k][j].serving_num = 0; + eNB_dlsch_info[i][k][j].status = S_DL_NONE; + // init UL + eNB_ulsch_info[i][k][j].subframe = 0; + eNB_ulsch_info[i][k][j].serving_num = 0; + eNB_ulsch_info[i][k][j].status = S_UL_NONE; + } } + } } @@ -1893,923 +1683,785 @@ void init_ue_sched_info(void) unsigned char get_ue_weight(module_id_t module_idP, int CC_idP, int ue_idP) //------------------------------------------------------------------------------ { - return (eNB_dlsch_info[module_idP][CC_idP][ue_idP].weight); + return (eNB_dlsch_info[module_idP][CC_idP][ue_idP].weight); } //------------------------------------------------------------------------------ int find_UE_id(module_id_t mod_idP, rnti_t rntiP) //------------------------------------------------------------------------------ { - int UE_id; - UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + int UE_id; + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { - if (UE_list->active[UE_id] != TRUE) - continue; - if (UE_list->UE_template[UE_PCCID(mod_idP, UE_id)][UE_id].rnti == - rntiP) { - return (UE_id); - } + for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { + if (UE_list->active[UE_id] != TRUE) + continue; + if (UE_list->UE_template[UE_PCCID(mod_idP, UE_id)][UE_id].rnti == + rntiP) { + return (UE_id); } + } - return (-1); + return (-1); } //------------------------------------------------------------------------------ int find_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP) //------------------------------------------------------------------------------ { - int RA_id; - AssertFatal(RC.mac[mod_idP], "RC.mac[%d] is null\n", mod_idP); + int RA_id; + AssertFatal(RC.mac[mod_idP], "RC.mac[%d] is null\n", mod_idP); - RA_t *ra = (RA_t *) & RC.mac[mod_idP]->common_channels[CC_idP].ra[0]; + RA_t *ra = (RA_t *) & RC.mac[mod_idP]->common_channels[CC_idP].ra[0]; - for (RA_id = 0; RA_id < NB_RA_PROC_MAX; RA_id++) { - LOG_D(MAC, - "Checking RA_id %d for %x : state %d\n", - RA_id, rntiP, ra[RA_id].state); + for (RA_id = 0; RA_id < NB_RA_PROC_MAX; RA_id++) { + LOG_D(MAC, + "Checking RA_id %d for %x : state %d\n", + RA_id, rntiP, ra[RA_id].state); - if (ra[RA_id].state != IDLE && - ra[RA_id].rnti == rntiP) - return (RA_id); - } - return (-1); + if (ra[RA_id].state != IDLE && + ra[RA_id].rnti == rntiP) + return (RA_id); + } + return (-1); } //------------------------------------------------------------------------------ int UE_num_active_CC(UE_list_t * listP, int ue_idP) //------------------------------------------------------------------------------ { - return (listP->numactiveCCs[ue_idP]); + return (listP->numactiveCCs[ue_idP]); } //------------------------------------------------------------------------------ int UE_PCCID(module_id_t mod_idP, int ue_idP) //------------------------------------------------------------------------------ { - return (RC.mac[mod_idP]->UE_list.pCC_id[ue_idP]); + return (RC.mac[mod_idP]->UE_list.pCC_id[ue_idP]); } //------------------------------------------------------------------------------ rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP) //------------------------------------------------------------------------------ { - rnti_t rnti = - RC.mac[mod_idP]-> - UE_list.UE_template[UE_PCCID(mod_idP, ue_idP)][ue_idP].rnti; + rnti_t rnti = + RC.mac[mod_idP]-> + UE_list.UE_template[UE_PCCID(mod_idP, ue_idP)][ue_idP].rnti; - if (rnti > 0) { - return (rnti); - } + if (rnti > 0) { + return (rnti); + } - LOG_D(MAC, "[eNB %d] Couldn't find RNTI for UE %d\n", mod_idP, ue_idP); - //display_backtrace(); - return (NOT_A_RNTI); + LOG_D(MAC, "[eNB %d] Couldn't find RNTI for UE %d\n", mod_idP, ue_idP); + //display_backtrace(); + return (NOT_A_RNTI); } //------------------------------------------------------------------------------ boolean_t is_UE_active(module_id_t mod_idP, int ue_idP) //------------------------------------------------------------------------------ { - return (RC.mac[mod_idP]->UE_list.active[ue_idP]); + return (RC.mac[mod_idP]->UE_list.active[ue_idP]); } -/* -uint8_t find_active_UEs(module_id_t module_idP,int CC_id){ - - module_id_t ue_mod_id = 0; - rnti_t rnti = 0; - uint8_t nb_active_ue = 0; - - for (ue_mod_id=0;ue_mod_idget_eNB_UE_stats(module_idP,rnti) != NULL){ // check at the phy enb_ue state for this rnti - nb_active_ue++; - } - else { // this ue is removed at the phy => remove it at the mac as well - mac_remove_ue(module_idP, CC_id, ue_mod_id); - } - } - } - return(nb_active_ue); -} -*/ - - -// get aggregation (L) form phy for a give UE unsigned char get_aggregation(uint8_t bw_index, uint8_t cqi, uint8_t dci_fmt) { - unsigned char aggregation = 3; + unsigned char aggregation = 3; - switch (dci_fmt) { - case format0: - aggregation = cqi2fmt0_agg[bw_index][cqi]; - break; - case format1: - case format1A: - case format1B: - case format1D: - aggregation = cqi2fmt1x_agg[bw_index][cqi]; - break; - case format2: - case format2A: - case format2B: - case format2C: - case format2D: - aggregation = cqi2fmt2x_agg[bw_index][cqi]; - break; - case format1C: - case format1E_2A_M10PRB: - case format3: - case format3A: - case format4: - default: - LOG_W(MAC, "unsupported DCI format %d\n", dci_fmt); - } + switch (dci_fmt) { + case format0: + aggregation = cqi2fmt0_agg[bw_index][cqi]; + break; + case format1: + case format1A: + case format1B: + case format1D: + aggregation = cqi2fmt1x_agg[bw_index][cqi]; + break; + case format2: + case format2A: + case format2B: + case format2C: + case format2D: + aggregation = cqi2fmt2x_agg[bw_index][cqi]; + break; + case format1C: + case format1E_2A_M10PRB: + case format3: + case format3A: + case format4: + default: + LOG_W(MAC, "unsupported DCI format %d\n", dci_fmt); + } - LOG_D(MAC, "Aggregation level %d (cqi %d, bw_index %d, format %d)\n", 1 << aggregation, cqi, bw_index, dci_fmt); + LOG_D(MAC, "Aggregation level %d (cqi %d, bw_index %d, format %d)\n", 1 << aggregation, cqi, bw_index, dci_fmt); - return 1 << aggregation; + return 1 << aggregation; } void dump_ue_list(UE_list_t * listP, int ul_flag) { - int j; + int j; - if (ul_flag == 0) { - for (j = listP->head; j >= 0; j = listP->next[j]) { - LOG_T(MAC, "node %d => %d\n", j, listP->next[j]); - } - } else { - for (j = listP->head_ul; j >= 0; j = listP->next_ul[j]) { - LOG_T(MAC, "node %d => %d\n", j, listP->next_ul[j]); - } + if (ul_flag == 0) { + for (j = listP->head; j >= 0; j = listP->next[j]) { + LOG_T(MAC, "node %d => %d\n", j, listP->next[j]); } + } else { + for (j = listP->head_ul; j >= 0; j = listP->next_ul[j]) { + LOG_T(MAC, "node %d => %d\n", j, listP->next_ul[j]); + } + } } int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP, int harq_pidP #ifdef Rel14 , uint8_t rach_resource_type #endif - ) + ) { - int UE_id; - int i, j; + int UE_id; + int i, j; - UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - LOG_D(MAC, - "[eNB %d, CC_id %d] Adding UE with rnti %x (next avail %d, num_UEs %d)\n", - mod_idP, cc_idP, rntiP, UE_list->avail, UE_list->num_UEs); - dump_ue_list(UE_list, 0); + LOG_D(MAC, + "[eNB %d, CC_id %d] Adding UE with rnti %x (next avail %d, num_UEs %d)\n", + mod_idP, cc_idP, rntiP, UE_list->avail, UE_list->num_UEs); + dump_ue_list(UE_list, 0); - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { - if (UE_list->active[i] == TRUE) - continue; - UE_id = i; - memset(&UE_list->UE_template[cc_idP][UE_id], 0, - sizeof(UE_TEMPLATE)); - UE_list->UE_template[cc_idP][UE_id].rnti = rntiP; - UE_list->UE_template[cc_idP][UE_id].configured = FALSE; - UE_list->numactiveCCs[UE_id] = 1; - UE_list->numactiveULCCs[UE_id] = 1; - UE_list->pCC_id[UE_id] = cc_idP; - UE_list->ordered_CCids[0][UE_id] = cc_idP; - UE_list->ordered_ULCCids[0][UE_id] = cc_idP; - UE_list->num_UEs++; - UE_list->active[UE_id] = TRUE; + for (i = 0; i < NUMBER_OF_UE_MAX; i++) { + if (UE_list->active[i] == TRUE) + continue; + UE_id = i; + memset(&UE_list->UE_template[cc_idP][UE_id], 0, + sizeof(UE_TEMPLATE)); + UE_list->UE_template[cc_idP][UE_id].rnti = rntiP; + UE_list->UE_template[cc_idP][UE_id].configured = FALSE; + UE_list->numactiveCCs[UE_id] = 1; + UE_list->numactiveULCCs[UE_id] = 1; + UE_list->pCC_id[UE_id] = cc_idP; + UE_list->ordered_CCids[0][UE_id] = cc_idP; + UE_list->ordered_ULCCids[0][UE_id] = cc_idP; + UE_list->num_UEs++; + UE_list->active[UE_id] = TRUE; #if defined(USRP_REC_PLAY) // not specific to record/playback ? - UE_list->UE_template[cc_idP][UE_id].pre_assigned_mcs_ul = 0; + UE_list->UE_template[cc_idP][UE_id].pre_assigned_mcs_ul = 0; #endif #ifdef Rel14 - UE_list->UE_template[cc_idP][UE_id].rach_resource_type = - rach_resource_type; + UE_list->UE_template[cc_idP][UE_id].rach_resource_type = + rach_resource_type; #endif - memset((void *) &UE_list->UE_sched_ctrl[UE_id], 0, - sizeof(UE_sched_ctrl)); - memset((void *) &UE_list->eNB_UE_stats[cc_idP][UE_id], 0, - sizeof(eNB_UE_STATS)); + memset((void *) &UE_list->UE_sched_ctrl[UE_id], 0, + sizeof(UE_sched_ctrl)); + memset((void *) &UE_list->eNB_UE_stats[cc_idP][UE_id], 0, + sizeof(eNB_UE_STATS)); - UE_list->UE_sched_ctrl[UE_id].ta_update = 31; + UE_list->UE_sched_ctrl[UE_id].ta_update = 31; - for (j = 0; j < 8; j++) { - UE_list->UE_template[cc_idP][UE_id].oldNDI[j] = (j == 0) ? 1 : 0; // 1 because first transmission is with format1A (Msg4) for harq_pid 0 - UE_list->UE_template[cc_idP][UE_id].oldNDI_UL[j] = (j == harq_pidP) ? 0 : 1; // 1st transmission is with Msg3; - UE_list->UE_sched_ctrl[UE_id].round[cc_idP][j] = 8; - UE_list->UE_sched_ctrl[UE_id].round_UL[cc_idP][j] = 0; - } - - eNB_ulsch_info[mod_idP][cc_idP][UE_id].status = S_UL_WAITING; - eNB_dlsch_info[mod_idP][cc_idP][UE_id].status = S_DL_WAITING; - LOG_D(MAC, "[eNB %d] Add UE_id %d on Primary CC_id %d: rnti %x\n", - mod_idP, UE_id, cc_idP, rntiP); - dump_ue_list(UE_list, 0); - return (UE_id); + for (j = 0; j < 8; j++) { + UE_list->UE_template[cc_idP][UE_id].oldNDI[j] = (j == 0) ? 1 : 0; // 1 because first transmission is with format1A (Msg4) for harq_pid 0 + UE_list->UE_template[cc_idP][UE_id].oldNDI_UL[j] = (j == harq_pidP) ? 0 : 1; // 1st transmission is with Msg3; + UE_list->UE_sched_ctrl[UE_id].round[cc_idP][j] = 8; + UE_list->UE_sched_ctrl[UE_id].round_UL[cc_idP][j] = 0; } - printf("MAC: cannot add new UE for rnti %x\n", rntiP); - LOG_E(MAC, - "error in add_new_ue(), could not find space in UE_list, Dumping UE list\n"); + eNB_ulsch_info[mod_idP][cc_idP][UE_id].status = S_UL_WAITING; + eNB_dlsch_info[mod_idP][cc_idP][UE_id].status = S_DL_WAITING; + LOG_D(MAC, "[eNB %d] Add UE_id %d on Primary CC_id %d: rnti %x\n", + mod_idP, UE_id, cc_idP, rntiP); dump_ue_list(UE_list, 0); - return (-1); + return (UE_id); + } + + printf("MAC: cannot add new UE for rnti %x\n", rntiP); + LOG_E(MAC, + "error in add_new_ue(), could not find space in UE_list, Dumping UE list\n"); + dump_ue_list(UE_list, 0); + return (-1); } //------------------------------------------------------------------------------ int rrc_mac_remove_ue(module_id_t mod_idP, rnti_t rntiP) //------------------------------------------------------------------------------ { - int i; - UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - int UE_id = find_UE_id(mod_idP, rntiP); - int pCC_id; - - if (UE_id == -1) { - LOG_W(MAC, "rrc_mac_remove_ue: UE %x not found\n", rntiP); - return 0; - } - - pCC_id = UE_PCCID(mod_idP, UE_id); - - LOG_I(MAC, "Removing UE %d from Primary CC_id %d (rnti %x)\n", UE_id, - pCC_id, rntiP); - dump_ue_list(UE_list, 0); - - UE_list->active[UE_id] = FALSE; - UE_list->num_UEs--; - - if (UE_list->head == UE_id) - UE_list->head = UE_list->next[UE_id]; - else - UE_list->next[prev(UE_list, UE_id, 0)] = UE_list->next[UE_id]; - if (UE_list->head_ul == UE_id) - UE_list->head_ul = UE_list->next_ul[UE_id]; - else - UE_list->next_ul[prev(UE_list, UE_id, 0)] = - UE_list->next_ul[UE_id]; - - // clear all remaining pending transmissions - UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID0] = 0; - UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID1] = 0; - UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID2] = 0; - UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID3] = 0; - - UE_list->UE_template[pCC_id][UE_id].ul_SR = 0; - UE_list->UE_template[pCC_id][UE_id].rnti = NOT_A_RNTI; - UE_list->UE_template[pCC_id][UE_id].ul_active = FALSE; - eNB_ulsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI; - eNB_ulsch_info[mod_idP][pCC_id][UE_id].status = S_UL_NONE; - eNB_dlsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI; - eNB_dlsch_info[mod_idP][pCC_id][UE_id].status = S_DL_NONE; - - // check if this has an RA process active - RA_t *ra; - for (i = 0; i < NB_RA_PROC_MAX; i++) { - ra = (RA_t *) & RC.mac[mod_idP]->common_channels[pCC_id].ra[i]; - if (ra->rnti == rntiP) { - ra->state = IDLE; - ra->timing_offset = 0; - ra->RRC_timer = 20; - ra->rnti = 0; - //break; - } - } + int i; + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + int UE_id = find_UE_id(mod_idP, rntiP); + int pCC_id; + if (UE_id == -1) { + LOG_W(MAC, "rrc_mac_remove_ue: UE %x not found\n", rntiP); return 0; + } + + pCC_id = UE_PCCID(mod_idP, UE_id); + + LOG_I(MAC, "Removing UE %d from Primary CC_id %d (rnti %x)\n", UE_id, + pCC_id, rntiP); + dump_ue_list(UE_list, 0); + + UE_list->active[UE_id] = FALSE; + UE_list->num_UEs--; + + if (UE_list->head == UE_id) + UE_list->head = UE_list->next[UE_id]; + else + UE_list->next[prev(UE_list, UE_id, 0)] = UE_list->next[UE_id]; + if (UE_list->head_ul == UE_id) + UE_list->head_ul = UE_list->next_ul[UE_id]; + else + UE_list->next_ul[prev(UE_list, UE_id, 0)] = + UE_list->next_ul[UE_id]; + + // clear all remaining pending transmissions + UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID0] = 0; + UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID1] = 0; + UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID2] = 0; + UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID3] = 0; + + UE_list->UE_template[pCC_id][UE_id].ul_SR = 0; + UE_list->UE_template[pCC_id][UE_id].rnti = NOT_A_RNTI; + UE_list->UE_template[pCC_id][UE_id].ul_active = FALSE; + eNB_ulsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI; + eNB_ulsch_info[mod_idP][pCC_id][UE_id].status = S_UL_NONE; + eNB_dlsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI; + eNB_dlsch_info[mod_idP][pCC_id][UE_id].status = S_DL_NONE; + + // check if this has an RA process active + RA_t *ra; + for (i = 0; i < NB_RA_PROC_MAX; i++) { + ra = (RA_t *) & RC.mac[mod_idP]->common_channels[pCC_id].ra[i]; + if (ra->rnti == rntiP) { + ra->state = IDLE; + ra->timing_offset = 0; + ra->RRC_timer = 20; + ra->rnti = 0; + //break; + } + } + + return 0; } int prev(UE_list_t * listP, int nodeP, int ul_flag) { - int j; + int j; - if (ul_flag == 0) { - if (nodeP == listP->head) { - return (nodeP); - } - - for (j = listP->head; j >= 0; j = listP->next[j]) { - if (listP->next[j] == nodeP) { - return (j); - } - } - } else { - if (nodeP == listP->head_ul) { - return (nodeP); - } - - for (j = listP->head_ul; j >= 0; j = listP->next_ul[j]) { - if (listP->next_ul[j] == nodeP) { - return (j); - } - } + if (ul_flag == 0) { + if (nodeP == listP->head) { + return (nodeP); } - LOG_E(MAC, - "error in prev(), could not find previous to %d in UE_list %s, should never happen, Dumping UE list\n", - nodeP, (ul_flag == 0) ? "DL" : "UL"); - dump_ue_list(listP, ul_flag); + for (j = listP->head; j >= 0; j = listP->next[j]) { + if (listP->next[j] == nodeP) { + return (j); + } + } + } else { + if (nodeP == listP->head_ul) { + return (nodeP); + } - return (-1); + for (j = listP->head_ul; j >= 0; j = listP->next_ul[j]) { + if (listP->next_ul[j] == nodeP) { + return (j); + } + } + } + + LOG_E(MAC, + "error in prev(), could not find previous to %d in UE_list %s, should never happen, Dumping UE list\n", + nodeP, (ul_flag == 0) ? "DL" : "UL"); + dump_ue_list(listP, ul_flag); + + return (-1); } void swap_UEs(UE_list_t * listP, int nodeiP, int nodejP, int ul_flag) { - int prev_i, prev_j, next_i, next_j; + int prev_i, prev_j, next_i, next_j; - LOG_T(MAC, "Swapping UE %d,%d\n", nodeiP, nodejP); - dump_ue_list(listP, ul_flag); + LOG_T(MAC, "Swapping UE %d,%d\n", nodeiP, nodejP); + dump_ue_list(listP, ul_flag); - prev_i = prev(listP, nodeiP, ul_flag); - prev_j = prev(listP, nodejP, ul_flag); + prev_i = prev(listP, nodeiP, ul_flag); + prev_j = prev(listP, nodejP, ul_flag); - AssertFatal((prev_i >= 0) && (prev_j >= 0), "swap_UEs: problem"); + AssertFatal((prev_i >= 0) && (prev_j >= 0), "swap_UEs: problem"); - if (ul_flag == 0) { - next_i = listP->next[nodeiP]; - next_j = listP->next[nodejP]; - } else { - next_i = listP->next_ul[nodeiP]; - next_j = listP->next_ul[nodejP]; + if (ul_flag == 0) { + next_i = listP->next[nodeiP]; + next_j = listP->next[nodejP]; + } else { + next_i = listP->next_ul[nodeiP]; + next_j = listP->next_ul[nodejP]; + } + + LOG_T(MAC, "[%s] next_i %d, next_i, next_j %d, head %d \n", + (ul_flag == 0) ? "DL" : "UL", next_i, next_j, listP->head); + + if (ul_flag == 0) { + + if (next_i == nodejP) { // case ... p(i) i j n(j) ... => ... p(j) j i n(i) ... + LOG_T(MAC, + "Case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...\n"); + + listP->next[nodeiP] = next_j; + listP->next[nodejP] = nodeiP; + + if (nodeiP == listP->head) { // case i j n(j) + listP->head = nodejP; + } else { + listP->next[prev_i] = nodejP; + } + } else if (next_j == nodeiP) { // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ... + LOG_T(MAC, + "Case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...\n"); + listP->next[nodejP] = next_i; + listP->next[nodeiP] = nodejP; + + if (nodejP == listP->head) { // case j i n(i) + listP->head = nodeiP; + } else { + listP->next[prev_j] = nodeiP; + } + } else { // case ... p(i) i n(i) ... p(j) j n(j) ... + listP->next[nodejP] = next_i; + listP->next[nodeiP] = next_j; + + if (nodeiP == listP->head) { + LOG_T(MAC, "changing head to %d\n", nodejP); + listP->head = nodejP; + listP->next[prev_j] = nodeiP; + } else if (nodejP == listP->head) { + LOG_D(MAC, "changing head to %d\n", nodeiP); + listP->head = nodeiP; + listP->next[prev_i] = nodejP; + } else { + listP->next[prev_i] = nodejP; + listP->next[prev_j] = nodeiP; + } } + } else { // ul_flag - LOG_T(MAC, "[%s] next_i %d, next_i, next_j %d, head %d \n", - (ul_flag == 0) ? "DL" : "UL", next_i, next_j, listP->head); + if (next_i == nodejP) { // case ... p(i) i j n(j) ... => ... p(j) j i n(i) ... + LOG_T(MAC, + "[UL] Case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...\n"); - if (ul_flag == 0) { + listP->next_ul[nodeiP] = next_j; + listP->next_ul[nodejP] = nodeiP; - if (next_i == nodejP) { // case ... p(i) i j n(j) ... => ... p(j) j i n(i) ... - LOG_T(MAC, - "Case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...\n"); + if (nodeiP == listP->head_ul) { // case i j n(j) + listP->head_ul = nodejP; + } else { + listP->next_ul[prev_i] = nodejP; + } + } else if (next_j == nodeiP) { // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ... + LOG_T(MAC, + "[UL]Case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...\n"); + listP->next_ul[nodejP] = next_i; + listP->next_ul[nodeiP] = nodejP; - listP->next[nodeiP] = next_j; - listP->next[nodejP] = nodeiP; + if (nodejP == listP->head_ul) { // case j i n(i) + listP->head_ul = nodeiP; + } else { + listP->next_ul[prev_j] = nodeiP; + } + } else { // case ... p(i) i n(i) ... p(j) j n(j) ... - if (nodeiP == listP->head) { // case i j n(j) - listP->head = nodejP; - } else { - listP->next[prev_i] = nodejP; - } - } else if (next_j == nodeiP) { // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ... - LOG_T(MAC, - "Case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...\n"); - listP->next[nodejP] = next_i; - listP->next[nodeiP] = nodejP; + listP->next_ul[nodejP] = next_i; + listP->next_ul[nodeiP] = next_j; - if (nodejP == listP->head) { // case j i n(i) - listP->head = nodeiP; - } else { - listP->next[prev_j] = nodeiP; - } - } else { // case ... p(i) i n(i) ... p(j) j n(j) ... - listP->next[nodejP] = next_i; - listP->next[nodeiP] = next_j; - - if (nodeiP == listP->head) { - LOG_T(MAC, "changing head to %d\n", nodejP); - listP->head = nodejP; - listP->next[prev_j] = nodeiP; - } else if (nodejP == listP->head) { - LOG_D(MAC, "changing head to %d\n", nodeiP); - listP->head = nodeiP; - listP->next[prev_i] = nodejP; - } else { - listP->next[prev_i] = nodejP; - listP->next[prev_j] = nodeiP; - } - } - } else { // ul_flag - - if (next_i == nodejP) { // case ... p(i) i j n(j) ... => ... p(j) j i n(i) ... - LOG_T(MAC, - "[UL] Case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...\n"); - - listP->next_ul[nodeiP] = next_j; - listP->next_ul[nodejP] = nodeiP; - - if (nodeiP == listP->head_ul) { // case i j n(j) - listP->head_ul = nodejP; - } else { - listP->next_ul[prev_i] = nodejP; - } - } else if (next_j == nodeiP) { // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ... - LOG_T(MAC, - "[UL]Case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...\n"); - listP->next_ul[nodejP] = next_i; - listP->next_ul[nodeiP] = nodejP; - - if (nodejP == listP->head_ul) { // case j i n(i) - listP->head_ul = nodeiP; - } else { - listP->next_ul[prev_j] = nodeiP; - } - } else { // case ... p(i) i n(i) ... p(j) j n(j) ... - - listP->next_ul[nodejP] = next_i; - listP->next_ul[nodeiP] = next_j; - - if (nodeiP == listP->head_ul) { - LOG_T(MAC, "[UL]changing head to %d\n", nodejP); - listP->head_ul = nodejP; - listP->next_ul[prev_j] = nodeiP; - } else if (nodejP == listP->head_ul) { - LOG_T(MAC, "[UL]changing head to %d\n", nodeiP); - listP->head_ul = nodeiP; - listP->next_ul[prev_i] = nodejP; - } else { - listP->next_ul[prev_i] = nodejP; - listP->next_ul[prev_j] = nodeiP; - } - } + if (nodeiP == listP->head_ul) { + LOG_T(MAC, "[UL]changing head to %d\n", nodejP); + listP->head_ul = nodejP; + listP->next_ul[prev_j] = nodeiP; + } else if (nodejP == listP->head_ul) { + LOG_T(MAC, "[UL]changing head to %d\n", nodeiP); + listP->head_ul = nodeiP; + listP->next_ul[prev_i] = nodejP; + } else { + listP->next_ul[prev_i] = nodejP; + listP->next_ul[prev_j] = nodeiP; + } } + } - LOG_T(MAC, "After swap\n"); - dump_ue_list(listP, ul_flag); + LOG_T(MAC, "After swap\n"); + dump_ue_list(listP, ul_flag); } -/* - #if defined(Rel10) || defined(Rel14) - unsigned char generate_mch_header( unsigned char *mac_header, - unsigned char num_sdus, - unsigned short *sdu_lengths, - unsigned char *sdu_lcids, - unsigned char msi, - unsigned char short_padding, - unsigned short post_padding) { - - SCH_SUBHEADER_FIXED *mac_header_ptr = (SCH_SUBHEADER_FIXED *)mac_header; - uint8_t first_element=0,last_size=0,i; - uint8_t mac_header_control_elements[2*num_sdus],*ce_ptr; - - ce_ptr = &mac_header_control_elements[0]; - - if ((short_padding == 1) || (short_padding == 2)) { - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_PADDING; - first_element=1; - last_size=1; - } - if (short_padding == 2) { - mac_header_ptr->E = 1; - mac_header_ptr++; - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_PADDING; - last_size=1; - } - - // SUBHEADER for MSI CE - if (msi != 0) {// there is MSI MAC Control Element - if (first_element>0) { - mac_header_ptr->E = 1; - mac_header_ptr+=last_size; - } - else { - first_element = 1; - } - if (num_sdus*2 < 128) { - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R = 0; - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E = 0; - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F = 0; - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID = MCH_SCHDL_INFO; - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L = num_sdus*2; - last_size=2; - } - else { - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->R = 0; - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->E = 0; - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->F = 1; - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->LCID = MCH_SCHDL_INFO; - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L = (num_sdus*2)&0x7fff; - last_size=3; - } - // Create the MSI MAC Control Element here - } - - // SUBHEADER for MAC SDU (MCCH+MTCHs) - for (i=0;i0) { - mac_header_ptr->E = 1; - mac_header_ptr+=last_size; - } - else { - first_element = 1; - } - if (sdu_lengths[i] < 128) { - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R = 0; - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E = 0; - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F = 0; - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID = sdu_lcids[i]; - ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L = (unsigned char)sdu_lengths[i]; - last_size=2; - } - else { - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->R = 0; - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->E = 0; - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->F = 1; - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->LCID = sdu_lcids[i]; - ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L = (unsigned short) sdu_lengths[i]&0x7fff; - last_size=3; - } - } - - if (post_padding>0) {// we have lots of padding at the end of the packet - mac_header_ptr->E = 1; - mac_header_ptr+=last_size; - // add a padding element - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_PADDING; - mac_header_ptr++; - } - else { // no end of packet padding - // last SDU subhead is of fixed type (sdu length implicitly to be computed at UE) - mac_header_ptr++; - } - - // Copy MSI Control Element to the end of the MAC Header if it presents - if ((ce_ptr-mac_header_control_elements) > 0) { - // printf("Copying %d bytes for control elements\n",ce_ptr-mac_header_control_elements); - memcpy((void*)mac_header_ptr,mac_header_control_elements,ce_ptr-mac_header_control_elements); - mac_header_ptr+=(unsigned char)(ce_ptr-mac_header_control_elements); - } - - return((unsigned char*)mac_header_ptr - mac_header); - } - #endif - */ - // This has to be updated to include BSR information uint8_t UE_is_to_be_scheduled(module_id_t module_idP, int CC_id, uint8_t UE_id) { - UE_TEMPLATE *UE_template = - &RC.mac[module_idP]->UE_list.UE_template[CC_id][UE_id]; - UE_sched_ctrl *UE_sched_ctl = - &RC.mac[module_idP]->UE_list.UE_sched_ctrl[UE_id]; + UE_TEMPLATE *UE_template = + &RC.mac[module_idP]->UE_list.UE_template[CC_id][UE_id]; + UE_sched_ctrl *UE_sched_ctl = + &RC.mac[module_idP]->UE_list.UE_sched_ctrl[UE_id]; - // do not schedule UE if UL is not working - if (UE_sched_ctl->ul_failure_timer > 0) - return (0); - if (UE_sched_ctl->ul_out_of_sync > 0) - return (0); + // do not schedule UE if UL is not working + if (UE_sched_ctl->ul_failure_timer > 0) + return (0); + if (UE_sched_ctl->ul_out_of_sync > 0) + return (0); - LOG_D(MAC, "[eNB %d][PUSCH] Checking UL requirements UE %d/%x\n", - module_idP, UE_id, UE_RNTI(module_idP, UE_id)); + LOG_D(MAC, "[eNB %d][PUSCH] Checking UL requirements UE %d/%x\n", + module_idP, UE_id, UE_RNTI(module_idP, UE_id)); - if ((UE_template->bsr_info[LCGID0] > 0) || (UE_template->bsr_info[LCGID1] > 0) || (UE_template->bsr_info[LCGID2] > 0) || (UE_template->bsr_info[LCGID3] > 0) || (UE_template->ul_SR > 0) || // uplink scheduling request - ((UE_sched_ctl->ul_inactivity_timer > 20) && (UE_sched_ctl->ul_scheduled == 0)) || // every 2 frames when RRC_CONNECTED - ((UE_sched_ctl->ul_inactivity_timer > 10) && (UE_sched_ctl->ul_scheduled == 0) && (mac_eNB_get_rrc_status(module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED))) // every Frame when not RRC_CONNECTED + if ((UE_template->bsr_info[LCGID0] > 0) || (UE_template->bsr_info[LCGID1] > 0) || (UE_template->bsr_info[LCGID2] > 0) || (UE_template->bsr_info[LCGID3] > 0) || (UE_template->ul_SR > 0) || // uplink scheduling request + ((UE_sched_ctl->ul_inactivity_timer > 20) && (UE_sched_ctl->ul_scheduled == 0)) || // every 2 frames when RRC_CONNECTED + ((UE_sched_ctl->ul_inactivity_timer > 10) && (UE_sched_ctl->ul_scheduled == 0) && (mac_eNB_get_rrc_status(module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED))) // every Frame when not RRC_CONNECTED { - LOG_D(MAC, - "[eNB %d][PUSCH] UE %d/%x should be scheduled (BSR0 %d,SR %d)\n", - module_idP, UE_id, UE_RNTI(module_idP, UE_id), - UE_template->bsr_info[LCGID0], UE_template->ul_SR); - return (1); + LOG_D(MAC, + "[eNB %d][PUSCH] UE %d/%x should be scheduled (BSR0 %d,SR %d)\n", + module_idP, UE_id, UE_RNTI(module_idP, UE_id), + UE_template->bsr_info[LCGID0], UE_template->ul_SR); + return (1); } else { - return (0); - } + return (0); + } } uint8_t get_tmode(module_id_t module_idP, int CC_idP, int UE_idP) { - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; - struct PhysicalConfigDedicated *physicalConfigDedicated = - eNB->UE_list.physicalConfigDedicated[CC_idP][UE_idP]; + struct PhysicalConfigDedicated *physicalConfigDedicated = + eNB->UE_list.physicalConfigDedicated[CC_idP][UE_idP]; - if (physicalConfigDedicated == NULL) { // RRCConnectionSetup not received by UE yet - AssertFatal(cc->p_eNB <= 2, "p_eNB is %d, should be <2\n", - cc->p_eNB); - return (cc->p_eNB); - } else { - AssertFatal(physicalConfigDedicated->antennaInfo != NULL, - "antennaInfo is null for CCId %d, UEid %d\n", CC_idP, - UE_idP); + if (physicalConfigDedicated == NULL) { // RRCConnectionSetup not received by UE yet + AssertFatal(cc->p_eNB <= 2, "p_eNB is %d, should be <2\n", + cc->p_eNB); + return (cc->p_eNB); + } else { + AssertFatal(physicalConfigDedicated->antennaInfo != NULL, + "antennaInfo is null for CCId %d, UEid %d\n", CC_idP, + UE_idP); - AssertFatal(physicalConfigDedicated->antennaInfo->present != - PhysicalConfigDedicated__antennaInfo_PR_NOTHING, - "antennaInfo (mod_id %d, CC_id %d) is set to NOTHING\n", - module_idP, CC_idP); + AssertFatal(physicalConfigDedicated->antennaInfo->present != + PhysicalConfigDedicated__antennaInfo_PR_NOTHING, + "antennaInfo (mod_id %d, CC_id %d) is set to NOTHING\n", + module_idP, CC_idP); - if (physicalConfigDedicated->antennaInfo->present == - PhysicalConfigDedicated__antennaInfo_PR_explicitValue) { - return (physicalConfigDedicated->antennaInfo-> - choice.explicitValue.transmissionMode); - } else if (physicalConfigDedicated->antennaInfo->present == - PhysicalConfigDedicated__antennaInfo_PR_defaultValue) { - AssertFatal(cc->p_eNB <= 2, "p_eNB is %d, should be <2\n", - cc->p_eNB); - return (cc->p_eNB); - } else - AssertFatal(1 == 0, "Shouldn't be here\n"); - } + if (physicalConfigDedicated->antennaInfo->present == + PhysicalConfigDedicated__antennaInfo_PR_explicitValue) { + return (physicalConfigDedicated->antennaInfo-> + choice.explicitValue.transmissionMode); + } else if (physicalConfigDedicated->antennaInfo->present == + PhysicalConfigDedicated__antennaInfo_PR_defaultValue) { + AssertFatal(cc->p_eNB <= 2, "p_eNB is %d, should be <2\n", + cc->p_eNB); + return (cc->p_eNB); + } else + AssertFatal(1 == 0, "Shouldn't be here\n"); + } } int8_t get_ULharq(module_id_t module_idP, int CC_idP, uint16_t frameP, uint8_t subframeP) { - uint8_t ret = -1; - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; - - if (cc->tdd_Config == NULL) { // FDD - ret = (((frameP << 1) + subframeP) & 7); - } else { - switch (cc->tdd_Config->subframeAssignment) { - case 1: - if ((subframeP == 2) || - (subframeP == 3) || (subframeP == 7) || (subframeP == 8)) - switch (subframeP) { - case 2: - case 3: - ret = (subframeP - 2); - break; - - case 7: - case 8: - ret = (subframeP - 5); - break; - - default: - AssertFatal(1 == 0, - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframeP, - (int) cc->tdd_Config->subframeAssignment); - break; - } - - break; + uint8_t ret = -1; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; + if (cc->tdd_Config == NULL) { // FDD + ret = (((frameP << 1) + subframeP) & 7); + } else { + switch (cc->tdd_Config->subframeAssignment) { + case 1: + if ((subframeP == 2) || + (subframeP == 3) || (subframeP == 7) || (subframeP == 8)) + switch (subframeP) { case 2: - AssertFatal((subframeP == 2) || (subframeP == 7), - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframeP, - (int) cc->tdd_Config->subframeAssignment); - ret = (subframeP / 7); - break; - case 3: - AssertFatal((subframeP > 1) && (subframeP < 5), - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframeP, - (int) cc->tdd_Config->subframeAssignment); - ret = (subframeP - 2); - break; + ret = (subframeP - 2); + break; - case 4: - AssertFatal((subframeP > 1) && (subframeP < 4), - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframeP, - (int) cc->tdd_Config->subframeAssignment); - ret = (subframeP - 2); - break; - - case 5: - AssertFatal(subframeP == 2, - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframeP, - (int) cc->tdd_Config->subframeAssignment); - ret = (subframeP - 2); - break; + case 7: + case 8: + ret = (subframeP - 5); + break; default: - AssertFatal(1 == 0, - "subframe2_harq_pid, Unsupported TDD mode %d\n", - (int) cc->tdd_Config->subframeAssignment); - break; + AssertFatal(1 == 0, + "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframeP, + (int) cc->tdd_Config->subframeAssignment); + break; } - } - AssertFatal(ret != -1, - "invalid harq_pid(%d) at SFN/SF = %d/%d\n", (int8_t) ret, - frameP, subframeP); - return ret; + break; + + case 2: + AssertFatal((subframeP == 2) || (subframeP == 7), + "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframeP, + (int) cc->tdd_Config->subframeAssignment); + ret = (subframeP / 7); + break; + + case 3: + AssertFatal((subframeP > 1) && (subframeP < 5), + "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframeP, + (int) cc->tdd_Config->subframeAssignment); + ret = (subframeP - 2); + break; + + case 4: + AssertFatal((subframeP > 1) && (subframeP < 4), + "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframeP, + (int) cc->tdd_Config->subframeAssignment); + ret = (subframeP - 2); + break; + + case 5: + AssertFatal(subframeP == 2, + "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframeP, + (int) cc->tdd_Config->subframeAssignment); + ret = (subframeP - 2); + break; + + default: + AssertFatal(1 == 0, + "subframe2_harq_pid, Unsupported TDD mode %d\n", + (int) cc->tdd_Config->subframeAssignment); + break; + } + } + + AssertFatal(ret != -1, + "invalid harq_pid(%d) at SFN/SF = %d/%d\n", (int8_t) ret, + frameP, subframeP); + return ret; } uint16_t getRIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs) { - uint16_t RIV; + uint16_t RIV; - if (Lcrbs <= (1 + (N_RB_DL >> 1))) - RIV = (N_RB_DL * (Lcrbs - 1)) + RBstart; - else - RIV = (N_RB_DL * (N_RB_DL + 1 - Lcrbs)) + (N_RB_DL - 1 - RBstart); + if (Lcrbs <= (1 + (N_RB_DL >> 1))) + RIV = (N_RB_DL * (Lcrbs - 1)) + RBstart; + else + RIV = (N_RB_DL * (N_RB_DL + 1 - Lcrbs)) + (N_RB_DL - 1 - RBstart); - return (RIV); + return (RIV); } uint32_t allocate_prbs(int UE_id, unsigned char nb_rb, int N_RB_DL, uint32_t * rballoc) { - int i; - uint32_t rballoc_dci = 0; - unsigned char nb_rb_alloc = 0; + int i; + uint32_t rballoc_dci = 0; + unsigned char nb_rb_alloc = 0; - for (i = 0; i < (N_RB_DL - 2); i += 2) { - if (((*rballoc >> i) & 3) == 0) { - *rballoc |= (3 << i); - rballoc_dci |= (1 << ((12 - i) >> 1)); - nb_rb_alloc += 2; - } - - if (nb_rb_alloc == nb_rb) { - return (rballoc_dci); - } + for (i = 0; i < (N_RB_DL - 2); i += 2) { + if (((*rballoc >> i) & 3) == 0) { + *rballoc |= (3 << i); + rballoc_dci |= (1 << ((12 - i) >> 1)); + nb_rb_alloc += 2; } - if ((N_RB_DL & 1) == 1) { - if ((*rballoc >> (N_RB_DL - 1) & 1) == 0) { - *rballoc |= (1 << (N_RB_DL - 1)); - rballoc_dci |= 1; - } + if (nb_rb_alloc == nb_rb) { + return (rballoc_dci); } + } - return (rballoc_dci); + if ((N_RB_DL & 1) == 1) { + if ((*rballoc >> (N_RB_DL - 1) & 1) == 0) { + *rballoc |= (1 << (N_RB_DL - 1)); + rballoc_dci |= 1; + } + } + + return (rballoc_dci); } int get_bw_index(module_id_t module_id, uint8_t CC_id) { - int bw_index = 0; + int bw_index = 0; - int N_RB_DL = - to_prb(RC.mac[module_id]->common_channels[CC_id].mib-> - message.dl_Bandwidth); + int N_RB_DL = + to_prb(RC.mac[module_id]->common_channels[CC_id].mib-> + message.dl_Bandwidth); - switch (N_RB_DL) { - case 6: // 1.4 MHz - bw_index = 0; - break; + switch (N_RB_DL) { + case 6: // 1.4 MHz + bw_index = 0; + break; - case 25: // 5HMz - bw_index = 1; - break; + case 25: // 5HMz + bw_index = 1; + break; - case 50: // 10HMz - bw_index = 2; - break; + case 50: // 10HMz + bw_index = 2; + break; - case 100: // 20HMz - bw_index = 3; - break; + case 100: // 20HMz + bw_index = 3; + break; - default: - bw_index = 1; - LOG_W(MAC, - "[eNB %d] N_RB_DL %d unknown for CC_id %d, setting bw_index to 1\n", - module_id, N_RB_DL, CC_id); - break; - } + default: + bw_index = 1; + LOG_W(MAC, + "[eNB %d] N_RB_DL %d unknown for CC_id %d, setting bw_index to 1\n", + module_id, N_RB_DL, CC_id); + break; + } - return bw_index; + return bw_index; } int get_min_rb_unit(module_id_t module_id, uint8_t CC_id) { - int min_rb_unit = 0; - int N_RB_DL = - to_prb(RC.mac[module_id]->common_channels[CC_id].mib-> - message.dl_Bandwidth); + int min_rb_unit = 0; + int N_RB_DL = + to_prb(RC.mac[module_id]->common_channels[CC_id].mib-> + message.dl_Bandwidth); - switch (N_RB_DL) { - case 6: // 1.4 MHz - min_rb_unit = 1; - break; + switch (N_RB_DL) { + case 6: // 1.4 MHz + min_rb_unit = 1; + break; - case 25: // 5HMz - min_rb_unit = 2; - break; + case 25: // 5HMz + min_rb_unit = 2; + break; - case 50: // 10HMz - min_rb_unit = 3; - break; + case 50: // 10HMz + min_rb_unit = 3; + break; - case 100: // 20HMz - min_rb_unit = 4; - break; + case 100: // 20HMz + min_rb_unit = 4; + break; - default: - min_rb_unit = 2; - LOG_W(MAC, - "[eNB %d] N_DL_RB %d unknown for CC_id %d, setting min_rb_unit to 2\n", - module_id, N_RB_DL, CC_id); - break; - } + default: + min_rb_unit = 2; + LOG_W(MAC, + "[eNB %d] N_DL_RB %d unknown for CC_id %d, setting min_rb_unit to 2\n", + module_id, N_RB_DL, CC_id); + break; + } - return min_rb_unit; + return min_rb_unit; } uint32_t allocate_prbs_sub(int nb_rb, int N_RB_DL, int N_RBG, uint8_t * rballoc) { - int check = 0; //check1=0,check2=0; - uint32_t rballoc_dci = 0; - //uint8_t number_of_subbands=13; + int check = 0; //check1=0,check2=0; + uint32_t rballoc_dci = 0; + //uint8_t number_of_subbands=13; - LOG_T(MAC, "*****Check1RBALLOC****: %d%d%d%d (nb_rb %d,N_RBG %d)\n", - rballoc[3], rballoc[2], rballoc[1], rballoc[0], nb_rb, N_RBG); + LOG_T(MAC, "*****Check1RBALLOC****: %d%d%d%d (nb_rb %d,N_RBG %d)\n", + rballoc[3], rballoc[2], rballoc[1], rballoc[0], nb_rb, N_RBG); - while ((nb_rb > 0) && (check < N_RBG)) { - //printf("rballoc[%d] %d\n",check,rballoc[check]); - if (rballoc[check] == 1) { - rballoc_dci |= (1 << ((N_RBG - 1) - check)); + while ((nb_rb > 0) && (check < N_RBG)) { + //printf("rballoc[%d] %d\n",check,rballoc[check]); + if (rballoc[check] == 1) { + rballoc_dci |= (1 << ((N_RBG - 1) - check)); - switch (N_RB_DL) { - case 6: - nb_rb--; - break; + switch (N_RB_DL) { + case 6: + nb_rb--; + break; - case 25: - if ((check == N_RBG - 1)) { - nb_rb--; - } else { - nb_rb -= 2; - } - - break; - - case 50: - if ((check == N_RBG - 1)) { - nb_rb -= 2; - } else { - nb_rb -= 3; - } - - break; - - case 100: - nb_rb -= 4; - break; - } + case 25: + if ((check == N_RBG - 1)) { + nb_rb--; + } else { + nb_rb -= 2; } - // printf("rb_alloc %x\n",rballoc_dci); - check = check + 1; - // check1 = check1+2; - } - // rballoc_dci = (rballoc_dci)&(0x1fff); - LOG_T(MAC, "*********RBALLOC : %x\n", rballoc_dci); - // exit(-1); - return (rballoc_dci); + break; + + case 50: + if ((check == N_RBG - 1)) { + nb_rb -= 2; + } else { + nb_rb -= 3; + } + + break; + + case 100: + nb_rb -= 4; + break; + } + } + // printf("rb_alloc %x\n",rballoc_dci); + check = check + 1; + // check1 = check1+2; + } + + // rballoc_dci = (rballoc_dci)&(0x1fff); + LOG_T(MAC, "*********RBALLOC : %x\n", rballoc_dci); + // exit(-1); + return (rballoc_dci); } int get_subbandsize(uint8_t dl_Bandwidth) { - uint8_t ss[6] = { 6, 4, 4, 6, 8, 8 }; + uint8_t ss[6] = { 6, 4, 4, 6, 8, 8 }; - AssertFatal(dl_Bandwidth < 6, "dl_Bandwidth %d is out of bounds\n", - dl_Bandwidth); + AssertFatal(dl_Bandwidth < 6, "dl_Bandwidth %d is out of bounds\n", + dl_Bandwidth); - return (ss[dl_Bandwidth]); + return (ss[dl_Bandwidth]); } int get_nb_subband(int N_RB_DL) { - int nb_sb = 0; + int nb_sb = 0; - switch (N_RB_DL) { - case 6: - nb_sb = 0; - break; + switch (N_RB_DL) { + case 6: + nb_sb = 0; + break; - case 15: - nb_sb = 4; // sb_size =4 + case 15: + nb_sb = 4; // sb_size =4 - case 25: - nb_sb = 7; // sb_size =4, 1 sb with 1PRB, 6 with 2 RBG, each has 2 PRBs - break; + case 25: + nb_sb = 7; // sb_size =4, 1 sb with 1PRB, 6 with 2 RBG, each has 2 PRBs + break; - case 50: // sb_size =6 - nb_sb = 9; - break; + case 50: // sb_size =6 + nb_sb = 9; + break; - case 75: // sb_size =8 - nb_sb = 10; - break; + case 75: // sb_size =8 + nb_sb = 10; + break; - case 100: // sb_size =8 , 1 sb with 1 RBG + 12 sb with 2RBG, each RBG has 4 PRBs - nb_sb = 13; - break; + case 100: // sb_size =8 , 1 sb with 1 RBG + 12 sb with 2RBG, each RBG has 4 PRBs + nb_sb = 13; + break; - default: - nb_sb = 0; - break; - } + default: + nb_sb = 0; + break; + } - return nb_sb; + return nb_sb; } void init_CCE_table(int module_idP, int CC_idP) { - memset(RC.mac[module_idP]->CCE_table[CC_idP], 0, 800 * sizeof(int)); + memset(RC.mac[module_idP]->CCE_table[CC_idP], 0, 800 * sizeof(int)); } @@ -2820,711 +2472,626 @@ get_nCCE_offset(int *CCE_table, const int common_dci, const unsigned short rnti, const unsigned char subframe) { - int search_space_free, m, nb_candidates = 0, l, i; - unsigned int Yk; - /* - printf("CCE Allocation: "); - for (i=0;i= 0; m--) { + for (m = nb_candidates - 1; m >= 0; m--) { - search_space_free = 1; - for (l = 0; l < L; l++) { + search_space_free = 1; + for (l = 0; l < L; l++) { - // printf("CCE_table[%d] %d\n",(m*L)+l,CCE_table[(m*L)+l]); - if (CCE_table[(m * L) + l] == 1) { - search_space_free = 0; - break; - } - } - - if (search_space_free == 1) { - - // printf("returning %d\n",m*L); - - for (l = 0; l < L; l++) - CCE_table[(m * L) + l] = 1; - return (m * L); - } + // printf("CCE_table[%d] %d\n",(m*L)+l,CCE_table[(m*L)+l]); + if (CCE_table[(m * L) + l] == 1) { + search_space_free = 0; + break; } + } - return (-1); + if (search_space_free == 1) { - } else { // Find first available in ue specific search space - // according to procedure in Section 9.1.1 of 36.213 (v. 8.6) - // compute Yk - Yk = (unsigned int) rnti; + // printf("returning %d\n",m*L); - for (i = 0; i <= subframe; i++) - Yk = (Yk * 39827) % 65537; - - Yk = Yk % (nCCE / L); - - switch (L) { - case 1: - case 2: - nb_candidates = 6; - break; - - case 4: - case 8: - nb_candidates = 2; - break; - - default: - DevParam(L, nCCE, rnti); - break; - } - - LOG_D(MAC, "rnti %x, Yk = %d, nCCE %d (nCCE/L %d),nb_cand %d\n", - rnti, Yk, nCCE, nCCE / L, nb_candidates); - - for (m = 0; m < nb_candidates; m++) { - search_space_free = 1; - - for (l = 0; l < L; l++) { - int cce = (((Yk + m) % (nCCE / L)) * L) + l; - if (cce >= nCCE || CCE_table[cce] == 1) { - search_space_free = 0; - break; - } - } - - if (search_space_free == 1) { - for (l = 0; l < L; l++) - CCE_table[(((Yk + m) % (nCCE / L)) * L) + l] = 1; - - return (((Yk + m) % (nCCE / L)) * L); - } - } - - return (-1); - } -} - -void -dump_CCE_table(int *CCE_table, const int nCCE, - const unsigned short rnti, const int subframe, int L) -{ - int nb_candidates = 0, i; - unsigned int Yk; - - printf("CCE 0: "); - for (i = 0; i < nCCE; i++) { - printf("%1d.", CCE_table[i]); - if ((i & 7) == 7) - printf("\n CCE %d: ", i); + for (l = 0; l < L; l++) + CCE_table[(m * L) + l] = 1; + return (m * L); + } } + return (-1); + + } else { // Find first available in ue specific search space + // according to procedure in Section 9.1.1 of 36.213 (v. 8.6) + // compute Yk Yk = (unsigned int) rnti; for (i = 0; i <= subframe; i++) - Yk = (Yk * 39827) % 65537; + Yk = (Yk * 39827) % 65537; Yk = Yk % (nCCE / L); switch (L) { case 1: case 2: - nb_candidates = 6; - break; + nb_candidates = 6; + break; case 4: case 8: - nb_candidates = 2; - break; + nb_candidates = 2; + break; default: - DevParam(L, nCCE, rnti); - break; + DevParam(L, nCCE, rnti); + break; } - printf("rnti %x, Yk*L = %d, nCCE %d (nCCE/L %d),nb_cand*L %d\n", rnti, - Yk * L, nCCE, nCCE / L, nb_candidates * L); + LOG_D(MAC, "rnti %x, Yk = %d, nCCE %d (nCCE/L %d),nb_cand %d\n", + rnti, Yk, nCCE, nCCE / L, nb_candidates); + + for (m = 0; m < nb_candidates; m++) { + search_space_free = 1; + + for (l = 0; l < L; l++) { + int cce = (((Yk + m) % (nCCE / L)) * L) + l; + if (cce >= nCCE || CCE_table[cce] == 1) { + search_space_free = 0; + break; + } + } + + if (search_space_free == 1) { + for (l = 0; l < L; l++) + CCE_table[(((Yk + m) % (nCCE / L)) * L) + l] = 1; + + return (((Yk + m) % (nCCE / L)) * L); + } + } + + return (-1); + } +} + +void +dump_CCE_table(int *CCE_table, const int nCCE, + const unsigned short rnti, const int subframe, int L) +{ + int nb_candidates = 0, i; + unsigned int Yk; + + printf("CCE 0: "); + for (i = 0; i < nCCE; i++) { + printf("%1d.", CCE_table[i]); + if ((i & 7) == 7) + printf("\n CCE %d: ", i); + } + + Yk = (unsigned int) rnti; + + for (i = 0; i <= subframe; i++) + Yk = (Yk * 39827) % 65537; + + Yk = Yk % (nCCE / L); + + switch (L) { + case 1: + case 2: + nb_candidates = 6; + break; + + case 4: + case 8: + nb_candidates = 2; + break; + + default: + DevParam(L, nCCE, rnti); + break; + } + + printf("rnti %x, Yk*L = %d, nCCE %d (nCCE/L %d),nb_cand*L %d\n", rnti, + Yk * L, nCCE, nCCE / L, nb_candidates * L); } uint16_t getnquad(COMMON_channels_t * cc, uint8_t num_pdcch_symbols, uint8_t mi) { - uint16_t Nreg = 0; + uint16_t Nreg = 0; - AssertFatal(cc != NULL, "cc is null\n"); - AssertFatal(cc->mib != NULL, "cc->mib is null\n"); + AssertFatal(cc != NULL, "cc is null\n"); + AssertFatal(cc->mib != NULL, "cc->mib is null\n"); - int N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); - int phich_resource = get_phich_resource_times6(cc); + int N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); + int phich_resource = get_phich_resource_times6(cc); - uint8_t Ngroup_PHICH = (phich_resource * N_RB_DL) / 48; + uint8_t Ngroup_PHICH = (phich_resource * N_RB_DL) / 48; - if (((phich_resource * N_RB_DL) % 48) > 0) - Ngroup_PHICH++; + if (((phich_resource * N_RB_DL) % 48) > 0) + Ngroup_PHICH++; - if (cc->Ncp == 1) { - Ngroup_PHICH <<= 1; + if (cc->Ncp == 1) { + Ngroup_PHICH <<= 1; + } + + Ngroup_PHICH *= mi; + + if ((num_pdcch_symbols > 0) && (num_pdcch_symbols < 4)) + switch (N_RB_DL) { + case 6: + Nreg = 12 + (num_pdcch_symbols - 1) * 18; + break; + + case 25: + Nreg = 50 + (num_pdcch_symbols - 1) * 75; + break; + + case 50: + Nreg = 100 + (num_pdcch_symbols - 1) * 150; + break; + + case 100: + Nreg = 200 + (num_pdcch_symbols - 1) * 300; + break; + + default: + return (0); } - - Ngroup_PHICH *= mi; - - if ((num_pdcch_symbols > 0) && (num_pdcch_symbols < 4)) - switch (N_RB_DL) { - case 6: - Nreg = 12 + (num_pdcch_symbols - 1) * 18; - break; - - case 25: - Nreg = 50 + (num_pdcch_symbols - 1) * 75; - break; - - case 50: - Nreg = 100 + (num_pdcch_symbols - 1) * 150; - break; - - case 100: - Nreg = 200 + (num_pdcch_symbols - 1) * 300; - break; - - default: - return (0); - } - // printf("Nreg %d (%d)\n",Nreg,Nreg - 4 - (3*Ngroup_PHICH)); - return (Nreg - 4 - (3 * Ngroup_PHICH)); + // printf("Nreg %d (%d)\n",Nreg,Nreg - 4 - (3*Ngroup_PHICH)); + return (Nreg - 4 - (3 * Ngroup_PHICH)); } uint16_t getnCCE(COMMON_channels_t * cc, uint8_t num_pdcch_symbols, uint8_t mi) { - AssertFatal(cc != NULL, "cc is null\n"); - return (getnquad(cc, num_pdcch_symbols, mi) / 9); + AssertFatal(cc != NULL, "cc is null\n"); + return (getnquad(cc, num_pdcch_symbols, mi) / 9); } uint8_t getmi(COMMON_channels_t * cc, int subframe) { - AssertFatal(cc != NULL, "cc is null\n"); + AssertFatal(cc != NULL, "cc is null\n"); - // for FDD - if (cc->tdd_Config == NULL) // FDD - return 1; + // for FDD + if (cc->tdd_Config == NULL) // FDD + return 1; - // for TDD - switch (cc->tdd_Config->subframeAssignment) { - case 0: - if ((subframe == 0) || (subframe == 5)) - return (2); - else - return (1); + // for TDD + switch (cc->tdd_Config->subframeAssignment) { + case 0: + if ((subframe == 0) || (subframe == 5)) + return (2); + else + return (1); - break; + break; - case 1: - if ((subframe == 0) || (subframe == 5)) - return (0); - else - return (1); + case 1: + if ((subframe == 0) || (subframe == 5)) + return (0); + else + return (1); - break; + break; - case 2: - if ((subframe == 3) || (subframe == 8)) - return (1); - else - return (0); + case 2: + if ((subframe == 3) || (subframe == 8)) + return (1); + else + return (0); - break; + break; - case 3: - if ((subframe == 0) || (subframe == 8) || (subframe == 9)) - return (1); - else - return (0); + case 3: + if ((subframe == 0) || (subframe == 8) || (subframe == 9)) + return (1); + else + return (0); - break; + break; - case 4: - if ((subframe == 8) || (subframe == 9)) - return (1); - else - return (0); + case 4: + if ((subframe == 8) || (subframe == 9)) + return (1); + else + return (0); - break; + break; - case 5: - if (subframe == 8) - return (1); - else - return (0); + case 5: + if (subframe == 8) + return (1); + else + return (0); - break; + break; - case 6: - return (1); - break; + case 6: + return (1); + break; - default: - return (0); - } + default: + return (0); + } } uint16_t get_nCCE_max(COMMON_channels_t * cc, int num_pdcch_symbols, int subframe) { - AssertFatal(cc != NULL, "cc is null\n"); - return (getnCCE(cc, num_pdcch_symbols, getmi(cc, subframe))); + AssertFatal(cc != NULL, "cc is null\n"); + return (getnCCE(cc, num_pdcch_symbols, getmi(cc, subframe))); } // Allocate the CCEs int allocate_CCEs(int module_idP, int CC_idP, int subframeP, int test_onlyP) { - int *CCE_table = RC.mac[module_idP]->CCE_table[CC_idP]; - nfapi_dl_config_request_body_t *DL_req = - &RC.mac[module_idP]->DL_req[CC_idP].dl_config_request_body; - nfapi_hi_dci0_request_body_t *HI_DCI0_req = - &RC.mac[module_idP]->HI_DCI0_req[CC_idP].hi_dci0_request_body; - nfapi_dl_config_request_pdu_t *dl_config_pdu = - &DL_req->dl_config_pdu_list[0]; - nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = - &HI_DCI0_req->hi_dci0_pdu_list[0]; - int nCCE_max = - get_nCCE_max(&RC.mac[module_idP]->common_channels[CC_idP], 1, - subframeP); - int fCCE; - int i, j, idci; - int nCCE = 0; + int *CCE_table = RC.mac[module_idP]->CCE_table[CC_idP]; + nfapi_dl_config_request_body_t *DL_req = + &RC.mac[module_idP]->DL_req[CC_idP].dl_config_request_body; + nfapi_hi_dci0_request_body_t *HI_DCI0_req = + &RC.mac[module_idP]->HI_DCI0_req[CC_idP].hi_dci0_request_body; + nfapi_dl_config_request_pdu_t *dl_config_pdu = + &DL_req->dl_config_pdu_list[0]; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = + &HI_DCI0_req->hi_dci0_pdu_list[0]; + int nCCE_max = + get_nCCE_max(&RC.mac[module_idP]->common_channels[CC_idP], 1, + subframeP); + int fCCE; + int i, j, idci; + int nCCE = 0; - LOG_D(MAC, - "Allocate CCEs subframe %d, test %d : (DL PDU %d, DL DCI %d, UL %d)\n", - subframeP, test_onlyP, DL_req->number_pdu, DL_req->number_dci, - HI_DCI0_req->number_of_dci); - DL_req->number_pdcch_ofdm_symbols = 1; + LOG_D(MAC, + "Allocate CCEs subframe %d, test %d : (DL PDU %d, DL DCI %d, UL %d)\n", + subframeP, test_onlyP, DL_req->number_pdu, DL_req->number_dci, + HI_DCI0_req->number_of_dci); + DL_req->number_pdcch_ofdm_symbols = 1; - try_again: - init_CCE_table(module_idP, CC_idP); - nCCE = 0; + try_again: + init_CCE_table(module_idP, CC_idP); + nCCE = 0; - for (i = 0, idci = 0; i < DL_req->number_pdu; i++) { - // allocate DL common DCIs first - if ((dl_config_pdu[i].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) - && (dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type == - 2)) { - LOG_D(MAC, - "Trying to allocate COMMON DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", - idci, DL_req->number_dci + HI_DCI0_req->number_of_dci, - DL_req->number_dci, HI_DCI0_req->number_of_dci, - dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti, - dl_config_pdu[i].dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level, nCCE, nCCE_max, - DL_req->number_pdcch_ofdm_symbols); + for (i = 0, idci = 0; i < DL_req->number_pdu; i++) { + // allocate DL common DCIs first + if ((dl_config_pdu[i].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) + && (dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type == + 2)) { + LOG_D(MAC, + "Trying to allocate COMMON DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", + idci, DL_req->number_dci + HI_DCI0_req->number_of_dci, + DL_req->number_dci, HI_DCI0_req->number_of_dci, + dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti, + dl_config_pdu[i].dci_dl_pdu. + dci_dl_pdu_rel8.aggregation_level, nCCE, nCCE_max, + DL_req->number_pdcch_ofdm_symbols); - if (nCCE + - (dl_config_pdu[i].dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level) > nCCE_max) { - if (DL_req->number_pdcch_ofdm_symbols == 3) - goto failed; - LOG_D(MAC, - "Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n", - DL_req->number_pdcch_ofdm_symbols); - DL_req->number_pdcch_ofdm_symbols++; - nCCE_max = - get_nCCE_max(&RC.mac[module_idP]-> - common_channels[CC_idP], - DL_req->number_pdcch_ofdm_symbols, - subframeP); - goto try_again; - } - // number of CCEs left can potentially hold this allocation - fCCE = get_nCCE_offset(CCE_table, - dl_config_pdu[i]. - dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level, nCCE_max, 1, - dl_config_pdu[i]. - dci_dl_pdu.dci_dl_pdu_rel8.rnti, - subframeP); - if (fCCE == -1) { - if (DL_req->number_pdcch_ofdm_symbols == 3) { - LOG_D(MAC, - "subframe %d: Dropping Allocation for RNTI %x\n", - subframeP, - dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8. - rnti); - for (j = 0; j <= i; j++) { - if (dl_config_pdu[j].pdu_type == - NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) - LOG_D(MAC, - "DCI %d/%d (%d,%d) : rnti %x dci format %d, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", - j, - DL_req->number_dci + - HI_DCI0_req->number_of_dci, - DL_req->number_dci, - HI_DCI0_req->number_of_dci, - dl_config_pdu[j]. - dci_dl_pdu.dci_dl_pdu_rel8.rnti, - dl_config_pdu[j]. - dci_dl_pdu.dci_dl_pdu_rel8.dci_format, - dl_config_pdu[j]. - dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level, nCCE, nCCE_max, - DL_req->number_pdcch_ofdm_symbols); - } - //dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<L); - goto failed; - } - LOG_D(MAC, - "Can't fit DCI allocations with %d PDCCH symbols (rnti condition), increasing by 1\n", - DL_req->number_pdcch_ofdm_symbols); - - DL_req->number_pdcch_ofdm_symbols++; - nCCE_max = - get_nCCE_max(&RC.mac[module_idP]-> - common_channels[CC_idP], - DL_req->number_pdcch_ofdm_symbols, - subframeP); - goto try_again; - } // fCCE==-1 - - // the allocation is feasible, rnti rule passes - nCCE += + if (nCCE + + (dl_config_pdu[i].dci_dl_pdu. + dci_dl_pdu_rel8.aggregation_level) > nCCE_max) { + if (DL_req->number_pdcch_ofdm_symbols == 3) + goto failed; + LOG_D(MAC, + "Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n", + DL_req->number_pdcch_ofdm_symbols); + DL_req->number_pdcch_ofdm_symbols++; + nCCE_max = + get_nCCE_max(&RC.mac[module_idP]-> + common_channels[CC_idP], + DL_req->number_pdcch_ofdm_symbols, + subframeP); + goto try_again; + } + // number of CCEs left can potentially hold this allocation + fCCE = get_nCCE_offset(CCE_table, + dl_config_pdu[i]. + dci_dl_pdu.dci_dl_pdu_rel8. + aggregation_level, nCCE_max, 1, + dl_config_pdu[i]. + dci_dl_pdu.dci_dl_pdu_rel8.rnti, + subframeP); + if (fCCE == -1) { + if (DL_req->number_pdcch_ofdm_symbols == 3) { + LOG_D(MAC, + "subframe %d: Dropping Allocation for RNTI %x\n", + subframeP, dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level; - LOG_D(MAC, "Allocating at nCCE %d\n", fCCE); - if (test_onlyP == 0) { - dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = fCCE; - LOG_D(MAC, - "Allocate COMMON DCI CCEs subframe %d, test %d => L %d fCCE %d\n", - subframeP, test_onlyP, - dl_config_pdu[i].dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level, fCCE); - } - idci++; + rnti); + for (j = 0; j <= i; j++) { + if (dl_config_pdu[j].pdu_type == + NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) + LOG_D(MAC, + "DCI %d/%d (%d,%d) : rnti %x dci format %d, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", + j, + DL_req->number_dci + + HI_DCI0_req->number_of_dci, + DL_req->number_dci, + HI_DCI0_req->number_of_dci, + dl_config_pdu[j]. + dci_dl_pdu.dci_dl_pdu_rel8.rnti, + dl_config_pdu[j]. + dci_dl_pdu.dci_dl_pdu_rel8.dci_format, + dl_config_pdu[j]. + dci_dl_pdu.dci_dl_pdu_rel8. + aggregation_level, nCCE, nCCE_max, + DL_req->number_pdcch_ofdm_symbols); + } + //dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<L); + goto failed; } - } // for i = 0 ... num_DL_DCIs + LOG_D(MAC, + "Can't fit DCI allocations with %d PDCCH symbols (rnti condition), increasing by 1\n", + DL_req->number_pdcch_ofdm_symbols); - // no try to allocate UL DCIs - for (i = 0; i < HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi; - i++) { - - // allocate UL DCIs - if (hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) { - - LOG_D(MAC, - "Trying to allocate format 0 DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", - idci, DL_req->number_dci + HI_DCI0_req->number_of_dci, - DL_req->number_dci, HI_DCI0_req->number_of_dci, - hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti, - hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.aggregation_level, - nCCE, nCCE_max, DL_req->number_pdcch_ofdm_symbols); - - if (nCCE + - (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.aggregation_level) > - nCCE_max) { - if (DL_req->number_pdcch_ofdm_symbols == 3) - goto failed; - LOG_D(MAC, - "Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n", - DL_req->number_pdcch_ofdm_symbols); - - DL_req->number_pdcch_ofdm_symbols++; - nCCE_max = - get_nCCE_max(&RC.mac[module_idP]-> + DL_req->number_pdcch_ofdm_symbols++; + nCCE_max = get_nCCE_max(&RC.mac[module_idP]-> common_channels[CC_idP], DL_req->number_pdcch_ofdm_symbols, subframeP); - goto try_again; - } - // number of CCEs left can potentially hold this allocation - fCCE = get_nCCE_offset(CCE_table, - hi_dci0_pdu[i].dci_pdu. - dci_pdu_rel8.aggregation_level, - nCCE_max, 0, - hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8. - rnti, subframeP); - if (fCCE == -1) { - if (DL_req->number_pdcch_ofdm_symbols == 3) { - LOG_D(MAC, - "subframe %d: Dropping Allocation for RNTI %x\n", - subframeP, - hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti); - for (j = 0; j <= i; j++) { - if (hi_dci0_pdu[j].pdu_type == - NFAPI_HI_DCI0_DCI_PDU_TYPE) - LOG_D(MAC, - "DCI %d/%d (%d,%d) : rnti %x dci format %d, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", - j, - DL_req->number_dci + - HI_DCI0_req->number_of_dci, - DL_req->number_dci, - HI_DCI0_req->number_of_dci, - hi_dci0_pdu[j].dci_pdu.dci_pdu_rel8.rnti, - hi_dci0_pdu[j].dci_pdu.dci_pdu_rel8. - dci_format, - hi_dci0_pdu[j].dci_pdu. - dci_pdu_rel8.aggregation_level, nCCE, - nCCE_max, - DL_req->number_pdcch_ofdm_symbols); - } - //dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<L); - goto failed; - } - LOG_D(MAC, - "Can't fit DCI allocations with %d PDCCH symbols (rnti condition), increasing by 1\n", - DL_req->number_pdcch_ofdm_symbols); + goto try_again; + } // fCCE==-1 - DL_req->number_pdcch_ofdm_symbols++; - nCCE_max = - get_nCCE_max(&RC.mac[module_idP]-> - common_channels[CC_idP], - DL_req->number_pdcch_ofdm_symbols, - subframeP); - goto try_again; - } // fCCE==-1 + // the allocation is feasible, rnti rule passes + nCCE += dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level; + LOG_D(MAC, "Allocating at nCCE %d\n", fCCE); + if (test_onlyP == 0) { + dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = fCCE; + LOG_D(MAC, + "Allocate COMMON DCI CCEs subframe %d, test %d => L %d fCCE %d\n", + subframeP, test_onlyP, + dl_config_pdu[i].dci_dl_pdu. + dci_dl_pdu_rel8.aggregation_level, fCCE); + } + idci++; + } + } // for i = 0 ... num_DL_DCIs - // the allocation is feasible, rnti rule passes - nCCE += hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.aggregation_level; - LOG_D(MAC, "Allocating at nCCE %d\n", fCCE); - if (test_onlyP == 0) { - hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.cce_index = fCCE; - LOG_D(MAC, "Allocate CCEs subframe %d, test %d\n", - subframeP, test_onlyP); - } - idci++; + // no try to allocate UL DCIs + for (i = 0; i < HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi; + i++) { + + // allocate UL DCIs + if (hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) { + + LOG_D(MAC, + "Trying to allocate format 0 DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", + idci, DL_req->number_dci + HI_DCI0_req->number_of_dci, + DL_req->number_dci, HI_DCI0_req->number_of_dci, + hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti, + hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.aggregation_level, + nCCE, nCCE_max, DL_req->number_pdcch_ofdm_symbols); + + if (nCCE + (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.aggregation_level) > nCCE_max) { + if (DL_req->number_pdcch_ofdm_symbols == 3) + goto failed; + LOG_D(MAC, + "Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n", + DL_req->number_pdcch_ofdm_symbols); + + DL_req->number_pdcch_ofdm_symbols++; + nCCE_max = + get_nCCE_max(&RC.mac[module_idP]->common_channels[CC_idP], + DL_req->number_pdcch_ofdm_symbols, + subframeP); + goto try_again; + } + // number of CCEs left can potentially hold this allocation + fCCE = get_nCCE_offset(CCE_table, + hi_dci0_pdu[i].dci_pdu. + dci_pdu_rel8.aggregation_level, + nCCE_max, 0, + hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8. + rnti, subframeP); + if (fCCE == -1) { + if (DL_req->number_pdcch_ofdm_symbols == 3) { + LOG_D(MAC, + "subframe %d: Dropping Allocation for RNTI %x\n", + subframeP, + hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti); + for (j = 0; j <= i; j++) { + if (hi_dci0_pdu[j].pdu_type == + NFAPI_HI_DCI0_DCI_PDU_TYPE) + LOG_D(MAC, + "DCI %d/%d (%d,%d) : rnti %x dci format %d, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", + j, + DL_req->number_dci + HI_DCI0_req->number_of_dci, + DL_req->number_dci, + HI_DCI0_req->number_of_dci, + hi_dci0_pdu[j].dci_pdu.dci_pdu_rel8.rnti, + hi_dci0_pdu[j].dci_pdu.dci_pdu_rel8. + dci_format, + hi_dci0_pdu[j].dci_pdu. + dci_pdu_rel8.aggregation_level, nCCE, + nCCE_max, + DL_req->number_pdcch_ofdm_symbols); + } + //dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<L); + goto failed; } - } // for i = 0 ... num_UL_DCIs + LOG_D(MAC, + "Can't fit DCI allocations with %d PDCCH symbols (rnti condition), increasing by 1\n", + DL_req->number_pdcch_ofdm_symbols); - for (i = 0; i < DL_req->number_pdu; i++) { - // allocate DL UE specific DCIs - if ((dl_config_pdu[i].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) - && (dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type == - 1)) { - LOG_D(MAC, - "Trying to allocate DL UE-SPECIFIC DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", - idci, DL_req->number_dci + HI_DCI0_req->number_of_dci, - DL_req->number_dci, HI_DCI0_req->number_of_dci, - dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti, - dl_config_pdu[i].dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level, nCCE, nCCE_max, - DL_req->number_pdcch_ofdm_symbols); + DL_req->number_pdcch_ofdm_symbols++; + nCCE_max = + get_nCCE_max(&RC.mac[module_idP]->common_channels[CC_idP], + DL_req->number_pdcch_ofdm_symbols, + subframeP); + goto try_again; + } // fCCE==-1 - if (nCCE + - (dl_config_pdu[i].dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level) > nCCE_max) { - if (DL_req->number_pdcch_ofdm_symbols == 3) - goto failed; - LOG_D(MAC, - "Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n", - DL_req->number_pdcch_ofdm_symbols); + // the allocation is feasible, rnti rule passes + nCCE += hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.aggregation_level; + LOG_D(MAC, "Allocating at nCCE %d\n", fCCE); + if (test_onlyP == 0) { + hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.cce_index = fCCE; + LOG_D(MAC, "Allocate CCEs subframe %d, test %d\n", + subframeP, test_onlyP); + } + idci++; + } + } // for i = 0 ... num_UL_DCIs - DL_req->number_pdcch_ofdm_symbols++; - nCCE_max = - get_nCCE_max(&RC.mac[module_idP]-> - common_channels[CC_idP], - DL_req->number_pdcch_ofdm_symbols, - subframeP); - goto try_again; - } - // number of CCEs left can potentially hold this allocation - fCCE = get_nCCE_offset(CCE_table, - dl_config_pdu[i]. - dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level, nCCE_max, 0, - dl_config_pdu[i]. - dci_dl_pdu.dci_dl_pdu_rel8.rnti, - subframeP); - if (fCCE == -1) { - if (DL_req->number_pdcch_ofdm_symbols == 3) { - LOG_I(MAC, - "subframe %d: Dropping Allocation for RNTI %x\n", - subframeP, - dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8. - rnti); - for (j = 0; j <= i; j++) { - if (dl_config_pdu[j].pdu_type == - NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) - LOG_I(MAC, - "DCI %d/%d (%d,%d) : rnti %x dci format %d, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", - j, - DL_req->number_dci + - HI_DCI0_req->number_of_dci, - DL_req->number_dci, - HI_DCI0_req->number_of_dci, - dl_config_pdu[j]. - dci_dl_pdu.dci_dl_pdu_rel8.rnti, - dl_config_pdu[j]. - dci_dl_pdu.dci_dl_pdu_rel8.dci_format, - dl_config_pdu[j]. - dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level, nCCE, nCCE_max, - DL_req->number_pdcch_ofdm_symbols); - } - //dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<L); - goto failed; - } - LOG_D(MAC, - "Can't fit DCI allocations with %d PDCCH symbols (rnti condition), increasing by 1\n", - DL_req->number_pdcch_ofdm_symbols); + for (i = 0; i < DL_req->number_pdu; i++) { + // allocate DL UE specific DCIs + if ((dl_config_pdu[i].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) + && (dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type == + 1)) { + LOG_D(MAC, + "Trying to allocate DL UE-SPECIFIC DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", + idci, DL_req->number_dci + HI_DCI0_req->number_of_dci, + DL_req->number_dci, HI_DCI0_req->number_of_dci, + dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti, + dl_config_pdu[i].dci_dl_pdu. + dci_dl_pdu_rel8.aggregation_level, nCCE, nCCE_max, + DL_req->number_pdcch_ofdm_symbols); - DL_req->number_pdcch_ofdm_symbols++; - nCCE_max = - get_nCCE_max(&RC.mac[module_idP]-> - common_channels[CC_idP], - DL_req->number_pdcch_ofdm_symbols, - subframeP); - goto try_again; - } // fCCE==-1 + if (nCCE + (dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level) > nCCE_max) { + if (DL_req->number_pdcch_ofdm_symbols == 3) + goto failed; + LOG_D(MAC, + "Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n", + DL_req->number_pdcch_ofdm_symbols); - // the allocation is feasible, rnti rule passes - nCCE += + DL_req->number_pdcch_ofdm_symbols++; + nCCE_max = get_nCCE_max(&RC.mac[module_idP]->common_channels[CC_idP], + DL_req->number_pdcch_ofdm_symbols, + subframeP); + goto try_again; + } + // number of CCEs left can potentially hold this allocation + fCCE = get_nCCE_offset(CCE_table, + dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, nCCE_max, 0, + dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti, + subframeP); + if (fCCE == -1) { + if (DL_req->number_pdcch_ofdm_symbols == 3) { + LOG_I(MAC, + "subframe %d: Dropping Allocation for RNTI %x\n", + subframeP, dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level; - LOG_D(MAC, "Allocating at nCCE %d\n", fCCE); - if (test_onlyP == 0) { - dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = fCCE; - LOG_D(MAC, "Allocate CCEs subframe %d, test %d\n", - subframeP, test_onlyP); - } - idci++; + rnti); + for (j = 0; j <= i; j++) { + if (dl_config_pdu[j].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) + LOG_I(MAC, + "DCI %d/%d (%d,%d) : rnti %x dci format %d, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", + j, + DL_req->number_dci + HI_DCI0_req->number_of_dci, + DL_req->number_dci, + HI_DCI0_req->number_of_dci, + dl_config_pdu[j].dci_dl_pdu.dci_dl_pdu_rel8.rnti, + dl_config_pdu[j].dci_dl_pdu.dci_dl_pdu_rel8.dci_format, + dl_config_pdu[j].dci_dl_pdu.dci_dl_pdu_rel8. + aggregation_level, + nCCE, + nCCE_max, + DL_req->number_pdcch_ofdm_symbols); + } + //dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<L); + goto failed; } - } // for i = 0 ... num_DL_DCIs + LOG_D(MAC, + "Can't fit DCI allocations with %d PDCCH symbols (rnti condition), increasing by 1\n", + DL_req->number_pdcch_ofdm_symbols); - return 0; + DL_req->number_pdcch_ofdm_symbols++; + nCCE_max = + get_nCCE_max(&RC.mac[module_idP]->common_channels[CC_idP], + DL_req->number_pdcch_ofdm_symbols, + subframeP); + goto try_again; + } // fCCE==-1 - failed: - return -1; + // the allocation is feasible, rnti rule passes + nCCE += dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level; + LOG_D(MAC, "Allocating at nCCE %d\n", fCCE); + if (test_onlyP == 0) { + dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = fCCE; + LOG_D(MAC, "Allocate CCEs subframe %d, test %d\n", + subframeP, test_onlyP); + } + idci++; + } + } // for i = 0 ... num_DL_DCIs + + return 0; + + failed: + return -1; } -/* -uint8_t get_ul_req_index(module_id_t module_idP, int CC_idP, sub_frame_t subframeP) -{ - if (RC.mac[module_idP]->common_channels[CC_idP].tdd_Config == NULL) - return(0); - - switch (RC.mac[module_idP]->common_channels[CC_idP].tdd_Config->subframeAssignment) { - case 0: - case 1: - case 2: - case 6: - return(0); - case 3: - // 1,5,6 -> 2, prog. 8, buffer 0 - // 7,8 -> 3, prog. 9, buffer 1 - // 9,0 -> 4, prog. 0, buffer 0 - if ((subframeP == 7) || (subframeP == 8)) return(1); - else return(0); - case 4: - // 0,1,4,5 -> 2, prog. 8, buffer 0 - // 6,7,8,9 -> 3, prog. 9, buffer 1 - if (subframeP<6) return(0); - else return(1); - return(1); - break; - case 5: - // 9(-1),0,1,3,4,5,6,7,8,9 -> 2, prog 8, buffer 0 - return(0); - break; - default: - AssertFatal(1==0,"Should not get here, why is tdd_Config->subframeAssignment = %d\n",(int)RC.mac[module_idP]->common_channels[CC_idP].tdd_Config->subframeAssignment); - break; - } - return(0); -} -*/ - nfapi_ul_config_request_pdu_t *has_ul_grant(module_id_t module_idP, int CC_idP, uint16_t absSFP, uint16_t rnti) { - nfapi_ul_config_request_body_t *ul_req; - nfapi_ul_config_request_pdu_t *ul_config_pdu; + nfapi_ul_config_request_body_t *ul_req; + nfapi_ul_config_request_pdu_t *ul_config_pdu; - ul_req = - &RC.mac[module_idP]->UL_req_tmp[CC_idP][absSFP % - 10].ul_config_request_body; - ul_config_pdu = &ul_req->ul_config_pdu_list[0]; - LOG_D(MAC, - "Checking for rnti %x UL grant in subframeP %d (num pdu %d)\n", - rnti, absSFP % 10, ul_req->number_of_pdus); + ul_req = &RC.mac[module_idP]->UL_req_tmp[CC_idP][absSFP % 10].ul_config_request_body; + ul_config_pdu = &ul_req->ul_config_pdu_list[0]; + LOG_D(MAC, + "Checking for rnti %x UL grant in subframeP %d (num pdu %d)\n", + rnti, absSFP % 10, ul_req->number_of_pdus); - for (int i = 0; i < ul_req->number_of_pdus; i++) { - LOG_D(MAC, "PDU %d : type %d,rnti %x\n", i, - ul_config_pdu[i].pdu_type, rnti); - if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) - && (ul_config_pdu[i].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == - NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) - && (ul_config_pdu[i].ulsch_cqi_ri_pdu.ulsch_pdu. - ulsch_pdu_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == - NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) - && (ul_config_pdu[i].ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8. - rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == - NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE) - && (ul_config_pdu[i].ulsch_cqi_harq_ri_pdu. - ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); + for (int i = 0; i < ul_req->number_of_pdus; i++) { + LOG_D(MAC, "PDU %d : type %d,rnti %x\n", i,ul_config_pdu[i].pdu_type, rnti); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) + && (ul_config_pdu[i].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) + && (ul_config_pdu[i].ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) + && (ul_config_pdu[i].ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE) + && (ul_config_pdu[i].ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE) - && (ul_config_pdu[i].uci_cqi_pdu. - ue_information.ue_information_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE) - && (ul_config_pdu[i].uci_sr_pdu. - ue_information.ue_information_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == - NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) - && (ul_config_pdu[i].uci_harq_pdu. - ue_information.ue_information_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == - NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE) - && (ul_config_pdu[i].uci_sr_harq_pdu. - ue_information.ue_information_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == - NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE) - && (ul_config_pdu[i].uci_cqi_harq_pdu. - ue_information.ue_information_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == - NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE) - && (ul_config_pdu[i].uci_cqi_sr_pdu. - ue_information.ue_information_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == - NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE) - && (ul_config_pdu[i].uci_cqi_sr_harq_pdu. - ue_information.ue_information_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE) + && (ul_config_pdu[i].uci_cqi_pdu.ue_information.ue_information_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE) + && (ul_config_pdu[i].uci_sr_pdu.ue_information.ue_information_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) + && (ul_config_pdu[i].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE) + && (ul_config_pdu[i].uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE) + && (ul_config_pdu[i].uci_cqi_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE) + && (ul_config_pdu[i].uci_cqi_sr_pdu.ue_information.ue_information_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE) + && (ul_config_pdu[i].uci_cqi_sr_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == - NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE) - && (ul_config_pdu[i].ulsch_uci_csi_pdu. - ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == - NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE) - && (ul_config_pdu[i].ulsch_uci_harq_pdu. - ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == - NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE) - && (ul_config_pdu[i].ulsch_csi_uci_harq_pdu. - ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - } + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE) + && (ul_config_pdu[i].ulsch_uci_csi_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE) + && (ul_config_pdu[i].ulsch_uci_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE) + && (ul_config_pdu[i].ulsch_csi_uci_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) + return (&ul_config_pdu[i]); + } - return (NULL); // no ul grant at all for this UE + return (NULL); // no ul grant at all for this UE } boolean_t @@ -3533,65 +3100,54 @@ CCE_allocation_infeasible(int module_idP, int format_flag, int subframe, int aggregation, int rnti) { - nfapi_dl_config_request_body_t *DL_req = - &RC.mac[module_idP]->DL_req[CC_idP].dl_config_request_body; - nfapi_dl_config_request_pdu_t *dl_config_pdu = - &DL_req->dl_config_pdu_list[DL_req->number_pdu]; - nfapi_hi_dci0_request_body_t *HI_DCI0_req = - &RC.mac[module_idP]->HI_DCI0_req[CC_idP].hi_dci0_request_body; - nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = - &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci + - HI_DCI0_req->number_of_hi]; - int ret; - boolean_t res = FALSE; + nfapi_dl_config_request_body_t *DL_req = &RC.mac[module_idP]->DL_req[CC_idP].dl_config_request_body; + nfapi_dl_config_request_pdu_t *dl_config_pdu = &DL_req->dl_config_pdu_list[DL_req->number_pdu]; + nfapi_hi_dci0_request_body_t *HI_DCI0_req = &RC.mac[module_idP]->HI_DCI0_req[CC_idP].hi_dci0_request_body; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi]; + int ret; + boolean_t res = FALSE; - if (format_flag != 2) { // DL DCI - if (DL_req->number_pdu == MAX_NUM_DL_PDU) { - LOG_W(MAC, - "Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", - subframe, rnti); - } else { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = - (format_flag == 0) ? 2 : 1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = - aggregation; - DL_req->number_pdu++; - LOG_D(MAC, - "Subframe %d: Checking CCE feasibility format %d : (%x,%d) (%x,%d,%d)\n", - subframe, format_flag, rnti, aggregation, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type); - ret = allocate_CCEs(module_idP, CC_idP, subframe, 0); - if (ret == -1) - res = TRUE; - DL_req->number_pdu--; - } - } else { // ue-specific UL DCI - if (HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi == - MAX_NUM_HI_DCI0_PDU) { - LOG_W(MAC, - "Subframe %d: FAPI UL structure is full, skip scheduling UE %d\n", - subframe, rnti); - } else { - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = - aggregation; - HI_DCI0_req->number_of_dci++; - ret = allocate_CCEs(module_idP, CC_idP, subframe, 0); - if (ret == -1) - res = TRUE; - HI_DCI0_req->number_of_dci--; - } + if (format_flag != 2) { // DL DCI + if (DL_req->number_pdu == MAX_NUM_DL_PDU) { + LOG_W(MAC, + "Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", + subframe, rnti); + } else { + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = (format_flag == 0) ? 2 : 1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = aggregation; + DL_req->number_pdu++; + LOG_D(MAC, + "Subframe %d: Checking CCE feasibility format %d : (%x,%d) (%x,%d,%d)\n", + subframe, format_flag, rnti, aggregation, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. + aggregation_level, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type); + ret = allocate_CCEs(module_idP, CC_idP, subframe, 0); + if (ret == -1) res = TRUE; + DL_req->number_pdu--; } + } else { // ue-specific UL DCI + if (HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi == MAX_NUM_HI_DCI0_PDU) { + LOG_W(MAC, + "Subframe %d: FAPI UL structure is full, skip scheduling UE %d\n", + subframe, rnti); + } else { + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; + HI_DCI0_req->number_of_dci++; + ret = allocate_CCEs(module_idP, CC_idP, subframe, 0); + if (ret == -1) res = TRUE; + HI_DCI0_req->number_of_dci--; + } + } - return res; + return res; } void @@ -3599,338 +3155,328 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id, frame_t frameP, sub_frame_t subframeP, void *harq_indication, int format) { - UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - rnti_t rnti = UE_RNTI(mod_idP, UE_id); - COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; - nfapi_harq_indication_fdd_rel13_t *harq_indication_fdd; - nfapi_harq_indication_tdd_rel13_t *harq_indication_tdd; - uint16_t num_ack_nak; - int numCC = UE_list->numactiveCCs[UE_id]; - int pCCid = UE_list->pCC_id[UE_id]; - int spatial_bundling = 0; - int tmode[5]; - int i, j; - uint8_t *pdu; + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + rnti_t rnti = UE_RNTI(mod_idP, UE_id); + COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; + nfapi_harq_indication_fdd_rel13_t *harq_indication_fdd; + nfapi_harq_indication_tdd_rel13_t *harq_indication_tdd; + uint16_t num_ack_nak; + int numCC = UE_list->numactiveCCs[UE_id]; + int pCCid = UE_list->pCC_id[UE_id]; + int spatial_bundling = 0; + int tmode[5]; + int i, j; + uint8_t *pdu; #ifdef Rel14 - if (UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated != NULL && - UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL && - (UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7) - && (UE_list->UE_template[pCCid][UE_id]. - physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13) - && - (((UE_list->UE_template[pCCid][UE_id]. - physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13-> - spatialBundlingPUCCH_r13) - && (format == 0)) - || - ((UE_list->UE_template[pCCid][UE_id]. - physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13-> - spatialBundlingPUSCH_r13) - && (format == 1)))) - spatial_bundling = 1; + if (UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated != NULL && + UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL && + (UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7) + && (UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13) + && (((UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13->spatialBundlingPUCCH_r13) && (format == 0)) + || ((UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13->spatialBundlingPUSCH_r13) + && (format == 1)))) + spatial_bundling = 1; #endif - for (i = 0; i < numCC; i++) - tmode[i] = get_tmode(mod_idP, i, UE_id); + for (i = 0; i < numCC; i++) + tmode[i] = get_tmode(mod_idP, i, UE_id); - if (cc->tdd_Config) { - harq_indication_tdd = - (nfapi_harq_indication_tdd_rel13_t *) harq_indication; - // pdu = &harq_indication_tdd->harq_tb_n[0]; + if (cc->tdd_Config) { + harq_indication_tdd = (nfapi_harq_indication_tdd_rel13_t *) harq_indication; + // pdu = &harq_indication_tdd->harq_tb_n[0]; - num_ack_nak = harq_indication_tdd->number_of_ack_nack; + num_ack_nak = harq_indication_tdd->number_of_ack_nack; - switch (harq_indication_tdd->mode) { - case 0: // Format 1a/b - AssertFatal(numCC == 1, - "numCC %d > 1, should not be using Format1a/b\n", - numCC); - break; - case 1: // Channel Selection - break; - case 2: // Format 3 - break; - case 3: // Format 4 - break; - case 4: // Format 5 - break; - } - } else { - harq_indication_fdd = - (nfapi_harq_indication_fdd_rel13_t *) harq_indication; - num_ack_nak = harq_indication_fdd->number_of_ack_nack; - pdu = &harq_indication_fdd->harq_tb_n[0]; - - uint8_t harq_pid = ((10 * frameP) + subframeP + 10236) & 7; - - LOG_D(MAC,"frame %d subframe %d harq_pid %d mode %d tmode[0] %d num_ack_nak %d round %d\n",frameP,subframeP,harq_pid,harq_indication_fdd->mode,tmode[0],num_ack_nak,sched_ctl->round[CC_idP][harq_pid]); - - switch (harq_indication_fdd->mode) { - case 0: // Format 1a/b (10.1.2.1) - AssertFatal(numCC == 1, - "numCC %d > 1, should not be using Format1a/b\n", - numCC); - if (tmode[0] == 1 || tmode[0] == 2 || tmode[0] == 5 || tmode[0] == 6 || tmode[0] == 7) { // NOTE: have to handle the case of TM9-10 with 1 antenna port - // single ACK/NAK bit - AssertFatal(num_ack_nak == 1, - "num_ack_nak %d > 1 for 1 CC and single-layer transmission frame:%d subframe:%d\n", - num_ack_nak,frameP,subframeP); - AssertFatal(sched_ctl->round[CC_idP][harq_pid] < 8, - "Got ACK/NAK for inactive harq_pid %d for UE %d/%x\n", - harq_pid, UE_id, rnti); - AssertFatal(pdu[0] == 1 || pdu[0] == 2 - || pdu[0] == 4, - "Received ACK/NAK %d which is not 1 or 2 for harq_pid %d from UE %d/%x\n", - pdu[0], harq_pid, UE_id, rnti); - LOG_D(MAC, "Received %d for harq_pid %d\n", pdu[0], - harq_pid); - - 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) - sched_ctl->round[CC_idP][harq_pid]++; // increment round - } else { - // one or two ACK/NAK bits - AssertFatal(num_ack_nak > 2, - "num_ack_nak %d > 2 for 1 CC and TM3/4/8/9/10\n", - num_ack_nak); - if ((num_ack_nak == 2) - && (sched_ctl->round[CC_idP][harq_pid] < 8) - && (sched_ctl->tbcnt[CC_idP][harq_pid] == 1) - && (pdu[0] == 1) && (pdu[1] == 1)) { - sched_ctl->round[CC_idP][harq_pid] = 8; - sched_ctl->tbcnt[CC_idP][harq_pid] = 0; - } - 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)) - sched_ctl->round[CC_idP][harq_pid]++; - else if (((num_ack_nak == 2) - && (sched_ctl->round[CC_idP][harq_pid] < 8) - && (sched_ctl->tbcnt[0][harq_pid] == 2) - && (pdu[0] == 1) && (pdu[1] == 2)) - || ((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] == 1))) { - sched_ctl->round[CC_idP][harq_pid]++; - sched_ctl->tbcnt[CC_idP][harq_pid] = 1; - } 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)) - sched_ctl->round[CC_idP][harq_pid]++; - else - AssertFatal(1 == 0, - "Illegal ACK/NAK/round combination (%d,%d,%d,%d,%d) for harq_pid %d, UE %d/%x\n", - num_ack_nak, - sched_ctl->round[CC_idP][harq_pid], - sched_ctl->round[CC_idP][harq_pid], pdu[0], - pdu[1], harq_pid, UE_id, rnti); - } - break; - case 1: // FDD Channel Selection (10.1.2.2.1), must be received for 2 serving cells - AssertFatal(numCC == 2, - "Should not receive harq indication with channel selection with %d active CCs\n", - numCC); - - if ((num_ack_nak == 2) - && (sched_ctl->round[pCCid][harq_pid] < 8) - && (sched_ctl->round[1 - pCCid][harq_pid] < 8) - && (sched_ctl->tbcnt[pCCid][harq_pid] == 1) - && (sched_ctl->tbcnt[1 - pCCid][harq_pid] == 1)) { - AssertFatal(pdu[0] <= 3, "pdu[0] %d is not ACK/NAK/DTX\n", - pdu[0]); - AssertFatal(pdu[1] <= 3, "pdu[1] %d is not ACK/NAK/DTX\n", - pdu[1]); - if (pdu[0] == 1) - sched_ctl->round[pCCid][harq_pid] = 8; - else - sched_ctl->round[pCCid][harq_pid]++; - if (pdu[1] == 1) - sched_ctl->round[1 - pCCid][harq_pid] = 8; - else - sched_ctl->round[1 - pCCid][harq_pid]++; - } // A=2 - else if ((num_ack_nak == 3) - && (sched_ctl->round[pCCid][harq_pid] < 8) - && (sched_ctl->tbcnt[pCCid][harq_pid] == 2) - && (sched_ctl->round[1 - pCCid][harq_pid] < 8) - && (sched_ctl->tbcnt[1 - pCCid][harq_pid] == 1)) { - AssertFatal(pdu[0] <= 3, "pdu[0] %d is not ACK/NAK/DTX\n", - pdu[0]); - AssertFatal(pdu[1] <= 3, "pdu[1] %d is not ACK/NAK/DTX\n", - pdu[1]); - AssertFatal(pdu[2] <= 3, "pdu[2] %d is not ACK/NAK/DTX\n", - pdu[2]); - AssertFatal(sched_ctl->tbcnt[pCCid][harq_pid] == 2, - "sched_ctl->tbcnt[%d][%d] != 2 for UE %d/%x\n", - pCCid, harq_pid, UE_id, rnti); - AssertFatal(sched_ctl->tbcnt[1 - pCCid][harq_pid] == 1, - "sched_ctl->tbcnt[%d][%d] != 1 for UE %d/%x\n", - 1 - pCCid, harq_pid, UE_id, rnti); - if ((pdu[0] == 1) && (pdu[1] == 1)) { // both ACK - sched_ctl->round[pCCid][harq_pid] = 8; - sched_ctl->tbcnt[pCCid][harq_pid] = 0; - } else if (((pdu[0] == 2) && (pdu[1] == 1)) || - ((pdu[0] == 1) && (pdu[1] == 2))) { - sched_ctl->round[pCCid][harq_pid]++; - sched_ctl->tbcnt[pCCid][harq_pid] = 1; - } else - sched_ctl->round[pCCid][harq_pid]++; - - if (pdu[2] == 1) - sched_ctl->round[1 - pCCid][harq_pid] = 8; - else - sched_ctl->round[1 - pCCid][harq_pid]++; - } // A=3 primary cell has 2 TBs - else if ((num_ack_nak == 3) - && (sched_ctl->round[1 - pCCid][harq_pid] < 8) - && (sched_ctl->round[pCCid][harq_pid] < 8) - && (sched_ctl->tbcnt[1 - pCCid][harq_pid] == 2) - && (sched_ctl->tbcnt[pCCid][harq_pid] == 1)) { - AssertFatal(pdu[0] <= 3, "pdu[0] %d is not ACK/NAK/DTX\n", - pdu[0]); - AssertFatal(pdu[1] <= 3, "pdu[1] %d is not ACK/NAK/DTX\n", - pdu[1]); - AssertFatal(pdu[2] <= 3, "pdu[2] %d is not ACK/NAK/DTX\n", - pdu[2]); - AssertFatal(sched_ctl->tbcnt[1 - pCCid][harq_pid] == 2, - "sched_ctl->tbcnt[%d][%d] != 2 for UE %d/%x\n", - 1 - pCCid, harq_pid, UE_id, rnti); - AssertFatal(sched_ctl->tbcnt[pCCid][harq_pid] == 1, - "sched_ctl->tbcnt[%d][%d] != 1 for UE %d/%x\n", - pCCid, harq_pid, UE_id, rnti); - if ((pdu[0] == 1) && (pdu[1] == 1)) { // both ACK - sched_ctl->round[1 - pCCid][harq_pid] = 8; - sched_ctl->tbcnt[1 - pCCid][harq_pid] = 0; - } else if (((pdu[0] >= 2) && (pdu[1] == 1)) - || ((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 - sched_ctl->round[1 - pCCid][harq_pid]++; - - if (pdu[2] == 1) - sched_ctl->round[pCCid][harq_pid] = 8; - else - sched_ctl->round[pCCid][harq_pid]++; - } // A=3 secondary cell has 2 TBs -#if MAX_NUM_CCs>1 - else if ((num_ack_nak == 4) - && (sched_ctl->round[0][harq_pid] < 8) - && (sched_ctl->round[1][harq_pid] < 8) - && (sched_ctl->tbcnt[1 - pCCid][harq_pid] == 2) - && (sched_ctl->tbcnt[pCCid][harq_pid] == 2)) { - AssertFatal(pdu[0] <= 3, "pdu[0] %d is not ACK/NAK/DTX\n", - pdu[0]); - AssertFatal(pdu[1] <= 3, "pdu[1] %d is not ACK/NAK/DTX\n", - pdu[1]); - AssertFatal(pdu[2] <= 3, "pdu[2] %d is not ACK/NAK/DTX\n", - pdu[2]); - AssertFatal(pdu[3] <= 3, "pdu[3] %d is not ACK/NAK/DTX\n", - pdu[3]); - AssertFatal(sched_ctl->tbcnt[0][harq_pid] == 2, - "sched_ctl->tbcnt[0][%d] != 2 for UE %d/%x\n", - harq_pid, UE_id, rnti); - AssertFatal(sched_ctl->tbcnt[1][harq_pid] == 2, - "sched_ctl->tbcnt[1][%d] != 2 for UE %d/%x\n", - harq_pid, UE_id, rnti); - if ((pdu[0] == 1) && (pdu[1] == 1)) { // both ACK - sched_ctl->round[0][harq_pid] = 8; - sched_ctl->tbcnt[0][harq_pid] = 0; - } else if (((pdu[0] >= 2) && (pdu[1] == 1)) - || ((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 - sched_ctl->round[0][harq_pid]++; - - if ((pdu[2] == 1) && (pdu[3] == 1)) { // both ACK - sched_ctl->round[1][harq_pid] = 8; - sched_ctl->tbcnt[1][harq_pid] = 0; - } else if (((pdu[2] >= 2) && (pdu[3] == 1)) - || ((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 - sched_ctl->round[1][harq_pid]++; - } // A=4 both serving cells have 2 TBs -#endif - break; - case 2: // Format 3 - AssertFatal(numCC > 2, - "Should not receive harq indication with FDD format 3 with %d < 3 active CCs\n", - numCC); - for (i = 0, j = 0; i < numCC; i++) { - if ((sched_ctl->round[i][harq_pid] < 8)) { - if (tmode[i] == 1 || tmode[i] == 2 || tmode[0] == 5 - || tmode[0] == 6 || tmode[0] == 7) { - if (pdu[j] == 1) { - sched_ctl->round[i][harq_pid] = 8; - sched_ctl->tbcnt[i][harq_pid] = 0; - } else if (pdu[j] == 2) - sched_ctl->round[i][harq_pid]++; - else - AssertFatal(1 == 0, - "Illegal harq_ack value for CC %d harq_pid %d (%d) UE %d/%x\n", - i, harq_pid, pdu[j], UE_id, rnti); - j++; - } else if (spatial_bundling == 0) { - if ((sched_ctl->tbcnt[i][harq_pid] == 2) - && (pdu[j] == 1) && (pdu[j + 1] == 1)) { - 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] == 1) && (pdu[j + 1] == 2)) { - sched_ctl->round[i][harq_pid]++; - sched_ctl->tbcnt[i][harq_pid] = 1; - } 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; - } else if ((sched_ctl->tbcnt[i][harq_pid] == 2) - && (pdu[j] == 2) && (pdu[j + 1] == 2)) { - sched_ctl->round[i][harq_pid]++; - } else - AssertFatal(1 == 0, - "Illegal combination for CC %d harq_pid %d (%d,%d,%d) UE %d/%x\n", - i, harq_pid, - sched_ctl->tbcnt[i][harq_pid], - pdu[j], pdu[j + 1], UE_id, rnti); - j += 2; - } else if (spatial_bundling == 1) { - if (pdu[j] == 1) { - sched_ctl->round[i][harq_pid] = 8; - sched_ctl->tbcnt[i][harq_pid] = 0; - } else if (pdu[j] == 2) { - sched_ctl->round[i][harq_pid]++; - } else - AssertFatal(1 == 0, - "Illegal hack_nak value %d for CC %d harq_pid %d UE %d/%x\n", - pdu[j], i, harq_pid, UE_id, rnti); - j++; - } else - AssertFatal(1 == 0, - "Illegal value for spatial_bundling %d\n", - spatial_bundling); - } - } - break; - case 3: // Format 4 - AssertFatal(1 == 0, - "Should not receive harq indication with Format 4\n"); - break; - case 4: // Format 5 - AssertFatal(1 == 0, - "Should not receive harq indication with Format 5\n"); - break; - } + switch (harq_indication_tdd->mode) { + case 0: // Format 1a/b + AssertFatal(numCC == 1, + "numCC %d > 1, should not be using Format1a/b\n", + numCC); + break; + case 1: // Channel Selection + break; + case 2: // Format 3 + break; + case 3: // Format 4 + break; + case 4: // Format 5 + break; } + } else { + harq_indication_fdd = (nfapi_harq_indication_fdd_rel13_t *) harq_indication; + num_ack_nak = harq_indication_fdd->number_of_ack_nack; + pdu = &harq_indication_fdd->harq_tb_n[0]; + + uint8_t harq_pid = ((10 * frameP) + subframeP + 10236) & 7; + + LOG_D(MAC,"frame %d subframe %d harq_pid %d mode %d tmode[0] %d num_ack_nak %d round %d\n",frameP,subframeP,harq_pid,harq_indication_fdd->mode,tmode[0],num_ack_nak,sched_ctl->round[CC_idP][harq_pid]); + + switch (harq_indication_fdd->mode) { + case 0: // Format 1a/b (10.1.2.1) + AssertFatal(numCC == 1, + "numCC %d > 1, should not be using Format1a/b\n", + numCC); + if (tmode[0] == 1 || tmode[0] == 2 || tmode[0] == 5 || tmode[0] == 6 || tmode[0] == 7) { // NOTE: have to handle the case of TM9-10 with 1 antenna port + // single ACK/NAK bit + AssertFatal(num_ack_nak == 1, + "num_ack_nak %d > 1 for 1 CC and single-layer transmission frame:%d subframe:%d\n", + num_ack_nak,frameP,subframeP); + AssertFatal(sched_ctl->round[CC_idP][harq_pid] < 8, + "Got ACK/NAK for inactive harq_pid %d for UE %d/%x\n", + harq_pid, UE_id, rnti); + AssertFatal(pdu[0] == 1 || pdu[0] == 2 + || pdu[0] == 4, + "Received ACK/NAK %d which is not 1 or 2 for harq_pid %d from UE %d/%x\n", + pdu[0], harq_pid, UE_id, rnti); + LOG_D(MAC, "Received %d for harq_pid %d\n", pdu[0], + harq_pid); + + 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) + sched_ctl->round[CC_idP][harq_pid]++; // increment round + } else { + // one or two ACK/NAK bits + AssertFatal(num_ack_nak > 2, + "num_ack_nak %d > 2 for 1 CC and TM3/4/8/9/10\n", + num_ack_nak); + if ((num_ack_nak == 2) + && (sched_ctl->round[CC_idP][harq_pid] < 8) + && (sched_ctl->tbcnt[CC_idP][harq_pid] == 1) + && (pdu[0] == 1) && (pdu[1] == 1)) { + sched_ctl->round[CC_idP][harq_pid] = 8; + sched_ctl->tbcnt[CC_idP][harq_pid] = 0; + } + 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)) + sched_ctl->round[CC_idP][harq_pid]++; + else if (((num_ack_nak == 2) + && (sched_ctl->round[CC_idP][harq_pid] < 8) + && (sched_ctl->tbcnt[0][harq_pid] == 2) + && (pdu[0] == 1) && (pdu[1] == 2)) + || ((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] == 1))) { + sched_ctl->round[CC_idP][harq_pid]++; + sched_ctl->tbcnt[CC_idP][harq_pid] = 1; + } 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)) + sched_ctl->round[CC_idP][harq_pid]++; + else + AssertFatal(1 == 0, + "Illegal ACK/NAK/round combination (%d,%d,%d,%d,%d) for harq_pid %d, UE %d/%x\n", + num_ack_nak, + sched_ctl->round[CC_idP][harq_pid], + sched_ctl->round[CC_idP][harq_pid], pdu[0], + pdu[1], harq_pid, UE_id, rnti); + } + break; + case 1: // FDD Channel Selection (10.1.2.2.1), must be received for 2 serving cells + AssertFatal(numCC == 2, + "Should not receive harq indication with channel selection with %d active CCs\n", + numCC); + + if ((num_ack_nak == 2) + && (sched_ctl->round[pCCid][harq_pid] < 8) + && (sched_ctl->round[1 - pCCid][harq_pid] < 8) + && (sched_ctl->tbcnt[pCCid][harq_pid] == 1) + && (sched_ctl->tbcnt[1 - pCCid][harq_pid] == 1)) { + AssertFatal(pdu[0] <= 3, "pdu[0] %d is not ACK/NAK/DTX\n", + pdu[0]); + AssertFatal(pdu[1] <= 3, "pdu[1] %d is not ACK/NAK/DTX\n", + pdu[1]); + if (pdu[0] == 1) + sched_ctl->round[pCCid][harq_pid] = 8; + else + sched_ctl->round[pCCid][harq_pid]++; + if (pdu[1] == 1) + sched_ctl->round[1 - pCCid][harq_pid] = 8; + else + sched_ctl->round[1 - pCCid][harq_pid]++; + } // A=2 + else if ((num_ack_nak == 3) + && (sched_ctl->round[pCCid][harq_pid] < 8) + && (sched_ctl->tbcnt[pCCid][harq_pid] == 2) + && (sched_ctl->round[1 - pCCid][harq_pid] < 8) + && (sched_ctl->tbcnt[1 - pCCid][harq_pid] == 1)) { + AssertFatal(pdu[0] <= 3, "pdu[0] %d is not ACK/NAK/DTX\n", + pdu[0]); + AssertFatal(pdu[1] <= 3, "pdu[1] %d is not ACK/NAK/DTX\n", + pdu[1]); + AssertFatal(pdu[2] <= 3, "pdu[2] %d is not ACK/NAK/DTX\n", + pdu[2]); + AssertFatal(sched_ctl->tbcnt[pCCid][harq_pid] == 2, + "sched_ctl->tbcnt[%d][%d] != 2 for UE %d/%x\n", + pCCid, harq_pid, UE_id, rnti); + AssertFatal(sched_ctl->tbcnt[1 - pCCid][harq_pid] == 1, + "sched_ctl->tbcnt[%d][%d] != 1 for UE %d/%x\n", + 1 - pCCid, harq_pid, UE_id, rnti); + if ((pdu[0] == 1) && (pdu[1] == 1)) { // both ACK + sched_ctl->round[pCCid][harq_pid] = 8; + sched_ctl->tbcnt[pCCid][harq_pid] = 0; + } else if (((pdu[0] == 2) && (pdu[1] == 1)) || + ((pdu[0] == 1) && (pdu[1] == 2))) { + sched_ctl->round[pCCid][harq_pid]++; + sched_ctl->tbcnt[pCCid][harq_pid] = 1; + } else + sched_ctl->round[pCCid][harq_pid]++; + + if (pdu[2] == 1) + sched_ctl->round[1 - pCCid][harq_pid] = 8; + else + sched_ctl->round[1 - pCCid][harq_pid]++; + } // A=3 primary cell has 2 TBs + else if ((num_ack_nak == 3) + && (sched_ctl->round[1 - pCCid][harq_pid] < 8) + && (sched_ctl->round[pCCid][harq_pid] < 8) + && (sched_ctl->tbcnt[1 - pCCid][harq_pid] == 2) + && (sched_ctl->tbcnt[pCCid][harq_pid] == 1)) { + AssertFatal(pdu[0] <= 3, "pdu[0] %d is not ACK/NAK/DTX\n", + pdu[0]); + AssertFatal(pdu[1] <= 3, "pdu[1] %d is not ACK/NAK/DTX\n", + pdu[1]); + AssertFatal(pdu[2] <= 3, "pdu[2] %d is not ACK/NAK/DTX\n", + pdu[2]); + AssertFatal(sched_ctl->tbcnt[1 - pCCid][harq_pid] == 2, + "sched_ctl->tbcnt[%d][%d] != 2 for UE %d/%x\n", + 1 - pCCid, harq_pid, UE_id, rnti); + AssertFatal(sched_ctl->tbcnt[pCCid][harq_pid] == 1, + "sched_ctl->tbcnt[%d][%d] != 1 for UE %d/%x\n", + pCCid, harq_pid, UE_id, rnti); + if ((pdu[0] == 1) && (pdu[1] == 1)) { // both ACK + sched_ctl->round[1 - pCCid][harq_pid] = 8; + sched_ctl->tbcnt[1 - pCCid][harq_pid] = 0; + } else if (((pdu[0] >= 2) && (pdu[1] == 1)) + || ((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 + sched_ctl->round[1 - pCCid][harq_pid]++; + + if (pdu[2] == 1) + sched_ctl->round[pCCid][harq_pid] = 8; + else + sched_ctl->round[pCCid][harq_pid]++; + } // A=3 secondary cell has 2 TBs +#if MAX_NUM_CCs>1 + else if ((num_ack_nak == 4) + && (sched_ctl->round[0][harq_pid] < 8) + && (sched_ctl->round[1][harq_pid] < 8) + && (sched_ctl->tbcnt[1 - pCCid][harq_pid] == 2) + && (sched_ctl->tbcnt[pCCid][harq_pid] == 2)) { + AssertFatal(pdu[0] <= 3, "pdu[0] %d is not ACK/NAK/DTX\n", + pdu[0]); + AssertFatal(pdu[1] <= 3, "pdu[1] %d is not ACK/NAK/DTX\n", + pdu[1]); + AssertFatal(pdu[2] <= 3, "pdu[2] %d is not ACK/NAK/DTX\n", + pdu[2]); + AssertFatal(pdu[3] <= 3, "pdu[3] %d is not ACK/NAK/DTX\n", + pdu[3]); + AssertFatal(sched_ctl->tbcnt[0][harq_pid] == 2, + "sched_ctl->tbcnt[0][%d] != 2 for UE %d/%x\n", + harq_pid, UE_id, rnti); + AssertFatal(sched_ctl->tbcnt[1][harq_pid] == 2, + "sched_ctl->tbcnt[1][%d] != 2 for UE %d/%x\n", + harq_pid, UE_id, rnti); + if ((pdu[0] == 1) && (pdu[1] == 1)) { // both ACK + sched_ctl->round[0][harq_pid] = 8; + sched_ctl->tbcnt[0][harq_pid] = 0; + } else if (((pdu[0] >= 2) && (pdu[1] == 1)) + || ((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 + sched_ctl->round[0][harq_pid]++; + + if ((pdu[2] == 1) && (pdu[3] == 1)) { // both ACK + sched_ctl->round[1][harq_pid] = 8; + sched_ctl->tbcnt[1][harq_pid] = 0; + } else if (((pdu[2] >= 2) && (pdu[3] == 1)) + || ((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 + sched_ctl->round[1][harq_pid]++; + } // A=4 both serving cells have 2 TBs +#endif + break; + case 2: // Format 3 + AssertFatal(numCC > 2, + "Should not receive harq indication with FDD format 3 with %d < 3 active CCs\n", + numCC); + for (i = 0, j = 0; i < numCC; i++) { + if ((sched_ctl->round[i][harq_pid] < 8)) { + if (tmode[i] == 1 || tmode[i] == 2 || tmode[0] == 5 + || tmode[0] == 6 || tmode[0] == 7) { + if (pdu[j] == 1) { + sched_ctl->round[i][harq_pid] = 8; + sched_ctl->tbcnt[i][harq_pid] = 0; + } else if (pdu[j] == 2) + sched_ctl->round[i][harq_pid]++; + else + AssertFatal(1 == 0, + "Illegal harq_ack value for CC %d harq_pid %d (%d) UE %d/%x\n", + i, harq_pid, pdu[j], UE_id, rnti); + j++; + } else if (spatial_bundling == 0) { + if ((sched_ctl->tbcnt[i][harq_pid] == 2) + && (pdu[j] == 1) && (pdu[j + 1] == 1)) { + 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] == 1) && (pdu[j + 1] == 2)) { + sched_ctl->round[i][harq_pid]++; + sched_ctl->tbcnt[i][harq_pid] = 1; + } 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; + } else if ((sched_ctl->tbcnt[i][harq_pid] == 2) + && (pdu[j] == 2) && (pdu[j + 1] == 2)) { + sched_ctl->round[i][harq_pid]++; + } else + AssertFatal(1 == 0, + "Illegal combination for CC %d harq_pid %d (%d,%d,%d) UE %d/%x\n", + i, harq_pid, + sched_ctl->tbcnt[i][harq_pid], + pdu[j], pdu[j + 1], UE_id, rnti); + j += 2; + } else if (spatial_bundling == 1) { + if (pdu[j] == 1) { + sched_ctl->round[i][harq_pid] = 8; + sched_ctl->tbcnt[i][harq_pid] = 0; + } else if (pdu[j] == 2) { + sched_ctl->round[i][harq_pid]++; + } else + AssertFatal(1 == 0, + "Illegal hack_nak value %d for CC %d harq_pid %d UE %d/%x\n", + pdu[j], i, harq_pid, UE_id, rnti); + j++; + } else + AssertFatal(1 == 0, + "Illegal value for spatial_bundling %d\n", + spatial_bundling); + } + } + break; + case 3: // Format 4 + AssertFatal(1 == 0, + "Should not receive harq indication with Format 4\n"); + break; + case 4: // Format 5 + AssertFatal(1 == 0, + "Should not receive harq indication with Format 5\n"); + break; + } + } } void @@ -3938,129 +3484,106 @@ extract_pucch_csi(module_id_t mod_idP, int CC_idP, int UE_id, frame_t frameP, sub_frame_t subframeP, uint8_t * pdu, uint8_t length) { - UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; - struct CQI_ReportPeriodic *cqi_ReportPeriodic; - int no_pmi; - uint8_t Ltab[6] = { 0, 2, 4, 4, 4, 4 }; - uint8_t Jtab[6] = { 0, 2, 2, 3, 4, 4 }; - int feedback_cnt; + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; + struct CQI_ReportPeriodic *cqi_ReportPeriodic; + int no_pmi; + uint8_t Ltab[6] = { 0, 2, 4, 4, 4, 4 }; + uint8_t Jtab[6] = { 0, 2, 2, 3, 4, 4 }; + int feedback_cnt; - AssertFatal(UE_list->UE_template[CC_idP][UE_id]. - physicalConfigDedicated != NULL, - "physicalConfigDedicated is null for UE %d\n", UE_id); - AssertFatal(UE_list-> - UE_template[CC_idP][UE_id].physicalConfigDedicated-> - cqi_ReportConfig != NULL, - "cqi_ReportConfig is null for UE %d\n", UE_id); - AssertFatal((cqi_ReportPeriodic = - UE_list-> - UE_template[CC_idP][UE_id].physicalConfigDedicated-> - cqi_ReportConfig->cqi_ReportPeriodic) != NULL, - "cqi_ReportPeriodic is null for UE %d\n", UE_id); + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, + "physicalConfigDedicated is null for UE %d\n", UE_id); + AssertFatal(UE_list-> + UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig != NULL, + "cqi_ReportConfig is null for UE %d\n", UE_id); + AssertFatal((cqi_ReportPeriodic = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) != NULL, + "cqi_ReportPeriodic is null for UE %d\n", UE_id); - // determine feedback mode - AssertFatal(cqi_ReportPeriodic->present != - CQI_ReportPeriodic_PR_NOTHING, - "cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_NOTHING!\n"); - AssertFatal(cqi_ReportPeriodic->choice. - setup.cqi_FormatIndicatorPeriodic.present != - CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING, - "cqi_ReportPeriodic->cqi_FormatIndicatorPeriodic.choice.setup.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING!\n"); + // determine feedback mode + AssertFatal(cqi_ReportPeriodic->present != CQI_ReportPeriodic_PR_NOTHING, + "cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_NOTHING!\n"); + AssertFatal(cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present != CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING, + "cqi_ReportPeriodic->cqi_FormatIndicatorPeriodic.choice.setup.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING!\n"); - uint16_t Npd, N_OFFSET_CQI; - int H, K, bandwidth_part, L, Lmask; - int ri = sched_ctl->periodic_ri_received[CC_idP]; + uint16_t Npd, N_OFFSET_CQI; + int H, K, bandwidth_part, L, Lmask; + int ri = sched_ctl->periodic_ri_received[CC_idP]; - get_csi_params(cc, cqi_ReportPeriodic, &Npd, &N_OFFSET_CQI, &H); - K = (H - 1) / Jtab[cc->mib->message.dl_Bandwidth]; - L = Ltab[cc->mib->message.dl_Bandwidth]; - Lmask = L - 1; - feedback_cnt = (((frameP * 10) + subframeP) / Npd) % H; + get_csi_params(cc, cqi_ReportPeriodic, &Npd, &N_OFFSET_CQI, &H); + K = (H - 1) / Jtab[cc->mib->message.dl_Bandwidth]; + L = Ltab[cc->mib->message.dl_Bandwidth]; + Lmask = L - 1; + feedback_cnt = (((frameP * 10) + subframeP) / Npd) % H; - if (feedback_cnt > 0) - bandwidth_part = (feedback_cnt - 1) % K; - else - bandwidth_part = 0; + if (feedback_cnt > 0) + bandwidth_part = (feedback_cnt - 1) % K; + else + bandwidth_part = 0; - switch (get_tmode(mod_idP, CC_idP, UE_id)) { - case 1: - case 2: - case 3: - case 7: - no_pmi = 1; - break; - case 4: - case 5: - case 6: - no_pmi = 0; - break; - default: - // note: need to check TM8-10 without PMI/RI or with 1 antenna port (see Section 5.2.3.3.1 from 36.213) - no_pmi = 0; - } + switch (get_tmode(mod_idP, CC_idP, UE_id)) { + case 1: + case 2: + case 3: + case 7: + no_pmi = 1; + break; + case 4: + case 5: + case 6: + no_pmi = 0; + break; + default: + // note: need to check TM8-10 without PMI/RI or with 1 antenna port (see Section 5.2.3.3.1 from 36.213) + no_pmi = 0; + } - if ((cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic. - present == - CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_widebandCQI) - || (feedback_cnt == 0)) { - // Note: This implements only Tables: 5.3.3.1-1,5.3.3.1-1A and 5.3.3.1-2 from 36.213 (1,2,4 antenna ports Wideband CQI/PMI) + if ((cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_widebandCQI) + || (feedback_cnt == 0)) { + // Note: This implements only Tables: 5.3.3.1-1,5.3.3.1-1A and 5.3.3.1-2 from 36.213 (1,2,4 antenna ports Wideband CQI/PMI) - if (no_pmi == 1) { // get spatial_diffcqi if needed - sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; - sched_ctl->periodic_wideband_spatial_diffcqi[CC_idP] = - (pdu[0] >> 4) & 7; - } else if ((cc->p_eNB == 2) && (ri == 1)) { - // p=2 Rank 1 wideband CQI/PMI 6 bits - sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; - sched_ctl->periodic_wideband_pmi[CC_idP] = (pdu[0] >> 4) & 3; - } else if ((cc->p_eNB == 2) && (ri > 1)) { - // p=2 Rank 2 wideband CQI/PMI 8 bits - sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; - sched_ctl->periodic_wideband_spatial_diffcqi[CC_idP] = - (pdu[0] >> 4) & 7; - sched_ctl->periodic_wideband_pmi[CC_idP] = (pdu[0] >> 7) & 1; - } else if ((cc->p_eNB == 4) && (ri == 1)) { - // p=4 Rank 1 wideband CQI/PMI 8 bits - sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; - sched_ctl->periodic_wideband_pmi[CC_idP] = - (pdu[0] >> 4) & 0x0F; - - } else if ((cc->p_eNB == 4) && (ri > 1)) { - // p=4 Rank 2 wideband CQI/PMI 11 bits - sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; - sched_ctl->periodic_wideband_spatial_diffcqi[CC_idP] = - (pdu[0] >> 4) & 7; - sched_ctl->periodic_wideband_pmi[CC_idP] = (pdu[0] >> 7) & 0xF; - } else - AssertFatal(1 == 0, - "illegal combination p %d, ri %d, no_pmi %d\n", - cc->p_eNB, ri, no_pmi); - } else if (cqi_ReportPeriodic->choice. - setup.cqi_FormatIndicatorPeriodic.present == - CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) + if (no_pmi == 1) { // get spatial_diffcqi if needed + sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; + sched_ctl->periodic_wideband_spatial_diffcqi[CC_idP] = + (pdu[0] >> 4) & 7; + } else if ((cc->p_eNB == 2) && (ri == 1)) { + // p=2 Rank 1 wideband CQI/PMI 6 bits + sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; + sched_ctl->periodic_wideband_pmi[CC_idP] = (pdu[0] >> 4) & 3; + } else if ((cc->p_eNB == 2) && (ri > 1)) { + // p=2 Rank 2 wideband CQI/PMI 8 bits + sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; + sched_ctl->periodic_wideband_spatial_diffcqi[CC_idP] = + (pdu[0] >> 4) & 7; + sched_ctl->periodic_wideband_pmi[CC_idP] = (pdu[0] >> 7) & 1; + } else if ((cc->p_eNB == 4) && (ri == 1)) { + // p=4 Rank 1 wideband CQI/PMI 8 bits + sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; + sched_ctl->periodic_wideband_pmi[CC_idP] = + (pdu[0] >> 4) & 0x0F; + } else if ((cc->p_eNB == 4) && (ri > 1)) { + // p=4 Rank 2 wideband CQI/PMI 11 bits + sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; + sched_ctl->periodic_wideband_spatial_diffcqi[CC_idP] = + (pdu[0] >> 4) & 7; + sched_ctl->periodic_wideband_pmi[CC_idP] = (pdu[0] >> 7) & 0xF; + } else + AssertFatal(1 == 0, + "illegal combination p %d, ri %d, no_pmi %d\n", + cc->p_eNB, ri, no_pmi); + } else if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) { - // This is Table 5.2.3.3.2-2 for 36.213 - if (ri == 1) { - //4+Ltab[cc->mib->message.dl_Bandwidth] bits - sched_ctl->periodic_subband_cqi[CC_idP][(bandwidth_part * L) + - ((pdu[0] >> 4) & - Lmask)] = - pdu[0] & 0xF; - } else if (ri > 1) { - //7+Ltab[cc->mib->message.dl_Bandwidth] bits; - sched_ctl-> - periodic_subband_spatial_diffcqi[CC_idP][(bandwidth_part * - L) + - ((pdu[0] >> 7) & - Lmask)] = - (pdu[0] >> 4) & 7; - sched_ctl->periodic_subband_cqi[CC_idP][(bandwidth_part * L) + - ((pdu[0] >> 7) & - Lmask)] = - pdu[0] & 0xF; - } + // This is Table 5.2.3.3.2-2 for 36.213 + if (ri == 1) { + //4+Ltab[cc->mib->message.dl_Bandwidth] bits + sched_ctl->periodic_subband_cqi[CC_idP][(bandwidth_part * L) +((pdu[0] >> 4) & Lmask)] = pdu[0] & 0xF; + } else if (ri > 1) { + //7+Ltab[cc->mib->message.dl_Bandwidth] bits; + sched_ctl->periodic_subband_spatial_diffcqi[CC_idP][(bandwidth_part * L) + ((pdu[0] >> 7) & Lmask)] = (pdu[0] >> 4) & 7; + sched_ctl->periodic_subband_cqi[CC_idP][(bandwidth_part * L) + ((pdu[0] >> 7) & Lmask)] = + pdu[0] & 0xF; + } } } @@ -4069,278 +3592,261 @@ extract_pusch_csi(module_id_t mod_idP, int CC_idP, int UE_id, frame_t frameP, sub_frame_t subframeP, uint8_t * pdu, uint8_t length) { - UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; - UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - int Ntab[6] = { 0, 4, 7, 9, 10, 13 }; - int Ntab_uesel[6] = { 0, 8, 13, 17, 19, 25 }; - int Ltab_uesel[6] = { 0, 6, 9, 13, 15, 18 }; - int Mtab_uesel[6] = { 0, 1, 3, 5, 6, 6 }; - int v[6]; - int i; - uint64_t p = *(uint64_t *) pdu; - int curbyte, curbit; - CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic; + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; + UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + int Ntab[6] = { 0, 4, 7, 9, 10, 13 }; + int Ntab_uesel[6] = { 0, 8, 13, 17, 19, 25 }; + int Ltab_uesel[6] = { 0, 6, 9, 13, 15, 18 }; + int Mtab_uesel[6] = { 0, 1, 3, 5, 6, 6 }; + int v[6]; + int i; + uint64_t p = *(uint64_t *) pdu; + int curbyte, curbit; + CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic; - AssertFatal(UE_list->UE_template[CC_idP][UE_id]. - physicalConfigDedicated != NULL, - "physicalConfigDedicated is null for UE %d\n", UE_id); - AssertFatal(UE_list-> - UE_template[CC_idP][UE_id].physicalConfigDedicated-> - cqi_ReportConfig != NULL, - "cqi_ReportConfig is null for UE %d\n", UE_id); - AssertFatal((cqi_ReportModeAperiodic = - UE_list-> - UE_template[CC_idP][UE_id].physicalConfigDedicated-> - cqi_ReportConfig->cqi_ReportModeAperiodic) != NULL, - "cqi_ReportModeAperiodic is null for UE %d\n", UE_id); + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, + "physicalConfigDedicated is null for UE %d\n", UE_id); + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig != NULL, + "cqi_ReportConfig is null for UE %d\n", UE_id); + AssertFatal((cqi_ReportModeAperiodic = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic) != NULL, + "cqi_ReportModeAperiodic is null for UE %d\n", UE_id); - int N = Ntab[cc->mib->message.dl_Bandwidth]; - int tmode = get_tmode(mod_idP, CC_idP, UE_id); - int ri = sched_ctl->aperiodic_ri_received[CC_idP]; - int r, diffcqi0 = 0, diffcqi1 = 0, pmi_uesel = 0; - int bw = cc->mib->message.dl_Bandwidth; - int m; + int N = Ntab[cc->mib->message.dl_Bandwidth]; + int tmode = get_tmode(mod_idP, CC_idP, UE_id); + int ri = sched_ctl->aperiodic_ri_received[CC_idP]; + int r, diffcqi0 = 0, diffcqi1 = 0, pmi_uesel = 0; + int bw = cc->mib->message.dl_Bandwidth; + int m; - switch (*cqi_ReportModeAperiodic) { - case CQI_ReportModeAperiodic_rm12: - AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); - // wideband multiple PMI (TM4/6), Table 5.2.2.6.1-1 (for TM4/6) - AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 - || tmode == 10, - "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm12\n", - tmode); - if (tmode <= 6) { //Table 5.2.2.6.1-1 36.213 - if ((ri == 1) && (cc->p_eNB == 2)) { - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_pmi[CC_idP][i] = - (uint8_t) (p & 0x03); - p >>= 2; - } - } - if ((ri == 2) && (cc->p_eNB == 2)) { - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - sched_ctl->aperiodic_wideband_cqi1[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_pmi[CC_idP][i] = - (uint8_t) (p & 0x01); - p >>= 1; - } - } - if ((ri == 1) && (cc->p_eNB == 4)) { - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_pmi[CC_idP][i] = - (uint8_t) (p & 0x03); - p >>= 4; - } - } - if ((ri == 2) && (cc->p_eNB == 4)) { - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - sched_ctl->aperiodic_wideband_cqi1[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_pmi[CC_idP][i] = - (uint8_t) (p & 0x01); - p >>= 4; - } - } - } // if (tmode <= 6) { //Table 5.2.2.6.1-1 36.213 - else { - AssertFatal(1 == 0, "support for TM 8-10 to be done\n"); - } - - break; - case CQI_ReportModeAperiodic_rm20: - AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); - // UE-selected subband CQI no PMI (TM1/2/3/7) , Table 5.2.2.6.3-1 from 36.213 - AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 - || tmode == 7, - "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm20\n", - tmode); - - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); + switch (*cqi_ReportModeAperiodic) { + case CQI_ReportModeAperiodic_rm12: + AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); + // wideband multiple PMI (TM4/6), Table 5.2.2.6.1-1 (for TM4/6) + AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 || tmode == 10, + "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm12\n", + tmode); + if (tmode <= 6) { //Table 5.2.2.6.1-1 36.213 + if ((ri == 1) && (cc->p_eNB == 2)) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); p >>= 4; - diffcqi0 = (uint8_t) (p & 0x03); - p >>= 2; - r = (uint8_t) (p & ((1 >> Ltab_uesel[bw]) - 1)); - reverse_index(Ntab_uesel[bw], Mtab_uesel[bw], r, v); - for (m = 0; m < Mtab_uesel[bw]; m++) - sched_ctl->aperiodic_subband_diffcqi0[CC_idP][v[m]] = diffcqi0; - break; - case CQI_ReportModeAperiodic_rm22: - AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); - // UE-selected subband CQI multiple PMI (TM4/6) Table 5.2.2.6.3-2 from 36.213 - - AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 - || tmode == 10, - "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm22\n", - tmode); - - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); - p >>= 4; - diffcqi0 = (uint8_t) (p & 0x03); - p >>= 2; - - if (ri > 1) { - sched_ctl->aperiodic_wideband_cqi1[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - diffcqi1 = (uint8_t) (p & 0x03); - p >>= 2; - } - r = (uint8_t) (p & ((1 >> Ltab_uesel[bw]) - 1)); - p >>= Ltab_uesel[bw]; - reverse_index(Ntab_uesel[bw], Mtab_uesel[bw], r, v); - if ((ri == 1) && (cc->p_eNB == 2)) { - pmi_uesel = p & 0x3; - p >>= 2; - sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x3; - } else if ((ri == 2) && (cc->p_eNB == 2)) { - pmi_uesel = p & 0x1; - p >>= 1; - sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x1; - } else if (cc->p_eNB == 4) { - pmi_uesel = p & 0x0F; - p >>= 4; - sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x0F; - } - for (m = 0; m < Mtab_uesel[bw]; m++) { - sched_ctl->aperiodic_subband_diffcqi0[CC_idP][v[m]] = diffcqi0; - if (ri > 1) - sched_ctl->aperiodic_subband_diffcqi1[CC_idP][v[m]] = - diffcqi1; - sched_ctl->aperiodic_subband_pmi[CC_idP][v[m]] = pmi_uesel; - } - break; - case CQI_ReportModeAperiodic_rm30: - //subband CQI no PMI (TM1/2/3/7) - AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 - || tmode == 7, - "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm30\n", - tmode); - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = pdu[0] >> 4; - curbyte = 0; - curbit = 3; for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = - (pdu[curbyte] >> (curbit - 1)) & 0x03; - curbit -= 2; - if (curbit < 0) { - curbit = 7; - curbyte++; - } + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t) (p & 0x03); + p >>= 2; } - sched_ctl->dl_cqi[CC_idP] = - sched_ctl->aperiodic_wideband_cqi0[CC_idP]; - break; - case CQI_ReportModeAperiodic_rm31: - AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); - //subband CQI single PMI (TM4/5/6) - AssertFatal(tmode == 4 || tmode == 5 || tmode == 6 || tmode == 8 - || tmode == 9 - || tmode == 10, - "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm31\n", - tmode); - - if ((ri == 1) && (cc->p_eNB == 2)) { - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = - (uint8_t) (p & 0x03); - p >>= 2; - } - sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x03; + } + if ((ri == 2) && (cc->p_eNB == 2)) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + sched_ctl->aperiodic_wideband_cqi1[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t) (p & 0x01); + p >>= 1; } - if ((ri == 2) && (cc->p_eNB == 2)) { - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_pmi[CC_idP][i] = - (uint8_t) (p & 0x01); - p >>= 1; - } - sched_ctl->aperiodic_wideband_cqi1[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_pmi[CC_idP][i] = - (uint8_t) (p & 0x01); - p >>= 1; - } - sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x01; + } + if ((ri == 1) && (cc->p_eNB == 4)) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t) (p & 0x03); + p >>= 4; } - if ((ri == 1) && (cc->p_eNB == 4)) { - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = - (uint8_t) (p & 0x03); - p >>= 2; - } - sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x0F; + } + if ((ri == 2) && (cc->p_eNB == 4)) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + sched_ctl->aperiodic_wideband_cqi1[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t) (p & 0x01); + p >>= 4; } - if ((ri > 1) && (cc->p_eNB == 4)) { // Note : 64 bits for 20 MHz - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_pmi[CC_idP][i] = - (uint8_t) (p & 0x01); - p >>= 1; - } - sched_ctl->aperiodic_wideband_cqi1[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_pmi[CC_idP][i] = - (uint8_t) (p & 0x01); - p >>= 2; - } - sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x0F; - } - - break; - case CQI_ReportModeAperiodic_rm32_v1250: - AssertFatal(tmode == 4 || tmode == 5 || tmode == 6 || tmode == 8 - || tmode == 9 - || tmode == 10, - "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm32\n", - tmode); - AssertFatal(1 == 0, "CQI_ReportModeAperiodic_rm32 to be done\n"); - break; - case CQI_ReportModeAperiodic_rm10_v1310: - AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 - || tmode == 7, - "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm10\n", - tmode); - AssertFatal(1 == 0, "CQI_ReportModeAperiodic_rm10 to be done\n"); - break; - case CQI_ReportModeAperiodic_rm11_v1310: - AssertFatal(tmode == 4 || tmode == 5 || tmode == 6 || tmode == 8 - || tmode == 9 - || tmode == 10, - "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm11\n", - tmode); - AssertFatal(1 == 0, "CQI_ReportModeAperiodic_rm11 to be done\n"); - break; + } + } // if (tmode <= 6) { //Table 5.2.2.6.1-1 36.213 + else { + AssertFatal(1 == 0, "support for TM 8-10 to be done\n"); } + + break; + case CQI_ReportModeAperiodic_rm20: + AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); + // UE-selected subband CQI no PMI (TM1/2/3/7) , Table 5.2.2.6.3-1 from 36.213 + AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 + || tmode == 7, + "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm20\n", + tmode); + + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + diffcqi0 = (uint8_t) (p & 0x03); + p >>= 2; + r = (uint8_t) (p & ((1 >> Ltab_uesel[bw]) - 1)); + reverse_index(Ntab_uesel[bw], Mtab_uesel[bw], r, v); + for (m = 0; m < Mtab_uesel[bw]; m++) + sched_ctl->aperiodic_subband_diffcqi0[CC_idP][v[m]] = diffcqi0; + break; + case CQI_ReportModeAperiodic_rm22: + AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); + // UE-selected subband CQI multiple PMI (TM4/6) Table 5.2.2.6.3-2 from 36.213 + + AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 + || tmode == 10, + "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm22\n", + tmode); + + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + diffcqi0 = (uint8_t) (p & 0x03); + p >>= 2; + + if (ri > 1) { + sched_ctl->aperiodic_wideband_cqi1[CC_idP] = + (uint8_t) (p & 0x0F); + p >>= 4; + diffcqi1 = (uint8_t) (p & 0x03); + p >>= 2; + } + r = (uint8_t) (p & ((1 >> Ltab_uesel[bw]) - 1)); + p >>= Ltab_uesel[bw]; + reverse_index(Ntab_uesel[bw], Mtab_uesel[bw], r, v); + if ((ri == 1) && (cc->p_eNB == 2)) { + pmi_uesel = p & 0x3; + p >>= 2; + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x3; + } else if ((ri == 2) && (cc->p_eNB == 2)) { + pmi_uesel = p & 0x1; + p >>= 1; + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x1; + } else if (cc->p_eNB == 4) { + pmi_uesel = p & 0x0F; + p >>= 4; + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x0F; + } + for (m = 0; m < Mtab_uesel[bw]; m++) { + sched_ctl->aperiodic_subband_diffcqi0[CC_idP][v[m]] = diffcqi0; + if (ri > 1) + sched_ctl->aperiodic_subband_diffcqi1[CC_idP][v[m]] = + diffcqi1; + sched_ctl->aperiodic_subband_pmi[CC_idP][v[m]] = pmi_uesel; + } + break; + case CQI_ReportModeAperiodic_rm30: + //subband CQI no PMI (TM1/2/3/7) + AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 + || tmode == 7, + "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm30\n", + tmode); + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = pdu[0] >> 4; + curbyte = 0; + curbit = 3; + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = + (pdu[curbyte] >> (curbit - 1)) & 0x03; + curbit -= 2; + if (curbit < 0) { + curbit = 7; + curbyte++; + } + } + sched_ctl->dl_cqi[CC_idP] = + sched_ctl->aperiodic_wideband_cqi0[CC_idP]; + break; + case CQI_ReportModeAperiodic_rm31: + AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); + //subband CQI single PMI (TM4/5/6) + AssertFatal(tmode == 4 || tmode == 5 || tmode == 6 || tmode == 8 + || tmode == 9 + || tmode == 10, + "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm31\n", + tmode); + + if ((ri == 1) && (cc->p_eNB == 2)) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = + (uint8_t) (p & 0x0F); + p >>= 4; + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = + (uint8_t) (p & 0x03); + p >>= 2; + } + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x03; + } + if ((ri == 2) && (cc->p_eNB == 2)) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = + (uint8_t) (p & 0x0F); + p >>= 4; + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = + (uint8_t) (p & 0x01); + p >>= 1; + } + sched_ctl->aperiodic_wideband_cqi1[CC_idP] = + (uint8_t) (p & 0x0F); + p >>= 4; + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = + (uint8_t) (p & 0x01); + p >>= 1; + } + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x01; + } + if ((ri == 1) && (cc->p_eNB == 4)) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = + (uint8_t) (p & 0x0F); + p >>= 4; + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = + (uint8_t) (p & 0x03); + p >>= 2; + } + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x0F; + } + if ((ri > 1) && (cc->p_eNB == 4)) { // Note : 64 bits for 20 MHz + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = + (uint8_t) (p & 0x0F); + p >>= 4; + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = + (uint8_t) (p & 0x01); + p >>= 1; + } + sched_ctl->aperiodic_wideband_cqi1[CC_idP] = + (uint8_t) (p & 0x0F); + p >>= 4; + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = + (uint8_t) (p & 0x01); + p >>= 2; + } + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x0F; + } + + break; + case CQI_ReportModeAperiodic_rm32_v1250: + AssertFatal(tmode == 4 || tmode == 5 || tmode == 6 || tmode == 8 + || tmode == 9 + || tmode == 10, + "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm32\n", + tmode); + AssertFatal(1 == 0, "CQI_ReportModeAperiodic_rm32 to be done\n"); + break; + case CQI_ReportModeAperiodic_rm10_v1310: + AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 + || tmode == 7, + "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm10\n", + tmode); + AssertFatal(1 == 0, "CQI_ReportModeAperiodic_rm10 to be done\n"); + break; + case CQI_ReportModeAperiodic_rm11_v1310: + AssertFatal(tmode == 4 || tmode == 5 || tmode == 6 || tmode == 8 + || tmode == 9 + || tmode == 10, + "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm11\n", + tmode); + AssertFatal(1 == 0, "CQI_ReportModeAperiodic_rm11 to be done\n"); + break; + } } void @@ -4349,105 +3855,105 @@ cqi_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, nfapi_cqi_indication_rel9_t * rel9, uint8_t * pdu, nfapi_ul_cqi_information_t * ul_cqi_information) { - int UE_id = find_UE_id(mod_idP, rntiP); - UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - if (UE_id == -1) { - LOG_W(MAC, "cqi_indication: UE %x not found\n", rntiP); - return; + int UE_id = find_UE_id(mod_idP, rntiP); + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + if (UE_id == -1) { + LOG_W(MAC, "cqi_indication: UE %x not found\n", rntiP); + return; + } + UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + + if (UE_id >= 0) { + + LOG_D(MAC,"%s() UE_id:%d channel:%d cqi:%d\n", __FUNCTION__, UE_id, ul_cqi_information->channel, ul_cqi_information->ul_cqi); + + if (ul_cqi_information->channel == 0) { // PUCCH + + // extract pucch csi information before changing RI information + extract_pucch_csi(mod_idP, CC_idP, UE_id, frameP, subframeP, + pdu, rel9->length); + + memcpy((void *) sched_ctl->periodic_ri_received, + (void *) rel9->ri, rel9->number_of_cc_reported); + + // SNR for PUCCH2 + sched_ctl->pucch2_snr[CC_idP] = ul_cqi_information->ul_cqi; + } else { //PUSCH + memcpy((void *) sched_ctl->aperiodic_ri_received, + (void *) rel9->ri, rel9->number_of_cc_reported); + + extract_pusch_csi(mod_idP, CC_idP, UE_id, frameP, subframeP, + pdu, rel9->length); + } - UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - if (UE_id >= 0) { - - LOG_D(MAC,"%s() UE_id:%d channel:%d cqi:%d\n", __FUNCTION__, UE_id, ul_cqi_information->channel, ul_cqi_information->ul_cqi); - - if (ul_cqi_information->channel == 0) { // PUCCH - - // extract pucch csi information before changing RI information - extract_pucch_csi(mod_idP, CC_idP, UE_id, frameP, subframeP, - pdu, rel9->length); - - memcpy((void *) sched_ctl->periodic_ri_received, - (void *) rel9->ri, rel9->number_of_cc_reported); - - // SNR for PUCCH2 - sched_ctl->pucch2_snr[CC_idP] = ul_cqi_information->ul_cqi; - } else { //PUSCH - memcpy((void *) sched_ctl->aperiodic_ri_received, - (void *) rel9->ri, rel9->number_of_cc_reported); - - extract_pusch_csi(mod_idP, CC_idP, UE_id, frameP, subframeP, - pdu, rel9->length); - - } - - // timing advance - sched_ctl->timing_advance = rel9->timing_advance; - sched_ctl->timing_advance_r9 = rel9->timing_advance_r9; - } + // timing advance + sched_ctl->timing_advance = rel9->timing_advance; + sched_ctl->timing_advance_r9 = rel9->timing_advance_r9; + } } void SR_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, sub_frame_t subframeP, rnti_t rntiP, uint8_t ul_cqi) { - T(T_ENB_MAC_SCHEDULING_REQUEST, T_INT(mod_idP), T_INT(cc_idP), - T_INT(frameP), T_INT(subframeP), T_INT(rntiP)); + T(T_ENB_MAC_SCHEDULING_REQUEST, T_INT(mod_idP), T_INT(cc_idP), + T_INT(frameP), T_INT(subframeP), T_INT(rntiP)); - int UE_id = find_UE_id(mod_idP, rntiP); - UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + int UE_id = find_UE_id(mod_idP, rntiP); + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - if (UE_id != -1) { - if (mac_eNB_get_rrc_status(mod_idP, UE_RNTI(mod_idP, UE_id)) < - RRC_CONNECTED) - LOG_D(MAC, - "[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d on CC_id %d\n", - mod_idP, rntiP, frameP, subframeP, UE_id, cc_idP); + if (UE_id != -1) { + if (mac_eNB_get_rrc_status(mod_idP, UE_RNTI(mod_idP, UE_id)) < + RRC_CONNECTED) + LOG_D(MAC, + "[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d on CC_id %d\n", + mod_idP, rntiP, frameP, subframeP, UE_id, cc_idP); #if 0 - UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - /* for the moment don't use ul_cqi from SR, value is too different from harq */ - sched_ctl->pucch1_snr[cc_idP] = ul_cqi; - sched_ctl->pucch1_cqi_update[cc_idP] = 1; + /* for the moment don't use ul_cqi from SR, value is too different from harq */ + sched_ctl->pucch1_snr[cc_idP] = ul_cqi; + sched_ctl->pucch1_cqi_update[cc_idP] = 1; #endif - UE_list->UE_template[cc_idP][UE_id].ul_SR = 1; - UE_list->UE_template[cc_idP][UE_id].ul_active = TRUE; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION, 1); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION, 0); - } else { - // AssertFatal(0, "find_UE_id(%u,rnti %d) not found", enb_mod_idP, rntiP); - // AssertError(0, 0, "Frame %d: find_UE_id(%u,rnti %d) not found\n", frameP, enb_mod_idP, rntiP); - LOG_D(MAC, - "[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d (unknown UEid) on CC_id %d\n", - mod_idP, rntiP, frameP, subframeP, UE_id, cc_idP); - } + UE_list->UE_template[cc_idP][UE_id].ul_SR = 1; + UE_list->UE_template[cc_idP][UE_id].ul_active = TRUE; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION, 1); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION, 0); + } else { + // AssertFatal(0, "find_UE_id(%u,rnti %d) not found", enb_mod_idP, rntiP); + // AssertError(0, 0, "Frame %d: find_UE_id(%u,rnti %d) not found\n", frameP, enb_mod_idP, rntiP); + LOG_D(MAC, + "[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d (unknown UEid) on CC_id %d\n", + mod_idP, rntiP, frameP, subframeP, UE_id, cc_idP); + } } void UL_failure_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, rnti_t rntiP, sub_frame_t subframeP) { - int UE_id = find_UE_id(mod_idP, rntiP); - UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + int UE_id = find_UE_id(mod_idP, rntiP); + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - if (UE_id != -1) { - LOG_D(MAC, - "[eNB %d][UE %d/%x] Frame %d subframeP %d Signaling UL Failure for UE %d on CC_id %d (timer %d)\n", - mod_idP, UE_id, rntiP, frameP, subframeP, UE_id, cc_idP, - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer); - if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 0) - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 1; - } else { - // AssertFatal(0, "find_UE_id(%u,rnti %d) not found", enb_mod_idP, rntiP); - // AssertError(0, 0, "Frame %d: find_UE_id(%u,rnti %d) not found\n", frameP, enb_mod_idP, rntiP); - LOG_W(MAC, - "[eNB %d][SR %x] Frame %d subframeP %d Signaling UL Failure for UE %d (unknown UEid) on CC_id %d\n", - mod_idP, rntiP, frameP, subframeP, UE_id, cc_idP); - } + if (UE_id != -1) { + LOG_D(MAC, + "[eNB %d][UE %d/%x] Frame %d subframeP %d Signaling UL Failure for UE %d on CC_id %d (timer %d)\n", + mod_idP, UE_id, rntiP, frameP, subframeP, UE_id, cc_idP, + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer); + if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 0) + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 1; + } else { + // AssertFatal(0, "find_UE_id(%u,rnti %d) not found", enb_mod_idP, rntiP); + // AssertError(0, 0, "Frame %d: find_UE_id(%u,rnti %d) not found\n", frameP, enb_mod_idP, rntiP); + LOG_W(MAC, + "[eNB %d][SR %x] Frame %d subframeP %d Signaling UL Failure for UE %d (unknown UEid) on CC_id %d\n", + mod_idP, rntiP, frameP, subframeP, UE_id, cc_idP); + } } void @@ -4455,31 +3961,31 @@ harq_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, sub_frame_t subframeP, nfapi_harq_indication_pdu_t * harq_pdu) { - rnti_t rnti = harq_pdu->rx_ue_information.rnti; - uint8_t ul_cqi = harq_pdu->ul_cqi_information.ul_cqi; - uint8_t channel = harq_pdu->ul_cqi_information.channel; - int UE_id = find_UE_id(mod_idP, rnti); - if (UE_id == -1) { - LOG_W(MAC, "harq_indication: UE %x not found\n", rnti); - return; - } - UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; - // extract HARQ Information - LOG_D(MAC, - "Frame %d, subframe %d: Received harq indication (%d) from UE %d/%x, ul_cqi %d\n", - frameP, subframeP, channel, UE_id, rnti, ul_cqi); - if (cc->tdd_Config) - extract_harq(mod_idP, CC_idP, UE_id, frameP, subframeP, - (void *) &harq_pdu->harq_indication_tdd_rel13, - channel); - else - extract_harq(mod_idP, CC_idP, UE_id, frameP, subframeP, - (void *) &harq_pdu->harq_indication_fdd_rel13, - channel); - if (channel == 0) { - sched_ctl->pucch1_snr[CC_idP] = ul_cqi; - sched_ctl->pucch1_cqi_update[CC_idP] = 1; - } + rnti_t rnti = harq_pdu->rx_ue_information.rnti; + uint8_t ul_cqi = harq_pdu->ul_cqi_information.ul_cqi; + uint8_t channel = harq_pdu->ul_cqi_information.channel; + int UE_id = find_UE_id(mod_idP, rnti); + if (UE_id == -1) { + LOG_W(MAC, "harq_indication: UE %x not found\n", rnti); + return; + } + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; + // extract HARQ Information + LOG_D(MAC, + "Frame %d, subframe %d: Received harq indication (%d) from UE %d/%x, ul_cqi %d\n", + frameP, subframeP, channel, UE_id, rnti, ul_cqi); + if (cc->tdd_Config) + extract_harq(mod_idP, CC_idP, UE_id, frameP, subframeP, + (void *) &harq_pdu->harq_indication_tdd_rel13, + channel); + else + extract_harq(mod_idP, CC_idP, UE_id, frameP, subframeP, + (void *) &harq_pdu->harq_indication_fdd_rel13, + channel); + if (channel == 0) { + sched_ctl->pucch1_snr[CC_idP] = ul_cqi; + sched_ctl->pucch1_cqi_update[CC_idP] = 1; + } } From 0937339a5385e8771f1a73f698f9e1b51acb0b0e Mon Sep 17 00:00:00 2001 From: Navid Nikaein Date: Fri, 12 Jan 2018 12:01:44 +0100 Subject: [PATCH 066/195] Update MAC scheduler for slicing (not tested) --- openair2/COMMON/platform_types.h | 1 + openair2/LAYER2/MAC/defs.h | 2 +- openair2/LAYER2/MAC/eNB_scheduler.c | 28 +- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 156 ++++++++++- .../LAYER2/MAC/eNB_scheduler_primitives.c | 25 ++ openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 256 ++++++++++-------- .../MAC/flexran_agent_scheduler_dlsch_ue.c | 2 +- openair2/LAYER2/MAC/pre_processor.c | 177 +++++++----- openair2/LAYER2/MAC/proto.h | 18 +- 9 files changed, 453 insertions(+), 212 deletions(-) diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index 3997d579bd..e5379d532d 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -69,6 +69,7 @@ typedef uint32_t frame_t; typedef int32_t sframe_t; typedef uint32_t sub_frame_t; typedef uint8_t module_id_t; +typedef uint8_t slice_id_t; typedef uint8_t eNB_index_t; typedef uint16_t ue_id_t; typedef int16_t smodule_id_t; diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index 43d8167fe6..e27ef3648a 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -800,7 +800,7 @@ typedef struct { ///Contention resolution timer used during random access uint8_t mac_ContentionResolutionTimer; - uint16_t max_allowed_rbs[MAX_NUM_LCID]; + uint16_t max_rbs_allowed_slice[MAX_NUM_LCID][MAX_NUM_SLICES]; uint8_t max_mcs[MAX_NUM_LCID]; diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 14715aff5a..432915eb8c 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -744,40 +744,14 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, copy_ulreq(module_idP, frameP, subframeP); // This schedules SRS in subframeP schedule_SRS(module_idP, frameP, subframeP); -#if defined(FLEXRAN_AGENT_SB_IF) - if (mac_agent_registered[module_idP]){ - agent_mac_xface[module_idP]->flexran_agent_schedule_ul_spec(module_idP,frameP,cooperation_flag,0,4, &msg); - } - flexran_agent_mac_destroy_ul_config(msg); -#else // This schedules ULSCH in subframeP (dci0) schedule_ulsch(module_idP, frameP, subframeP); -#endif // This schedules UCI_SR in subframeP schedule_SR(module_idP, frameP, subframeP); // This schedules UCI_CSI in subframeP schedule_CSI(module_idP, frameP, subframeP); - -#if defined(FLEXRAN_AGENT_SB_IF) - if (mac_agent_registered[module_idP]) { - agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec( - module_idP, - frameP, - subframeP, - mbsfn_status, - &msg); - - flexran_apply_scheduling_decisions(module_idP, - frameP, - subframeP, - mbsfn_status, - msg); - flexran_agent_mac_destroy_dl_config(msg); - } -#else // This schedules DLSCH in subframeP - schedule_ue_spec(module_idP, frameP, subframeP, mbsfn_status); -#endif + schedule_dlsch(module_idP, frameP, subframeP, mbsfn_status); // Allocate CCEs for good after scheduling is done for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 9dbbb39d03..0d9f129fa6 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -57,6 +57,15 @@ #include "intertask_interface.h" #endif +#if defined FLEXRAN_AGENT_SB_IF +#include "ENB_APP/flexran_agent_defs.h" +#include "flexran_agent_ran_api.h" +#include "header.pb-c.h" +#include "flexran.pb-c.h" +#include "flexran_agent_mac.h" +#include +#endif + #include "T.h" #define ENABLE_MAC_PAYLOAD_DEBUG @@ -64,6 +73,36 @@ extern RAN_CONTEXT_t RC; + +// number of active slices for past and current time +int n_active_slices = 1; +int n_active_slices_current = 1; + +// RB share for each slice for past and current time +float avg_slice_percentage=0.25; +float slice_percentage[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; +float slice_percentage_current[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; +float total_slice_percentage = 0; +float total_slice_percentage_current = 0; + +// MAX MCS for each slice for past and current time +int slice_maxmcs[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; +int slice_maxmcs_current[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; + +int update_dl_scheduler[MAX_NUM_SLICES] = { 1, 1, 1, 1 }; +int update_dl_scheduler_current[MAX_NUM_SLICES] = { 1, 1, 1, 1 }; + +// name of available scheduler +char *dl_scheduler_type[MAX_NUM_SLICES] = + { "schedule_ue_spec", + "schedule_ue_spec", + "schedule_ue_spec", + "schedule_ue_spec" + }; + +// pointer to the slice specific scheduler +slice_scheduler_dl slice_sched_dl[MAX_NUM_SLICES] = {0}; + //------------------------------------------------------------------------------ void add_ue_dlsch_info(module_id_t module_idP, @@ -408,12 +447,117 @@ set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP, } } +//------------------------------------------------------------------------------ +void +schedule_dlsch(module_id_ module_idP, + frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) +//------------------------------------------------------------------------------{ +{ + + int i=0; + + total_slice_percentage=0; + avg_slice_percentage=1.0/n_active_slices; + + // reset the slice percentage for inactive slices + for (i = n_active_slices; i< MAX_NUM_SLICES; i++) { + slice_percentage[i]=0; + } + for (i = 0; i < n_active_slices; i++) { + if (slice_percentage[i] < 0 ){ + LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero", + mod_id, frame, subframe, i, slice_percentage[i]); + slice_percentage[i]=0; + } + total_slice_percentage+=slice_percentage[i]; + } + + for (i = 0; i < n_active_slices; i++) { + + // Load any updated functions + if (update_dl_scheduler[i] > 0 ) { + slice_sched_dl[i] = dlsym(NULL, dl_scheduler_type[i]); + update_dl_scheduler[i] = 0; + update_dl_scheduler_current[i] = 0; + LOG_N(MAC,"update dl scheduler slice %d\n", i); + } + + if (total_slice_percentage <= 1.0){ // the new total RB share is within the range + + // check if the number of slices has changed, and log + if (n_active_slices_current != n_active_slices ){ + if ((n_active_slices > 0) && (n_active_slices <= MAX_NUM_SLICES)) { + LOG_N(MAC,"[eNB %d]frame %d subframe %d: number of active DL slices has changed: %d-->%d\n", + mod_id, frame, subframe, n_active_slices_current, n_active_slices); + + n_active_slices_current = n_active_slices; + + } else { + LOG_W(MAC,"invalid number of DL slices %d, revert to the previous value %d\n",n_active_slices, n_active_slices_current); + n_active_slices = n_active_slices_current; + } + } + + // check if the slice rb share has changed, and log the console + if (slice_percentage_current[i] != slice_percentage[i]){ // new slice percentage + LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", + mod_id, i, frame, subframe, total_slice_percentage_current, total_slice_percentage, slice_percentage_current[i], slice_percentage[i]); + total_slice_percentage_current= total_slice_percentage; + slice_percentage_current[i] = slice_percentage[i]; + + } + + // check if the slice max MCS, and log the console + if (slice_maxmcs_current[i] != slice_maxmcs[i]){ + if ((slice_maxmcs[i] >= 0) && (slice_maxmcs[i] < 29)){ + LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", + mod_id, i, frame, subframe, slice_maxmcs_current[i], slice_maxmcs[i]); + slice_maxmcs_current[i] = slice_maxmcs[i]; + } else { + LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid slice max mcs %d, revert the previous value %d\n",mod_id, i, slice_maxmcs[i],slice_maxmcs_current[i]); + slice_maxmcs[i]= slice_maxmcs_current[i]; + } + } + + // check if a new scheduler, and log the console + if (update_dl_scheduler_current[i] != update_dl_scheduler[i]){ + LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: DL scheduler for this slice is updated: %s \n", + mod_id, i, frame, subframe, dl_scheduler_type[i]); + update_dl_scheduler_current[i] = update_dl_scheduler[i]; + } + + } else { + // here we can correct the values, e.g. reduce proportionally + + if (n_active_slices == n_active_slices_current){ + LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n", + mod_id,i, + total_slice_percentage_current, total_slice_percentage); + if (slice_percentage[i] >= avg_slice_percentage){ + slice_percentage[i]-=0.1; + total_slice_percentage-=0.1; + } + } else { + LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n", + mod_id,i, + total_slice_percentage_current, total_slice_percentage, + n_active_slices, n_active_slices_current ); + n_active_slices = n_active_slices_current; + slice_percentage[i] = slice_percentage_current[i]; + } + } + + // Run each enabled slice-specific schedulers one by one + slice_sched_dl[i](mod_id, i, frame, subframe, mbsfn_flag,dl_info); + } + +} // changes to pre-processor for eMTC //------------------------------------------------------------------------------ void -schedule_ue_spec(module_id_t module_idP, +schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) //------------------------------------------------------------------------------ { @@ -539,7 +683,11 @@ schedule_ue_spec(module_id_t module_idP, (VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_IN); start_meas(&eNB->schedule_dlsch_preprocessor); dlsch_scheduler_pre_processor(module_idP, - frameP, subframeP, N_RBG, mbsfn_flag); + slice_idP, + frameP, + subframeP, + N_RBG, + mbsfn_flag); stop_meas(&eNB->schedule_dlsch_preprocessor); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME (VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT); @@ -570,6 +718,8 @@ schedule_ue_spec(module_id_t module_idP, LOG_D(MAC, "[eNB] Cannot find eNB_UE_stats\n"); continue_flag = 1; } + if (flexran_slice_member(UE_id, slice_idP) == 0) + continue; if (continue_flag != 1) { switch (get_tmode(module_idP, CC_id, UE_id)) { @@ -656,7 +806,7 @@ schedule_ue_spec(module_id_t module_idP, */ eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; - eNB_UE_stats->dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; //cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); + eNB_UE_stats->dlsch_mcs1 =cmin(eNB_UE_stats->dlsch_mcs1, flexran_slice_maxmcs(slice_idP));//openair_daq_vars.target_ue_dl_mcs); // store stats diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index e5f608d74c..4a316cf92c 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -4472,3 +4472,28 @@ harq_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, sched_ctl->pucch1_cqi_update[CC_idP] = 1; } } + +// Flexran Slicing functions + +uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, int total_rbs) +{ + return (uint16_t) floor(rb_percentage * total_rbs); +} + +int flexran_slice_maxmcs(int slice_id) +{ + return slice_maxmcs[slice_id]; +} + +int flexran_slice_member(int UE_id, int slice_id) +{ + + if ((slice_id < 0) || (slice_id > n_active_slices)) + LOG_W(MAC, "out of range slice id %d\n", slice_id); + + + if ((UE_id % n_active_slices) == slice_id) { + return 1; // this ue is a member of this slice + } + return 0; +} diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 035e4c5fa3..b5256820bb 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -57,6 +57,15 @@ #include "intertask_interface.h" #endif +#if defined FLEXRAN_AGENT_SB_IF +#include "ENB_APP/flexran_agent_defs.h" +#include "flexran_agent_ran_api.h" +#include "header.pb-c.h" +#include "flexran.pb-c.h" +#include "flexran_agent_mac.h" +#include +#endif + #include "T.h" #define ENABLE_MAC_PAYLOAD_DEBUG @@ -68,6 +77,37 @@ uint8_t rb_table[34] = 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80, 81, 90, 96, 100 }; +/* number of active slices for past and current time*/ +int n_active_slices_uplink = 1; +int n_active_slices_current_uplink = 1; + +/* RB share for each slice for past and current time*/ +float avg_slice_percentage_uplink=0.25; +float slice_percentage_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; +float slice_percentage_current_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; +float total_slice_percentage_uplink = 0; +float total_slice_percentage_current_uplink = 0; + +// MAX MCS for each slice for past and current time +int slice_maxmcs_uplink[MAX_NUM_SLICES] = {16, 16, 16, 16}; +int slice_maxmcs_current_uplink[MAX_NUM_SLICES] = {16,16,16,16}; + +/*resource blocks allowed*/ +uint16_t nb_rbs_allowed_slice_uplink[MAX_NUM_CCs][MAX_NUM_SLICES]; +/*Slice Update */ +int update_ul_scheduler[MAX_NUM_SLICES] = {1, 1, 1, 1}; +int update_ul_scheduler_current[MAX_NUM_SLICES] = {1, 1, 1, 1}; + +/* name of available scheduler*/ +char *ul_scheduler_type[MAX_NUM_SLICES] = {"schedule_ulsch_rnti", + "schedule_ulsch_rnti", + "schedule_ulsch_rnti", + "schedule_ulsch_rnti" +}; + +/* Slice Function Pointer */ +slice_scheduler_ul slice_sched_ul[MAX_NUM_SLICES] = {0}; + void rx_sdu(const module_id_t enb_mod_idP, const int CC_idP, @@ -921,7 +961,6 @@ set_msg3_subframe(module_id_t Mod_id, } } - void schedule_ulsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) @@ -1035,14 +1074,117 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, } } - schedule_ulsch_rnti(module_idP, frameP, subframeP, sched_subframe, - first_rb); + // perform slice-specifc operations + + total_slice_percentage_uplink=0; + avg_slice_percentage_uplink=1.0/n_active_slices_uplink; + + // reset the slice percentage for inactive slices + for (i = n_active_slices_uplink; i< MAX_NUM_SLICES; i++) { + slice_percentage_uplink[i]=0; + } + for (i = 0; i < n_active_slices_uplink; i++) { + if (slice_percentage_uplink[i] < 0 ){ + LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero", + mod_id, frame, subframe, i, slice_percentage_uplink[i]); + slice_percentage_uplink[i]=0; + } + total_slice_percentage_uplink+=slice_percentage_uplink[i]; + } + + for (i = 0; i < n_active_slices_uplink; i++) { + + // Load any updated functions + if (update_ul_scheduler[i] > 0 ) { + slice_sched_ul[i] = dlsym(NULL, ul_scheduler_type[i]); + update_ul_scheduler[i] = 0; + update_ul_scheduler_current[i] = 0; + //slice_percentage_current_uplink[i]= slice_percentage_uplink[i]; + //total_slice_percentage_current_uplink+=slice_percentage_uplink[i]; + //if (total_slice_percentage_current_uplink> 1) + // total_slice_percentage_current_uplink=1; + LOG_N(MAC,"update ul scheduler slice %d\n", i); + } + // the new total RB share is within the range + if (total_slice_percentage_uplink <= 1.0){ + + // check if the number of slices has changed, and log + if (n_active_slices_current_uplink != n_active_slices_uplink ){ + if ((n_active_slices_uplink > 0) && (n_active_slices_uplink <= MAX_NUM_SLICES)) { + LOG_N(MAC,"[eNB %d]frame %d subframe %d: number of active UL slices has changed: %d-->%d\n", + mod_id, frame, subframe, n_active_slices_current_uplink, n_active_slices_uplink); + + n_active_slices_current_uplink = n_active_slices_uplink; + + } else { + LOG_W(MAC,"invalid number of UL slices %d, revert to the previous value %d\n",n_active_slices_uplink, n_active_slices_current_uplink); + n_active_slices_uplink = n_active_slices_current_uplink; + } + } + + // check if the slice rb share has changed, and log the console + if (slice_percentage_current_uplink[i] != slice_percentage_uplink[i]){ + LOG_N(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", + mod_id, i, frame, subframe, total_slice_percentage_current_uplink, total_slice_percentage_uplink, slice_percentage_current_uplink[i], slice_percentage_uplink[i]); + total_slice_percentage_current_uplink= total_slice_percentage_uplink; + slice_percentage_current_uplink[i] = slice_percentage_uplink[i]; + + } + + // check if the slice max MCS, and log the console + if (slice_maxmcs_current_uplink[i] != slice_maxmcs_uplink[i]){ + if ((slice_maxmcs_uplink[i] >= 0) && (slice_maxmcs_uplink[i] <= 16)){ + LOG_N(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", + mod_id, i, frame, subframe, slice_maxmcs_current_uplink[i], slice_maxmcs_uplink[i]); + slice_maxmcs_current_uplink[i] = slice_maxmcs_uplink[i]; + } else { + LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid slice max mcs %d, revert the previous value %d\n",mod_id, i, slice_maxmcs_uplink[i],slice_maxmcs_current_uplink[i]); + slice_maxmcs_uplink[i]= slice_maxmcs_current_uplink[i]; + + } + } + + // check if a new scheduler, and log the console + if (update_ul_scheduler_current[i] != update_ul_scheduler[i]){ + LOG_N(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: UL scheduler for this slice is updated: %s \n", + mod_id, i, frame, subframe, ul_scheduler_type[i]); + + update_ul_scheduler_current[i] = update_ul_scheduler[i]; + } + } + else { + + if (n_active_slices_uplink == n_active_slices_current_uplink){ + LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n", + mod_id,i, + total_slice_percentage_current_uplink, total_slice_percentage_uplink); + if (slice_percentage_uplink[i] > avg_slice_percentage_uplink){ + slice_percentage_uplink[i]-=0.1; + total_slice_percentage_uplink-=0.1; + } + } else { + // here we can correct the values, e.g. reduce proportionally + LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n", + mod_id,i, + total_slice_percentage_current_uplink, total_slice_percentage_uplink, + n_active_slices_uplink, n_active_slices_current_uplink); + n_active_slices_uplink = n_active_slices_current_uplink; + slice_percentage_uplink[i] = slice_percentage_current_uplink[i]; + } + } + + // Run each enabled slice-specific schedulers one by one + slice_sched_ul[i](module_idP, i,frameP, subframeP, sched_subframe, + first_rb); + } + stop_meas(&mac->schedule_ulsch); } void schedule_ulsch_rnti(module_id_t module_idP, + slice_id_t slice_id, frame_t frameP, sub_frame_t subframeP, unsigned char sched_subframeP, uint16_t * first_rb) @@ -1081,7 +1223,7 @@ schedule_ulsch_rnti(module_id_t module_idP, &mac->UL_req_tmp[CC_id][sched_subframeP].ul_config_request_body; LOG_D(MAC, "entering ulsch preprocesor\n"); - ulsch_scheduler_pre_processor(module_idP, frameP, subframeP, first_rb); + ulsch_scheduler_pre_processor(module_idP, slice_id, frameP, subframeP, first_rb); LOG_D(MAC, "exiting ulsch preprocesor\n"); @@ -1115,7 +1257,6 @@ schedule_ulsch_rnti(module_id_t module_idP, for (n=0; nnumactiveULCCs[UE_id]; n++) { CC_id = UE_list->ordered_ULCCids[n][UE_id]; -<<<<<<< HEAD if (mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti) == NULL) { LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: no PHY context\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id); drop_ue = 1; @@ -1142,111 +1283,6 @@ schedule_ulsch_rnti(module_id_t module_idP, subframeP, rnti); UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 1; -======= - // loop over all active UL CC_ids for this UE - for (n=0; nnumactiveULCCs[UE_id]; n++) { - // This is the actual CC_id in the list - CC_id = UE_list->ordered_ULCCids[n][UE_id]; - frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id); - eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti); - - aggregation=get_aggregation(get_bw_index(module_idP,CC_id), - eNB_UE_stats->DL_cqi[0], - format0); - - if (CCE_allocation_infeasible(module_idP,CC_id,0,subframeP,aggregation,rnti)) { - LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: not enough nCCE\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id); - continue; // break; - } else{ - LOG_D(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d mode %s: aggregation level %d\n", - module_idP,frameP,subframeP,UE_id,rnti,CC_id, mode_string[eNB_UE_stats->mode], 1<mode == PUSCH) { // ue has a ulsch channel - - DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu; - UE_template = &UE_list->UE_template[CC_id][UE_id]; - UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id]; - - if (mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL) == -1 ) { - LOG_W(MAC,"[eNB %d] Scheduler Frame %d, subframeP %d: candidate harq_pid from PHY for UE %d CC %d RNTI %x\n", - module_idP,frameP,subframeP, UE_id, CC_id, rnti); - continue; - } else - LOG_T(MAC,"[eNB %d] Frame %d, subframeP %d, UE %d CC %d : got harq pid %d round %d (rnti %x,mode %s)\n", - module_idP,frameP,subframeP,UE_id,CC_id, harq_pid, round,rnti,mode_string[eNB_UE_stats->mode]); - - PHY_vars_eNB_g[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->ul_total_buffer; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO,PHY_vars_eNB_g[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP]); - if (((UE_is_to_be_scheduled(module_idP,CC_id,UE_id)>0)) || (round>0))// || ((frameP%10)==0)) - // if there is information on bsr of DCCH, DTCH or if there is UL_SR, or if there is a packet to retransmit, or we want to schedule a periodic feedback every 10 frames - { - LOG_D(MAC,"[eNB %d][PUSCH] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d)\n", - module_idP,frameP,subframeP,UE_id,rnti,round,UE_template->ul_SR, - UE_sched_ctrl->ul_inactivity_timer, - UE_sched_ctrl->ul_failure_timer); - // reset the scheduling request - UE_template->ul_SR = 0; - status = mac_eNB_get_rrc_status(module_idP,rnti); - if (status < RRC_CONNECTED) - cqi_req = 0; - else if (UE_sched_ctrl->cqi_req_timer>30) { - cqi_req = 1; - UE_sched_ctrl->cqi_req_timer=0; - } - else - cqi_req = 0; - - //power control - //compute the expected ULSCH RX power (for the stats) - - // this is the normalized RX power and this should be constant (regardless of mcs - normalized_rx_power = eNB_UE_stats->UL_rssi[0]; - target_rx_power = mac_xface->get_target_pusch_rx_power(module_idP,CC_id); - - // this assumes accumulated tpc - // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out - int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame*10+UE_template->pusch_tpc_tx_subframe; - if (((framex10psubframe+10)<=(frameP*10+subframeP)) || //normal case - ((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=10)))) //frame wrap-around - { - UE_template->pusch_tpc_tx_frame=frameP; - UE_template->pusch_tpc_tx_subframe=subframeP; - if (normalized_rx_power>(target_rx_power+1)) { - tpc = 0; //-1 - tpc_accumulated--; - } else if (normalized_rx_power<(target_rx_power-1)) { - tpc = 2; //+1 - tpc_accumulated++; - } else { - tpc = 1; //0 - } - } else { - tpc = 1; //0 - } - - if (tpc!=1) { - LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", - module_idP,frameP,subframeP,harq_pid,tpc, - tpc_accumulated,normalized_rx_power,target_rx_power); - } - - // new transmission - if (round==0) { - - ndi = 1-UE_template->oldNDI_UL[harq_pid]; - UE_template->oldNDI_UL[harq_pid]=ndi; - UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power=normalized_rx_power; - UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power=target_rx_power; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=UE_template->pre_assigned_mcs_ul; - mcs = UE_template->pre_assigned_mcs_ul;//cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS - if (UE_template->pre_allocated_rb_table_index_ul >=0) { - rb_table_index=UE_template->pre_allocated_rb_table_index_ul; - } else { - mcs=10;//cmin (10, openair_daq_vars.target_ue_ul_mcs); - rb_table_index=13; // for PHR ->>>>>>> feature-68-enb-agent } continue; } diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c index a988862542..6445fa0845 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c @@ -578,7 +578,7 @@ _dlsch_scheduler_pre_processor(module_id_t Mod_id, if (!phy_stats_exist(Mod_id, rnti)) continue; - for (ii=0; ii < UE_num_active_CC(UE_list,UE_id); ii++) { + for (ii=0; ii < UE_num_active_CC(UE_list,UE_id); ii++) { CC_id = UE_list->ordered_CCids[ii][UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; ue_sched_ctl->max_allowed_rbs[CC_id]=nb_rbs_allowed_slice[CC_id][slice_id]; diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 23d3f3bd60..a0cc0dd412 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -96,7 +96,7 @@ int phy_stats_exist(module_id_t Mod_id, int rnti) // This function stores the downlink buffer for all the logical channels void -store_dlsch_buffer(module_id_t Mod_id, frame_t frameP, +store_dlsch_buffer(module_id_t Mod_id, slice_id_t slice_id, frame_t frameP, sub_frame_t subframeP) { @@ -110,6 +110,9 @@ store_dlsch_buffer(module_id_t Mod_id, frame_t frameP, if (UE_list->active[UE_id] != TRUE) continue; + if (flexran_slice_member(UE_id, slice_id) == 0) + continue; + UE_template = &UE_list->UE_template[UE_PCCID(Mod_id, UE_id)][UE_id]; @@ -153,8 +156,8 @@ store_dlsch_buffer(module_id_t Mod_id, frame_t frameP, */ if (UE_template->dl_buffer_info[i] > 0) LOG_D(MAC, - "[eNB %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and size %d, head sdu queuing time %d, remaining size %d, is segmeneted %d \n", - Mod_id, frameP, subframeP, UE_id, + "[eNB %d][SLICE %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and size %d, head sdu queuing time %d, remaining size %d, is segmeneted %d \n", + Mod_id, slice_id, frameP, subframeP, UE_id, i, UE_template->dl_pdus_in_buffer[i], UE_template->dl_buffer_info[i], UE_template->dl_buffer_head_sdu_creation_time[i], @@ -182,6 +185,7 @@ store_dlsch_buffer(module_id_t Mod_id, frame_t frameP, // This function returns the estimated number of RBs required by each UE for downlink scheduling void assign_rbs_required(module_id_t Mod_id, + slice_id_t slice_id, frame_t frameP, sub_frame_t subframe, uint16_t @@ -200,7 +204,8 @@ assign_rbs_required(module_id_t Mod_id, for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { if (UE_list->active[UE_id] != TRUE) continue; - + if (flexran_slice_member(UE_id, slice_id) == 0) + continue; pCCid = UE_PCCID(Mod_id, UE_id); //update CQI information across component carriers @@ -262,16 +267,18 @@ assign_rbs_required(module_id_t Mod_id, to_prb(RC.mac[Mod_id]->common_channels[CC_id]. mib->message.dl_Bandwidth); + UE_list->ue_sched_ctl.max_allowed_rbs[CC_id][slice_id]= flexran_nb_rbs_allowed_slice(slice_percentage[slice_id],N_RB_DL); + /* calculating required number of RBs for each UE */ while (TBS < UE_list->UE_template[pCCid][UE_id]. dl_buffer_total) { nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id]; - if (nb_rbs_required[CC_id][UE_id] > N_RB_DL) { + if (nb_rbs_required[CC_id][UE_id] > UE_list->ue_sched_ctl.max_allowed_rbs[CC_id][slice_id]) { TBS = - get_TBS_DL(eNB_UE_stats->dlsch_mcs1, N_RB_DL); - nb_rbs_required[CC_id][UE_id] = N_RB_DL; + get_TBS_DL(eNB_UE_stats->dlsch_mcs1, UE_list->ue_sched_ctl.max_allowed_rbs[CC_id][slice_id]); + nb_rbs_required[CC_id][UE_id] = UE_list->ue_sched_ctl.max_allowed_rbs[CC_id][slice_id]; break; } @@ -556,13 +563,14 @@ void sort_UEs(module_id_t Mod_idP, int frameP, sub_frame_t subframeP) // This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done void dlsch_scheduler_pre_processor(module_id_t Mod_id, + slice_id_t slice_id, frame_t frameP, sub_frame_t subframeP, int N_RBG[MAX_NUM_CCs], int *mbsfn_flag) { unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], harq_pid = - 0, round = 0, total_ue_count; + 0, round = 0, total_ue_count[MAX_NUM_CCs], total_rbs_used[MAX_NUM_CCs]; unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]; int UE_id, i; uint16_t ii, j; @@ -619,6 +627,8 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, N_RBG[CC_id], nb_rbs_required, nb_rbs_required_remaining, + total_ue_count, + total_rbs_used, rballoc_sub, MIMO_mode_indicator); @@ -627,12 +637,12 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, // Store the DLSCH buffer for each logical channel - store_dlsch_buffer(Mod_id, frameP, subframeP); + store_dlsch_buffer(Mod_id, slice_id,frameP, subframeP); // Calculate the number of RBs required by each UE on the basis of logical channel's buffer - assign_rbs_required(Mod_id, frameP, subframeP, nb_rbs_required, + assign_rbs_required(Mod_id, slice_id, frameP, subframeP, nb_rbs_required, min_rb_unit); @@ -641,65 +651,89 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, sort_UEs(Mod_id, frameP, subframeP); - - total_ue_count = 0; - // loop over all active UEs for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - rnti = UE_RNTI(Mod_id, i); + rnti = UE_RNTI(Mod_id, i); - if (rnti == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; - UE_id = i; + if (rnti == NOT_A_RNTI) + continue; + if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) + continue; + UE_id = i; + if (flexran_slice_member(UE_id, slice_id) == 0) + continue; - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - cc = &RC.mac[Mod_id]->common_channels[ii]; - if (cc->tdd_Config) - harq_pid = ((frameP * 10) + subframeP) % 10; - else - harq_pid = ((frameP * 10) + subframeP) & 7; - round = ue_sched_ctl->round[CC_id][harq_pid]; + for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { + CC_id = UE_list->ordered_CCids[ii][UE_id]; + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + cc = &RC.mac[Mod_id]->common_channels[ii]; + if (cc->tdd_Config) + harq_pid = ((frameP * 10) + subframeP) % 10; + else + harq_pid = ((frameP * 10) + subframeP) & 7; + round = ue_sched_ctl->round[CC_id][harq_pid]; - average_rbs_per_user[CC_id] = 0; + average_rbs_per_user[CC_id] = 0; - if (round != 8) { - nb_rbs_required[CC_id][UE_id] = - UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - } - //nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id]; - if (nb_rbs_required[CC_id][UE_id] > 0) { - total_ue_count = total_ue_count + 1; - } - // hypothetical assignment - /* - * If schedule is enabled and if the priority of the UEs is modified - * The average rbs per logical channel per user will depend on the level of - * priority. Concerning the hypothetical assignement, we should assign more - * rbs to prioritized users. Maybe, we can do a mapping between the - * average rbs per user and the level of priority or multiply the average rbs - * per user by a coefficient which represents the degree of priority. - */ + if (round != 8) { + nb_rbs_required[CC_id][UE_id] = + UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + total_rbs_used[CC_id]+=nb_rbs_required[CC_id][UE_id]; + } - N_RB_DL = - to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib-> - message.dl_Bandwidth); + //nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id]; + if (nb_rbs_required[CC_id][UE_id] > 0) { + total_ue_count[CC_id] = total_ue_count[CC_id] + 1; + } - if (total_ue_count == 0) { - average_rbs_per_user[CC_id] = 0; - } else if ((min_rb_unit[CC_id] * total_ue_count) <= (N_RB_DL)) { - average_rbs_per_user[CC_id] = - (uint16_t) floor(N_RB_DL / total_ue_count); - } else { - average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; // consider the total number of use that can be scheduled UE - } - } + } } + // loop over all active UEs and calculate avg rb per user based on total active UEs + for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { + rnti = UE_RNTI(Mod_id, i); + + if (rnti == NOT_A_RNTI) + continue; + if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) + continue; + UE_id = i; + if (flexran_slice_member(UE_id, slice_id) == 0) + continue; + + for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { + CC_id = UE_list->ordered_CCids[ii][UE_id]; + + // hypothetical assignment + /* + * If schedule is enabled and if the priority of the UEs is modified + * The average rbs per logical channel per user will depend on the level of + * priority. Concerning the hypothetical assignement, we should assign more + * rbs to prioritized users. Maybe, we can do a mapping between the + * average rbs per user and the level of priority or multiply the average rbs + * per user by a coefficient which represents the degree of priority. + */ + + + N_RB_DL = + to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib-> + message.dl_Bandwidth) - total_rbs_used[CC_id]; + + //recalcualte based on the what is left after retransmission + ue_sched_ctl.max_allowed_rbs[CC_id][slice_id]= flexran_nb_rbs_allowed_slice(slice_percentage[slice_id],N_RB_DL); + + if (total_ue_count[CC_id] == 0) { + average_rbs_per_user[CC_id] = 0; + } else if ((min_rb_unit[CC_id] * total_ue_count[CC_id]) <= (ue_sched_ctl.max_allowed_rbs[CC_id][slice_id])) { + average_rbs_per_user[CC_id] = + (uint16_t) floor(ue_sched_ctl.max_allowed_rbs[CC_id][slice_id] / total_ue_count[CC_id]); + } else { + average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; // consider the total number of use that can be scheduled UE + } + } + } + // note: nb_rbs_required is assigned according to total_buffer_dl // extend nb_rbs_required to capture per LCID RB required for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { @@ -709,6 +743,8 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, continue; if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; + if (flexran_slice_member(i, slice_id) == 0) + continue; for (ii = 0; ii < UE_num_active_CC(UE_list, i); ii++) { CC_id = UE_list->ordered_CCids[ii][i]; @@ -765,11 +801,14 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, } } - if (total_ue_count > 0) { - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { + + for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { UE_id = i; for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { + + // if there are UEs with traffic + if (total_ue_count [CC_id] > 0) { CC_id = UE_list->ordered_CCids[ii][UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; round = ue_sched_ctl->round[CC_id][harq_pid]; @@ -969,9 +1008,9 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, } } #endif - } + } // total_ue_count } - } // total_ue_count + } } // end of for for r1 and r2 #ifdef TM5 @@ -1044,7 +1083,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, } //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id]; - LOG_D(MAC, "Total RBs allocated for UE%d = %d\n", UE_id, + LOG_D(MAC, "[eNB %d][SLICE %d]Total RBs allocated for UE%d = %d\n", Mod_id, slice_id, UE_id, ue_sched_ctl->pre_nb_available_rbs[CC_id]); } } @@ -1065,9 +1104,12 @@ dlsch_scheduler_pre_processor_reset(int module_idP, uint16_t nb_rbs_required_remaining [MAX_NUM_CCs][NUMBER_OF_UE_MAX], + unsigned char total_ue_count[MAX_NUM_CCs], + unsigned char total_rbs_used[MAX_NUM_CCs], unsigned char rballoc_sub[MAX_NUM_CCs] - [N_RBG_MAX], unsigned char + [N_RBG_MAX], + unsigned char MIMO_mode_indicator[MAX_NUM_CCs] [N_RBG_MAX]) { @@ -1154,7 +1196,8 @@ dlsch_scheduler_pre_processor_reset(int module_idP, ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0; ue_sched_ctl->dl_pow_off[CC_id] = 2; nb_rbs_required_remaining[CC_id][UE_id] = 0; - + total_ue_count[CC_id]=0; + total_rbs_used[CC_id]=0; switch (N_RB_DL) { case 6: RBGsize = 1; @@ -1322,7 +1365,7 @@ dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, void ulsch_scheduler_pre_processor(module_id_t module_idP, - int frameP, + slice_id_t slice_id, int frameP, sub_frame_t subframeP, uint16_t * first_rb) { @@ -1538,7 +1581,7 @@ ulsch_scheduler_pre_processor(module_id_t module_idP, void -assign_max_mcs_min_rb(module_id_t module_idP, int frameP, +assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, sub_frame_t subframeP, uint16_t * first_rb) { diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/proto.h index 9f3af1b053..a83aabef27 100644 --- a/openair2/LAYER2/MAC/proto.h +++ b/openair2/LAYER2/MAC/proto.h @@ -102,11 +102,12 @@ void schedule_ulsch(module_id_t module_idP, frame_t frameP, /** \brief ULSCH Scheduling per RNTI @param Mod_id Instance ID of eNB +@param slice_id Instance slice for this eNB @param frame Frame index @param subframe Subframe number on which to act @param sched_subframe Subframe number where PUSCH is transmitted (for DAI lookup) */ -void schedule_ulsch_rnti(module_id_t module_idP, frame_t frameP, +void schedule_ulsch_rnti(module_id_t module_idP, slice_id_t slice_idP, frame_t frameP, sub_frame_t subframe, unsigned char sched_subframe, uint16_t * first_rb); @@ -127,9 +128,12 @@ void fill_DLSCH_dci(module_id_t module_idP, frame_t frameP, @param mbsfn_flag Indicates that MCH/MCCH is in this subframe */ -void schedule_ue_spec(module_id_t module_idP, frame_t frameP, +void schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframe, int *mbsfn_flag); +void schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, + frame_t frameP,sub_frame_t subframe, int *mbsfn_flag); + /** \brief Function for UE/PHY to compute PUSCH transmit power in power-control procedure. @param Mod_id Module id of UE @@ -209,6 +213,7 @@ void dlsch_scheduler_pre_processor_reset(int module_idP, int UE_id, void dlsch_scheduler_pre_processor(module_id_t module_idP, + slice_id_t slice_idP, frame_t frameP, sub_frame_t subframe, int N_RBG[MAX_NUM_CCs], @@ -633,7 +638,7 @@ int UE_PCCID(module_id_t mod_idP, int ue_idP); rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP); -void ulsch_scheduler_pre_processor(module_id_t module_idP, int frameP, +void ulsch_scheduler_pre_processor(module_id_t module_idP, slice_id_t slice_id, int frameP, sub_frame_t subframeP, uint16_t * first_rb); void store_ulsch_buffer(module_id_t module_idP, int frameP, @@ -1158,5 +1163,12 @@ int32_t get_uldl_offset(int eutra_bandP); int l2_init_ue(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, uint8_t HO_active); +/*Slice related functions */ +uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, int total_rbs); + +int flexran_slice_member(int UE_id, int slice_id); + +int flexran_slice_maxmcs(int slice_id;) + #endif /** @}*/ From 765d6370f640c23703bfe1d77e56ddd278b25c16 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 10 Jan 2018 14:22:14 +0100 Subject: [PATCH 067/195] update FlexRAN configuration definition (paramdef) --- openair2/ENB_APP/enb_paramdef.h | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index 6a03687fab..36a1f2c0a7 100755 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -611,18 +611,26 @@ static int DEFENBS[] = {0}; /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ -#define ENB_CONFIG_STRING_NETWORK_CONTROLLER_CONFIG "NETWORK_CONTROLLER" +#define CONFIG_STRING_NETWORK_CONTROLLER_CONFIG "NETWORK_CONTROLLER" -#define ENB_CONFIG_STRING_FLEXRAN_AGENT_INTERFACE_NAME "FLEXRAN_AGENT_INTERFACE_NAME" -#define ENB_CONFIG_STRING_FLEXRAN_AGENT_IPV4_ADDRESS "FLEXRAN_AGENT_IPV4_ADDRESS" -#define ENB_CONFIG_STRING_FLEXRAN_AGENT_PORT "FLEXRAN_AGENT_PORT" -#define ENB_CONFIG_STRING_FLEXRAN_AGENT_CACHE "FLEXRAN_AGENT_CACHE" +#define CONFIG_STRING_FLEXRAN_INTERFACE_NAME "FLEXRAN_INTERFACE_NAME" +#define CONFIG_STRING_FLEXRAN_IPV4_ADDRESS "FLEXRAN_IPV4_ADDRESS" +#define CONFIG_STRING_FLEXRAN_PORT "FLEXRAN_PORT" +#define CONFIG_STRING_FLEXRAN_CACHE "FLEXRAN_CACHE" +#define CONFIG_STRING_FLEXRAN_AWAIT_RECONF "FLEXRAN_AWAIT_RECONF" + +#define FLEXRAN_INTERFACE_NAME_IDX 0 +#define FLEXRAN_IPV4_ADDRESS_IDX 1 +#define FLEXRAN_PORT_IDX 2 +#define FLEXRAN_CACHE_IDX 3 +#define FLEXRAN_AWAIT_RECONF_IDX 4 #define FLEXRANPARAMS_DESC { \ -{ENB_CONFIG_STRING_FLEXRAN_AGENT_INTERFACE_NAME, NULL, 0, uptr:NULL, defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE, TYPE_STRING, 0}, \ -{ENB_CONFIG_STRING_FLEXRAN_AGENT_IPV4_ADDRESS, NULL, 0, uptr:NULL, defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE, TYPE_STRING, 0}, \ -{ENB_CONFIG_STRING_FLEXRAN_AGENT_PORT, NULL, 0, uptr:NULL, defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE, TYPE_STRING, 0}, \ -{ENB_CONFIG_STRING_FLEXRAN_AGENT_CACHE, NULL, 0, uptr:NULL, defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE, TYPE_STRING, 0} \ +{CONFIG_STRING_FLEXRAN_INTERFACE_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ +{CONFIG_STRING_FLEXRAN_IPV4_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1/30", TYPE_STRING, 0}, \ +{CONFIG_STRING_FLEXRAN_PORT, NULL, 0, uptr:NULL, defintval:2210, TYPE_UINT, 0}, \ +{CONFIG_STRING_FLEXRAN_CACHE, NULL, 0, strptr:NULL, defstrval:"/mnt/oai_agent_cache", TYPE_STRING, 0}, \ +{CONFIG_STRING_FLEXRAN_AWAIT_RECONF, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0} \ } /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ From fac968246dd4ac9806545df257e394e504a29a80 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 10 Jan 2018 17:49:39 +0100 Subject: [PATCH 068/195] define FlexRAN data in RAN context and use it - defines RCconfig data structures - adds method to read data - use it in source files --- common/ran_context.h | 7 ++ .../MAC/flexran_agent_mac_internal.c | 2 +- openair2/ENB_APP/enb_app.c | 4 +- openair2/ENB_APP/enb_config.c | 71 ++++++++++--------- openair2/ENB_APP/enb_config.h | 3 + openair2/ENB_APP/enb_paramdef.h | 2 +- openair2/ENB_APP/flexran_agent.c | 60 ++++------------ openair2/ENB_APP/flexran_agent.h | 1 - openair2/ENB_APP/flexran_agent_common.c | 4 +- openair2/ENB_APP/flexran_agent_defs.h | 23 +++--- openair2/ENB_APP/flexran_agent_extern.h | 6 +- 11 files changed, 82 insertions(+), 101 deletions(-) diff --git a/common/ran_context.h b/common/ran_context.h index 4e25729c86..d5e2a1f172 100644 --- a/common/ran_context.h +++ b/common/ran_context.h @@ -40,6 +40,9 @@ #include "PHY/impl_defs_top.h" #include "PHY/impl_defs_lte.h" #include "RRC/LITE/defs.h" +#ifdef FLEXRAN_AGENT_SB_IF +#include "flexran_agent_defs.h" +#endif #include "gtpv1u.h" #include "NwGtpv1u.h" @@ -64,6 +67,10 @@ typedef struct { int *nb_L1_CC; /// Number of RU instances in this node int nb_RU; +#ifdef FLEXRAN_AGENT_SB_IF + /// FlexRAN context variables + flexran_agent_info_t **flexran; +#endif /// eNB context variables struct PHY_VARS_eNB_s ***eNB; /// RRC context variables diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index 7239ca8233..2af6514ef6 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -869,7 +869,7 @@ int load_dl_scheduler_function(mid_t mod_id, const char *function_name) { char lib_name[120]; char target[512]; snprintf(lib_name, sizeof(lib_name), "/%s.so", function_name); - strcpy(target, local_cache); + strcpy(target, RC.flexran[mod_id]->cache_name); strcat(target, lib_name); LOG_I(FLEXRAN_AGENT, "Opening pushed code: %s\n", target); diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index bd9be082c2..636df458ae 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -343,8 +343,8 @@ void *eNB_app_task(void *args_p) enb_app_start_phy_rrc(enb_id_start, enb_id_end); #ifdef FLEXRAN_AGENT_SB_IF - for (enb_i = 0; enb_i <1; enb_i ++){ // To be handled for all of current eNB - flexran_set_enb_vars(enb_i, RAN_LTE_OAI); + for (uint32_t enb_i = 0; enb_i <1; enb_i ++){ // To be handled for all of current eNB + flexran_set_RC_vars(enb_i, RAN_LTE_OAI); } #endif diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index f2f89ad1ca..d2a35c3bd7 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -237,6 +237,44 @@ void RCconfig_RU(void) { } +#ifdef FLEXRAN_AGENT_SB_IF +void RCconfig_flexran() +{ + int 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, + "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*)); + } + + /* For all agent instance, fill in the same controller configuration. */ + for (i = 0; i < RC.nb_L1_inst; i++) { + RC.flexran[i] = calloc(1, sizeof(flexran_agent_info_t)); + AssertFatal(RC.flexran[i] != NULL, + "can't ALLOCATE %zu Bytes for flexran agent info (iteration %d/%d)\n", + sizeof(flexran_agent_info_t), i + 1, RC.nb_L1_inst); + 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); + //strcpy(in_ip, DEFAULT_FLEXRAN_AGENT_IPv4_ADDRESS ); + RC.flexran[i]->remote_ipv4_addr = strdup(*(flexranParams[FLEXRAN_IPV4_ADDRESS_IDX].strptr)); + // DEFAULT_FLEXRAN_AGENT_PORT + RC.flexran[i]->remote_port = *(flexranParams[FLEXRAN_PORT_IDX].uptr); + // DEFAULT_FLEXRAN_AGENT_CACHE + RC.flexran[i]->cache_name = strdup(*(flexranParams[FLEXRAN_CACHE_IDX].strptr)); + RC.flexran[i]->await_reconf = strcmp(*(flexranParams[FLEXRAN_AWAIT_RECONF_IDX].strptr), "yes") == 0; + RC.flexran[i]->enb_id = i; + } + + /* TODO: show FlexRAN config now? */ +} +#endif + void RCconfig_L1() { int i,j; paramdef_t L1_Params[] = L1PARAMS_DESC; @@ -451,10 +489,6 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { /* - char* flexran_agent_interface_name = NULL; - char* flexran_agent_ipv4_address = NULL; - int32_t flexran_agent_port = 0; - char* flexran_agent_cache = NULL; int32_t otg_ue_id = 0; char* otg_app_type = NULL; char* otg_bg_traffic = NULL; @@ -2028,35 +2062,6 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { rrc->srb1_poll_byte = PollByte_kBinfinity; rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t8; } - /* - // Network Controller - subsetting = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_NETWORK_CONTROLLER_CONFIG); - - if (subsetting != NULL) { - if ( ( - config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_INTERFACE_NAME, - (const char **)&flexran_agent_interface_name) - && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_IPV4_ADDRESS, - (const char **)&flexran_agent_ipv4_address) - && config_setting_lookup_int(subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_PORT, - &flexran_agent_port) - && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_CACHE, - (const char **)&flexran_agent_cache) - ) - ) { - enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_interface_name = strdup(flexran_agent_interface_name); - cidr = flexran_agent_ipv4_address; - address = strtok(cidr, "/"); - //enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_ipv4_address = strdup(address); - if (address) { - IPV4_STR_ADDR_TO_INT_NWBO (address, enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_ipv4_address, "BAD IP ADDRESS FORMAT FOR eNB Agent !\n" ); - } - - enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_port = flexran_agent_port; - enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_cache = strdup(flexran_agent_cache); - } - } - */ /* // OTG _CONFIG diff --git a/openair2/ENB_APP/enb_config.h b/openair2/ENB_APP/enb_config.h index 0406e11e4c..4e4434ad70 100644 --- a/openair2/ENB_APP/enb_config.h +++ b/openair2/ENB_APP/enb_config.h @@ -94,6 +94,9 @@ typedef struct ru_config_s { } ru_config_t; extern void RCconfig_RU(void); +#ifdef FLEXRAN_AGENT_SB_IF +extern void RCconfig_flexran(void); +#endif extern void RCconfig_L1(void); extern void RCconfig_macrlc(void); extern int RCconfig_gtpu(void ); diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index 36a1f2c0a7..0203380314 100755 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -627,7 +627,7 @@ static int DEFENBS[] = {0}; #define FLEXRANPARAMS_DESC { \ {CONFIG_STRING_FLEXRAN_INTERFACE_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ -{CONFIG_STRING_FLEXRAN_IPV4_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1/30", TYPE_STRING, 0}, \ +{CONFIG_STRING_FLEXRAN_IPV4_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ {CONFIG_STRING_FLEXRAN_PORT, NULL, 0, uptr:NULL, defintval:2210, TYPE_UINT, 0}, \ {CONFIG_STRING_FLEXRAN_CACHE, NULL, 0, strptr:NULL, defstrval:"/mnt/oai_agent_cache", TYPE_STRING, 0}, \ {CONFIG_STRING_FLEXRAN_AWAIT_RECONF, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0} \ diff --git a/openair2/ENB_APP/flexran_agent.c b/openair2/ENB_APP/flexran_agent.c index 530cb81042..60239cbbbd 100644 --- a/openair2/ENB_APP/flexran_agent.c +++ b/openair2/ENB_APP/flexran_agent.c @@ -30,15 +30,6 @@ #include - -//#define TEST_TIMER - -flexran_agent_instance_t flexran_agent[NUM_MAX_ENB]; - -char in_ip[40]; -static uint16_t in_port; -char local_cache[40]; - void *send_thread(void *args); void *receive_thread(void *args); pthread_t new_thread(void *(*f)(void *), void *b); @@ -52,7 +43,7 @@ int agent_task_created = 0; */ void *flexran_agent_task(void *args){ - //flexran_agent_instance_t *d = (flexran_agent_instance_t *) args; + //flexran_agent_info_t *d = (flexran_agent_info_t *) args; Protocol__FlexranMessage *msg; void *data; int size; @@ -113,7 +104,7 @@ void *flexran_agent_task(void *args){ void *receive_thread(void *args) { - flexran_agent_instance_t *d = args; + flexran_agent_info_t *d = args; void *data; int size; int priority; @@ -186,46 +177,19 @@ pthread_t new_thread(void *(*f)(void *), void *b) { return t; } -void flexran_agent_reconfigure(mid_t mod_id){ - Enb_properties_array_t *enb_properties = enb_config_get(); - - /* - * check the configuration - */ - if (enb_properties->properties[mod_id]->flexran_agent_cache != NULL) { - strncpy(local_cache, enb_properties->properties[mod_id]->flexran_agent_cache, sizeof(local_cache)); - local_cache[sizeof(local_cache) - 1] = 0; - } else { - strcpy(local_cache, DEFAULT_FLEXRAN_AGENT_CACHE); - } - - if (enb_properties->properties[mod_id]->flexran_agent_ipv4_address != 0) { - inet_ntop(AF_INET, &(enb_properties->properties[mod_id]->flexran_agent_ipv4_address), in_ip, INET_ADDRSTRLEN); - } else { - strcpy(in_ip, DEFAULT_FLEXRAN_AGENT_IPv4_ADDRESS ); - } - - if (enb_properties->properties[mod_id]->flexran_agent_port != 0 ) { - in_port = enb_properties->properties[mod_id]->flexran_agent_port; - } else { - in_port = DEFAULT_FLEXRAN_AGENT_PORT ; - } - LOG_I(FLEXRAN_AGENT,"starting enb agent client for module id %d on ipv4 %s, port %d\n", - flexran_agent[mod_id].enb_id, - in_ip, - in_port); - -} - int channel_container_init = 0; int flexran_agent_start(mid_t mod_id) { int channel_id; + char *in_ip = RC.flexran[mod_id]->remote_ipv4_addr; + uint16_t in_port = RC.flexran[mod_id]->remote_port; - flexran_set_enb_vars(mod_id, RAN_LTE_OAI); - flexran_agent[mod_id].enb_id = mod_id; - - flexran_agent_reconfigure(mod_id); + RC.flexran[mod_id]->enb_id = mod_id; + /* assume for the moment the monolithic case, i.e. agent can provide + * information for all layers */ + RC.flexran[mod_id]->capability_mask = FLEXRAN_CAP_LOL1 | FLEXRAN_CAP_HIL1 + | FLEXRAN_CAP_LOL2 | FLEXRAN_CAP_HIL2 + | FLEXRAN_CAP_PDCP | FLEXRAN_CAP_RRC; /* * Initialize the channel container @@ -264,7 +228,7 @@ int flexran_agent_start(mid_t mod_id) /*Initialize the continuous stats update mechanism*/ flexran_agent_init_cont_stats_update(mod_id); - new_thread(receive_thread, &flexran_agent[mod_id]); + new_thread(receive_thread, RC.flexran[mod_id]); /*Initialize and register the mac xface. Must be modified later *for more flexibility in agent management */ @@ -293,7 +257,7 @@ int flexran_agent_start(mid_t mod_id) * start the enb agent task for tx and interaction with the underlying network function */ if (!agent_task_created) { - if (itti_create_task (TASK_FLEXRAN_AGENT, flexran_agent_task, (void *) &flexran_agent[mod_id]) < 0) { + if (itti_create_task (TASK_FLEXRAN_AGENT, flexran_agent_task, (void *) RC.flexran[mod_id]) < 0) { LOG_E(FLEXRAN_AGENT, "Create task for FlexRAN Agent failed\n"); return -1; } diff --git a/openair2/ENB_APP/flexran_agent.h b/openair2/ENB_APP/flexran_agent.h index f3f71c0631..ed9ee444c3 100644 --- a/openair2/ENB_APP/flexran_agent.h +++ b/openair2/ENB_APP/flexran_agent.h @@ -48,7 +48,6 @@ /* Initiation and termination of the eNodeB agent */ int flexran_agent_start(mid_t mod_id); int flexran_agent_stop(mid_t mod_id); -void flexran_agent_reconfigure(mid_t mod_id); /* * enb agent task mainly wakes up the tx thread for periodic and oneshot messages to the controller diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index b69ddf35cd..00aa7e9263 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -391,7 +391,7 @@ int flexran_agent_control_delegation(mid_t mod_id, const void *params, Protocol_ char lib_name[120]; char target[512]; snprintf(lib_name, sizeof(lib_name), "/%s.so", control_delegation_msg->name); - strcpy(target, local_cache); + strcpy(target, RC.flexran[mod_id]->cache_name); strcat(target, lib_name); FILE *f; @@ -1075,7 +1075,7 @@ int flexran_agent_rrc_measurement(mid_t mod_id, const void *params, Protocol__Fl struct rrc_eNB_ue_context_s *ue_context_p = NULL; - RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(eNB_rrc_inst[mod_id].rrc_ue_head)){ + RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[mod_id]->rrc_ue_head)){ PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, mod_id, ENB_FLAG_YES, ue_context_p->ue_context.rnti, flexran_get_current_frame(mod_id), flexran_get_current_subframe (mod_id), mod_id); diff --git a/openair2/ENB_APP/flexran_agent_defs.h b/openair2/ENB_APP/flexran_agent_defs.h index 2de19e59aa..dc86a422c4 100644 --- a/openair2/ENB_APP/flexran_agent_defs.h +++ b/openair2/ENB_APP/flexran_agent_defs.h @@ -138,11 +138,24 @@ 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 typedef struct { /* general info */ - + char *interface_name; + char *remote_ipv4_addr; + uint16_t remote_port; + char *cache_name; + uint8_t await_reconf; + + int enb_id; + uint8_t capability_mask; + /* stats */ uint32_t total_rx_msg; @@ -200,10 +213,4 @@ typedef struct stats_request_config_s{ report_config_t *config; } stats_request_config_t; -typedef struct { - mid_t enb_id; - flexran_agent_info_t agent_info; - -} flexran_agent_instance_t; - #endif diff --git a/openair2/ENB_APP/flexran_agent_extern.h b/openair2/ENB_APP/flexran_agent_extern.h index 8e9fef383d..589975b310 100644 --- a/openair2/ENB_APP/flexran_agent_extern.h +++ b/openair2/ENB_APP/flexran_agent_extern.h @@ -34,11 +34,7 @@ #include "flexran_agent_mac_defs.h" #include "flexran_agent_rrc_defs.h" #include "flexran_agent_pdcp_defs.h" - -//extern msg_context_t shared_ctxt[NUM_MAX_ENB][FLEXRAN_AGENT_MAX]; - -/* full path of the local cache for storing VSFs */ -extern char local_cache[40]; +#include "common/ran_context.h" /* Control module interface for the communication of the MAC Control Module with the agent */ extern AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB]; From ab3f9dad492e11c9730e911e7876984b86a76c26 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 10 Jan 2018 15:52:02 +0100 Subject: [PATCH 069/195] add flexran sample config --- .../CONF/enb.band7.tm1.50PRB.usrpb210.conf | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf index ff302811e9..b35b6147cd 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf @@ -189,6 +189,15 @@ RUs = ( } ); +NETWORK_CONTROLLER : +{ + FLEXRAN_INTERFACE_NAME = "lo"; + FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; + log_config : { global_log_level ="info"; From 6198a673f040e4c5f19005786a61942793ecbc8f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 11 Jan 2018 15:14:40 +0100 Subject: [PATCH 070/195] correctly instantiate flexran agent --- targets/RT/USER/lte-softmodem.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index ed1e708689..315eee23cd 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1268,7 +1268,9 @@ int main( int argc, char **argv ) pthread_mutex_init(&mutex_node_ctrl, NULL); pthread_cond_init(&cond_node_ctrl, NULL); - for (i = 0; i < NB_eNB_INST; i++) { + /* create RC.flexran data structure */ + RCconfig_flexran(); + for (i = 0; i < RC.nb_L1_inst; i++) { flexran_agent_start(i); } @@ -1279,11 +1281,12 @@ int main( int argc, char **argv ) pthread_mutex_unlock(&mutex_node_ctrl); /* reconfigure eNB in case FlexRAN controller applied changes */ - for (i=0; i < NB_eNB_INST; i++){ - LOG_I(ENB_APP, "Reconfigure eNB module %d and FlexRAN eNB variables\n", i); - reconfigure_enb_params(i); - flexran_set_enb_vars(i, RAN_LTE_OAI); - } + /* TODO needs to be done? */ + //for (i=0; i < NB_eNB_INST; i++){ + // LOG_I(ENB_APP, "Reconfigure eNB module %d and FlexRAN eNB variables\n", i); + // reconfigure_enb_params(i); + // flexran_set_enb_vars(i, RAN_LTE_OAI); + //} #endif if (UE_flag==1) { From cdbf65f5afdb69d26105635c047e76a902475d48 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 12 Jan 2018 09:43:33 +0100 Subject: [PATCH 071/195] revise RAN API - when changing values RC.rrc[i]->configuration should be changed too - then, RRC_RECONFIGURATION_REQ will pass the changed conf down until PHY - give warnings at functions that are not implemented - rename functions flexran_get_tdd_ack_nack_feedback() -> flexran_get_tdd_ack_nack_feedback_mode() flexran_get_ue_pmi() -> flexran_get_ue_wpmi() --- openair2/ENB_APP/flexran_agent_ran_api.c | 1626 ++++++++++------------ openair2/ENB_APP/flexran_agent_ran_api.h | 214 +-- 2 files changed, 811 insertions(+), 1029 deletions(-) diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 16462b4d40..af1d1be63d 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -21,237 +21,196 @@ /*! \file flexran_agent_ran_api.c * \brief FlexRAN RAN API abstraction - * \author N. Nikaein, X. Foukas and S. SHARIAT BAGHERI + * \author N. Nikaein, X. Foukas, S. SHARIAT BAGHERI and R. Schmidt * \date 2017 * \version 0.1 */ #include "flexran_agent_ran_api.h" - /* * generic info from RAN */ +PHY_VARS_eNB *phy[NUM_MAX_ENB][MAX_NUM_CCs] = { NULL }; +eNB_MAC_INST *mac[NUM_MAX_ENB] = { NULL }; +eNB_RRC_INST *rrc[NUM_MAX_ENB] = { NULL }; +UE_list_t *UE_list[NUM_MAX_ENB] = { NULL }; - -void * enb[NUM_MAX_ENB]; -void * enb_ue[NUM_MAX_ENB]; -void * enb_rrc[NUM_MAX_ENB]; -Enb_properties_array_t* enb_properties; - -void flexran_set_enb_vars(mid_t mod_id, ran_name_t ran){ - - switch (ran){ - case RAN_LTE_OAI : - enb_properties = enb_config_get(); - if(eNB_mac_inst == NULL){ - enb[mod_id] = NULL; - enb_ue[mod_id] = NULL; - enb_rrc[mod_id] = NULL; - }else{ - enb[mod_id] = (void *)&eNB_mac_inst[mod_id]; - enb_ue[mod_id] = (void *)&eNB_mac_inst[mod_id].UE_list; - enb_rrc[mod_id] = (void *)&eNB_rrc_inst[mod_id]; +void flexran_set_RC_vars(mid_t mod_id, ran_name_t ran) +{ + int i; + if (ran == RAN_LTE_OAI) { + if (RC.eNB && mod_id < RC.nb_RU && RC.eNB[mod_id] && RC.nb_CC) + for (i = 0; i < *RC.nb_CC; i++) + phy[mod_id][i] = RC.eNB[mod_id][i]; + if (RC.mac && mod_id < RC.nb_macrlc_inst && RC.mac[mod_id]) { + mac[mod_id] = RC.mac[mod_id]; + UE_list[mod_id] = &RC.mac[mod_id]->UE_list; } - break; - default : - goto error; - } - - return; - - error: - LOG_E(FLEXRAN_AGENT, "unknown RAN name %d\n", ran); -} - -static int mac_xface_not_ready(void) -{ - if (mac_xface == NULL) { - return 1; + if (RC.rrc && mod_id < RC.nb_macrlc_inst && RC.rrc[mod_id]) + rrc[mod_id] = RC.rrc[mod_id]; } else { - //printf("max_xface %p %d \n", mac_xface, mac_xface->active); - return 0;// !mac_xface->active; + LOG_E(FLEXRAN_AGENT, "unknown RAN name %d when setting RAN API variables\n", ran); } } -static int eNB_rrc_inst_not_ready(void) +uint32_t flexran_get_current_time_ms(mid_t mod_id, int subframe_flag) { - if (NULL == eNB_rrc_inst) { - return 1; - } - else { - return 0; - } + if (!mac[mod_id]) return 0; + if (subframe_flag == 1) + return mac[mod_id]->frame*10 + mac[mod_id]->subframe; + else + return mac[mod_id]->frame*10; } -int flexran_get_current_time_ms (mid_t mod_id, int subframe_flag){ - if (enb[mod_id] == NULL) return 0; - if (subframe_flag == 1){ - return ((eNB_MAC_INST *)enb[mod_id])->frame*10 + ((eNB_MAC_INST *)enb[mod_id])->subframe; - }else { - return ((eNB_MAC_INST *)enb[mod_id])->frame*10; - } - -} - -unsigned int flexran_get_current_frame (mid_t mod_id) { - if (enb[mod_id] == NULL) return 0; +frame_t flexran_get_current_frame(mid_t mod_id) +{ + if (!mac[mod_id]) return 0; // #warning "SFN will not be in [0-1023] when oaisim is used" - return ((eNB_MAC_INST *)enb[mod_id])->frame; - + return mac[mod_id]->frame; } -unsigned int flexran_get_current_system_frame_num(mid_t mod_id) { - return (flexran_get_current_frame(mod_id) %1024); +frame_t flexran_get_current_system_frame_num(mid_t mod_id) +{ + return flexran_get_current_frame(mod_id) % 1024; } -unsigned int flexran_get_current_subframe (mid_t mod_id) { - if (enb[mod_id] == NULL) return 0; - return ((eNB_MAC_INST *)enb[mod_id])->subframe; - +sub_frame_t flexran_get_current_subframe(mid_t mod_id) +{ + if (!mac[mod_id]) return 0; + return mac[mod_id]->subframe; } -uint16_t flexran_get_sfn_sf (mid_t mod_id) { - - frame_t frame; - sub_frame_t subframe; +/* Why uint16_t, frame_t and sub_frame_t are defined as uint32_t? */ +uint16_t flexran_get_sfn_sf(mid_t mod_id) +{ + frame_t frame = flexran_get_current_system_frame_num(mod_id); + sub_frame_t subframe = flexran_get_current_subframe(mod_id); uint16_t sfn_sf, frame_mask, sf_mask; - - frame = (frame_t) flexran_get_current_system_frame_num(mod_id); - subframe = (sub_frame_t) flexran_get_current_subframe(mod_id); - frame_mask = ((1<<12) - 1); - sf_mask = ((1<<4) - 1); + + frame_mask = (1 << 12) - 1; + sf_mask = (1 << 4) - 1; sfn_sf = (subframe & sf_mask) | ((frame & frame_mask) << 4); - + return sfn_sf; } -uint16_t flexran_get_future_sfn_sf (mid_t mod_id, int ahead_of_time) { - - frame_t frame; - sub_frame_t subframe; +uint16_t flexran_get_future_sfn_sf(mid_t mod_id, int ahead_of_time) +{ + frame_t frame = flexran_get_current_system_frame_num(mod_id); + sub_frame_t subframe = flexran_get_current_subframe(mod_id); uint16_t sfn_sf, frame_mask, sf_mask; - - frame = (frame_t) flexran_get_current_system_frame_num(mod_id); - subframe = (sub_frame_t) flexran_get_current_subframe(mod_id); + int additional_frames; - subframe = ((subframe + ahead_of_time) % 10); - - if (subframe < flexran_get_current_subframe(mod_id)) { + subframe = (subframe + ahead_of_time) % 10; + + if (subframe < flexran_get_current_subframe(mod_id)) frame = (frame + 1) % 1024; - } - - int additional_frames = ahead_of_time / 10; + + additional_frames = ahead_of_time / 10; frame = (frame + additional_frames) % 1024; - - frame_mask = ((1<<12) - 1); - sf_mask = ((1<<4) - 1); + + frame_mask = (1 << 12) - 1; + sf_mask = (1 << 4) - 1; sfn_sf = (subframe & sf_mask) | ((frame & frame_mask) << 4); - + return sfn_sf; } -int flexran_get_num_ues (mid_t mod_id){ - if (enb_ue[mod_id] == NULL) return 0; - return ((UE_list_t *)enb_ue[mod_id])->num_UEs; +int flexran_get_num_ues(mid_t mod_id) +{ + if (!UE_list[mod_id]) return 0; + return UE_list[mod_id]->num_UEs; } -int flexran_get_ue_crnti (mid_t mod_id, mid_t ue_id) { - - return UE_RNTI(mod_id, ue_id); +rnti_t flexran_get_ue_crnti(mid_t mod_id, mid_t ue_id) +{ + return UE_RNTI(mod_id, ue_id); } -int flexran_get_ue_bsr (mid_t mod_id, mid_t ue_id, lcid_t lcid) { - if (enb_ue[mod_id] == NULL) return 0; - return ((UE_list_t *)enb_ue[mod_id])->UE_template[UE_PCCID(mod_id,ue_id)][ue_id].bsr_info[lcid]; +uint8_t flexran_get_ue_bsr(mid_t mod_id, mid_t ue_id, lcid_t lcid) +{ + if (!UE_list[mod_id]) return 0; + return UE_list[mod_id]->UE_template[UE_PCCID(mod_id, ue_id)][ue_id].bsr_info[lcid]; } -int flexran_get_ue_phr (mid_t mod_id, mid_t ue_id) { - if (enb_ue[mod_id] == NULL) return 0; - return ((UE_list_t *)enb_ue[mod_id])->UE_template[UE_PCCID(mod_id,ue_id)][ue_id].phr_info; +int8_t flexran_get_ue_phr(mid_t mod_id, mid_t ue_id) +{ + if (!UE_list[mod_id]) return 0; + return UE_list[mod_id]->UE_template[UE_PCCID(mod_id, ue_id)][ue_id].phr_info; } -int flexran_get_ue_wcqi (mid_t mod_id, mid_t ue_id) { - LTE_eNB_UE_stats *eNB_UE_stats = NULL; - if (mac_xface_not_ready()) return 0 ; - - eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, 0, UE_RNTI(mod_id, ue_id)); - return eNB_UE_stats->DL_cqi[0]; - - // return ((UE_list_t *)enb_ue[mod_id])->eNB_UE_stats[UE_PCCID(mod_id,ue_id)][ue_id].dl_cqi; +uint8_t flexran_get_ue_wcqi(mid_t mod_id, mid_t ue_id) +{ + if (!phy[mod_id][0]) return 0; + return phy[mod_id][0]->UE_stats[ue_id].DL_cqi[0]; } -int flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) { - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - uint16_t frame = (uint16_t) flexran_get_current_frame(mod_id); - uint16_t subframe = (uint16_t) flexran_get_current_subframe(mod_id); +rlc_buffer_occupancy_t flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) +{ + rnti_t rnti = flexran_get_ue_crnti(mod_id, ue_id); + frame_t frame = flexran_get_current_frame(mod_id); + sub_frame_t subframe = flexran_get_current_subframe(mod_id); mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id, frame, subframe, ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0); return rlc_status.bytes_in_buffer; } - -int flexran_get_num_pdus_buffer(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) { +rlc_buffer_occupancy_t flexran_get_num_pdus_buffer(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) +{ rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - uint16_t frame = (uint16_t) flexran_get_current_frame(mod_id); - uint16_t subframe = (uint16_t) flexran_get_current_subframe(mod_id); + frame_t frame = flexran_get_current_frame(mod_id); + sub_frame_t subframe = flexran_get_current_subframe(mod_id); mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id, frame, subframe, ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0); return rlc_status.pdus_in_buffer; } - - -int flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) { +frame_t flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) +{ rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - uint16_t frame = (uint16_t) flexran_get_current_frame(mod_id); - uint16_t subframe = (uint16_t) flexran_get_current_subframe(mod_id); + frame_t frame = flexran_get_current_frame(mod_id); + sub_frame_t subframe = flexran_get_current_subframe(mod_id); mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, subframe, ENB_FLAG_YES, MBMS_FLAG_NO, channel_id, 0); return rlc_status.head_sdu_creation_time; } -short flexran_get_TA(mid_t mod_id, mid_t ue_id, int CC_id) { - - // UE_list_t *UE_list=&eNB_mac_inst[mod_id].UE_list; - int rnti; +int32_t flexran_get_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; - rnti = flexran_get_ue_crnti(mod_id, ue_id); - if (mac_xface_not_ready()) return 0 ; - - LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti); - //ue_sched_ctl->ta_timer = 20; // wait 20 subframes before taking TA measurement from PHY - switch (flexran_get_N_RB_DL(mod_id, CC_id)) { + int32_t tau = phy[mod_id][cc_id]->UE_stats[ue_id].timing_advance_update; + switch (flexran_get_N_RB_DL(mod_id, cc_id)) { case 6: - return eNB_UE_stats->timing_advance_update; + return tau; case 15: - return eNB_UE_stats->timing_advance_update/2; + return tau / 2; case 25: - return eNB_UE_stats->timing_advance_update/4; + return tau / 4; case 50: - return eNB_UE_stats->timing_advance_update/8; + return tau / 8; case 75: - return eNB_UE_stats->timing_advance_update/12; + return tau / 12; case 100: - if (flexran_get_threequarter_fs(mod_id, CC_id) == 0) { - return eNB_UE_stats->timing_advance_update/16; - } else { - return eNB_UE_stats->timing_advance_update/12; - } + if (flexran_get_threequarter_fs(mod_id, cc_id) == 0) + return tau / 16; + else + return tau / 12; default: return 0; } } -int flexran_get_ue_pmi(mid_t mod_id){ - - /*Xenofon to check this*/ - - return 0; +uint8_t flexran_get_ue_wpmi(mid_t mod_id, mid_t ue_id, uint8_t cc_id) +{ + if (!UE_list[mod_id]) return 0; + return UE_list[mod_id]->UE_sched_ctrl[ue_id].periodic_wideband_pmi[cc_id]; } - -void flexran_update_TA(mid_t mod_id, mid_t ue_id, int CC_id) { - +/* TODO needs to be revised */ +void flexran_update_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id) +{ +/* UE_list_t *UE_list=&eNB_mac_inst[mod_id].UE_list; UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[ue_id]; @@ -268,92 +227,79 @@ void flexran_update_TA(mid_t mod_id, mid_t ue_id, int CC_id) { ue_sched_ctl->ta_timer--; ue_sched_ctl->ta_update = 0; // don't trigger a timing advance command } +*/ +#warning "Implement flexran_update_TA() in RAN API" } -int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id,int CC_id) { - - // UE_list_t *UE_list = &eNB_mac_inst[mod_id].UE_list; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - if (mac_xface_not_ready()) return 0 ; +/* TODO needs to be revised, looks suspicious: why do we need UE stats? */ +int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id) +{ +#warning "Implement flexran_get_MAC_CE_bitmap_TA() in RAN API" + if (!phy[mod_id][cc_id]) return 0; + /* UE_stats can not be null, they are an array in RC LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id,CC_id,rnti); if (eNB_UE_stats == NULL) { return 0; } + */ - if (flexran_get_TA(mod_id, ue_id, CC_id) != 0) { + if (flexran_get_TA(mod_id, ue_id, cc_id) != 0) { return PROTOCOL__FLEX_CE_TYPE__FLPCET_TA; } else { return 0; } - } -int flexran_get_active_CC(mid_t mod_id, mid_t ue_id) { - if (enb_ue[mod_id] == NULL) return 0; - return ((UE_list_t *)enb_ue[mod_id])->numactiveCCs[ue_id]; +int flexran_get_active_CC(mid_t mod_id, mid_t ue_id) +{ + if (!UE_list[mod_id]) return 0; + return UE_list[mod_id]->numactiveCCs[ue_id]; } -int flexran_get_current_RI(mid_t mod_id, mid_t ue_id, int CC_id) { - LTE_eNB_UE_stats *eNB_UE_stats = NULL; - if (mac_xface_not_ready()) return 0 ; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - - eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id,CC_id,rnti); - - if (eNB_UE_stats == NULL) { - return 0; - } - - return eNB_UE_stats[CC_id].rank; +uint8_t flexran_get_current_RI(mid_t mod_id, mid_t ue_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->UE_stats[ue_id].rank; } -int flexran_get_tpc(mid_t mod_id, mid_t ue_id) { - LTE_eNB_UE_stats *eNB_UE_stats = NULL; - int32_t normalized_rx_power, target_rx_power; - int tpc = 1; +int flexran_get_tpc(mid_t mod_id, mid_t ue_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; - int pCCid = UE_PCCID(mod_id,ue_id); - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - if (mac_xface_not_ready()) return 0 ; + /* before: tested that UL_rssi != NULL and set parameter ([0]), but it is a + * static array -> target_rx_power is useless in old ifs?! */ + int pCCid = UE_PCCID(mod_id,ue_id); + int32_t target_rx_power = phy[mod_id][pCCid]->frame_parms.ul_power_control_config_common.p0_NominalPUSCH; + int32_t normalized_rx_power = phy[mod_id][cc_id]->UE_stats[ue_id].UL_rssi[0]; - eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, pCCid, rnti); - - target_rx_power = mac_xface->get_target_pusch_rx_power(mod_id,pCCid); - - if (eNB_UE_stats == NULL) { - normalized_rx_power = target_rx_power; - } else if (eNB_UE_stats->UL_rssi != NULL) { - normalized_rx_power = eNB_UE_stats->UL_rssi[0]; - } else { - normalized_rx_power = target_rx_power; - } - - if (normalized_rx_power>(target_rx_power+1)) { - tpc = 0; //-1 - } else if (normalized_rx_power<(target_rx_power-1)) { - tpc = 2; //+1 - } else { - tpc = 1; //0 - } - return tpc; + int tpc; + if (normalized_rx_power > target_rx_power + 1) + tpc = 0; //-1 + else if (normalized_rx_power < target_rx_power - 1) + tpc = 2; //+1 + else + tpc = 1; //0 + return tpc; } -int flexran_get_harq(const mid_t mod_id, - const uint8_t CC_id, - const mid_t ue_id, - const int frame, - const uint8_t subframe, - uint8_t *pid, - uint8_t *round, - const uint8_t harq_flag) { //flag_id_status = 0 then id, else status - /*TODO: Add int TB in function parameters to get the status of the second TB. This can be done to by editing in - * get_ue_active_harq_pid function in line 272 file: phy_procedures_lte_eNB.c to add - * DLSCH_ptr = PHY_vars_eNB_g[Mod_id][CC_id]->dlsch_eNB[(uint32_t)UE_id][1];*/ +int flexran_get_harq(mid_t mod_id, + uint8_t cc_id, + mid_t ue_id, + frame_t frame, + sub_frame_t subframe, + uint8_t *pid, + uint8_t *round, + uint8_t harq_flag) +{ + /* TODO: Add int TB in function parameters to get the status of the second + * TB. This can be done to by editing in get_ue_active_harq_pid function in + * line 272 file: phy_procedures_lte_eNB.c to add DLSCH_ptr = + * PHY_vars_eNB_g[Mod_id][CC_id]->dlsch_eNB[(uint32_t)UE_id][1];*/ + /* TODO IMPLEMENT */ + /* uint8_t harq_pid; uint8_t harq_round; @@ -375,61 +321,39 @@ int flexran_get_harq(const mid_t mod_id, *pid = harq_pid; - *round = harq_round; + *round = harq_round;*/ /* if (round > 0) { */ /* *status = 1; */ /* } else { */ /* *status = 0; */ /* } */ - - /* return 0; */ - return *round; + /*return *round;*/ +#warning "Implement flexran_get_harq() in RAN API" + return 0; } -int flexran_get_p0_pucch_dbm(mid_t mod_id, mid_t ue_id, int CC_id) { - LTE_eNB_UE_stats *eNB_UE_stats = NULL; - uint32_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - if (mac_xface_not_ready()) return 0 ; - - eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti); - - if (eNB_UE_stats == NULL) { - return -1; - } - - // if(eNB_UE_stats->Po_PUCCH_update == 1) { - return eNB_UE_stats->Po_PUCCH_dBm; - //} - //else - // return -1; +int32_t flexran_get_p0_pucch_dbm(mid_t mod_id, mid_t ue_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_dBm; } -int flexran_get_p0_nominal_pucch(mid_t mod_id, int CC_id) { - if (mac_xface_not_ready()) return 0 ; - - int32_t pucch_rx_received = mac_xface->get_target_pucch_rx_power(mod_id, CC_id); - return pucch_rx_received; +int8_t flexran_get_p0_nominal_pucch(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.ul_power_control_config_common.p0_NominalPUCCH; } -int flexran_get_p0_pucch_status(mid_t mod_id, mid_t ue_id, int CC_id) { - if (mac_xface_not_ready()) return 0 ; - - LTE_eNB_UE_stats *eNB_UE_stats = NULL; - uint32_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - - eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti); - return eNB_UE_stats->Po_PUCCH_update; +int32_t flexran_get_p0_pucch_status(mid_t mod_id, mid_t ue_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_update; } -int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, int CC_id) { - if (mac_xface_not_ready()) return 0 ; - - LTE_eNB_UE_stats *eNB_UE_stats = NULL; - uint32_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - - eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti); - eNB_UE_stats->Po_PUCCH_update = 0; - +int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + phy[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_update = 0; return 0; } @@ -439,243 +363,206 @@ int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, int CC_id) { * Get Messages for eNB Configuration Reply * ************************************ */ -int flexran_get_threequarter_fs(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - if (mac_xface_not_ready()) return 0 ; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->threequarter_fs; +uint8_t flexran_get_threequarter_fs(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.threequarter_fs; } -int flexran_get_hopping_offset(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - if (mac_xface_not_ready()) return 0 ; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->pusch_config_common.pusch_HoppingOffset; +uint8_t flexran_get_hopping_offset(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.pusch_config_common.pusch_HoppingOffset; } -int flexran_get_hopping_mode(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - if (mac_xface_not_ready()) return 0 ; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->pusch_config_common.hoppingMode; +PUSCH_HOPPING_t flexran_get_hopping_mode(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.pusch_config_common.hoppingMode; } -int flexran_get_n_SB(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - if (mac_xface_not_ready()) return 0 ; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->pusch_config_common.n_SB; +uint8_t flexran_get_n_SB(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.pusch_config_common.n_SB; } -int flexran_get_enable64QAM(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - if (mac_xface_not_ready()) return 0 ; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->pusch_config_common.enable64QAM; +uint8_t flexran_get_enable64QAM(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.pusch_config_common.enable64QAM; } -int flexran_get_phich_duration(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - if (mac_xface_not_ready()) return 0 ; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->phich_config_common.phich_duration; +PHICH_DURATION_t flexran_get_phich_duration(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.phich_config_common.phich_duration; } -int flexran_get_phich_resource(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - if (mac_xface_not_ready()) return 0 ; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - if(frame_parms->phich_config_common.phich_resource == oneSixth) - return 0; - else if(frame_parms->phich_config_common.phich_resource == half) - return 1; - else if(frame_parms->phich_config_common.phich_resource == one) - return 2; - else if(frame_parms->phich_config_common.phich_resource == two) - return 3; - - return -1; +int flexran_get_phich_resource(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + /* TODO why don't we return phich_resource? */ + switch (phy[mod_id][cc_id]->frame_parms.phich_config_common.phich_resource) { + case oneSixth: + return 0; + case half: + return 1; + case one: + return 2; + case two: + return 3; + default: + return -1; + } } -int flexran_get_n1pucch_an(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - if (mac_xface_not_ready()) return 0 ; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->pucch_config_common.n1PUCCH_AN; +uint16_t flexran_get_n1pucch_an(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.pucch_config_common.n1PUCCH_AN; } -int flexran_get_nRB_CQI(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - if (mac_xface_not_ready()) return 0 ; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->pucch_config_common.nRB_CQI; +uint8_t flexran_get_nRB_CQI(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.pucch_config_common.nRB_CQI; } -int flexran_get_deltaPUCCH_Shift(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - if (mac_xface_not_ready()) return 0 ; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->pucch_config_common.deltaPUCCH_Shift; +uint8_t flexran_get_deltaPUCCH_Shift(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.pucch_config_common.deltaPUCCH_Shift; } -int flexran_get_prach_ConfigIndex(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - if (mac_xface_not_ready()) return 0 ; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex; +uint8_t flexran_get_prach_ConfigIndex(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex; } -int flexran_get_prach_FreqOffset(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - if (mac_xface_not_ready()) return 0 ; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset; +uint8_t flexran_get_prach_FreqOffset(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset; } -int flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - if (mac_xface_not_ready()) return 0 ; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->maxHARQ_Msg3Tx; +uint8_t flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.maxHARQ_Msg3Tx; } -int flexran_get_ul_cyclic_prefix_length(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - if (mac_xface_not_ready()) return 0 ; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->Ncp_UL; +lte_prefix_type_t flexran_get_ul_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.Ncp_UL; } -int flexran_get_dl_cyclic_prefix_length(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - if (mac_xface_not_ready()) return 0 ; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->Ncp; +lte_prefix_type_t flexran_get_dl_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.Ncp; } -int flexran_get_cell_id(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - - if (mac_xface_not_ready()) return 0; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->Nid_cell; +uint16_t flexran_get_cell_id(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.Nid_cell; } -int flexran_get_srs_BandwidthConfig(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - if (mac_xface_not_ready()) return 0 ; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->soundingrs_ul_config_common.srs_BandwidthConfig; +uint8_t flexran_get_srs_BandwidthConfig(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig; } -int flexran_get_srs_SubframeConfig(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - if (mac_xface_not_ready()) return 0 ; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->soundingrs_ul_config_common.srs_SubframeConfig; +uint8_t flexran_get_srs_SubframeConfig(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig; } -int flexran_get_srs_MaxUpPts(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - if (mac_xface_not_ready()) return 0 ; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->soundingrs_ul_config_common.srs_MaxUpPts; +uint8_t flexran_get_srs_MaxUpPts(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.soundingrs_ul_config_common.srs_MaxUpPts; } -int flexran_get_N_RB_DL(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - if (mac_xface_not_ready()) return 0 ; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->N_RB_DL; +uint8_t flexran_get_N_RB_DL(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.N_RB_DL; } -int flexran_get_N_RB_UL(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - if (mac_xface_not_ready()) return 0 ; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->N_RB_UL; +uint8_t flexran_get_N_RB_UL(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.N_RB_UL; } -int flexran_get_N_RBG(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - if (mac_xface_not_ready()) return 0 ; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->N_RBG; +uint8_t flexran_get_N_RBG(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.N_RBG; } -int flexran_get_subframe_assignment(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - if (mac_xface_not_ready()) return 0 ; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return frame_parms->tdd_config; +uint8_t flexran_get_subframe_assignment(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.tdd_config; } -int flexran_get_special_subframe_assignment(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - if (mac_xface_not_ready()) return 0 ; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return (frame_parms == NULL)? 0:frame_parms->tdd_config_S; +uint8_t flexran_get_special_subframe_assignment(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.tdd_config_S; } -int flexran_get_ra_ResponseWindowSize(mid_t mod_id, int CC_id) { - return enb_config_get()->properties[mod_id]->rach_raResponseWindowSize[CC_id]; +long flexran_get_ra_ResponseWindowSize(mid_t mod_id, uint8_t cc_id) +{ + if (!rrc[mod_id]) return 0; + return rrc[mod_id]->configuration.rach_raResponseWindowSize[cc_id]; } -int flexran_get_mac_ContentionResolutionTimer(mid_t mod_id, int CC_id) { - return enb_config_get()->properties[mod_id]->rach_macContentionResolutionTimer[CC_id]; +long flexran_get_mac_ContentionResolutionTimer(mid_t mod_id, uint8_t cc_id) +{ + if (!rrc[mod_id]) return 0; + return rrc[mod_id]->configuration.rach_macContentionResolutionTimer[cc_id]; } -int flexran_get_duplex_mode(mid_t mod_id, int CC_id) { - LTE_DL_FRAME_PARMS *frame_parms; - if (mac_xface_not_ready()) return 0 ; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - if (frame_parms == NULL) return -1; - if(frame_parms->frame_type == TDD) - return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD; - else if (frame_parms->frame_type == FDD) - return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_FDD; - - return -1; +Protocol__FlexDuplexMode flexran_get_duplex_mode(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + switch (phy[mod_id][cc_id]->frame_parms.frame_type) { + case TDD: + return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD; + case FDD: + return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_FDD; + default: + return -1; + } } -long flexran_get_si_window_length(mid_t mod_id, int CC_id) { - return ((eNB_RRC_INST *)enb_rrc[mod_id])->carrier[CC_id].sib1->si_WindowLength; +long flexran_get_si_window_length(mid_t mod_id, uint8_t cc_id) +{ + if (!rrc[mod_id] || !rrc[mod_id]->carrier[cc_id].sib1) return 0; + return rrc[mod_id]->carrier[cc_id].sib1->si_WindowLength; } -int flexran_get_sib1_length(mid_t mod_id, int CC_id) { - return ((eNB_RRC_INST *)enb_rrc[mod_id])->carrier[CC_id].sizeof_SIB1; +uint8_t flexran_get_sib1_length(mid_t mod_id, uint8_t cc_id) +{ + if (!rrc[mod_id]) return 0; + return rrc[mod_id]->carrier[cc_id].sizeof_SIB1; } -int flexran_get_num_pdcch_symb(mid_t mod_id, int CC_id) { - /* TODO: This should return the number of PDCCH symbols initially used by the cell CC_id */ - return 0; - //(PHY_vars_UE_g[mod_id][CC_id]->lte_ue_pdcch_vars[mod_id]->num_pdcch_symbols); +uint8_t flexran_get_num_pdcch_symb(mid_t mod_id, uint8_t cc_id) { + /* TODO: This should return the number of PDCCH symbols initially used by the + * cell cc_id -> is the correction right? */ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->pdcch_vars[0].num_pdcch_symbols; + //(PHY_vars_UE_g[mod_id][cc_id]->lte_ue_pdcch_vars[mod_id]->num_pdcch_symbols); } @@ -687,98 +574,86 @@ int flexran_get_num_pdcch_symb(mid_t mod_id, int CC_id) { */ -int flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); +TimeAlignmentTimer_t flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id) +{ + if (!rrc[mod_id]) return -1; - if (eNB_rrc_inst_not_ready()) return -1; - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.mac_MainConfig != NULL) { - return ue_context_p->ue_context.mac_MainConfig->timeAlignmentTimerDedicated; - } else { - return -1; - } - } else { + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.mac_MainConfig) return -1; + return ue_context_p->ue_context.mac_MainConfig->timeAlignmentTimerDedicated; +} + +Protocol__FlexMeasGapConfigPattern flexran_get_meas_gap_config(mid_t mod_id, mid_t ue_id) +{ + if (!rrc[mod_id]) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.measGapConfig) return -1; + if (ue_context_p->ue_context.measGapConfig->present != MeasGapConfig_PR_setup) return -1; + switch (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present) { + case MeasGapConfig__setup__gapOffset_PR_gp0: + return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_GP1; + case MeasGapConfig__setup__gapOffset_PR_gp1: + return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_GP2; + default: + return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF; + } +} + + +long flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id) +{ + if (!rrc[mod_id]) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.measGapConfig) return -1; + if (ue_context_p->ue_context.measGapConfig->present != MeasGapConfig_PR_setup) return -1; + switch (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present) { + case MeasGapConfig__setup__gapOffset_PR_gp0: + return ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.choice.gp0; + case MeasGapConfig__setup__gapOffset_PR_gp1: + return ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.choice.gp1; + default: return -1; } } -int flexran_get_meas_gap_config(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); +/* TODO is there a reason we take the RNTI and not the UE ID? */ +/* TODO return type is unsigned, so we cannot return -1 in case of error! */ +uint8_t flexran_get_rrc_status(mid_t mod_id, rnti_t rnti) +{ + if (!rrc[mod_id]) return 0; - if (eNB_rrc_inst_not_ready()) return -1; + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.measGapConfig != NULL) { - if(ue_context_p->ue_context.measGapConfig->present == MeasGapConfig_PR_setup) { - if (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present == MeasGapConfig__setup__gapOffset_PR_gp0) { - return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_GP1; - } else if (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present == MeasGapConfig__setup__gapOffset_PR_gp1) { - return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_GP2; - } else { - return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF; - } - } - } - } - return -1; + if (!ue_context_p) return RRC_INACTIVE; + return ue_context_p->ue_context.Status; } - -int flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - - if (eNB_rrc_inst_not_ready()) return -1; - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.measGapConfig != NULL){ - if(ue_context_p->ue_context.measGapConfig->present == MeasGapConfig_PR_setup) { - if (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present == MeasGapConfig__setup__gapOffset_PR_gp0) { - return ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.choice.gp0; - } else if (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present == MeasGapConfig__setup__gapOffset_PR_gp1) { - return ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.choice.gp0; - } - } - } - } - return -1; +uint64_t flexran_get_ue_aggregated_max_bitrate_dl(mid_t mod_id, mid_t ue_id) +{ + if (!UE_list[mod_id]) return 0; + return UE_list[mod_id]->UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateDL; } - -int flexran_get_rrc_status(const mid_t mod_id, const rnti_t rntiP){ - - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - - if (eNB_rrc_inst_not_ready()) return -1; - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - - if (ue_context_p != NULL) { - return(ue_context_p->ue_context.Status); - } else { - return RRC_INACTIVE; - } - +uint64_t flexran_get_ue_aggregated_max_bitrate_ul(mid_t mod_id, mid_t ue_id) +{ + if (!UE_list[mod_id]) return 0; + return UE_list[mod_id]->UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateUL; } -int flexran_get_ue_aggregated_max_bitrate_dl (mid_t mod_id, mid_t ue_id) { - if (enb_ue[mod_id] == NULL) return 0; - return ((UE_list_t *)enb_ue[mod_id])->UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateDL; -} - -int flexran_get_ue_aggregated_max_bitrate_ul (mid_t mod_id, mid_t ue_id) { - if (enb_ue[mod_id] == NULL) return 0; - return ((UE_list_t *)enb_ue[mod_id])->UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateUL; -} - -int flexran_get_half_duplex(mid_t ue_id) { +int flexran_get_half_duplex(mid_t ue_id) +{ +#warning "Implement flexran_get_half_duplex() in RAN API" // TODO //int halfduplex = 0; //int bands_to_scan = ((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count; @@ -790,14 +665,18 @@ int flexran_get_half_duplex(mid_t ue_id) { return 0; } -int flexran_get_intra_sf_hopping(mid_t ue_id) { +int flexran_get_intra_sf_hopping(mid_t ue_id) +{ +#warning "Implement flexran_get_intra_sf_hopping() in RAN API" //TODO:Get proper value //temp = (((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->featureGroupIndicators->buf); //return (0 & ( 1 << (31))); return 0; } -int flexran_get_type2_sb_1(mid_t ue_id) { +int flexran_get_type2_sb_1(mid_t ue_id) +{ +#warning "Implement flexran_get_type2_sb_1() in RAN API" //TODO:Get proper value //uint8_t temp = 0; //temp = (((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->featureGroupIndicators->buf); @@ -805,13 +684,17 @@ int flexran_get_type2_sb_1(mid_t ue_id) { return 0; } -int flexran_get_ue_category(mid_t ue_id) { +int flexran_get_ue_category(mid_t ue_id) +{ +#warning "Implement flexran_get_ue_category() in RAN API" //TODO:Get proper value //return (((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->ue_Category); return 0; } -int flexran_get_res_alloc_type1(mid_t ue_id) { +int flexran_get_res_alloc_type1(mid_t ue_id) +{ +#warning "Implement flexran_get_res_alloc_type1() in RAN API" //TODO:Get proper value //uint8_t temp = 0; //temp = (((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->featureGroupIndicators->buf); @@ -819,313 +702,291 @@ int flexran_get_res_alloc_type1(mid_t ue_id) { return 0; } -int flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); +long flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id) +{ + if (!rrc[mod_id]) return -1; - if (eNB_rrc_inst_not_ready()) return -1; - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ - return ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode; - } else { - return -1; - } - } else { - return -1; - } + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated->antennaInfo) return -1; + return ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode; } -int flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); +BOOLEAN_t flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id) +{ + if (!rrc[mod_id]) return -1; - if (eNB_rrc_inst_not_ready()) return -1; - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.mac_MainConfig != NULL){ - return ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config->ttiBundling; - } else { - return -1; - } - } - else { - return -1; - } + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.mac_MainConfig) return -1; + if (!ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config) return -1; + return ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config->ttiBundling; } -int flexran_get_maxHARQ_TX(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); +long flexran_get_maxHARQ_TX(mid_t mod_id, mid_t ue_id) +{ + if (!rrc[mod_id]) return -1; - if (eNB_rrc_inst_not_ready()) return -1; - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.mac_MainConfig != NULL){ - return *ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config->maxHARQ_Tx; - } - } - return -1; + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.mac_MainConfig) return -1; + if (!ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config) return -1; + return *(ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config->maxHARQ_Tx); } -int flexran_get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); +long flexran_get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id) +{ + if (!rrc[mod_id]) return -1; - if (eNB_rrc_inst_not_ready()) return -1; - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ - return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_ACK_Index; - } else { - return -1; - } - } else { - return -1; - } + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated) return -1; + return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_ACK_Index; } -int flexran_get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); +long flexran_get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id) +{ + if (!rrc[mod_id]) return -1; - if (eNB_rrc_inst_not_ready()) return -1; - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ - return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index; - } else { - return -1; - } - } else { - return -1; - } + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated) return -1; + return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index; } -int flexran_get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); +long flexran_get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id) +{ + if (!rrc[mod_id]) return -1; - if (eNB_rrc_inst_not_ready()) return -1; - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ - return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index; - } else { - return -1; - } - } - else { - return -1; - } + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated) return -1; + return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index; } -int flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); +BOOLEAN_t flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id) +{ + if (!rrc[mod_id]) return -1; - if (eNB_rrc_inst_not_ready()) return -1; - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ - if (ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic != NULL) { - return ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.simultaneousAckNackAndCQI; - } - } - } - return -1; + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) return -1; + return ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.simultaneousAckNackAndCQI; } -int flexran_get_ack_nack_simultaneous_trans(mid_t mod_id,mid_t ue_id) { - - if (eNB_rrc_inst_not_ready()) return -1; - - return (&eNB_rrc_inst[mod_id])->carrier[0].sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; +BOOLEAN_t flexran_get_ack_nack_simultaneous_trans(mid_t mod_id, mid_t ue_id, uint8_t cc_id) +{ + if (!rrc[mod_id]) return -1; + if (!rrc[mod_id]->carrier[cc_id].sib2) return -1; + return rrc[mod_id]->carrier[cc_id].sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; } -int flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); +CQI_ReportModeAperiodic_t flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id) +{ + if (!rrc[mod_id]) return -1; - if (eNB_rrc_inst_not_ready()) return -1; + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ - return *ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic; - } - } - return -1; + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig) return -1; + return *ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic; } -int flexran_get_tdd_ack_nack_feedback(mid_t mod_id, mid_t ue_id) { - // TODO: This needs fixing - return -1; +long flexran_get_tdd_ack_nack_feedback_mode(mid_t mod_id, mid_t ue_id) +{ + if (!rrc[mod_id]) return -1; - /* if (eNB_rrc_inst_not_ready()) return -1; */ + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); - /* struct rrc_eNB_ue_context_s* ue_context_p = NULL; */ - /* uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); */ - - /* ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); */ - - /* if(ue_context_p != NULL) { */ - /* if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ */ - /* return ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode; */ - /* } else { */ - /* return -1; */ - /* } */ - /* } else { */ - /* return -1; */ - /* } */ + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode) return -1; + return *(ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode); } -int flexran_get_ack_nack_repetition_factor(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); +long flexran_get_ack_nack_repetition_factor(mid_t mod_id, mid_t ue_id) +{ + if (!rrc[mod_id]) return -1; - if (eNB_rrc_inst_not_ready()) return -1; - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ - return ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->ackNackRepetition.choice.setup.repetitionFactor; - } else { - return -1; - } - } else { - return -1; - } + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated) return -1; + return ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->ackNackRepetition.choice.setup.repetitionFactor; } -int flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id) { - //TODO: need to double check - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); +long flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id) +{ + if (!rrc[mod_id]) return -1; - if (eNB_rrc_inst_not_ready()) return -1; + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.mac_MainConfig != NULL){ - if(ue_context_p->ue_context.mac_MainConfig->ext2 != NULL){ - long val = (*(ue_context_p->ue_context.mac_MainConfig->ext2->mac_MainConfig_v1020->extendedBSR_Sizes_r10)); - if (val > 0) { - return 1; - } - } - } - } - return -1; + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.mac_MainConfig) return -1; + if (!ue_context_p->ue_context.mac_MainConfig->ext2) return -1; + if (!ue_context_p->ue_context.mac_MainConfig->ext2->mac_MainConfig_v1020) return -1; + return *(ue_context_p->ue_context.mac_MainConfig->ext2->mac_MainConfig_v1020->extendedBSR_Sizes_r10); } -int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); +int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id) +{ + if (!rrc[mod_id]) return -1; - if (eNB_rrc_inst_not_ready()) return -1; + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.physicalConfigDedicated != NULL){ - if(ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.choice.setup == AntennaInfoDedicated__ue_TransmitAntennaSelection__setup_closedLoop) { - return 2; - } else if(ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.choice.setup == AntennaInfoDedicated__ue_TransmitAntennaSelection__setup_openLoop) { - return 1; - } else { - return 0; - } - } else { - return -1; - } - } else { - return -1; - } -} - -int flexran_get_lcg(mid_t ue_id, mid_t lc_id) { - if (UE_mac_inst == NULL) { - return -1; - } - if(UE_mac_inst[ue_id].logicalChannelConfig[lc_id] != NULL) { - return *UE_mac_inst[ue_id].logicalChannelConfig[lc_id]->ul_SpecificParameters->logicalChannelGroup; - } else { - return -1; - } -} - -int flexran_get_direction(mid_t ue_id, mid_t lc_id) { - /*TODO: fill with the value for the rest of LCID*/ - if(lc_id == DCCH || lc_id == DCCH1) { + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; + if (!ue_context_p->ue_context.physicalConfigDedicated->antennaInfo) return -1; + switch (ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.choice.setup) { + case AntennaInfoDedicated__ue_TransmitAntennaSelection__setup_closedLoop: return 2; - } else if(lc_id == DTCH) { + case AntennaInfoDedicated__ue_TransmitAntennaSelection__setup_openLoop: return 1; - } else { + default: + return 0; + } +} + +long flexran_get_lcg(mid_t ue_id, mid_t lc_id) +{ + if (!UE_mac_inst) return -1; + if (!UE_mac_inst[ue_id].logicalChannelConfig[lc_id]) return -1; + if (!UE_mac_inst[ue_id].logicalChannelConfig[lc_id]->ul_SpecificParameters) return -1; + if (!UE_mac_inst[ue_id].logicalChannelConfig[lc_id]->ul_SpecificParameters->logicalChannelGroup) return -1; + return *(UE_mac_inst[ue_id].logicalChannelConfig[lc_id]->ul_SpecificParameters->logicalChannelGroup); +} + +int flexran_get_direction(mid_t ue_id, mid_t lc_id) +{ + /* TODO: fill with the value for the rest of LCID -> Robert: What does that + * mean? */ + switch (lc_id) { + case DCCH: + case DCCH1: + return 2; + case DTCH: + return 1; + default: return -1; } } -int flexran_get_antenna_ports(mid_t mod_id, int CC_id){ - - LTE_DL_FRAME_PARMS *frame_parms; - - if (mac_xface_not_ready()) return 0; - - frame_parms = mac_xface->get_lte_frame_parms(mod_id, CC_id); - return (frame_parms == NULL)? 0:frame_parms->nb_antenna_ports_eNB; - +uint8_t flexran_get_antenna_ports(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.nb_antenna_ports_eNB; } - -uint32_t flexran_agent_get_operating_dl_freq (mid_t mod_id, int cc_id) { - - return (enb_properties->properties[mod_id]->downlink_frequency[cc_id] / 1000000); +/* TODO better give real value (without division)? */ +uint32_t flexran_agent_get_operating_dl_freq(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.dl_CarrierFreq / 1000000; } -uint32_t flexran_agent_get_operating_ul_freq (mid_t mod_id, int cc_id) { - return ((enb_properties->properties[mod_id]->downlink_frequency[cc_id] + enb_properties->properties[0]->uplink_frequency_offset[cc_id]) / 1000000); +/* TODO better give real value (without division)? */ +uint32_t flexran_agent_get_operating_ul_freq(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.ul_CarrierFreq / 1000000; } -int flexran_agent_get_operating_eutra_band (mid_t mod_id, int cc_id) { - return enb_properties->properties[mod_id]->eutra_band[cc_id]; -} -int flexran_agent_get_operating_pdsch_refpower (mid_t mod_id, int cc_id) { - return enb_properties->properties[mod_id]->pdsch_referenceSignalPower[cc_id]; -} -int flexran_agent_get_operating_pusch_p0 (mid_t mod_id, int cc_id) { - return enb_properties->properties[mod_id]->pusch_p0_Nominal[cc_id]; +uint8_t flexran_agent_get_operating_eutra_band(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.eutra_band; } -void flexran_agent_set_operating_dl_freq (mid_t mod_id, int cc_id, uint32_t dl_freq_mhz) { - - enb_properties->properties[mod_id]->downlink_frequency[cc_id]=dl_freq_mhz * 1000000; - /*printf("[ENB_APP] mod id %d ccid %d dl freq %d/%d\n", mod_id, cc_id, dl_freq_mhz, enb_properties->properties[mod_id]->downlink_frequency[cc_id]); */ +int8_t flexran_agent_get_operating_pdsch_refpower(mid_t mod_id, uint8_t cc_id) +{ + if (!phy[mod_id][cc_id]) return 0; + return phy[mod_id][cc_id]->frame_parms.pdsch_config_common.referenceSignalPower; } -void flexran_agent_set_operating_ul_freq (mid_t mod_id, int cc_id, int32_t ul_freq_offset_mhz) { - enb_properties->properties[mod_id]->uplink_frequency_offset[cc_id]=ul_freq_offset_mhz * 1000000; -} -//TBD -void flexran_agent_set_operating_eutra_band (mid_t mod_id, int cc_id) { - enb_properties->properties[mod_id]->eutra_band[cc_id]=7; +long flexran_agent_get_operating_pusch_p0(mid_t mod_id, uint8_t cc_id) +{ + if (!rrc[mod_id]) return 0; + return rrc[mod_id]->configuration.pusch_p0_Nominal[cc_id]; } -void flexran_agent_set_operating_bandwidth (mid_t mod_id, int cc_id, int bandwidth) { - enb_properties->properties[mod_id]->N_RB_DL[cc_id]=bandwidth; +void flexran_agent_set_operating_dl_freq(mid_t mod_id, uint8_t cc_id, uint32_t dl_freq_mhz) +{ + if (phy[mod_id][cc_id]) { + phy[mod_id][cc_id]->frame_parms.dl_CarrierFreq = dl_freq_mhz * 1000000; + } + if (rrc[mod_id]) { + rrc[mod_id]->configuration.downlink_frequency[cc_id] = dl_freq_mhz * 1000000; + } } -void flexran_agent_set_operating_frame_type (mid_t mod_id, int cc_id, int frame_type) { - enb_properties->properties[mod_id]->frame_type[cc_id]=frame_type; +void flexran_agent_set_operating_ul_freq(mid_t mod_id, uint8_t cc_id, int32_t ul_freq_mhz_offset) +{ + if (phy[mod_id][cc_id]) { + uint32_t new_ul_freq_mhz = flexran_agent_get_operating_dl_freq(mod_id, cc_id) + ul_freq_mhz_offset; + phy[mod_id][cc_id]->frame_parms.ul_CarrierFreq = new_ul_freq_mhz * 1000000; + } + if (rrc[mod_id]) { + rrc[mod_id]->configuration.uplink_frequency_offset[cc_id] = ul_freq_mhz_offset; + } +} + +void flexran_agent_set_operating_eutra_band(mid_t mod_id, uint8_t cc_id, uint8_t eutra_band) +{ + if (phy[mod_id][cc_id]) { + phy[mod_id][cc_id]->frame_parms.eutra_band = eutra_band; + } + if (rrc[mod_id]) { + rrc[mod_id]->configuration.eutra_band[cc_id] = eutra_band; + } +} + +/* Sets both DL/UL */ +void flexran_agent_set_operating_bandwidth(mid_t mod_id, uint8_t cc_id, uint8_t N_RB) +{ + if (phy[mod_id][cc_id]) { + phy[mod_id][cc_id]->frame_parms.N_RB_DL = N_RB; + phy[mod_id][cc_id]->frame_parms.N_RB_UL = N_RB; + } + if (rrc[mod_id]) { + rrc[mod_id]->configuration.N_RB_DL[cc_id] = N_RB; + } +} + +void flexran_agent_set_operating_frame_type(mid_t mod_id, uint8_t cc_id, lte_frame_type_t frame_type) +{ + if (phy[mod_id][cc_id]) { + phy[mod_id][cc_id]->frame_parms.frame_type = frame_type; + } + if (rrc[mod_id]) { + rrc[mod_id]->configuration.frame_type[cc_id] = frame_type; + } } /*********** PDCP *************/ @@ -1234,192 +1095,99 @@ uint32_t flexran_get_pdcp_rx_oo(const mid_t mod_id, const mid_t ue_id, const lc /******************** RRC *****************************/ -int flexran_get_rrc_pcell_measid(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); +MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, mid_t ue_id) +{ + if (!rrc[mod_id]) return -1; - if (eNB_rrc_inst_not_ready()) return -1; - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.measResults != NULL) { - return ue_context_p->ue_context.measResults->measId; - } else { - return -1; - } - } else { - return -1; - } + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.measResults) return -1; + return ue_context_p->ue_context.measResults->measId; } -int flexran_get_rrc_pcell_rsrp(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - if (eNB_rrc_inst_not_ready()) return -1; +float flexran_get_rrc_pcell_rsrp(mid_t mod_id, mid_t ue_id) +{ + if (!rrc[mod_id]) return -1; - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.measResults != NULL) { - return RSRP_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrpResult]; - } else { - return -1; - } - } else { - return -1; - } + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.measResults) return -1; + return RSRP_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrpResult]; } -int flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); - if (eNB_rrc_inst_not_ready()) return -1; +float flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id) +{ + if (!rrc[mod_id]) return -1; - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.measResults != NULL) { - return RSRQ_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrqResult]; - } else { - return -1; - } - } else { - return -1; - } + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.measResults) return -1; + return RSRQ_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrqResult]; } /*Number of neighbouring cells for specific UE*/ -int flexran_get_rrc_num_ncell(mid_t mod_id, mid_t ue_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); +int flexran_get_rrc_num_ncell(mid_t mod_id, mid_t ue_id) +{ + if (!rrc[mod_id]) return 0; - if (eNB_rrc_inst_not_ready()) return 0; - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); - if (ue_context_p->ue_context.measResults != NULL){ - - if(ue_context_p->ue_context.measResults->measResultNeighCells != NULL) { - - if (ue_context_p->ue_context.measResults->measResultNeighCells->present == MeasResults__measResultNeighCells_PR_measResultListEUTRA) { - - return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count; - } - else{ - - return 0; - } - - } else { - - return 0; - } - - } else { - - return 0; - - } - - } else { - return 0; - } - + if (!ue_context_p) return 0; + if (!ue_context_p->ue_context.measResults) return 0; + if (!ue_context_p->ue_context.measResults->measResultNeighCells) return 0; + if (ue_context_p->ue_context.measResults->measResultNeighCells->present != MeasResults__measResultNeighCells_PR_measResultListEUTRA) return 0; + return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count; } -int flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, int cell_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); +PhysCellId_t flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, int cell_id) +{ + if (!rrc[mod_id]) return -1; - if (eNB_rrc_inst_not_ready()) return -1; - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.measResults->measResultNeighCells != NULL) { + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); - if (ue_context_p->ue_context.measResults->measResultNeighCells->present == MeasResults__measResultNeighCells_PR_measResultListEUTRA) { - - return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->physCellId; - - } - else { - - return -1; - } - } else { - return -1; - } - } else { - return -1; - } + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.measResults) return -1; + if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1; + if (ue_context_p->ue_context.measResults->measResultNeighCells->present != MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1; + if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]) return -1; + return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->physCellId; } -int flexran_get_rrc_neigh_rsrp(mid_t mod_id, mid_t ue_id, int cell_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); +float flexran_get_rrc_neigh_rsrp(mid_t mod_id, mid_t ue_id, int cell_id) +{ + if (!rrc[mod_id]) return -1; - if (eNB_rrc_inst_not_ready()) return -1; - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); - if(ue_context_p->ue_context.measResults->measResultNeighCells != NULL) { - - if (ue_context_p->ue_context.measResults->measResultNeighCells->present == MeasResults__measResultNeighCells_PR_measResultListEUTRA) { - - if (ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult){ - return RSRP_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult)]; - - } - else { - - return 0; - } - - } - else { - - return -1; - } - - } - else { - return -1; - } - - } - else { - return -1; - } + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.measResults) return -1; + if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1; + if (ue_context_p->ue_context.measResults->measResultNeighCells->present != MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1; + if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]) return -1; + if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult) return 0; + return RSRP_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult)]; } -int flexran_get_rrc_neigh_rsrq(mid_t mod_id, mid_t ue_id, int cell_id) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - uint32_t rntiP = flexran_get_ue_crnti(mod_id,ue_id); +float flexran_get_rrc_neigh_rsrq(mid_t mod_id, mid_t ue_id, int cell_id) +{ + if (!rrc[mod_id]) return -1; - if (eNB_rrc_inst_not_ready()) return -1; - - ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id],rntiP); - if(ue_context_p != NULL) { - if(ue_context_p->ue_context.measResults->measResultNeighCells != NULL) { - if (ue_context_p->ue_context.measResults->measResultNeighCells->present == MeasResults__measResultNeighCells_PR_measResultListEUTRA) { + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); - if (ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult){ - return RSRQ_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult)]; - - } - else { - - return 0; - } - } - else { - - return -1; - } - } else { - return -1; - } - } else { - return -1; - } + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.measResults) return -1; + if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1; + if (ue_context_p->ue_context.measResults->measResultNeighCells->present != MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1; + if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult) return 0; + return RSRQ_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult)]; } diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 05c6817136..6dc6fba377 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -50,23 +50,23 @@ * get generic info from RAN ****************************/ -void flexran_set_enb_vars(mid_t mod_id, ran_name_t ran); +void flexran_set_RC_vars(mid_t mod_id, ran_name_t ran); -int flexran_get_current_time_ms (mid_t mod_id, int subframe_flag); +uint32_t flexran_get_current_time_ms(mid_t mod_id, int subframe_flag); /*Return the current frame number *Could be using implementation specific numbering of frames */ -unsigned int flexran_get_current_frame(mid_t mod_id); +frame_t flexran_get_current_frame(mid_t mod_id); /*Return the current SFN (0-1023)*/ -unsigned int flexran_get_current_system_frame_num(mid_t mod_id); +frame_t flexran_get_current_system_frame_num(mid_t mod_id); -unsigned int flexran_get_current_subframe(mid_t mod_id); +sub_frame_t flexran_get_current_subframe(mid_t mod_id); /*Return the frame and subframe number in compact 16-bit format. Bits 0-3 subframe, rest for frame. Required by FlexRAN protocol*/ -uint16_t flexran_get_sfn_sf (mid_t mod_id); +uint16_t flexran_get_sfn_sf(mid_t mod_id); /* Return a future frame and subframe number that is ahead_of_time subframes later in compact 16-bit format. Bits 0-3 subframe, @@ -77,144 +77,151 @@ uint16_t flexran_get_future_sfn_sf(mid_t mod_id, int ahead_of_time); int flexran_get_num_ues(mid_t mod_id); /* Get the rnti of a UE with id ue_id */ -int flexran_get_ue_crnti (mid_t mod_id, mid_t ue_id); +rnti_t flexran_get_ue_crnti(mid_t mod_id, mid_t ue_id); /* Get the RLC buffer status report of a ue for a designated logical channel id */ -int flexran_get_ue_bsr (mid_t mod_id, mid_t ue_id, lcid_t lcid); +uint8_t flexran_get_ue_bsr(mid_t mod_id, mid_t ue_id, lcid_t lcid); /* Get power headroom of UE with id ue_id */ -int flexran_get_ue_phr (mid_t mod_id, mid_t ue_id); +int8_t flexran_get_ue_phr(mid_t mod_id, mid_t ue_id); /* Get the UE wideband CQI */ -int flexran_get_ue_wcqi (mid_t mod_id, mid_t ue_id); +uint8_t flexran_get_ue_wcqi(mid_t mod_id, mid_t ue_id); /* Get the transmission queue size for a UE with a channel_id logical channel id */ -int flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id); +rlc_buffer_occupancy_t flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id); /*Get number of pdus in RLC buffer*/ -int flexran_get_num_pdus_buffer(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id); +rlc_buffer_occupancy_t flexran_get_num_pdus_buffer(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id); /* Get the head of line delay for a UE with a channel_id logical channel id */ -int flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id); +frame_t flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id); /* Check the status of the timing advance for a UE */ -short flexran_get_TA(mid_t mod_id, mid_t ue_id, int CC_id); +int32_t flexran_get_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id); -/* Update the timing advance status (find out whether a timing advance command is required) */ -void flexran_update_TA(mid_t mod_id, mid_t ue_id, int CC_id); +/* Update the timing advance status(find out whether a timing advance command is required) */ +/* currently broken +void flexran_update_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id); */ /* Return timing advance MAC control element for a designated cell and UE */ -int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id, int CC_id); +/* this function is broken */ +int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id); /* Get the number of active component carriers for a specific UE */ int flexran_get_active_CC(mid_t mod_id, mid_t ue_id); /* Get the rank indicator for a designated cell and UE */ -int flexran_get_current_RI(mid_t mod_id, mid_t ue_id, int CC_id); +uint8_t flexran_get_current_RI(mid_t mod_id, mid_t ue_id, uint8_t cc_id); /* See TS 36.213, section 10.1 */ -int flexran_get_n1pucch_an(mid_t mod_id, int CC_id); +uint16_t flexran_get_n1pucch_an(mid_t mod_id, uint8_t cc_id); /* See TS 36.211, section 5.4 */ -int flexran_get_nRB_CQI(mid_t mod_id, int CC_id); +uint8_t flexran_get_nRB_CQI(mid_t mod_id, uint8_t cc_id); /* See TS 36.211, section 5.4 */ -int flexran_get_deltaPUCCH_Shift(mid_t mod_id, int CC_id); +uint8_t flexran_get_deltaPUCCH_Shift(mid_t mod_id, uint8_t cc_id); /* See TS 36.211, section 5.7.1 */ -int flexran_get_prach_ConfigIndex(mid_t mod_id, int CC_id); +uint8_t flexran_get_prach_ConfigIndex(mid_t mod_id, uint8_t cc_id); /* See TS 36.211, section 5.7.1 */ -int flexran_get_prach_FreqOffset(mid_t mod_id, int CC_id); +uint8_t flexran_get_prach_FreqOffset(mid_t mod_id, uint8_t cc_id); /* See TS 36.321 */ -int flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, int CC_id); +uint8_t flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, uint8_t cc_id); /* Get the length of the UL cyclic prefix */ -int flexran_get_ul_cyclic_prefix_length(mid_t mod_id, int CC_id); +lte_prefix_type_t flexran_get_ul_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id); /* Get the length of the DL cyclic prefix */ -int flexran_get_dl_cyclic_prefix_length(mid_t mod_id, int CC_id); +lte_prefix_type_t flexran_get_dl_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id); /* Get the physical cell id of a cell */ -int flexran_get_cell_id(mid_t mod_id, int CC_id); +uint16_t flexran_get_cell_id(mid_t mod_id, uint8_t cc_id); /* See TS 36.211, section 5.5.3.2 */ -int flexran_get_srs_BandwidthConfig(mid_t mod_id, int CC_id); +uint8_t flexran_get_srs_BandwidthConfig(mid_t mod_id, uint8_t cc_id); /* See TS 36.211, table 5.5.3.3-1 and 2 */ -int flexran_get_srs_SubframeConfig(mid_t mod_id, int CC_id); +uint8_t flexran_get_srs_SubframeConfig(mid_t mod_id, uint8_t cc_id); /* Boolean value. See TS 36.211, section 5.5.3.2. TDD only */ -int flexran_get_srs_MaxUpPts(mid_t mod_id, int CC_id); +uint8_t flexran_get_srs_MaxUpPts(mid_t mod_id, uint8_t cc_id); /* Get number of DL resource blocks */ -int flexran_get_N_RB_DL(mid_t mod_id, int CC_id); +uint8_t flexran_get_N_RB_DL(mid_t mod_id, uint8_t cc_id); /* Get number of UL resource blocks */ -int flexran_get_N_RB_UL(mid_t mod_id, int CC_id); +uint8_t flexran_get_N_RB_UL(mid_t mod_id, uint8_t cc_id); /* Get number of resource block groups */ -int flexran_get_N_RBG(mid_t mod_id, int CC_id); +uint8_t flexran_get_N_RBG(mid_t mod_id, uint8_t cc_id); /* Get DL/UL subframe assignment. TDD only */ -int flexran_get_subframe_assignment(mid_t mod_id, int CC_id); +uint8_t flexran_get_subframe_assignment(mid_t mod_id, uint8_t cc_id); /* TDD only. See TS 36.211, table 4.2.1 */ -int flexran_get_special_subframe_assignment(mid_t mod_id, int CC_id); +uint8_t flexran_get_special_subframe_assignment(mid_t mod_id, uint8_t cc_id); /* Get the duration of the random access response window in subframes */ -int flexran_get_ra_ResponseWindowSize(mid_t mod_id, int CC_id); +long flexran_get_ra_ResponseWindowSize(mid_t mod_id, uint8_t cc_id); /* Get timer used for random access */ -int flexran_get_mac_ContentionResolutionTimer(mid_t mod_id, int CC_id); +long flexran_get_mac_ContentionResolutionTimer(mid_t mod_id, uint8_t cc_id); -/* Get type of duplex mode (FDD/TDD) */ -int flexran_get_duplex_mode(mid_t mod_id, int CC_id); +/* Get type of duplex mode(FDD/TDD) */ +Protocol__FlexDuplexMode flexran_get_duplex_mode(mid_t mod_id, uint8_t cc_id); /* Get the SI window length */ -long flexran_get_si_window_length(mid_t mod_id, int CC_id); +long flexran_get_si_window_length(mid_t mod_id, uint8_t cc_id); + +/* Get length of SystemInformationBlock1 */ +uint8_t flexran_get_sib1_length(mid_t mod_id, uint8_t cc_id); /* Get the number of PDCCH symbols configured for the cell */ -int flexran_get_num_pdcch_symb(mid_t mod_id, int CC_id); +uint8_t flexran_get_num_pdcch_symb(mid_t mod_id, uint8_t cc_id); -int flexran_get_antenna_ports(mid_t mod_id, int CC_id); +uint8_t flexran_get_antenna_ports(mid_t mod_id, uint8_t cc_id); /* See TS 36.213, sec 5.1.1.1 */ -int flexran_get_tpc(mid_t mod_id, mid_t ue_id); +int flexran_get_tpc(mid_t mod_id, mid_t ue_id, uint8_t cc_id); -int flexran_get_ue_pmi(mid_t mod_id); +uint8_t flexran_get_ue_wpmi(mid_t mod_id, mid_t ue_id, uint8_t cc_id); /* Get the first available HARQ process for a specific cell and UE during a designated frame and subframe. Returns 0 for success. The id and the status of the HARQ process are stored in id and status respectively */ -int flexran_get_harq(const mid_t mod_id, const uint8_t CC_id, const mid_t ue_id, - const int frame, const uint8_t subframe, unsigned char *id, unsigned char *round,const uint8_t harq_flag); +/* currently broken +int flexran_get_harq(mid_t mod_id, uint8_t cc_id, mid_t ue_id, frame_t frame, + sub_frame_t subframe, unsigned char *id, unsigned char *round, + uint8_t harq_flag); */ /* Uplink power control management*/ -int flexran_get_p0_pucch_dbm(mid_t mod_id, mid_t ue_id, int CC_id); +int32_t flexran_get_p0_pucch_dbm(mid_t mod_id, mid_t ue_id, uint8_t cc_id); -int flexran_get_p0_nominal_pucch(mid_t mod_id, int CC_id); +int8_t flexran_get_p0_nominal_pucch(mid_t mod_id, uint8_t cc_id); -int flexran_get_p0_pucch_status(mid_t mod_id, mid_t ue_id, int CC_id); +int32_t flexran_get_p0_pucch_status(mid_t mod_id, mid_t ue_id, uint8_t cc_id); -int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, int CC_id); +int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, uint8_t cc_id); -int flexran_get_threequarter_fs(mid_t mod_id, int CC_id); +uint8_t flexran_get_threequarter_fs(mid_t mod_id, uint8_t cc_id); -int flexran_get_hopping_mode(mid_t mod_id, int CC_id); +PUSCH_HOPPING_t flexran_get_hopping_mode(mid_t mod_id, uint8_t cc_id); -int flexran_get_hopping_offset(mid_t mod_id, int CC_id); +uint8_t flexran_get_hopping_offset(mid_t mod_id, uint8_t cc_id); -int flexran_get_n_SB(mid_t mod_id, int CC_id); +uint8_t flexran_get_n_SB(mid_t mod_id, uint8_t cc_id); -int flexran_get_phich_resource(mid_t mod_id, int CC_id); +int flexran_get_phich_resource(mid_t mod_id, uint8_t cc_id); -int flexran_get_enable64QAM(mid_t mod_id, int CC_id); +uint8_t flexran_get_enable64QAM(mid_t mod_id, uint8_t cc_id); -int flexran_get_phich_duration(mid_t mod_id, int CC_id); +PHICH_DURATION_t flexran_get_phich_duration(mid_t mod_id, uint8_t cc_id); /* * ************************************ @@ -225,119 +232,124 @@ int flexran_get_phich_duration(mid_t mod_id, int CC_id); /* Get timer in subframes. Controls the synchronization status of the UE, not the actual timing advance procedure. See TS 36.321 */ -int flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id); +TimeAlignmentTimer_t flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id); /* Get measurement gap configuration. See TS 36.133 */ -int flexran_get_meas_gap_config(mid_t mod_id, mid_t ue_id); +Protocol__FlexMeasGapConfigPattern flexran_get_meas_gap_config(mid_t mod_id, mid_t ue_id); /* Get measurement gap configuration offset if applicable */ -int flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id); +long flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id); /* DL aggregated bit-rate of non-gbr bearer per UE. See TS 36.413 */ -int flexran_get_ue_aggregated_max_bitrate_dl (mid_t mod_id, mid_t ue_id); +uint64_t flexran_get_ue_aggregated_max_bitrate_dl(mid_t mod_id, mid_t ue_id); /* UL aggregated bit-rate of non-gbr bearer per UE. See TS 36.413 */ -int flexran_get_ue_aggregated_max_bitrate_ul (mid_t mod_id, mid_t ue_id); +uint64_t flexran_get_ue_aggregated_max_bitrate_ul(mid_t mod_id, mid_t ue_id); /* Only half-duplex support. FDD operation. Boolean value */ -int flexran_get_half_duplex(mid_t ue_id); +/* currently broken +int flexran_get_half_duplex(mid_t ue_id); */ /* Support of intra-subframe hopping. Boolean value */ -int flexran_get_intra_sf_hopping(mid_t ue_id); +/* currently broken +int flexran_get_intra_sf_hopping(mid_t ue_id); */ /* UE support for type 2 hopping with n_sb>1 */ -int flexran_get_type2_sb_1(mid_t ue_id); +/* currently broken +int flexran_get_type2_sb_1(mid_t ue_id); */ /* Get the UE category */ -int flexran_get_ue_category(mid_t ue_id); +/* currently broken +int flexran_get_ue_category(mid_t ue_id); */ /* UE support for resource allocation type 1 */ -int flexran_get_res_alloc_type1(mid_t ue_id); +/* currently broken +int flexran_get_res_alloc_type1(mid_t ue_id); */ /* Get UE transmission mode */ -int flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id); +long flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id); /* Boolean value. See TS 36.321 */ -int flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id); +BOOLEAN_t flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id); /* The max HARQ retransmission for UL. See TS 36.321 */ -int flexran_get_maxHARQ_TX(mid_t mod_id, mid_t ue_id); +long flexran_get_maxHARQ_TX(mid_t mod_id, mid_t ue_id); /* See TS 36.213 */ -int flexran_get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id); +long flexran_get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id); /* See TS 36.213 */ -int flexran_get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id); +long flexran_get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id); /* See TS 36.213 */ -int flexran_get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id); +long flexran_get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id); /* Boolean. See TS36.213, Section 10.1 */ -int flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id); +BOOLEAN_t flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id); /* Boolean. See TS 36.213, Section 8.2 */ -int flexran_get_ack_nack_simultaneous_trans(mid_t mod_id,mid_t ue_id); +BOOLEAN_t flexran_get_ack_nack_simultaneous_trans(mid_t mod_id, mid_t ue_id, uint8_t cc_id); /* Get aperiodic CQI report mode */ -int flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id); +CQI_ReportModeAperiodic_t flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id); /* Get ACK/NACK feedback mode. TDD only */ -int flexran_get_tdd_ack_nack_feedback(mid_t mod_id, mid_t ue_id); +long flexran_get_tdd_ack_nack_feedback_mode(mid_t mod_id, mid_t ue_id); /* See TS36.213, section 10.1 */ -int flexran_get_ack_nack_repetition_factor(mid_t mod_id, mid_t ue_id); +long flexran_get_ack_nack_repetition_factor(mid_t mod_id, mid_t ue_id); /* Boolean. Extended buffer status report size */ -int flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id); +long flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id); /* Get number of UE transmission antennas */ int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id); /* Get logical channel group of a channel with id lc_id */ -int flexran_get_lcg(mid_t ue_id, mid_t lc_id); +long flexran_get_lcg(mid_t ue_id, mid_t lc_id); /* Get direction of logical channel with id lc_id */ int flexran_get_direction(mid_t ue_id, mid_t lc_id); /*Get downlink frequency*/ -uint32_t flexran_agent_get_operating_dl_freq (mid_t mod_id, int cc_id); +uint32_t flexran_agent_get_operating_dl_freq(mid_t mod_id, uint8_t cc_id); /*Get uplink frequency*/ -uint32_t flexran_agent_get_operating_ul_freq (mid_t mod_id, int cc_id); +uint32_t flexran_agent_get_operating_ul_freq(mid_t mod_id, uint8_t cc_id); /*Get eutra band*/ -int flexran_agent_get_operating_eutra_band (mid_t mod_id, int cc_id); +uint8_t flexran_agent_get_operating_eutra_band(mid_t mod_id, uint8_t cc_id); /*Get downlink ref signal power*/ -int flexran_agent_get_operating_pdsch_refpower (mid_t mod_id, int cc_id); +int8_t flexran_agent_get_operating_pdsch_refpower(mid_t mod_id, uint8_t cc_id); /*Get uplink power*/ -int flexran_agent_get_operating_pusch_p0 (mid_t mod_id, int cc_id); +long flexran_agent_get_operating_pusch_p0(mid_t mod_id, uint8_t cc_id); /*set the dl freq */ -void flexran_agent_set_operating_dl_freq (mid_t mod_id, int cc_id, uint32_t dl_freq_mhz); +void flexran_agent_set_operating_dl_freq(mid_t mod_id, uint8_t cc_id, uint32_t dl_freq_mhz); /* set the ul freq */ -void flexran_agent_set_operating_ul_freq (mid_t mod_id, int cc_id, int32_t ul_freq_offset_mhz); +void flexran_agent_set_operating_ul_freq(mid_t mod_id, uint8_t cc_id, int32_t ul_freq_mhz_offset); /*set the the band */ -void flexran_agent_set_operating_eutra_band (mid_t mod_id, int cc_id); +void flexran_agent_set_operating_eutra_band(mid_t mod_id, uint8_t cc_id, uint8_t eutra_band); -/* set the bandwidth */ -void flexran_agent_set_operating_bandwidth (mid_t mod_id, int cc_id, int bandwidth); +/* set the bandwidth (in RB) */ +void flexran_agent_set_operating_bandwidth(mid_t mod_id, uint8_t cc_id, uint8_t N_RB); /*set frame type*/ -void flexran_agent_set_operating_frame_type (mid_t mod_id, int cc_id, int frame_type); +void flexran_agent_set_operating_frame_type(mid_t mod_id, uint8_t cc_id, lte_frame_type_t frame_type); /*RRC status flexRAN*/ -int flexran_get_rrc_status(const mid_t mod_id, const rnti_t rntiP); +uint8_t flexran_get_rrc_status(const mid_t mod_id, const rnti_t rntiP); /***************************** PDCP ***********************/ @@ -399,28 +411,30 @@ uint32_t flexran_get_pdcp_rx_oo(const mid_t mod_id, const mid_t ue_id, const lc /*********************RRC**********************/ /*Get primary cell measuremeant id flexRAN*/ -int flexran_get_rrc_pcell_measid(mid_t mod_id, mid_t ue_id); +MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, mid_t ue_id); /*Get primary cell RSRP measurement flexRAN*/ -int flexran_get_rrc_pcell_rsrp(mid_t mod_id, mid_t ue_id); +float flexran_get_rrc_pcell_rsrp(mid_t mod_id, mid_t ue_id); /*Get primary cell RSRQ measurement flexRAN*/ -int flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id); +float flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id); /* Get RRC neighbouring measurement */ int flexran_get_rrc_num_ncell(mid_t mod_id, mid_t ue_id); /*Get physical cell id*/ -int flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, int cell_id); +PhysCellId_t flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, int cell_id); /*Get RSRP of neighbouring Cell*/ -int flexran_get_rrc_neigh_rsrp(mid_t mod_id, mid_t ue_id, int cell_id); +float flexran_get_rrc_neigh_rsrp(mid_t mod_id, mid_t ue_id, int cell_id); /*Get RSRQ of neighbouring Cell*/ -int flexran_get_rrc_neigh_rsrq(mid_t mod_id, mid_t ue_id, int cell_id); +float flexran_get_rrc_neigh_rsrq(mid_t mod_id, mid_t ue_id, int cell_id); /*Get MCC PLMN identity neighbouring Cell*/ -int flexran_get_rrc_neigh_plmn_mcc(mid_t mod_id, mid_t ue_id, int cell_id); +/* currently not implemented +int flexran_get_rrc_neigh_plmn_mcc(mid_t mod_id, mid_t ue_id, int cell_id); */ /*Get MNC PLMN identity neighbouring Cell*/ -int flexran_get_rrc_neigh_plmn_mnc(mid_t mod_id, mid_t ue_id, int cell_id); \ No newline at end of file +/* currently not implemented +int flexran_get_rrc_neigh_plmn_mnc(mid_t mod_id, mid_t ue_id, int cell_id); */ From b45a340b63f0f9695d3a1d4e218a79617bf03c50 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 23 Jan 2018 15:47:40 +0100 Subject: [PATCH 072/195] RAN API: no set_RC_vars(), check use RC directly, give error messages --- openair2/ENB_APP/enb_app.c | 6 - openair2/ENB_APP/flexran_agent_ran_api.c | 419 ++++++++++++----------- openair2/ENB_APP/flexran_agent_ran_api.h | 2 - 3 files changed, 213 insertions(+), 214 deletions(-) diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index 636df458ae..3b3c8c24c7 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -342,12 +342,6 @@ void *eNB_app_task(void *args_p) enb_app_start_phy_rrc(enb_id_start, enb_id_end); -#ifdef FLEXRAN_AGENT_SB_IF - for (uint32_t enb_i = 0; enb_i <1; enb_i ++){ // To be handled for all of current eNB - flexran_set_RC_vars(enb_i, RAN_LTE_OAI); - } -#endif - # if defined(ENABLE_USE_MME) /* Try to register each eNB */ registered_enb = 0; diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index af1d1be63d..75552526a7 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -28,48 +28,35 @@ #include "flexran_agent_ran_api.h" -/* - * generic info from RAN - */ - -PHY_VARS_eNB *phy[NUM_MAX_ENB][MAX_NUM_CCs] = { NULL }; -eNB_MAC_INST *mac[NUM_MAX_ENB] = { NULL }; -eNB_RRC_INST *rrc[NUM_MAX_ENB] = { NULL }; -UE_list_t *UE_list[NUM_MAX_ENB] = { NULL }; - -void flexran_set_RC_vars(mid_t mod_id, ran_name_t ran) +static inline int phy_is_present(mid_t mod_id, uint8_t cc_id) { - int i; - if (ran == RAN_LTE_OAI) { - if (RC.eNB && mod_id < RC.nb_RU && RC.eNB[mod_id] && RC.nb_CC) - for (i = 0; i < *RC.nb_CC; i++) - phy[mod_id][i] = RC.eNB[mod_id][i]; - if (RC.mac && mod_id < RC.nb_macrlc_inst && RC.mac[mod_id]) { - mac[mod_id] = RC.mac[mod_id]; - UE_list[mod_id] = &RC.mac[mod_id]->UE_list; - } - if (RC.rrc && mod_id < RC.nb_macrlc_inst && RC.rrc[mod_id]) - rrc[mod_id] = RC.rrc[mod_id]; - } - else { - LOG_E(FLEXRAN_AGENT, "unknown RAN name %d when setting RAN API variables\n", ran); - } + return RC.eNB && RC.eNB[mod_id] && RC.eNB[mod_id][cc_id]; +} + +static inline int mac_is_present(mid_t mod_id) +{ + return RC.mac && RC.mac[mod_id]; +} + +static inline int rrc_is_present(mid_t mod_id) +{ + return RC.rrc && RC.rrc[mod_id]; } uint32_t flexran_get_current_time_ms(mid_t mod_id, int subframe_flag) { - if (!mac[mod_id]) return 0; + if (!mac_is_present(mod_id)) return 0; if (subframe_flag == 1) - return mac[mod_id]->frame*10 + mac[mod_id]->subframe; + return RC.mac[mod_id]->frame*10 + RC.mac[mod_id]->subframe; else - return mac[mod_id]->frame*10; + return RC.mac[mod_id]->frame*10; } frame_t flexran_get_current_frame(mid_t mod_id) { - if (!mac[mod_id]) return 0; + if (!mac_is_present(mod_id)) return 0; // #warning "SFN will not be in [0-1023] when oaisim is used" - return mac[mod_id]->frame; + return RC.mac[mod_id]->frame; } frame_t flexran_get_current_system_frame_num(mid_t mod_id) @@ -79,8 +66,8 @@ frame_t flexran_get_current_system_frame_num(mid_t mod_id) sub_frame_t flexran_get_current_subframe(mid_t mod_id) { - if (!mac[mod_id]) return 0; - return mac[mod_id]->subframe; + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->subframe; } /* Why uint16_t, frame_t and sub_frame_t are defined as uint32_t? */ @@ -121,8 +108,8 @@ uint16_t flexran_get_future_sfn_sf(mid_t mod_id, int ahead_of_time) int flexran_get_num_ues(mid_t mod_id) { - if (!UE_list[mod_id]) return 0; - return UE_list[mod_id]->num_UEs; + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.num_UEs; } rnti_t flexran_get_ue_crnti(mid_t mod_id, mid_t ue_id) @@ -132,20 +119,20 @@ rnti_t flexran_get_ue_crnti(mid_t mod_id, mid_t ue_id) uint8_t flexran_get_ue_bsr(mid_t mod_id, mid_t ue_id, lcid_t lcid) { - if (!UE_list[mod_id]) return 0; - return UE_list[mod_id]->UE_template[UE_PCCID(mod_id, ue_id)][ue_id].bsr_info[lcid]; + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.UE_template[UE_PCCID(mod_id, ue_id)][ue_id].bsr_info[lcid]; } int8_t flexran_get_ue_phr(mid_t mod_id, mid_t ue_id) { - if (!UE_list[mod_id]) return 0; - return UE_list[mod_id]->UE_template[UE_PCCID(mod_id, ue_id)][ue_id].phr_info; + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.UE_template[UE_PCCID(mod_id, ue_id)][ue_id].phr_info; } uint8_t flexran_get_ue_wcqi(mid_t mod_id, mid_t ue_id) { - if (!phy[mod_id][0]) return 0; - return phy[mod_id][0]->UE_stats[ue_id].DL_cqi[0]; + if (!phy_is_present(mod_id, 0)) return 0; + return RC.eNB[mod_id][0]->UE_stats[ue_id].DL_cqi[0]; } rlc_buffer_occupancy_t flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) @@ -177,9 +164,9 @@ frame_t flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t chann int32_t flexran_get_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; + if (!phy_is_present(mod_id, cc_id)) return 0; - int32_t tau = phy[mod_id][cc_id]->UE_stats[ue_id].timing_advance_update; + int32_t tau = RC.eNB[mod_id][cc_id]->UE_stats[ue_id].timing_advance_update; switch (flexran_get_N_RB_DL(mod_id, cc_id)) { case 6: return tau; @@ -203,8 +190,8 @@ int32_t flexran_get_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id) uint8_t flexran_get_ue_wpmi(mid_t mod_id, mid_t ue_id, uint8_t cc_id) { - if (!UE_list[mod_id]) return 0; - return UE_list[mod_id]->UE_sched_ctrl[ue_id].periodic_wideband_pmi[cc_id]; + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].periodic_wideband_pmi[cc_id]; } /* TODO needs to be revised */ @@ -235,7 +222,7 @@ void flexran_update_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id) int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id) { #warning "Implement flexran_get_MAC_CE_bitmap_TA() in RAN API" - if (!phy[mod_id][cc_id]) return 0; + if (!phy_is_present(mod_id, cc_id)) return 0; /* UE_stats can not be null, they are an array in RC LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id,CC_id,rnti); @@ -254,25 +241,25 @@ int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id) int flexran_get_active_CC(mid_t mod_id, mid_t ue_id) { - if (!UE_list[mod_id]) return 0; - return UE_list[mod_id]->numactiveCCs[ue_id]; + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.numactiveCCs[ue_id]; } uint8_t flexran_get_current_RI(mid_t mod_id, mid_t ue_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->UE_stats[ue_id].rank; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->UE_stats[ue_id].rank; } int flexran_get_tpc(mid_t mod_id, mid_t ue_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; + if (!phy_is_present(mod_id, cc_id)) return 0; /* before: tested that UL_rssi != NULL and set parameter ([0]), but it is a * static array -> target_rx_power is useless in old ifs?! */ int pCCid = UE_PCCID(mod_id,ue_id); - int32_t target_rx_power = phy[mod_id][pCCid]->frame_parms.ul_power_control_config_common.p0_NominalPUSCH; - int32_t normalized_rx_power = phy[mod_id][cc_id]->UE_stats[ue_id].UL_rssi[0]; + int32_t target_rx_power = RC.eNB[mod_id][pCCid]->frame_parms.ul_power_control_config_common.p0_NominalPUSCH; + int32_t normalized_rx_power = RC.eNB[mod_id][cc_id]->UE_stats[ue_id].UL_rssi[0]; int tpc; if (normalized_rx_power > target_rx_power + 1) @@ -334,26 +321,26 @@ int flexran_get_harq(mid_t mod_id, int32_t flexran_get_p0_pucch_dbm(mid_t mod_id, mid_t ue_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_dBm; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_dBm; } int8_t flexran_get_p0_nominal_pucch(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.ul_power_control_config_common.p0_NominalPUCCH; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.ul_power_control_config_common.p0_NominalPUCCH; } int32_t flexran_get_p0_pucch_status(mid_t mod_id, mid_t ue_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_update; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_update; } int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - phy[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_update = 0; + if (!phy_is_present(mod_id, cc_id)) return 0; + RC.eNB[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_update = 0; return 0; } @@ -365,46 +352,46 @@ int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, uint8_t cc_id) */ uint8_t flexran_get_threequarter_fs(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.threequarter_fs; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.threequarter_fs; } uint8_t flexran_get_hopping_offset(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.pusch_config_common.pusch_HoppingOffset; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.pusch_HoppingOffset; } PUSCH_HOPPING_t flexran_get_hopping_mode(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.pusch_config_common.hoppingMode; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.hoppingMode; } uint8_t flexran_get_n_SB(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.pusch_config_common.n_SB; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.n_SB; } uint8_t flexran_get_enable64QAM(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.pusch_config_common.enable64QAM; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.enable64QAM; } PHICH_DURATION_t flexran_get_phich_duration(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.phich_config_common.phich_duration; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.phich_config_common.phich_duration; } int flexran_get_phich_resource(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; + if (!phy_is_present(mod_id, cc_id)) return 0; /* TODO why don't we return phich_resource? */ - switch (phy[mod_id][cc_id]->frame_parms.phich_config_common.phich_resource) { + switch (RC.eNB[mod_id][cc_id]->frame_parms.phich_config_common.phich_resource) { case oneSixth: return 0; case half: @@ -420,122 +407,122 @@ int flexran_get_phich_resource(mid_t mod_id, uint8_t cc_id) uint16_t flexran_get_n1pucch_an(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.pucch_config_common.n1PUCCH_AN; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.pucch_config_common.n1PUCCH_AN; } uint8_t flexran_get_nRB_CQI(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.pucch_config_common.nRB_CQI; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.pucch_config_common.nRB_CQI; } uint8_t flexran_get_deltaPUCCH_Shift(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.pucch_config_common.deltaPUCCH_Shift; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.pucch_config_common.deltaPUCCH_Shift; } uint8_t flexran_get_prach_ConfigIndex(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex; } uint8_t flexran_get_prach_FreqOffset(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset; } uint8_t flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.maxHARQ_Msg3Tx; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.maxHARQ_Msg3Tx; } lte_prefix_type_t flexran_get_ul_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.Ncp_UL; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.Ncp_UL; } lte_prefix_type_t flexran_get_dl_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.Ncp; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.Ncp; } uint16_t flexran_get_cell_id(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.Nid_cell; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.Nid_cell; } uint8_t flexran_get_srs_BandwidthConfig(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig; } uint8_t flexran_get_srs_SubframeConfig(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig; } uint8_t flexran_get_srs_MaxUpPts(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.soundingrs_ul_config_common.srs_MaxUpPts; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.soundingrs_ul_config_common.srs_MaxUpPts; } uint8_t flexran_get_N_RB_DL(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.N_RB_DL; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.N_RB_DL; } uint8_t flexran_get_N_RB_UL(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.N_RB_UL; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.N_RB_UL; } uint8_t flexran_get_N_RBG(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.N_RBG; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.N_RBG; } uint8_t flexran_get_subframe_assignment(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.tdd_config; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.tdd_config; } uint8_t flexran_get_special_subframe_assignment(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.tdd_config_S; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.tdd_config_S; } long flexran_get_ra_ResponseWindowSize(mid_t mod_id, uint8_t cc_id) { - if (!rrc[mod_id]) return 0; - return rrc[mod_id]->configuration.rach_raResponseWindowSize[cc_id]; + if (!rrc_is_present(mod_id)) return 0; + return RC.rrc[mod_id]->configuration.rach_raResponseWindowSize[cc_id]; } long flexran_get_mac_ContentionResolutionTimer(mid_t mod_id, uint8_t cc_id) { - if (!rrc[mod_id]) return 0; - return rrc[mod_id]->configuration.rach_macContentionResolutionTimer[cc_id]; + if (!rrc_is_present(mod_id)) return 0; + return RC.rrc[mod_id]->configuration.rach_macContentionResolutionTimer[cc_id]; } Protocol__FlexDuplexMode flexran_get_duplex_mode(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - switch (phy[mod_id][cc_id]->frame_parms.frame_type) { + if (!phy_is_present(mod_id, cc_id)) return 0; + switch (RC.eNB[mod_id][cc_id]->frame_parms.frame_type) { case TDD: return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD; case FDD: @@ -547,21 +534,21 @@ Protocol__FlexDuplexMode flexran_get_duplex_mode(mid_t mod_id, uint8_t cc_id) long flexran_get_si_window_length(mid_t mod_id, uint8_t cc_id) { - if (!rrc[mod_id] || !rrc[mod_id]->carrier[cc_id].sib1) return 0; - return rrc[mod_id]->carrier[cc_id].sib1->si_WindowLength; + if (!rrc_is_present(mod_id) || !RC.rrc[mod_id]->carrier[cc_id].sib1) return 0; + return RC.rrc[mod_id]->carrier[cc_id].sib1->si_WindowLength; } uint8_t flexran_get_sib1_length(mid_t mod_id, uint8_t cc_id) { - if (!rrc[mod_id]) return 0; - return rrc[mod_id]->carrier[cc_id].sizeof_SIB1; + if (!rrc_is_present(mod_id)) return 0; + return RC.rrc[mod_id]->carrier[cc_id].sizeof_SIB1; } uint8_t flexran_get_num_pdcch_symb(mid_t mod_id, uint8_t cc_id) { /* TODO: This should return the number of PDCCH symbols initially used by the * cell cc_id -> is the correction right? */ - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->pdcch_vars[0].num_pdcch_symbols; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->pdcch_vars[0].num_pdcch_symbols; //(PHY_vars_UE_g[mod_id][cc_id]->lte_ue_pdcch_vars[mod_id]->num_pdcch_symbols); } @@ -576,10 +563,10 @@ uint8_t flexran_get_num_pdcch_symb(mid_t mod_id, uint8_t cc_id) { TimeAlignmentTimer_t flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id) { - if (!rrc[mod_id]) return -1; + if (!rrc_is_present(mod_id)) return -1; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return -1; if (!ue_context_p->ue_context.mac_MainConfig) return -1; @@ -588,10 +575,10 @@ TimeAlignmentTimer_t flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id) Protocol__FlexMeasGapConfigPattern flexran_get_meas_gap_config(mid_t mod_id, mid_t ue_id) { - if (!rrc[mod_id]) return -1; + if (!rrc_is_present(mod_id)) return -1; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return -1; if (!ue_context_p->ue_context.measGapConfig) return -1; @@ -609,10 +596,10 @@ Protocol__FlexMeasGapConfigPattern flexran_get_meas_gap_config(mid_t mod_id, mid long flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id) { - if (!rrc[mod_id]) return -1; + if (!rrc_is_present(mod_id)) return -1; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return -1; if (!ue_context_p->ue_context.measGapConfig) return -1; @@ -631,9 +618,9 @@ long flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id) /* TODO return type is unsigned, so we cannot return -1 in case of error! */ uint8_t flexran_get_rrc_status(mid_t mod_id, rnti_t rnti) { - if (!rrc[mod_id]) return 0; + if (!rrc_is_present(mod_id)) return 0; - struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return RRC_INACTIVE; return ue_context_p->ue_context.Status; @@ -641,14 +628,14 @@ uint8_t flexran_get_rrc_status(mid_t mod_id, rnti_t rnti) uint64_t flexran_get_ue_aggregated_max_bitrate_dl(mid_t mod_id, mid_t ue_id) { - if (!UE_list[mod_id]) return 0; - return UE_list[mod_id]->UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateDL; + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateDL; } uint64_t flexran_get_ue_aggregated_max_bitrate_ul(mid_t mod_id, mid_t ue_id) { - if (!UE_list[mod_id]) return 0; - return UE_list[mod_id]->UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateUL; + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateUL; } int flexran_get_half_duplex(mid_t ue_id) @@ -704,10 +691,10 @@ int flexran_get_res_alloc_type1(mid_t ue_id) long flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id) { - if (!rrc[mod_id]) return -1; + if (!rrc_is_present(mod_id)) return -1; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; @@ -717,10 +704,10 @@ long flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id) BOOLEAN_t flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id) { - if (!rrc[mod_id]) return -1; + if (!rrc_is_present(mod_id)) return -1; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return -1; if (!ue_context_p->ue_context.mac_MainConfig) return -1; if (!ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config) return -1; @@ -729,10 +716,10 @@ BOOLEAN_t flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id) long flexran_get_maxHARQ_TX(mid_t mod_id, mid_t ue_id) { - if (!rrc[mod_id]) return -1; + if (!rrc_is_present(mod_id)) return -1; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return -1; if (!ue_context_p->ue_context.mac_MainConfig) return -1; @@ -742,10 +729,10 @@ long flexran_get_maxHARQ_TX(mid_t mod_id, mid_t ue_id) long flexran_get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id) { - if (!rrc[mod_id]) return -1; + if (!rrc_is_present(mod_id)) return -1; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; @@ -755,10 +742,10 @@ long flexran_get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id) long flexran_get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id) { - if (!rrc[mod_id]) return -1; + if (!rrc_is_present(mod_id)) return -1; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; @@ -768,10 +755,10 @@ long flexran_get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id) long flexran_get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id) { - if (!rrc[mod_id]) return -1; + if (!rrc_is_present(mod_id)) return -1; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; @@ -781,10 +768,10 @@ long flexran_get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id) BOOLEAN_t flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id) { - if (!rrc[mod_id]) return -1; + if (!rrc_is_present(mod_id)) return -1; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; @@ -795,17 +782,17 @@ BOOLEAN_t flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id) BOOLEAN_t flexran_get_ack_nack_simultaneous_trans(mid_t mod_id, mid_t ue_id, uint8_t cc_id) { - if (!rrc[mod_id]) return -1; - if (!rrc[mod_id]->carrier[cc_id].sib2) return -1; - return rrc[mod_id]->carrier[cc_id].sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; + if (!rrc_is_present(mod_id)) return -1; + if (!RC.rrc[mod_id]->carrier[cc_id].sib2) return -1; + return RC.rrc[mod_id]->carrier[cc_id].sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; } CQI_ReportModeAperiodic_t flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id) { - if (!rrc[mod_id]) return -1; + if (!rrc_is_present(mod_id)) return -1; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; @@ -815,10 +802,10 @@ CQI_ReportModeAperiodic_t flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t long flexran_get_tdd_ack_nack_feedback_mode(mid_t mod_id, mid_t ue_id) { - if (!rrc[mod_id]) return -1; + if (!rrc_is_present(mod_id)) return -1; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; @@ -829,10 +816,10 @@ long flexran_get_tdd_ack_nack_feedback_mode(mid_t mod_id, mid_t ue_id) long flexran_get_ack_nack_repetition_factor(mid_t mod_id, mid_t ue_id) { - if (!rrc[mod_id]) return -1; + if (!rrc_is_present(mod_id)) return -1; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; @@ -842,10 +829,10 @@ long flexran_get_ack_nack_repetition_factor(mid_t mod_id, mid_t ue_id) long flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id) { - if (!rrc[mod_id]) return -1; + if (!rrc_is_present(mod_id)) return -1; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return -1; if (!ue_context_p->ue_context.mac_MainConfig) return -1; @@ -856,10 +843,10 @@ long flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id) int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id) { - if (!rrc[mod_id]) return -1; + if (!rrc_is_present(mod_id)) return -1; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; @@ -900,92 +887,112 @@ int flexran_get_direction(mid_t ue_id, mid_t lc_id) uint8_t flexran_get_antenna_ports(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.nb_antenna_ports_eNB; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.nb_antenna_ports_eNB; } /* TODO better give real value (without division)? */ uint32_t flexran_agent_get_operating_dl_freq(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.dl_CarrierFreq / 1000000; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.dl_CarrierFreq / 1000000; } /* TODO better give real value (without division)? */ uint32_t flexran_agent_get_operating_ul_freq(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.ul_CarrierFreq / 1000000; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.ul_CarrierFreq / 1000000; } uint8_t flexran_agent_get_operating_eutra_band(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.eutra_band; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.eutra_band; } int8_t flexran_agent_get_operating_pdsch_refpower(mid_t mod_id, uint8_t cc_id) { - if (!phy[mod_id][cc_id]) return 0; - return phy[mod_id][cc_id]->frame_parms.pdsch_config_common.referenceSignalPower; + if (!phy_is_present(mod_id, cc_id)) return 0; + return RC.eNB[mod_id][cc_id]->frame_parms.pdsch_config_common.referenceSignalPower; } long flexran_agent_get_operating_pusch_p0(mid_t mod_id, uint8_t cc_id) { - if (!rrc[mod_id]) return 0; - return rrc[mod_id]->configuration.pusch_p0_Nominal[cc_id]; + if (!rrc_is_present(mod_id)) return 0; + return RC.rrc[mod_id]->configuration.pusch_p0_Nominal[cc_id]; } void flexran_agent_set_operating_dl_freq(mid_t mod_id, uint8_t cc_id, uint32_t dl_freq_mhz) { - if (phy[mod_id][cc_id]) { - phy[mod_id][cc_id]->frame_parms.dl_CarrierFreq = dl_freq_mhz * 1000000; + if (phy_is_present(mod_id, cc_id)) { + RC.eNB[mod_id][cc_id]->frame_parms.dl_CarrierFreq = dl_freq_mhz * 1000000; + } else { + LOG_E(FLEXRAN_AGENT, "can not set dl_CarrierFreq to %d MHz in PHY: PHY is not present\n", dl_freq_mhz); } - if (rrc[mod_id]) { - rrc[mod_id]->configuration.downlink_frequency[cc_id] = dl_freq_mhz * 1000000; + if (rrc_is_present(mod_id)) { + RC.rrc[mod_id]->configuration.downlink_frequency[cc_id] = dl_freq_mhz * 1000000; + } else { + LOG_E(FLEXRAN_AGENT, "can not set downlink_frequency to %d MHz in RRC: RRC is not present\n", dl_freq_mhz); } } void flexran_agent_set_operating_ul_freq(mid_t mod_id, uint8_t cc_id, int32_t ul_freq_mhz_offset) { - if (phy[mod_id][cc_id]) { + if (phy_is_present(mod_id, cc_id)) { uint32_t new_ul_freq_mhz = flexran_agent_get_operating_dl_freq(mod_id, cc_id) + ul_freq_mhz_offset; - phy[mod_id][cc_id]->frame_parms.ul_CarrierFreq = new_ul_freq_mhz * 1000000; + RC.eNB[mod_id][cc_id]->frame_parms.ul_CarrierFreq = new_ul_freq_mhz * 1000000; + } else { + LOG_E(FLEXRAN_AGENT, "can not set ul_CarrierFreq using offset %d MHz in PHY: PHY is not present\n", ul_freq_mhz_offset); } - if (rrc[mod_id]) { - rrc[mod_id]->configuration.uplink_frequency_offset[cc_id] = ul_freq_mhz_offset; + if (rrc_is_present(mod_id)) { + RC.rrc[mod_id]->configuration.uplink_frequency_offset[cc_id] = ul_freq_mhz_offset; + } else { + LOG_E(FLEXRAN_AGENT, "can not set uplink_frequency_offset to %d MHz in RRC: RRC is not present\n", ul_freq_mhz_offset); } } void flexran_agent_set_operating_eutra_band(mid_t mod_id, uint8_t cc_id, uint8_t eutra_band) { - if (phy[mod_id][cc_id]) { - phy[mod_id][cc_id]->frame_parms.eutra_band = eutra_band; + if (phy_is_present(mod_id, cc_id)) { + RC.eNB[mod_id][cc_id]->frame_parms.eutra_band = eutra_band; + } else { + LOG_E(FLEXRAN_AGENT, "can not set eutra_band to %d in PHY: PHY is not present\n", eutra_band); } - if (rrc[mod_id]) { - rrc[mod_id]->configuration.eutra_band[cc_id] = eutra_band; + if (rrc_is_present(mod_id)) { + RC.rrc[mod_id]->configuration.eutra_band[cc_id] = eutra_band; + } else { + LOG_E(FLEXRAN_AGENT, "can not set eutra_band to %d in RRC: RRC is not present\n", eutra_band); } } /* Sets both DL/UL */ void flexran_agent_set_operating_bandwidth(mid_t mod_id, uint8_t cc_id, uint8_t N_RB) { - if (phy[mod_id][cc_id]) { - phy[mod_id][cc_id]->frame_parms.N_RB_DL = N_RB; - phy[mod_id][cc_id]->frame_parms.N_RB_UL = N_RB; + if (phy_is_present(mod_id, cc_id)) { + RC.eNB[mod_id][cc_id]->frame_parms.N_RB_DL = N_RB; + RC.eNB[mod_id][cc_id]->frame_parms.N_RB_UL = N_RB; + } else { + LOG_E(FLEXRAN_AGENT, "can not set N_RB_DL and N_RB_UL to %d in PHY: PHY is not present\n", N_RB); } - if (rrc[mod_id]) { - rrc[mod_id]->configuration.N_RB_DL[cc_id] = N_RB; + if (rrc_is_present(mod_id)) { + RC.rrc[mod_id]->configuration.N_RB_DL[cc_id] = N_RB; + } else { + LOG_E(FLEXRAN_AGENT, "can not set N_RB_DL to %d in RRC: RRC is not present\n", N_RB); } } void flexran_agent_set_operating_frame_type(mid_t mod_id, uint8_t cc_id, lte_frame_type_t frame_type) { - if (phy[mod_id][cc_id]) { - phy[mod_id][cc_id]->frame_parms.frame_type = frame_type; + if (phy_is_present(mod_id, cc_id)) { + RC.eNB[mod_id][cc_id]->frame_parms.frame_type = frame_type; + } else { + LOG_E(FLEXRAN_AGENT, "can not set frame_type to %d in PHY: PHY is not present\n", frame_type); } - if (rrc[mod_id]) { - rrc[mod_id]->configuration.frame_type[cc_id] = frame_type; + if (rrc_is_present(mod_id)) { + RC.rrc[mod_id]->configuration.frame_type[cc_id] = frame_type; + } else { + LOG_E(FLEXRAN_AGENT, "can not set frame_type to %d in RRC: RRC is not present\n", frame_type); } } @@ -1097,10 +1104,10 @@ uint32_t flexran_get_pdcp_rx_oo(const mid_t mod_id, const mid_t ue_id, const lc MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, mid_t ue_id) { - if (!rrc[mod_id]) return -1; + if (!rrc_is_present(mod_id)) return -1; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return -1; if (!ue_context_p->ue_context.measResults) return -1; @@ -1109,10 +1116,10 @@ MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, mid_t ue_id) float flexran_get_rrc_pcell_rsrp(mid_t mod_id, mid_t ue_id) { - if (!rrc[mod_id]) return -1; + if (!rrc_is_present(mod_id)) return -1; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return -1; if (!ue_context_p->ue_context.measResults) return -1; @@ -1121,10 +1128,10 @@ float flexran_get_rrc_pcell_rsrp(mid_t mod_id, mid_t ue_id) float flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id) { - if (!rrc[mod_id]) return -1; + if (!rrc_is_present(mod_id)) return -1; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return -1; if (!ue_context_p->ue_context.measResults) return -1; @@ -1134,10 +1141,10 @@ float flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id) /*Number of neighbouring cells for specific UE*/ int flexran_get_rrc_num_ncell(mid_t mod_id, mid_t ue_id) { - if (!rrc[mod_id]) return 0; + if (!rrc_is_present(mod_id)) return 0; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return 0; if (!ue_context_p->ue_context.measResults) return 0; @@ -1148,10 +1155,10 @@ int flexran_get_rrc_num_ncell(mid_t mod_id, mid_t ue_id) PhysCellId_t flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, int cell_id) { - if (!rrc[mod_id]) return -1; + if (!rrc_is_present(mod_id)) return -1; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return -1; if (!ue_context_p->ue_context.measResults) return -1; @@ -1163,10 +1170,10 @@ PhysCellId_t flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, int ce float flexran_get_rrc_neigh_rsrp(mid_t mod_id, mid_t ue_id, int cell_id) { - if (!rrc[mod_id]) return -1; + if (!rrc_is_present(mod_id)) return -1; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return -1; if (!ue_context_p->ue_context.measResults) return -1; @@ -1179,10 +1186,10 @@ float flexran_get_rrc_neigh_rsrp(mid_t mod_id, mid_t ue_id, int cell_id) float flexran_get_rrc_neigh_rsrq(mid_t mod_id, mid_t ue_id, int cell_id) { - if (!rrc[mod_id]) return -1; + if (!rrc_is_present(mod_id)) return -1; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); - struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(rrc[mod_id], rnti); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return -1; if (!ue_context_p->ue_context.measResults) return -1; diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 6dc6fba377..25faa105a6 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -50,8 +50,6 @@ * get generic info from RAN ****************************/ -void flexran_set_RC_vars(mid_t mod_id, ran_name_t ran); - uint32_t flexran_get_current_time_ms(mid_t mod_id, int subframe_flag); /*Return the current frame number From a6098dbf09d5bc7caa3bd544c2594dec054a5608 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 15 Jan 2018 18:31:37 +0100 Subject: [PATCH 073/195] delete unnecessary FlexRAN source files all the FlexRAN scheduling code is now also handled by the general OAI scheduling code --- cmake_targets/CMakeLists.txt | 22 - .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 2 - openair2/LAYER2/MAC/eNB_scheduler.c | 1 - openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 2 +- openair2/LAYER2/MAC/flexran_agent_mac_proto.h | 323 --- .../MAC/flexran_agent_scheduler_dataplane.c | 583 ------ .../MAC/flexran_agent_scheduler_dlsch_ue.c | 1814 ----------------- .../flexran_agent_scheduler_dlsch_ue_remote.c | 202 -- .../flexran_agent_scheduler_dlsch_ue_remote.h | 70 - .../MAC/flexran_agent_scheduler_ulsch_ue.c | 1112 ---------- openair2/LAYER2/MAC/flexran_dci_conversions.h | 51 - 11 files changed, 1 insertion(+), 4181 deletions(-) delete mode 100644 openair2/LAYER2/MAC/flexran_agent_mac_proto.h delete mode 100644 openair2/LAYER2/MAC/flexran_agent_scheduler_dataplane.c delete mode 100644 openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c delete mode 100644 openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue_remote.c delete mode 100644 openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue_remote.h delete mode 100644 openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c delete mode 100644 openair2/LAYER2/MAC/flexran_dci_conversions.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index da0c3fbc1f..b659819e25 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1191,17 +1191,6 @@ set (MAC_SRC ${MAC_DIR}/config.c ) -if (FLEXRAN_AGENT_SB_IF) - -set (MAC_SRC ${MAC_SRC} - ${MAC_DIR}/flexran_agent_scheduler_dlsch_ue.c - ${MAC_DIR}/flexran_agent_scheduler_ulsch_ue.c - ${MAC_DIR}/flexran_agent_scheduler_dataplane.c - ${MAC_DIR}/flexran_agent_scheduler_dlsch_ue_remote.c -) - -endif() - set (ENB_APP_SRC ${OPENAIR2_DIR}/ENB_APP/enb_app.c ${OPENAIR2_DIR}/ENB_APP/enb_config.c @@ -1213,17 +1202,6 @@ add_library(L2 ${ENB_APP_SRC}) # ${OPENAIR2_DIR}/RRC/L2_INTERFACE/openair_rrc_L2_interface.c) -if (FLEXRAN_AGENT_SB_IF) - -#Test for adding a shared library -add_library(default_sched SHARED ${MAC_DIR}/flexran_agent_scheduler_dlsch_ue.c) -add_library(remote_sched SHARED ${MAC_DIR}/flexran_agent_scheduler_dlsch_ue_remote.c) - -add_library(default_ul_sched SHARED ${MAC_DIR}/flexran_agent_scheduler_ulsch_ue.c) - - -endif() - # L3 Libs ########################## diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 02350eb0c1..d60a9eb3b7 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -35,8 +35,6 @@ #include "flexran_agent_ran_api.h" #include "LAYER2/MAC/proto.h" -#include "LAYER2/MAC/flexran_agent_mac_proto.h" -#include "LAYER2/MAC/flexran_agent_scheduler_dlsch_ue_remote.h" #include "liblfds700.h" diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 432915eb8c..1195e05379 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -56,7 +56,6 @@ //Agent-related headers #include "flexran_agent_extern.h" #include "flexran_agent_mac.h" -#include "flexran_agent_mac_proto.h" #endif #if defined(ENABLE_ITTI) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 0d9f129fa6..a0da4f4961 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -62,7 +62,7 @@ #include "flexran_agent_ran_api.h" #include "header.pb-c.h" #include "flexran.pb-c.h" -#include "flexran_agent_mac.h" +#endif #include #endif diff --git a/openair2/LAYER2/MAC/flexran_agent_mac_proto.h b/openair2/LAYER2/MAC/flexran_agent_mac_proto.h deleted file mode 100644 index be61fa1590..0000000000 --- a/openair2/LAYER2/MAC/flexran_agent_mac_proto.h +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file flexran_agent_mac_proto.h - * \brief MAC functions for FlexRAN agent - * \author Xenofon Foukas and Navid Nikaein - * \date 2016 - * \email: x.foukas@sms.ed.ac.uk - * \version 0.1 - * @ingroup _mac - - */ - -#ifndef __LAYER2_MAC_FLEXRAN_AGENT_MAC_PROTO_H__ -#define __LAYER2_MAC_FLEXRAN_AGENT_MAC_PROTO_H__ - -#include "flexran_agent_defs.h" -#include "header.pb-c.h" -#include "flexran.pb-c.h" - -/* - * slice specific scheduler - */ -typedef void (*slice_scheduler_dl)(module_id_t mod_id, - int slice_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage **dl_info); - -typedef void (*slice_scheduler_ul)(module_id_t mod_id, - frame_t frame, - unsigned char cooperation_flag, - uint32_t subframe, - unsigned char sched_subframe, - Protocol__FlexranMessage **ul_info); - - -/* - * top level flexran scheduler used by the eNB scheduler - */ -void flexran_schedule_ue_dl_spec_default(mid_t mod_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info); -/* - * slice specific scheduler for embb - */ -void -flexran_schedule_ue_spec_embb(mid_t mod_id, - int slice_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info); -/* - * slice specific scheduler for urllc - */ -void -flexran_schedule_ue_spec_urllc(mid_t mod_id, - int slice_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info); - -/* - * slice specific scheduler for mmtc - */ -void -flexran_schedule_ue_spec_mmtc(mid_t mod_id, - int slice_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info); -/* - * slice specific scheduler for best effort traffic - */ -void -flexran_schedule_ue_spec_be(mid_t mod_id, - int slice_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info); - -/* - * common flexran scheduler function - */ -void -<<<<<<< HEAD -flexran_schedule_ue_spec_common(mid_t mod_id, - int slice_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info); - -uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, int total_rbs); - -int flexran_slice_member(int UE_id, int slice_id); - -int flexran_slice_maxmcs(int slice_id); - -void _store_dlsch_buffer(module_id_t Mod_id, - int slice_id, - frame_t frameP, sub_frame_t subframeP); - - -void _assign_rbs_required(module_id_t Mod_id, - int slice_id, - frame_t frameP, - sub_frame_t subframe, - uint16_t - nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], - uint16_t - nb_rbs_allowed_slice[MAX_NUM_CCs] - [MAX_NUM_SLICES], int min_rb_unit[MAX_NUM_CCs]); - -void _dlsch_scheduler_pre_processor(module_id_t Mod_id, - int slice_id, - frame_t frameP, - sub_frame_t subframeP, - int N_RBG[MAX_NUM_CCs], - int *mbsfn_flag); - -void _dlsch_scheduler_pre_processor_reset(int module_idP, - int UE_id, - uint8_t CC_id, - int frameP, - int subframeP, - int N_RBG, - uint16_t - nb_rbs_required[MAX_NUM_CCs] - [NUMBER_OF_UE_MAX], - uint16_t - nb_rbs_required_remaining - [MAX_NUM_CCs][NUMBER_OF_UE_MAX], - uint16_t - nb_rbs_allowed_slice[MAX_NUM_CCs] - [MAX_NUM_SLICES], - unsigned char - rballoc_sub[MAX_NUM_CCs] - [N_RBG_MAX], - unsigned char - MIMO_mode_indicator[MAX_NUM_CCs] - [N_RBG_MAX]); - -void _dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, - int UE_id, - uint8_t CC_id, - int N_RBG, - int transmission_mode, - int min_rb_unit, - uint8_t N_RB_DL, - uint16_t - nb_rbs_required[MAX_NUM_CCs] - [NUMBER_OF_UE_MAX], - uint16_t - nb_rbs_required_remaining - [MAX_NUM_CCs] - [NUMBER_OF_UE_MAX], - unsigned char - rballoc_sub[MAX_NUM_CCs] - [N_RBG_MAX], - unsigned char - MIMO_mode_indicator - [MAX_NUM_CCs][N_RBG_MAX]); -======= -flexran_schedule_ue_dl_spec_common(mid_t mod_id, - int slice_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage **dl_info); - -void -flexran_schedule_ue_ul_spec_default(mid_t mod_id, - uint32_t frame, - uint32_t cooperation_flag, - int subframe, - unsigned char sched_subframe, - Protocol__FlexranMessage **ul_info); - - -uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, - int total_rbs); - -int flexran_slice_member(int UE_id, - int slice_id); - -int flexran_slice_maxmcs(int slice_id) ; - -/* Downlink Primitivies */ - -void _store_dlsch_buffer (module_id_t Mod_id, - int slice_id, - frame_t frameP, - sub_frame_t subframeP); - - -void _assign_rbs_required (module_id_t Mod_id, - int slice_id, - frame_t frameP, - sub_frame_t subframe, - uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], - uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES], - int min_rb_unit[MAX_NUM_CCs]); - - -/* Uplink Primitivies */ - -// void _sort_ue_ul (module_id_t module_idP,int frameP, sub_frame_t subframeP); - -void _assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, sub_frame_t subframeP, uint16_t *first_rb); - - -void _ulsch_scheduler_pre_processor(module_id_t module_idP, - int slice_id, - int frameP, - sub_frame_t subframeP, - uint16_t *first_rb); - - -void flexran_agent_schedule_ulsch_rnti(module_id_t module_idP, - unsigned char cooperation_flag, - frame_t frameP, - sub_frame_t subframeP, - unsigned char sched_subframe, - uint16_t *first_rb); - -/* Downlink Primitives */ - -void _dlsch_scheduler_pre_processor (module_id_t Mod_id, - int slice_id, - frame_t frameP, - sub_frame_t subframeP, - int N_RBG[MAX_NUM_CCs], - int *mbsfn_flag); - -void _dlsch_scheduler_pre_processor_reset (int module_idP, - int UE_id, - uint8_t CC_id, - int frameP, - int subframeP, - int N_RBG, - uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], - uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX], - uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES], - unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], - unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]); - -void _dlsch_scheduler_pre_processor_allocate (module_id_t Mod_id, - int UE_id, - uint8_t CC_id, - int N_RBG, - int transmission_mode, - int min_rb_unit, - uint8_t N_RB_DL, - uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], - uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX], - unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], - unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]); ->>>>>>> feature-68-enb-agent - -/* - * Default scheduler used by the eNB agent - */ -void flexran_schedule_ue_dl_spec_default(mid_t mod_id, uint32_t frame, uint32_t subframe, - int *mbsfn_flag, Protocol__FlexranMessage **dl_info); - -/* - Uplink scheduler used by MAC agent -*/ - -void flexran_agent_schedule_ulsch_ue_spec(module_id_t module_idP, frame_t frameP, unsigned char cooperation_flag, - sub_frame_t subframeP, - unsigned char sched_subframe, Protocol__FlexranMessage **ul_info); - -/* - * Data plane function for applying the DL decisions of the scheduler - */ -void flexran_apply_scheduling_decisions(mid_t mod_id, uint32_t frame, uint32_t subframe, int *mbsfn_flag, - Protocol__FlexranMessage *dl_scheduling_info); - -/* - * Data plane function for applying the UE specific DL decisions of the scheduler - */ -void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - uint32_t n_dl_ue_data, - Protocol__FlexDlData ** - dl_ue_data); - -/* - * Data plane function for filling the DCI structure - */ -void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti, - Protocol__FlexDlDci * dl_dci); - -#endif diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dataplane.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_dataplane.c deleted file mode 100644 index 6b1c2579b2..0000000000 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dataplane.c +++ /dev/null @@ -1,583 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file flexran_agent_scheduler_dataplane.c - * \brief data plane procedures related to eNB scheduling - * \author Xenofon Foukas - * \date 2016 - * \email: x.foukas@sms.ed.ac.uk - * \version 0.1 - * @ingroup _mac - - */ - -#include "assertions.h" -#include "PHY/defs.h" -#include "PHY/extern.h" - -#include "SCHED/defs.h" -#include "SCHED/extern.h" - -#include "LAYER2/MAC/flexran_agent_mac_proto.h" -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/proto.h" -#include "LAYER2/MAC/extern.h" -#include "LAYER2/MAC/flexran_dci_conversions.h" - -#include "UTIL/LOG/log.h" -#include "UTIL/LOG/vcd_signal_dumper.h" -#include "UTIL/OPT/opt.h" -#include "OCG.h" -#include "OCG_extern.h" - -#include "RRC/LITE/extern.h" -#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" - -#include "header.pb-c.h" -#include "flexran.pb-c.h" -#include "flexran_agent_extern.h" - -#include "flexran_agent_common.h" - -#include "SIMULATION/TOOLS/defs.h" // for taus - -void -flexran_apply_dl_scheduling_decisions(mid_t mod_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage * - dl_scheduling_info) -{ - - Protocol__FlexDlMacConfig *mac_config = - dl_scheduling_info->dl_mac_config_msg; - - // Check if there is anything to schedule for random access - if (mac_config->n_dl_rar > 0) { - /*TODO: call the random access data plane function */ - } - // Check if there is anything to schedule for paging/broadcast - if (mac_config->n_dl_broadcast > 0) { - /*TODO: call the broadcast/paging data plane function */ - } - // Check if there is anything to schedule for the UEs - if (mac_config->n_dl_ue_data > 0) { - flexran_apply_ue_spec_scheduling_decisions(mod_id, frame, subframe, - mbsfn_flag, - mac_config-> - n_dl_ue_data, - mac_config->dl_ue_data); - } - -} - -void -flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - uint32_t n_dl_ue_data, - Protocol__FlexDlData ** - dl_ue_data) -{ - - uint8_t CC_id; - int UE_id; - mac_rlc_status_resp_t rlc_status; - unsigned char ta_len = 0; - unsigned char header_len = 0, header_len_tmp = 0; - unsigned char sdu_lcids[11], offset, num_sdus = 0; - uint16_t nb_rb; - uint16_t TBS, sdu_lengths[11], rnti, padding = 0, post_padding = 0; - unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; - uint8_t round = 0; - uint8_t harq_pid = 0; - // LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; - LTE_eNB_UE_stats *eNB_UE_stats = NULL; - uint16_t sdu_length_total = 0; - short ta_update = 0; - eNB_MAC_INST *eNB = &eNB_mac_inst[mod_id]; - UE_list_t *UE_list = &eNB->UE_list; - // static int32_t tpc_accumulated=0; - UE_sched_ctrl *ue_sched_ctl; - - int last_sdu_header_len = 0; - - int i, j; - - Protocol__FlexDlData *dl_data; - Protocol__FlexDlDci *dl_dci; - - uint32_t rlc_size, n_lc, lcid; - - // For each UE-related command - for (i = 0; i < n_dl_ue_data; i++) { - - dl_data = dl_ue_data[i]; - dl_dci = dl_data->dl_dci; - - CC_id = dl_data->serv_cell_index; - // frame_parms[CC_id] = mac_xface->get_lte_frame_parms(mod_id, CC_id); - - rnti = dl_data->rnti; - UE_id = find_ue(rnti, PHY_vars_eNB_g[mod_id][CC_id]); - - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti); - - round = dl_dci->rv[0]; - harq_pid = dl_dci->harq_process; - - //LOG_I(FLEXRAN_AGENT, "[Frame %d][Subframe %d] Scheduling harq %d\n", frame, subframe, harq_pid); - // LOG_I(FLEXRAN_AGENT, "[Frame %d][Subframe %d]Now scheduling harq_pid %d (round %d)\n", frame, subframe, harq_pid, round); - - // If this is a new transmission - if (round == 0) { - // First we have to deal with the creation of the PDU based on the message instructions - rlc_status.bytes_in_buffer = 0; - - TBS = dl_dci->tbs_size[0]; - - if (dl_data->n_ce_bitmap > 0) { - //Check if there is TA command and set the length appropriately - ta_len = - (dl_data-> - ce_bitmap[0] & PROTOCOL__FLEX_CE_TYPE__FLPCET_TA) ? 2 - : 0; - } - - num_sdus = 0; - sdu_length_total = 0; - - n_lc = dl_data->n_rlc_pdu; - // Go through each one of the channel commands and create SDUs - header_len = 0; - last_sdu_header_len = 0; - for (j = 0; j < n_lc; j++) { - sdu_lengths[j] = 0; - lcid = - dl_data->rlc_pdu[j]->rlc_pdu_tb[0]->logical_channel_id; - rlc_size = dl_data->rlc_pdu[j]->rlc_pdu_tb[0]->size; - LOG_D(MAC, - "[TEST] [eNB %d] [Frame %d] [Subframe %d], LCID %d, CC_id %d, Requesting %d bytes from RLC (RRC message)\n", - mod_id, frame, subframe, lcid, CC_id, rlc_size); - if (rlc_size > 0) { - - rlc_status = mac_rlc_status_ind(mod_id, - rnti, - mod_id, - frame, - subframe, - ENB_FLAG_YES, - MBMS_FLAG_NO, lcid, 0); - - if (rlc_status.bytes_in_buffer > 0) { - - if (rlc_status.bytes_in_buffer < rlc_size) { - rlc_size = rlc_status.bytes_in_buffer; - } - - if (rlc_size <= 2) { - rlc_size = 3; - } - - rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, subframe, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, rlc_size); // transport block set size - - LOG_D(MAC, - "[TEST] RLC can give %d bytes for LCID %d during second call\n", - rlc_status.bytes_in_buffer, lcid); - - if (rlc_status.bytes_in_buffer > 0) { - - sdu_lengths[j] = mac_rlc_data_req(mod_id, rnti, mod_id, frame, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, rlc_size, //not used - (char *) - &dlsch_buffer - [sdu_length_total]); - - LOG_D(MAC, - "[eNB %d][LCID %d] CC_id %d Got %d bytes from RLC\n", - mod_id, lcid, CC_id, sdu_lengths[j]); - sdu_length_total += sdu_lengths[j]; - sdu_lcids[j] = lcid; - - UE_list-> - eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid] - += 1; - UE_list-> - eNB_UE_stats[CC_id][UE_id].num_bytes_tx - [lcid] += sdu_lengths[j]; - - if (sdu_lengths[j] < 128) { - header_len += 2; - last_sdu_header_len = 2; - } else { - header_len += 3; - last_sdu_header_len = 3; - } - num_sdus++; - } - } - } - } // SDU creation end - - - if (((sdu_length_total + header_len + ta_len) > 0)) { - - header_len_tmp = header_len; - - // If we have only a single SDU, header length becomes 1 - if ((num_sdus) == 1) { - //if (header_len == 2 || header_len == 3) { - header_len = 1; - } else { - header_len = (header_len - last_sdu_header_len) + 1; - } - - // If we need a 1 or 2 bit padding or no padding at all - if ((TBS - header_len - sdu_length_total - ta_len) <= 2 || (TBS - header_len - sdu_length_total - ta_len) > TBS) { //protect from overflow - padding = - (TBS - header_len - sdu_length_total - ta_len); - post_padding = 0; - } else { // The last sdu needs to have a length field, since we add padding - padding = 0; - header_len = header_len_tmp; - post_padding = TBS - sdu_length_total - header_len - ta_len; // 1 is for the postpadding header - } - - if (ta_len > 0) { - // Reset the measurement - ta_update = flexran_get_TA(mod_id, UE_id, CC_id); - ue_sched_ctl->ta_timer = 20; - eNB_UE_stats->timing_advance_update = 0; - } else { - ta_update = 0; - } - - // If there is nothing to schedule, just leave - if ((sdu_length_total) <= 0) { - harq_pid_updated[UE_id][harq_pid] = 1; - harq_pid_round[UE_id][harq_pid] = 0; - continue; - } - // LOG_I(FLEXRAN_AGENT, "[Frame %d][Subframe %d] TBS is %d and bytes are %d\n", frame, subframe, TBS, sdu_length_total); - - offset = generate_dlsch_header((unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], num_sdus, //num_sdus - sdu_lengths, // - sdu_lcids, 255, // no drx - ta_update, // timing advance - NULL, // contention res id - padding, post_padding); - -#ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n"); - - for (i = 0; i < 16; i++) { - LOG_T(MAC, "%x.", dlsch_buffer[i]); - } - - LOG_T(MAC, "\n"); -#endif - // cycle through SDUs and place in dlsch_buffer - memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id]. - payload[0][offset], dlsch_buffer, sdu_length_total); - // memcpy(&eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); - - // fill remainder of DLSCH with random data - for (j = 0; j < (TBS - sdu_length_total - offset); j++) { - UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + - sdu_length_total - + j] = - (char) (taus() & 0xff); - } - - //eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0][offset+sdu_lengths[0]+j] = (char)(taus()&0xff); - if (opt_enabled == 1) { - trace_pdu(1, - (uint8_t *) - UE_list->DLSCH_pdu[CC_id][0][UE_id]. - payload[0], TBS, mod_id, 3, UE_RNTI(mod_id, - UE_id), - eNB->frame, eNB->subframe, 0, 0); - LOG_D(OPT, - "[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", - mod_id, CC_id, frame, UE_RNTI(mod_id, UE_id), - TBS); - } - // store stats - eNB->eNB_stats[CC_id].dlsch_bytes_tx += sdu_length_total; - eNB->eNB_stats[CC_id].dlsch_pdus_tx += 1; - UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi = - eNB_UE_stats->DL_cqi[0]; - - UE_list->eNB_UE_stats[CC_id][UE_id].crnti = rnti; - UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status = - mac_eNB_get_rrc_status(mod_id, rnti); - UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; - UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round; - - //nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - //Find the number of resource blocks and set them to the template for retransmissions - nb_rb = get_min_rb_unit(mod_id, CC_id); - uint16_t stats_tbs = - mac_xface->get_TBS_DL(dl_dci->mcs[0], nb_rb); - - while (stats_tbs < TBS) { - nb_rb += get_min_rb_unit(mod_id, CC_id); - stats_tbs = - mac_xface->get_TBS_DL(dl_dci->mcs[0], nb_rb); - } - - // LOG_I(FLEXRAN_AGENT, "The MCS was %d\n", dl_dci->mcs[0]); - - UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used += - nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = - dl_dci->mcs[0]; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = - dl_dci->mcs[0]; - UE_list->eNB_UE_stats[CC_id][UE_id].TBS = TBS; - - UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes = - TBS - sdu_length_total; - UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes += - sdu_length_total; - UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes += TBS; - UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus += 1; - - //eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[eNB_UE_stats->DL_cqi[0]]; - //eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); - } else { - LOG_D(FLEXRAN_AGENT, - "No need to schedule a dci after all. Just drop it\n"); - harq_pid_updated[UE_id][harq_pid] = 1; - harq_pid_round[UE_id][harq_pid] = 0; - continue; - } - } else { - // No need to create anything apart of DCI in case of retransmission - /*TODO: Must add these */ - // eNB_UE_stats->dlsch_trials[round]++; - //UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission+=1; - //UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx=nb_rb; - //UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_retx+=nb_rb; - //UE_list->eNB_UE_stats[CC_id][UE_id].ncce_used_retx=nCCECC_id]; - } - - // UE_list->UE_template[CC_id][UE_id].oldNDI[dl_dci->harq_process] = dl_dci->ndi[0]; - // eNB_UE_stats->dlsch_mcs1 = dl_dci->mcs[0]; - - //Fill the proper DCI of OAI - flexran_fill_oai_dci(mod_id, CC_id, rnti, dl_dci); - } -} - -void -flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti, - Protocol__FlexDlDci * dl_dci) -{ - - void *DLSCH_dci = NULL; - DCI_PDU *DCI_pdu; - - unsigned char harq_pid = 0; - // unsigned char round = 0; - LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; - int size_bits = 0, size_bytes = 0; - eNB_MAC_INST *eNB = &eNB_mac_inst[mod_id]; - UE_list_t *UE_list = &eNB->UE_list; - LTE_eNB_UE_stats *eNB_UE_stats = NULL; - - int UE_id = find_ue(rnti, PHY_vars_eNB_g[mod_id][CC_id]); - - uint32_t format; - - harq_pid = dl_dci->harq_process; - // round = dl_dci->rv[0]; - - // Note this code is for a specific DCI format - DLSCH_dci = - (void *) UE_list->UE_template[CC_id][UE_id].DLSCH_DCI[harq_pid]; - DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu; - - frame_parms[CC_id] = mac_xface->get_lte_frame_parms(mod_id, CC_id); - - if (dl_dci->has_tpc == 1) { - // Check if tpc has been set and reset measurement */ - if ((dl_dci->tpc == 0) || (dl_dci->tpc == 2)) { - eNB_UE_stats = - mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti); - eNB_UE_stats->Po_PUCCH_update = 0; - } - } - - - switch (frame_parms[CC_id]->N_RB_DL) { - case 6: - if (frame_parms[CC_id]->frame_type == TDD) { - if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) { - FILL_DCI_TDD_1(DCI1_1_5MHz_TDD_t, DLSCH_dci, dl_dci); - size_bytes = sizeof(DCI1_1_5MHz_TDD_t); - size_bits = sizeof_DCI1_1_5MHz_TDD_t; - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) { - //TODO - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) { - //TODO - } - } else { - if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) { - FILL_DCI_FDD_1(DCI1_1_5MHz_FDD_t, DLSCH_dci, dl_dci); - size_bytes = sizeof(DCI1_1_5MHz_FDD_t); - size_bits = sizeof_DCI1_1_5MHz_FDD_t; - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) { - //TODO - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) { - //TODO - } - } - break; - case 25: - if (frame_parms[CC_id]->frame_type == TDD) { - if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) { - FILL_DCI_TDD_1(DCI1_5MHz_TDD_t, DLSCH_dci, dl_dci); - size_bytes = sizeof(DCI1_5MHz_TDD_t); - size_bits = sizeof_DCI1_5MHz_TDD_t; - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) { - //TODO - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) { - //TODO - } - } else { - if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) { - FILL_DCI_FDD_1(DCI1_5MHz_FDD_t, DLSCH_dci, dl_dci); - size_bytes = sizeof(DCI1_5MHz_FDD_t); - size_bits = sizeof_DCI1_5MHz_FDD_t; - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) { - //TODO - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) { - //TODO - } - } - break; - case 50: - if (frame_parms[CC_id]->frame_type == TDD) { - if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) { - FILL_DCI_TDD_1(DCI1_10MHz_TDD_t, DLSCH_dci, dl_dci); - size_bytes = sizeof(DCI1_10MHz_TDD_t); - size_bits = sizeof_DCI1_10MHz_TDD_t; - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) { - //TODO - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) { - //TODO - } - } else { - if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) { - FILL_DCI_FDD_1(DCI1_10MHz_FDD_t, DLSCH_dci, dl_dci); - size_bytes = sizeof(DCI1_10MHz_FDD_t); - size_bits = sizeof_DCI1_10MHz_FDD_t; - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) { - //TODO - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) { - //TODO - } - } - break; - case 100: - if (frame_parms[CC_id]->frame_type == TDD) { - if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) { - FILL_DCI_TDD_1(DCI1_20MHz_TDD_t, DLSCH_dci, dl_dci); - size_bytes = sizeof(DCI1_20MHz_TDD_t); - size_bits = sizeof_DCI1_20MHz_TDD_t; - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) { - //TODO - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) { - //TODO - } - } else { - if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) { - FILL_DCI_FDD_1(DCI1_20MHz_FDD_t, DLSCH_dci, dl_dci); - size_bytes = sizeof(DCI1_20MHz_FDD_t); - size_bits = sizeof_DCI1_20MHz_FDD_t; - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) { - //TODO - } else if (dl_dci->format == - PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) { - //TODO - } - } - break; - } - - //Set format to the proper type - switch (dl_dci->format) { - case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1: - format = format1; - break; - case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1A: - format = format1A; - break; - case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1B: - format = format1B; - break; - case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1C: - format = format1C; - break; - case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D: - format = format1E_2A_M10PRB; - break; - case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2: - format = format2; - break; - case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A: - format = format2A; - break; - case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2B: - format = format2B; - break; - case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_3: - format = 3; - break; - default: - /*TODO: Need to deal with unsupported DCI type */ - return; - } - - add_ue_spec_dci(DCI_pdu, - DLSCH_dci, - rnti, - size_bytes, dl_dci->aggr_level, size_bits, format, 0); -} diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c deleted file mode 100644 index 6445fa0845..0000000000 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c +++ /dev/null @@ -1,1814 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file flexran_agent_scheduler_dlsch_ue.c - * \brief procedures related to eNB for the DLSCH transport channel - * \author Xenofon Foukas, Navid Nikaein and Raymond Knopp - * \date 2016 - * \email: x.foukas@sms.ed.ac.uk - * \version 0.1 - * @ingroup _mac - - */ - -#include "assertions.h" -#include "PHY/defs.h" -#include "PHY/extern.h" - -#include "SCHED/defs.h" -#include "SCHED/extern.h" - -#include "LAYER2/MAC/flexran_agent_mac_proto.h" -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/proto.h" -#include "LAYER2/MAC/extern.h" -#include "UTIL/LOG/log.h" -#include "UTIL/LOG/vcd_signal_dumper.h" -#include "UTIL/OPT/opt.h" -#include "OCG.h" -#include "OCG_extern.h" - -#include "RRC/LITE/extern.h" -#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" - -#include "ENB_APP/flexran_agent_defs.h" -#include "flexran_agent_ran_api.h" -#include "pdcp.h" - -#include "header.pb-c.h" -#include "flexran.pb-c.h" -#include "flexran_agent_mac.h" -#include - -#include "SIMULATION/TOOLS/defs.h" // for taus - -#if defined(ENABLE_ITTI) -#include "intertask_interface.h" -#endif - -#define ENABLE_MAC_PAYLOAD_DEBUG - -/** - * Local variables to support slicing - * - */ - - -/*!\brief UE ULSCH scheduling states*/ -typedef enum { - MIN_SLICE_STRATEGY = 0, - SLICE_MASK, - UEID_TO_SLICEID, - MAX_SLICE_STRATEGY -} SLICING_STRATEGY; - -// this assumes a max of of 16 UE per eNB/CC -#define SLICE0_MASK 0x000f -#define SLICE1_MASK 0x00f0 -#define SLICE2_MASK 0x0f00 -#define SLICE3_MASK 0xf000 - - -// number of active slices for past and current time -int n_active_slices = 1; -int n_active_slices_current = 1; - -// ue to slice mapping -int slicing_strategy = UEID_TO_SLICEID; -int slicing_strategy_current = UEID_TO_SLICEID; - -// RB share for each slice for past and current time -float avg_slice_percentage=0.25; -float slice_percentage[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; -float slice_percentage_current[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; -float total_slice_percentage = 0; -float total_slice_percentage_current = 0; - -// MAX MCS for each slice for past and current time -int slice_maxmcs[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; -int slice_maxmcs_current[MAX_NUM_SLICES] = { 28, 28, 28, 28 }; - -int update_dl_scheduler[MAX_NUM_SLICES] = { 1, 1, 1, 1 }; -int update_dl_scheduler_current[MAX_NUM_SLICES] = { 1, 1, 1, 1 }; - -// name of available scheduler -char *dl_scheduler_type[MAX_NUM_SLICES] = - { "flexran_schedule_ue_spec_embb", - "flexran_schedule_ue_spec_urllc", - "flexran_schedule_ue_spec_mmtc", - "flexran_schedule_ue_spec_be" // best effort -}; - -// pointer to the slice specific scheduler -slice_scheduler_dl slice_sched_dl[MAX_NUM_SLICES] = {0}; - - -/** - * preprocessor functions for scheduling - * - */ - - -// This function stores the downlink buffer for all the logical channels -void -_store_dlsch_buffer(module_id_t Mod_id, - int slice_id, frame_t frameP, sub_frame_t subframeP) -{ - - int UE_id, i; - rnti_t rnti; - mac_rlc_status_resp_t rlc_status; - UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list; - UE_TEMPLATE *UE_template; - - for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { - if (UE_list->active[UE_id] != TRUE) - continue; - - if (flexran_slice_member(UE_id, slice_id) == 0) - continue; - - UE_template = - &UE_list->UE_template[UE_PCCID(Mod_id, UE_id)][UE_id]; - - // clear logical channel interface variables - UE_template->dl_buffer_total = 0; - UE_template->dl_pdus_total = 0; - - for (i = 0; i < MAX_NUM_LCID; i++) { - UE_template->dl_buffer_info[i] = 0; - UE_template->dl_pdus_in_buffer[i] = 0; - UE_template->dl_buffer_head_sdu_creation_time[i] = 0; - UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = 0; - } - - rnti = UE_RNTI(Mod_id, UE_id); - - for (i = 0; i < MAX_NUM_LCID; i++) { // loop over all the logical channels - - rlc_status = - mac_rlc_status_ind(Mod_id, rnti, Mod_id, frameP, subframeP, - ENB_FLAG_YES, MBMS_FLAG_NO, i, 0); - UE_template->dl_buffer_info[i] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel - UE_template->dl_pdus_in_buffer[i] = rlc_status.pdus_in_buffer; - UE_template->dl_buffer_head_sdu_creation_time[i] = - rlc_status.head_sdu_creation_time; - UE_template->dl_buffer_head_sdu_creation_time_max = - cmax(UE_template->dl_buffer_head_sdu_creation_time_max, - rlc_status.head_sdu_creation_time); - UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = - rlc_status.head_sdu_remaining_size_to_send; - UE_template->dl_buffer_head_sdu_is_segmented[i] = - rlc_status.head_sdu_is_segmented; - UE_template->dl_buffer_total += UE_template->dl_buffer_info[i]; //storing the total dlsch buffer - UE_template->dl_pdus_total += - UE_template->dl_pdus_in_buffer[i]; - -#ifdef DEBUG_eNB_SCHEDULER - - /* note for dl_buffer_head_sdu_remaining_size_to_send[i] : - * 0 if head SDU has not been segmented (yet), else remaining size not already segmented and sent - */ - if (UE_template->dl_buffer_info[i] > 0) - LOG_D(MAC, - "[eNB %d][SLICE %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and size %d, head sdu queuing time %d, remaining size %d, is segmeneted %d \n", - Mod_id, slice_id, frameP, subframeP, UE_id, - i, UE_template->dl_pdus_in_buffer[i], - UE_template->dl_buffer_info[i], - UE_template->dl_buffer_head_sdu_creation_time[i], - UE_template-> - dl_buffer_head_sdu_remaining_size_to_send[i], - UE_template->dl_buffer_head_sdu_is_segmented[i]); - -#endif - - } - - //#ifdef DEBUG_eNB_SCHEDULER - if (UE_template->dl_buffer_total > 0) - LOG_D(MAC, - "[eNB %d] Frame %d Subframe %d : RLC status for UE %d : total DL buffer size %d and total number of pdu %d \n", - Mod_id, frameP, subframeP, UE_id, - UE_template->dl_buffer_total, - UE_template->dl_pdus_total); - - //#endif - } -} - - -// This function returns the estimated number of RBs required by each UE for downlink scheduling -void -_assign_rbs_required(module_id_t Mod_id, - int slice_id, - frame_t frameP, - sub_frame_t subframe, - uint16_t - nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], - uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs] - [MAX_NUM_SLICES], int min_rb_unit[MAX_NUM_CCs]) -{ - - - rnti_t rnti; - uint16_t TBS = 0; - LTE_eNB_UE_stats *eNB_UE_stats[MAX_NUM_CCs]; - int UE_id, n, i, j, CC_id, pCCid, tmp; - UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list; - // UE_TEMPLATE *UE_template; - - // clear rb allocations across all CC_ids - for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { - if (UE_list->active[UE_id] != TRUE) - continue; - - if (flexran_slice_member(UE_id, slice_id) == 0) - continue; - - pCCid = UE_PCCID(Mod_id, UE_id); - rnti = UE_list->UE_template[pCCid][UE_id].rnti; - - /* skip UE not present in PHY (for any of its active CCs) */ - if (!phy_stats_exist(Mod_id, rnti)) - continue; - - //update CQI information across component carriers - for (n = 0; n < UE_list->numactiveCCs[UE_id]; n++) { - CC_id = UE_list->ordered_CCids[n][UE_id]; - eNB_UE_stats[CC_id] = - mac_xface->get_eNB_UE_stats(Mod_id, CC_id, rnti); - eNB_UE_stats[CC_id]->dlsch_mcs1 = - cqi_to_mcs[flexran_get_ue_wcqi(Mod_id, UE_id)]; - } - - // provide the list of CCs sorted according to MCS - for (i = 0; i < UE_list->numactiveCCs[UE_id]; i++) { - for (j = i + 1; j < UE_list->numactiveCCs[UE_id]; j++) { - DevAssert(j < MAX_NUM_CCs); - - if (eNB_UE_stats[UE_list->ordered_CCids[i][UE_id]]-> - dlsch_mcs1 > - eNB_UE_stats[UE_list->ordered_CCids[j][UE_id]]-> - dlsch_mcs1) { - tmp = UE_list->ordered_CCids[i][UE_id]; - UE_list->ordered_CCids[i][UE_id] = - UE_list->ordered_CCids[j][UE_id]; - UE_list->ordered_CCids[j][UE_id] = tmp; - } - } - } - /* NN --> RK - * check the index of UE_template" - */ - if (UE_list->UE_template[pCCid][UE_id].dl_buffer_total> 0) { - LOG_D(MAC,"[preprocessor] assign RB for UE %d\n",UE_id); - - for (i=0; inumactiveCCs[UE_id]; i++) { - CC_id = UE_list->ordered_CCids[i][UE_id]; - eNB_UE_stats[CC_id] = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti); - - if (cqi_to_mcs[flexran_get_ue_wcqi(Mod_id, UE_id)] == 0) {//eNB_UE_stats[CC_id]->dlsch_mcs1==0) { - nb_rbs_required[CC_id][UE_id] = 4; // don't let the TBS get too small - } else { - nb_rbs_required[CC_id][UE_id] = min_rb_unit[CC_id]; - } - - TBS = mac_xface->get_TBS_DL(cqi_to_mcs[flexran_get_ue_wcqi(Mod_id, UE_id)], nb_rbs_required[CC_id][UE_id]); - nb_rbs_allowed_slice[CC_id][slice_id] = flexran_nb_rbs_allowed_slice(slice_percentage[slice_id], - flexran_get_N_RB_DL(Mod_id, CC_id)); - LOG_D(MAC,"[preprocessor] start RB assignement for UE %d CC_id %d dl buffer %d (RB unit %d, MCS %d, TBS %d) \n", - UE_id, CC_id, UE_list->UE_template[pCCid][UE_id].dl_buffer_total, - nb_rbs_required[CC_id][UE_id], flexran_get_ue_wcqi(Mod_id, UE_id), TBS); - - /* calculating required number of RBs for each UE */ - while (TBS < UE_list->UE_template[pCCid][UE_id].dl_buffer_total) { - nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id]; - - if (nb_rbs_required[CC_id][UE_id] > nb_rbs_allowed_slice[CC_id][slice_id]) { - TBS = mac_xface->get_TBS_DL(cqi_to_mcs[flexran_get_ue_wcqi(Mod_id, UE_id)], nb_rbs_allowed_slice[CC_id][slice_id]); - nb_rbs_required[CC_id][UE_id] = nb_rbs_allowed_slice[CC_id][slice_id]; - break; - } - - TBS = mac_xface->get_TBS_DL(cqi_to_mcs[flexran_get_ue_wcqi(Mod_id, UE_id)], nb_rbs_required[CC_id][UE_id]); - } // end of while - - LOG_D(MAC,"[eNB %d][SLICE %d] Frame %d: UE %d on CC %d: RB unit %d, nb_required RB %d (TBS %d, mcs %d)\n", - Mod_id, slice_id,frameP,UE_id, CC_id, min_rb_unit[CC_id], nb_rbs_required[CC_id][UE_id], TBS, cqi_to_mcs[flexran_get_ue_wcqi(Mod_id, UE_id)]); - } - } - } -} - -void -_dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, - int UE_id, - uint8_t CC_id, - int N_RBG, - int transmission_mode, - int min_rb_unit, - uint8_t N_RB_DL, - uint16_t - nb_rbs_required[MAX_NUM_CCs] - [NUMBER_OF_UE_MAX], - uint16_t - nb_rbs_required_remaining - [MAX_NUM_CCs] - [NUMBER_OF_UE_MAX], unsigned char - rballoc_sub[MAX_NUM_CCs] - [N_RBG_MAX], unsigned char - MIMO_mode_indicator - [MAX_NUM_CCs][N_RBG_MAX]) -{ - int i; - UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list; - UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - - for (i = 0; i < N_RBG; i++) { - - if ((rballoc_sub[CC_id][i] == 0) && - (ue_sched_ctl->rballoc_sub_UE[CC_id][i] == 0) && - (nb_rbs_required_remaining[CC_id][UE_id] > 0) && - (ue_sched_ctl->pre_nb_available_rbs[CC_id] < - nb_rbs_required[CC_id][UE_id])) { - - // if this UE is not scheduled for TM5 - if (ue_sched_ctl->dl_pow_off[CC_id] != 0) { - - if ((i == N_RBG - 1) - && ((N_RB_DL == 25) || (N_RB_DL == 50))) { - rballoc_sub[CC_id][i] = 1; - ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1; - MIMO_mode_indicator[CC_id][i] = 1; - if (transmission_mode == 5) { - ue_sched_ctl->dl_pow_off[CC_id] = 1; - } - nb_rbs_required_remaining[CC_id][UE_id] = - nb_rbs_required_remaining[CC_id][UE_id] - - min_rb_unit + 1; - ue_sched_ctl->pre_nb_available_rbs[CC_id] = - ue_sched_ctl->pre_nb_available_rbs[CC_id] + - min_rb_unit - 1; - } else { - if (nb_rbs_required_remaining[CC_id][UE_id] >= - min_rb_unit) { - rballoc_sub[CC_id][i] = 1; - ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1; - MIMO_mode_indicator[CC_id][i] = 1; - if (transmission_mode == 5) { - ue_sched_ctl->dl_pow_off[CC_id] = 1; - } - nb_rbs_required_remaining[CC_id][UE_id] = - nb_rbs_required_remaining[CC_id][UE_id] - - min_rb_unit; - ue_sched_ctl->pre_nb_available_rbs[CC_id] = - ue_sched_ctl->pre_nb_available_rbs[CC_id] + - min_rb_unit; - } - } - } // dl_pow_off[CC_id][UE_id] ! = 0 - } - } -} - -void -_dlsch_scheduler_pre_processor_reset(int module_idP, - int UE_id, - uint8_t CC_id, - int frameP, - int subframeP, - int N_RBG, - uint16_t nb_rbs_required[MAX_NUM_CCs] - [NUMBER_OF_UE_MAX], - uint16_t - nb_rbs_required_remaining - [MAX_NUM_CCs][NUMBER_OF_UE_MAX], - uint16_t - nb_rbs_allowed_slice[MAX_NUM_CCs] - [MAX_NUM_SLICES], unsigned char - rballoc_sub[MAX_NUM_CCs] - [N_RBG_MAX], unsigned char - MIMO_mode_indicator[MAX_NUM_CCs] - [N_RBG_MAX]) -{ - int i, j; - UE_list_t *UE_list = &eNB_mac_inst[module_idP].UE_list; - UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - uint8_t *vrb_map = - eNB_mac_inst[module_idP].common_channels[CC_id].vrb_map; - int RBGsize = - PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.N_RB_DL / N_RBG; -#ifdef SF05_LIMIT - //int subframe05_limit=0; - int sf05_upper = -1, sf05_lower = -1; -#endif - // LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti); - - flexran_update_TA(module_idP, UE_id, CC_id); - - if (UE_id == 0) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME - (VCD_SIGNAL_DUMPER_VARIABLES_UE0_TIMING_ADVANCE, - ue_sched_ctl->ta_update); - } - nb_rbs_required[CC_id][UE_id] = 0; - ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0; - ue_sched_ctl->dl_pow_off[CC_id] = 2; - nb_rbs_required_remaining[CC_id][UE_id] = 0; - for (i = 0; i < n_active_slices; i++) - nb_rbs_allowed_slice[CC_id][i] = 0; -#ifdef SF05_LIMIT - switch (N_RBG) { - case 6: - sf05_lower = 0; - sf05_upper = 5; - break; - case 8: - sf05_lower = 2; - sf05_upper = 5; - break; - case 13: - sf05_lower = 4; - sf05_upper = 7; - break; - case 17: - sf05_lower = 7; - sf05_upper = 9; - break; - case 25: - sf05_lower = 11; - sf05_upper = 13; - break; - } -#endif - // Initialize Subbands according to VRB map - for (i = 0; i < N_RBG; i++) { - ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0; - rballoc_sub[CC_id][i] = 0; -#ifdef SF05_LIMIT - // for avoiding 6+ PRBs around DC in subframe 0-5 (avoid excessive errors) - - if ((subframeP == 0 || subframeP == 5) && - (i >= sf05_lower && i <= sf05_upper)) - rballoc_sub[CC_id][i] = 1; -#endif - // for SI-RNTI,RA-RNTI and P-RNTI allocations - for (j = 0; j < RBGsize; j++) { - if (vrb_map[j + (i * RBGsize)] != 0) { - rballoc_sub[CC_id][i] = 1; - LOG_D(MAC, "Frame %d, subframe %d : vrb %d allocated\n", - frameP, subframeP, j + (i * RBGsize)); - break; - } - } - LOG_D(MAC, "Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n", - frameP, subframeP, CC_id, i, rballoc_sub[CC_id][i]); - MIMO_mode_indicator[CC_id][i] = 2; - } -} - -// This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done -void -_dlsch_scheduler_pre_processor(module_id_t Mod_id, - int slice_id, - frame_t frameP, - sub_frame_t subframeP, - int N_RBG[MAX_NUM_CCs], int *mbsfn_flag) -{ - - unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], total_ue_count; - unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]; - int UE_id, i; - uint8_t round = 0; - uint8_t harq_pid = 0; - uint16_t ii, j; - uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES]; - uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - uint16_t nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - uint16_t average_rbs_per_user[MAX_NUM_CCs] = { 0 }; - rnti_t rnti; - int min_rb_unit[MAX_NUM_CCs]; - uint16_t r1 = 0; - uint8_t CC_id; - UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list; - LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs] = { 0 }; - - int transmission_mode = 0; - UE_sched_ctrl *ue_sched_ctl; - - - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - - if (mbsfn_flag[CC_id] > 0) // If this CC is allocated for MBSFN skip it here - continue; - - frame_parms[CC_id] = mac_xface->get_lte_frame_parms(Mod_id, CC_id); - - - min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id); - - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { - if (UE_list->active[i] != TRUE) - continue; - - UE_id = i; - // Initialize scheduling information for all active UEs - - //if (flexran_slice_member(UE_id, slice_id) == 0) - //continue; - _dlsch_scheduler_pre_processor_reset(Mod_id, - UE_id, - CC_id, - frameP, - subframeP, - N_RBG[CC_id], - nb_rbs_required, - nb_rbs_required_remaining, - nb_rbs_allowed_slice, - rballoc_sub, - MIMO_mode_indicator); - - } - } - - - /* Store the DLSCH buffer for each logical channel for each UE */ - _store_dlsch_buffer (Mod_id,slice_id,frameP,subframeP); - - // Calculate the number of RBs required by each UE on the basis of logical channel's buffer - _assign_rbs_required (Mod_id,slice_id, frameP,subframeP,nb_rbs_required,nb_rbs_allowed_slice,min_rb_unit); - - // Sorts the user on the basis of dlsch logical channel buffer and CQI - sort_UEs (Mod_id,frameP,subframeP); - - total_ue_count = 0; - - // loop over all active UEs - for (i=UE_list->head; i>=0; i=UE_list->next[i]) { - rnti = flexran_get_ue_crnti(Mod_id, i); - if(rnti == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; - - UE_id = i; - - if (flexran_slice_member(UE_id, slice_id) == 0) - continue; - - if (!phy_stats_exist(Mod_id, rnti)) - continue; - - for (ii=0; ii < UE_num_active_CC(UE_list,UE_id); ii++) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - ue_sched_ctl->max_allowed_rbs[CC_id]=nb_rbs_allowed_slice[CC_id][slice_id]; - flexran_get_harq(Mod_id, CC_id, UE_id, frameP, subframeP, &harq_pid, &round, openair_harq_DL); - - // if there is no available harq_process, skip the UE - if (UE_list->UE_sched_ctrl[UE_id].harq_pid[CC_id]<0) - continue; - - average_rbs_per_user[CC_id]=0; - - frame_parms[CC_id] = mac_xface->get_lte_frame_parms(Mod_id,CC_id); - - // mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0); - - if(round>0) { - nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - } - - //nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id]; - if (nb_rbs_required[CC_id][UE_id] > 0) { - total_ue_count = total_ue_count + 1; - } - - - // hypotetical assignement - /* - * If schedule is enabled and if the priority of the UEs is modified - * The average rbs per logical channel per user will depend on the level of - * priority. Concerning the hypothetical assignement, we should assign more - * rbs to prioritized users. Maybe, we can do a mapping between the - * average rbs per user and the level of priority or multiply the average rbs - * per user by a coefficient which represents the degree of priority. - */ - - if (total_ue_count == 0) { - average_rbs_per_user[CC_id] = 0; - } else if( (min_rb_unit[CC_id] * total_ue_count) <= nb_rbs_allowed_slice[CC_id][slice_id] ) { - average_rbs_per_user[CC_id] = (uint16_t) floor(nb_rbs_allowed_slice[CC_id][slice_id]/total_ue_count); - } else { - average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; // consider the total number of use that can be scheduled UE - } - } - } - - // note: nb_rbs_required is assigned according to total_buffer_dl - // extend nb_rbs_required to capture per LCID RB required - for(i=UE_list->head; i>=0; i=UE_list->next[i]) { - rnti = UE_RNTI(Mod_id,i); - - if(rnti == NOT_A_RNTI) - continue; - - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; - - if (!phy_stats_exist(Mod_id, rnti)) - continue; - - if (flexran_slice_member(i, slice_id) == 0) - continue; - - for (ii=0; iiordered_CCids[ii][i]; - - // control channel - if (mac_eNB_get_rrc_status(Mod_id,rnti) < RRC_RECONFIGURED) { - nb_rbs_required_remaining_1[CC_id][i] = nb_rbs_required[CC_id][i]; - } else { - nb_rbs_required_remaining_1[CC_id][i] = cmin(average_rbs_per_user[CC_id],nb_rbs_required[CC_id][i]); - - } - } - - // note: nb_rbs_required is assigned according to total_buffer_dl - // extend nb_rbs_required to capture per LCID RB required - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - rnti = UE_RNTI(Mod_id, i); - - if (rnti == NOT_A_RNTI) - continue; - - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; - - if (!phy_stats_exist(Mod_id, rnti)) - continue; - - if (flexran_slice_member(i, slice_id) == 0) - continue; - - for (ii = 0; ii < UE_num_active_CC(UE_list, i); ii++) { - CC_id = UE_list->ordered_CCids[ii][i]; - - // control channel - if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED) { - nb_rbs_required_remaining_1[CC_id][i] = - nb_rbs_required[CC_id][i]; - } else { - nb_rbs_required_remaining_1[CC_id][i] = - cmin(average_rbs_per_user[CC_id], - nb_rbs_required[CC_id][i]); - - } - } - } - - //Allocation to UEs is done in 2 rounds, - // 1st stage: average number of RBs allocated to each UE - // 2nd stage: remaining RBs are allocated to high priority UEs - for (r1 = 0; r1 < 2; r1++) { - - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - - if (flexran_slice_member(i, slice_id) == 0) - continue; - - for (ii = 0; ii < UE_num_active_CC(UE_list, i); ii++) { - CC_id = UE_list->ordered_CCids[ii][i]; - - if (r1 == 0) { - nb_rbs_required_remaining[CC_id][i] = - nb_rbs_required_remaining_1[CC_id][i]; - } else { // rb required based only on the buffer - rb allloctaed in the 1st round + extra reaming rb form the 1st round - nb_rbs_required_remaining[CC_id][i] = - nb_rbs_required[CC_id][i] - - nb_rbs_required_remaining_1[CC_id][i] + - nb_rbs_required_remaining[CC_id][i]; - } - - if (nb_rbs_required[CC_id][i] > 0) - LOG_D(MAC, - "round %d : nb_rbs_required_remaining[%d][%d]= %d (remaining_1 %d, required %d, pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n", - r1, CC_id, i, - nb_rbs_required_remaining[CC_id][i], - nb_rbs_required_remaining_1[CC_id][i], - nb_rbs_required[CC_id][i], - UE_list->UE_sched_ctrl[i]. - pre_nb_available_rbs[CC_id], N_RBG[CC_id], - min_rb_unit[CC_id]); - - } - } - - if (total_ue_count > 0) { - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - UE_id = i; - - if (flexran_slice_member(UE_id, slice_id) == 0) - continue; - - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - flexran_get_harq(Mod_id, CC_id, UE_id, frameP, - subframeP, &harq_pid, &round); - rnti = UE_RNTI(Mod_id, UE_id); - - // LOG_D(MAC,"UE %d rnti 0x\n", UE_id, rnti ); - if (rnti == NOT_A_RNTI) - continue; - - if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) - continue; - - if (!phy_stats_exist(Mod_id, rnti)) - continue; - - transmission_mode = - mac_xface->get_transmission_mode(Mod_id, CC_id, - rnti); - //rrc_status = mac_eNB_get_rrc_status(Mod_id,rnti); - /* 1st allocate for the retx */ - - // retransmission in data channels - // control channel in the 1st transmission - // data channel for all TM - LOG_T(MAC, - "calling dlsch_scheduler_pre_processor_allocate .. \n "); - _dlsch_scheduler_pre_processor_allocate(Mod_id, UE_id, - CC_id, - N_RBG[CC_id], - transmission_mode, - min_rb_unit - [CC_id], - frame_parms - [CC_id]-> - N_RB_DL, - nb_rbs_required, - nb_rbs_required_remaining, - rballoc_sub, - MIMO_mode_indicator); - } - } - } // total_ue_count - } // end of for for r1 and r2 - - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - UE_id = i; - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - - if (flexran_slice_member(UE_id, slice_id) == 0) - continue; - - for (ii=0; iiordered_CCids[ii][UE_id]; - flexran_get_harq(Mod_id, CC_id, UE_id, frameP, subframeP, &harq_pid, &round, openair_harq_DL); - rnti = UE_RNTI(Mod_id,UE_id); - - // LOG_D(MAC,"UE %d rnti 0x\n", UE_id, rnti ); - if(rnti == NOT_A_RNTI) - continue; - - if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) - continue; - - if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0) { - LOG_D(MAC, - "******************DL Scheduling Information for UE%d ************************\n", - UE_id); - LOG_D(MAC, "dl power offset UE%d = %d \n", UE_id, - ue_sched_ctl->dl_pow_off[CC_id]); - LOG_D(MAC, - "***********RB Alloc for every subband for UE%d ***********\n", - UE_id); - - for (j = 0; j < N_RBG[CC_id]; j++) { - //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[i] = rballoc_sub_UE[CC_id][UE_id][i]; - LOG_D(MAC, "RB Alloc for UE%d and Subband%d = %d\n", - UE_id, j, - ue_sched_ctl->rballoc_sub_UE[CC_id][j]); - } - - //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id]; - LOG_D(MAC, - "[eNB %d][SLICE %d] Total RBs allocated for UE%d = %d\n", - Mod_id, slice_id, UE_id, - ue_sched_ctl->pre_nb_available_rbs[CC_id]); - } - } - } - } -} - -#define SF05_LIMIT 1 - -/* - * Main Downlink Slicing - * - */ - -void -flexran_schedule_ue_dl_spec_default(mid_t mod_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage **dl_info) -//------------------------------------------------------------------------------ -{ - int i=0; - - flexran_agent_mac_create_empty_dl_config(mod_id, dl_info); - - total_slice_percentage=0; - avg_slice_percentage=1.0/n_active_slices; - - // reset the slice percentage for inactive slices - for (i = n_active_slices; i< MAX_NUM_SLICES; i++) { - slice_percentage[i]=0; - } - for (i = 0; i < n_active_slices; i++) { - if (slice_percentage[i] < 0 ){ - LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero", - mod_id, frame, subframe, i, slice_percentage[i]); - slice_percentage[i]=0; - } - total_slice_percentage+=slice_percentage[i]; - } - - for (i = 0; i < n_active_slices; i++) { - - // Load any updated functions - if (update_dl_scheduler[i] > 0 ) { - slice_sched_dl[i] = dlsym(NULL, dl_scheduler_type[i]); - update_dl_scheduler[i] = 0; - update_dl_scheduler_current[i] = 0; - LOG_N(MAC,"update dl scheduler slice %d\n", i); - } - - if (total_slice_percentage <= 1.0){ // the new total RB share is within the range - - // check if the number of slices has changed, and log - if (n_active_slices_current != n_active_slices ){ - if ((n_active_slices > 0) && (n_active_slices <= MAX_NUM_SLICES)) { - LOG_N(MAC,"[eNB %d]frame %d subframe %d: number of active DL slices has changed: %d-->%d\n", - mod_id, frame, subframe, n_active_slices_current, n_active_slices); - - n_active_slices_current = n_active_slices; - - } else { - LOG_W(MAC,"invalid number of DL slices %d, revert to the previous value %d\n",n_active_slices, n_active_slices_current); - n_active_slices = n_active_slices_current; - } - } - - // check if the slice rb share has changed, and log the console - if (slice_percentage_current[i] != slice_percentage[i]){ // new slice percentage - LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", - mod_id, i, frame, subframe, total_slice_percentage_current, total_slice_percentage, slice_percentage_current[i], slice_percentage[i]); - total_slice_percentage_current= total_slice_percentage; - slice_percentage_current[i] = slice_percentage[i]; - - } - - // check if the slice max MCS, and log the console - if (slice_maxmcs_current[i] != slice_maxmcs[i]){ - if ((slice_maxmcs[i] >= 0) && (slice_maxmcs[i] < 29)){ - LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", - mod_id, i, frame, subframe, slice_maxmcs_current[i], slice_maxmcs[i]); - slice_maxmcs_current[i] = slice_maxmcs[i]; - } else { - LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid slice max mcs %d, revert the previous value %d\n",mod_id, i, slice_maxmcs[i],slice_maxmcs_current[i]); - slice_maxmcs[i]= slice_maxmcs_current[i]; - } - } - - // check if a new scheduler, and log the console - if (update_dl_scheduler_current[i] != update_dl_scheduler[i]){ - LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: DL scheduler for this slice is updated: %s \n", - mod_id, i, frame, subframe, dl_scheduler_type[i]); - update_dl_scheduler_current[i] = update_dl_scheduler[i]; - } - - } else { - // here we can correct the values, e.g. reduce proportionally - - if (n_active_slices == n_active_slices_current){ - LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n", - mod_id,i, - total_slice_percentage_current, total_slice_percentage); - if (slice_percentage[i] >= avg_slice_percentage){ - slice_percentage[i]-=0.1; - total_slice_percentage-=0.1; - } - } else { - LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n", - mod_id,i, - total_slice_percentage_current, total_slice_percentage, - n_active_slices, n_active_slices_current ); - n_active_slices = n_active_slices_current; - slice_percentage[i] = slice_percentage_current[i]; - } - } - - // Run each enabled slice-specific schedulers one by one - slice_sched_dl[i](mod_id, i, frame, subframe, mbsfn_flag,dl_info); - } -} - -uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, int total_rbs) -{ - return (uint16_t) floor(rb_percentage * total_rbs); -} - -int flexran_slice_maxmcs(int slice_id) -{ - return slice_maxmcs[slice_id]; -} - -int flexran_slice_member(int UE_id, int slice_id) -{ - // group membership definition - int slice_member = 0; - - if ((slice_id < 0) || (slice_id > n_active_slices)) - LOG_W(MAC, "out of range slice id %d\n", slice_id); - - switch (slicing_strategy) { - case SLICE_MASK: - switch (slice_id) { - case 0: - if (SLICE0_MASK & UE_id) { - slice_member = 1; - } - break; - case 1: - if (SLICE1_MASK & UE_id) { - slice_member = 1; - } - break; - case 2: - if (SLICE2_MASK & UE_id) { - slice_member = 1; - } - break; - case 3: - if (SLICE3_MASK & UE_id) { - slice_member = 1; - } - break; - default: - LOG_W(MAC, "unknown slice_id %d\n", slice_id); - break; - - } - break; - case UEID_TO_SLICEID: - default: - if ((UE_id % n_active_slices) == slice_id) { - slice_member = 1; // this ue is a member of this slice - } - break; - } - - return slice_member; -} - -/* more aggressive rb and mcs allocation with medium priority and the traffic qci */ -void -flexran_schedule_ue_spec_embb(mid_t mod_id, - int slice_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info) -{ - flexran_schedule_ue_dl_spec_common(mod_id, - slice_id, - frame, - subframe, - mbsfn_flag, - dl_info); -} - -/* more conservative mcs allocation with high priority and the traffic qci */ -void -flexran_schedule_ue_spec_urllc(mid_t mod_id, - int slice_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info) -{ - flexran_schedule_ue_dl_spec_common(mod_id, - slice_id, - frame, - subframe, - mbsfn_flag, - dl_info); -} - -/* constant rb allocation with low mcs with low priority and given the UE capabilities */ -void -flexran_schedule_ue_spec_mmtc(mid_t mod_id, - int slice_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info) -{ - flexran_schedule_ue_dl_spec_common(mod_id, - slice_id, - frame, - subframe, - mbsfn_flag, - dl_info); -} - -/* regular rb and mcs allocation with low priority */ -void -flexran_schedule_ue_spec_be(mid_t mod_id, - int slice_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info) -{ - flexran_schedule_ue_dl_spec_common(mod_id, - slice_id, - frame, - subframe, - mbsfn_flag, - dl_info); -} - -//------------------------------------------------------------------------------ -void -flexran_schedule_ue_dl_spec_common(mid_t mod_id, - int slice_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag, - Protocol__FlexranMessage **dl_info) -//------------------------------------------------------------------------------ -{ - uint8_t CC_id; - int UE_id; - int N_RBG[MAX_NUM_CCs]; - unsigned char aggregation; - mac_rlc_status_resp_t rlc_status; - unsigned char header_len = 0, header_len_last = 0, ta_len = 0; - uint16_t nb_rb, nb_rb_temp, total_nb_available_rb[MAX_NUM_CCs], - nb_available_rb; - uint16_t TBS, j, rnti; - uint8_t round = 0; - uint8_t harq_pid = 0; - uint16_t sdu_length_total = 0; - int mcs, mcs_tmp; - uint16_t min_rb_unit[MAX_NUM_CCs]; - eNB_MAC_INST *eNB = &eNB_mac_inst[mod_id]; - /* TODO: Must move the helper structs to scheduler implementation */ - UE_list_t *UE_list = &eNB->UE_list; - int32_t normalized_rx_power, target_rx_power; - int32_t tpc = 1; - static int32_t tpc_accumulated = 0; - UE_sched_ctrl *ue_sched_ctl; - LTE_eNB_UE_stats *eNB_UE_stats = NULL; - Protocol__FlexDlData *dl_data[NUM_MAX_UE]; - int num_ues_added = 0; - int channels_added = 0; - - Protocol__FlexDlDci *dl_dci; - Protocol__FlexRlcPdu *rlc_pdus[11]; - uint32_t ce_flags = 0; - - uint8_t rballoc_sub[25]; - int i; - uint32_t data_to_request; - uint32_t dci_tbs; - uint8_t ue_has_transmission = 0; - uint32_t ndi; - -#if 0 - - if (UE_list->head == -1) { - return; - } -#endif - - start_meas(&eNB->schedule_dlsch); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,VCD_FUNCTION_IN); - - //weight = get_ue_weight(module_idP,UE_id); - aggregation = 1; // set to the maximum aggregation level - - for (CC_id=0; CC_idcommon_channels[CC_id].vrb_map[i] != 0) - total_nb_available_rb[CC_id]--; - - N_RBG[CC_id] = flexran_get_N_RBG(mod_id, CC_id); - - // store the global enb stats: - eNB->eNB_stats[CC_id].num_dlactive_UEs = UE_list->num_UEs; - eNB->eNB_stats[CC_id].available_prbs = total_nb_available_rb[CC_id]; - eNB->eNB_stats[CC_id].total_available_prbs += total_nb_available_rb[CC_id]; - eNB->eNB_stats[CC_id].dlsch_bytes_tx=0; - eNB->eNB_stats[CC_id].dlsch_pdus_tx=0; - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,VCD_FUNCTION_IN); - - start_meas(&eNB->schedule_dlsch_preprocessor); - _dlsch_scheduler_pre_processor(mod_id, - slice_id, - frame, - subframe, - N_RBG, - mbsfn_flag); - stop_meas(&eNB->schedule_dlsch_preprocessor); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,VCD_FUNCTION_OUT); - - for (CC_id=0; CC_id0) - continue; - - for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { - - rnti = flexran_get_ue_crnti(mod_id, UE_id); - eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id,CC_id,rnti); - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - - if (eNB_UE_stats==NULL) { - - LOG_D(MAC,"[eNB] Cannot find eNB_UE_stats\n"); - // mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n"); - continue; - } - - if (flexran_slice_member(UE_id, slice_id) == 0) - continue; - - if (rnti==NOT_A_RNTI) { - LOG_D(MAC,"Cannot find rnti for UE_id %d (num_UEs %d)\n", UE_id,UE_list->num_UEs); - // mac_xface->macphy_exit("Cannot find rnti for UE_id"); - continue; - } - - switch(mac_xface->get_transmission_mode(mod_id,CC_id,rnti)){ - case 1: - case 2: - case 7: - aggregation = get_aggregation(get_bw_index(mod_id,CC_id), - eNB_UE_stats->DL_cqi[0], - format1); - break; - case 3: - aggregation = get_aggregation(get_bw_index(mod_id,CC_id), - eNB_UE_stats->DL_cqi[0], - format2A); - break; - default: - LOG_W(MAC,"Unsupported transmission mode %d\n", mac_xface->get_transmission_mode(mod_id,CC_id,rnti)); - aggregation = 2; - } - - if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated - CCE_allocation_infeasible(mod_id, CC_id, 0, subframe, aggregation, rnti)) { - - LOG_D(MAC,"[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n", - mod_id, frame, UE_id, CC_id); - //if(mac_xface->get_transmission_mode(module_idP,rnti)==5) - continue; //to next user (there might be rbs availiable for other UEs in TM5 - // else - // break; - } - - if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { - set_ue_dai (subframe, - flexran_get_subframe_assignment(mod_id, CC_id), - UE_id, - CC_id, - UE_list); - //TODO: update UL DAI after DLSCH scheduling - //set_ul_DAI(mod_id, UE_id, CC_id, frame, subframe,frame_parms); - } - - channels_added = 0; - - // After this point all the UEs will be scheduled - dl_data[num_ues_added] = (Protocol__FlexDlData *) malloc(sizeof(Protocol__FlexDlData)); - protocol__flex_dl_data__init(dl_data[num_ues_added]); - dl_data[num_ues_added]->has_rnti = 1; - dl_data[num_ues_added]->rnti = rnti; - dl_data[num_ues_added]->n_rlc_pdu = 0; - dl_data[num_ues_added]->has_serv_cell_index = 1; - dl_data[num_ues_added]->serv_cell_index = CC_id; - - flexran_get_harq(mod_id, CC_id, UE_id, frame, subframe, &harq_pid, &round, openair_harq_DL); - sdu_length_total=0; - mcs = cqi_to_mcs[flexran_get_ue_wcqi(mod_id, UE_id)]; - // LOG_I(FLEXRAN_AGENT, "The MCS is %d\n", mcs); - mcs = cmin(mcs,flexran_slice_maxmcs(slice_id)); -// #ifdef EXMIMO - -// if (mac_xface->get_transmission_mode(mod_id, CC_id, rnti) == 5) { -// mcs = cqi_to_mcs[flexran_get_ue_wcqi(mod_id, UE_id)]; -// mcs = cmin(mcs,16); -// } - -// #endif - - /*Get pre available resource blocks based on buffers*/ - nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id]; - // initializing the rb allocation indicator for each UE - for(j = 0; j < flexran_get_N_RBG(mod_id, CC_id); j++) { - - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = 0; - rballoc_sub[j] = 0; - } - - /* LOG_D(MAC,"[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n", */ - /* mod_id, frame, UE_id, CC_id, rnti, harq_pid, round, nb_available_rb, */ - /* eNB_UE_stats->DL_cqi[0], mcs, */ - /* UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status); */ - - dl_dci = (Protocol__FlexDlDci*) malloc(sizeof(Protocol__FlexDlDci)); - protocol__flex_dl_dci__init(dl_dci); - dl_data[num_ues_added]->dl_dci = dl_dci; - - - dl_dci->has_rnti = 1; - dl_dci->rnti = rnti; - dl_dci->has_harq_process = 1; - dl_dci->harq_process = harq_pid; - - /* process retransmission */ - if (round > 0) { - - LOG_D(FLEXRAN_AGENT, "There was a retransmission just now and the round was %d\n", round); - - if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { - UE_list->UE_template[CC_id][UE_id].DAI++; - update_ul_dci(mod_id, CC_id, rnti, UE_list->UE_template[CC_id][UE_id].DAI); - LOG_D(MAC,"DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n", - CC_id, subframe,UE_id,UE_list->UE_template[CC_id][UE_id].DAI); - } - - mcs = UE_list->UE_template[CC_id][UE_id].mcs[harq_pid]; - - // get freq_allocation - nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - - /*TODO: Must add this to FlexRAN agent API */ - dci_tbs = mac_xface->get_TBS_DL(mcs, nb_rb); - - if (nb_rb <= nb_available_rb) { - - if(nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { - for(j = 0; j < flexran_get_N_RBG(mod_id, CC_id); j++) { // for indicating the rballoc for each sub-band - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - } - } else { - nb_rb_temp = nb_rb; - j = 0; - - while((nb_rb_temp > 0) && (j < flexran_get_N_RBG(mod_id, CC_id))) { - if(ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - - if((j == flexran_get_N_RBG(mod_id, CC_id) - 1) && - ((flexran_get_N_RB_DL(mod_id, CC_id) == 25)|| - (flexran_get_N_RB_DL(mod_id, CC_id) == 50))) { - nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]+1; - } else { - nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; - } - } - j = j + 1; - } - } - - nb_available_rb -= nb_rb; - PHY_vars_eNB_g[mod_id][CC_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; - PHY_vars_eNB_g[mod_id][CC_id]->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; - - for(j=0; j < flexran_get_N_RBG(mod_id, CC_id); j++) { - PHY_vars_eNB_g[mod_id][CC_id]->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; - rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; - } - - // Keep the old NDI, do not toggle - ndi = UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; - tpc = UE_list->UE_template[CC_id][UE_id].oldTPC[harq_pid]; - UE_list->UE_template[CC_id][UE_id].mcs[harq_pid] = mcs; - - ue_has_transmission = 1; - num_ues_added++; - } else { - LOG_D(MAC,"[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n", - mod_id, frame, CC_id, UE_id); - ue_has_transmission = 0; - } - //End of retransmission - } - - else { /* This is a potentially new SDU opportunity */ - rlc_status.bytes_in_buffer = 0; - // Now check RLC information to compute number of required RBs - // get maximum TBS size for RLC request - //TBS = mac_xface->get_TBS(eNB_UE_stats->DL_cqi[0]<<1,nb_available_rb); - TBS = mac_xface->get_TBS_DL(mcs, nb_available_rb); - dci_tbs = TBS; - LOG_D(FLEXRAN_AGENT, "TBS is %d\n", TBS); - - // check first for RLC data on DCCH - // add the length for all the control elements (timing adv, drx, etc) : header + payload - - ta_len = (ue_sched_ctl->ta_update != 0) ? 2 : 0; - - dl_data[num_ues_added]->n_ce_bitmap = 2; - dl_data[num_ues_added]->ce_bitmap = (uint32_t *) calloc(2, sizeof(uint32_t)); - - if (ta_len > 0) { - ce_flags |= PROTOCOL__FLEX_CE_TYPE__FLPCET_TA; - } - - /*TODO: Add other flags if DRX and other CE are required*/ - - // Add the control element flags to the flexran message - dl_data[num_ues_added]->ce_bitmap[0] = ce_flags; - dl_data[num_ues_added]->ce_bitmap[1] = ce_flags; - - // TODO : Need to prioritize DRBs - // Loop through the UE logical channels (DCCH, DCCH1, DTCH for now) - header_len = 0; - header_len_last = 0; - sdu_length_total = 0; - for (j = 1; j < NB_RB_MAX; j++) { - header_len += 3; - // Need to see if we have space for data from this channel - if (dci_tbs - ta_len - header_len - sdu_length_total > 0) { - LOG_D(MAC, "[TEST]Requested %d bytes from RLC buffer on channel %d during first call\n", dci_tbs-ta_len-header_len, j); - //If we have space, we need to see how much data we can request at most (if any available) - rlc_status = mac_rlc_status_ind(mod_id, - rnti, - mod_id, - frame, - subframe, - ENB_FLAG_YES, - MBMS_FLAG_NO, - j, - (dci_tbs - ta_len - header_len - sdu_length_total)); // transport block set size - - //If data are available in channel j - if (rlc_status.bytes_in_buffer > 0) { - LOG_D(MAC, "[TEST]Have %d bytes in DCCH buffer during first call\n", rlc_status.bytes_in_buffer); - //Fill in as much as possible - data_to_request = cmin(dci_tbs - ta_len - header_len - sdu_length_total, rlc_status.bytes_in_buffer); - LOG_D(FLEXRAN_AGENT, "Will request %d bytes from channel %d\n", data_to_request, j); - - if (data_to_request < 128) { //The header will be one byte less - header_len--; - header_len_last = 2; - } - else { - - header_len_last = 3; - } - /* if (j == 1 || j == 2) { - data_to_request+=0; - } */ - LOG_D(MAC, "[TEST]Will request %d from channel %d\n", data_to_request, j); - rlc_pdus[channels_added] = (Protocol__FlexRlcPdu *) malloc(sizeof(Protocol__FlexRlcPdu)); - protocol__flex_rlc_pdu__init(rlc_pdus[channels_added]); - rlc_pdus[channels_added]->n_rlc_pdu_tb = 2; - rlc_pdus[channels_added]->rlc_pdu_tb = (Protocol__FlexRlcPduTb **) malloc(sizeof(Protocol__FlexRlcPduTb *) * 2); - rlc_pdus[channels_added]->rlc_pdu_tb[0] = (Protocol__FlexRlcPduTb *) malloc(sizeof(Protocol__FlexRlcPduTb)); - protocol__flex_rlc_pdu_tb__init(rlc_pdus[channels_added]->rlc_pdu_tb[0]); - rlc_pdus[channels_added]->rlc_pdu_tb[0]->has_logical_channel_id = 1; - rlc_pdus[channels_added]->rlc_pdu_tb[0]->logical_channel_id = j; - rlc_pdus[channels_added]->rlc_pdu_tb[0]->has_size = 1; - rlc_pdus[channels_added]->rlc_pdu_tb[0]->size = data_to_request; - rlc_pdus[channels_added]->rlc_pdu_tb[1] = (Protocol__FlexRlcPduTb *) malloc(sizeof(Protocol__FlexRlcPduTb)); - protocol__flex_rlc_pdu_tb__init(rlc_pdus[channels_added]->rlc_pdu_tb[1]); - rlc_pdus[channels_added]->rlc_pdu_tb[1]->has_logical_channel_id = 1; - rlc_pdus[channels_added]->rlc_pdu_tb[1]->logical_channel_id = j; - rlc_pdus[channels_added]->rlc_pdu_tb[1]->has_size = 1; - rlc_pdus[channels_added]->rlc_pdu_tb[1]->size = data_to_request; - dl_data[num_ues_added]->n_rlc_pdu++; - channels_added++; - //Set this to the max value that we might request - sdu_length_total += data_to_request; - } else { - //Take back the assumption of a header for this channel - header_len -= 3; - } //End rlc_status.bytes_in_buffer <= 0 - } //end of if dci_tbs - ta_len - header_len > 0 - } // End of iterating the logical channels - - // Add rlc_pdus to the dl_data message - dl_data[num_ues_added]->rlc_pdu = (Protocol__FlexRlcPdu **) malloc(sizeof(Protocol__FlexRlcPdu *) * - dl_data[num_ues_added]->n_rlc_pdu); - for (i = 0; i < dl_data[num_ues_added]->n_rlc_pdu; i++) { - dl_data[num_ues_added]->rlc_pdu[i] = rlc_pdus[i]; - } - - if (header_len == 0) { - LOG_D(FLEXRAN_AGENT, "Header was empty\n"); - header_len_last = 0; - } - - // there is a payload - if ((dl_data[num_ues_added]->n_rlc_pdu > 0)) { - // Now compute number of required RBs for total sdu length - // Assume RAH format 2 - // adjust header lengths - LOG_D(FLEXRAN_AGENT, "We have %d bytes to transfer\n", sdu_length_total); - if (header_len != 0) { - LOG_D(FLEXRAN_AGENT, "Header length was %d ", header_len); - header_len_last--; - header_len -= header_len_last; - LOG_D(FLEXRAN_AGENT, "so we resized it to %d\n", header_len); - } - - /* if (header_len == 2 || header_len == 3) { //Only one SDU, remove length field */ - /* header_len = 1; */ - /* } else { //Remove length field from the last SDU */ - /* header_len--; */ - /* } */ - - mcs_tmp = mcs; - if (mcs_tmp == 0) { - nb_rb = 4; // don't let the TBS get too small - } else { - nb_rb=min_rb_unit[CC_id]; - } - - LOG_D(MAC,"[TEST]The initial number of resource blocks was %d\n", nb_rb); - LOG_D(MAC,"[TEST] The initial mcs was %d\n", mcs_tmp); - - TBS = mac_xface->get_TBS_DL(mcs_tmp, nb_rb); - LOG_D(MAC,"[TEST]The TBS during rate matching was %d\n", TBS); - - while (TBS < (sdu_length_total + header_len + ta_len)) { - nb_rb += min_rb_unit[CC_id]; // - LOG_D(MAC, "[TEST]Had to increase the number of RBs\n"); - if (nb_rb > nb_available_rb) { // if we've gone beyond the maximum number of RBs - // (can happen if N_RB_DL is odd) - TBS = mac_xface->get_TBS_DL(mcs_tmp, nb_available_rb); - nb_rb = nb_available_rb; - break; - } - - TBS = mac_xface->get_TBS_DL(mcs_tmp, nb_rb); - } - - if(nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { - LOG_D(MAC, "[TEST]We had the exact number of rbs. Time to fill the rballoc subband\n"); - for(j = 0; j < flexran_get_N_RBG(mod_id, CC_id); j++) { // for indicating the rballoc for each sub-band - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - } - } - else { - nb_rb_temp = nb_rb; - j = 0; - LOG_D(MAC, "[TEST]Will only partially fill the bitmap\n"); - while((nb_rb_temp > 0) && (j < flexran_get_N_RBG(mod_id, CC_id))) { - if(ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - if ((j == flexran_get_N_RBG(mod_id, CC_id) - 1) && - ((flexran_get_N_RB_DL(mod_id, CC_id) == 25)|| - (flexran_get_N_RB_DL(mod_id, CC_id) == 50))) { - nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1; - } else { - nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; - } - } - j = j+1; - } - } - - PHY_vars_eNB_g[mod_id][CC_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; - PHY_vars_eNB_g[mod_id][CC_id]->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; - - for(j = 0; j < flexran_get_N_RBG(mod_id, CC_id); j++) { - PHY_vars_eNB_g[mod_id][CC_id]->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; - } - - // decrease mcs until TBS falls below required length - while ((TBS > (sdu_length_total + header_len + ta_len)) && (mcs_tmp > 0)) { - mcs_tmp--; - TBS = mac_xface->get_TBS_DL(mcs_tmp, nb_rb); - } - - // if we have decreased too much or we don't have enough RBs, increase MCS - while ((TBS < (sdu_length_total + header_len + ta_len)) && - ((( ue_sched_ctl->dl_pow_off[CC_id] > 0) && (mcs_tmp < 28)) || ( (ue_sched_ctl->dl_pow_off[CC_id]==0) && (mcs_tmp <= 15)))) { - mcs_tmp++; - TBS = mac_xface->get_TBS_DL(mcs_tmp, nb_rb); - } - - dci_tbs = TBS; - mcs = mcs_tmp; - LOG_D(FLEXRAN_AGENT, "Final mcs was %d\n", mcs); - - dl_dci->has_aggr_level = 1; - dl_dci->aggr_level = aggregation; - - UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb; - - // if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { - // UE_list->UE_template[CC_id][UE_id].DAI++; - // // printf("DAI update: subframeP %d: UE %d, DAI %d\n",subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].DAI); - //#warning only for 5MHz channel - // update_ul_dci(mod_id, CC_id, rnti, UE_list->UE_template[CC_id][UE_id].DAI); - // } - - // do PUCCH power control - // this is the normalized RX power - normalized_rx_power = flexran_get_p0_pucch_dbm(mod_id,UE_id, CC_id); //eNB_UE_stats->Po_PUCCH_dBm; - target_rx_power = flexran_get_p0_nominal_pucch(mod_id, CC_id) + 20; //mac_xface->get_target_pucch_rx_power(mod_id, CC_id) + 20; - // this assumes accumulated tpc - // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out - int32_t framex10psubframe = UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame*10+UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe; - - if (((framex10psubframe+10)<=(frame*10+subframe)) || //normal case - ((framex10psubframe>(frame*10+subframe)) && (((10240-framex10psubframe+frame*10+subframe)>=10)))) //frame wrap-around - if (flexran_get_p0_pucch_status(mod_id, UE_id, CC_id) == 1) { - flexran_update_p0_pucch(mod_id, UE_id, CC_id); - - UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame = frame; - UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe = subframe; - if (normalized_rx_power>(target_rx_power+1)) { - tpc = 0; //-1 - tpc_accumulated--; - } else if (normalized_rx_power<(target_rx_power-1)) { - tpc = 2; //+1 - tpc_accumulated++; - } else { - tpc = 1; //0 - } - LOG_D(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", - mod_id, frame, subframe, harq_pid, tpc, - tpc_accumulated, normalized_rx_power, target_rx_power); - } // Po_PUCCH has been updated - else { - tpc = 1; //0 - } // time to do TPC update - else { - tpc = 1; //0 - } - - for(i=0; iframe_parms.N_RBG; i++) { - rballoc_sub[i] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][i]; - } - - // Toggle NDI - LOG_D(MAC,"CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n", - CC_id, frame, subframe, UE_id, - UE_list->UE_template[CC_id][UE_id].rnti,harq_pid, UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]); - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]= 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; - ndi = UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; - - UE_list->UE_template[CC_id][UE_id].mcs[harq_pid] = mcs; - UE_list->UE_template[CC_id][UE_id].oldTPC[harq_pid] = tpc; - - // Increase the pointer for the number of scheduled UEs - num_ues_added++; - ue_has_transmission = 1; - } else { // There is no data from RLC or MAC header, so don't schedule - ue_has_transmission = 0; - } - } // End of new scheduling - - // If we has transmission or retransmission - if (ue_has_transmission) { - switch (mac_xface->get_transmission_mode(mod_id, CC_id, rnti)) { - case 1: - case 2: - default: - dl_dci->has_res_alloc = 1; - dl_dci->res_alloc = 0; - dl_dci->has_vrb_format = 1; - dl_dci->vrb_format = PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; - dl_dci->has_format = 1; - dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1; - dl_dci->has_rb_bitmap = 1; - dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, rballoc_sub); - dl_dci->has_rb_shift = 1; - dl_dci->rb_shift = 0; - dl_dci->n_ndi = 1; - dl_dci->ndi = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); - dl_dci->ndi[0] = ndi; - dl_dci->n_rv = 1; - dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); - dl_dci->rv[0] = round & 3; - dl_dci->has_tpc = 1; - dl_dci->tpc = tpc; - dl_dci->n_mcs = 1; - dl_dci->mcs = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_mcs); - dl_dci->mcs[0] = mcs; - dl_dci->n_tbs_size = 1; - dl_dci->tbs_size = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_tbs_size); - dl_dci->tbs_size[0] = dci_tbs; - if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { - dl_dci->has_dai = 1; - dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; - } - break; - case 3: - dl_dci->has_res_alloc = 1; - dl_dci->res_alloc = 0; - dl_dci->has_vrb_format = 1; - dl_dci->vrb_format = PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; - dl_dci->has_format = 1; - dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A; - dl_dci->has_rb_bitmap = 1; - dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, rballoc_sub); - dl_dci->has_rb_shift = 1; - dl_dci->rb_shift = 0; - dl_dci->n_ndi = 2; - dl_dci->ndi = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); - dl_dci->ndi[0] = ndi; - dl_dci->ndi[1] = ndi; - dl_dci->n_rv = 2; - dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); - dl_dci->rv[0] = round & 3; - dl_dci->rv[1] = round & 3; - dl_dci->has_tpc = 1; - dl_dci->tpc = tpc; - dl_dci->n_mcs = 2; - dl_dci->mcs = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_mcs); - dl_dci->mcs[0] = mcs; - dl_dci->mcs[1] = mcs; - dl_dci->n_tbs_size = 2; - dl_dci->tbs_size = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_tbs_size); - dl_dci->tbs_size[0] = dci_tbs; - dl_dci->tbs_size[1] = dci_tbs; - if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { - dl_dci->has_dai = 1; - dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; - } - break; - case 4: - dl_dci->has_res_alloc = 1; - dl_dci->res_alloc = 0; - dl_dci->has_vrb_format = 1; - dl_dci->vrb_format = PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; - dl_dci->has_format = 1; - dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A; - dl_dci->has_rb_bitmap = 1; - dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, rballoc_sub); - dl_dci->has_rb_shift = 1; - dl_dci->rb_shift = 0; - dl_dci->n_ndi = 2; - dl_dci->ndi = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); - dl_dci->ndi[0] = ndi; - dl_dci->ndi[1] = ndi; - dl_dci->n_rv = 2; - dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); - dl_dci->rv[0] = round & 3; - dl_dci->rv[1] = round & 3; - dl_dci->has_tpc = 1; - dl_dci->tpc = tpc; - dl_dci->n_mcs = 2; - dl_dci->mcs = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_mcs); - dl_dci->mcs[0] = mcs; - dl_dci->mcs[1] = mcs; - dl_dci->n_tbs_size = 2; - dl_dci->tbs_size = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_tbs_size); - dl_dci->tbs_size[0] = dci_tbs; - dl_dci->tbs_size[1] = dci_tbs; - if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { - dl_dci->has_dai = 1; - dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; - } - break; - case 5: - dl_dci->has_res_alloc = 1; - dl_dci->res_alloc = 0; - dl_dci->has_vrb_format = 1; - dl_dci->vrb_format = PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; - dl_dci->has_format = 1; - dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D; - dl_dci->has_rb_bitmap = 1; - dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, rballoc_sub); - dl_dci->has_rb_shift = 1; - dl_dci->rb_shift = 0; - dl_dci->n_ndi = 1; - dl_dci->ndi[0] = ndi; - dl_dci->n_rv = 1; - dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); - dl_dci->rv[0] = round & 3; - dl_dci->has_tpc = 1; - dl_dci->tpc = tpc; - dl_dci->n_mcs = 1; - dl_dci->mcs = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_mcs); - dl_dci->mcs[0] = mcs; - dl_dci->n_tbs_size = 1; - dl_dci->tbs_size = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_tbs_size); - dl_dci->tbs_size[0] = dci_tbs; - if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { - dl_dci->has_dai = 1; - dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; - } - - if(ue_sched_ctl->dl_pow_off[CC_id] == 2) { - ue_sched_ctl->dl_pow_off[CC_id] = 1; - } - - dl_dci->has_dl_power_offset = 1; - dl_dci->dl_power_offset = ue_sched_ctl->dl_pow_off[CC_id]; - dl_dci->has_precoding_info = 1; - dl_dci->precoding_info = 5; // Is this right?? - - break; - case 6: - dl_dci->has_res_alloc = 1; - dl_dci->res_alloc = 0; - dl_dci->has_vrb_format = 1; - dl_dci->vrb_format = PROTOCOL__FLEX_VRB_FORMAT__FLVRBF_LOCALIZED; - dl_dci->has_format = 1; - dl_dci->format = PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D; - dl_dci->has_rb_bitmap = 1; - dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, rballoc_sub); - dl_dci->has_rb_shift = 1; - dl_dci->rb_shift = 0; - dl_dci->n_ndi = 1; - dl_dci->ndi = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); - dl_dci->ndi[0] = ndi; - dl_dci->n_rv = 1; - dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); - dl_dci->rv[0] = round & 3; - dl_dci->has_tpc = 1; - dl_dci->tpc = tpc; - dl_dci->n_mcs = 1; - dl_dci->mcs = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_mcs); - dl_dci->mcs[0] = mcs; - if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { - dl_dci->has_dai = 1; - dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; - } - - dl_dci->has_dl_power_offset = 1; - dl_dci->dl_power_offset = ue_sched_ctl->dl_pow_off[CC_id]; - dl_dci->has_precoding_info = 1; - dl_dci->precoding_info = 5; // Is this right?? - break; - } - } - - // if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) { - - /* TODO */ - //set_ul_DAI(mod_id, UE_id, CC_id, frame, subframe, frame_parms); - // } - } // UE_id loop - } // CC_id loop - - // Add all the dl_data elements to the flexran message - int offset = (*dl_info)->dl_mac_config_msg->n_dl_ue_data; - (*dl_info)->dl_mac_config_msg->n_dl_ue_data += num_ues_added; - if ( num_ues_added > 0 ){ - (*dl_info)->dl_mac_config_msg->dl_ue_data = (Protocol__FlexDlData **) realloc( (*dl_info)->dl_mac_config_msg->dl_ue_data, - sizeof(Protocol__FlexDlData *) * ((*dl_info)->dl_mac_config_msg->n_dl_ue_data)); - if ((*dl_info)->dl_mac_config_msg->dl_ue_data == NULL ){ - LOG_E(MAC, "Request for memory reallocation failed\n"); - return; - } - for (i = 0; i < num_ues_added; i++) { - (*dl_info)->dl_mac_config_msg->dl_ue_data[offset+i] = dl_data[i]; - } - } - - stop_meas(&eNB->schedule_dlsch); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,VCD_FUNCTION_OUT); -} diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue_remote.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue_remote.c deleted file mode 100644 index 2b0bf72015..0000000000 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue_remote.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file flexran_agent_scheduler_dlsch_ue_remote.c - * \brief procedures related to remote scheduling in the DLSCH transport channel - * \author Xenofon Foukas - * \date 2016 - * \email: x.foukas@sms.ed.ac.uk - * \version 0.1 - * @ingroup _mac - - */ - -#include "flexran_agent_common_internal.h" -#include "flexran_agent_ran_api.h" -#include "flexran_agent_scheduler_dlsch_ue_remote.h" - -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/extern.h" - -struct DlMacConfigHead queue_head; - -int queue_initialized = 0; - -//uint32_t skip_subframe = 1; -//uint32_t period = 10; -//uint32_t sched [] = {1, 2, 3}; - -void -flexran_schedule_ue_spec_remote(mid_t mod_id, uint32_t frame, - uint32_t subframe, int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info) -{ - - - //if ((subframe == skip_subframe) && (frame % period == 0)) { - // LOG_I(MAC, "Will skip subframe %d %d\n", subframe, frame); - // for (int i = 0; i < 3; i++) { - // LOG_I(MAC, "%d\n", sched[i]); - // } - //} - - /* if (frame == 500 && subframe == 1) { */ - /* char policy[] = "rrc: \n - ul_scheduler: \n behavior : tester_function\n parameters:\n period: !!int 3\nmac: \n - dl_scheduler: \n parameters: \n period : !!int 40\n skip_subframe : !!int 3\n sched : [!!int 4, !!int 5, !!int 6]"; */ - /* apply_reconfiguration_policy(mod_id, policy, strlen(policy)); */ - /* } */ - - eNB_MAC_INST *eNB; - - if (!queue_initialized) { - TAILQ_INIT(&queue_head); - queue_initialized = 1; - } - - eNB = &eNB_mac_inst[mod_id]; - - dl_mac_config_element_t *dl_config_elem; - - int diff; - LOG_D(MAC, "[TEST] Current frame and subframe %d, %d\n", frame, - subframe); - // First we check to see if we have a scheduling decision for this sfn_sf already in our queue - while (queue_head.tqh_first != NULL) { - dl_config_elem = queue_head.tqh_first; - - diff = - get_sf_difference(mod_id, - dl_config_elem->dl_info-> - dl_mac_config_msg->sfn_sf); - // Check if this decision is for now, for a later or a previous subframe - if (diff == 0) { // Now - LOG_D(MAC, - "Found a decision for this subframe in the queue. Let's use it!\n"); - TAILQ_REMOVE(&queue_head, queue_head.tqh_first, configs); - *dl_info = dl_config_elem->dl_info; - free(dl_config_elem); - eNB->eNB_stats[mod_id].sched_decisions++; - return; - } else if (diff < 0) { //previous subframe , delete message and free memory - LOG_D(MAC, - "Found a decision for a previous subframe in the queue. Let's get rid of it\n"); - TAILQ_REMOVE(&queue_head, queue_head.tqh_first, configs); - flexran_agent_mac_destroy_dl_config(dl_config_elem->dl_info); - free(dl_config_elem); - eNB->eNB_stats[mod_id].sched_decisions++; - eNB->eNB_stats[mod_id].missed_deadlines++; - } else { // next subframe, nothing to do now - LOG_D(MAC, - "Found a decision for a future subframe in the queue. Nothing to do now\n"); - flexran_agent_mac_create_empty_dl_config(mod_id, dl_info); - return; - } - } - - //Done with the local cache. Now we need to check if something new arrived - flexran_agent_get_pending_dl_mac_config(mod_id, dl_info); - while (*dl_info != NULL) { - - diff = - get_sf_difference(mod_id, - (*dl_info)->dl_mac_config_msg->sfn_sf); - if (diff == 0) { // Got a command for this sfn_sf - LOG_D(MAC, - "Found a decision for this subframe pending. Let's use it\n"); - eNB->eNB_stats[mod_id].sched_decisions++; - return; - } else if (diff < 0) { - LOG_D(MAC, - "Found a decision for a previous subframe. Let's get rid of it\n"); - flexran_agent_mac_destroy_dl_config(*dl_info); - *dl_info = NULL; - flexran_agent_get_pending_dl_mac_config(mod_id, dl_info); - eNB->eNB_stats[mod_id].sched_decisions++; - eNB->eNB_stats[mod_id].missed_deadlines++; - } else { // Intended for future subframe. Store it in local cache - LOG_D(MAC, - "Found a decision for a future subframe in the queue. Let's store it in the cache\n"); - dl_mac_config_element_t *e = - malloc(sizeof(dl_mac_config_element_t)); - e->dl_info = *dl_info; - TAILQ_INSERT_TAIL(&queue_head, e, configs); - flexran_agent_mac_create_empty_dl_config(mod_id, dl_info); - // No need to look for another. Messages arrive ordered - return; - } - } - - // We found no pending command, so we will simply pass an empty one - flexran_agent_mac_create_empty_dl_config(mod_id, dl_info); -} - -int get_sf_difference(mid_t mod_id, uint32_t sfn_sf) -{ - int diff_in_subframes; - - uint16_t current_frame = flexran_get_current_system_frame_num(mod_id); - uint16_t current_subframe = flexran_get_current_subframe(mod_id); - uint32_t current_sfn_sf = flexran_get_sfn_sf(mod_id); - - if (sfn_sf == current_sfn_sf) { - return 0; - } - - uint16_t frame_mask = ((1 << 12) - 1); - uint16_t frame = (sfn_sf & (frame_mask << 4)) >> 4; - - uint16_t sf_mask = ((1 << 4) - 1); - uint16_t subframe = (sfn_sf & sf_mask); - - LOG_D(MAC, "[TEST] Target frame and subframe %d, %d\n", frame, - subframe); - - if (frame == current_frame) { - return subframe - current_subframe; - } else if (frame > current_frame) { - diff_in_subframes = - ((frame * 10) + subframe) - ((current_frame * 10) + - current_subframe); - - // diff_in_subframes = 9 - current_subframe; - //diff_in_subframes += (subframe + 1); - //diff_in_subframes += (frame-2) * 10; - if (diff_in_subframes > SCHED_AHEAD_SUBFRAMES) { - return -1; - } else { - return 1; - } - } else { //frame < current_frame - //diff_in_subframes = 9 - current_subframe; - //diff_in_subframes += (subframe + 1); - //if (frame > 0) { - // diff_in_subframes += (frame - 1) * 10; - //} - //diff_in_subframes += (1023 - current_frame) * 10; - diff_in_subframes = - 10240 - ((current_frame * 10) + current_subframe) + - ((frame * 10) + subframe); - if (diff_in_subframes > SCHED_AHEAD_SUBFRAMES) { - return -1; - } else { - return 1; - } - } -} diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue_remote.h b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue_remote.h deleted file mode 100644 index 449ba1e8cd..0000000000 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue_remote.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file flexran_agent_scheduler_dlsch_ue_remote.h - * \brief Local stub for remote scheduler used by the controller - * \author Xenofon Foukas - * \date 2016 - * \email: x.foukas@sms.ed.ac.uk - * \version 0.1 - * @ingroup _mac - - */ - -#ifndef __LAYER2_MAC_FLEXRAN_AGENT_SCHEDULER_DLSCH_UE_REMOTE_H__ -#define __LAYER2_MAC_FLEXRAN_AGENT_SCHEDULER_DLSCH_UE_REMOTE_H___ - -#include "flexran.pb-c.h" -#include "header.pb-c.h" - -#include "ENB_APP/flexran_agent_defs.h" -#include "flexran_agent_mac.h" -#include "LAYER2/MAC/flexran_agent_mac_proto.h" - -#include - -// Maximum value of schedule ahead of time -// Required to identify if a dl_command is for the future or not -#define SCHED_AHEAD_SUBFRAMES 20 - -typedef struct dl_mac_config_element_s { - Protocol__FlexranMessage *dl_info; - TAILQ_ENTRY(dl_mac_config_element_s) configs; -} dl_mac_config_element_t; - -TAILQ_HEAD(DlMacConfigHead, dl_mac_config_element_s); - -/* - * Default scheduler used by the eNB agent - */ -void flexran_schedule_ue_spec_remote(mid_t mod_id, uint32_t frame, - uint32_t subframe, int *mbsfn_flag, - Protocol__FlexranMessage ** dl_info); - - -// Find the difference in subframes from the given subframe -// negative for older value -// 0 for equal -// positive for future value -// Based on -int get_sf_difference(mid_t mod_id, uint32_t sfn_sf); - -#endif diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c deleted file mode 100644 index 86ea61d943..0000000000 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_ulsch_ue.c +++ /dev/null @@ -1,1112 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file eNB_scheduler_ulsch.c - * \brief FlexRAN eNB procedures for the ULSCH transport channel - * \author Navid Nikaein and shahab SHARIAT BAGHERI - * \date 2017 - * \version 1.0 - * @ingroup _mac - - */ - -#include "assertions.h" -#include "PHY/defs.h" -#include "PHY/extern.h" - -#include "SCHED/defs.h" -#include "SCHED/extern.h" - -#include "LAYER2/MAC/flexran_agent_mac_proto.h" -#include "LAYER2/MAC/defs.h" -#include "LAYER2/MAC/proto.h" -#include "LAYER2/MAC/extern.h" -#include "UTIL/LOG/log.h" -#include "UTIL/LOG/vcd_signal_dumper.h" -#include "UTIL/OPT/opt.h" -#include "OCG.h" -#include "OCG_extern.h" - -#include "RRC/LITE/extern.h" -#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" - -//#include "LAYER2/MAC/pre_processor.c" -#include "ENB_APP/flexran_agent_defs.h" -#include "flexran_agent_ran_api.h" -#include "pdcp.h" - -#include "header.pb-c.h" -#include "flexran.pb-c.h" -#include "flexran_agent_mac.h" - -#if defined(ENABLE_ITTI) -# include "intertask_interface.h" -#endif - -#include "T.h" - -#include - -/* number of active slices for past and current time*/ -int n_active_slices_uplink = 1; -int n_active_slices_current_uplink = 1; - -/* RB share for each slice for past and current time*/ -float avg_slice_percentage_uplink=0.25; -float slice_percentage_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; -float slice_percentage_current_uplink[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; -float total_slice_percentage_uplink = 0; -float total_slice_percentage_current_uplink = 0; - -// MAX MCS for each slice for past and current time -int slice_maxmcs_uplink[MAX_NUM_SLICES] = {16, 16, 16, 16}; -int slice_maxmcs_current_uplink[MAX_NUM_SLICES] = {16,16,16,16}; - -/*resource blocks allowed*/ -uint16_t nb_rbs_allowed_slice_uplink[MAX_NUM_CCs][MAX_NUM_SLICES]; -/*Slice Update */ -int update_ul_scheduler[MAX_NUM_SLICES] = {1, 1, 1, 1}; -int update_ul_scheduler_current[MAX_NUM_SLICES] = {1, 1, 1, 1}; - - /* Slice Function Pointer */ -slice_scheduler_ul slice_sched_ul[MAX_NUM_SLICES] = {0}; - -/* name of available scheduler*/ -char *ul_scheduler_type[MAX_NUM_SLICES] = {"flexran_schedule_ue_ul_spec_embb", - "flexran_schedule_ue_ul_spec_embb", - "flexran_schedule_ue_ul_spec_embb", - "flexran_schedule_ue_ul_spec_embb" // best effort -}; - - -uint16_t flexran_nb_rbs_allowed_slice_uplink(float rb_percentage, int total_rbs){ - return (uint16_t) floor(rb_percentage * total_rbs); -} - - -void _assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, sub_frame_t subframeP, uint16_t *first_rb) -{ - - int i; - uint16_t n,UE_id; - uint8_t CC_id; - rnti_t rnti = -1; - int mcs; - int rb_table_index=0,tbs,tx_power; - eNB_MAC_INST *eNB = &eNB_mac_inst[module_idP]; - UE_list_t *UE_list = &eNB->UE_list; - - UE_TEMPLATE *UE_template; - LTE_DL_FRAME_PARMS *frame_parms; - - - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { - if (UE_list->active[i] != TRUE) continue; - - rnti = UE_RNTI(module_idP,i); - - if (rnti==NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; - if (!phy_stats_exist(module_idP, rnti)) - continue; - - if (UE_list->UE_sched_ctrl[i].phr_received == 1) - mcs = 20; // if we've received the power headroom information the UE, we can go to maximum mcs - else - mcs = 10; // otherwise, limit to QPSK PUSCH - - UE_id = i; - - for (n=0; nnumactiveULCCs[UE_id]; n++) { - // This is the actual CC_id in the list - CC_id = UE_list->ordered_ULCCids[n][UE_id]; - - if (CC_id >= MAX_NUM_CCs) { - LOG_E( MAC, "CC_id %u should be < %u, loop n=%u < numactiveULCCs[%u]=%u", - CC_id, - MAX_NUM_CCs, - n, - UE_id, - UE_list->numactiveULCCs[UE_id]); - } - - AssertFatal( CC_id < MAX_NUM_CCs, "CC_id %u should be < %u, loop n=%u < numactiveULCCs[%u]=%u", - CC_id, - MAX_NUM_CCs, - n, - UE_id, - UE_list->numactiveULCCs[UE_id]); - frame_parms=mac_xface->get_lte_frame_parms(module_idP,CC_id); - UE_template = &UE_list->UE_template[CC_id][UE_id]; - nb_rbs_allowed_slice_uplink[CC_id][UE_id] = flexran_nb_rbs_allowed_slice_uplink(slice_percentage_uplink[UE_id], flexran_get_N_RB_UL(module_idP, CC_id)); - // if this UE has UL traffic - if (UE_template->ul_total_buffer > 0 ) { - - tbs = mac_xface->get_TBS_UL(mcs,3); // 1 or 2 PRB with cqi enabled does not work well! - // fixme: set use_srs flag - tx_power= mac_xface->estimate_ue_tx_power(tbs,rb_table[rb_table_index],0,frame_parms->Ncp,0); - - while ((((UE_template->phr_info - tx_power) < 0 ) || (tbs > UE_template->ul_total_buffer))&& - (mcs > 3)) { - // LOG_I(MAC,"UE_template->phr_info %d tx_power %d mcs %d\n", UE_template->phr_info,tx_power, mcs); - mcs--; - tbs = mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]); - tx_power = mac_xface->estimate_ue_tx_power(tbs,rb_table[rb_table_index],0,frame_parms->Ncp,0); // fixme: set use_srs - } - - while ((tbs < UE_template->ul_total_buffer) && - (rb_table[rb_table_index]<(nb_rbs_allowed_slice_uplink[CC_id][UE_id]-first_rb[CC_id])) && - ((UE_template->phr_info - tx_power) > 0) && - (rb_table_index < 32 )) { - // LOG_I(MAC,"tbs %d ul buffer %d rb table %d max ul rb %d\n", tbs, UE_template->ul_total_buffer, rb_table[rb_table_index], frame_parms->N_RB_UL-first_rb[CC_id]); - rb_table_index++; - tbs = mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]); - tx_power = mac_xface->estimate_ue_tx_power(tbs,rb_table[rb_table_index],0,frame_parms->Ncp,0); - } - - UE_template->ue_tx_power = tx_power; - - if (rb_table[rb_table_index]>(nb_rbs_allowed_slice_uplink[CC_id][UE_id]-first_rb[CC_id]-1)) { - rb_table_index--; - } - - // 1 or 2 PRB with cqi enabled does not work well! - if (rb_table[rb_table_index]<3) { - rb_table_index=2; //3PRB - } - - UE_template->pre_assigned_mcs_ul=mcs; - UE_template->pre_allocated_rb_table_index_ul=rb_table_index; - UE_template->pre_allocated_nb_rb_ul= rb_table[rb_table_index]; - LOG_D(MAC,"[eNB %d] frame %d subframe %d: for UE %d CC %d: pre-assigned mcs %d, pre-allocated rb_table[%d]=%d RBs (phr %d, tx power %d)\n", - module_idP, frameP, subframeP, UE_id, CC_id, - UE_template->pre_assigned_mcs_ul, - UE_template->pre_allocated_rb_table_index_ul, - UE_template->pre_allocated_nb_rb_ul, - UE_template->phr_info,tx_power); - } else { - UE_template->pre_allocated_rb_table_index_ul=-1; - UE_template->pre_allocated_nb_rb_ul=0; - } - } - } -} - - - - -void _ulsch_scheduler_pre_processor(module_id_t module_idP, - int slice_id, - int frameP, - sub_frame_t subframeP, - uint16_t *first_rb) -{ - - int16_t i; - uint16_t UE_id,n,r; - uint8_t CC_id, round, harq_pid; - uint16_t nb_allocated_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX],total_allocated_rbs[MAX_NUM_CCs],average_rbs_per_user[MAX_NUM_CCs]; - uint16_t nb_rbs_allowed_slice_uplink[MAX_NUM_CCs][MAX_NUM_SLICES]; - int16_t total_remaining_rbs[MAX_NUM_CCs]; - uint16_t max_num_ue_to_be_scheduled=0,total_ue_count=0; - rnti_t rnti= -1; - UE_list_t *UE_list = &eNB_mac_inst[module_idP].UE_list; - UE_TEMPLATE *UE_template = 0; - // LTE_DL_FRAME_PARMS *frame_parms; //Not used yet - UE_sched_ctrl *ue_sched_ctl; - - - //LOG_I(MAC,"assign max mcs min rb\n"); - // maximize MCS and then allocate required RB according to the buffer occupancy with the limit of max available UL RB - _assign_max_mcs_min_rb(module_idP, slice_id, frameP, subframeP, first_rb); - - //LOG_I(MAC,"sort ue \n"); - // sort ues - sort_ue_ul (module_idP,frameP, subframeP); - - - // we need to distribute RBs among UEs - // step1: reset the vars - for (CC_id=0; CC_idhead_ul; i>=0; i=UE_list->next_ul[i]) { - nb_allocated_rbs[CC_id][i]=0; - } - } - - //LOG_I(MAC,"step2 \n"); - // step 2: calculate the average rb per UE - total_ue_count =0; - max_num_ue_to_be_scheduled=0; - - for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) { - - rnti = UE_RNTI(module_idP,i); - - if (rnti==NOT_A_RNTI) - continue; - - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; - - if (!phy_stats_exist(module_idP, rnti)) - continue; - - UE_id = i; - - for (n=0; nnumactiveULCCs[UE_id]; n++) { - // This is the actual CC_id in the list - CC_id = UE_list->ordered_ULCCids[n][UE_id]; - UE_template = &UE_list->UE_template[CC_id][UE_id]; - average_rbs_per_user[CC_id]=0; - // frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id); - - if (UE_template->pre_allocated_nb_rb_ul > 0) { - total_ue_count+=1; - } - /* - if((mac_xface->get_nCCE_max(module_idP,CC_id,3,subframeP) - nCCE_to_be_used[CC_id]) > (1< 0 ) { - average_rbs_per_user[CC_id] = (uint16_t) floor((nb_rbs_allowed_slice_uplink[CC_id][i]-first_rb[CC_id])/max_num_ue_to_be_scheduled); - } else { - average_rbs_per_user[CC_id]=1; - LOG_W(MAC,"[eNB %d] frame %d subframe %d: UE %d CC %d: can't get average rb per user (should not be here)\n", - module_idP,frameP,subframeP,UE_id,CC_id); - } - } - } - if (total_ue_count > 0) - LOG_D(MAC,"[eNB %d] Frame %d subframe %d: total ue to be scheduled %d/%d\n", - module_idP, frameP, subframeP,total_ue_count, max_num_ue_to_be_scheduled); - - //LOG_D(MAC,"step3\n"); - - // step 3: assigne RBS - for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) { - rnti = UE_RNTI(module_idP,i); - - if (rnti==NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; - if (!phy_stats_exist(module_idP, rnti)) - continue; - - UE_id = i; - - for (n=0; nnumactiveULCCs[UE_id]; n++) { - // This is the actual CC_id in the list - CC_id = UE_list->ordered_ULCCids[n][UE_id]; - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - ue_sched_ctl->max_allowed_rbs[CC_id]=nb_rbs_allowed_slice_uplink[CC_id][UE_id]; - // mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL); - flexran_get_harq(module_idP, CC_id, UE_id, frameP, subframeP, &harq_pid, &round, openair_harq_UL); - if(round>0) { - nb_allocated_rbs[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb_ul[harq_pid]; - } else { - nb_allocated_rbs[CC_id][UE_id] = cmin(UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul, average_rbs_per_user[CC_id]); - } - - total_allocated_rbs[CC_id]+= nb_allocated_rbs[CC_id][UE_id]; - - } - } - - // step 4: assigne the remaining RBs and set the pre_allocated rbs accordingly - for(r=0; r<2; r++) { - - for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) { - rnti = UE_RNTI(module_idP,i); - - if (rnti==NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; - if (!phy_stats_exist(module_idP, rnti)) - continue; - - UE_id = i; - - for (n=0; nnumactiveULCCs[UE_id]; n++) { - // This is the actual CC_id in the list - CC_id = UE_list->ordered_ULCCids[n][UE_id]; - UE_template = &UE_list->UE_template[CC_id][UE_id]; - // frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id); - total_remaining_rbs[CC_id]=nb_rbs_allowed_slice_uplink[CC_id][UE_id] - first_rb[CC_id] - total_allocated_rbs[CC_id]; - - if (total_ue_count == 1 ) { - total_remaining_rbs[CC_id]+=1; - } - - if ( r == 0 ) { - while ( (UE_template->pre_allocated_nb_rb_ul > 0 ) && - (nb_allocated_rbs[CC_id][UE_id] < UE_template->pre_allocated_nb_rb_ul) && - (total_remaining_rbs[CC_id] > 0)) { - nb_allocated_rbs[CC_id][UE_id] = cmin(nb_allocated_rbs[CC_id][UE_id]+1,UE_template->pre_allocated_nb_rb_ul); - total_remaining_rbs[CC_id]--; - total_allocated_rbs[CC_id]++; - } - } else { - UE_template->pre_allocated_nb_rb_ul= nb_allocated_rbs[CC_id][UE_id]; - LOG_D(MAC,"******************UL Scheduling Information for UE%d CC_id %d ************************\n",UE_id, CC_id); - LOG_D(MAC,"[eNB %d] total RB allocated for UE%d CC_id %d = %d\n", module_idP, UE_id, CC_id, UE_template->pre_allocated_nb_rb_ul); - } - } - } - } - - for (CC_id=0; CC_idget_lte_frame_parms(module_idP,CC_id); - - if (total_allocated_rbs[CC_id]>0) { - LOG_D(MAC,"[eNB %d] total RB allocated for all UEs = %d/%d\n", module_idP, total_allocated_rbs[CC_id], nb_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id]); - } - } -} - -/* - * Main Uplink Slicing - * - */ - -void -flexran_schedule_ue_ul_spec_default(mid_t mod_id, - uint32_t frame, - uint32_t cooperation_flag, - int subframe, - unsigned char sched_subframe, - Protocol__FlexranMessage **ul_info) -//------------------------------------------------------------------------------ -{ - int i=0; - - flexran_agent_mac_create_empty_ul_config(mod_id, ul_info); - - total_slice_percentage_uplink=0; - avg_slice_percentage_uplink=1.0/n_active_slices_uplink; - - // reset the slice percentage for inactive slices - for (i = n_active_slices_uplink; i< MAX_NUM_SLICES; i++) { - slice_percentage_uplink[i]=0; - } - for (i = 0; i < n_active_slices_uplink; i++) { - if (slice_percentage_uplink[i] < 0 ){ - LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero", - mod_id, frame, subframe, i, slice_percentage_uplink[i]); - slice_percentage_uplink[i]=0; - } - total_slice_percentage_uplink+=slice_percentage_uplink[i]; - } - - for (i = 0; i < n_active_slices_uplink; i++) { - - // Load any updated functions - if (update_ul_scheduler[i] > 0 ) { - slice_sched_ul[i] = dlsym(NULL, ul_scheduler_type[i]); - update_ul_scheduler[i] = 0; - update_ul_scheduler_current[i] = 0; - //slice_percentage_current_uplink[i]= slice_percentage_uplink[i]; - //total_slice_percentage_current_uplink+=slice_percentage_uplink[i]; - //if (total_slice_percentage_current_uplink> 1) - // total_slice_percentage_current_uplink=1; - LOG_N(MAC,"update ul scheduler slice %d\n", i); - } - // the new total RB share is within the range - if (total_slice_percentage_uplink <= 1.0){ - - // check if the number of slices has changed, and log - if (n_active_slices_current_uplink != n_active_slices_uplink ){ - if ((n_active_slices_uplink > 0) && (n_active_slices_uplink <= MAX_NUM_SLICES)) { - LOG_N(MAC,"[eNB %d]frame %d subframe %d: number of active UL slices has changed: %d-->%d\n", - mod_id, frame, subframe, n_active_slices_current_uplink, n_active_slices_uplink); - - n_active_slices_current_uplink = n_active_slices_uplink; - - } else { - LOG_W(MAC,"invalid number of UL slices %d, revert to the previous value %d\n",n_active_slices_uplink, n_active_slices_current_uplink); - n_active_slices_uplink = n_active_slices_current_uplink; - } - } - - // check if the slice rb share has changed, and log the console - if (slice_percentage_current_uplink[i] != slice_percentage_uplink[i]){ - LOG_N(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", - mod_id, i, frame, subframe, total_slice_percentage_current_uplink, total_slice_percentage_uplink, slice_percentage_current_uplink[i], slice_percentage_uplink[i]); - total_slice_percentage_current_uplink= total_slice_percentage_uplink; - slice_percentage_current_uplink[i] = slice_percentage_uplink[i]; - - } - - // check if the slice max MCS, and log the console - if (slice_maxmcs_current_uplink[i] != slice_maxmcs_uplink[i]){ - if ((slice_maxmcs_uplink[i] >= 0) && (slice_maxmcs_uplink[i] <= 16)){ - LOG_N(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", - mod_id, i, frame, subframe, slice_maxmcs_current_uplink[i], slice_maxmcs_uplink[i]); - slice_maxmcs_current_uplink[i] = slice_maxmcs_uplink[i]; - } else { - LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid slice max mcs %d, revert the previous value %d\n",mod_id, i, slice_maxmcs_uplink[i],slice_maxmcs_current_uplink[i]); - slice_maxmcs_uplink[i]= slice_maxmcs_current_uplink[i]; - - } - } - - // check if a new scheduler, and log the console - if (update_ul_scheduler_current[i] != update_ul_scheduler[i]){ - LOG_N(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: UL scheduler for this slice is updated: %s \n", - mod_id, i, frame, subframe, ul_scheduler_type[i]); - - update_ul_scheduler_current[i] = update_ul_scheduler[i]; - } - } - else { - - if (n_active_slices_uplink == n_active_slices_current_uplink){ - LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n", - mod_id,i, - total_slice_percentage_current_uplink, total_slice_percentage_uplink); - if (slice_percentage_uplink[i] > avg_slice_percentage_uplink){ - slice_percentage_uplink[i]-=0.1; - total_slice_percentage_uplink-=0.1; - } - } else { - // here we can correct the values, e.g. reduce proportionally - LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n", - mod_id,i, - total_slice_percentage_current_uplink, total_slice_percentage_uplink, - n_active_slices_uplink, n_active_slices_current_uplink); - n_active_slices_uplink = n_active_slices_current_uplink; - slice_percentage_uplink[i] = slice_percentage_current_uplink[i]; - } - } - - // Run each enabled slice-specific schedulers one by one - slice_sched_ul[i](mod_id, frame, cooperation_flag, subframe, sched_subframe,ul_info); - } -} - -void -flexran_schedule_ue_ul_spec_embb(mid_t mod_id, - frame_t frame, - unsigned char cooperation_flag, - uint32_t subframe, - unsigned char sched_subframe, - Protocol__FlexranMessage **ul_info) - -{ - flexran_agent_schedule_ulsch_ue_spec(mod_id, - frame, - cooperation_flag, - subframe, - sched_subframe, - ul_info); - -} - - -void flexran_agent_schedule_ulsch_ue_spec(mid_t module_idP, - frame_t frameP, - unsigned char cooperation_flag, - sub_frame_t subframeP, - unsigned char sched_subframe, - Protocol__FlexranMessage **ul_info) { - - - uint16_t first_rb[MAX_NUM_CCs],i; - int CC_id; - eNB_MAC_INST *eNB=&eNB_mac_inst[module_idP]; - - start_meas(&eNB->schedule_ulsch); - - - for (CC_id=0; CC_idcommon_channels[CC_id].RA_template[i].RA_active == TRUE) && - (eNB->common_channels[CC_id].RA_template[i].generate_rar == 0) && - (eNB->common_channels[CC_id].RA_template[i].generate_Msg4 == 0) && - (eNB->common_channels[CC_id].RA_template[i].wait_ack_Msg4 == 0) && - (eNB->common_channels[CC_id].RA_template[i].Msg3_subframe == sched_subframe)) { - first_rb[CC_id]++; - eNB->common_channels[CC_id].RA_template[i].Msg3_subframe = -1; - break; - } - } - - /* - if (mac_xface->is_prach_subframe(&(mac_xface->lte_frame_parms),frameP,subframeP)) { - first_rb[CC_id] = (mac_xface->get_prach_prb_offset(&(mac_xface->lte_frame_parms), - */ - - } - - flexran_agent_schedule_ulsch_rnti(module_idP, cooperation_flag, frameP, subframeP, sched_subframe,first_rb); - - stop_meas(&eNB->schedule_ulsch); - -} - - - -void flexran_agent_schedule_ulsch_rnti(module_id_t module_idP, - unsigned char cooperation_flag, - frame_t frameP, - sub_frame_t subframeP, - unsigned char sched_subframe, - uint16_t *first_rb) -{ - - int UE_id; - uint8_t aggregation = 2; - rnti_t rnti = -1; - uint8_t round = 0; - uint8_t harq_pid = 0; - void *ULSCH_dci = NULL; - LTE_eNB_UE_stats *eNB_UE_stats = NULL; - DCI_PDU *DCI_pdu; - uint8_t status = 0; - uint8_t rb_table_index = -1; - uint16_t TBS = 0; - // int32_t buffer_occupancy=0; - uint32_t cqi_req,cshift,ndi,mcs=0,rballoc,tpc; - int32_t normalized_rx_power, target_rx_power=-90; - static int32_t tpc_accumulated=0; - - int n,CC_id = 0; - eNB_MAC_INST *eNB=&eNB_mac_inst[module_idP]; - UE_list_t *UE_list=&eNB->UE_list; - UE_TEMPLATE *UE_template; - UE_sched_ctrl *UE_sched_ctrl; - - // int rvidx_tab[4] = {0,2,3,1}; - LTE_DL_FRAME_PARMS *frame_parms; - int drop_ue=0; - - // LOG_I(MAC,"entering ulsch preprocesor\n"); - - - /*TODO*/ - int slice_id = 0; - - - _ulsch_scheduler_pre_processor(module_idP, - slice_id, - frameP, - subframeP, - first_rb); - - // LOG_I(MAC,"exiting ulsch preprocesor\n"); - - // loop over all active UEs - for (UE_id=UE_list->head_ul; UE_id>=0; UE_id=UE_list->next_ul[UE_id]) { - - // don't schedule if Msg4 is not received yet - if (UE_list->UE_template[UE_PCCID(module_idP,UE_id)][UE_id].configured==FALSE) { - LOG_I(MAC,"[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n", - module_idP,frameP,subframeP,UE_id); - continue; - } - - rnti = flexran_get_ue_crnti(module_idP, UE_id); - - if (rnti==NOT_A_RNTI) { - LOG_W(MAC,"[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n", module_idP,frameP,subframeP,UE_id); - continue; - } - - /* let's drop the UE if get_eNB_UE_stats returns NULL when calling it with any of the UE's active UL CCs */ - /* TODO: refine? */ - drop_ue = 0; - for (n=0; nnumactiveULCCs[UE_id]; n++) { - CC_id = UE_list->ordered_ULCCids[n][UE_id]; - if (mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti) == NULL) { - LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: no PHY context\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id); - drop_ue = 1; - break; - } - } - if (drop_ue == 1) { -/* we can't come here, ulsch_scheduler_pre_processor won't put in the list a UE with no PHY context */ -abort(); - /* TODO: this is a hack. Sometimes the UE has no PHY context but - * is still present in the MAC with 'ul_failure_timer' = 0 and - * 'ul_out_of_sync' = 0. It seems wrong and the UE stays there forever. Let's - * start an UL out of sync procedure in this case. - * The root cause of this problem has to be found and corrected. - * In the meantime, this hack... - */ - if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 0 && - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0) { - LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: UE in weird state, let's put it 'out of sync'\n", - module_idP,frameP,subframeP,UE_id,rnti,CC_id); - // inform RRC of failure and clear timer - mac_eNB_rrc_ul_failure(module_idP,CC_id,frameP,subframeP,rnti); - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer=0; - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync=1; - } - continue; - } - - // loop over all active UL CC_ids for this UE - for (n=0; nnumactiveULCCs[UE_id]; n++) { - // This is the actual CC_id in the list - CC_id = UE_list->ordered_ULCCids[n][UE_id]; - frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id); - eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti); - - aggregation=get_aggregation(get_bw_index(module_idP,CC_id), - eNB_UE_stats->DL_cqi[0], - format0); - - if (CCE_allocation_infeasible(module_idP,CC_id,0,subframeP,aggregation,rnti)) { - LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: not enough nCCE\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id); - continue; // break; - } else{ - LOG_D(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d mode %s: aggregation level %d\n", - module_idP,frameP,subframeP,UE_id,rnti,CC_id, mode_string[eNB_UE_stats->mode], 1<mode == PUSCH) { // ue has a ulsch channel - - DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu; - UE_template = &UE_list->UE_template[CC_id][UE_id]; - UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id]; - - if (flexran_get_harq(module_idP, CC_id, UE_id, frameP, subframeP, &harq_pid, &round, openair_harq_UL) == -1 ) { - LOG_W(MAC,"[eNB %d] Scheduler Frame %d, subframeP %d: candidate harq_pid from PHY for UE %d CC %d RNTI %x\n", - module_idP,frameP,subframeP, UE_id, CC_id, rnti); - continue; - } else - LOG_T(MAC,"[eNB %d] Frame %d, subframeP %d, UE %d CC %d : got harq pid %d round %d (rnti %x,mode %s)\n", - module_idP,frameP,subframeP,UE_id,CC_id, harq_pid, round,rnti,mode_string[eNB_UE_stats->mode]); - - PHY_vars_eNB_g[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->ul_total_buffer; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO,PHY_vars_eNB_g[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP]); - if (((UE_is_to_be_scheduled(module_idP,CC_id,UE_id)>0)) || (round>0))// || ((frameP%10)==0)) - // if there is information on bsr of DCCH, DTCH or if there is UL_SR, or if there is a packet to retransmit, or we want to schedule a periodic feedback every 10 frames - { - LOG_D(MAC,"[eNB %d][PUSCH] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d)\n", - module_idP,frameP,subframeP,UE_id,rnti,round,UE_template->ul_SR, - UE_sched_ctrl->ul_inactivity_timer, - UE_sched_ctrl->ul_failure_timer); - // reset the scheduling request - UE_template->ul_SR = 0; - // status = mac_eNB_get_rrc_status(module_idP,rnti); - status = flexran_get_rrc_status(module_idP, rnti); - - if (status < RRC_CONNECTED) - cqi_req = 0; - else if (UE_sched_ctrl->cqi_req_timer>30) { - cqi_req = 1; - UE_sched_ctrl->cqi_req_timer=0; - } - else - cqi_req = 0; - - //power control - //compute the expected ULSCH RX power (for the stats) - - // this is the normalized RX power and this should be constant (regardless of mcs - normalized_rx_power = eNB_UE_stats->UL_rssi[0]; - target_rx_power = mac_xface->get_target_pusch_rx_power(module_idP,CC_id); - - // this assumes accumulated tpc - // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out - int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame*10+UE_template->pusch_tpc_tx_subframe; - if (((framex10psubframe+10)<=(frameP*10+subframeP)) || //normal case - ((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=10)))) //frame wrap-around - { - UE_template->pusch_tpc_tx_frame=frameP; - UE_template->pusch_tpc_tx_subframe=subframeP; - if (normalized_rx_power>(target_rx_power+1)) { - tpc = 0; //-1 - tpc_accumulated--; - } else if (normalized_rx_power<(target_rx_power-1)) { - tpc = 2; //+1 - tpc_accumulated++; - } else { - tpc = 1; //0 - } - } else { - tpc = 1; //0 - } - - if (tpc!=1) { - LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", - module_idP,frameP,subframeP,harq_pid,tpc, - tpc_accumulated,normalized_rx_power,target_rx_power); - } - - // new transmission - if (round==0) { - - ndi = 1-UE_template->oldNDI_UL[harq_pid]; - UE_template->oldNDI_UL[harq_pid]=ndi; - UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power=normalized_rx_power; - UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power=target_rx_power; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=UE_template->pre_assigned_mcs_ul; - mcs = UE_template->pre_assigned_mcs_ul;//cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS - if (UE_template->pre_allocated_rb_table_index_ul >=0) { - rb_table_index=UE_template->pre_allocated_rb_table_index_ul; - } else { - mcs=10;//cmin (10, openair_daq_vars.target_ue_ul_mcs); - rb_table_index=5; // for PHR - } - - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs; - // buffer_occupancy = UE_template->ul_total_buffer; - - while (((rb_table[rb_table_index]>(nb_rbs_allowed_slice_uplink[CC_id][UE_id]-1-first_rb[CC_id])) || - (rb_table[rb_table_index]>45)) && - (rb_table_index>0)) { - rb_table_index--; - } - - TBS = mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]); - UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=rb_table[rb_table_index]; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS=TBS; - // buffer_occupancy -= TBS; - rballoc = mac_xface->computeRIV(frame_parms->N_RB_UL, - first_rb[CC_id], - rb_table[rb_table_index]); - - T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), T_INT(mcs), T_INT(first_rb[CC_id]), T_INT(rb_table[rb_table_index]), - T_INT(TBS), T_INT(ndi)); - - if (mac_eNB_get_rrc_status(module_idP,rnti) < RRC_CONNECTED) - LOG_I(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n", - module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,mcs, - first_rb[CC_id],rb_table[rb_table_index], - rb_table_index,TBS,harq_pid); - - // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB) - // increment for next UE allocation - first_rb[CC_id]+=rb_table[rb_table_index]; - //store for possible retransmission - UE_template->nb_rb_ul[harq_pid] = rb_table[rb_table_index]; - UE_sched_ctrl->ul_scheduled |= (1<head) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED,UE_sched_ctrl->ul_scheduled); - - // adjust total UL buffer status by TBS, wait for UL sdus to do final update - LOG_D(MAC,"[eNB %d] CC_id %d UE %d/%x : adjusting ul_total_buffer, old %d, TBS %d\n", module_idP,CC_id,UE_id,rnti,UE_template->ul_total_buffer,TBS); - if (UE_template->ul_total_buffer > TBS) - UE_template->ul_total_buffer -= TBS; - else - UE_template->ul_total_buffer = 0; - LOG_D(MAC,"ul_total_buffer, new %d\n", UE_template->ul_total_buffer); - // Cyclic shift for DM RS - cshift = 0;// values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1) - - if (frame_parms->frame_type == TDD) { - switch (frame_parms->N_RB_UL) { - case 6: - ULSCH_dci = UE_template->ULSCH_DCI[harq_pid]; - - ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->type = 0; - ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->hopping = 0; - ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->rballoc = rballoc; - ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->mcs = mcs; - ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->ndi = ndi; - ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->TPC = tpc; - ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->cshift = cshift; - ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->padding = 0; - ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->dai = UE_template->DAI_ul[sched_subframe]; - ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req = cqi_req; - - add_ue_spec_dci(DCI_pdu, - ULSCH_dci, - rnti, - sizeof(DCI0_1_5MHz_TDD_1_6_t), - aggregation, - sizeof_DCI0_1_5MHz_TDD_1_6_t, - format0, - 0); - break; - - default: - case 25: - ULSCH_dci = UE_template->ULSCH_DCI[harq_pid]; - - ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->type = 0; - ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->hopping = 0; - ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->rballoc = rballoc; - ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->mcs = mcs; - ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->ndi = ndi; - ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->TPC = tpc; - ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->cshift = cshift; - ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->padding = 0; - ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->dai = UE_template->DAI_ul[sched_subframe]; - ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req = cqi_req; - - add_ue_spec_dci(DCI_pdu, - ULSCH_dci, - rnti, - sizeof(DCI0_5MHz_TDD_1_6_t), - aggregation, - sizeof_DCI0_5MHz_TDD_1_6_t, - format0, - 0); - break; - - case 50: - ULSCH_dci = UE_template->ULSCH_DCI[harq_pid]; - - ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->type = 0; - ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->hopping = 0; - ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->rballoc = rballoc; - ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->mcs = mcs; - ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->ndi = ndi; - ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->TPC = tpc; - ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->cshift = cshift; - ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->padding = 0; - ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->dai = UE_template->DAI_ul[sched_subframe]; - ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req = cqi_req; - - add_ue_spec_dci(DCI_pdu, - ULSCH_dci, - rnti, - sizeof(DCI0_10MHz_TDD_1_6_t), - aggregation, - sizeof_DCI0_10MHz_TDD_1_6_t, - format0, - 0); - break; - - case 100: - ULSCH_dci = UE_template->ULSCH_DCI[harq_pid]; - - ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->type = 0; - ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->hopping = 0; - ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->rballoc = rballoc; - ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->mcs = mcs; - ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->ndi = ndi; - ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->TPC = tpc; - ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->cshift = cshift; - ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->padding = 0; - ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->dai = UE_template->DAI_ul[sched_subframe]; - ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req = cqi_req; - - add_ue_spec_dci(DCI_pdu, - ULSCH_dci, - rnti, - sizeof(DCI0_20MHz_TDD_1_6_t), - aggregation, - sizeof_DCI0_20MHz_TDD_1_6_t, - format0, - 0); - break; - } - } // TDD - else { //FDD - switch (frame_parms->N_RB_UL) { - case 25: - default: - - ULSCH_dci = UE_template->ULSCH_DCI[harq_pid]; - - ((DCI0_5MHz_FDD_t *)ULSCH_dci)->type = 0; - ((DCI0_5MHz_FDD_t *)ULSCH_dci)->hopping = 0; - ((DCI0_5MHz_FDD_t *)ULSCH_dci)->rballoc = rballoc; - ((DCI0_5MHz_FDD_t *)ULSCH_dci)->mcs = mcs; - ((DCI0_5MHz_FDD_t *)ULSCH_dci)->ndi = ndi; - ((DCI0_5MHz_FDD_t *)ULSCH_dci)->TPC = tpc; - ((DCI0_5MHz_FDD_t *)ULSCH_dci)->cshift = cshift; - ((DCI0_5MHz_FDD_t *)ULSCH_dci)->padding = 0; - ((DCI0_5MHz_FDD_t *)ULSCH_dci)->cqi_req = cqi_req; - - add_ue_spec_dci(DCI_pdu, - ULSCH_dci, - rnti, - sizeof(DCI0_5MHz_FDD_t), - aggregation, - sizeof_DCI0_5MHz_FDD_t, - format0, - 0); - break; - - case 6: - ULSCH_dci = UE_template->ULSCH_DCI[harq_pid]; - - ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->type = 0; - ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->hopping = 0; - ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->rballoc = rballoc; - ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->mcs = mcs; - ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->ndi = ndi; - ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->TPC = tpc; - ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->cshift = cshift; - ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->padding = 0; - ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->cqi_req = cqi_req; - - add_ue_spec_dci(DCI_pdu, - ULSCH_dci, - rnti, - sizeof(DCI0_1_5MHz_FDD_t), - aggregation, - sizeof_DCI0_1_5MHz_FDD_t, - format0, - 0); - break; - - case 50: - ULSCH_dci = UE_template->ULSCH_DCI[harq_pid]; - - ((DCI0_10MHz_FDD_t *)ULSCH_dci)->type = 0; - ((DCI0_10MHz_FDD_t *)ULSCH_dci)->hopping = 0; - ((DCI0_10MHz_FDD_t *)ULSCH_dci)->rballoc = rballoc; - ((DCI0_10MHz_FDD_t *)ULSCH_dci)->mcs = mcs; - ((DCI0_10MHz_FDD_t *)ULSCH_dci)->ndi = ndi; - ((DCI0_10MHz_FDD_t *)ULSCH_dci)->TPC = tpc; - ((DCI0_10MHz_FDD_t *)ULSCH_dci)->padding = 0; - ((DCI0_10MHz_FDD_t *)ULSCH_dci)->cshift = cshift; - ((DCI0_10MHz_FDD_t *)ULSCH_dci)->cqi_req = cqi_req; - - add_ue_spec_dci(DCI_pdu, - ULSCH_dci, - rnti, - sizeof(DCI0_10MHz_FDD_t), - aggregation, - sizeof_DCI0_10MHz_FDD_t, - format0, - 0); - break; - - case 100: - ULSCH_dci = UE_template->ULSCH_DCI[harq_pid]; - - ((DCI0_20MHz_FDD_t *)ULSCH_dci)->type = 0; - ((DCI0_20MHz_FDD_t *)ULSCH_dci)->hopping = 0; - ((DCI0_20MHz_FDD_t *)ULSCH_dci)->rballoc = rballoc; - ((DCI0_20MHz_FDD_t *)ULSCH_dci)->mcs = mcs; - ((DCI0_20MHz_FDD_t *)ULSCH_dci)->ndi = ndi; - ((DCI0_20MHz_FDD_t *)ULSCH_dci)->TPC = tpc; - ((DCI0_20MHz_FDD_t *)ULSCH_dci)->padding = 0; - ((DCI0_20MHz_FDD_t *)ULSCH_dci)->cshift = cshift; - ((DCI0_20MHz_FDD_t *)ULSCH_dci)->cqi_req = cqi_req; - - add_ue_spec_dci(DCI_pdu, - ULSCH_dci, - rnti, - sizeof(DCI0_20MHz_FDD_t), - aggregation, - sizeof_DCI0_20MHz_FDD_t, - format0, - 0); - break; - - } - } - - - add_ue_ulsch_info(module_idP, - CC_id, - UE_id, - subframeP, - S_UL_SCHEDULED); - - LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP,CC_id,frameP,subframeP,UE_id); -#ifdef DEBUG - dump_dci(frame_parms, &DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci-1]); -#endif - - } - else { - T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), T_INT(mcs), T_INT(first_rb[CC_id]), T_INT(rb_table[rb_table_index]), - T_INT(round)); - - LOG_D(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d,round %d)\n", - module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,mcs, - first_rb[CC_id],rb_table[rb_table_index], - rb_table_index,TBS,harq_pid,round); - }/* - else if (round > 0) { //we schedule a retransmission - - ndi = UE_template->oldNDI_UL[harq_pid]; - - if ((round&3)==0) { - mcs = openair_daq_vars.target_ue_ul_mcs; - } else { - mcs = rvidx_tab[round&3] + 28; //not correct for round==4! - - } - - LOG_I(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE retransmission (mcs %d, first rb %d, nb_rb %d, harq_pid %d, round %d)\n", - module_idP,UE_id,rnti,CC_id,frameP,subframeP,mcs, - first_rb[CC_id],UE_template->nb_rb_ul[harq_pid], - harq_pid, round); - - rballoc = mac_xface->computeRIV(frame_parms->N_RB_UL, - first_rb[CC_id], - UE_template->nb_rb_ul[harq_pid]); - first_rb[CC_id]+=UE_template->nb_rb_ul[harq_pid]; // increment for next UE allocation - - UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission_rx+=1; - UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx_rx=UE_template->nb_rb_ul[harq_pid]; - UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=UE_template->nb_rb_ul[harq_pid]; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=mcs; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs; - } - */ - - } // UE_is_to_be_scheduled - } // UE is in PUSCH - } // loop over UE_id - } // loop of CC_id -} - diff --git a/openair2/LAYER2/MAC/flexran_dci_conversions.h b/openair2/LAYER2/MAC/flexran_dci_conversions.h deleted file mode 100644 index 5c18b43104..0000000000 --- a/openair2/LAYER2/MAC/flexran_dci_conversions.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file flexran_dci_conversions.h - * \brief Conversion helpers from flexran messages to OAI formats DCI - * \author Xenofon Foukas - * \date 2016 - * \version 0.1 - */ - -#ifndef LAYER2_MAC_FLEXRAN_DCI_CONVERISIONS_H__ -#define LAYER2_MAC_DCI_FLEXRAN_CONVERISIONS_H__ - -#define FILL_DCI_FDD_1(TYPE, DCI, FLEXRAN_DCI) \ - ((TYPE*)DCI)->harq_pid = FLEXRAN_DCI->harq_process; \ - ((TYPE*)DCI)->rv = FLEXRAN_DCI->rv[0]; \ - ((TYPE*)DCI)->rballoc = FLEXRAN_DCI->rb_bitmap; \ - ((TYPE*)DCI)->rah = FLEXRAN_DCI->res_alloc; \ - ((TYPE*)DCI)->mcs = FLEXRAN_DCI->mcs[0]; \ - ((TYPE*)DCI)->TPC = FLEXRAN_DCI->tpc; \ - ((TYPE*)DCI)->ndi = FLEXRAN_DCI->ndi[0]; - -#define FILL_DCI_TDD_1(TYPE, DCI, FLEXRAN_DCI) \ - ((TYPE*)DCI)->harq_pid = FLEXRAN_DCI->harq_process; \ - ((TYPE*)DCI)->rv = FLEXRAN_DCI->rv[0]; \ - ((TYPE*)DCI)->dai = FLEXRAN_DCI->dai; \ - ((TYPE*)DCI)->rballoc = FLEXRAN_DCI->rb_bitmap; \ - ((TYPE*)DCI)->rah = FLEXRAN_DCI->res_alloc; \ - ((TYPE*)DCI)->mcs = FLEXRAN_DCI->mcs[0]; \ - ((TYPE*)DCI)->TPC = FLEXRAN_DCI->tpc; \ - ((TYPE*)DCI)->ndi = FLEXRAN_DCI->ndi[0]; - -#endif From 024904db903a4246657056aeef07130c492e5829 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 15 Jan 2018 18:32:35 +0100 Subject: [PATCH 074/195] repair enb_app.c after merge, delete unnecessary code --- openair2/ENB_APP/enb_app.c | 155 ++----------------------------------- 1 file changed, 6 insertions(+), 149 deletions(-) diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index 3b3c8c24c7..f1a5437e98 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -50,10 +50,6 @@ # include "gtpv1u_eNB_task.h" # endif -#if defined(FLEXRAN_AGENT_SB_IF) -# include "targets/RT/USER/lte-softmodem.h" -#endif - extern unsigned char NB_eNB_INST; #endif @@ -102,102 +98,6 @@ static void configure_rrc(uint32_t enb_id) if (RC.rrc[enb_id]) { RCconfig_RRC(msg_p,enb_id, RC.rrc[enb_id]); - /* - RRC_CONFIGURATION_REQ (msg_p).cell_identity = enb_properties->properties[enb_id]->eNB_id; - RRC_CONFIGURATION_REQ (msg_p).tac = enb_properties->properties[enb_id]->tac; - RRC_CONFIGURATION_REQ (msg_p).mcc = enb_properties->properties[enb_id]->mcc; - RRC_CONFIGURATION_REQ (msg_p).mnc = enb_properties->properties[enb_id]->mnc; - RRC_CONFIGURATION_REQ (msg_p).mnc_digit_length = enb_properties->properties[enb_id]->mnc_digit_length; - - for (CC_id=0; CC_idproperties[enb_id]->frame_type[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).tdd_config[CC_id] = enb_properties->properties[enb_id]->tdd_config[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).tdd_config_s[CC_id] = enb_properties->properties[enb_id]->tdd_config_s[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).eutra_band[CC_id] = enb_properties->properties[enb_id]->eutra_band[CC_id]; - - // RACH-Config - RRC_CONFIGURATION_REQ (msg_p).rach_numberOfRA_Preambles[CC_id] = enb_properties->properties[enb_id]->rach_numberOfRA_Preambles[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).rach_preamblesGroupAConfig[CC_id] = enb_properties->properties[enb_id]->rach_preamblesGroupAConfig[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).rach_sizeOfRA_PreamblesGroupA[CC_id] = enb_properties->properties[enb_id]->rach_sizeOfRA_PreamblesGroupA[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).rach_messageSizeGroupA[CC_id] = enb_properties->properties[enb_id]->rach_messageSizeGroupA[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[CC_id] = enb_properties->properties[enb_id]->rach_messagePowerOffsetGroupB[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).rach_powerRampingStep[CC_id] = enb_properties->properties[enb_id]->rach_powerRampingStep[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).rach_preambleInitialReceivedTargetPower[CC_id] = enb_properties->properties[enb_id]->rach_preambleInitialReceivedTargetPower[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[CC_id] = enb_properties->properties[enb_id]->rach_preambleTransMax[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).rach_raResponseWindowSize[CC_id] = enb_properties->properties[enb_id]->rach_raResponseWindowSize[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).rach_macContentionResolutionTimer[CC_id] = enb_properties->properties[enb_id]->rach_macContentionResolutionTimer[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).rach_maxHARQ_Msg3Tx[CC_id] = enb_properties->properties[enb_id]->rach_maxHARQ_Msg3Tx[CC_id]; - - // BCCH-Config - RRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff[CC_id] = enb_properties->properties[enb_id]->bcch_modificationPeriodCoeff[CC_id]; - - // PCCH-Config - RRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle[CC_id] = enb_properties->properties[enb_id]->pcch_defaultPagingCycle[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pcch_nB[CC_id] = enb_properties->properties[enb_id]->pcch_nB[CC_id]; - - // PRACH-Config - RRC_CONFIGURATION_REQ (msg_p).prach_root[CC_id] = enb_properties->properties[enb_id]->prach_root[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).prach_config_index[CC_id] = enb_properties->properties[enb_id]->prach_config_index[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).prach_high_speed[CC_id] = enb_properties->properties[enb_id]->prach_high_speed[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).prach_zero_correlation[CC_id] = enb_properties->properties[enb_id]->prach_zero_correlation[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).prach_freq_offset[CC_id] = enb_properties->properties[enb_id]->prach_freq_offset[CC_id]; - - // PDSCH-Config - RRC_CONFIGURATION_REQ (msg_p).pdsch_referenceSignalPower[CC_id] = enb_properties->properties[enb_id]->pdsch_referenceSignalPower[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pdsch_p_b[CC_id] = enb_properties->properties[enb_id]->pdsch_p_b[CC_id]; - - // PUSCH-Config - RRC_CONFIGURATION_REQ (msg_p).pusch_n_SB[CC_id] = enb_properties->properties[enb_id]->pusch_n_SB[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pusch_hoppingMode[CC_id] = enb_properties->properties[enb_id]->pusch_hoppingMode[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pusch_hoppingOffset[CC_id] = enb_properties->properties[enb_id]->pusch_hoppingOffset[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pusch_enable64QAM[CC_id] = enb_properties->properties[enb_id]->pusch_enable64QAM[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pusch_groupHoppingEnabled[CC_id] = enb_properties->properties[enb_id]->pusch_groupHoppingEnabled[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pusch_groupAssignment[CC_id] = enb_properties->properties[enb_id]->pusch_groupAssignment[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pusch_sequenceHoppingEnabled[CC_id] = enb_properties->properties[enb_id]->pusch_sequenceHoppingEnabled[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pusch_nDMRS1[CC_id] = enb_properties->properties[enb_id]->pusch_nDMRS1[CC_id]; - - // PUCCH-Config - - RRC_CONFIGURATION_REQ (msg_p).pucch_delta_shift[CC_id] = enb_properties->properties[enb_id]->pucch_delta_shift[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pucch_nRB_CQI[CC_id] = enb_properties->properties[enb_id]->pucch_nRB_CQI[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pucch_nCS_AN[CC_id] = enb_properties->properties[enb_id]->pucch_nCS_AN[CC_id]; -#if !defined(Rel10) && !defined(Rel14) - RRC_CONFIGURATION_REQ (msg_p).pucch_n1_AN[CC_id] = enb_properties->properties[enb_id]->pucch_n1_AN[CC_id]; -#endif - - // SRS Config - RRC_CONFIGURATION_REQ (msg_p).srs_enable[CC_id] = enb_properties->properties[enb_id]->srs_enable[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).srs_BandwidthConfig[CC_id] = enb_properties->properties[enb_id]->srs_BandwidthConfig[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).srs_SubframeConfig[CC_id] = enb_properties->properties[enb_id]->srs_SubframeConfig[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).srs_ackNackST[CC_id] = enb_properties->properties[enb_id]->srs_ackNackST[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).srs_MaxUpPts[CC_id] = enb_properties->properties[enb_id]->srs_MaxUpPts[CC_id]; - - // uplinkPowerControlCommon - - RRC_CONFIGURATION_REQ (msg_p).pusch_p0_Nominal[CC_id] = enb_properties->properties[enb_id]->pusch_p0_Nominal[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pucch_p0_Nominal[CC_id] = enb_properties->properties[enb_id]->pucch_p0_Nominal[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[CC_id] = enb_properties->properties[enb_id]->pusch_alpha[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1[CC_id] = enb_properties->properties[enb_id]->pucch_deltaF_Format1[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1b[CC_id] = enb_properties->properties[enb_id]->pucch_deltaF_Format1b[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2[CC_id] = enb_properties->properties[enb_id]->pucch_deltaF_Format2[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2a[CC_id] = enb_properties->properties[enb_id]->pucch_deltaF_Format2a[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2b[CC_id] = enb_properties->properties[enb_id]->pucch_deltaF_Format2b[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).msg3_delta_Preamble[CC_id] = enb_properties->properties[enb_id]->msg3_delta_Preamble[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).ul_CyclicPrefixLength[CC_id] = enb_properties->properties[enb_id]->ul_CyclicPrefixLength[CC_id]; - - // UE Timers and Constants - - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[CC_id] = enb_properties->properties[enb_id]->ue_TimersAndConstants_t300[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[CC_id] = enb_properties->properties[enb_id]->ue_TimersAndConstants_t301[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[CC_id] = enb_properties->properties[enb_id]->ue_TimersAndConstants_t310[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[CC_id] = enb_properties->properties[enb_id]->ue_TimersAndConstants_n310[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[CC_id] = enb_properties->properties[enb_id]->ue_TimersAndConstants_t311[CC_id]; - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[CC_id] = enb_properties->properties[enb_id]->ue_TimersAndConstants_n311[CC_id]; - - RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[CC_id] = enb_properties->properties[enb_id]->ue_TransmissionMode[CC_id]; - - } - */ LOG_I(ENB_APP,"Sending configuration message to RRC task\n"); itti_send_msg_to_task (TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); @@ -206,15 +106,6 @@ static void configure_rrc(uint32_t enb_id) else AssertFatal(0,"RRC context for eNB %d not allocated\n",enb_id); } -void enb_app_start_phy_rrc(uint32_t enb_id_start, uint32_t enb_id_end) -{ - Enb_properties_array_t *enb_properties_p = enb_config_get(); - for (uint32_t enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { - configure_phy(enb_id, enb_properties_p); - configure_rrc(enb_id, enb_properties_p); - } -} - /*------------------------------------------------------------------------------*/ # if defined(ENABLE_USE_MME) static uint32_t eNB_app_register(uint32_t enb_id_start, uint32_t enb_id_end)//, const Enb_properties_array_t *enb_properties) @@ -240,44 +131,6 @@ static uint32_t eNB_app_register(uint32_t enb_id_start, uint32_t enb_id_end)//, s1ap_register_eNB = &S1AP_REGISTER_ENB_REQ(msg_p); LOG_I(ENB_APP,"default drx %d\n",s1ap_register_eNB->default_drx); - /* - - s1ap_register_eNB->eNB_id = enb_properties->properties[enb_id]->eNB_id; - s1ap_register_eNB->cell_type = enb_properties->properties[enb_id]->cell_type; - s1ap_register_eNB->eNB_name = enb_properties->properties[enb_id]->eNB_name; - s1ap_register_eNB->tac = enb_properties->properties[enb_id]->tac; - s1ap_register_eNB->mcc = enb_properties->properties[enb_id]->mcc; - s1ap_register_eNB->mnc = enb_properties->properties[enb_id]->mnc; - s1ap_register_eNB->mnc_digit_length = enb_properties->properties[enb_id]->mnc_digit_length; - s1ap_register_eNB->default_drx = enb_properties->properties[enb_id]->pcch_defaultPagingCycle[0]; - - s1ap_register_eNB->nb_mme = enb_properties->properties[enb_id]->nb_mme; - - AssertFatal (s1ap_register_eNB->nb_mme <= S1AP_MAX_NB_MME_IP_ADDRESS, "Too many MME for eNB %d (%d/%d)!", enb_id, s1ap_register_eNB->nb_mme, - S1AP_MAX_NB_MME_IP_ADDRESS); - - for (mme_id = 0; mme_id < s1ap_register_eNB->nb_mme; mme_id++) { - s1ap_register_eNB->mme_ip_address[mme_id].ipv4 = enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv4; - s1ap_register_eNB->mme_ip_address[mme_id].ipv6 = enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv6; - strncpy (s1ap_register_eNB->mme_ip_address[mme_id].ipv4_address, - enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv4_address, - sizeof(s1ap_register_eNB->mme_ip_address[0].ipv4_address)); - strncpy (s1ap_register_eNB->mme_ip_address[mme_id].ipv6_address, - enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv6_address, - sizeof(s1ap_register_eNB->mme_ip_address[0].ipv6_address)); - } - - s1ap_register_eNB->sctp_in_streams = enb_properties->properties[enb_id]->sctp_in_streams; - s1ap_register_eNB->sctp_out_streams = enb_properties->properties[enb_id]->sctp_out_streams; - - - s1ap_register_eNB->enb_ip_address.ipv6 = 0; - s1ap_register_eNB->enb_ip_address.ipv4 = 1; - addr.s_addr = enb_properties->properties[enb_id]->enb_ipv4_address_for_S1_MME; - str = inet_ntoa(addr); - strcpy(s1ap_register_eNB->enb_ip_address.ipv4_address, str); - - */ LOG_I(ENB_APP,"[eNB %d] eNB_app_register for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id)); itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); @@ -297,13 +150,13 @@ void *eNB_app_task(void *args_p) #if defined(ENABLE_ITTI) uint32_t enb_nb = RC.nb_inst; uint32_t enb_id_start = 0; - uint32_t enb_i; uint32_t enb_id_end = enb_id_start + enb_nb; # if defined(ENABLE_USE_MME) uint32_t register_enb_pending; uint32_t registered_enb; long enb_register_retry_timer_id; # endif + uint32_t enb_id; MessageDef *msg_p = NULL; const char *msg_name = NULL; instance_t instance; @@ -340,7 +193,11 @@ void *eNB_app_task(void *args_p) RC.rrc = (eNB_RRC_INST **)malloc(RC.nb_inst*sizeof(eNB_RRC_INST *)); - enb_app_start_phy_rrc(enb_id_start, enb_id_end); + for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { + RC.rrc[enb_id] = (eNB_RRC_INST*)malloc(sizeof(eNB_RRC_INST)); + memset((void *)RC.rrc[enb_id],0,sizeof(eNB_RRC_INST)); + configure_rrc(enb_id); + } # if defined(ENABLE_USE_MME) /* Try to register each eNB */ From 7dfac059b0757f2e320d7adbc1779d44b29637d3 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 15 Jan 2018 18:34:58 +0100 Subject: [PATCH 075/195] Review Navid: UL Scheduler: make slice aware --- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 3 +++ openair2/LAYER2/MAC/pre_processor.c | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index b5256820bb..119f5b8074 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -1233,6 +1233,9 @@ schedule_ulsch_rnti(module_id_t module_idP, for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) { + if (flexran_slice_member(UE_id, slice_id) == 0) + continue; + // don't schedule if Msg4 is not received yet if (UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id]. configured == FALSE) { diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index a0cc0dd412..af5b6f660b 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -614,6 +614,9 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, if (UE_list->active[i] != TRUE) continue; + if (!flexran_slice_member(UE_id, slice_id)) + continue; + UE_id = i; // Initialize scheduling information for all active UEs @@ -820,6 +823,8 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (flexran_slice_member(i, slice_id) == 0) + continue; transmission_mode = get_tmode(Mod_id, CC_id, UE_id); // mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0); From a03877e7f710cf1c71496e36db5993aa50b8df44 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 15 Jan 2018 18:36:29 +0100 Subject: [PATCH 076/195] delete unnecessary code --- openair2/LAYER2/MAC/eNB_scheduler_primitives.c | 17 ----------------- openair2/LAYER2/MAC/proto.h | 2 -- 2 files changed, 19 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 4a316cf92c..fe885d38cc 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -1980,11 +1980,6 @@ uint8_t find_active_UEs(module_id_t module_idP,int CC_id){ } */ -int UE_BSR (uint8_t mod_id, uint8_t ue_id, uint8_t lcid) { - - if (eNB_mac_inst == NULL) return 0; - return eNB_mac_inst[mod_id].UE_list.UE_template[UE_PCCID(mod_id,ue_id)][ue_id].bsr_info[lcid]; -} // get aggregation (L) form phy for a give UE unsigned char @@ -2108,12 +2103,6 @@ int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP, int harq_pidP return (-1); } -int CC_id_rnti_downlink (uint8_t mod_id, int CC_index, uint16_t ue_rnti) { - - return eNB_mac_inst[mod_id].UE_list.ordered_CCids[CC_index][ue_rnti]; -} - - //------------------------------------------------------------------------------ int rrc_mac_remove_ue(module_id_t mod_idP, rnti_t rntiP) //------------------------------------------------------------------------------ @@ -4480,14 +4469,8 @@ uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, int total_rbs) return (uint16_t) floor(rb_percentage * total_rbs); } -int flexran_slice_maxmcs(int slice_id) -{ - return slice_maxmcs[slice_id]; -} - int flexran_slice_member(int UE_id, int slice_id) { - if ((slice_id < 0) || (slice_id > n_active_slices)) LOG_W(MAC, "out of range slice id %d\n", slice_id); diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/proto.h index a83aabef27..f237bbf299 100644 --- a/openair2/LAYER2/MAC/proto.h +++ b/openair2/LAYER2/MAC/proto.h @@ -1168,7 +1168,5 @@ uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, int total_rbs); int flexran_slice_member(int UE_id, int slice_id); -int flexran_slice_maxmcs(int slice_id;) - #endif /** @}*/ From 9b4d3bbae75f90f5bd56c3952696b29fb38df216 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 15 Jan 2018 18:38:05 +0100 Subject: [PATCH 077/195] move scheduler function pointer typedef to proto.h --- openair2/LAYER2/MAC/proto.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/proto.h index f237bbf299..00ea994ddf 100644 --- a/openair2/LAYER2/MAC/proto.h +++ b/openair2/LAYER2/MAC/proto.h @@ -35,6 +35,25 @@ * @{ */ +/** + * slice specific scheduler + */ +/* TODO Navid: Protocol__FlexranMessage -> unknown when compiling without + * FlexRAN, what to do with it? */ +typedef void (*slice_scheduler_dl)(module_id_t mod_id, + int slice_id, + uint32_t frame, + uint32_t subframe, + int *mbsfn_flag/*, + Protocol__FlexranMessage **dl_info*/); + +typedef void (*slice_scheduler_ul)(module_id_t mod_id, + frame_t frame, + unsigned char cooperation_flag, + uint32_t subframe, + unsigned char sched_subframe/*, + Protocol__FlexranMessage **ul_info*/); + /** \fn void schedule_mib(module_id_t module_idP,frame_t frameP,sub_frame_t subframe); \brief MIB scheduling for PBCH. This function requests the MIB from RRC and provides it to L1. @param Mod_id Instance ID of eNB From dfece3ff58f9bee908e1ace4e38babb7c3a8d6ce Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 16 Jan 2018 17:23:26 +0100 Subject: [PATCH 078/195] correct scheduler typedefs --- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 4 ++-- openair2/LAYER2/MAC/proto.h | 24 ++++++++++++----------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 119f5b8074..7076827896 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -1174,8 +1174,8 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, } // Run each enabled slice-specific schedulers one by one - slice_sched_ul[i](module_idP, i,frameP, subframeP, sched_subframe, - first_rb); + /* TODO Navid What is the right call for this message? */ + slice_sched_ul[i](module_idP, i, frameP, subframeP, sched_subframe, first_rb); } diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/proto.h index 00ea994ddf..842e1d7080 100644 --- a/openair2/LAYER2/MAC/proto.h +++ b/openair2/LAYER2/MAC/proto.h @@ -39,20 +39,22 @@ * slice specific scheduler */ /* TODO Navid: Protocol__FlexranMessage -> unknown when compiling without - * FlexRAN, what to do with it? */ + * FlexRAN, what to do with it? Matches schedule_ue_spec now */ typedef void (*slice_scheduler_dl)(module_id_t mod_id, - int slice_id, - uint32_t frame, - uint32_t subframe, - int *mbsfn_flag/*, - Protocol__FlexranMessage **dl_info*/); + slice_id_t slice_id, + frame_t frame, + sub_frame_t subframe, + int *mbsfn_flag + /* Protocol__FlexranMessage **dl_info*/); +/* TODO Navid: the same as above, matches schedule_ulsch_rnti now */ typedef void (*slice_scheduler_ul)(module_id_t mod_id, - frame_t frame, - unsigned char cooperation_flag, - uint32_t subframe, - unsigned char sched_subframe/*, - Protocol__FlexranMessage **ul_info*/); + slice_id_t slice_id, + frame_t frame, + sub_frame_t subframe, + unsigned char sched_subframe, + uint16_t *first_rb + /* Protocol__FlexranMessage **ul_info*/); /** \fn void schedule_mib(module_id_t module_idP,frame_t frameP,sub_frame_t subframe); \brief MIB scheduling for PBCH. This function requests the MIB from RRC and provides it to L1. From 6a6729bdaca3016286b9239ec9baaae1b67b1875 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 15 Jan 2018 18:38:29 +0100 Subject: [PATCH 079/195] fix various compilaton errors due to merge --- .../ENB_APP/flexran_agent_common_internal.c | 8 +- openair2/LAYER2/MAC/defs.h | 1 + openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 26 ++-- .../LAYER2/MAC/eNB_scheduler_primitives.c | 8 +- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 28 ++-- openair2/LAYER2/MAC/pre_processor.c | 26 ++-- openair2/LAYER2/MAC/proto.h | 4 +- openair2/RRC/LITE/rrc_eNB.c | 2 +- targets/RT/USER/lte-enb.c | 23 +-- targets/RT/USER/lte-softmodem.c | 137 ++---------------- targets/RT/USER/lte-softmodem.h | 2 +- 11 files changed, 72 insertions(+), 193 deletions(-) diff --git a/openair2/ENB_APP/flexran_agent_common_internal.c b/openair2/ENB_APP/flexran_agent_common_internal.c index de937db0c6..e3fac4594b 100644 --- a/openair2/ENB_APP/flexran_agent_common_internal.c +++ b/openair2/ENB_APP/flexran_agent_common_internal.c @@ -37,6 +37,7 @@ #include "assertions.h" #include "enb_app.h" +#if 0 void handle_reconfiguration(mid_t mod_id) { /* NOTE: this function might be extended by using stop_modem() @@ -69,6 +70,7 @@ void handle_reconfiguration(mid_t mod_id) LOG_I(ENB_APP, "lte-softmodem restart succeeded in %d ms\n", diff_ms); } } +#endif int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy_length) { @@ -109,7 +111,8 @@ int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy if (parse_enb_id(mod_id, &parser) == -1) { goto error; } else { // succeful parse and setting - handle_reconfiguration(mod_id); + /* TODO implement */ + //handle_reconfiguration(mod_id); } } else if (strcmp((char *) event.data.scalar.value, "mac") == 0) { LOG_D(ENB_APP, "This is intended for the mac system\n"); @@ -293,8 +296,7 @@ int parse_enb_config_parameters(mid_t mod_id, yaml_parser_t *parser) { yaml_event_delete(&event); } - /* reflect in RAN API */ - flexran_set_enb_vars(mod_id, RAN_LTE_OAI); + /* TODO: reflect in RAN API */ return 0; diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index e27ef3648a..36538a3364 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -800,6 +800,7 @@ typedef struct { ///Contention resolution timer used during random access uint8_t mac_ContentionResolutionTimer; + /* TODO Navid MAX_NUM_LCID -> MAX_NUM_CCs? */ uint16_t max_rbs_allowed_slice[MAX_NUM_LCID][MAX_NUM_SLICES]; uint8_t max_mcs[MAX_NUM_LCID]; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index a0da4f4961..ae4afc8b42 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -64,7 +64,6 @@ #include "flexran.pb-c.h" #endif #include -#endif #include "T.h" @@ -449,7 +448,7 @@ set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP, //------------------------------------------------------------------------------ void -schedule_dlsch(module_id_ module_idP, +schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) //------------------------------------------------------------------------------{ { @@ -466,7 +465,7 @@ schedule_dlsch(module_id_ module_idP, for (i = 0; i < n_active_slices; i++) { if (slice_percentage[i] < 0 ){ LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero", - mod_id, frame, subframe, i, slice_percentage[i]); + module_idP, frameP, subframeP, i, slice_percentage[i]); slice_percentage[i]=0; } total_slice_percentage+=slice_percentage[i]; @@ -488,7 +487,7 @@ schedule_dlsch(module_id_ module_idP, if (n_active_slices_current != n_active_slices ){ if ((n_active_slices > 0) && (n_active_slices <= MAX_NUM_SLICES)) { LOG_N(MAC,"[eNB %d]frame %d subframe %d: number of active DL slices has changed: %d-->%d\n", - mod_id, frame, subframe, n_active_slices_current, n_active_slices); + module_idP, frameP, subframeP, n_active_slices_current, n_active_slices); n_active_slices_current = n_active_slices; @@ -501,7 +500,7 @@ schedule_dlsch(module_id_ module_idP, // check if the slice rb share has changed, and log the console if (slice_percentage_current[i] != slice_percentage[i]){ // new slice percentage LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", - mod_id, i, frame, subframe, total_slice_percentage_current, total_slice_percentage, slice_percentage_current[i], slice_percentage[i]); + module_idP, i, frameP, subframeP, total_slice_percentage_current, total_slice_percentage, slice_percentage_current[i], slice_percentage[i]); total_slice_percentage_current= total_slice_percentage; slice_percentage_current[i] = slice_percentage[i]; @@ -511,10 +510,10 @@ schedule_dlsch(module_id_ module_idP, if (slice_maxmcs_current[i] != slice_maxmcs[i]){ if ((slice_maxmcs[i] >= 0) && (slice_maxmcs[i] < 29)){ LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", - mod_id, i, frame, subframe, slice_maxmcs_current[i], slice_maxmcs[i]); + module_idP, i, frameP, subframeP, slice_maxmcs_current[i], slice_maxmcs[i]); slice_maxmcs_current[i] = slice_maxmcs[i]; } else { - LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid slice max mcs %d, revert the previous value %d\n",mod_id, i, slice_maxmcs[i],slice_maxmcs_current[i]); + LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid slice max mcs %d, revert the previous value %d\n",module_idP, i, slice_maxmcs[i],slice_maxmcs_current[i]); slice_maxmcs[i]= slice_maxmcs_current[i]; } } @@ -522,7 +521,7 @@ schedule_dlsch(module_id_ module_idP, // check if a new scheduler, and log the console if (update_dl_scheduler_current[i] != update_dl_scheduler[i]){ LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: DL scheduler for this slice is updated: %s \n", - mod_id, i, frame, subframe, dl_scheduler_type[i]); + module_idP, i, frameP, subframeP, dl_scheduler_type[i]); update_dl_scheduler_current[i] = update_dl_scheduler[i]; } @@ -531,16 +530,14 @@ schedule_dlsch(module_id_ module_idP, if (n_active_slices == n_active_slices_current){ LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n", - mod_id,i, - total_slice_percentage_current, total_slice_percentage); + module_idP, i, total_slice_percentage_current, total_slice_percentage); if (slice_percentage[i] >= avg_slice_percentage){ slice_percentage[i]-=0.1; total_slice_percentage-=0.1; } } else { LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n", - mod_id,i, - total_slice_percentage_current, total_slice_percentage, + module_idP, i, total_slice_percentage_current, total_slice_percentage, n_active_slices, n_active_slices_current ); n_active_slices = n_active_slices_current; slice_percentage[i] = slice_percentage_current[i]; @@ -548,7 +545,8 @@ schedule_dlsch(module_id_ module_idP, } // Run each enabled slice-specific schedulers one by one - slice_sched_dl[i](mod_id, i, frame, subframe, mbsfn_flag,dl_info); + /* TODO Navid took out the dl_info additional information */ + slice_sched_dl[i](module_idP, i, frameP, subframeP, mbsfn_flag/*, dl_info*/); } } @@ -806,7 +804,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, */ eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; - eNB_UE_stats->dlsch_mcs1 =cmin(eNB_UE_stats->dlsch_mcs1, flexran_slice_maxmcs(slice_idP));//openair_daq_vars.target_ue_dl_mcs); + eNB_UE_stats->dlsch_mcs1 =cmin(eNB_UE_stats->dlsch_mcs1, slice_maxmcs[slice_idP]);//openair_daq_vars.target_ue_dl_mcs); // store stats diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index fe885d38cc..15f67871b1 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -61,6 +61,8 @@ #define ENABLE_MAC_PAYLOAD_DEBUG #define DEBUG_eNB_SCHEDULER 1 +extern int n_active_slices; + int choose(int n, int k) { int res = 1; @@ -1927,7 +1929,7 @@ int UE_num_active_CC(UE_list_t * listP, int ue_idP) int UE_PCCID(module_id_t mod_idP, int ue_idP) //------------------------------------------------------------------------------ { - if (RC.mac[mod_idP] == NULL) return 0; + if (!RC.mac || !RC.mac[mod_idP]) return 0; return (RC.mac[mod_idP]->UE_list.pCC_id[ue_idP]); } @@ -1935,7 +1937,7 @@ int UE_PCCID(module_id_t mod_idP, int ue_idP) rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP) //------------------------------------------------------------------------------ { - if (RC.mac[mod_idP] == NULL) return 0; + if (!RC.mac || !RC.mac[mod_idP]) return 0; rnti_t rnti = RC.mac[mod_idP]-> UE_list.UE_template[UE_PCCID(mod_idP, ue_idP)][ue_idP].rnti; @@ -1953,7 +1955,7 @@ rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP) boolean_t is_UE_active(module_id_t mod_idP, int ue_idP) //------------------------------------------------------------------------------ { - if (RC.mac[mod_idP] == NULL) return 0; + if (!RC.mac || !RC.mac[mod_idP]) return 0; return (RC.mac[mod_idP]->UE_list.active[ue_idP]); } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 7076827896..f1bfac7949 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -63,8 +63,8 @@ #include "header.pb-c.h" #include "flexran.pb-c.h" #include "flexran_agent_mac.h" -#include #endif +#include #include "T.h" @@ -943,13 +943,13 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header, * (done below in schedule_ulsch). */ void -set_msg3_subframe(module_id_t Mod_id, +set_msg3_subframe(module_id_t mod_id, int CC_id, int frame, int subframe, int rnti, int Msg3_frame, int Msg3_subframe) { - eNB_MAC_INST *mac = RC.mac[Mod_id]; + eNB_MAC_INST *mac = RC.mac[mod_id]; int i; for (i = 0; i < NB_RA_PROC_MAX; i++) { if (mac->common_channels[CC_id].ra[i].state != IDLE && @@ -1086,7 +1086,7 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, for (i = 0; i < n_active_slices_uplink; i++) { if (slice_percentage_uplink[i] < 0 ){ LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero", - mod_id, frame, subframe, i, slice_percentage_uplink[i]); + module_idP, frameP, subframeP, i, slice_percentage_uplink[i]); slice_percentage_uplink[i]=0; } total_slice_percentage_uplink+=slice_percentage_uplink[i]; @@ -1112,7 +1112,7 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, if (n_active_slices_current_uplink != n_active_slices_uplink ){ if ((n_active_slices_uplink > 0) && (n_active_slices_uplink <= MAX_NUM_SLICES)) { LOG_N(MAC,"[eNB %d]frame %d subframe %d: number of active UL slices has changed: %d-->%d\n", - mod_id, frame, subframe, n_active_slices_current_uplink, n_active_slices_uplink); + module_idP, frameP, subframeP, n_active_slices_current_uplink, n_active_slices_uplink); n_active_slices_current_uplink = n_active_slices_uplink; @@ -1125,7 +1125,7 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, // check if the slice rb share has changed, and log the console if (slice_percentage_current_uplink[i] != slice_percentage_uplink[i]){ LOG_N(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n", - mod_id, i, frame, subframe, total_slice_percentage_current_uplink, total_slice_percentage_uplink, slice_percentage_current_uplink[i], slice_percentage_uplink[i]); + module_idP, i, frameP, subframeP, total_slice_percentage_current_uplink, total_slice_percentage_uplink, slice_percentage_current_uplink[i], slice_percentage_uplink[i]); total_slice_percentage_current_uplink= total_slice_percentage_uplink; slice_percentage_current_uplink[i] = slice_percentage_uplink[i]; @@ -1135,10 +1135,10 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, if (slice_maxmcs_current_uplink[i] != slice_maxmcs_uplink[i]){ if ((slice_maxmcs_uplink[i] >= 0) && (slice_maxmcs_uplink[i] <= 16)){ LOG_N(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n", - mod_id, i, frame, subframe, slice_maxmcs_current_uplink[i], slice_maxmcs_uplink[i]); + module_idP, i, frameP, subframeP, slice_maxmcs_current_uplink[i], slice_maxmcs_uplink[i]); slice_maxmcs_current_uplink[i] = slice_maxmcs_uplink[i]; } else { - LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid slice max mcs %d, revert the previous value %d\n",mod_id, i, slice_maxmcs_uplink[i],slice_maxmcs_current_uplink[i]); + LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid slice max mcs %d, revert the previous value %d\n",module_idP, i, slice_maxmcs_uplink[i],slice_maxmcs_current_uplink[i]); slice_maxmcs_uplink[i]= slice_maxmcs_current_uplink[i]; } @@ -1147,7 +1147,7 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, // check if a new scheduler, and log the console if (update_ul_scheduler_current[i] != update_ul_scheduler[i]){ LOG_N(MAC,"[eNB %d][SLICE %d][UL] frame %d subframe %d: UL scheduler for this slice is updated: %s \n", - mod_id, i, frame, subframe, ul_scheduler_type[i]); + module_idP, i, frameP, subframeP, ul_scheduler_type[i]); update_ul_scheduler_current[i] = update_ul_scheduler[i]; } @@ -1156,8 +1156,8 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, if (n_active_slices_uplink == n_active_slices_current_uplink){ LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n", - mod_id,i, - total_slice_percentage_current_uplink, total_slice_percentage_uplink); + module_idP, i, total_slice_percentage_current_uplink, + total_slice_percentage_uplink); if (slice_percentage_uplink[i] > avg_slice_percentage_uplink){ slice_percentage_uplink[i]-=0.1; total_slice_percentage_uplink-=0.1; @@ -1165,9 +1165,9 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, } else { // here we can correct the values, e.g. reduce proportionally LOG_W(MAC,"[eNB %d][SLICE %d][UL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n", - mod_id,i, - total_slice_percentage_current_uplink, total_slice_percentage_uplink, - n_active_slices_uplink, n_active_slices_current_uplink); + module_idP, i, total_slice_percentage_current_uplink, + total_slice_percentage_uplink, n_active_slices_uplink, + n_active_slices_current_uplink); n_active_slices_uplink = n_active_slices_current_uplink; slice_percentage_uplink[i] = slice_percentage_current_uplink[i]; } diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index af5b6f660b..dbe0d820f2 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -57,6 +57,8 @@ #define DEBUG_HEADER_PARSING 1 //#define DEBUG_PACKET_TRACE 1 +extern float slice_percentage[MAX_NUM_SLICES]; + //#define ICIC 0 /* @@ -267,7 +269,8 @@ assign_rbs_required(module_id_t Mod_id, to_prb(RC.mac[Mod_id]->common_channels[CC_id]. mib->message.dl_Bandwidth); - UE_list->ue_sched_ctl.max_allowed_rbs[CC_id][slice_id]= flexran_nb_rbs_allowed_slice(slice_percentage[slice_id],N_RB_DL); + /* TODO Navid: field max_rbs_allowed_slice is [MAX_NUM_LCID][MAX_NUM_SLICES] -> Why CC_id? or bug in definition? */ + UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]= flexran_nb_rbs_allowed_slice(slice_percentage[slice_id],N_RB_DL); /* calculating required number of RBs for each UE */ while (TBS < @@ -275,10 +278,13 @@ assign_rbs_required(module_id_t Mod_id, dl_buffer_total) { nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id]; - if (nb_rbs_required[CC_id][UE_id] > UE_list->ue_sched_ctl.max_allowed_rbs[CC_id][slice_id]) { + /* TODO Navid: field max_rbs_allowed_slice is [MAX_NUM_LCID][MAX_NUM_SLICES] -> Why CC_id? or bug in definition? */ + if (nb_rbs_required[CC_id][UE_id] > UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]) { TBS = - get_TBS_DL(eNB_UE_stats->dlsch_mcs1, UE_list->ue_sched_ctl.max_allowed_rbs[CC_id][slice_id]); - nb_rbs_required[CC_id][UE_id] = UE_list->ue_sched_ctl.max_allowed_rbs[CC_id][slice_id]; + /* TODO Navid: field max_rbs_allowed_slice is [MAX_NUM_LCID][MAX_NUM_SLICES] -> Why CC_id? or bug in definition? */ + get_TBS_DL(eNB_UE_stats->dlsch_mcs1, UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]); + /* TODO Navid: field max_rbs_allowed_slice is [MAX_NUM_LCID][MAX_NUM_SLICES] -> Why CC_id? */ + nb_rbs_required[CC_id][UE_id] = UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]; break; } @@ -614,7 +620,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, if (UE_list->active[i] != TRUE) continue; - if (!flexran_slice_member(UE_id, slice_id)) + if (!flexran_slice_member(i, slice_id)) continue; UE_id = i; @@ -724,13 +730,15 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, message.dl_Bandwidth) - total_rbs_used[CC_id]; //recalcualte based on the what is left after retransmission - ue_sched_ctl.max_allowed_rbs[CC_id][slice_id]= flexran_nb_rbs_allowed_slice(slice_percentage[slice_id],N_RB_DL); + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + /* TODO Navid: as above */ + ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id]= flexran_nb_rbs_allowed_slice(slice_percentage[slice_id],N_RB_DL); if (total_ue_count[CC_id] == 0) { average_rbs_per_user[CC_id] = 0; - } else if ((min_rb_unit[CC_id] * total_ue_count[CC_id]) <= (ue_sched_ctl.max_allowed_rbs[CC_id][slice_id])) { + } else if ((min_rb_unit[CC_id] * total_ue_count[CC_id]) <= (ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id])) { average_rbs_per_user[CC_id] = - (uint16_t) floor(ue_sched_ctl.max_allowed_rbs[CC_id][slice_id] / total_ue_count[CC_id]); + (uint16_t) floor(ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] / total_ue_count[CC_id]); } else { average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; // consider the total number of use that can be scheduled UE } @@ -1390,7 +1398,7 @@ ulsch_scheduler_pre_processor(module_id_t module_idP, int N_RB_UL; LOG_D(MAC, "In ulsch_preprocessor: assign max mcs min rb\n"); // maximize MCS and then allocate required RB according to the buffer occupancy with the limit of max available UL RB - assign_max_mcs_min_rb(module_idP, frameP, subframeP, first_rb); + assign_max_mcs_min_rb(module_idP, slice_id, frameP, subframeP, first_rb); LOG_D(MAC, "In ulsch_preprocessor: sort ue \n"); // sort ues diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/proto.h index 842e1d7080..c7aa6290ae 100644 --- a/openair2/LAYER2/MAC/proto.h +++ b/openair2/LAYER2/MAC/proto.h @@ -217,6 +217,8 @@ void dlsch_scheduler_pre_processor_reset(int module_idP, int UE_id, uint16_t nb_rbs_required_remaining [MAX_NUM_CCs][NUMBER_OF_UE_MAX], + unsigned char total_ue_count[MAX_NUM_CCs], + unsigned char total_rbs_used[MAX_NUM_CCs], unsigned char rballoc_sub[MAX_NUM_CCs] [N_RBG_MAX], @@ -665,7 +667,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, slice_id_t slice_id, void store_ulsch_buffer(module_id_t module_idP, int frameP, sub_frame_t subframeP); void sort_ue_ul(module_id_t module_idP, int frameP, sub_frame_t subframeP); -void assign_max_mcs_min_rb(module_id_t module_idP, int frameP, +void assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, sub_frame_t subframeP, uint16_t * first_rb); void adjust_bsr_info(int buffer_occupancy, uint16_t TBS, UE_TEMPLATE * UE_template); diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index c946dcf818..8402d1ba61 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -2156,7 +2156,7 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt int i; // configure SRB1/SRB2, PhysicalConfigDedicated, MAC_MainConfig for UE - eNB_RRC_INST* rrc_inst = &eNB_rrc_inst[ctxt_pP->module_id]; + eNB_RRC_INST* rrc_inst = RC.rrc[ctxt_pP->module_id]; struct PhysicalConfigDedicated** physicalConfigDedicated = &ue_context_pP->ue_context.physicalConfigDedicated; struct SRB_ToAddMod *SRB2_config = NULL; diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 0626ad7725..6b418bb8ff 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -239,9 +239,7 @@ static void* eNB_thread_rxtx( void* param ) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); -#ifdef DEBUG_THREADS - printf(" *** Exiting eNB thread RXn_TXnp4\n"); -#endif + LOG_D(PHY, " *** Exiting eNB thread RXn_TXnp4\n"); eNB_thread_rxtx_status = 0; return &eNB_thread_rxtx_status; @@ -624,8 +622,6 @@ void init_eNB_proc(int inst) { pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL); pthread_mutex_init( &proc->mutex_RU,NULL); pthread_mutex_init( &proc->mutex_RU_PRACH,NULL); - pthread_mutex_init( &proc->mutex_synch,NULL); - pthread_mutex_init( &proc->mutex_FH, NULL); pthread_cond_init( &proc->cond_prach, NULL); pthread_cond_init( &proc->cond_asynch_rxtx, NULL); @@ -727,22 +723,12 @@ void kill_eNB_proc(int inst) { proc_rxtx[1].instance_cnt_rxtx = 0; pthread_mutex_unlock(&proc_rxtx[1].mutex_rxtx); } - pthread_mutex_lock(&PHY_vars_eNB_g[0][CC_id]->proc.mutex_synch); - PHY_vars_eNB_g[0][CC_id]->proc.instance_cnt_synch = 1; - pthread_mutex_unlock(&PHY_vars_eNB_g[0][CC_id]->proc.mutex_synch); proc->instance_cnt_prach = 0; pthread_cond_signal( &proc->cond_prach ); - pthread_cond_signal( &proc->cond_FH ); pthread_cond_signal( &proc->cond_asynch_rxtx ); - pthread_cond_signal( &proc->cond_synch ); pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx); - LOG_D(PHY, "joining pthread_FH\n"); - pthread_join( proc->pthread_FH, (void**)&status ); - pthread_mutex_destroy( &proc->mutex_FH ); - pthread_cond_destroy( &proc->cond_FH ); - LOG_D(PHY, "joining pthread_prach\n"); pthread_join( proc->pthread_prach, (void**)&status ); @@ -776,12 +762,7 @@ void kill_eNB_proc(int inst) { LOG_D(PHY, "joining pthread_single\n"); pthread_join(proc->pthread_single, (void**)&status ); - - LOG_D(PHY, "joining pthread_synch\n"); - pthread_join(proc->pthread_synch, (void**)&status ); - pthread_mutex_destroy(&proc->mutex_synch); - pthread_cond_destroy(&proc->cond_synch); - LOG_D(PHY, "joined all threads\n"); + LOG_D(PHY, "joined all eNB threads\n"); } } diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 315eee23cd..eab0a88c45 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -229,8 +229,6 @@ uint8_t abstraction_flag=0; /* forward declarations */ void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]); -/* override the enb configuration parameters */ -static void reconfigure_enb_params(int enb_id); /*---------------------BMC: timespec helpers -----------------------------*/ @@ -691,54 +689,6 @@ static void get_options(void) { } -static void reconfigure_enb_params(int enb_id) -{ - int CC_id, k; - const Enb_properties_array_t *enb_properties=enb_config_get(); - - for (CC_id=0; CC_idproperties[enb_id]->cc_node_function[CC_id]; - node_timing[CC_id] = enb_properties->properties[enb_id]->cc_node_timing[CC_id]; - node_synch_ref[CC_id] = enb_properties->properties[enb_id]->cc_node_synch_ref[CC_id]; - - frame_parms[CC_id]->frame_type = enb_properties->properties[enb_id]->frame_type[CC_id]; - frame_parms[CC_id]->tdd_config = enb_properties->properties[enb_id]->tdd_config[CC_id]; - frame_parms[CC_id]->tdd_config_S = enb_properties->properties[enb_id]->tdd_config_s[CC_id]; - frame_parms[CC_id]->Ncp = enb_properties->properties[enb_id]->prefix_type[CC_id]; - - //for (j=0; j < enb_properties->properties[i]->nb_cc; j++ ){ - frame_parms[CC_id]->Nid_cell = enb_properties->properties[enb_id]->Nid_cell[CC_id]; - frame_parms[CC_id]->N_RB_DL = enb_properties->properties[enb_id]->N_RB_DL[CC_id]; - frame_parms[CC_id]->N_RB_UL = enb_properties->properties[enb_id]->N_RB_DL[CC_id]; - frame_parms[CC_id]->nb_antennas_tx = enb_properties->properties[enb_id]->nb_antennas_tx[CC_id]; - frame_parms[CC_id]->nb_antenna_ports_eNB = enb_properties->properties[enb_id]->nb_antenna_ports[CC_id]; - frame_parms[CC_id]->nb_antennas_rx = enb_properties->properties[enb_id]->nb_antennas_rx[CC_id]; - - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex = enb_properties->properties[enb_id]->prach_config_index[CC_id]; - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset = enb_properties->properties[enb_id]->prach_freq_offset[CC_id]; - - frame_parms[CC_id]->mode1_flag = (frame_parms[CC_id]->nb_antenna_ports_eNB == 1) ? 1 : 0; - frame_parms[CC_id]->threequarter_fs = threequarter_fs; - - for (k = 0 ; k < 4; k++) { - downlink_frequency[CC_id][k] = enb_properties->properties[enb_id]->downlink_frequency[CC_id]; - uplink_frequency_offset[CC_id][k] = enb_properties->properties[enb_id]->uplink_frequency_offset[CC_id]; - rx_gain[CC_id][k] = (double)enb_properties->properties[enb_id]->rx_gain[CC_id]; - tx_gain[CC_id][k] = (double)enb_properties->properties[enb_id]->tx_gain[CC_id]; - } - - printf("Downlink frequency/ uplink offset of CC_id %d set to %ju/%d\n", CC_id, - enb_properties->properties[enb_id]->downlink_frequency[CC_id], - enb_properties->properties[enb_id]->uplink_frequency_offset[CC_id]); - - init_ul_hopping(frame_parms[CC_id]); - init_frame_parms(frame_parms[CC_id],1); - // phy_init_top(frame_parms[CC_id]); - phy_init_lte_top(frame_parms[CC_id]); - } // CC_id -} - #if T_TRACER int T_nowait = 0; /* by default we wait for the tracer */ int T_port = 2021; /* default port to listen to to wait for the tracer */ @@ -887,6 +837,7 @@ void init_openair0() { } } + void wait_RUs(void) { LOG_I(PHY,"Waiting for RUs to be configured ...\n"); @@ -923,70 +874,6 @@ void wait_eNBs(void) { printf("eNB L1 are configured\n"); } -void fill_PHY_vars_eNB_g(uint8_t abstraction_flag, uint8_t beta_ACK, uint8_t beta_RI, uint8_t beta_CQI) -{ - int CC_id, i, j, k, re; - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - PHY_vars_eNB_g[0][CC_id] = init_lte_eNB(frame_parms[CC_id], - 0, - frame_parms[CC_id]->Nid_cell, - node_function[CC_id], - abstraction_flag); - PHY_vars_eNB_g[0][CC_id]->ue_dl_rb_alloc = 0x1fff; - PHY_vars_eNB_g[0][CC_id]->target_ue_dl_mcs = target_dl_mcs; - PHY_vars_eNB_g[0][CC_id]->ue_ul_nb_rb = 6; - PHY_vars_eNB_g[0][CC_id]->target_ue_ul_mcs = target_ul_mcs; - // initialization for phy-test - for (k = 0; k < NUMBER_OF_UE_MAX; k++) { - PHY_vars_eNB_g[0][CC_id]->transmission_mode[k] = transmission_mode; - if (transmission_mode == 7) - lte_gold_ue_spec_port5(PHY_vars_eNB_g[0][CC_id]->lte_gold_uespec_port5_table[k], - frame_parms[CC_id]->Nid_cell, - 0x1235+k); - } - if ((transmission_mode == 1) || (transmission_mode == 7)) { - for (j = 0; j < frame_parms[CC_id]->nb_antennas_tx; j++) - for (re = 0; re < frame_parms[CC_id]->ofdm_symbol_size; re++) - PHY_vars_eNB_g[0][CC_id]->common_vars.beam_weights[0][0][j][re] = 0x00007fff / frame_parms[CC_id]->nb_antennas_tx; - } - - if (phy_test==1) - PHY_vars_eNB_g[0][CC_id]->mac_enabled = 0; - else - PHY_vars_eNB_g[0][CC_id]->mac_enabled = 1; - - if (PHY_vars_eNB_g[0][CC_id]->mac_enabled == 0) { //set default parameters for testing mode - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { - PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK; - PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index = beta_RI; - PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI; - - PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = i; - PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(i%3); - PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4; - } - } - - compute_prach_seq(&PHY_vars_eNB_g[0][CC_id]->frame_parms.prach_config_common, - PHY_vars_eNB_g[0][CC_id]->frame_parms.frame_type, - PHY_vars_eNB_g[0][CC_id]->X_u); - - - PHY_vars_eNB_g[0][CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0]; - - if (frame_parms[CC_id]->frame_type == FDD) { - PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 0; - } else { - if (frame_parms[CC_id]->N_RB_DL == 100) - PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624; - else if (frame_parms[CC_id]->N_RB_DL == 50) - PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624/2; - else if (frame_parms[CC_id]->N_RB_DL == 25) - PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624/4; - } - } -} - #if defined(ENABLE_ITTI) && defined(FLEXRAN_AGENT_SB_IF) /* * helper function to terminate a certain ITTI task @@ -999,6 +886,7 @@ void terminate_task(task_id_t task_id, mid_t mod_id) itti_send_msg_to_task (task_id, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); } +#if 0 int stop_L1L2(int enb_id) { int CC_id; @@ -1107,6 +995,7 @@ int restart_L1L2(int enb_id) return 0; } #endif +#endif int main( int argc, char **argv ) { @@ -1274,19 +1163,14 @@ int main( int argc, char **argv ) flexran_agent_start(i); } - LOG_I(ENB_APP, " * Waiting for FlexRAN RTController command *\n"); - pthread_mutex_lock(&mutex_node_ctrl); - while (ENB_NORMAL_OPERATION != node_control_state) - pthread_cond_wait(&cond_node_ctrl, &mutex_node_ctrl); - pthread_mutex_unlock(&mutex_node_ctrl); + /* TODO handle restart/initial blocking */ + //LOG_I(ENB_APP, " * Waiting for FlexRAN RTController command *\n"); + //pthread_mutex_lock(&mutex_node_ctrl); + //while (ENB_NORMAL_OPERATION != node_control_state) + // pthread_cond_wait(&cond_node_ctrl, &mutex_node_ctrl); + //pthread_mutex_unlock(&mutex_node_ctrl); - /* reconfigure eNB in case FlexRAN controller applied changes */ - /* TODO needs to be done? */ - //for (i=0; i < NB_eNB_INST; i++){ - // LOG_I(ENB_APP, "Reconfigure eNB module %d and FlexRAN eNB variables\n", i); - // reconfigure_enb_params(i); - // flexran_set_enb_vars(i, RAN_LTE_OAI); - //} + /* TODO do eNB reconfiguration (handled implicitly?) */ #endif if (UE_flag==1) { @@ -1611,6 +1495,7 @@ int main( int argc, char **argv ) } } } + #endif printf("stopping MODEM threads\n"); diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index 6274fc1610..13e5ba6b91 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -269,7 +269,7 @@ extern int restart_L1L2(int enb_id); #ifdef FLEXRAN_AGENT_SB_IF #include "flexran_agent.h" // for locking -volatile ENB_MODULE_STATE node_control_state; +//volatile ENB_MODULE_STATE node_control_state; pthread_cond_t cond_node_ctrl; pthread_mutex_t mutex_node_ctrl; #endif From 56d4d0ebef8e5b21987d4a5412c961f52952549d Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 16 Jan 2018 12:27:55 +0100 Subject: [PATCH 080/195] Bugfix: avoid cyclic header dependency, use FlexRAN variables instead --- .../ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h | 1 - openair2/ENB_APP/flexran_agent_extern.h | 7 +++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h index a101bab242..cf20c477de 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h @@ -31,7 +31,6 @@ #ifndef __FLEXRAN_AGENT_RRC_PRIMITIVES_H__ #define __FLEXRAN_AGENT_RRC_PRIMITIVES_H__ -#include "PHY/extern.h" #include "flexran_agent_defs.h" #include "flexran.pb-c.h" #include "header.pb-c.h" diff --git a/openair2/ENB_APP/flexran_agent_extern.h b/openair2/ENB_APP/flexran_agent_extern.h index 589975b310..ae77e9227a 100644 --- a/openair2/ENB_APP/flexran_agent_extern.h +++ b/openair2/ENB_APP/flexran_agent_extern.h @@ -30,11 +30,10 @@ #ifndef __FLEXRAN_AGENT_EXTERN_H__ #define __FLEXRAN_AGENT_EXTERN_H__ -// #include "flexran_agent_defs.h" +#include "flexran_agent_defs.h" #include "flexran_agent_mac_defs.h" #include "flexran_agent_rrc_defs.h" #include "flexran_agent_pdcp_defs.h" -#include "common/ran_context.h" /* Control module interface for the communication of the MAC Control Module with the agent */ extern AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB]; @@ -55,7 +54,7 @@ extern AGENT_PDCP_xface *agent_pdcp_xface[NUM_MAX_ENB]; extern unsigned int pdcp_agent_registered[NUM_MAX_ENB]; /* Requried to know which UEs had a harq updated over some subframe */ -extern int harq_pid_updated[NUMBER_OF_UE_MAX][8]; -extern int harq_pid_round[NUMBER_OF_UE_MAX][8]; +extern int harq_pid_updated[NUM_MAX_UE][8]; +extern int harq_pid_round[NUM_MAX_UE][8]; #endif From 3740afecc7081971dfcf8eb0e3c0b03495f1aaad Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 16 Jan 2018 12:30:34 +0100 Subject: [PATCH 081/195] consider changed RAN API --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 17 ++++++++++------- .../CONTROL_MODULES/RRC/flexran_agent_rrc.c | 9 +++++---- openair2/ENB_APP/flexran_agent_common.c | 9 +++++---- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index d60a9eb3b7..4f91e65c6a 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -219,21 +219,21 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, if (flexran_get_antenna_ports(enb_id, j) == 2 && csi_reports[j]->ri == 1) { // TODO PMI - csi11->wb_pmi = flexran_get_ue_pmi(enb_id); + csi11->wb_pmi = flexran_get_ue_wpmi(enb_id, i, 0); csi11->has_wb_pmi = 1; } else if (flexran_get_antenna_ports(enb_id, j) == 2 && csi_reports[j]->ri == 2){ // TODO PMI - csi11->wb_pmi = flexran_get_ue_pmi(enb_id); + csi11->wb_pmi = flexran_get_ue_wpmi(enb_id, i, 0); csi11->has_wb_pmi = 1; } else if (flexran_get_antenna_ports(enb_id, j) == 4 && csi_reports[j]->ri == 2){ // TODO PMI - csi11->wb_pmi = flexran_get_ue_pmi(enb_id); + csi11->wb_pmi = flexran_get_ue_wpmi(enb_id, i, 0); csi11->has_wb_pmi = 1; @@ -868,13 +868,16 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle protocol__flex_ul_info__init(ul_info[i]); ul_info[i]->rnti = flexran_get_ue_crnti(mod_id, i); ul_info[i]->has_rnti = 1; - /*Fill in the Tx power control command for this UE (if available)*/ - if(flexran_get_tpc(mod_id,i) != 1){ - ul_info[i]->tpc = flexran_get_tpc(mod_id,i); + /* Fill in the Tx power control command for this UE (if available), + * primary carrier */ + if(flexran_get_tpc(mod_id, i, 0) != 1){ + /* assume primary carrier */ + ul_info[i]->tpc = flexran_get_tpc(mod_id, i, 0); ul_info[i]->has_tpc = 1; } else{ - ul_info[i]->tpc = flexran_get_tpc(mod_id,i); + /* assume primary carrier */ + ul_info[i]->tpc = flexran_get_tpc(mod_id, i, 0); ul_info[i]->has_tpc = 0; } /*TODO: fill in the amount of data in bytes in the MAC SDU received in this subframe for the diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c index 6f42d1da97..590e9c870f 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c @@ -165,9 +165,10 @@ void flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_ch config->beta_offset_cqi_index = flexran_get_beta_offset_cqi_index(mod_id,i); } - if(flexran_get_ack_nack_simultaneous_trans(mod_id,i) != -1) { + /* assume primary carrier */ + if(flexran_get_ack_nack_simultaneous_trans(mod_id,i,0) != -1) { config->has_ack_nack_simultaneous_trans = 1; - config->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id,i); + config->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id,i,0); } if(flexran_get_simultaneous_ack_nack_cqi(mod_id,i) != -1) { @@ -185,9 +186,9 @@ void flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_ch } } - if(flexran_get_tdd_ack_nack_feedback(mod_id, i) != -1) { + if(flexran_get_tdd_ack_nack_feedback_mode(mod_id, i) != -1) { config->has_tdd_ack_nack_feedback = 1; - config->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback(mod_id,i); + config->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback_mode(mod_id,i); } if(flexran_get_ack_nack_repetition_factor(mod_id, i) != -1) { diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index 00aa7e9263..33879714d9 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -676,9 +676,10 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl ue_config[i]->beta_offset_cqi_index = flexran_get_beta_offset_cqi_index(mod_id,i); } - if (flexran_get_ack_nack_simultaneous_trans(mod_id,i) != -1) { + /* assume primary carrier */ + if (flexran_get_ack_nack_simultaneous_trans(mod_id, i, 0) != -1) { ue_config[i]->has_ack_nack_simultaneous_trans = 1; - ue_config[i]->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id,i); + ue_config[i]->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id, i, 0); } if (flexran_get_simultaneous_ack_nack_cqi(mod_id,i) != -1) { @@ -696,9 +697,9 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl } } - if (flexran_get_tdd_ack_nack_feedback(mod_id, i) != -1) { + if (flexran_get_tdd_ack_nack_feedback_mode(mod_id, i) != -1) { ue_config[i]->has_tdd_ack_nack_feedback = 1; - ue_config[i]->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback(mod_id,i); + ue_config[i]->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback_mode(mod_id,i); } if(flexran_get_ack_nack_repetition_factor(mod_id, i) != -1) { From 356d406cffbbfa444aa7e05a7c96e637132c60e3 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 16 Jan 2018 12:36:44 +0100 Subject: [PATCH 082/195] Navid: remove FlexRAN Agent MAC xface function callbacks for scheduling --- .../ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c | 5 ----- .../CONTROL_MODULES/MAC/flexran_agent_mac_defs.h | 11 ----------- .../CONTROL_MODULES/MAC/flexran_agent_mac_internal.c | 1 - 3 files changed, 17 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 4f91e65c6a..3d0d08efbb 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -1249,9 +1249,6 @@ int flexran_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { xface->flexran_agent_send_sr_info = flexran_agent_send_sr_info; xface->flexran_agent_send_sf_trigger = flexran_agent_send_sf_trigger; //xface->flexran_agent_send_update_mac_stats = flexran_agent_send_update_mac_stats; - xface->flexran_agent_schedule_ue_spec = flexran_schedule_ue_dl_spec_default; - xface->flexran_agent_schedule_ul_spec = flexran_schedule_ue_ul_spec_default; - //xface->flexran_agent_schedule_ue_spec = flexran_schedule_ue_spec_remote; xface->flexran_agent_get_pending_dl_mac_config = flexran_agent_get_pending_dl_mac_config; xface->dl_scheduler_loaded_lib = NULL; @@ -1268,9 +1265,7 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { xface->flexran_agent_send_sr_info = NULL; xface->flexran_agent_send_sf_trigger = NULL; //xface->flexran_agent_send_update_mac_stats = NULL; - xface->flexran_agent_schedule_ue_spec = NULL; xface->flexran_agent_get_pending_dl_mac_config = NULL; - xface->flexran_agent_schedule_ul_spec = NULL; xface->dl_scheduler_loaded_lib = NULL; xface->ul_scheduler_loaded_lib = NULL; diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h index 769ddbb1b6..5c1fc1379c 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_defs.h @@ -54,17 +54,6 @@ typedef struct { void (*flexran_agent_get_pending_dl_mac_config)(mid_t mod_id, Protocol__FlexranMessage **msg); - /// Run the UE DL scheduler and fill the Protocol__FlexranMessage. Assumes that - /// dl_info is already initialized as flex_dl_mac_config and fills the - /// flex_dl_data part of it - void (*flexran_agent_schedule_ue_spec)(mid_t mod_id, uint32_t frame, uint32_t subframe, - int *mbsfn_flag, Protocol__FlexranMessage **dl_info); - - /// Run the UE UL scheduler and fill the Protocol__FlexranMessage. Assumes that - - void (*flexran_agent_schedule_ul_spec)(mid_t module_idP, uint32_t frameP, uint32_t cooperation_flag, - int subframeP, unsigned char sched_subframe, Protocol__FlexranMessage **ul_info); - /// Notify the controller for a state change of a particular UE, by sending the proper /// UE state change message (ACTIVATION, DEACTIVATION, HANDOVER) // int (*flexran_agent_notify_ue_state_change)(mid_t mod_id, uint32_t rnti, diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index 2af6514ef6..b7a93b8491 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -883,7 +883,6 @@ int load_dl_scheduler_function(mid_t mod_id, const char *function_name) { void *loaded_scheduler = dlsym(lib, function_name); if (loaded_scheduler) { if (mac_agent_registered[mod_id]) { - agent_mac_xface[mod_id]->flexran_agent_schedule_ue_spec = loaded_scheduler; if (agent_mac_xface[mod_id]->dl_scheduler_loaded_lib != NULL) { dlclose(agent_mac_xface[mod_id]->dl_scheduler_loaded_lib); } From 6179d9d7481ddecc17802a2975dea60c578dfe69 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 16 Jan 2018 15:18:22 +0100 Subject: [PATCH 083/195] Navid: fix access to non-existent harq_pid_* variables via RC read --- .../ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 3d0d08efbb..4f5d8af250 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -785,7 +785,7 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle for (i = 0; i < NUMBER_OF_UE_MAX; i++) { for (j = 0; j < 8; j++) { - if (harq_pid_updated[i][j] == 1) { + if (RC.mac && RC.mac[mod_id] && RC.mac[mod_id]->UE_list.eNB_UE_stats[UE_PCCID(mod_id,i)][i].harq_pid == 1) { available_harq[i] = j; sf_trigger_msg->n_dl_info++; break; @@ -828,14 +828,15 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle dl_info[i]->harq_process_id = available_harq[UE_id]; - harq_pid_updated[UE_id][available_harq[UE_id]] = 0; + if (RC.mac && RC.mac[mod_id]) + RC.mac[mod_id]->UE_list.eNB_UE_stats[UE_PCCID(mod_id,i)][UE_id].harq_pid = 0; dl_info[i]->has_harq_process_id = 1; /* Fill in the status of the HARQ process (2 TBs)*/ dl_info[i]->n_harq_status = 2; dl_info[i]->harq_status = malloc(sizeof(uint32_t) * dl_info[i]->n_harq_status); for (j = 0; j < dl_info[i]->n_harq_status; j++) { - dl_info[i]->harq_status[j] = harq_pid_round[UE_id][available_harq[UE_id]]; - // TODO: This should be different per TB + dl_info[i]->harq_status[j] = RC.mac[mod_id]->UE_list.UE_sched_ctrl[i].round[UE_PCCID(mod_id,i)][j]; + // TODO: This should be different per TB } // LOG_I(FLEXRAN_AGENT, "Sending subframe trigger for frame %d and subframe %d and harq %d (round %d)\n", flexran_get_current_frame(mod_id), (flexran_get_current_subframe(mod_id) + 1) % 10, dl_info[i]->harq_process_id, dl_info[i]->harq_status[0]); if(dl_info[i]->harq_status[0] > 0) { @@ -1168,7 +1169,8 @@ void flexran_agent_init_mac_agent(mid_t mod_id) { lfds700_ringbuffer_init_valid_on_current_logical_core( &ringbuffer_state[mod_id], dl_mac_config_array[mod_id], num_elements, &ps[mod_id], NULL ); for (i = 0; i < NUMBER_OF_UE_MAX; i++) { for (j = 0; j < 8; j++) { - harq_pid_updated[i][j] = 0; + if (RC.mac && RC.mac[mod_id]) + RC.mac[mod_id]->UE_list.eNB_UE_stats[UE_PCCID(mod_id,i)][i].harq_pid = 0; } } } From 1576b7bd08ff7d060dfa8022c1e26af55dfeb2ba Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 29 Jan 2018 11:03:16 +0100 Subject: [PATCH 084/195] bugfix: max_rbs_allowed_slice is array over CC, not LCID --- openair2/LAYER2/MAC/defs.h | 3 +-- openair2/LAYER2/MAC/pre_processor.c | 8 +------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index 36538a3364..2f71c0ee74 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -800,8 +800,7 @@ typedef struct { ///Contention resolution timer used during random access uint8_t mac_ContentionResolutionTimer; - /* TODO Navid MAX_NUM_LCID -> MAX_NUM_CCs? */ - uint16_t max_rbs_allowed_slice[MAX_NUM_LCID][MAX_NUM_SLICES]; + uint16_t max_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES]; uint8_t max_mcs[MAX_NUM_LCID]; diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index dbe0d820f2..017e62b48f 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -269,7 +269,6 @@ assign_rbs_required(module_id_t Mod_id, to_prb(RC.mac[Mod_id]->common_channels[CC_id]. mib->message.dl_Bandwidth); - /* TODO Navid: field max_rbs_allowed_slice is [MAX_NUM_LCID][MAX_NUM_SLICES] -> Why CC_id? or bug in definition? */ UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]= flexran_nb_rbs_allowed_slice(slice_percentage[slice_id],N_RB_DL); /* calculating required number of RBs for each UE */ @@ -278,12 +277,8 @@ assign_rbs_required(module_id_t Mod_id, dl_buffer_total) { nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id]; - /* TODO Navid: field max_rbs_allowed_slice is [MAX_NUM_LCID][MAX_NUM_SLICES] -> Why CC_id? or bug in definition? */ if (nb_rbs_required[CC_id][UE_id] > UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]) { - TBS = - /* TODO Navid: field max_rbs_allowed_slice is [MAX_NUM_LCID][MAX_NUM_SLICES] -> Why CC_id? or bug in definition? */ - get_TBS_DL(eNB_UE_stats->dlsch_mcs1, UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]); - /* TODO Navid: field max_rbs_allowed_slice is [MAX_NUM_LCID][MAX_NUM_SLICES] -> Why CC_id? */ + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]); nb_rbs_required[CC_id][UE_id] = UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_id]; break; } @@ -731,7 +726,6 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, //recalcualte based on the what is left after retransmission ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - /* TODO Navid: as above */ ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id]= flexran_nb_rbs_allowed_slice(slice_percentage[slice_id],N_RB_DL); if (total_ue_count[CC_id] == 0) { From 9333c16ecbc7040fa45724534e4eaaad1e5d67e3 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 18 Jan 2018 17:27:15 +0100 Subject: [PATCH 085/195] bugfixes: correctly initialize mutexes, conds of RU_proc_t, unlock RU.mutex after using --- targets/RT/USER/lte-ru.c | 2 ++ targets/RT/USER/lte-softmodem.c | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 54693f43c8..8903438eb0 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -1615,11 +1615,13 @@ void init_RU_proc(RU_t *ru) { pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL); pthread_mutex_init( &proc->mutex_synch,NULL); pthread_mutex_init( &proc->mutex_FH,NULL); + pthread_mutex_init( &proc->mutex_eNBs, NULL); pthread_cond_init( &proc->cond_prach, NULL); pthread_cond_init( &proc->cond_FH, NULL); pthread_cond_init( &proc->cond_asynch_rxtx, NULL); pthread_cond_init( &proc->cond_synch,NULL); + pthread_cond_init( &proc->cond_eNBs, NULL); pthread_attr_init( &proc->attr_FH); pthread_attr_init( &proc->attr_prach); diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index eab0a88c45..44512843d7 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -844,12 +844,10 @@ void wait_RUs(void) { // wait for all RUs to be configured over fronthaul pthread_mutex_lock(&RC.ru_mutex); - - - while (RC.ru_mask>0) { pthread_cond_wait(&RC.ru_cond,&RC.ru_mutex); } + pthread_mutex_unlock(&RC.ru_mutex); LOG_I(PHY,"RUs configured\n"); } From a91a35877dd8b8b2791e173063f9b5080088b69f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 18 Jan 2018 17:28:08 +0100 Subject: [PATCH 086/195] join all RU threads --- targets/RT/USER/lte-ru.c | 119 ++++++++++++++++++++++++++++++-- targets/RT/USER/lte-softmodem.c | 3 +- 2 files changed, 115 insertions(+), 7 deletions(-) diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 8903438eb0..3ff4c4e7ac 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -116,7 +116,7 @@ extern volatile int oai_exit; extern void phy_init_RU(RU_t*); void init_RU(char*); -void stop_RU(RU_t *ru); +void stop_RU(int nb_ru); void do_ru_sync(RU_t *ru); void configure_ru(int idx, @@ -1673,9 +1673,115 @@ void init_RU_proc(RU_t *ru) { } +void kill_RU_proc(int inst) +{ + RU_t *ru = RC.ru[inst]; + RU_proc_t *proc = &ru->proc; + pthread_mutex_lock(&proc->mutex_FH); + proc->instance_cnt_FH = 0; + pthread_mutex_unlock(&proc->mutex_FH); + pthread_cond_signal(&proc->cond_FH); + pthread_mutex_lock(&proc->mutex_prach); + proc->instance_cnt_prach = 0; + pthread_mutex_unlock(&proc->mutex_prach); + pthread_cond_signal(&proc->cond_prach); +#ifdef Rel14 + pthread_mutex_lock(&proc->mutex_prach_br); + proc->instance_cnt_prach_br = 0; + pthread_mutex_unlock(&proc->mutex_prach_br); + pthread_cond_signal(&proc->cond_prach_br); +#endif + + pthread_mutex_lock(&proc->mutex_synch); + proc->instance_cnt_synch = 0; + pthread_mutex_unlock(&proc->mutex_synch); + pthread_cond_signal(&proc->cond_synch); + + pthread_mutex_lock(&proc->mutex_eNBs); + proc->instance_cnt_eNBs = 0; + pthread_mutex_unlock(&proc->mutex_eNBs); + pthread_cond_signal(&proc->cond_eNBs); + + pthread_mutex_lock(&proc->mutex_asynch_rxtx); + proc->instance_cnt_asynch_rxtx = 0; + pthread_mutex_unlock(&proc->mutex_asynch_rxtx); + pthread_cond_signal(&proc->cond_asynch_rxtx); + + LOG_D(PHY, "Joining pthread_FH\n"); + pthread_join(proc->pthread_FH, NULL); + if (ru->function == NGFI_RRU_IF4p5) { + LOG_D(PHY, "Joining pthread_prach\n"); + pthread_join(proc->pthread_prach, NULL); +#ifdef Rel14 + LOG_D(PHY, "Joining pthread_prach_br\n"); + pthread_join(proc->pthread_prach_br, NULL); +#endif + if (ru->is_slave) { + LOG_D(PHY, "Joining pthread_\n"); + pthread_join(proc->pthread_synch, NULL); + } + + if ((ru->if_timing == synch_to_other) || + (ru->function == NGFI_RRU_IF5) || + (ru->function == NGFI_RRU_IF4p5)) { + LOG_D(PHY, "Joining pthread_asynch_rxtx\n"); + pthread_join(proc->pthread_asynch_rxtx, NULL); + } + } + if (get_nprocs() >= 2) { + if (ru->feprx) { + pthread_mutex_lock(&proc->mutex_fep); + proc->instance_cnt_fep = 0; + pthread_mutex_unlock(&proc->mutex_fep); + pthread_cond_signal(&proc->cond_fep); + LOG_D(PHY, "Joining pthread_fep\n"); + pthread_join(proc->pthread_fep, NULL); + pthread_mutex_destroy(&proc->mutex_fep); + pthread_cond_destroy(&proc->cond_fep); + } + if (ru->feptx_ofdm) { + pthread_mutex_lock(&proc->mutex_feptx); + proc->instance_cnt_feptx = 0; + pthread_mutex_unlock(&proc->mutex_feptx); + pthread_cond_signal(&proc->cond_feptx); + LOG_D(PHY, "Joining pthread_feptx\n"); + pthread_join(proc->pthread_feptx, NULL); + pthread_mutex_destroy(&proc->mutex_feptx); + pthread_cond_destroy(&proc->cond_feptx); + } + } + if (opp_enabled) { + LOG_D(PHY, "Joining ru_stats_thread\n"); + pthread_join(ru->ru_stats_thread, NULL); + } + + pthread_mutex_destroy(&proc->mutex_prach); + pthread_mutex_destroy(&proc->mutex_asynch_rxtx); + pthread_mutex_destroy(&proc->mutex_synch); + pthread_mutex_destroy(&proc->mutex_FH); + pthread_mutex_destroy(&proc->mutex_eNBs); + + pthread_cond_destroy(&proc->cond_prach); + pthread_cond_destroy(&proc->cond_FH); + pthread_cond_destroy(&proc->cond_asynch_rxtx); + pthread_cond_destroy(&proc->cond_synch); + pthread_cond_destroy(&proc->cond_eNBs); + + pthread_attr_destroy(&proc->attr_FH); + pthread_attr_destroy(&proc->attr_prach); + pthread_attr_destroy(&proc->attr_synch); + pthread_attr_destroy(&proc->attr_asynch_rxtx); + pthread_attr_destroy(&proc->attr_fep); + +#ifdef Rel14 + pthread_mutex_destroy(&proc->mutex_prach_br); + pthread_cond_destroy(&proc->cond_prach_br); + pthread_attr_destroy(&proc->attr_prach_br); +#endif +} int check_capabilities(RU_t *ru,RRU_capabilities_t *cap) { @@ -2062,9 +2168,10 @@ void init_RU(char *rf_config_file) { -void stop_ru(RU_t *ru) { - - printf("Stopping RU %p processing threads\n",(void*)ru); - +void stop_RU(int nb_ru) +{ + for (int inst = 0; inst < nb_ru; inst++) { + LOG_I(PHY, "Stopping RU %d processing threads\n", inst); + kill_RU_proc(inst); + } } - diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 44512843d7..181150c672 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1501,7 +1501,8 @@ int main( int argc, char **argv ) // cleanup if (UE_flag == 1) { } else { - stop_eNB(1); + stop_eNB(NB_eNB_INST); + stop_RU(NB_RU); } From 8e9d9807aee187dd649d7704242115d3929b62a3 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 23 Jan 2018 11:01:35 +0100 Subject: [PATCH 087/195] lte-ru.c: fct for interface -dependant config, export more functions - add set_function_spec_param() which configures RU_t instance depending on its function(al split) - export more functions like kill_RU_proc() so that they can be reused by restart functionality --- targets/RT/USER/lte-ru.c | 292 ++++++++++++++++---------------- targets/RT/USER/lte-softmodem.h | 4 + 2 files changed, 152 insertions(+), 144 deletions(-) diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 3ff4c4e7ac..e2918091e9 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -1959,13 +1959,159 @@ void init_precoding_weights(PHY_VARS_eNB *eNB) { } } +void set_function_spec_param(RU_t *ru) +{ + int ret; + + switch (ru->if_south) { + case LOCAL_RF: // this is an RU with integrated RF (RRU, eNB) + if (ru->function == NGFI_RRU_IF5) { // IF5 RRU + ru->do_prach = 0; // no prach processing in RU + ru->fh_north_in = NULL; // no shynchronous incoming fronthaul from north + ru->fh_north_out = fh_if5_north_out; // need only to do send_IF5 reception + ru->fh_south_out = tx_rf; // send output to RF + ru->fh_north_asynch_in = fh_if5_north_asynch_in; // TX packets come asynchronously + ru->feprx = NULL; // nothing (this is a time-domain signal) + ru->feptx_ofdm = NULL; // nothing (this is a time-domain signal) + ru->feptx_prec = NULL; // nothing (this is a time-domain signal) + ru->start_if = start_if; // need to start the if interface for if5 + ru->ifdevice.host_type = RRU_HOST; + ru->rfdevice.host_type = RRU_HOST; + ru->ifdevice.eth_params = &ru->eth_params; + reset_meas(&ru->rx_fhaul); + reset_meas(&ru->tx_fhaul); + reset_meas(&ru->compression); + reset_meas(&ru->transport); + + ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); + printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); + if (ret<0) { + printf("Exiting, cannot initialize transport protocol\n"); + exit(-1); + } + } + else if (ru->function == NGFI_RRU_IF4p5) { + ru->do_prach = 1; // do part of prach processing in RU + ru->fh_north_in = NULL; // no synchronous incoming fronthaul from north + ru->fh_north_out = fh_if4p5_north_out; // send_IF4p5 on reception + ru->fh_south_out = tx_rf; // send output to RF + ru->fh_north_asynch_in = fh_if4p5_north_asynch_in; // TX packets come asynchronously + ru->feprx = (get_nprocs()<=2) ? fep_full :ru_fep_full_2thread; // RX DFTs + ru->feptx_ofdm = (get_nprocs()<=2) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft only (no precoding in RRU) + ru->feptx_prec = NULL; + ru->start_if = start_if; // need to start the if interface for if4p5 + ru->ifdevice.host_type = RRU_HOST; + ru->rfdevice.host_type = RRU_HOST; + ru->ifdevice.eth_params = &ru->eth_params; + reset_meas(&ru->rx_fhaul); + reset_meas(&ru->tx_fhaul); + reset_meas(&ru->compression); + reset_meas(&ru->transport); + + ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); + printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); + if (ret<0) { + printf("Exiting, cannot initialize transport protocol\n"); + exit(-1); + } + malloc_IF4p5_buffer(ru); + } + else if (ru->function == eNodeB_3GPP) { + ru->do_prach = 0; // no prach processing in RU + ru->feprx = (get_nprocs()<=2) ? fep_full : ru_fep_full_2thread; // RX DFTs + ru->feptx_ofdm = (get_nprocs()<=2) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft and precoding + ru->feptx_prec = feptx_prec; // this is fep with idft and precoding + ru->fh_north_in = NULL; // no incoming fronthaul from north + ru->fh_north_out = NULL; // no outgoing fronthaul to north + ru->start_if = NULL; // no if interface + ru->rfdevice.host_type = RAU_HOST; + } + ru->fh_south_in = rx_rf; // local synchronous RF RX + ru->fh_south_out = tx_rf; // local synchronous RF TX + ru->start_rf = start_rf; // need to start the local RF interface + printf("configuring ru_id %d (start_rf %p)\n", ru->idx, start_rf); +/* + if (ru->function == eNodeB_3GPP) { // configure RF parameters only for 3GPP eNodeB, we need to get them from RAU otherwise + fill_rf_config(ru,rf_config_file); + init_frame_parms(&ru->frame_parms,1); + phy_init_RU(ru); + } + + ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); + if (setup_RU_buffers(ru)!=0) { + printf("Exiting, cannot initialize RU Buffers\n"); + exit(-1); + }*/ + break; + + case REMOTE_IF5: // the remote unit is IF5 RRU + ru->do_prach = 0; + ru->feprx = (get_nprocs()<=2) ? fep_full : fep_full; // this is frequency-shift + DFTs + ru->feptx_prec = feptx_prec; // need to do transmit Precoding + IDFTs + ru->feptx_ofdm = (get_nprocs()<=2) ? feptx_ofdm : feptx_ofdm_2thread; // need to do transmit Precoding + IDFTs + if (ru->if_timing == synch_to_other) { + ru->fh_south_in = fh_slave_south_in; // synchronize to master + ru->fh_south_out = fh_if5_mobipass_south_out; // use send_IF5 for mobipass + ru->fh_south_asynch_in = fh_if5_south_asynch_in_mobipass; // UL is asynchronous + } + else { + ru->fh_south_in = fh_if5_south_in; // synchronous IF5 reception + ru->fh_south_out = fh_if5_south_out; // synchronous IF5 transmission + ru->fh_south_asynch_in = NULL; // no asynchronous UL + } + ru->start_rf = NULL; // no local RF + ru->start_if = start_if; // need to start if interface for IF5 + ru->ifdevice.host_type = RAU_HOST; + ru->ifdevice.eth_params = &ru->eth_params; + ru->ifdevice.configure_rru = configure_ru; + + ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); + printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); + if (ret<0) { + printf("Exiting, cannot initialize transport protocol\n"); + exit(-1); + } + break; + + case REMOTE_IF4p5: + ru->do_prach = 0; + ru->feprx = NULL; // DFTs + ru->feptx_prec = feptx_prec; // Precoding operation + ru->feptx_ofdm = NULL; // no OFDM mod + ru->fh_south_in = fh_if4p5_south_in; // synchronous IF4p5 reception + ru->fh_south_out = fh_if4p5_south_out; // synchronous IF4p5 transmission + ru->fh_south_asynch_in = (ru->if_timing == synch_to_other) ? fh_if4p5_south_in : NULL; // asynchronous UL if synch_to_other + ru->fh_north_out = NULL; + ru->fh_north_asynch_in = NULL; + ru->start_rf = NULL; // no local RF + ru->start_if = start_if; // need to start if interface for IF4p5 + ru->ifdevice.host_type = RAU_HOST; + ru->ifdevice.eth_params = &ru->eth_params; + ru->ifdevice.configure_rru = configure_ru; + + ret = openair0_transport_load(&ru->ifdevice, &ru->openair0_cfg, &ru->eth_params); + printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); + if (ret<0) { + printf("Exiting, cannot initialize transport protocol\n"); + exit(-1); + } + + malloc_IF4p5_buffer(ru); + + break; + + default: + LOG_E(PHY,"RU with invalid or unknown southbound interface type %d\n",ru->if_south); + break; + } // switch on interface type +} + extern void RCconfig_RU(void); void init_RU(char *rf_config_file) { int ru_id; RU_t *ru; - int ret; PHY_VARS_eNB *eNB0; int i; int CC_id; @@ -2008,149 +2154,7 @@ void init_RU(char *rf_config_file) { } // LOG_I(PHY,"Initializing RRU descriptor %d : (%s,%s,%d)\n",ru_id,ru_if_types[ru->if_south],eNB_timing[ru->if_timing],ru->function); - - switch (ru->if_south) { - case LOCAL_RF: // this is an RU with integrated RF (RRU, eNB) - if (ru->function == NGFI_RRU_IF5) { // IF5 RRU - ru->do_prach = 0; // no prach processing in RU - ru->fh_north_in = NULL; // no shynchronous incoming fronthaul from north - ru->fh_north_out = fh_if5_north_out; // need only to do send_IF5 reception - ru->fh_south_out = tx_rf; // send output to RF - ru->fh_north_asynch_in = fh_if5_north_asynch_in; // TX packets come asynchronously - ru->feprx = NULL; // nothing (this is a time-domain signal) - ru->feptx_ofdm = NULL; // nothing (this is a time-domain signal) - ru->feptx_prec = NULL; // nothing (this is a time-domain signal) - ru->start_if = start_if; // need to start the if interface for if5 - ru->ifdevice.host_type = RRU_HOST; - ru->rfdevice.host_type = RRU_HOST; - ru->ifdevice.eth_params = &ru->eth_params; - reset_meas(&ru->rx_fhaul); - reset_meas(&ru->tx_fhaul); - reset_meas(&ru->compression); - reset_meas(&ru->transport); - - ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); - printf("openair0_transport_init returns %d for ru_id %d\n",ret,ru_id); - if (ret<0) { - printf("Exiting, cannot initialize transport protocol\n"); - exit(-1); - } - } - else if (ru->function == NGFI_RRU_IF4p5) { - ru->do_prach = 1; // do part of prach processing in RU - ru->fh_north_in = NULL; // no synchronous incoming fronthaul from north - ru->fh_north_out = fh_if4p5_north_out; // send_IF4p5 on reception - ru->fh_south_out = tx_rf; // send output to RF - ru->fh_north_asynch_in = fh_if4p5_north_asynch_in; // TX packets come asynchronously - ru->feprx = (get_nprocs()<=2) ? fep_full :ru_fep_full_2thread; // RX DFTs - ru->feptx_ofdm = (get_nprocs()<=2) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft only (no precoding in RRU) - ru->feptx_prec = NULL; - ru->start_if = start_if; // need to start the if interface for if4p5 - ru->ifdevice.host_type = RRU_HOST; - ru->rfdevice.host_type = RRU_HOST; - ru->ifdevice.eth_params = &ru->eth_params; - reset_meas(&ru->rx_fhaul); - reset_meas(&ru->tx_fhaul); - reset_meas(&ru->compression); - reset_meas(&ru->transport); - - ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); - printf("openair0_transport_init returns %d for ru_id %d\n",ret,ru_id); - if (ret<0) { - printf("Exiting, cannot initialize transport protocol\n"); - exit(-1); - } - malloc_IF4p5_buffer(ru); - } - else if (ru->function == eNodeB_3GPP) { - ru->do_prach = 0; // no prach processing in RU - ru->feprx = (get_nprocs()<=2) ? fep_full : ru_fep_full_2thread; // RX DFTs - ru->feptx_ofdm = (get_nprocs()<=2) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft and precoding - ru->feptx_prec = feptx_prec; // this is fep with idft and precoding - ru->fh_north_in = NULL; // no incoming fronthaul from north - ru->fh_north_out = NULL; // no outgoing fronthaul to north - ru->start_if = NULL; // no if interface - ru->rfdevice.host_type = RAU_HOST; - } - ru->fh_south_in = rx_rf; // local synchronous RF RX - ru->fh_south_out = tx_rf; // local synchronous RF TX - ru->start_rf = start_rf; // need to start the local RF interface - printf("configuring ru_id %d (start_rf %p)\n",ru_id,start_rf); -/* - if (ru->function == eNodeB_3GPP) { // configure RF parameters only for 3GPP eNodeB, we need to get them from RAU otherwise - fill_rf_config(ru,rf_config_file); - init_frame_parms(&ru->frame_parms,1); - phy_init_RU(ru); - } - - ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); - if (setup_RU_buffers(ru)!=0) { - printf("Exiting, cannot initialize RU Buffers\n"); - exit(-1); - }*/ - break; - - case REMOTE_IF5: // the remote unit is IF5 RRU - ru->do_prach = 0; - ru->feprx = (get_nprocs()<=2) ? fep_full : fep_full; // this is frequency-shift + DFTs - ru->feptx_prec = feptx_prec; // need to do transmit Precoding + IDFTs - ru->feptx_ofdm = (get_nprocs()<=2) ? feptx_ofdm : feptx_ofdm_2thread; // need to do transmit Precoding + IDFTs - if (ru->if_timing == synch_to_other) { - ru->fh_south_in = fh_slave_south_in; // synchronize to master - ru->fh_south_out = fh_if5_mobipass_south_out; // use send_IF5 for mobipass - ru->fh_south_asynch_in = fh_if5_south_asynch_in_mobipass; // UL is asynchronous - } - else { - ru->fh_south_in = fh_if5_south_in; // synchronous IF5 reception - ru->fh_south_out = fh_if5_south_out; // synchronous IF5 transmission - ru->fh_south_asynch_in = NULL; // no asynchronous UL - } - ru->start_rf = NULL; // no local RF - ru->start_if = start_if; // need to start if interface for IF5 - ru->ifdevice.host_type = RAU_HOST; - ru->ifdevice.eth_params = &ru->eth_params; - ru->ifdevice.configure_rru = configure_ru; - - ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); - printf("openair0_transport_init returns %d for ru_id %d\n",ret,ru_id); - if (ret<0) { - printf("Exiting, cannot initialize transport protocol\n"); - exit(-1); - } - break; - - case REMOTE_IF4p5: - ru->do_prach = 0; - ru->feprx = NULL; // DFTs - ru->feptx_prec = feptx_prec; // Precoding operation - ru->feptx_ofdm = NULL; // no OFDM mod - ru->fh_south_in = fh_if4p5_south_in; // synchronous IF4p5 reception - ru->fh_south_out = fh_if4p5_south_out; // synchronous IF4p5 transmission - ru->fh_south_asynch_in = (ru->if_timing == synch_to_other) ? fh_if4p5_south_in : NULL; // asynchronous UL if synch_to_other - ru->fh_north_out = NULL; - ru->fh_north_asynch_in = NULL; - ru->start_rf = NULL; // no local RF - ru->start_if = start_if; // need to start if interface for IF4p5 - ru->ifdevice.host_type = RAU_HOST; - ru->ifdevice.eth_params = &ru->eth_params; - ru->ifdevice.configure_rru = configure_ru; - - ret = openair0_transport_load(&ru->ifdevice, &ru->openair0_cfg, &ru->eth_params); - printf("openair0_transport_init returns %d for ru_id %d\n",ret,ru_id); - if (ret<0) { - printf("Exiting, cannot initialize transport protocol\n"); - exit(-1); - } - - malloc_IF4p5_buffer(ru); - - break; - - default: - LOG_E(PHY,"RU with invalid or unknown southbound interface type %d\n",ru->if_south); - break; - } // switch on interface type - + set_function_spec_param(ru); LOG_I(PHY,"Starting ru_thread %d\n",ru_id); init_RU_proc(ru); diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index 13e5ba6b91..c1d63eef4c 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -244,6 +244,10 @@ extern void kill_eNB_proc(int inst); // In lte-ru.c extern void init_RU(const char*); +extern void init_RU_proc(RU_t *ru); +extern void stop_RU(int nb_ru); +extern void kill_RU_proc(int inst); +extern void set_function_spec_param(RU_t *ru); // In lte-ue.c extern int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg); From 811ada242989071dac9fb83796cdaf44b949243c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 23 Jan 2018 12:01:24 +0100 Subject: [PATCH 088/195] soft-restart (i.e. only layers PHY-RRC) the lte-softmodem --- .../ENB_APP/flexran_agent_common_internal.c | 65 +++++------ targets/RT/USER/lte-softmodem.c | 110 +++++++++--------- targets/RT/USER/lte-softmodem.h | 4 +- 3 files changed, 83 insertions(+), 96 deletions(-) diff --git a/openair2/ENB_APP/flexran_agent_common_internal.c b/openair2/ENB_APP/flexran_agent_common_internal.c index e3fac4594b..416f13f241 100644 --- a/openair2/ENB_APP/flexran_agent_common_internal.c +++ b/openair2/ENB_APP/flexran_agent_common_internal.c @@ -32,45 +32,37 @@ #include "flexran_agent_common_internal.h" #include "flexran_agent_mac_internal.h" -/* the following is needed to soft-restart the lte-softmodem */ +/* needed to soft-restart the lte-softmodem */ #include "targets/RT/USER/lte-softmodem.h" -#include "assertions.h" -#include "enb_app.h" -#if 0 void handle_reconfiguration(mid_t mod_id) { - /* NOTE: this function might be extended by using stop_modem() - * to halt the modem so that it can later be resumed */ - int do_restart = 0; + struct timespec start, end; + clock_gettime(CLOCK_MONOTONIC, &start); - pthread_mutex_lock(&mutex_node_ctrl); - if (ENB_NORMAL_OPERATION != node_control_state) { - node_control_state = ENB_NORMAL_OPERATION; - pthread_cond_broadcast(&cond_node_ctrl); + if (stop_L1L2(mod_id) < 0) { + LOG_E(ENB_APP, "can not stop lte-softmodem, aborting restart\n"); + return; + } + + /* TODO wait state could be here IF IT IS NOT EXECUTED BY THE FLEXRAN THREAD */ + + if (restart_L1L2(mod_id) < 0) { + LOG_F(ENB_APP, "can not restart, killing lte-softmodem\n"); + itti_terminate_tasks(TASK_PHY_ENB); + return; + } + + clock_gettime(CLOCK_MONOTONIC, &end); + end.tv_sec -= start.tv_sec; + if (end.tv_nsec >= start.tv_nsec) { + end.tv_nsec -= start.tv_nsec; } else { - do_restart = 1; - } - pthread_mutex_unlock(&mutex_node_ctrl); - - if (do_restart) { - clock_t start_ms = 1000 * clock(); - /* operator || enforces sequence points */ - if (stop_L1L2(mod_id) < 0 || restart_L1L2(mod_id) < 0) { - LOG_E(ENB_APP, "could not restart, killing lte-softmodem\n"); - /* shutdown the whole lte-softmodem */ - itti_terminate_tasks(TASK_PHY_ENB); - return; - } - enb_app_start_phy_rrc(mod_id, mod_id+1); - MessageDef *msg_p = itti_alloc_new_message(TASK_ENB_APP, INITIALIZE_MESSAGE); - itti_send_msg_to_task(TASK_L2L1, INSTANCE_DEFAULT, msg_p); - - int diff_ms = (1000 * clock() - start_ms) / CLOCKS_PER_SEC; - LOG_I(ENB_APP, "lte-softmodem restart succeeded in %d ms\n", diff_ms); + end.tv_sec -= 1; + end.tv_nsec = end.tv_nsec - start.tv_nsec + 1000000000; } + LOG_I(ENB_APP, "lte-softmodem restart succeeded in %ld.%ld s\n", end.tv_sec, end.tv_nsec / 1000000); } -#endif int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy_length) { @@ -111,8 +103,7 @@ int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy if (parse_enb_id(mod_id, &parser) == -1) { goto error; } else { // succeful parse and setting - /* TODO implement */ - //handle_reconfiguration(mod_id); + handle_reconfiguration(mod_id); } } else if (strcmp((char *) event.data.scalar.value, "mac") == 0) { LOG_D(ENB_APP, "This is intended for the mac system\n"); @@ -265,9 +256,9 @@ int parse_enb_config_parameters(mid_t mod_id, yaml_parser_t *parser) { } else if (strcmp((char *) event.data.scalar.value, "ul_freq_offset") == 0) { if (!yaml_parser_parse(parser, &event)) goto error; - flexran_agent_set_operating_ul_freq(mod_id, - 0, - strtol((char *) event.data.scalar.value, &endptr, 10)); + flexran_agent_set_operating_ul_freq(mod_id, + 0, + strtol((char *) event.data.scalar.value, &endptr, 10)); LOG_I(ENB_APP, "Setting ul_freq_offset to %s\n", event.data.scalar.value); } else if (strcmp((char *) event.data.scalar.value, "bandwidth") == 0) { if (!yaml_parser_parse(parser, &event)) @@ -296,8 +287,6 @@ int parse_enb_config_parameters(mid_t mod_id, yaml_parser_t *parser) { yaml_event_delete(&event); } - /* TODO: reflect in RAN API */ - return 0; error: diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 181150c672..c8db435d46 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -872,11 +872,11 @@ void wait_eNBs(void) { printf("eNB L1 are configured\n"); } -#if defined(ENABLE_ITTI) && defined(FLEXRAN_AGENT_SB_IF) +#if defined(ENABLE_ITTI) /* * helper function to terminate a certain ITTI task */ -void terminate_task(task_id_t task_id, mid_t mod_id) +void terminate_task(task_id_t task_id, module_id_t mod_id) { LOG_I(ENB_APP, "sending TERMINATE_MESSAGE to task %s (%d)\n", itti_get_task_name(task_id), task_id); MessageDef *msg; @@ -884,70 +884,71 @@ void terminate_task(task_id_t task_id, mid_t mod_id) itti_send_msg_to_task (task_id, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); } -#if 0 -int stop_L1L2(int enb_id) +int stop_L1L2(module_id_t enb_id) { - int CC_id; - LOG_W(ENB_APP, "stopping lte-softmodem\n"); oai_exit = 1; - /* stop trx devices */ - for(CC_id=0; CC_idrfdevice.trx_stop_func) { - LOG_I(ENB_APP, "stopping PHY_vars_eNB_g[0][%d]->rfdevice (via trx_stop_func())\n", CC_id); - PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_stop_func(&PHY_vars_eNB_g[0][CC_id]->rfdevice); + if (!RC.ru) { + LOG_F(ENB_APP, "no RU configured\n"); + return -1; + } + + /* stop trx devices, multiple carrier currently not supported by RU */ + if (RC.ru[enb_id]) { + if (RC.ru[enb_id]->rfdevice.trx_stop_func) { + RC.ru[enb_id]->rfdevice.trx_stop_func(&RC.ru[enb_id]->rfdevice); + LOG_I(ENB_APP, "turned off RU rfdevice\n"); + } else { + LOG_W(ENB_APP, "can not turn off rfdevice due to missing trx_stop_func callback, proceding anyway!\n"); } - if (PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_stop_func) { - LOG_I(ENB_APP, "stopping PHY_vars_eNB_g[0][%d]->ifdevice (via trx_stop_func())\n", CC_id); - PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_stop_func(&PHY_vars_eNB_g[0][CC_id]->ifdevice); + if (RC.ru[enb_id]->ifdevice.trx_stop_func) { + RC.ru[enb_id]->ifdevice.trx_stop_func(&RC.ru[enb_id]->ifdevice); + LOG_I(ENB_APP, "turned off RU ifdevice\n"); + } else { + LOG_W(ENB_APP, "can not turn off ifdevice due to missing trx_stop_func callback, proceding anyway!\n"); } + } else { + LOG_W(ENB_APP, "no RU found for index %d\n", enb_id); + return -1; } /* these tasks need to pick up new configuration */ terminate_task(TASK_RRC_ENB, enb_id); terminate_task(TASK_L2L1, enb_id); - LOG_W(ENB_APP, "calling kill_eNB_proc() for instance %d\n", enb_id); + LOG_I(ENB_APP, "calling kill_eNB_proc() for instance %d\n", enb_id); kill_eNB_proc(enb_id); + LOG_I(ENB_APP, "calling kill_RU_proc() for instance %d\n", enb_id); + kill_RU_proc(enb_id); oai_exit = 0; return 0; } /* - * Restart the lte-softmodem. - * This function checks whether we are in ENB_NORMAL_OPERATION (defined by - * FlexRAN). If yes, first stop L1/L2/L3, then resume. + * Restart the lte-softmodem after it has been soft-stopped with stop_L1L2() */ -int restart_L1L2(int enb_id) +int restart_L1L2(module_id_t enb_id) { - int i, aa, CC_id; - /* needed for fill_PHY_vars_eNB_g(), defined locally in main(); - * abstraction flag is needed too, but defined both globally and in main () */ - uint8_t beta_ACK = 0, beta_RI = 0, beta_CQI = 2; - /* needed for macphy_init() */ - int eMBMS_active = 0; + RU_t *ru = RC.ru[enb_id]; + int cc_id; + MessageDef *msg_p = NULL; LOG_W(ENB_APP, "restarting lte-softmodem\n"); /* block threads */ sync_var = -1; - reconfigure_enb_params(enb_id); /* set frame parameters from configuration */ - - /* PHY_vars_eNB_g will be filled by init_lte_eNB(), so free and - * let the data structure be filled again */ - for (CC_id=0; CC_idconfigured = 0; } - dump_frame_parms(frame_parms[0]); - init_openair0(); - /* give MAC interface current cell information, the rest is the same. - * For more info, check l2_init(). Then, initialize it (cf. line 1904). */ - mac_xface->frame_parms = frame_parms[0]; - mac_xface->macphy_init(eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL,0,0); + /* TODO undo malloc_IF4p5_buffer() */ + RC.ru_mask |= (1 << ru->idx); + /* copy the changed frame parameters to the RU */ + /* TODO this should be done for all RUs associated to this eNB */ + memcpy(&ru->frame_parms, &RC.eNB[enb_id][0]->frame_parms, sizeof(LTE_DL_FRAME_PARMS)); + set_function_spec_param(RC.ru[enb_id]); LOG_I(ENB_APP, "attempting to create ITTI tasks\n"); if (itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL) < 0) { @@ -963,28 +964,26 @@ int restart_L1L2(int enb_id) LOG_I(PDCP, "Re-created task for L2L1 successfully\n"); } + /* pass a reconfiguration request which will configure everything down to + * RC.eNB[i][j]->frame_parms, too */ + msg_p = itti_alloc_new_message(TASK_ENB_APP, RRC_CONFIGURATION_REQ); + RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[enb_id]->configuration; + itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); + /* TODO XForms here */ - printf("Initializing eNB threads\n"); - init_eNB(node_function, node_timing, 1, eth_params, single_thread_flag, wait_for_sync); - for(CC_id=0; CC_idrf_map.card=0; - PHY_vars_eNB_g[0][CC_id]->rf_map.chain=CC_id+chain_offset; - } + /* TODO check for memory leaks */ + /* TODO wait_eNBs() would wait for phy_config_request()? */ + //init_eNB(single_thread_flag,wait_for_sync); + wait_eNBs(); + init_RU_proc(ru); + ru->rf_map.card = 0; + ru->rf_map.chain = 0; /* CC_id + chain_offset;*/ + wait_RUs(); + init_eNB_afterRU(); - mlockall(MCL_CURRENT | MCL_FUTURE); - - printf("Setting eNB buffer to all-RX\n"); - // Set LSBs for antenna switch (ExpressMIMO) - for (CC_id=0; CC_idhw_timing_advance = 0; - for (i=0; isamples_per_tti*10; i++) - for (aa=0; aanb_antennas_tx; aa++) - PHY_vars_eNB_g[0][CC_id]->common_vars.txdata[0][aa][i] = 0x00010001; - } printf("Sending sync to all threads\n"); - pthread_mutex_lock(&sync_mutex); sync_var=0; pthread_cond_broadcast(&sync_cond); @@ -993,7 +992,6 @@ int restart_L1L2(int enb_id) return 0; } #endif -#endif int main( int argc, char **argv ) { diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index c1d63eef4c..c6f8d8d54c 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -268,8 +268,8 @@ PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, uint8_t abstraction_flag); void init_eNB_afterRU(void); -extern int stop_L1L2(int enb_id); -extern int restart_L1L2(int enb_id); +extern int stop_L1L2(module_id_t enb_id); +extern int restart_L1L2(module_id_t enb_id); #ifdef FLEXRAN_AGENT_SB_IF #include "flexran_agent.h" // for locking From 3f043c7d73b62e4147267a32fb5927776753f55f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 23 Jan 2018 15:20:15 +0100 Subject: [PATCH 089/195] FlexRAN: implement possibilty to await a configuration Through configuration, the lte-softmodem can be halted to await a reconfiguration from the lte-softmodem. A mutex and condition variable are used to implement this. Furthermore, the dependance of lte-softmodem.c on FlexRAN has been reduced to one include and the flexran_agent_start() call. --- openair2/ENB_APP/enb_config.c | 2 +- openair2/ENB_APP/flexran_agent.c | 45 ++++++++++++++----- openair2/ENB_APP/flexran_agent.h | 6 +-- .../ENB_APP/flexran_agent_common_internal.c | 21 ++++++++- openair2/ENB_APP/flexran_agent_defs.h | 12 ++++- targets/RT/USER/lte-softmodem.c | 33 +++----------- targets/RT/USER/lte-softmodem.h | 5 +-- 7 files changed, 74 insertions(+), 50 deletions(-) diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index d2a35c3bd7..2056bfaa27 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -267,7 +267,7 @@ void RCconfig_flexran() RC.flexran[i]->remote_port = *(flexranParams[FLEXRAN_PORT_IDX].uptr); // DEFAULT_FLEXRAN_AGENT_CACHE RC.flexran[i]->cache_name = strdup(*(flexranParams[FLEXRAN_CACHE_IDX].strptr)); - RC.flexran[i]->await_reconf = strcmp(*(flexranParams[FLEXRAN_AWAIT_RECONF_IDX].strptr), "yes") == 0; + 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; } diff --git a/openair2/ENB_APP/flexran_agent.c b/openair2/ENB_APP/flexran_agent.c index 60239cbbbd..d32f3e660f 100644 --- a/openair2/ENB_APP/flexran_agent.c +++ b/openair2/ENB_APP/flexran_agent.c @@ -180,16 +180,17 @@ pthread_t new_thread(void *(*f)(void *), void *b) { int channel_container_init = 0; int flexran_agent_start(mid_t mod_id) { + flexran_agent_info_t *flexran = RC.flexran[mod_id]; int channel_id; - char *in_ip = RC.flexran[mod_id]->remote_ipv4_addr; - uint16_t in_port = RC.flexran[mod_id]->remote_port; + char *in_ip = flexran->remote_ipv4_addr; + uint16_t in_port = flexran->remote_port; - RC.flexran[mod_id]->enb_id = mod_id; + flexran->enb_id = mod_id; /* assume for the moment the monolithic case, i.e. agent can provide * information for all layers */ - RC.flexran[mod_id]->capability_mask = FLEXRAN_CAP_LOL1 | FLEXRAN_CAP_HIL1 - | FLEXRAN_CAP_LOL2 | FLEXRAN_CAP_HIL2 - | FLEXRAN_CAP_PDCP | FLEXRAN_CAP_RRC; + 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 @@ -228,7 +229,7 @@ int flexran_agent_start(mid_t mod_id) /*Initialize the continuous stats update mechanism*/ flexran_agent_init_cont_stats_update(mod_id); - new_thread(receive_thread, RC.flexran[mod_id]); + new_thread(receive_thread, flexran); /*Initialize and register the mac xface. Must be modified later *for more flexibility in agent management */ @@ -239,8 +240,8 @@ int flexran_agent_start(mid_t mod_id) AGENT_RRC_xface *rrc_agent_xface = (AGENT_RRC_xface *) malloc(sizeof(AGENT_RRC_xface)); flexran_agent_register_rrc_xface(mod_id, rrc_agent_xface); - AGENT_PDCP_xface *pdcp_agent_xface = (AGENT_PDCP_xface *) malloc(sizeof(AGENT_PDCP_xface)); - flexran_agent_register_pdcp_xface(mod_id, pdcp_agent_xface); + AGENT_PDCP_xface *pdcp_agent_xface = (AGENT_PDCP_xface *) malloc(sizeof(AGENT_PDCP_xface)); + flexran_agent_register_pdcp_xface(mod_id, pdcp_agent_xface); /* * initilize a timer @@ -257,14 +258,34 @@ int flexran_agent_start(mid_t mod_id) * start the enb agent task for tx and interaction with the underlying network function */ if (!agent_task_created) { - if (itti_create_task (TASK_FLEXRAN_AGENT, flexran_agent_task, (void *) RC.flexran[mod_id]) < 0) { + if (itti_create_task (TASK_FLEXRAN_AGENT, flexran_agent_task, flexran) < 0) { LOG_E(FLEXRAN_AGENT, "Create task for FlexRAN Agent failed\n"); return -1; } agent_task_created = 1; } - - LOG_I(FLEXRAN_AGENT,"client ends\n"); + + pthread_mutex_init(&flexran->mutex_node_ctrl, NULL); + pthread_cond_init(&flexran->cond_node_ctrl, NULL); + + if (flexran->node_ctrl_state == ENB_WAIT) { + /* wait three seconds before showing message and waiting "for real". + * This way, the message is (hopefully...) the last one and the user knows + * what is happening. If the controller sends a reconfiguration message in + * the meantime, the softmodem will never wait */ + sleep(3); + LOG_I(ENB_APP, " * eNB %d: Waiting for FlexRAN RTController command *\n", mod_id); + pthread_mutex_lock(&flexran->mutex_node_ctrl); + while (ENB_NORMAL_OPERATION != flexran->node_ctrl_state) + pthread_cond_wait(&flexran->cond_node_ctrl, &flexran->mutex_node_ctrl); + pthread_mutex_unlock(&flexran->mutex_node_ctrl); + + /* reconfigure RRC again, the agent might have changed the configuration */ + MessageDef *msg_p = itti_alloc_new_message(TASK_ENB_APP, RRC_CONFIGURATION_REQ); + RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[mod_id]->configuration; + itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg_p); + } + return 0; error: diff --git a/openair2/ENB_APP/flexran_agent.h b/openair2/ENB_APP/flexran_agent.h index ed9ee444c3..aed8f9eb60 100644 --- a/openair2/ENB_APP/flexran_agent.h +++ b/openair2/ENB_APP/flexran_agent.h @@ -42,12 +42,8 @@ #include "log.h" #include "assertions.h" -#include "enb_config.h" // for enb properties - - -/* Initiation and termination of the eNodeB agent */ +/* Initiation of the eNodeB agent */ int flexran_agent_start(mid_t mod_id); -int flexran_agent_stop(mid_t mod_id); /* * enb agent task mainly wakes up the tx thread for periodic and oneshot messages to the controller diff --git a/openair2/ENB_APP/flexran_agent_common_internal.c b/openair2/ENB_APP/flexran_agent_common_internal.c index 416f13f241..0e65fe7236 100644 --- a/openair2/ENB_APP/flexran_agent_common_internal.c +++ b/openair2/ENB_APP/flexran_agent_common_internal.c @@ -39,13 +39,32 @@ void handle_reconfiguration(mid_t mod_id) { struct timespec start, end; clock_gettime(CLOCK_MONOTONIC, &start); + flexran_agent_info_t *flexran = RC.flexran[mod_id]; + + if (ENB_WAIT == flexran->node_ctrl_state) { + /* this is already waiting, just release */ + pthread_mutex_lock(&flexran->mutex_node_ctrl); + flexran->node_ctrl_state = ENB_NORMAL_OPERATION; + pthread_mutex_unlock(&flexran->mutex_node_ctrl); + pthread_cond_signal(&flexran->cond_node_ctrl); + return; + } if (stop_L1L2(mod_id) < 0) { LOG_E(ENB_APP, "can not stop lte-softmodem, aborting restart\n"); return; } - /* TODO wait state could be here IF IT IS NOT EXECUTED BY THE FLEXRAN THREAD */ + /* node_ctrl_state should have value ENB_MAKE_WAIT only if this method is not + * executed by the FlexRAN thread */ + if (ENB_MAKE_WAIT == flexran->node_ctrl_state) { + LOG_I(ENB_APP, " * eNB %d: Waiting for FlexRAN RTController command *\n", mod_id); + pthread_mutex_lock(&flexran->mutex_node_ctrl); + flexran->node_ctrl_state = ENB_WAIT; + while (ENB_NORMAL_OPERATION != flexran->node_ctrl_state) + pthread_cond_wait(&flexran->cond_node_ctrl, &flexran->mutex_node_ctrl); + pthread_mutex_unlock(&flexran->mutex_node_ctrl); + } if (restart_L1L2(mod_id) < 0) { LOG_F(ENB_APP, "can not restart, killing lte-softmodem\n"); diff --git a/openair2/ENB_APP/flexran_agent_defs.h b/openair2/ENB_APP/flexran_agent_defs.h index dc86a422c4..fd22b01e61 100644 --- a/openair2/ENB_APP/flexran_agent_defs.h +++ b/openair2/ENB_APP/flexran_agent_defs.h @@ -145,17 +145,27 @@ typedef enum { #define FLEXRAN_CAP_PDCP 0x16 #define FLEXRAN_CAP_RRC 0x32 +typedef enum { + ENB_NORMAL_OPERATION = 0x0, + ENB_WAIT = 0x1, + ENB_MAKE_WAIT = 0x2, +} flexran_enb_state_t; + typedef struct { /* general info */ char *interface_name; char *remote_ipv4_addr; uint16_t remote_port; char *cache_name; - uint8_t await_reconf; int enb_id; uint8_t capability_mask; + /* lock for waiting before starting or soft-restart */ + pthread_cond_t cond_node_ctrl; + pthread_mutex_t mutex_node_ctrl; + flexran_enb_state_t node_ctrl_state; + /* stats */ uint32_t total_rx_msg; diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index c8db435d46..91d626c9d3 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1149,26 +1149,6 @@ int main( int argc, char **argv ) for (CC_id=0; CC_idrfdevice.trx_end_func) diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index c6f8d8d54c..dd178c2911 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -272,10 +272,7 @@ extern int stop_L1L2(module_id_t enb_id); extern int restart_L1L2(module_id_t enb_id); #ifdef FLEXRAN_AGENT_SB_IF -#include "flexran_agent.h" // for locking -//volatile ENB_MODULE_STATE node_control_state; -pthread_cond_t cond_node_ctrl; -pthread_mutex_t mutex_node_ctrl; +#include "flexran_agent.h" #endif #endif From d5b8310fb9b49990a5049eb1f75e274bb2ec4759 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 23 Jan 2018 17:13:54 +0100 Subject: [PATCH 090/195] add some logging for RRM command parsing --- openair2/ENB_APP/flexran_agent_common_internal.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair2/ENB_APP/flexran_agent_common_internal.c b/openair2/ENB_APP/flexran_agent_common_internal.c index 0e65fe7236..8874a0f648 100644 --- a/openair2/ENB_APP/flexran_agent_common_internal.c +++ b/openair2/ENB_APP/flexran_agent_common_internal.c @@ -120,6 +120,7 @@ int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy LOG_I(ENB_APP, "This is intended for the enb system\n"); // Call the enb handler if (parse_enb_id(mod_id, &parser) == -1) { + LOG_E(ENB_APP, "cannot parse data for eNB\n"); goto error; } else { // succeful parse and setting handle_reconfiguration(mod_id); @@ -294,6 +295,7 @@ int parse_enb_config_parameters(mid_t mod_id, yaml_parser_t *parser) { strtol((char *) event.data.scalar.value, &endptr, 10)); LOG_I(ENB_APP, "Setting frame_type to %s\n", event.data.scalar.value); }else { // not supported tag + LOG_E(FLEXRAN_AGENT, "Unsupported tag %s\n", event.data.scalar.value); goto error; } From 2c8dd796e8c4910945a2442c2f47a4c8a9e9f8bb Mon Sep 17 00:00:00 2001 From: shahab SHARIAT BAGHERI Date: Fri, 19 Jan 2018 16:29:50 +0100 Subject: [PATCH 091/195] Scheduler must send FlexRAN stats updates --- openair2/LAYER2/MAC/eNB_scheduler.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 1195e05379..67d8f270db 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -751,6 +751,10 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, schedule_CSI(module_idP, frameP, subframeP); // This schedules DLSCH in subframeP schedule_dlsch(module_idP, frameP, subframeP, mbsfn_status); + +#if defined(FLEXRAN_AGENT_SB_IF) + flexran_agent_send_update_stats(module_idP); +#endif // Allocate CCEs for good after scheduling is done for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) From 4f1c51f38ca4812fd8423ce70f57cda7b97e9d17 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 25 Jan 2018 14:07:45 +0100 Subject: [PATCH 092/195] add phy_free_RU() and phy_free_lte_eNB() this methods free the memory that is allocated by the functions phy_init_RU() and phy_init_lte_eNB() --- openair1/PHY/INIT/defs.h | 7 ++ openair1/PHY/INIT/lte_init.c | 127 +++++++++++++++++++++++++++++++- openair1/PHY/defs.h | 6 ++ targets/RT/USER/lte-enb.c | 2 + targets/RT/USER/lte-ru.c | 3 + targets/RT/USER/lte-softmodem.c | 4 + 6 files changed, 147 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/INIT/defs.h b/openair1/PHY/INIT/defs.h index 744fb3d3ce..e7972335ab 100644 --- a/openair1/PHY/INIT/defs.h +++ b/openair1/PHY/INIT/defs.h @@ -90,6 +90,13 @@ int phy_init_lte_eNB(PHY_VARS_eNB *phy_vars_eNb, unsigned char is_secondary_eNb, unsigned char abstraction_flag); +/*! +\brief Free the PHY variables relevant to the LTE implementation (eNB). +\details Only a subset of phy_vars_eNb is freed (those who have been allocated with phy_init_lte_eNB()). +@param[in] phy_vars_eNb Pointer to eNB Variables + */ +void phy_free_lte_eNB(PHY_VARS_eNB *phy_vars_eNb); + /** \brief Configure LTE_DL_FRAME_PARMS with components derived after initial synchronization (MIB decoding + primary/secondary synch). \details The basically allows configuration of \f$N_{\mathrm{RB}}^{\mathrm{DL}}\f$, the cell id \f$N_{\mathrm{ID}}^{\mathrm{cell}}\f$, the normal/extended prefix mode, the frame type (FDD/TDD), \f$N_{\mathrm{cp}}\f$, the number of TX antennas at eNB (\f$p\f$) and the number of PHICH groups, \f$N_{\mathrm{group}}^{\mathrm{PHICH}}\f$ @param lte_frame_parms pointer to LTE parameter structure diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index 283667134d..f5db781309 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -1777,7 +1777,55 @@ int phy_init_RU(RU_t *ru) { return(0); } - + +void phy_free_RU(RU_t *ru) +{ + int i,j; + int p; + + LOG_I(PHY, "Feeing RU signal buffers (if_south %s) nb_tx %d\n", ru_if_types[ru->if_south], ru->nb_tx); + + if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so free memory for time-domain signals + for (i = 0; i < ru->nb_tx; i++) free_and_zero(ru->common.txdata[i]); + for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdata[i]); + free_and_zero(ru->common.txdata); + free_and_zero(ru->common.rxdata); + } // else: IF5 or local RF -> nothing to free() + + if (ru->function != NGFI_RRU_IF5) { // we need to do RX/TX RU processing + for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdata_7_5kHz[i]); + free_and_zero(ru->common.rxdata_7_5kHz); + + // free IFFT input buffers (TX) + for (i = 0; i < ru->nb_tx; i++) free_and_zero(ru->common.txdataF_BF[i]); + free_and_zero(ru->common.txdataF_BF); + + // free FFT output buffers (RX) + for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdataF[i]); + free_and_zero(ru->common.rxdataF); + + for (i = 0; i < ru->nb_rx; i++) { + free_and_zero(ru->prach_rxsigF[i]); +#ifdef Rel14 + for (j = 0; j < 4; j++) free_and_zero(ru->prach_rxsigF_br[j][i]); +#endif + } + for (j = 0; j < 4; j++) free_and_zero(ru->prach_rxsigF_br[j]); + free_and_zero(ru->prach_rxsigF); + /* ru->prach_rxsigF_br is not allocated -> don't free */ + + for (i = 0; i < RC.nb_L1_inst; i++) { + for (p = 0; p < 15; p++) { + if (p < ru->eNB_list[i]->frame_parms.nb_antenna_ports_eNB || p == 5) { + for (j=0; jnb_tx; j++) free_and_zero(ru->beam_weights[i][p][j]); + free_and_zero(ru->beam_weights[i][p]); + } + } + } + } + free_and_zero(ru->common.sync_corr); +} + int phy_init_lte_eNB(PHY_VARS_eNB *eNB, unsigned char is_secondary_eNB, unsigned char abstraction_flag) @@ -1911,7 +1959,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, AssertFatal(fp->N_RB_UL > 5, "fp->N_RB_UL %d < 6\n",fp->N_RB_UL); for (i=0; i<2; i++) { // RK 2 times because of output format of FFT! - // FIXME We should get rid of this + // FIXME We should get rid of this, consider also phy_free_lte_eNB() pusch_vars[UE_id]->rxdataF_ext[i] = (int32_t*)malloc16_clear( 2*sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti ); pusch_vars[UE_id]->rxdataF_ext2[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti ); pusch_vars[UE_id]->drs_ch_estimates[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti ); @@ -1934,3 +1982,78 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, return (0); } + + +void phy_free_lte_eNB(PHY_VARS_eNB *eNB) +{ + LTE_DL_FRAME_PARMS* const fp = &eNB->frame_parms; + LTE_eNB_COMMON* const common_vars = &eNB->common_vars; + LTE_eNB_PUSCH** const pusch_vars = eNB->pusch_vars; + LTE_eNB_SRS* const srs_vars = eNB->srs_vars; + LTE_eNB_PRACH* const prach_vars = &eNB->prach_vars; +#ifdef Rel14 + LTE_eNB_PRACH* const prach_vars_br = &eNB->prach_vars_br; +#endif + int i, UE_id; + + for (i = 0; i < NB_ANTENNA_PORTS_ENB; i++) { + if (i < fp->nb_antenna_ports_eNB || i == 5) { + free_and_zero(common_vars->txdataF[i]); + /* rxdataF[i] is not allocated -> don't free */ + } + } + free_and_zero(common_vars->txdataF); + free_and_zero(common_vars->rxdataF); + + // Channel estimates for SRS + for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { + for (i=0; i<64; i++) { + free_and_zero(srs_vars[UE_id].srs_ch_estimates[i]); + free_and_zero(srs_vars[UE_id].srs_ch_estimates_time[i]); + } + free_and_zero(srs_vars[UE_id].srs_ch_estimates); + free_and_zero(srs_vars[UE_id].srs_ch_estimates_time); + } //UE_id + + free_ul_ref_sigs(); + + for (UE_id=0; UE_idprachF); + + for (i = 0; i < 64; i++) free_and_zero(prach_vars->prach_ifft[0][i]); + free_and_zero(prach_vars->prach_ifft[0]); + +#ifdef Rel14 + for (int ce_level = 0; ce_level < 4; ce_level++) { + for (i = 0; i < 64; i++) free_and_zero(prach_vars_br->prach_ifft[ce_level][i]); + free_and_zero(prach_vars_br->prach_ifft[ce_level]); + free_and_zero(prach_vars->rxsigF[ce_level]); + } + free_and_zero(prach_vars_br->prachF); +#endif + free_and_zero(prach_vars->rxsigF[0]); + + for (UE_id=0; UE_idrxdataF_ext[i]); + free_and_zero(pusch_vars[UE_id]->rxdataF_ext2[i]); + free_and_zero(pusch_vars[UE_id]->drs_ch_estimates[i]); + free_and_zero(pusch_vars[UE_id]->drs_ch_estimates_time[i]); + free_and_zero(pusch_vars[UE_id]->rxdataF_comp[i]); + free_and_zero(pusch_vars[UE_id]->ul_ch_mag[i]); + free_and_zero(pusch_vars[UE_id]->ul_ch_magb[i]); + } + free_and_zero(pusch_vars[UE_id]->rxdataF_ext); + free_and_zero(pusch_vars[UE_id]->rxdataF_ext2); + free_and_zero(pusch_vars[UE_id]->drs_ch_estimates); + free_and_zero(pusch_vars[UE_id]->drs_ch_estimates_time); + free_and_zero(pusch_vars[UE_id]->rxdataF_comp); + free_and_zero(pusch_vars[UE_id]->ul_ch_mag); + free_and_zero(pusch_vars[UE_id]->ul_ch_magb); + free_and_zero(pusch_vars[UE_id]->llr); + free_and_zero(pusch_vars[UE_id]); + } //UE_id + + for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) eNB->UE_stats_ptr[UE_id] = NULL; +} diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index 0e44a7f8bd..b5c2e54fa5 100644 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -79,6 +79,12 @@ #define bigmalloc16 malloc16 #define openair_free(y,x) free((y)) #define PAGE_SIZE 4096 +#define free_and_zero(PtR) do { \ + if (PtR) { \ + free(PtR); \ + PtR = NULL; \ + } \ + } while (0) #define RX_NB_TH_MAX 2 #define RX_NB_TH 2 diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 6b418bb8ff..ece2b75c77 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -974,5 +974,7 @@ void stop_eNB(int nb_inst) { for (int inst=0;inst Date: Fri, 26 Jan 2018 14:49:45 +0100 Subject: [PATCH 093/195] free memory when stopping/restarting lte-softmodem - add function free_td() -> complements init_td() [seems to not be used, added for completeness] - add function free_td8() -> undoes init_td8() [free memory of 8-bit LLR Turbo decoder] - add function free_td16() -> undoes init_td16() [free memory of 16-bit LLR Turbo decoder] - change function free_tdavx216() -> undoes init_tdavx216() [free memory of 16-bit LLR Turbo decoder, AVX2 version] - add free_lte_top() -> frees memory allocated by init_lte_top() - change free_ul_ref_sigs() to set freed pointers to NULL - add method free_transport() -> frees memory of ULSCH/DLSCH transport channels - use the above functions when stopping/restarting the lte-softmodem --- .../CODING/3gpplte_turbo_decoder_avx2_16bit.c | 8 ++++---- .../PHY/CODING/3gpplte_turbo_decoder_sse.c | 12 +++++++++++ .../CODING/3gpplte_turbo_decoder_sse_16bit.c | 8 ++++---- .../CODING/3gpplte_turbo_decoder_sse_8bit.c | 8 ++++---- openair1/PHY/CODING/defs.h | 10 ++++++++++ openair1/PHY/INIT/defs.h | 1 + openair1/PHY/INIT/lte_init.c | 12 +++++++++++ openair1/PHY/LTE_REFSIG/lte_ul_ref.c | 8 ++++++-- openair1/PHY/LTE_TRANSPORT/proto.h | 6 ++++++ targets/RT/USER/lte-enb.c | 20 ++++++++++++++++++- targets/RT/USER/lte-ru.c | 2 -- targets/RT/USER/lte-softmodem.c | 8 +++++++- 12 files changed, 85 insertions(+), 18 deletions(-) diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c index 616eed7446..83a50f214b 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c @@ -830,10 +830,10 @@ void free_td16avx2(void) int ind; for (ind=0; ind<188; ind++) { - free(pi2tab16avx2[ind]); - free(pi5tab16avx2[ind]); - free(pi4tab16avx2[ind]); - free(pi6tab16avx2[ind]); + free_and_zero(pi2tab16avx2[ind]); + free_and_zero(pi5tab16avx2[ind]); + free_and_zero(pi4tab16avx2[ind]); + free_and_zero(pi6tab16avx2[ind]); } } diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse.c index 9ec25367d9..f628bff55b 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse.c @@ -1907,6 +1907,18 @@ void compute_ext(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,llr_t* ext, ll //int pi2[n],pi3[n+8],pi5[n+8],pi4[n+8],pi6[n+8], int *pi2tab[188],*pi5tab[188],*pi4tab[188],*pi6tab[188]; +void free_td() +{ + int ind; + + for (ind = 0; ind < 188; ind++) { + free_and_zero(pi2tab[ind]); + free_and_zero(pi5tab[ind]); + free_and_zero(pi4tab[ind]); + free_and_zero(pi6tab[ind]); + } +} + void init_td() { diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c index cb4a4e1f84..a32edd711d 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c @@ -1117,10 +1117,10 @@ void free_td16(void) int ind; for (ind=0; ind<188; ind++) { - free(pi2tab16[ind]); - free(pi5tab16[ind]); - free(pi4tab16[ind]); - free(pi6tab16[ind]); + free_and_zero(pi2tab16[ind]); + free_and_zero(pi5tab16[ind]); + free_and_zero(pi4tab16[ind]); + free_and_zero(pi6tab16[ind]); } } diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c index d6ef84b218..4754e26f38 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c @@ -838,10 +838,10 @@ void free_td8(void) int ind; for (ind=0; ind<188; ind++) { - free(pi2tab8[ind]); - free(pi5tab8[ind]); - free(pi4tab8[ind]); - free(pi6tab8[ind]); + free_and_zero(pi2tab8[ind]); + free_and_zero(pi5tab8[ind]); + free_and_zero(pi4tab8[ind]); + free_and_zero(pi6tab8[ind]); } } diff --git a/openair1/PHY/CODING/defs.h b/openair1/PHY/CODING/defs.h index 06311a188b..9150e19bf1 100644 --- a/openair1/PHY/CODING/defs.h +++ b/openair1/PHY/CODING/defs.h @@ -356,10 +356,17 @@ void ccodedab_init_inv(void); \brief This function initializes the different crc tables.*/ void crcTableInit (void); +/*!\fn void free_td8(void) +\brief This function frees the tables for 8-bit LLR Turbo decoder.*/ +void free_td8(void); + /*!\fn void init_td8(void) \brief This function initializes the tables for 8-bit LLR Turbo decoder.*/ void init_td8 (void); +/*!\fn void free_td16(void) +\brief This function frees the tables for 16-bit LLR Turbo decoder.*/ +void free_td16(void); /*!\fn void init_td16(void) \brief This function initializes the tables for 16-bit LLR Turbo decoder.*/ @@ -370,6 +377,9 @@ void init_td16 (void); \brief This function initializes the tables for 8-bit LLR Turbo decoder (AVX2).*/ void init_td8avx2 (void); +/*!\fn void free_td16avx2(void) +\brief This function frees the tables for 16-bit LLR Turbo decoder (AVX2).*/ +void free_td16avx2(void); /*!\fn void init_td16(void) \brief This function initializes the tables for 16-bit LLR Turbo decoder (AVX2).*/ diff --git a/openair1/PHY/INIT/defs.h b/openair1/PHY/INIT/defs.h index e7972335ab..55d220824e 100644 --- a/openair1/PHY/INIT/defs.h +++ b/openair1/PHY/INIT/defs.h @@ -324,6 +324,7 @@ void phy_config_dedicated_eNB_step2(PHY_VARS_eNB *phy_vars_eNB); */ int phy_init_secsys_eNB(PHY_VARS_eNB *phy_vars_eNb); +void free_lte_top(void); void init_lte_top(LTE_DL_FRAME_PARMS *lte_frame_parms); diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index f5db781309..86ed62040f 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -1247,6 +1247,18 @@ void phy_config_cba_rnti (module_id_t Mod_id,int CC_id,eNB_flag_t eNB_flag, uin } } +void free_lte_top(void) +{ + free_td8(); + free_td16(); +#ifdef __AVX2__ + free_td16avx2(); +#endif + lte_sync_time_free(); + + /* free_ul_ref_sigs() is called in phy_free_lte_eNB() */ +} + void init_lte_top(LTE_DL_FRAME_PARMS *frame_parms) { diff --git a/openair1/PHY/LTE_REFSIG/lte_ul_ref.c b/openair1/PHY/LTE_REFSIG/lte_ul_ref.c index cddb642b2b..cacd0f4292 100644 --- a/openair1/PHY/LTE_REFSIG/lte_ul_ref.c +++ b/openair1/PHY/LTE_REFSIG/lte_ul_ref.c @@ -188,11 +188,15 @@ void free_ul_ref_sigs(void) for (Msc_RS=2; Msc_RS<33; Msc_RS++) { for (u=0; u<30; u++) { for (v=0; v<2; v++) { - if (ul_ref_sigs[u][v][Msc_RS]) + if (ul_ref_sigs[u][v][Msc_RS]) { free16(ul_ref_sigs[u][v][Msc_RS],2*sizeof(int16_t)*dftsizes[Msc_RS]); + ul_ref_sigs_rx[u][v][Msc_RS] = NULL; + } - if (ul_ref_sigs_rx[u][v][Msc_RS]) + if (ul_ref_sigs_rx[u][v][Msc_RS]) { free16(ul_ref_sigs_rx[u][v][Msc_RS],4*sizeof(int16_t)*dftsizes[Msc_RS]); + ul_ref_sigs_rx[u][v][Msc_RS] = NULL; + } } } } diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 8a0e160f23..98a32f68a0 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -83,6 +83,12 @@ void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); void free_ue_ulsch(LTE_UE_ULSCH_t *ulsch); +/** \fn free_eNB_ulsch(LTE_eNB_DLSCH_t *dlsch) + \brief This function frees memory allocated for a particular ULSCH at eNB + @param ulsch Pointer to ULSCH to be removed +*/ +void free_eNB_ulsch(LTE_eNB_ULSCH_t *ulsch); + LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag); LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag); diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index ece2b75c77..bd9fbab19d 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -794,6 +794,21 @@ void print_opp_meas(void) { } } +void free_transport(PHY_VARS_eNB *eNB) +{ + int i; + int j; + + for (i=0; idlsch[i][j]); + + LOG_I(PHY, "Freeing Transport Channel Buffer for ULSCH, UE %d\n",i); + free_eNB_ulsch(eNB->ulsch[1+i]); + } + free_eNB_ulsch(eNB->ulsch[0]); +} + void init_transport(PHY_VARS_eNB *eNB) { int i; @@ -975,6 +990,9 @@ void stop_eNB(int nb_inst) { LOG_I(PHY,"Killing eNB %d processing threads\n",inst); kill_eNB_proc(inst); /* release memory used by these threads (incomplete) */ - for (int cc_id = 0; cc_id < RC.nb_CC[inst]; cc_id++) phy_free_lte_eNB(RC.eNB[inst][cc_id]); + for (int cc_id = 0; cc_id < RC.nb_CC[inst]; cc_id++) { + free_transport(RC.eNB[inst][cc_id]); + phy_free_lte_eNB(RC.eNB[inst][cc_id]); + } } } diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 6459b6a58d..5a2f49212c 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -1557,8 +1557,6 @@ void *ru_thread_synch(void *arg) { if (release_thread(&ru->proc.mutex_synch,&ru->proc.instance_cnt_synch,"ru_synch_thread") < 0) break; } // oai_exit - lte_sync_time_free(); - ru_thread_synch_status = 0; return &ru_thread_synch_status; diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 6ae35a9bf0..8df540bc49 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -884,6 +884,7 @@ void terminate_task(task_id_t task_id, module_id_t mod_id) itti_send_msg_to_task (task_id, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); } +extern void free_transport(PHY_VARS_eNB *); extern void phy_free_RU(RU_t*); int stop_L1L2(module_id_t enb_id) @@ -923,8 +924,12 @@ int stop_L1L2(module_id_t enb_id) LOG_I(ENB_APP, "calling kill_RU_proc() for instance %d\n", enb_id); kill_RU_proc(enb_id); oai_exit = 0; - for (int cc_id = 0; cc_id < RC.nb_CC[enb_id]; cc_id++) phy_free_lte_eNB(RC.eNB[enb_id][cc_id]); + for (int cc_id = 0; cc_id < RC.nb_CC[enb_id]; cc_id++) { + free_transport(RC.eNB[enb_id][cc_id]); + phy_free_lte_eNB(RC.eNB[enb_id][cc_id]); + } phy_free_RU(RC.ru[enb_id]); + free_lte_top(); return 0; } @@ -1491,6 +1496,7 @@ int main( int argc, char **argv ) } else { stop_eNB(NB_eNB_INST); stop_RU(NB_RU); + free_lte_top(); } From 6dcac9234cb0d13317f311e1c5633ce76af6010f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 29 Jan 2018 10:25:16 +0100 Subject: [PATCH 094/195] Navid: revise FlexRAN --- openair2/ENB_APP/flexran_agent_common.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index 33879714d9..de0de15c0a 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -467,6 +467,7 @@ int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__Fl //Set this according to the current state of the UE. This is only a temporary fix int status = 0; status = mac_eNB_get_rrc_status(mod_id, flexran_get_ue_crnti(mod_id, i)); + /* TODO needs to be revised and appropriate API to be implemented */ if (status < RRC_CONNECTED) { lc_ue_config[i]->n_lc_config = 0; } else if (status == RRC_CONNECTED) { @@ -505,6 +506,7 @@ int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__Fl lc_config[j]->has_qci = 1; lc_config[j]->qci = 1; if (lc_config[j]->direction == PROTOCOL__FLEX_QOS_BEARER_TYPE__FLQBT_GBR) { + /* TODO all of the need to be taken from API */ //TODO: Set the max bitrate (UL) lc_config[j]->has_e_rab_max_bitrate_ul = 0; lc_config[j]->e_rab_max_bitrate_ul = 0; From e669f83dc1789c3dbc75c13a290e70d659cc3a3f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 29 Jan 2018 11:05:04 +0100 Subject: [PATCH 095/195] Navid: revise RAN API --- openair2/ENB_APP/flexran_agent_ran_api.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 75552526a7..2e1878f5e5 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -861,6 +861,7 @@ int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id) } } +/* TODO Navid: Get the same for eNB */ long flexran_get_lcg(mid_t ue_id, mid_t lc_id) { if (!UE_mac_inst) return -1; @@ -870,10 +871,9 @@ long flexran_get_lcg(mid_t ue_id, mid_t lc_id) return *(UE_mac_inst[ue_id].logicalChannelConfig[lc_id]->ul_SpecificParameters->logicalChannelGroup); } +/* TODO Navid: needs to be revised */ int flexran_get_direction(mid_t ue_id, mid_t lc_id) { - /* TODO: fill with the value for the rest of LCID -> Robert: What does that - * mean? */ switch (lc_id) { case DCCH: case DCCH1: From dd7d2ef63b4f8b49aabcc921f42cdd8ca6a34cfa Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 29 Jan 2018 11:05:52 +0100 Subject: [PATCH 096/195] Navid: revise RRC --- openair2/RRC/LITE/rrc_eNB.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index 8402d1ba61..9fb1165beb 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -2141,7 +2141,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons } #if defined(FLEXRAN_AGENT_SB_IF) - +/* TODO Navid: does this belong here? */ //----------------------------------------------------------------------------- void flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* const ctxt_pP, From 6eeb25771727db8bf7368096b19acf97ec857960 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 29 Jan 2018 14:47:52 +0100 Subject: [PATCH 097/195] add UE_Capability to type eNB_RRC_UE_t and read it when received --- openair2/RRC/LITE/defs.h | 2 ++ openair2/RRC/LITE/rrc_eNB.c | 24 +++++++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/openair2/RRC/LITE/defs.h b/openair2/RRC/LITE/defs.h index 9a346f7fb7..91e50a16d8 100644 --- a/openair2/RRC/LITE/defs.h +++ b/openair2/RRC/LITE/defs.h @@ -395,6 +395,8 @@ typedef struct eNB_RRC_UE_s { MeasConfig_t* measConfig; HANDOVER_INFO* handover_info; MeasResults_t* measResults; + + UE_EUTRA_Capability_t* UE_Capability; #if defined(ENABLE_SECURITY) /* KeNB as derived from KASME received from EPC */ diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index 9fb1165beb..bae9138b5f 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -4994,7 +4994,6 @@ rrc_eNB_decode_dcch( asn_dec_rval_t dec_rval; //UL_DCCH_Message_t uldcchmsg; UL_DCCH_Message_t *ul_dcch_msg = NULL; //&uldcchmsg; - UE_EUTRA_Capability_t *UE_EUTRA_Capability = NULL; int i; struct rrc_eNB_ue_context_s* ue_context_p = NULL; @@ -5385,18 +5384,33 @@ rrc_eNB_decode_dcch( xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void *)ul_dcch_msg); #endif LOG_I(RRC, "got UE capabilities for UE %x\n", ctxt_pP->rnti); + if (ue_context_p->ue_context.UE_Capability) { + LOG_I(RRC, "freeing old UE capabilities for UE %x\n", ctxt_pP->rnti); + asn_DEF_UE_EUTRA_Capability.free_struct(&asn_DEF_UE_EUTRA_Capability, + ue_context_p->ue_context.UE_Capability, 0); + ue_context_p->ue_context.UE_Capability = 0; + } dec_rval = uper_decode(NULL, &asn_DEF_UE_EUTRA_Capability, - (void **)&UE_EUTRA_Capability, + (void **)&ue_context_p->ue_context.UE_Capability, ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions. choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list. array[0]->ueCapabilityRAT_Container.buf, ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions. choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list. array[0]->ueCapabilityRAT_Container.size, 0, 0); - //#ifdef XER_PRINT - //xer_fprint(stdout, &asn_DEF_UE_EUTRA_Capability, (void *)UE_EUTRA_Capability); - //#endif +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_UE_EUTRA_Capability, ue_context_p->ue_context.UE_Capability); +#endif + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Failed to decode UE capabilities (%zu bytes)\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + dec_rval.consumed); + asn_DEF_UE_EUTRA_Capability.free_struct(&asn_DEF_UE_EUTRA_Capability, + ue_context_p->ue_context.UE_Capability, 0); + ue_context_p->ue_context.UE_Capability = 0; + } #if defined(ENABLE_USE_MME) From fcddbc2b441ead0d8d026e6c40362348e9d11176 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 29 Jan 2018 14:48:41 +0100 Subject: [PATCH 098/195] RAN API: add functions using UE_Capability - flexran_get_half_duplex() - flexran_get_intra_sf_hopping() - flexran_get_type2_sb_1() - flexran_get_ue_category() - flexran_get_res_alloc_type1() --- openair2/ENB_APP/flexran_agent_ran_api.c | 102 +++++++++++++++-------- openair2/ENB_APP/flexran_agent_ran_api.h | 27 ++---- 2 files changed, 76 insertions(+), 53 deletions(-) diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 2e1878f5e5..ddbc3ad869 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -638,55 +638,87 @@ uint64_t flexran_get_ue_aggregated_max_bitrate_ul(mid_t mod_id, mid_t ue_id) return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateUL; } -int flexran_get_half_duplex(mid_t ue_id) +int flexran_get_half_duplex(mid_t mod_id, mid_t ue_id) { -#warning "Implement flexran_get_half_duplex() in RAN API" - // TODO - //int halfduplex = 0; - //int bands_to_scan = ((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count; - //for (int i =0; i < bands_to_scan; i++){ - //if(((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->halfDuplex > 0) - // halfduplex = 1; - //} - //return halfduplex; + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.UE_Capability) return -1; + SupportedBandListEUTRA_t *bands = &ue_context_p->ue_context.UE_Capability->rf_Parameters.supportedBandListEUTRA; + for (int i = 0; i < bands->list.count; i++) { + if (bands->list.array[i]->halfDuplex > 0) return 1; + } return 0; } -int flexran_get_intra_sf_hopping(mid_t ue_id) +int flexran_get_intra_sf_hopping(mid_t mod_id, mid_t ue_id) { -#warning "Implement flexran_get_intra_sf_hopping() in RAN API" - //TODO:Get proper value - //temp = (((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->featureGroupIndicators->buf); - //return (0 & ( 1 << (31))); - return 0; + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.UE_Capability) return -1; + if (!ue_context_p->ue_context.UE_Capability->featureGroupIndicators) return -1; + /* According to TS 36.331 Annex B.1, Intra SF Hopping is bit 1 (leftmost bit) + * in this bitmap, i.e. the eighth bit (from right) in the first bye (from + * left) */ + BIT_STRING_t *fgi = ue_context_p->ue_context.UE_Capability->featureGroupIndicators; + uint8_t buf = fgi->buf[0]; + return (buf >> 7) & 1; } -int flexran_get_type2_sb_1(mid_t ue_id) +int flexran_get_type2_sb_1(mid_t mod_id, mid_t ue_id) { -#warning "Implement flexran_get_type2_sb_1() in RAN API" - //TODO:Get proper value - //uint8_t temp = 0; - //temp = (((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->featureGroupIndicators->buf); - //return (temp & ( 1 << (11))); - return 0; + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.UE_Capability) return -1; + if (!ue_context_p->ue_context.UE_Capability->featureGroupIndicators) return -1; + /* According to TS 36.331 Annex B.1, Predefined intra- and inter-sf or + * predfined inter-sf frequency hopping for PUSCH with N_sb>1 is bit 21 (bit + * 1 is leftmost bit) in this bitmap, i.e. the fourth bit (from right) in the + * third byte (from left) */ + BIT_STRING_t *fgi = ue_context_p->ue_context.UE_Capability->featureGroupIndicators; + uint8_t buf = fgi->buf[2]; + return (buf >> 3) & 1; } -int flexran_get_ue_category(mid_t ue_id) +long flexran_get_ue_category(mid_t mod_id, mid_t ue_id) { -#warning "Implement flexran_get_ue_category() in RAN API" - //TODO:Get proper value - //return (((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->ue_Category); - return 0; + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.UE_Capability) return -1; + return ue_context_p->ue_context.UE_Capability->ue_Category; } -int flexran_get_res_alloc_type1(mid_t ue_id) +int flexran_get_res_alloc_type1(mid_t mod_id, mid_t ue_id) { -#warning "Implement flexran_get_res_alloc_type1() in RAN API" - //TODO:Get proper value - //uint8_t temp = 0; - //temp = (((UE_RRC_INST *)enb_ue_rrc[ue_id])->UECap->UE_EUTRA_Capability->featureGroupIndicators->buf); - //return (temp & ( 1 << (30))); - return 0; + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + if (!ue_context_p->ue_context.UE_Capability) return -1; + if (!ue_context_p->ue_context.UE_Capability->featureGroupIndicators) return -1; + /* According to TS 36.331 Annex B.1, Resource allocation type 1 for PDSCH is + * bit 2 (bit 1 is leftmost bit) in this bitmap, i.e. the seventh bit (from + * right) in the first byte (from left) */ + BIT_STRING_t *fgi = ue_context_p->ue_context.UE_Capability->featureGroupIndicators; + uint8_t buf = fgi->buf[0]; + return (buf >> 6) & 1; } long flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id) diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 25faa105a6..62752f1308 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -246,29 +246,20 @@ uint64_t flexran_get_ue_aggregated_max_bitrate_dl(mid_t mod_id, mid_t ue_id); per UE. See TS 36.413 */ uint64_t flexran_get_ue_aggregated_max_bitrate_ul(mid_t mod_id, mid_t ue_id); -/* Only half-duplex support. FDD - operation. Boolean value */ -/* currently broken -int flexran_get_half_duplex(mid_t ue_id); */ +/* Only half-duplex support. FDD operation. Boolean value */ +int flexran_get_half_duplex(mid_t mod_id, mid_t ue_id); -/* Support of intra-subframe hopping. - Boolean value */ -/* currently broken -int flexran_get_intra_sf_hopping(mid_t ue_id); */ +/* Support of intra-subframe hopping. Boolean value */ +int flexran_get_intra_sf_hopping(mid_t mod_id, mid_t ue_id); -/* UE support for type 2 hopping with - n_sb>1 */ -/* currently broken -int flexran_get_type2_sb_1(mid_t ue_id); */ +/* UE support for type 2 hopping with n_sb>1 */ +int flexran_get_type2_sb_1(mid_t mod_id, mid_t ue_id); /* Get the UE category */ -/* currently broken -int flexran_get_ue_category(mid_t ue_id); */ +long flexran_get_ue_category(mid_t mod_id, mid_t ue_id); -/* UE support for resource allocation - type 1 */ -/* currently broken -int flexran_get_res_alloc_type1(mid_t ue_id); */ +/* UE support for resource allocation type 1 */ +int flexran_get_res_alloc_type1(mid_t mod_id, mid_t ue_id); /* Get UE transmission mode */ long flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id); From 4af41d2a265f2fdfbe0ba26bdb37bc4ba7706471 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Sat, 3 Feb 2018 07:53:33 -0800 Subject: [PATCH 099/195] more correction of indentation --- openair2/LAYER2/MAC/eNB_scheduler_bch.c | 329 +- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 3376 ++++++++++----------- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 2506 +++++++-------- 3 files changed, 2887 insertions(+), 3324 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c index 9a1046ff26..258ca36c02 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c @@ -235,35 +235,28 @@ schedule_SIB1_BR(module_id_t module_idP, memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = TBS; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = - eNB->pdu_index[CC_id]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = - getRIV(N_RB_DL, first_rb, 6); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 6); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = rvidx; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = - (cc->p_eNB == 1) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = - 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = - (cc->p_eNB == 1) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; // Rel10 fields @@ -280,10 +273,7 @@ schedule_SIB1_BR(module_id_t module_idP, dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; // Program TX Request - TX_req = - &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB-> - TX_req - [CC_id].tx_request_body.number_of_pdus]; + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; TX_req->pdu_length = bcch_sdu_length; TX_req->pdu_index = eNB->pdu_index[CC_id]++; TX_req->num_segments = 1; @@ -315,11 +305,8 @@ schedule_SIB1_BR(module_id_t module_idP, } } -int si_WindowLength_BR_r13tab - [SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_spare] -= { 20, 40, 60, 80, 120, 160, 200 }; -int si_TBS_r13tab[SchedulingInfo_BR_r13__si_TBS_r13_b936 + 1] = - { 152, 208, 256, 328, 408, 504, 600, 712, 808, 936 }; +int si_WindowLength_BR_r13tab[SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_spare] = { 20, 40, 60, 80, 120, 160, 200 }; +int si_TBS_r13tab[SchedulingInfo_BR_r13__si_TBS_r13_b936 + 1] = { 152, 208, 256, 328, 408, 504, 600, 712, 808, 936 }; //------------------------------------------------------------------------------ void @@ -354,65 +341,40 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, if (cc->mib->message.schedulingInfoSIB1_BR_r13 == 0) continue; else { - - - AssertFatal(cc-> - sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 - != NULL, + AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 != NULL, "sib_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); - SchedulingInfoList_BR_r13_t *schedulingInfoList_BR_r13 = - cc->sib1_v13ext-> - bandwidthReducedAccessRelatedInfo_r13->schedulingInfoList_BR_r13; + SchedulingInfoList_BR_r13_t *schedulingInfoList_BR_r13 = cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->schedulingInfoList_BR_r13; AssertFatal(schedulingInfoList_BR_r13 != NULL, "sib_v13ext->schedulingInfoList_BR_r13 is null\n"); - SchedulingInfoList_t *schedulingInfoList = - cc->schedulingInfoList; - AssertFatal(schedulingInfoList_BR_r13->list.count == - schedulingInfoList->list.count, + SchedulingInfoList_t *schedulingInfoList = cc->schedulingInfoList; + AssertFatal(schedulingInfoList_BR_r13->list.count == schedulingInfoList->list.count, "schedulingInfolist_BR.r13->list.count %d != schedulingInfoList.list.count %d\n", schedulingInfoList_BR_r13->list.count, schedulingInfoList->list.count); - AssertFatal(cc-> - sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13 - <= - SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200, + AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13<=SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200, "si_WindowLength_BR_r13 %d > %d\n", - (int) cc-> - sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13, + (int) cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13, SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200); // check that SI frequency-hopping is disabled - AssertFatal(cc-> - sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_HoppingConfigCommon_r13 - == - SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_HoppingConfigCommon_r13_off, + AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_HoppingConfigCommon_r13 == SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_HoppingConfigCommon_r13_off, "Deactivate SI_HoppingConfigCommon_r13 in configuration file, not supported for now\n"); - long si_WindowLength_BR_r13 = - si_WindowLength_BR_r13tab[cc-> - sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13]; + long si_WindowLength_BR_r13 = si_WindowLength_BR_r13tab[cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13]; - long si_RepetitionPattern_r13 = - cc->sib1_v13ext-> - bandwidthReducedAccessRelatedInfo_r13->si_RepetitionPattern_r13; - AssertFatal(si_RepetitionPattern_r13 <= - SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_RepetitionPattern_r13_every8thRF, + long si_RepetitionPattern_r13 = cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_RepetitionPattern_r13; + AssertFatal(si_RepetitionPattern_r13<=SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_RepetitionPattern_r13_every8thRF, "si_RepetitionPattern_r13 %d > %d\n", (int) si_RepetitionPattern_r13, SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_RepetitionPattern_r13_every8thRF); // cycle through SIB list for (i = 0; i < schedulingInfoList_BR_r13->list.count; i++) { - long si_Periodicity = - schedulingInfoList->list.array[i]->si_Periodicity; - long si_Narrowband_r13 = - schedulingInfoList_BR_r13->list.array[i]-> - si_Narrowband_r13; - long si_TBS_r13 = - si_TBS_r13tab[schedulingInfoList_BR_r13-> - list.array[i]->si_TBS_r13]; + long si_Periodicity = schedulingInfoList->list.array[i]->si_Periodicity; + long si_Narrowband_r13 = schedulingInfoList_BR_r13->list.array[i]->si_Narrowband_r13; + long si_TBS_r13 = si_TBS_r13tab[schedulingInfoList_BR_r13->list.array[i]->si_TBS_r13]; // check if the SI is to be scheduled now int period_in_sf = 80 << si_Periodicity; // 2^i * 80 subframes, note: si_Periodicity is 2^i * 80ms @@ -434,18 +396,14 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, "RRC provided bcch with length %d > %d (si_TBS_r13 %d)\n", bcch_sdu_length, (int) (si_TBS_r13 >> 3), - (int) schedulingInfoList_BR_r13-> - list.array[i]->si_TBS_r13); + (int) schedulingInfoList_BR_r13->list.array[i]->si_TBS_r13); // allocate all 6 PRBs in narrowband for SIB1_BR // check that SIB1 didn't take this narrowband - if (vrb_map[first_rb] > 0) - continue; + if (vrb_map[first_rb] > 0) continue; - first_rb = - narrowband_to_first_rb(cc, - si_Narrowband_r13 - 1); + first_rb = narrowband_to_first_rb(cc,si_Narrowband_r13 - 1); vrb_map[first_rb] = 1; vrb_map[first_rb + 1] = 1; vrb_map[first_rb + 2] = 1; @@ -465,89 +423,54 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, - dl_config_pdu = - &dl_req->dl_config_pdu_list[dl_req-> - number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = - NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + - sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = - si_TBS_r13 >> 3; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = - eNB->pdu_index[CC_id]; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = - 0xFFFF; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = si_TBS_r13 >> 3; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.resource_block_coding = - getRIV(N_RB_DL, first_rb, 6); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 6); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.redundancy_version = rvidx; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = rvidx; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.transport_block_to_codeword_swap_flag - = 0; - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.transmission_scheme = - (cc->p_eNB == 1) ? 0 : 1; - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.number_of_layers = 1; - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.number_of_subbands = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.transmission_mode = - (cc->p_eNB == 1) ? 1 : 2; - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.num_bf_prb_per_subband = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - num_bf_vector = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; // Rel10 fields (for PDSCH starting symbol) dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10. - pdsch_start = - cc[CC_id]. - sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; // Rel13 fields dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 1; // CEModeA UE dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 1; // SI-BR - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel13.initial_transmission_sf_io = - absSF - sf_mod_period; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = absSF - sf_mod_period; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; dl_req->number_pdu++; dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; // Program TX Request - TX_req = - &eNB->TX_req[CC_id]. - tx_request_body.tx_pdu_list[eNB->TX_req[CC_id]. - tx_request_body.number_of_pdus]; + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; TX_req->pdu_length = bcch_sdu_length; TX_req->pdu_index = eNB->pdu_index[CC_id]++; TX_req->num_segments = 1; - TX_req->segments[0].segment_length = - bcch_sdu_length; - TX_req->segments[0].segment_data = - cc->BCCH_BR_pdu[i + 1].payload; - eNB->TX_req[CC_id].tx_request_body. - number_of_pdus++; + TX_req->segments[0].segment_length = bcch_sdu_length; + TX_req->segments[0].segment_data = cc->BCCH_BR_pdu[i + 1].payload; + eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; eNB->TX_req[CC_id].sfn_sf = sfn_sf; eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; @@ -620,19 +543,16 @@ schedule_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) module_idP, frameP, CC_id, mib_sdu_length, (int) cc->mib->message.schedulingInfoSIB1_BR_r13); - dl_config_pdu = - &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = - NFAPI_DL_CONFIG_BCH_PDU_TYPE, dl_config_pdu->pdu_size = + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_BCH_PDU_TYPE, dl_config_pdu->pdu_size = 2 + sizeof(nfapi_dl_config_bch_pdu); - dl_config_pdu->bch_pdu.bch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG; - dl_config_pdu->bch_pdu.bch_pdu_rel8.length = mib_sdu_length; - dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index = - eNB->pdu_index[CC_id]; + dl_config_pdu->bch_pdu.bch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG; + dl_config_pdu->bch_pdu.bch_pdu_rel8.length = mib_sdu_length; + dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; dl_config_pdu->bch_pdu.bch_pdu_rel8.transmission_power = 6000; - dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; dl_req->number_pdu++; dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST; @@ -641,9 +561,7 @@ schedule_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) LOG_D(MAC, "eNB->DL_req[0].number_pdu %d (%p)\n", dl_req->number_pdu, &dl_req->number_pdu); // DL request - TX_req = - &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req - [CC_id].tx_request_body.number_of_pdus]; + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; TX_req->pdu_length = 3; TX_req->pdu_index = eNB->pdu_index[CC_id]++; TX_req->num_segments = 1; @@ -753,114 +671,81 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) } - dl_config_pdu = - &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = - NFAPI_DL_DCI_FORMAT_1A; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level = 4; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFF; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // S-RNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFF; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // S-RNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - new_data_indicator_1 = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - redundancy_version_1 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.resource_block_coding = - getRIV(N_RB_DL, first_rb, 4); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); dl_config_request->sfn_sf = sfn_sf; - if (!CCE_allocation_infeasible - (module_idP, CC_id, 0, subframeP, - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level, SI_RNTI)) { + if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, SI_RNTI)) { LOG_D(MAC, "Frame %d: Subframe %d : Adding common DCI for S_RNTI\n", frameP, subframeP); dl_req->number_dci++; dl_req->number_pdu++; - dl_config_pdu = - &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = - NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = - eNB->pdu_index[CC_id]; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = bcch_sdu_length; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D + sizeof(nfapi_dl_config_request_p du_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = bcch_sdu_length; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.resource_block_coding = - getRIV(N_RB_DL, first_rb, 4); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - redundancy_version = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.transport_block_to_codeword_swap_flag - = 0; - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.transmission_scheme = - (cc->p_eNB == 1) ? 0 : 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - number_of_layers = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - number_of_subbands = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.ue_category_capacity = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.delta_power_offset_index = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - transmission_mode = (cc->p_eNB == 1) ? 1 : 2; - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.num_bf_prb_per_subband = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = - 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; dl_req->number_pdu++; // Rel10 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; // Rel13 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SF + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SF - dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST; - dl_config_request->sfn_sf = sfn_sf; + dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST; + dl_config_request->sfn_sf = sfn_sf; // Program TX Request - TX_req = - &eNB->TX_req[CC_id]. - tx_request_body.tx_pdu_list[eNB->TX_req[CC_id]. - tx_request_body.number_of_pdus]; + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; TX_req->pdu_length = bcch_sdu_length; TX_req->pdu_index = eNB->pdu_index[CC_id]++; TX_req->num_segments = 1; TX_req->segments[0].segment_length = bcch_sdu_length; - TX_req->segments[0].segment_data = - cc->BCCH_pdu.payload; + TX_req->segments[0].segment_data = cc->BCCH_pdu.payload; eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; eNB->TX_req[CC_id].sfn_sf = sfn_sf; eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 9f2ab1cba8..4d298f69f5 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -74,13 +74,13 @@ add_ue_dlsch_info(module_id_t module_idP, { //LOG_D(MAC, "%s(module_idP:%d, CC_id:%d, UE_id:%d, subframeP:%d, status:%d) serving_num:%d rnti:%x\n", __FUNCTION__, module_idP, CC_id, UE_id, subframeP, status, eNB_dlsch_info[module_idP][CC_id][UE_id].serving_num, UE_RNTI(module_idP,UE_id)); - eNB_dlsch_info[module_idP][CC_id][UE_id].rnti = - UE_RNTI(module_idP, UE_id); - // eNB_dlsch_info[module_idP][CC_id][ue_mod_idP].weight = weight; - eNB_dlsch_info[module_idP][CC_id][UE_id].subframe = subframeP; - eNB_dlsch_info[module_idP][CC_id][UE_id].status = status; + eNB_dlsch_info[module_idP][CC_id][UE_id].rnti = + UE_RNTI(module_idP, UE_id); + // eNB_dlsch_info[module_idP][CC_id][ue_mod_idP].weight = weight; + eNB_dlsch_info[module_idP][CC_id][UE_id].subframe = subframeP; + eNB_dlsch_info[module_idP][CC_id][UE_id].status = status; - eNB_dlsch_info[module_idP][CC_id][UE_id].serving_num++; + eNB_dlsch_info[module_idP][CC_id][UE_id].serving_num++; } @@ -91,27 +91,25 @@ schedule_next_dlue(module_id_t module_idP, int CC_id, //------------------------------------------------------------------------------ { - int next_ue; - UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; + int next_ue; + UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; - for (next_ue = UE_list->head; next_ue >= 0; - next_ue = UE_list->next[next_ue]) { - if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == - S_DL_WAITING) { - return next_ue; - } + for (next_ue = UE_list->head; next_ue >= 0; + next_ue = UE_list->next[next_ue]) { + if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == + S_DL_WAITING) { + return next_ue; } + } - for (next_ue = UE_list->head; next_ue >= 0; - next_ue = UE_list->next[next_ue]) { - if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == - S_DL_BUFFERED) { - eNB_dlsch_info[module_idP][CC_id][next_ue].status = - S_DL_WAITING; - } + for (next_ue = UE_list->head; next_ue >= 0; + next_ue = UE_list->next[next_ue]) { + if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == S_DL_BUFFERED) { + eNB_dlsch_info[module_idP][CC_id][next_ue].status = S_DL_WAITING; } + } - return (-1); //next_ue; + return (-1); //next_ue; } @@ -129,187 +127,183 @@ generate_dlsch_header(unsigned char *mac_header, //------------------------------------------------------------------------------ { - SCH_SUBHEADER_FIXED *mac_header_ptr = - (SCH_SUBHEADER_FIXED *) mac_header; - uint8_t first_element = 0, last_size = 0, i; - uint8_t mac_header_control_elements[16], *ce_ptr; + SCH_SUBHEADER_FIXED *mac_header_ptr = (SCH_SUBHEADER_FIXED *) mac_header; + uint8_t first_element = 0, last_size = 0, i; + uint8_t mac_header_control_elements[16], *ce_ptr; - ce_ptr = &mac_header_control_elements[0]; + ce_ptr = &mac_header_control_elements[0]; - // compute header components + // compute header components - if ((short_padding == 1) || (short_padding == 2)) { - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_PADDING; - first_element = 1; - last_size = 1; + if ((short_padding == 1) || (short_padding == 2)) { + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = SHORT_PADDING; + first_element = 1; + last_size = 1; + } + + if (short_padding == 2) { + mac_header_ptr->E = 1; + mac_header_ptr++; + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = SHORT_PADDING; + last_size = 1; + } + + if (drx_cmd != 255) { + if (first_element > 0) { + mac_header_ptr->E = 1; + mac_header_ptr++; + } else { + first_element = 1; } - if (short_padding == 2) { - mac_header_ptr->E = 1; - mac_header_ptr++; - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_PADDING; - last_size = 1; + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = DRX_CMD; + last_size = 1; + } + + if (timing_advance_cmd != 31) { + if (first_element > 0) { + mac_header_ptr->E = 1; + mac_header_ptr++; + } else { + first_element = 1; } - if (drx_cmd != 255) { - if (first_element > 0) { - mac_header_ptr->E = 1; - mac_header_ptr++; - } else { - first_element = 1; - } + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = TIMING_ADV_CMD; + last_size = 1; + // msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); + ((TIMING_ADVANCE_CMD *) ce_ptr)->R = 0; + AssertFatal(timing_advance_cmd < 64, + "timing_advance_cmd %d > 63\n", timing_advance_cmd); + ((TIMING_ADVANCE_CMD *) ce_ptr)->TA = timing_advance_cmd; //(timing_advance_cmd+31)&0x3f; + LOG_D(MAC, "timing advance =%d (%d)\n", timing_advance_cmd, + ((TIMING_ADVANCE_CMD *) ce_ptr)->TA); + ce_ptr += sizeof(TIMING_ADVANCE_CMD); + //msg("offset %d\n",ce_ptr-mac_header_control_elements); + } - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = DRX_CMD; - last_size = 1; + if (ue_cont_res_id) { + if (first_element > 0) { + mac_header_ptr->E = 1; + /* + printf("[eNB][MAC] last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); + */ + mac_header_ptr++; + } else { + first_element = 1; } - if (timing_advance_cmd != 31) { - if (first_element > 0) { - mac_header_ptr->E = 1; - mac_header_ptr++; - } else { - first_element = 1; - } + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = UE_CONT_RES; + last_size = 1; - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = TIMING_ADV_CMD; - last_size = 1; - // msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); - ((TIMING_ADVANCE_CMD *) ce_ptr)->R = 0; - AssertFatal(timing_advance_cmd < 64, - "timing_advance_cmd %d > 63\n", timing_advance_cmd); - ((TIMING_ADVANCE_CMD *) ce_ptr)->TA = timing_advance_cmd; //(timing_advance_cmd+31)&0x3f; - LOG_D(MAC, "timing advance =%d (%d)\n", timing_advance_cmd, - ((TIMING_ADVANCE_CMD *) ce_ptr)->TA); - ce_ptr += sizeof(TIMING_ADVANCE_CMD); - //msg("offset %d\n",ce_ptr-mac_header_control_elements); + LOG_T(MAC, + "[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n", + ue_cont_res_id[0], ue_cont_res_id[1], ue_cont_res_id[2], + ue_cont_res_id[3], ue_cont_res_id[4], ue_cont_res_id[5]); + + memcpy(ce_ptr, ue_cont_res_id, 6); + ce_ptr += 6; + // msg("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements); + } + //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); + + for (i = 0; i < num_sdus; i++) { + LOG_T(MAC, "[eNB] Generate DLSCH header num sdu %d len sdu %d\n", + num_sdus, sdu_lengths[i]); + + if (first_element > 0) { + mac_header_ptr->E = 1; + /*msg("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); + */ + mac_header_ptr += last_size; + //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); + } else { + first_element = 1; } - if (ue_cont_res_id) { - if (first_element > 0) { - mac_header_ptr->E = 1; - /* - printf("[eNB][MAC] last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); - */ - mac_header_ptr++; - } else { - first_element = 1; - } - - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = UE_CONT_RES; - last_size = 1; - - LOG_T(MAC, - "[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n", - ue_cont_res_id[0], ue_cont_res_id[1], ue_cont_res_id[2], - ue_cont_res_id[3], ue_cont_res_id[4], ue_cont_res_id[5]); - - memcpy(ce_ptr, ue_cont_res_id, 6); - ce_ptr += 6; - // msg("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements); - } - //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); - - for (i = 0; i < num_sdus; i++) { - LOG_T(MAC, "[eNB] Generate DLSCH header num sdu %d len sdu %d\n", - num_sdus, sdu_lengths[i]); - - if (first_element > 0) { - mac_header_ptr->E = 1; - /*msg("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); - */ - mac_header_ptr += last_size; - //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); - } else { - first_element = 1; - } - - if (sdu_lengths[i] < 128) { - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->R = 0; - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->E = 0; - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F = 0; - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->LCID = sdu_lcids[i]; - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L = - (unsigned char) sdu_lengths[i]; - last_size = 2; - } else { - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->R = 0; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->E = 0; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->F = 1; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->LCID = sdu_lcids[i]; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB = - ((unsigned short) sdu_lengths[i] >> 8) & 0x7f; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB = - (unsigned short) sdu_lengths[i] & 0xff; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->padding = 0x00; - last_size = 3; + if (sdu_lengths[i] < 128) { + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->R = 0; + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->E = 0; + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F = 0; + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->LCID = sdu_lcids[i]; + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L = (unsigned char) sdu_lengths[i]; + last_size = 2; + } else { + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->R = 0; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->E = 0; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->F = 1; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->LCID = sdu_lcids[i]; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB = ((unsigned short) sdu_lengths[i] >> 8) & 0x7f; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB = (unsigned short) sdu_lengths[i] & 0xff; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->padding = 0x00; + last_size = 3; #ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, - "[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n", - sdu_lengths[i], - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB, - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB); + LOG_D(MAC, + "[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n", + sdu_lengths[i], + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB, + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB); #endif - } } + } - /* + /* - printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); + printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); - printf("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); + printf("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); - if (((SCH_SUBHEADER_FIXED*)mac_header_ptr)->LCID < UE_CONT_RES) { - if (((SCH_SUBHEADER_SHORT*)mac_header_ptr)->F == 0) - printf("F = 0, sdu len (L field) %d\n",(((SCH_SUBHEADER_SHORT*)mac_header_ptr)->L)); - else - printf("F = 1, sdu len (L field) %d\n",(((SCH_SUBHEADER_LONG*)mac_header_ptr)->L)); - } - */ - if (post_padding > 0) { // we have lots of padding at the end of the packet - mac_header_ptr->E = 1; - mac_header_ptr += last_size; - // add a padding element - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_PADDING; - mac_header_ptr++; - } else { // no end of packet padding - // last SDU subhead is of fixed type (sdu length implicitly to be computed at UE) - mac_header_ptr++; + if (((SCH_SUBHEADER_FIXED*)mac_header_ptr)->LCID < UE_CONT_RES) { + if (((SCH_SUBHEADER_SHORT*)mac_header_ptr)->F == 0) + printf("F = 0, sdu len (L field) %d\n",(((SCH_SUBHEADER_SHORT*)mac_header_ptr)->L)); + else + printf("F = 1, sdu len (L field) %d\n",(((SCH_SUBHEADER_LONG*)mac_header_ptr)->L)); } + */ + if (post_padding > 0) { // we have lots of padding at the end of the packet + mac_header_ptr->E = 1; + mac_header_ptr += last_size; + // add a padding element + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = SHORT_PADDING; + mac_header_ptr++; + } else { // no end of packet padding + // last SDU subhead is of fixed type (sdu length implicitly to be computed at UE) + mac_header_ptr++; + } - //msg("After subheaders %d\n",(uint8_t*)mac_header_ptr - mac_header); + //msg("After subheaders %d\n",(uint8_t*)mac_header_ptr - mac_header); - if ((ce_ptr - mac_header_control_elements) > 0) { - // printf("Copying %d bytes for control elements\n",ce_ptr-mac_header_control_elements); - memcpy((void *) mac_header_ptr, mac_header_control_elements, - ce_ptr - mac_header_control_elements); - mac_header_ptr += - (unsigned char) (ce_ptr - mac_header_control_elements); - } - //msg("After CEs %d\n",(uint8_t*)mac_header_ptr - mac_header); + if ((ce_ptr - mac_header_control_elements) > 0) { + // printf("Copying %d bytes for control elements\n",ce_ptr-mac_header_control_elements); + memcpy((void *) mac_header_ptr, mac_header_control_elements, + ce_ptr - mac_header_control_elements); + mac_header_ptr += + (unsigned char) (ce_ptr - mac_header_control_elements); + } + //msg("After CEs %d\n",(uint8_t*)mac_header_ptr - mac_header); - return ((unsigned char *) mac_header_ptr - mac_header); + return ((unsigned char *) mac_header_ptr - mac_header); } @@ -320,94 +314,94 @@ set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP, //------------------------------------------------------------------------------ { - eNB_MAC_INST *eNB = RC.mac[module_idP]; - UE_list_t *UE_list = &eNB->UE_list; - unsigned char DAI; - COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; - if (cc->tdd_Config != NULL) { //TDD - DAI = (UE_list->UE_template[CC_idP][UE_idP].DAI - 1) & 3; - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d, subframe %d: DAI %d for UE %d\n", - module_idP, CC_idP, frameP, subframeP, DAI, UE_idP); - // Save DAI for Format 0 DCI + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &eNB->UE_list; + unsigned char DAI; + COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; + if (cc->tdd_Config != NULL) { //TDD + DAI = (UE_list->UE_template[CC_idP][UE_idP].DAI - 1) & 3; + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d, subframe %d: DAI %d for UE %d\n", + module_idP, CC_idP, frameP, subframeP, DAI, UE_idP); + // Save DAI for Format 0 DCI - switch (cc->tdd_Config->subframeAssignment) { - case 0: - // if ((subframeP==0)||(subframeP==1)||(subframeP==5)||(subframeP==6)) - break; + switch (cc->tdd_Config->subframeAssignment) { + case 0: + // if ((subframeP==0)||(subframeP==1)||(subframeP==5)||(subframeP==6)) + break; - case 1: - switch (subframeP) { - case 1: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[7] = DAI; - break; + case 1: + switch (subframeP) { + case 1: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[7] = DAI; + break; - case 4: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[8] = DAI; - break; + case 4: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[8] = DAI; + break; - case 6: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; - break; + case 6: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; + break; - case 9: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; - break; - } + case 9: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; + break; + } - case 2: - // if ((subframeP==3)||(subframeP==8)) - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; - break; + case 2: + // if ((subframeP==3)||(subframeP==8)) + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; + break; - case 3: + case 3: - //if ((subframeP==6)||(subframeP==8)||(subframeP==0)) { - // LOG_D(MAC,"schedule_ue_spec: setting UL DAI to %d for subframeP %d => %d\n",DAI,subframeP, ((subframeP+8)%10)>>1); - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul[((subframeP+8)%10)>>1] = DAI; - //} - switch (subframeP) { - case 5: - case 6: - case 1: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; - break; + //if ((subframeP==6)||(subframeP==8)||(subframeP==0)) { + // LOG_D(MAC,"schedule_ue_spec: setting UL DAI to %d for subframeP %d => %d\n",DAI,subframeP, ((subframeP+8)%10)>>1); + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul[((subframeP+8)%10)>>1] = DAI; + //} + switch (subframeP) { + case 5: + case 6: + case 1: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; + break; - case 7: - case 8: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; - break; + case 7: + case 8: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; + break; - case 9: - case 0: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[4] = DAI; - break; + case 9: + case 0: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[4] = DAI; + break; - default: - break; - } + default: + break; + } - break; + break; - case 4: - // if ((subframeP==8)||(subframeP==9)) - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; - break; + case 4: + // if ((subframeP==8)||(subframeP==9)) + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; + break; - case 5: - // if (subframeP==8) - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; - break; + case 5: + // if (subframeP==8) + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; + break; - case 6: - // if ((subframeP==1)||(subframeP==4)||(subframeP==6)||(subframeP==9)) - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; - break; + case 6: + // if ((subframeP==1)||(subframeP==4)||(subframeP==6)||(subframeP==9)) + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; + break; - default: - break; - } + default: + break; } + } } @@ -421,1106 +415,977 @@ schedule_ue_spec(module_id_t module_idP, { - uint8_t CC_id; - int UE_id; - unsigned char aggregation; - mac_rlc_status_resp_t rlc_status; - unsigned char header_len_dcch = 0, header_len_dcch_tmp = 0; - unsigned char header_len_dtch = 0, header_len_dtch_tmp = - 0, header_len_dtch_last = 0; - unsigned char ta_len = 0; - unsigned char sdu_lcids[NB_RB_MAX], lcid, offset, num_sdus = 0; - uint16_t nb_rb, nb_rb_temp, nb_available_rb; - uint16_t TBS, j, sdu_lengths[NB_RB_MAX], rnti, padding = - 0, post_padding = 0; - unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; - unsigned char round = 0; - unsigned char harq_pid = 0; - eNB_UE_STATS *eNB_UE_stats = NULL; - uint16_t sdu_length_total = 0; + uint8_t CC_id; + int UE_id; + unsigned char aggregation; + mac_rlc_status_resp_t rlc_status; + unsigned char header_len_dcch = 0, header_len_dcch_tmp = 0; + unsigned char header_len_dtch = 0, header_len_dtch_tmp = + 0, header_len_dtch_last = 0; + unsigned char ta_len = 0; + unsigned char sdu_lcids[NB_RB_MAX], lcid, offset, num_sdus = 0; + uint16_t nb_rb, nb_rb_temp, nb_available_rb; + uint16_t TBS, j, sdu_lengths[NB_RB_MAX], rnti, padding = + 0, post_padding = 0; + unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; + unsigned char round = 0; + unsigned char harq_pid = 0; + eNB_UE_STATS *eNB_UE_stats = NULL; + uint16_t sdu_length_total = 0; - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc = eNB->common_channels; - UE_list_t *UE_list = &eNB->UE_list; - int continue_flag = 0; - int32_t normalized_rx_power, target_rx_power; - int32_t tpc = 1; - static int32_t tpc_accumulated = 0; - UE_sched_ctrl *ue_sched_ctl; - int mcs; - int i; - int min_rb_unit[MAX_NUM_CCs]; - int N_RB_DL[MAX_NUM_CCs]; - int total_nb_available_rb[MAX_NUM_CCs]; - int N_RBG[MAX_NUM_CCs]; - nfapi_dl_config_request_body_t *dl_req; - nfapi_dl_config_request_pdu_t *dl_config_pdu; - int tdd_sfa; - int ta_update; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = eNB->common_channels; + UE_list_t *UE_list = &eNB->UE_list; + int continue_flag = 0; + int32_t normalized_rx_power, target_rx_power; + int32_t tpc = 1; + static int32_t tpc_accumulated = 0; + UE_sched_ctrl *ue_sched_ctl; + int mcs; + int i; + int min_rb_unit[MAX_NUM_CCs]; + int N_RB_DL[MAX_NUM_CCs]; + int total_nb_available_rb[MAX_NUM_CCs]; + int N_RBG[MAX_NUM_CCs]; + nfapi_dl_config_request_body_t *dl_req; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + int tdd_sfa; + int ta_update; #if 0 - if (UE_list->head == -1) { - return; - } + if (UE_list->head == -1) { + return; + } #endif - start_meas(&eNB->schedule_dlsch); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN); + start_meas(&eNB->schedule_dlsch); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN); - // for TDD: check that we have to act here, otherwise return - if (cc[0].tdd_Config) { - tdd_sfa = cc[0].tdd_Config->subframeAssignment; - switch (subframeP) { - case 0: - // always continue - break; + // for TDD: check that we have to act here, otherwise return + if (cc[0].tdd_Config) { + tdd_sfa = cc[0].tdd_Config->subframeAssignment; + switch (subframeP) { + case 0: + // always continue + break; + case 1: + return; + break; + case 2: + return; + break; + case 3: + if ((tdd_sfa != 2) && (tdd_sfa != 5)) + return; + break; + case 4: + if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4) + && (tdd_sfa != 5)) + return; + break; + case 5: + break; + case 6: + case 7: + if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4) + && (tdd_sfa != 5)) + return; + break; + case 8: + if ((tdd_sfa != 2) && (tdd_sfa != 3) && (tdd_sfa != 4) + && (tdd_sfa != 5)) + return; + break; + case 9: + if ((tdd_sfa != 1) && (tdd_sfa != 3) && (tdd_sfa != 4) + && (tdd_sfa != 6)) + return; + break; + + } + } + //weight = get_ue_weight(module_idP,UE_id); + aggregation = 2; + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + N_RB_DL[CC_id] = to_prb(cc[CC_id].mib->message.dl_Bandwidth); + min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id); + // get number of PRBs less those used by common channels + total_nb_available_rb[CC_id] = N_RB_DL[CC_id]; + for (i = 0; i < N_RB_DL[CC_id]; i++) + if (cc[CC_id].vrb_map[i] != 0) + total_nb_available_rb[CC_id]--; + + N_RBG[CC_id] = to_rbg(cc[CC_id].mib->message.dl_Bandwidth); + + // store the global enb stats: + eNB->eNB_stats[CC_id].num_dlactive_UEs = UE_list->num_UEs; + eNB->eNB_stats[CC_id].available_prbs = total_nb_available_rb[CC_id]; + eNB->eNB_stats[CC_id].total_available_prbs += total_nb_available_rb[CC_id]; + eNB->eNB_stats[CC_id].dlsch_bytes_tx = 0; + eNB->eNB_stats[CC_id].dlsch_pdus_tx = 0; + } + + /// CALLING Pre_Processor for downlink scheduling (Returns estimation of RBs required by each UE and the allocation on sub-band) + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_IN); + start_meas(&eNB->schedule_dlsch_preprocessor); + dlsch_scheduler_pre_processor(module_idP, + frameP, subframeP, N_RBG, mbsfn_flag); + stop_meas(&eNB->schedule_dlsch_preprocessor); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT); + + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n", CC_id); + + dl_req = &eNB->DL_req[CC_id].dl_config_request_body; + + if (mbsfn_flag[CC_id] > 0) + continue; + + for (UE_id = UE_list->head; UE_id >= 0; + UE_id = UE_list->next[UE_id]) { + continue_flag = 0; // reset the flag to allow allocation for the remaining UEs + rnti = UE_RNTI(module_idP, UE_id); + eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + + + if (rnti == NOT_A_RNTI) { + LOG_D(MAC, "Cannot find rnti for UE_id %d (num_UEs %d)\n", + UE_id, UE_list->num_UEs); + continue_flag = 1; + } + + if (eNB_UE_stats == NULL) { + LOG_D(MAC, "[eNB] Cannot find eNB_UE_stats\n"); + continue_flag = 1; + } + + if (continue_flag != 1) { + switch (get_tmode(module_idP, CC_id, UE_id)) { case 1: - return; - break; case 2: - return; - break; - case 3: - if ((tdd_sfa != 2) && (tdd_sfa != 5)) - return; - break; - case 4: - if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4) - && (tdd_sfa != 5)) - return; - break; - case 5: - break; - case 6: case 7: - if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4) - && (tdd_sfa != 5)) - return; - break; - case 8: - if ((tdd_sfa != 2) && (tdd_sfa != 3) && (tdd_sfa != 4) - && (tdd_sfa != 5)) - return; - break; - case 9: - if ((tdd_sfa != 1) && (tdd_sfa != 3) && (tdd_sfa != 4) - && (tdd_sfa != 6)) - return; - break; - + aggregation = + get_aggregation(get_bw_index(module_idP, CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format1); + break; + case 3: + aggregation = + get_aggregation(get_bw_index(module_idP, CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format2A); + break; + default: + LOG_W(MAC, "Unsupported transmission mode %d\n", + get_tmode(module_idP, CC_id, UE_id)); + aggregation = 2; } - } - //weight = get_ue_weight(module_idP,UE_id); - aggregation = 2; - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - N_RB_DL[CC_id] = to_prb(cc[CC_id].mib->message.dl_Bandwidth); - min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id); - // get number of PRBs less those used by common channels - total_nb_available_rb[CC_id] = N_RB_DL[CC_id]; - for (i = 0; i < N_RB_DL[CC_id]; i++) - if (cc[CC_id].vrb_map[i] != 0) - total_nb_available_rb[CC_id]--; + } + /* if (continue_flag != 1 */ + if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated + CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, + aggregation, rnti)) { + LOG_D(MAC, + "[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n", + module_idP, frameP, UE_id, CC_id); + continue_flag = 1; //to next user (there might be rbs availiable for other UEs in TM5 + } - N_RBG[CC_id] = to_rbg(cc[CC_id].mib->message.dl_Bandwidth); + if (cc[CC_id].tdd_Config != NULL) { //TDD + set_ue_dai(subframeP, + UE_id, + CC_id, + cc[CC_id].tdd_Config->subframeAssignment, + UE_list); + // update UL DAI after DLSCH scheduling + set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); + } - // store the global enb stats: - eNB->eNB_stats[CC_id].num_dlactive_UEs = UE_list->num_UEs; - eNB->eNB_stats[CC_id].available_prbs = - total_nb_available_rb[CC_id]; - eNB->eNB_stats[CC_id].total_available_prbs += - total_nb_available_rb[CC_id]; - eNB->eNB_stats[CC_id].dlsch_bytes_tx = 0; - eNB->eNB_stats[CC_id].dlsch_pdus_tx = 0; - } - - /// CALLING Pre_Processor for downlink scheduling (Returns estimation of RBs required by each UE and the allocation on sub-band) - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_IN); - start_meas(&eNB->schedule_dlsch_preprocessor); - dlsch_scheduler_pre_processor(module_idP, - frameP, subframeP, N_RBG, mbsfn_flag); - stop_meas(&eNB->schedule_dlsch_preprocessor); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT); - - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n", CC_id); - - dl_req = &eNB->DL_req[CC_id].dl_config_request_body; - - if (mbsfn_flag[CC_id] > 0) - continue; - - for (UE_id = UE_list->head; UE_id >= 0; - UE_id = UE_list->next[UE_id]) { - continue_flag = 0; // reset the flag to allow allocation for the remaining UEs - rnti = UE_RNTI(module_idP, UE_id); - eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - - - if (rnti == NOT_A_RNTI) { - LOG_D(MAC, "Cannot find rnti for UE_id %d (num_UEs %d)\n", - UE_id, UE_list->num_UEs); - continue_flag = 1; - } - - if (eNB_UE_stats == NULL) { - LOG_D(MAC, "[eNB] Cannot find eNB_UE_stats\n"); - continue_flag = 1; - } - - if (continue_flag != 1) { - switch (get_tmode(module_idP, CC_id, UE_id)) { - case 1: - case 2: - case 7: - aggregation = - get_aggregation(get_bw_index(module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format1); - break; - case 3: - aggregation = - get_aggregation(get_bw_index(module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format2A); - break; - default: - LOG_W(MAC, "Unsupported transmission mode %d\n", - get_tmode(module_idP, CC_id, UE_id)); - aggregation = 2; - } - } - /* if (continue_flag != 1 */ - if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated - CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, - aggregation, rnti)) { - LOG_D(MAC, - "[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n", - module_idP, frameP, UE_id, CC_id); - continue_flag = 1; //to next user (there might be rbs availiable for other UEs in TM5 - } - - if (cc[CC_id].tdd_Config != NULL) { //TDD - set_ue_dai(subframeP, - UE_id, - CC_id, - cc[CC_id].tdd_Config->subframeAssignment, - UE_list); - // update UL DAI after DLSCH scheduling - set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); - } - - if (continue_flag == 1) { - add_ue_dlsch_info(module_idP, - CC_id, UE_id, subframeP, S_DL_NONE); - continue; - } + if (continue_flag == 1) { + add_ue_dlsch_info(module_idP, + CC_id, UE_id, subframeP, S_DL_NONE); + continue; + } #warning RK->CR This old API call has to be revisited for FAPI, or logic must be changed #if 0 - /* add "fake" DCI to have CCE_allocation_infeasible work properly for next allocations */ - /* if we don't add it, next allocations may succeed but overall allocations may fail */ - /* will be removed at the end of this function */ - add_ue_spec_dci(&eNB->common_channels[CC_id].DCI_pdu, &(char[]) { - 0}, rnti, 1, aggregation, 1, format1, 0); + /* add "fake" DCI to have CCE_allocation_infeasible work properly for next allocations */ + /* if we don't add it, next allocations may succeed but overall allocations may fail */ + /* will be removed at the end of this function */ + add_ue_spec_dci(&eNB->common_channels[CC_id].DCI_pdu, &(char[]) { + 0}, rnti, 1, aggregation, 1, format1, 0); #endif - nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id]; + nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id]; - if (cc->tdd_Config) - harq_pid = ((frameP * 10) + subframeP) % 10; - else - harq_pid = ((frameP * 10) + subframeP) & 7; + if (cc->tdd_Config) harq_pid = ((frameP * 10) + subframeP) % 10; + else harq_pid = ((frameP * 10) + subframeP) & 7; - round = ue_sched_ctl->round[CC_id][harq_pid]; + round = ue_sched_ctl->round[CC_id][harq_pid]; - UE_list->eNB_UE_stats[CC_id][UE_id].crnti = rnti; - UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status = - mac_eNB_get_rrc_status(module_idP, rnti); - UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; - UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round; + UE_list->eNB_UE_stats[CC_id][UE_id].crnti = rnti; + UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status = mac_eNB_get_rrc_status(module_idP, rnti); + UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; + UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round; - if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < - RRC_CONNECTED) - continue; + if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < RRC_CONNECTED) continue; - sdu_length_total = 0; - num_sdus = 0; + sdu_length_total = 0; + num_sdus = 0; - /* - DevCheck(((eNB_UE_stats->dl_cqi < MIN_CQI_VALUE) || (eNB_UE_stats->dl_cqi > MAX_CQI_VALUE)), - eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE); - */ - if (nfapi_mode) { - eNB_UE_stats->dlsch_mcs1 = 10;//cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; - } - else { - eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; - } - eNB_UE_stats->dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; //cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); + /* + DevCheck(((eNB_UE_stats->dl_cqi < MIN_CQI_VALUE) || (eNB_UE_stats->dl_cqi > MAX_CQI_VALUE)), + eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE); + */ + if (nfapi_mode) { + eNB_UE_stats->dlsch_mcs1 = 10;//cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; + } + else { + eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; + } + eNB_UE_stats->dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; //cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); - // store stats - //UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->dl_cqi; + // store stats + //UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->dl_cqi; - // initializing the rb allocation indicator for each UE - for (j = 0; j < N_RBG[CC_id]; j++) { - UE_list-> - UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] - = 0; - } + // initializing the rb allocation indicator for each UE + for (j = 0; j < N_RBG[CC_id]; j++) { + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = 0; + } + LOG_D(MAC, + "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n", + module_idP, frameP, UE_id, CC_id, rnti, harq_pid, round, + nb_available_rb, ue_sched_ctl->dl_cqi[CC_id], + eNB_UE_stats->dlsch_mcs1, + UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status); + + + + /* process retransmission */ + + if (round != 8) { + + // get freq_allocation + nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + TBS = get_TBS_DL(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid], + nb_rb); + + if (nb_rb <= nb_available_rb) { + if (cc[CC_id].tdd_Config != NULL) { + UE_list->UE_template[CC_id][UE_id].DAI++; + update_ul_dci(module_idP, CC_id, rnti, + UE_list->UE_template[CC_id][UE_id]. + DAI); LOG_D(MAC, - "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n", - module_idP, frameP, UE_id, CC_id, rnti, harq_pid, round, - nb_available_rb, ue_sched_ctl->dl_cqi[CC_id], - eNB_UE_stats->dlsch_mcs1, - UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status); + "DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n", + CC_id, subframeP, UE_id, + UE_list->UE_template[CC_id][UE_id].DAI); + } + if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { + for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + } + } else { + nb_rb_temp = nb_rb; + j = 0; + while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { + if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { + if (UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]) + printf("WARN: rballoc_subband not free for retrans?\n"); + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - /* process retransmission */ - - if (round != 8) { - - // get freq_allocation - nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - TBS = - get_TBS_DL(UE_list-> - UE_template[CC_id][UE_id].oldmcs1[harq_pid], - nb_rb); - - if (nb_rb <= nb_available_rb) { - if (cc[CC_id].tdd_Config != NULL) { - UE_list->UE_template[CC_id][UE_id].DAI++; - update_ul_dci(module_idP, CC_id, rnti, - UE_list->UE_template[CC_id][UE_id]. - DAI); - LOG_D(MAC, - "DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n", - CC_id, subframeP, UE_id, - UE_list->UE_template[CC_id][UE_id].DAI); - } - - if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { - for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band - UE_list->UE_template[CC_id][UE_id]. - rballoc_subband[harq_pid][j] = - ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - } - } else { - nb_rb_temp = nb_rb; - j = 0; - - while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { - if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == - 1) { - if (UE_list-> - UE_template[CC_id] - [UE_id].rballoc_subband[harq_pid][j]) - printf - ("WARN: rballoc_subband not free for retrans?\n"); - UE_list-> - UE_template[CC_id] - [UE_id].rballoc_subband[harq_pid][j] = - ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - - if ((j == N_RBG[CC_id] - 1) && - ((N_RB_DL[CC_id] == 25) || - (N_RB_DL[CC_id] == 50))) { - nb_rb_temp = - nb_rb_temp - min_rb_unit[CC_id] + - 1; - } else { - nb_rb_temp = - nb_rb_temp - min_rb_unit[CC_id]; - } - } - - j = j + 1; - } - } - - nb_available_rb -= nb_rb; - /* - eNB->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; - eNB->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; - - for(j=0; jmu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; - } - */ - - switch (get_tmode(module_idP, CC_id, UE_id)) { - case 1: - case 2: - case 7: - default: - LOG_D(MAC,"retransmission DL_REQ: rnti:%x\n",rnti); - - dl_config_pdu = - &dl_req->dl_config_pdu_list[dl_req-> - number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = - NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + - sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - dci_format = NFAPI_DL_DCI_FORMAT_1; - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level = - get_aggregation(get_bw_index - (module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format1); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = - rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - harq_process = harq_pid; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // dont adjust power when retransmitting - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.new_data_indicator_1 = - UE_list->UE_template[CC_id][UE_id]. - oldNDI[harq_pid]; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = - UE_list->UE_template[CC_id][UE_id]. - oldmcs1[harq_pid]; - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.redundancy_version_1 = - round & 3; - - if (cc[CC_id].tdd_Config != NULL) { //TDD - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.downlink_assignment_index = - (UE_list->UE_template[CC_id][UE_id].DAI - - 1) & 3; - LOG_D(MAC, - "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n", - module_idP, CC_id, harq_pid, round, - (UE_list->UE_template[CC_id][UE_id].DAI - - 1), - UE_list-> - UE_template[CC_id][UE_id].oldmcs1 - [harq_pid]); - } else { - LOG_D(MAC, - "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n", - module_idP, CC_id, harq_pid, round, - UE_list-> - UE_template[CC_id][UE_id].oldmcs1 - [harq_pid]); - - } - if (!CCE_allocation_infeasible - (module_idP, CC_id, 1, subframeP, - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level, rnti)) { - dl_req->number_dci++; - dl_req->number_pdu++; - dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - - eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; - eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; - - fill_nfapi_dlsch_config(eNB, dl_req, TBS, -1 - /* retransmission, no pdu_index */ - , rnti, 0, // type 0 allocation from 7.1.6 in 36.213 - 0, // virtual_resource_block_assignment_flag, unused here - 0, // resource_block_coding, to be filled in later - getQm(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]), round & 3, // redundancy version - 1, // transport blocks - 0, // transport block to codeword swap flag - cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme - 1, // number of layers - 1, // number of subbands - // uint8_t codebook_index, - 4, // UE category capacity - UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0, // delta_power_offset for TM5 - 0, // ngap - 0, // nprb - cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode - 0, //number of PRBs treated as one subband, not used here - 0 // number of beamforming vectors, not used here - ); - - LOG_D(MAC, - "Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n", - eNB->pdu_index[CC_id], round); - - program_dlsch_acknak(module_idP, CC_id, UE_id, - frameP, subframeP, - dl_config_pdu-> - dci_dl_pdu.dci_dl_pdu_rel8. - cce_idx); - // No TX request for retransmission (check if null request for FAPI) - } else { - LOG_W(MAC, - "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d\%x, infeasible CCE allocation\n", - frameP, subframeP, UE_id, rnti); - } - } - - - add_ue_dlsch_info(module_idP, - CC_id, UE_id, subframeP, - S_DL_SCHEDULED); - - //eNB_UE_stats->dlsch_trials[round]++; - UE_list->eNB_UE_stats[CC_id][UE_id]. - num_retransmission += 1; - UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx = - nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id]. - total_rbs_used_retx += nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = - eNB_UE_stats->dlsch_mcs1; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = - eNB_UE_stats->dlsch_mcs1; + if ((j == N_RBG[CC_id] - 1) && + ((N_RB_DL[CC_id] == 25) || + (N_RB_DL[CC_id] == 50))) { + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1; } else { - LOG_D(MAC, - "[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n", - module_idP, frameP, CC_id, UE_id); + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; } - } else { /* This is a potentially new SDU opportunity */ - - rlc_status.bytes_in_buffer = 0; - // Now check RLC information to compute number of required RBs - // get maximum TBS size for RLC request - TBS = - get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb); - // check first for RLC data on DCCH - // add the length for all the control elements (timing adv, drx, etc) : header + payload - - if (ue_sched_ctl->ta_timer == 0) { - ta_update = ue_sched_ctl->ta_update; - /* if we send TA then set timer to not send it for a while */ - if (ta_update != 31) - ue_sched_ctl->ta_timer = 20; - /* reset ta_update */ - ue_sched_ctl->ta_update = 31; - } else { - ta_update = 31; - } - - ta_len = (ta_update != 31) ? 2 : 0; - - header_len_dcch = 2; // 2 bytes DCCH SDU subheader - - if (TBS - ta_len - header_len_dcch > 0) { - rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, (TBS - ta_len - header_len_dcch)); // transport block set size - - sdu_lengths[0] = 0; - - if (rlc_status.bytes_in_buffer > 0) { // There is DCCH to transmit - LOG_D(MAC, - "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", - module_idP, frameP, subframeP, CC_id, - TBS - header_len_dcch); - sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, TBS, //not used - (char *) - &dlsch_buffer - [0]); - - T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), T_INT(DCCH), - T_INT(sdu_lengths[0])); - - LOG_D(MAC, - "[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n", - module_idP, CC_id, sdu_lengths[0]); - sdu_length_total = sdu_lengths[0]; - sdu_lcids[0] = DCCH; - UE_list->eNB_UE_stats[CC_id][UE_id]. - num_pdu_tx[DCCH] += 1; - UE_list-> - eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH] - += sdu_lengths[0]; - num_sdus = 1; -#ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, - "[eNB %d][DCCH] CC_id %d Got %d bytes :", - module_idP, CC_id, sdu_lengths[0]); - - for (j = 0; j < sdu_lengths[0]; j++) { - LOG_T(MAC, "%x ", dlsch_buffer[j]); - } - - LOG_T(MAC, "\n"); -#endif - } else { - header_len_dcch = 0; - sdu_length_total = 0; - } - } - // check for DCCH1 and update header information (assume 2 byte sub-header) - if (TBS - ta_len - header_len_dcch - sdu_length_total > 0) { - rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, (TBS - ta_len - header_len_dcch - sdu_length_total)); // transport block set size less allocations for timing advance and - // DCCH SDU - sdu_lengths[num_sdus] = 0; - - if (rlc_status.bytes_in_buffer > 0) { - LOG_D(MAC, - "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n", - module_idP, frameP, CC_id, - TBS - header_len_dcch - sdu_length_total); - sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, TBS, //not used - (char *) - &dlsch_buffer - [sdu_length_total]); - - T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), - T_INT(DCCH + 1), T_INT(sdu_lengths[num_sdus])); - - sdu_lcids[num_sdus] = DCCH1; - sdu_length_total += sdu_lengths[num_sdus]; - header_len_dcch += 2; - UE_list->eNB_UE_stats[CC_id][UE_id]. - num_pdu_tx[DCCH1] += 1; - UE_list-> - eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1] - += sdu_lengths[num_sdus]; - num_sdus++; -#ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, - "[eNB %d][DCCH1] CC_id %d Got %d bytes :", - module_idP, CC_id, sdu_lengths[num_sdus]); - - for (j = 0; j < sdu_lengths[num_sdus]; j++) { - LOG_T(MAC, "%x ", dlsch_buffer[j]); - } - - LOG_T(MAC, "\n"); -#endif - - } - } - // assume the max dtch header size, and adjust it later - header_len_dtch = 0; - header_len_dtch_last = 0; // the header length of the last mac sdu - // lcid has to be sorted before the actual allocation (similar struct as ue_list). - for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { - // TBD: check if the lcid is active - - header_len_dtch += 3; - header_len_dtch_last = 3; - LOG_D(MAC, - "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", - module_idP, frameP, lcid, TBS, - TBS - ta_len - header_len_dcch - - sdu_length_total - header_len_dtch); - - if (TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch > 0) { // NN: > 2 ? - rlc_status = mac_rlc_status_ind(module_idP, - rnti, - module_idP, - frameP, - subframeP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - lcid, - TBS - ta_len - - header_len_dcch - - sdu_length_total - - header_len_dtch); - - - if (rlc_status.bytes_in_buffer > 0) { - - LOG_D(MAC, - "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n", - module_idP, frameP, - TBS - header_len_dcch - - sdu_length_total - header_len_dtch, lcid, - header_len_dtch); - sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, TBS, //not used - (char - *) - &dlsch_buffer - [sdu_length_total]); - T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), - T_INT(lcid), T_INT(sdu_lengths[num_sdus])); - - LOG_D(MAC, - "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", - module_idP, sdu_lengths[num_sdus], lcid); - sdu_lcids[num_sdus] = lcid; - sdu_length_total += sdu_lengths[num_sdus]; - UE_list-> - eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid] - += 1; - UE_list-> - eNB_UE_stats[CC_id][UE_id].num_bytes_tx - [lcid] += sdu_lengths[num_sdus]; - if (sdu_lengths[num_sdus] < 128) { - header_len_dtch--; - header_len_dtch_last--; - } - num_sdus++; - UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; - } // no data for this LCID - else { - header_len_dtch -= 3; - } - } // no TBS left - else { - header_len_dtch -= 3; - break; - } - } - if (header_len_dtch == 0) - header_len_dtch_last = 0; - // there is at least one SDU - // if (num_sdus > 0 ){ - if ((sdu_length_total + header_len_dcch + - header_len_dtch) > 0) { - - // Now compute number of required RBs for total sdu length - // Assume RAH format 2 - // adjust header lengths - header_len_dcch_tmp = header_len_dcch; - header_len_dtch_tmp = header_len_dtch; - if (header_len_dtch == 0) { - header_len_dcch = (header_len_dcch > 0) ? 1 : 0; //header_len_dcch; // remove length field - } else { - header_len_dtch_last -= 1; // now use it to find how many bytes has to be removed for the last MAC SDU - header_len_dtch = (header_len_dtch > 0) ? header_len_dtch - header_len_dtch_last : header_len_dtch; // remove length field for the last SDU - } - - mcs = eNB_UE_stats->dlsch_mcs1; - - if (mcs == 0) { - nb_rb = 4; // don't let the TBS get too small - } else { - nb_rb = min_rb_unit[CC_id]; - } - - TBS = get_TBS_DL(mcs, nb_rb); - - while (TBS < - (sdu_length_total + header_len_dcch + - header_len_dtch + ta_len)) { - nb_rb += min_rb_unit[CC_id]; // - - if (nb_rb > nb_available_rb) { // if we've gone beyond the maximum number of RBs - // (can happen if N_RB_DL is odd) - TBS = - get_TBS_DL(eNB_UE_stats->dlsch_mcs1, - nb_available_rb); - nb_rb = nb_available_rb; - break; - } - - TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rb); - } - - if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { - for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band - UE_list->UE_template[CC_id][UE_id]. - rballoc_subband[harq_pid][j] = - ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - } - } else { - nb_rb_temp = nb_rb; - j = 0; - - while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { - if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == - 1) { - UE_list-> - UE_template[CC_id] - [UE_id].rballoc_subband[harq_pid][j] = - ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - - if ((j == N_RBG[CC_id] - 1) && - ((N_RB_DL[CC_id] == 25) || - (N_RB_DL[CC_id] == 50))) { - nb_rb_temp = - nb_rb_temp - min_rb_unit[CC_id] + - 1; - } else { - nb_rb_temp = - nb_rb_temp - min_rb_unit[CC_id]; - } - } - - j = j + 1; - } - } - - // decrease mcs until TBS falls below required length - while ((TBS > - (sdu_length_total + header_len_dcch + - header_len_dtch + ta_len)) && (mcs > 0)) { - mcs--; - TBS = get_TBS_DL(mcs, nb_rb); - } - - // if we have decreased too much or we don't have enough RBs, increase MCS - while ((TBS < - (sdu_length_total + header_len_dcch + - header_len_dtch + ta_len)) - && (((ue_sched_ctl->dl_pow_off[CC_id] > 0) - && (mcs < 28)) - || ((ue_sched_ctl->dl_pow_off[CC_id] == 0) - && (mcs <= 15)))) { - mcs++; - TBS = get_TBS_DL(mcs, nb_rb); - } - - LOG_D(MAC, - "dlsch_mcs before and after the rate matching = (%d, %d)\n", - eNB_UE_stats->dlsch_mcs1, mcs); - -#ifdef DEBUG_eNB_SCHEDULER - LOG_D(MAC, - "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", - module_idP, CC_id, mcs, TBS, nb_rb); - // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n", - // TBS, sdu_length_total, offset, TBS-sdu_length_total-offset); -#endif - - if ((TBS - header_len_dcch - header_len_dtch - - sdu_length_total - ta_len) <= 2) { - padding = - (TBS - header_len_dcch - header_len_dtch - - sdu_length_total - ta_len); - post_padding = 0; - } else { - padding = 0; - - // adjust the header len - if (header_len_dtch == 0) { - header_len_dcch = header_len_dcch_tmp; - } else { //if (( header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2))) - header_len_dtch = header_len_dtch_tmp; - } - - post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len; // 1 is for the postpadding header - } - - - offset = generate_dlsch_header((unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], num_sdus, //num_sdus - sdu_lengths, // - sdu_lcids, 255, // no drx - ta_update, // timing advance - NULL, // contention res id - padding, post_padding); - - //#ifdef DEBUG_eNB_SCHEDULER - if (ta_update != 31) { - LOG_D(MAC, - "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_dcch %d, header_dtch %d\n", - module_idP, frameP, UE_id, CC_id, - sdu_length_total, num_sdus, sdu_lengths[0], - sdu_lcids[0], offset, ta_update, padding, - post_padding, mcs, TBS, nb_rb, - header_len_dcch, header_len_dtch); - } - //#endif -#ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n"); - - for (i = 0; i < 16; i++) { - LOG_T(MAC, "%x.", dlsch_buffer[i]); - } - - LOG_T(MAC, "\n"); -#endif - - // cycle through SDUs and place in dlsch_buffer - memcpy(&UE_list-> - DLSCH_pdu[CC_id][0][UE_id].payload[0][offset], - dlsch_buffer, sdu_length_total); - // memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); - - // fill remainder of DLSCH with random data - for (j = 0; j < (TBS - sdu_length_total - offset); j++) { - UE_list->DLSCH_pdu[CC_id][0][UE_id]. - payload[0][offset + sdu_length_total + j] = - (char) (taus() & 0xff); - } - - - if (opt_enabled == 1) { - trace_pdu(1, (uint8_t *) - UE_list->DLSCH_pdu[CC_id][0][UE_id]. - payload[0], TBS, module_idP, 3, - UE_RNTI(module_idP, UE_id), eNB->frame, - eNB->subframe, 0, 0); - LOG_D(OPT, - "[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", - module_idP, CC_id, frameP, - UE_RNTI(module_idP, UE_id), TBS); - } - - T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), - T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id]. - payload[0], TBS)); - - UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = - nb_rb; - - add_ue_dlsch_info(module_idP, - CC_id, UE_id, subframeP, - S_DL_SCHEDULED); - // store stats - eNB->eNB_stats[CC_id].dlsch_bytes_tx += - sdu_length_total; - eNB->eNB_stats[CC_id].dlsch_pdus_tx += 1; - - UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used += - nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = - eNB_UE_stats->dlsch_mcs1; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = mcs; - UE_list->eNB_UE_stats[CC_id][UE_id].TBS = TBS; - - UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes = - TBS - sdu_length_total; - UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes += - sdu_length_total; - UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes += - TBS; - UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus += - 1; - - if (cc[CC_id].tdd_Config != NULL) { // TDD - UE_list->UE_template[CC_id][UE_id].DAI++; - update_ul_dci(module_idP, CC_id, rnti, - UE_list->UE_template[CC_id][UE_id]. - DAI); - } - // do PUCCH power control - // this is the normalized RX power - eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; - - /* TODO: fix how we deal with power, unit is not dBm, it's special from nfapi */ - normalized_rx_power = ue_sched_ctl->pucch1_snr[CC_id]; - target_rx_power = 208; - - // this assumes accumulated tpc - // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out - int32_t framex10psubframe = - UE_list->UE_template[CC_id][UE_id]. - pucch_tpc_tx_frame * 10 + - UE_list->UE_template[CC_id][UE_id]. - pucch_tpc_tx_subframe; - if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || //normal case - ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) //frame wrap-around - if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) { - ue_sched_ctl->pucch1_cqi_update[CC_id] = 0; - - UE_list-> - UE_template[CC_id] - [UE_id].pucch_tpc_tx_frame = frameP; - UE_list-> - UE_template[CC_id] - [UE_id].pucch_tpc_tx_subframe = subframeP; - - if (normalized_rx_power > - (target_rx_power + 4)) { - tpc = 0; //-1 - tpc_accumulated--; - } else if (normalized_rx_power < - (target_rx_power - 4)) { - tpc = 2; //+1 - tpc_accumulated++; - } else { - tpc = 1; //0 - } - - LOG_D(MAC, - "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", - module_idP, frameP, subframeP, harq_pid, - tpc, tpc_accumulated, - normalized_rx_power, target_rx_power); - - } // Po_PUCCH has been updated - else { - tpc = 1; //0 - } // time to do TPC update - else { - tpc = 1; //0 - } - - dl_config_pdu = - &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = - NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = - NFAPI_DL_DCI_FORMAT_1; - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level = - get_aggregation(get_bw_index(module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format1); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - harq_process = harq_pid; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; // dont adjust power when retransmitting - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.new_data_indicator_1 = - 1 - - UE_list->UE_template[CC_id][UE_id]. - oldNDI[harq_pid]; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.redundancy_version_1 = 0; - //deactivate second codeword - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0; - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.redundancy_version_2 = 1; - if (cc[CC_id].tdd_Config != NULL) { //TDD - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.downlink_assignment_index = - (UE_list->UE_template[CC_id][UE_id].DAI - - 1) & 3; - LOG_D(MAC, - "[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n", - module_idP, CC_id, harq_pid, - (UE_list->UE_template[CC_id][UE_id].DAI - 1), - mcs); - } else { - LOG_D(MAC, - "[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n", - module_idP, CC_id, harq_pid, mcs); - - } - LOG_D(MAC, "Checking feasibility pdu %d (new sdu)\n", - dl_req->number_pdu); - if (!CCE_allocation_infeasible - (module_idP, CC_id, 1, subframeP, - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level, rnti)) { - - - ue_sched_ctl->round[CC_id][harq_pid] = 0; - dl_req->number_dci++; - dl_req->number_pdu++; - dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - - eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; - eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; - - // Toggle NDI for next time - LOG_D(MAC, - "CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n", - CC_id, frameP, subframeP, UE_id, rnti, - harq_pid, - UE_list-> - UE_template[CC_id][UE_id].oldNDI[harq_pid]); - - UE_list->UE_template[CC_id][UE_id]. - oldNDI[harq_pid] = - 1 - - UE_list->UE_template[CC_id][UE_id]. - oldNDI[harq_pid]; - UE_list->UE_template[CC_id][UE_id]. - oldmcs1[harq_pid] = mcs; - UE_list->UE_template[CC_id][UE_id]. - oldmcs2[harq_pid] = 0; - AssertFatal(UE_list->UE_template[CC_id] - [UE_id].physicalConfigDedicated != - NULL, - "physicalConfigDedicated is NULL\n"); - AssertFatal(UE_list->UE_template[CC_id] - [UE_id]. - physicalConfigDedicated->pdsch_ConfigDedicated - != NULL, - "physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n"); - - fill_nfapi_dlsch_config(eNB, dl_req, TBS, eNB->pdu_index[CC_id], rnti, 0, // type 0 allocation from 7.1.6 in 36.213 - 0, // virtual_resource_block_assignment_flag, unused here - 0, // resource_block_coding, to be filled in later - getQm(mcs), 0, // redundancy version - 1, // transport blocks - 0, // transport block to codeword swap flag - cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme - 1, // number of layers - 1, // number of subbands - // uint8_t codebook_index, - 4, // UE category capacity - UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0, // delta_power_offset for TM5 - 0, // ngap - 0, // nprb - cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode - 0, //number of PRBs treated as one subband, not used here - 0 // number of beamforming vectors, not used here - ); - eNB->TX_req[CC_id].sfn_sf = - fill_nfapi_tx_req(&eNB-> - TX_req - [CC_id].tx_request_body, - (frameP * 10) + subframeP, - TBS, eNB->pdu_index[CC_id], - eNB-> - UE_list.DLSCH_pdu[CC_id][0][(unsigned char) - UE_id].payload + } + + j = j + 1; + } + } + + nb_available_rb -= nb_rb; + /* + eNB->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; + eNB->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; + + for(j=0; jmu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; + } + */ + + switch (get_tmode(module_idP, CC_id, UE_id)) { + case 1: + case 2: + case 7: + default: + LOG_D(MAC,"retransmission DL_REQ: rnti:%x\n",rnti); + + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP, CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format1); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // dont adjust power when retransmitting + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = round & 3; + + if (cc[CC_id].tdd_Config != NULL) { //TDD + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (UE_list->UE_template[CC_id][UE_id].DAI - 1) & 3; + LOG_D(MAC, + "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n", + module_idP, CC_id, harq_pid, round, + (UE_list->UE_template[CC_id][UE_id].DAI - 1), + UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]); + } else { + LOG_D(MAC, + "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n", + module_idP, CC_id, harq_pid, round, + UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]); + + } + if (!CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, rnti)) { + dl_req->number_dci++; + dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + + eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; + eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; + + fill_nfapi_dlsch_config(eNB, dl_req, TBS, -1 + /* retransmission, no pdu_index */ + , rnti, 0, // type 0 allocation from 7.1.6 in 36.213 + 0, // virtual_resource_block_assignment_flag, unused here + 0, // resource_block_coding, to be filled in later + getQm(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]), round & 3, // redundancy version + 1, // transport blocks + 0, // transport block to codeword swap flag + cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme + 1, // number of layers + 1, // number of subbands + // uint8_t codebook_index, + 4, // UE category capacity + UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0, // delta_power_offset for TM5 + 0, // ngap + 0, // nprb + cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode + 0, //number of PRBs treated as one subband, not used here + 0 // number of beamforming vectors, not used here + ); + + LOG_D(MAC, + "Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n", + eNB->pdu_index[CC_id], round); + + program_dlsch_acknak(module_idP, CC_id, UE_id, + frameP, subframeP, + dl_config_pdu-> + dci_dl_pdu.dci_dl_pdu_rel8. + cce_idx); + // No TX request for retransmission (check if null request for FAPI) + } else { + LOG_W(MAC, + "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d\%x, infeasible CCE allocation\n", + frameP, subframeP, UE_id, rnti); + } + } + + + add_ue_dlsch_info(module_idP, + CC_id, UE_id, subframeP, + S_DL_SCHEDULED); + + //eNB_UE_stats->dlsch_trials[round]++; + UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx = nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_retx += nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = eNB_UE_stats->dlsch_mcs1; + } else { + LOG_D(MAC, + "[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n", + module_idP, frameP, CC_id, UE_id); + } + } else { /* This is a potentially new SDU opportunity */ + + rlc_status.bytes_in_buffer = 0; + // Now check RLC information to compute number of required RBs + // get maximum TBS size for RLC request + TBS = + get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb); + // check first for RLC data on DCCH + // add the length for all the control elements (timing adv, drx, etc) : header + payload + + if (ue_sched_ctl->ta_timer == 0) { + ta_update = ue_sched_ctl->ta_update; + /* if we send TA then set timer to not send it for a while */ + if (ta_update != 31) ue_sched_ctl->ta_timer = 20; + /* reset ta_update */ + ue_sched_ctl->ta_update = 31; + } else { + ta_update = 31; + } + + ta_len = (ta_update != 31) ? 2 : 0; + + header_len_dcch = 2; // 2 bytes DCCH SDU subheader + + if (TBS - ta_len - header_len_dcch > 0) { + rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, (TBS - ta_len - header_len_dcch)); // transport block set size + + sdu_lengths[0] = 0; + + if (rlc_status.bytes_in_buffer > 0) { // There is DCCH to transmit + LOG_D(MAC, + "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", + module_idP, frameP, subframeP, CC_id, + TBS - header_len_dcch); + sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, TBS, //not used + (char *) + &dlsch_buffer [0]); - LOG_D(MAC, - "Filled NFAPI configuration for DCI/DLSCH/TXREQ %d, new SDU\n", - eNB->pdu_index[CC_id]); + T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), + T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), T_INT(DCCH), + T_INT(sdu_lengths[0])); - eNB->pdu_index[CC_id]++; - program_dlsch_acknak(module_idP, CC_id, UE_id, - frameP, subframeP, - dl_config_pdu-> - dci_dl_pdu.dci_dl_pdu_rel8. - cce_idx); + LOG_D(MAC, + "[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n", + module_idP, CC_id, sdu_lengths[0]); + sdu_length_total = sdu_lengths[0]; + sdu_lcids[0] = DCCH; + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH] += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH] += sdu_lengths[0]; + num_sdus = 1; +#ifdef DEBUG_eNB_SCHEDULER + LOG_T(MAC, + "[eNB %d][DCCH] CC_id %d Got %d bytes :", + module_idP, CC_id, sdu_lengths[0]); - } else { - LOG_W(MAC, - "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d/%x, infeasible CCE allocations\n", - frameP, subframeP, UE_id, rnti); - } - } else { // There is no data from RLC or MAC header, so don't schedule + for (j = 0; j < sdu_lengths[0]; j++) { + LOG_T(MAC, "%x ", dlsch_buffer[j]); + } + LOG_T(MAC, "\n"); +#endif + } else { + header_len_dcch = 0; + sdu_length_total = 0; + } + } + // check for DCCH1 and update header information (assume 2 byte sub-header) + if (TBS - ta_len - header_len_dcch - sdu_length_total > 0) { + rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, (TBS - ta_len - header_len_dcch - sdu_length_total)); // transport block set size less allocations for timing advance and + // DCCH SDU + sdu_lengths[num_sdus] = 0; + + if (rlc_status.bytes_in_buffer > 0) { + LOG_D(MAC, + "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n", + module_idP, frameP, CC_id, + TBS - header_len_dcch - sdu_length_total); + sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, TBS, //not used + (char *) + &dlsch_buffer + [sdu_length_total]); + + T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), + T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), + T_INT(DCCH + 1), T_INT(sdu_lengths[num_sdus])); + + sdu_lcids[num_sdus] = DCCH1; + sdu_length_total += sdu_lengths[num_sdus]; + header_len_dcch += 2; + UE_list->eNB_UE_stats[CC_id][UE_id]. + num_pdu_tx[DCCH1] += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1] += sdu_lengths[num_sdus]; + num_sdus++; +#ifdef DEBUG_eNB_SCHEDULER + LOG_T(MAC, + "[eNB %d][DCCH1] CC_id %d Got %d bytes :", + module_idP, CC_id, sdu_lengths[num_sdus]); + + for (j = 0; j < sdu_lengths[num_sdus]; j++) { + LOG_T(MAC, "%x ", dlsch_buffer[j]); + } + + LOG_T(MAC, "\n"); +#endif + + } + } + // assume the max dtch header size, and adjust it later + header_len_dtch = 0; + header_len_dtch_last = 0; // the header length of the last mac sdu + // lcid has to be sorted before the actual allocation (similar struct as ue_list). + for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { + // TBD: check if the lcid is active + + header_len_dtch += 3; + header_len_dtch_last = 3; + LOG_D(MAC, + "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", + module_idP, frameP, lcid, TBS, + TBS - ta_len - header_len_dcch - + sdu_length_total - header_len_dtch); + + if (TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch > 0) { // NN: > 2 ? + rlc_status = mac_rlc_status_ind(module_idP, + rnti, + module_idP, + frameP, + subframeP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + TBS - ta_len - + header_len_dcch - + sdu_length_total - + header_len_dtch); + + + if (rlc_status.bytes_in_buffer > 0) { + + LOG_D(MAC, + "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n", + module_idP, frameP, + TBS - header_len_dcch - + sdu_length_total - header_len_dtch, lcid, + header_len_dtch); + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, TBS, //not used + (char + *) + &dlsch_buffer + [sdu_length_total]); + T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), + T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), + T_INT(lcid), T_INT(sdu_lengths[num_sdus])); + + LOG_D(MAC, + "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", + module_idP, sdu_lengths[num_sdus], lcid); + sdu_lcids[num_sdus] = lcid; + sdu_length_total += sdu_lengths[num_sdus]; + UE_list-> + eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid] + += 1; + UE_list-> + eNB_UE_stats[CC_id][UE_id].num_bytes_tx + [lcid] += sdu_lengths[num_sdus]; + if (sdu_lengths[num_sdus] < 128) { + header_len_dtch--; + header_len_dtch_last--; + } + num_sdus++; + UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; + } // no data for this LCID + else { + header_len_dtch -= 3; + } + } // no TBS left + else { + header_len_dtch -= 3; + break; + } + } + if (header_len_dtch == 0) + header_len_dtch_last = 0; + // there is at least one SDU + // if (num_sdus > 0 ){ + if ((sdu_length_total + header_len_dcch + + header_len_dtch) > 0) { + + // Now compute number of required RBs for total sdu length + // Assume RAH format 2 + // adjust header lengths + header_len_dcch_tmp = header_len_dcch; + header_len_dtch_tmp = header_len_dtch; + if (header_len_dtch == 0) { + header_len_dcch = (header_len_dcch > 0) ? 1 : 0; //header_len_dcch; // remove length field + } else { + header_len_dtch_last -= 1; // now use it to find how many bytes has to be removed for the last MAC SDU + header_len_dtch = (header_len_dtch > 0) ? header_len_dtch - header_len_dtch_last : header_len_dtch; // remove length field for the last SDU + } + + mcs = eNB_UE_stats->dlsch_mcs1; + + if (mcs == 0) { + nb_rb = 4; // don't let the TBS get too small + } else { + nb_rb = min_rb_unit[CC_id]; + } + + TBS = get_TBS_DL(mcs, nb_rb); + + while (TBS < + (sdu_length_total + header_len_dcch + + header_len_dtch + ta_len)) { + nb_rb += min_rb_unit[CC_id]; // + + if (nb_rb > nb_available_rb) { // if we've gone beyond the maximum number of RBs + // (can happen if N_RB_DL is odd) + TBS = + get_TBS_DL(eNB_UE_stats->dlsch_mcs1, + nb_available_rb); + nb_rb = nb_available_rb; + break; + } + + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rb); + } + + if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { + for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + } + } else { + nb_rb_temp = nb_rb; + j = 0; + + while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { + if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + + if ((j == N_RBG[CC_id] - 1) && + ((N_RB_DL[CC_id] == 25) || + (N_RB_DL[CC_id] == 50))) { + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1; + } else { + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; } + } + + j = j + 1; + } + } + + // decrease mcs until TBS falls below required length + while ((TBS > (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && (mcs > 0)) { + mcs--; + TBS = get_TBS_DL(mcs, nb_rb); + } + + // if we have decreased too much or we don't have enough RBs, increase MCS + while ((TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) + && (((ue_sched_ctl->dl_pow_off[CC_id] > 0) + && (mcs < 28)) + || ((ue_sched_ctl->dl_pow_off[CC_id] == 0) + && (mcs <= 15)))) { + mcs++; + TBS = get_TBS_DL(mcs, nb_rb); + } + + LOG_D(MAC, + "dlsch_mcs before and after the rate matching = (%d, %d)\n", + eNB_UE_stats->dlsch_mcs1, mcs); + +#ifdef DEBUG_eNB_SCHEDULER + LOG_D(MAC, + "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", + module_idP, CC_id, mcs, TBS, nb_rb); + // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n", + // TBS, sdu_length_total, offset, TBS-sdu_length_total-offset); +#endif + + if ((TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len) <= 2) { + padding = (TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len); + post_padding = 0; + } else { + padding = 0; + + // adjust the header len + if (header_len_dtch == 0) { + header_len_dcch = header_len_dcch_tmp; + } else { //if (( header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2))) + header_len_dtch = header_len_dtch_tmp; } - if (cc[CC_id].tdd_Config != NULL) { // TDD - set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); - } + post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len; // 1 is for the postpadding header + } - } // UE_id loop - } // CC_id loop + + offset = generate_dlsch_header((unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], num_sdus, //num_sdus + sdu_lengths, // + sdu_lcids, 255, // no drx + ta_update, // timing advance + NULL, // contention res id + padding, post_padding); + + //#ifdef DEBUG_eNB_SCHEDULER + if (ta_update != 31) { + LOG_D(MAC, + "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_dcch %d, header_dtch %d\n", + module_idP, frameP, UE_id, CC_id, + sdu_length_total, num_sdus, sdu_lengths[0], + sdu_lcids[0], offset, ta_update, padding, + post_padding, mcs, TBS, nb_rb, + header_len_dcch, header_len_dtch); + } + //#endif +#ifdef DEBUG_eNB_SCHEDULER + LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n"); + + for (i = 0; i < 16; i++) { + LOG_T(MAC, "%x.", dlsch_buffer[i]); + } + + LOG_T(MAC, "\n"); +#endif + + // cycle through SDUs and place in dlsch_buffer + memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset], + dlsch_buffer, sdu_length_total); + // memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); + + // fill remainder of DLSCH with random data + for (j = 0; j < (TBS - sdu_length_total - offset); j++) { + UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + sdu_length_total + j] = (char) (taus() & 0xff); + } + + + if (opt_enabled == 1) { + trace_pdu(1, (uint8_t *) + UE_list->DLSCH_pdu[CC_id][0][UE_id]. + payload[0], TBS, module_idP, 3, + UE_RNTI(module_idP, UE_id), eNB->frame, + eNB->subframe, 0, 0); + LOG_D(OPT, + "[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", + module_idP, CC_id, frameP, + UE_RNTI(module_idP, UE_id), TBS); + } + + T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), + T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), + T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id]. + payload[0], TBS)); + + UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb; + + add_ue_dlsch_info(module_idP, + CC_id, UE_id, subframeP, + S_DL_SCHEDULED); + // store stats + eNB->eNB_stats[CC_id].dlsch_bytes_tx += sdu_length_total; + eNB->eNB_stats[CC_id].dlsch_pdus_tx += 1; + + UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used += nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = mcs; + UE_list->eNB_UE_stats[CC_id][UE_id].TBS = TBS; + + UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes = TBS - sdu_length_total; + UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes += sdu_length_total; + UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes += TBS; + UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus += 1; + + if (cc[CC_id].tdd_Config != NULL) { // TDD + UE_list->UE_template[CC_id][UE_id].DAI++; + update_ul_dci(module_idP, CC_id, rnti, + UE_list->UE_template[CC_id][UE_id]. + DAI); + } + // do PUCCH power control + // this is the normalized RX power + eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; + + /* TODO: fix how we deal with power, unit is not dBm, it's special from nfapi */ + normalized_rx_power = ue_sched_ctl->pucch1_snr[CC_id]; + target_rx_power = 208; + + // this assumes accumulated tpc + // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out + int32_t framex10psubframe = UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame * 10 + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe; + if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || //normal case + ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) //frame wrap-around + if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) { + ue_sched_ctl->pucch1_cqi_update[CC_id] = 0; + + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame = frameP; + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe = subframeP; + + if (normalized_rx_power > (target_rx_power + 4)) { + tpc = 0; //-1 + tpc_accumulated--; + } else if (normalized_rx_power < (target_rx_power - 4)) { + tpc = 2; //+1 + tpc_accumulated++; + } else { + tpc = 1; //0 + } + + LOG_D(MAC, + "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", + module_idP, frameP, subframeP, harq_pid, + tpc, tpc_accumulated, + normalized_rx_power, target_rx_power); + + } // Po_PUCCH has been updated + else { + tpc = 1; //0 + } // time to do TPC update + else { + tpc = 1; //0 + } + + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP, CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format1); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; // dont adjust power when retransmitting + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; + //deactivate second codeword + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1; + if (cc[CC_id].tdd_Config != NULL) { //TDD + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (UE_list->UE_template[CC_id][UE_id].DAI - 1) & 3; + LOG_D(MAC, + "[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n", + module_idP, CC_id, harq_pid, + (UE_list->UE_template[CC_id][UE_id].DAI - 1), + mcs); + } else { + LOG_D(MAC, + "[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n", + module_idP, CC_id, harq_pid, mcs); + + } + LOG_D(MAC, "Checking feasibility pdu %d (new sdu)\n", + dl_req->number_pdu); + if (!CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, + dl_config_pdu->dci_dl_pdu. + dci_dl_pdu_rel8.aggregation_level, rnti)) { + + + ue_sched_ctl->round[CC_id][harq_pid] = 0; + dl_req->number_dci++; + dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + + eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; + eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; + + // Toggle NDI for next time + LOG_D(MAC, + "CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n", + CC_id, frameP, subframeP, UE_id, rnti, + harq_pid, + UE_list-> + UE_template[CC_id][UE_id].oldNDI[harq_pid]); + + UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid] = 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs; + UE_list->UE_template[CC_id][UE_id].oldmcs2[harq_pid] = 0; + AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != + NULL, + "physicalConfigDedicated is NULL\n"); + AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated != NULL, + "physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n"); + + fill_nfapi_dlsch_config(eNB, dl_req, TBS, eNB->pdu_index[CC_id], rnti, 0, // type 0 allocation from 7.1.6 in 36.213 + 0, // virtual_resource_block_assignment_flag, unused here + 0, // resource_block_coding, to be filled in later + getQm(mcs), 0, // redundancy version + 1, // transport blocks + 0, // transport block to codeword swap flag + cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme + 1, // number of layers + 1, // number of subbands + // uint8_t codebook_index, + 4, // UE category capacity + UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0, // delta_power_offset for TM5 + 0, // ngap + 0, // nprb + cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode + 0, //number of PRBs treated as one subband, not used here + 0 // number of beamforming vectors, not used here + ); + eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB-> + TX_req + [CC_id].tx_request_body, + (frameP * 10) + subframeP, + TBS, eNB->pdu_index[CC_id], + eNB-> + UE_list.DLSCH_pdu[CC_id][0][(unsigned char) + UE_id].payload + [0]); + + LOG_D(MAC, + "Filled NFAPI configuration for DCI/DLSCH/TXREQ %d, new SDU\n", + eNB->pdu_index[CC_id]); + + eNB->pdu_index[CC_id]++; + program_dlsch_acknak(module_idP, CC_id, UE_id, + frameP, subframeP, + dl_config_pdu-> + dci_dl_pdu.dci_dl_pdu_rel8. + cce_idx); + + } else { + LOG_W(MAC, + "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d/%x, infeasible CCE allocations\n", + frameP, subframeP, UE_id, rnti); + } + } else { // There is no data from RLC or MAC header, so don't schedule + + } + } + + if (cc[CC_id].tdd_Config != NULL) { // TDD + set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); + } + + } // UE_id loop + } // CC_id loop - fill_DLSCH_dci(module_idP, frameP, subframeP, mbsfn_flag); + fill_DLSCH_dci(module_idP, frameP, subframeP, mbsfn_flag); - stop_meas(&eNB->schedule_dlsch); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT); + stop_meas(&eNB->schedule_dlsch); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT); } @@ -1531,111 +1396,84 @@ fill_DLSCH_dci(module_id_t module_idP, //------------------------------------------------------------------------------ { - // loop over all allocated UEs and compute frequency allocations for PDSCH - int UE_id = -1; - uint8_t /* first_rb, */ nb_rb = 3; - rnti_t rnti; - //unsigned char *vrb_map; - uint8_t rballoc_sub[25]; - //uint8_t number_of_subbands=13; + // loop over all allocated UEs and compute frequency allocations for PDSCH + int UE_id = -1; + uint8_t /* first_rb, */ nb_rb = 3; + rnti_t rnti; + //unsigned char *vrb_map; + uint8_t rballoc_sub[25]; + //uint8_t number_of_subbands=13; - //unsigned char round; - unsigned char harq_pid; - int i; - int CC_id; - eNB_MAC_INST *eNB = RC.mac[module_idP]; - UE_list_t *UE_list = &eNB->UE_list; - int N_RBG; - int N_RB_DL; - COMMON_channels_t *cc; + //unsigned char round; + unsigned char harq_pid; + int i; + int CC_id; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &eNB->UE_list; + int N_RBG; + int N_RB_DL; + COMMON_channels_t *cc; - start_meas(&eNB->fill_DLSCH_dci); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_IN); + start_meas(&eNB->fill_DLSCH_dci); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_IN); - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - LOG_D(MAC, "Doing fill DCI for CC_id %d\n", CC_id); + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + LOG_D(MAC, "Doing fill DCI for CC_id %d\n", CC_id); - if (mbsfn_flagP[CC_id] > 0) - continue; + if (mbsfn_flagP[CC_id] > 0) + continue; - cc = &eNB->common_channels[CC_id]; - N_RBG = to_rbg(cc->mib->message.dl_Bandwidth); - N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); + cc = &eNB->common_channels[CC_id]; + N_RBG = to_rbg(cc->mib->message.dl_Bandwidth); + N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); - // UE specific DCIs - for (UE_id = UE_list->head; UE_id >= 0; - UE_id = UE_list->next[UE_id]) { - LOG_T(MAC, "CC_id %d, UE_id: %d => status %d\n", CC_id, UE_id, - eNB_dlsch_info[module_idP][CC_id][UE_id].status); + // UE specific DCIs + for (UE_id = UE_list->head; UE_id >= 0; + UE_id = UE_list->next[UE_id]) { + LOG_T(MAC, "CC_id %d, UE_id: %d => status %d\n", CC_id, UE_id, + eNB_dlsch_info[module_idP][CC_id][UE_id].status); - if (eNB_dlsch_info[module_idP][CC_id][UE_id].status == - S_DL_SCHEDULED) { + if (eNB_dlsch_info[module_idP][CC_id][UE_id].status == S_DL_SCHEDULED) { - // clear scheduling flag - eNB_dlsch_info[module_idP][CC_id][UE_id].status = - S_DL_WAITING; - rnti = UE_RNTI(module_idP, UE_id); - if (cc->tdd_Config) - harq_pid = ((frameP * 10) + subframeP) % 10; - else - harq_pid = ((frameP * 10) + subframeP) & 7; - nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + // clear scheduling flag + eNB_dlsch_info[module_idP][CC_id][UE_id].status = S_DL_WAITING; + rnti = UE_RNTI(module_idP, UE_id); + if (cc->tdd_Config) harq_pid = ((frameP * 10) + subframeP) % 10; + else harq_pid = ((frameP * 10) + subframeP) & 7; + nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - - - /// Synchronizing rballoc with rballoc_sub - for (i = 0; i < N_RBG; i++) { - rballoc_sub[i] = - UE_list-> - UE_template[CC_id][UE_id].rballoc_subband[harq_pid] - [i]; - } - - nfapi_dl_config_request_t *DL_req = - &RC.mac[module_idP]->DL_req[0]; - nfapi_dl_config_request_pdu_t *dl_config_pdu; - - for (i = 0; - i < DL_req[CC_id].dl_config_request_body.number_pdu; - i++) { - dl_config_pdu = - &DL_req[CC_id]. - dl_config_request_body.dl_config_pdu_list[i]; - if ((dl_config_pdu->pdu_type == - NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) - && (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - rnti == rnti) - && (dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.dci_format != 1)) { - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.resource_block_coding = - allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG, - rballoc_sub); - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.resource_allocation_type = 0; - } else - if ((dl_config_pdu->pdu_type == - NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) - && (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. - rnti == rnti) - && (dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.resource_allocation_type == - 0)) { - dl_config_pdu->dlsch_pdu. - dlsch_pdu_rel8.resource_block_coding = - allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG, - rballoc_sub); - } - } - } + /// Synchronizing rballoc with rballoc_sub + for (i = 0; i < N_RBG; i++) { + rballoc_sub[i] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][i]; } + nfapi_dl_config_request_t *DL_req = &RC.mac[module_idP]->DL_req[0]; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + + for (i = 0; + i < DL_req[CC_id].dl_config_request_body.number_pdu; + i++) { + dl_config_pdu = &DL_req[CC_id].dl_config_request_body.dl_config_pdu_list[i]; + if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) + && (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti) + && (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format != 1)) { + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG,rballoc_sub); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0; + } else + if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) + && (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == rnti) + && (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type == 0)) { + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding =allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG,rballoc_sub); + } + } + } } - stop_meas(&eNB->fill_DLSCH_dci); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_OUT); + } + + stop_meas(&eNB->fill_DLSCH_dci); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_OUT); } //------------------------------------------------------------------------------ @@ -1645,37 +1483,35 @@ unsigned char *get_dlsch_sdu(module_id_t module_idP, //------------------------------------------------------------------------------ { - int UE_id; - eNB_MAC_INST *eNB = RC.mac[module_idP]; + int UE_id; + eNB_MAC_INST *eNB = RC.mac[module_idP]; - if (rntiP == SI_RNTI) { - LOG_D(MAC, "[eNB %d] CC_id %d Frame %d Get DLSCH sdu for BCCH \n", - module_idP, CC_id, frameP); + if (rntiP == SI_RNTI) { + LOG_D(MAC, "[eNB %d] CC_id %d Frame %d Get DLSCH sdu for BCCH \n", + module_idP, CC_id, frameP); - return ((unsigned char *) &eNB->common_channels[CC_id]. - BCCH_pdu.payload[0]); - } + return ((unsigned char *) &eNB->common_channels[CC_id].BCCH_pdu.payload[0]); + } - if (rntiP==P_RNTI) { - LOG_D(MAC,"[eNB %d] CC_id %d Frame %d Get PCH sdu for PCCH \n", module_idP, CC_id, frameP); + if (rntiP==P_RNTI) { + LOG_D(MAC,"[eNB %d] CC_id %d Frame %d Get PCH sdu for PCCH \n", module_idP, CC_id, frameP); - return((unsigned char *)&eNB->common_channels[CC_id].PCCH_pdu.payload[0]); - } + return((unsigned char *)&eNB->common_channels[CC_id].PCCH_pdu.payload[0]); + } UE_id = find_UE_id(module_idP,rntiP); - if (UE_id != -1) { - LOG_D(MAC, - "[eNB %d] Frame %d: CC_id %d Get DLSCH sdu for rnti %x => UE_id %d\n", - module_idP, frameP, CC_id, rntiP, UE_id); - return ((unsigned char *) &eNB-> - UE_list.DLSCH_pdu[CC_id][TBindex][UE_id].payload[0]); - } else { - LOG_E(MAC, - "[eNB %d] Frame %d: CC_id %d UE with RNTI %x does not exist\n", - module_idP, frameP, CC_id, rntiP); - return NULL; - } + if (UE_id != -1) { + LOG_D(MAC, + "[eNB %d] Frame %d: CC_id %d Get DLSCH sdu for rnti %x => UE_id %d\n", + module_idP, frameP, CC_id, rntiP, UE_id); + return ((unsigned char *) &eNB->UE_list.DLSCH_pdu[CC_id][TBindex][UE_id].payload[0]); + } else { + LOG_E(MAC, + "[eNB %d] Frame %d: CC_id %d UE with RNTI %x does not exist\n", + module_idP, frameP, CC_id, rntiP); + return NULL; + } } @@ -1687,27 +1523,25 @@ update_ul_dci(module_id_t module_idP, //------------------------------------------------------------------------------ { - nfapi_hi_dci0_request_t *HI_DCI0_req = - &RC.mac[module_idP]->HI_DCI0_req[CC_idP]; - nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = - &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[0]; - COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_idP]; - int i; + nfapi_hi_dci0_request_t *HI_DCI0_req = + &RC.mac[module_idP]->HI_DCI0_req[CC_idP]; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = + &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[0]; + COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_idP]; + int i; - if (cc->tdd_Config != NULL) { // TDD - for (i = 0; - i < - HI_DCI0_req->hi_dci0_request_body.number_of_dci + - HI_DCI0_req->hi_dci0_request_body.number_of_dci; i++) { + if (cc->tdd_Config != NULL) { // TDD + for (i = 0; + i hi_dci0_request_body.number_of_dci + HI_DCI0_req->hi_dci0_request_body.number_of_dci; + i++) { - if ((hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) && - (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti == rntiP)) - hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.dl_assignment_index = - (daiP - 1) & 3; + if ((hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) && + (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti == rntiP)) + hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.dl_assignment_index = (daiP - 1) & 3; - } } + } } @@ -1718,64 +1552,64 @@ set_ue_dai(sub_frame_t subframeP, UE_list_t * UE_list) //------------------------------------------------------------------------------ { - switch (tdd_config) { - case 0: - if ((subframeP == 0) || (subframeP == 1) || (subframeP == 3) - || (subframeP == 5) || (subframeP == 6) || (subframeP == 8)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } - - break; - - case 1: - if ((subframeP == 0) || (subframeP == 4) || (subframeP == 5) - || (subframeP == 9)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } - - break; - - case 2: - if ((subframeP == 4) || (subframeP == 5)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } - - break; - - case 3: - if ((subframeP == 5) || (subframeP == 7) || (subframeP == 9)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } - - break; - - case 4: - if ((subframeP == 0) || (subframeP == 6)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } - - break; - - case 5: - if (subframeP == 9) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } - - break; - - case 6: - if ((subframeP == 0) || (subframeP == 1) || (subframeP == 5) - || (subframeP == 6) || (subframeP == 9)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } - - break; - - default: - UE_list->UE_template[CC_id][UE_id].DAI = 0; - LOG_N(MAC, "unknow TDD config %d\n", tdd_config); - break; + switch (tdd_config) { + case 0: + if ((subframeP == 0) || (subframeP == 1) || (subframeP == 3) + || (subframeP == 5) || (subframeP == 6) || (subframeP == 8)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; } + + break; + + case 1: + if ((subframeP == 0) || (subframeP == 4) || (subframeP == 5) + || (subframeP == 9)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } + + break; + + case 2: + if ((subframeP == 4) || (subframeP == 5)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } + + break; + + case 3: + if ((subframeP == 5) || (subframeP == 7) || (subframeP == 9)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } + + break; + + case 4: + if ((subframeP == 0) || (subframeP == 6)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } + + break; + + case 5: + if (subframeP == 9) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } + + break; + + case 6: + if ((subframeP == 0) || (subframeP == 1) || (subframeP == 5) + || (subframeP == 6) || (subframeP == 9)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } + + break; + + default: + UE_list->UE_template[CC_id][UE_id].DAI = 0; + LOG_N(MAC, "unknow TDD config %d\n", tdd_config); + break; + } } void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) @@ -1796,22 +1630,22 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) #ifdef FORMAT1C int gap_index = 0; /* indicate which gap(1st or 2nd) is used (0:1st) */ const int GAP_MAP [9][2] = { - {-1, 0}, /* N_RB_DL [6-10] -1: |N_RB/2| 0: N/A*/ - {4, 0}, /* N_RB_DL [11] */ - {8, 0}, /* N_RB_DL [12-19] */ - {12, 0}, /* N_RB_DL [20-26] */ - {18, 0}, /* N_RB_DL [27-44] */ - {27, 0}, /* N_RB_DL [45-49] */ - {27, 9}, /* N_RB_DL [50-63] */ - {32, 16}, /* N_RB_DL [64-79] */ - {48, 16} /* N_RB_DL [80-110] */ - }; + {-1, 0}, /* N_RB_DL [6-10] -1: |N_RB/2| 0: N/A*/ + {4, 0}, /* N_RB_DL [11] */ + {8, 0}, /* N_RB_DL [12-19] */ + {12, 0}, /* N_RB_DL [20-26] */ + {18, 0}, /* N_RB_DL [27-44] */ + {27, 0}, /* N_RB_DL [45-49] */ + {27, 9}, /* N_RB_DL [50-63] */ + {32, 16}, /* N_RB_DL [64-79] */ + {48, 16} /* N_RB_DL [80-110] */ + }; uint8_t n_rb_step = 0; uint8_t n_gap = 0; uint8_t n_vrb_dl = 0; uint8_t Lcrbs = 0; uint16_t rb_bit = 168; /* RB bit number value is unsure */ - #endif +#endif start_meas(&eNB->schedule_pch); @@ -1825,298 +1659,298 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) continue; } if (frameP % UE_PF_PO[CC_id][i].T == UE_PF_PO[CC_id][i].PF_min && subframeP == UE_PF_PO[CC_id][i].PO) { - pcch_sdu_length = mac_rrc_data_req(module_idP, + pcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, PCCH,1, &cc->PCCH_pdu.payload[0], i); // used for ue index - if (pcch_sdu_length == 0) { - LOG_D(MAC,"[eNB %d] Frame %d subframe %d: PCCH not active(size = 0 byte)\n", module_idP,frameP, subframeP); - continue; - } - LOG_D(MAC,"[eNB %d] Frame %d subframe %d: PCCH->PCH CC_id %d UE_id %d, Received %d bytes \n", module_idP, frameP, subframeP, CC_id,i, pcch_sdu_length); + if (pcch_sdu_length == 0) { + LOG_D(MAC,"[eNB %d] Frame %d subframe %d: PCCH not active(size = 0 byte)\n", module_idP,frameP, subframeP); + continue; + } + LOG_D(MAC,"[eNB %d] Frame %d subframe %d: PCCH->PCH CC_id %d UE_id %d, Received %d bytes \n", module_idP, frameP, subframeP, CC_id,i, pcch_sdu_length); #ifdef FORMAT1C - //NO SIB - if ((subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) || - (subframeP == 5 && ((frameP % 2) != 0 && (frameP % 8) != 1))) { - switch (n_rb_dl) { + //NO SIB + if ((subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) || + (subframeP == 5 && ((frameP % 2) != 0 && (frameP % 8) != 1))) { + switch (n_rb_dl) { #if 0 - case 6: - n_gap = n_rb_dl/2; /* expect: 3 */ - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));; /* expect: 6 */ - first_rb = 0; - break; - case 15: - n_gap = GAP_MAP[2][0]; /* expect: 8 */ - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 14 */ - first_rb = 6; - break; + case 6: + n_gap = n_rb_dl/2; /* expect: 3 */ + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));; /* expect: 6 */ + first_rb = 0; + break; + case 15: + n_gap = GAP_MAP[2][0]; /* expect: 8 */ + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 14 */ + first_rb = 6; + break; #endif - case 25: - n_gap = GAP_MAP[3][0]; /* expect: 12 */ - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 24 */ - first_rb = 10; - break; - case 50: - n_gap = GAP_MAP[6][gap_index]; /* expect: 27 or 9 */ - if (gap_index > 0) { - n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* 36 */ - } else { - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 46 */ - } - first_rb = 24; - break; - case 100: - n_gap = GAP_MAP[8][gap_index]; /* expect: 48 or 16 */ - if (gap_index > 0) { - n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* expect: 96 */ - } else { - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 96 */ - } - first_rb = 48; - break; - } - } else if (subframeP == 5 && ((frameP % 2) == 0 || (frameP % 8) == 1)) { // SIB + paging - switch (n_rb_dl) { + case 25: + n_gap = GAP_MAP[3][0]; /* expect: 12 */ + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 24 */ + first_rb = 10; + break; + case 50: + n_gap = GAP_MAP[6][gap_index]; /* expect: 27 or 9 */ + if (gap_index > 0) { + n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* 36 */ + } else { + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 46 */ + } + first_rb = 24; + break; + case 100: + n_gap = GAP_MAP[8][gap_index]; /* expect: 48 or 16 */ + if (gap_index > 0) { + n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* expect: 96 */ + } else { + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 96 */ + } + first_rb = 48; + break; + } + } else if (subframeP == 5 && ((frameP % 2) == 0 || (frameP % 8) == 1)) { // SIB + paging + switch (n_rb_dl) { #if 0 - case 6: - n_gap = n_rb_dl/2; /* expect: 3 */ - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));; /* expect: 6 */ - first_rb = 0; - break; - case 15: - n_gap = GAP_MAP[2][0]; /* expect: 8 */ - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 14 */ - first_rb = 10; - break; + case 6: + n_gap = n_rb_dl/2; /* expect: 3 */ + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));; /* expect: 6 */ + first_rb = 0; + break; + case 15: + n_gap = GAP_MAP[2][0]; /* expect: 8 */ + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 14 */ + first_rb = 10; + break; #endif - case 25: - n_gap = GAP_MAP[3][0]; /* expect: 12 */ - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 24 */ - first_rb = 14; - break; - case 50: - n_gap = GAP_MAP[6][gap_index]; /* expect: 27 or 9 */ - if (gap_index > 0) { - n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* 36 */ - } else { - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 46 */ - } - first_rb = 28; - break; - case 100: - n_gap = GAP_MAP[8][gap_index]; /* expect: 48 or 16 */ - if (gap_index > 0) { - n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* expect: 96 */ - } else { - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 96 */ - } - first_rb = 52; - break; - } - } - /* Get MCS for length of PCH */ - if (pcch_sdu_length <= TBStable1C[0]) { - mcs=0; - } else if (pcch_sdu_length <= TBStable1C[1]) { - mcs=1; - } else if (pcch_sdu_length <= TBStable1C[2]) { - mcs=2; - } else if (pcch_sdu_length <= TBStable1C[3]) { - mcs=3; - } else if (pcch_sdu_length <= TBStable1C[4]) { - mcs=4; - } else if (pcch_sdu_length <= TBStable1C[5]) { - mcs=5; - } else if (pcch_sdu_length <= TBStable1C[6]) { - mcs=6; - } else if (pcch_sdu_length <= TBStable1C[7]) { - mcs=7; - } else if (pcch_sdu_length <= TBStable1C[8]) { - mcs=8; - } else if (pcch_sdu_length <= TBStable1C[9]) { - mcs=9; - } else { - /* unexpected: pcch sdb size is over max value*/ - LOG_E(MAC,"[eNB %d] Frame %d : PCCH->PCH CC_id %d, Received %d bytes is over max length(256) \n", - module_idP, frameP,CC_id, pcch_sdu_length); - return; - } - rb_num = TBStable1C[mcs] / rb_bit + ( (TBStable1C[mcs] % rb_bit == 0)? 0: 1) + 1; - /* calculate N_RB_STEP and Lcrbs */ - if (n_rb_dl < 50) { - n_rb_step = 2; - Lcrbs = rb_num / 2 + ((rb_num % 2 == 0) ? 0:2); - } else { - n_rb_step = 4; - Lcrbs = rb_num / 4 + ((rb_num % 4 == 0) ? 0:4); - } - for(i = 0;i < Lcrbs ;i++){ - vrb_map[first_rb+i] = 1; - } + case 25: + n_gap = GAP_MAP[3][0]; /* expect: 12 */ + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 24 */ + first_rb = 14; + break; + case 50: + n_gap = GAP_MAP[6][gap_index]; /* expect: 27 or 9 */ + if (gap_index > 0) { + n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* 36 */ + } else { + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 46 */ + } + first_rb = 28; + break; + case 100: + n_gap = GAP_MAP[8][gap_index]; /* expect: 48 or 16 */ + if (gap_index > 0) { + n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* expect: 96 */ + } else { + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 96 */ + } + first_rb = 52; + break; + } + } + /* Get MCS for length of PCH */ + if (pcch_sdu_length <= TBStable1C[0]) { + mcs=0; + } else if (pcch_sdu_length <= TBStable1C[1]) { + mcs=1; + } else if (pcch_sdu_length <= TBStable1C[2]) { + mcs=2; + } else if (pcch_sdu_length <= TBStable1C[3]) { + mcs=3; + } else if (pcch_sdu_length <= TBStable1C[4]) { + mcs=4; + } else if (pcch_sdu_length <= TBStable1C[5]) { + mcs=5; + } else if (pcch_sdu_length <= TBStable1C[6]) { + mcs=6; + } else if (pcch_sdu_length <= TBStable1C[7]) { + mcs=7; + } else if (pcch_sdu_length <= TBStable1C[8]) { + mcs=8; + } else if (pcch_sdu_length <= TBStable1C[9]) { + mcs=9; + } else { + /* unexpected: pcch sdb size is over max value*/ + LOG_E(MAC,"[eNB %d] Frame %d : PCCH->PCH CC_id %d, Received %d bytes is over max length(256) \n", + module_idP, frameP,CC_id, pcch_sdu_length); + return; + } + rb_num = TBStable1C[mcs] / rb_bit + ( (TBStable1C[mcs] % rb_bit == 0)? 0: 1) + 1; + /* calculate N_RB_STEP and Lcrbs */ + if (n_rb_dl < 50) { + n_rb_step = 2; + Lcrbs = rb_num / 2 + ((rb_num % 2 == 0) ? 0:2); + } else { + n_rb_step = 4; + Lcrbs = rb_num / 4 + ((rb_num % 4 == 0) ? 0:4); + } + for(i = 0;i < Lcrbs ;i++){ + vrb_map[first_rb+i] = 1; + } #else - //NO SIB - if ((subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) || - (subframeP == 5 && ((frameP % 2) != 0 && (frameP % 8) != 1))) { - switch (n_rb_dl) { - case 25: - first_rb = 10; - break; - case 50: - first_rb = 24; - break; - case 100: - first_rb = 48; - break; - } - } else if (subframeP == 5 && ((frameP % 2) == 0 || (frameP % 8) == 1)) { // SIB + paging - switch (n_rb_dl) { - case 25: - first_rb = 14; - break; - case 50: - first_rb = 28; - break; - case 100: - first_rb = 52; - break; - } - } + //NO SIB + if ((subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) || + (subframeP == 5 && ((frameP % 2) != 0 && (frameP % 8) != 1))) { + switch (n_rb_dl) { + case 25: + first_rb = 10; + break; + case 50: + first_rb = 24; + break; + case 100: + first_rb = 48; + break; + } + } else if (subframeP == 5 && ((frameP % 2) == 0 || (frameP % 8) == 1)) { // SIB + paging + switch (n_rb_dl) { + case 25: + first_rb = 14; + break; + case 50: + first_rb = 28; + break; + case 100: + first_rb = 52; + break; + } + } - vrb_map[first_rb] = 1; - vrb_map[first_rb+1] = 1; - vrb_map[first_rb+2] = 1; - vrb_map[first_rb+3] = 1; - /* Get MCS for length of PCH */ - if (pcch_sdu_length <= get_TBS_DL(0,3)) { - mcs=0; - } else if (pcch_sdu_length <= get_TBS_DL(1,3)) { - mcs=1; - } else if (pcch_sdu_length <= get_TBS_DL(2,3)) { - mcs=2; - } else if (pcch_sdu_length <= get_TBS_DL(3,3)) { - mcs=3; - } else if (pcch_sdu_length <= get_TBS_DL(4,3)) { - mcs=4; - } else if (pcch_sdu_length <= get_TBS_DL(5,3)) { - mcs=5; - } else if (pcch_sdu_length <= get_TBS_DL(6,3)) { - mcs=6; - } else if (pcch_sdu_length <= get_TBS_DL(7,3)) { - mcs=7; - } else if (pcch_sdu_length <= get_TBS_DL(8,3)) { - mcs=8; - } else if (pcch_sdu_length <= get_TBS_DL(9,3)) { - mcs=9; - } + vrb_map[first_rb] = 1; + vrb_map[first_rb+1] = 1; + vrb_map[first_rb+2] = 1; + vrb_map[first_rb+3] = 1; + /* Get MCS for length of PCH */ + if (pcch_sdu_length <= get_TBS_DL(0,3)) { + mcs=0; + } else if (pcch_sdu_length <= get_TBS_DL(1,3)) { + mcs=1; + } else if (pcch_sdu_length <= get_TBS_DL(2,3)) { + mcs=2; + } else if (pcch_sdu_length <= get_TBS_DL(3,3)) { + mcs=3; + } else if (pcch_sdu_length <= get_TBS_DL(4,3)) { + mcs=4; + } else if (pcch_sdu_length <= get_TBS_DL(5,3)) { + mcs=5; + } else if (pcch_sdu_length <= get_TBS_DL(6,3)) { + mcs=6; + } else if (pcch_sdu_length <= get_TBS_DL(7,3)) { + mcs=7; + } else if (pcch_sdu_length <= get_TBS_DL(8,3)) { + mcs=8; + } else if (pcch_sdu_length <= get_TBS_DL(9,3)) { + mcs=9; + } #endif - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); #ifdef FORMAT1C - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1C; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.ngap = n_gap; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1C; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.ngap = n_gap; #else - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_rb_dl,first_rb,4); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_rb_dl,first_rb,4); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; #endif - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFE; // P-RNTI - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // P-RNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFE; // P-RNTI + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // P-RNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; - // Rel10 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; - // Rel13 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; + // Rel10 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; + // Rel13 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; - if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, P_RNTI)) { - LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for P_RNTI\n", frameP,subframeP); - dl_req->number_dci++; - dl_req->number_pdu++; - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu)); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFE; + if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, P_RNTI)) { + LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for P_RNTI\n", frameP,subframeP); + dl_req->number_dci++; + dl_req->number_pdu++; + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFE; #ifdef FORMAT1C - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 3; // format 1C - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 3; // format 1C + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step); #else - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_rb_dl,first_rb,4); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_rb_dl,first_rb,4); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized #endif - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB==1 ) ? 0 : 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB==1 ) ? 1 : 2; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; - dl_req->number_pdu++; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB==1 ) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB==1 ) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; + dl_req->number_pdu++; - eNB->TX_req[CC_id].sfn_sf = (frameP<<4)+subframeP; - TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; - TX_req->pdu_length = pcch_sdu_length; - TX_req->pdu_index = eNB->pdu_index[CC_id]++; - TX_req->num_segments = 1; - TX_req->segments[0].segment_length = pcch_sdu_length; - TX_req->segments[0].segment_data = cc[CC_id].PCCH_pdu.payload; - eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; - } else { - LOG_E(MAC,"[eNB %d] CCid %d Frame %d, subframe %d : Cannot add DCI 1A/1C for Paging\n",module_idP, CC_id, frameP, subframeP); - continue; + eNB->TX_req[CC_id].sfn_sf = (frameP<<4)+subframeP; + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; + TX_req->pdu_length = pcch_sdu_length; + TX_req->pdu_index = eNB->pdu_index[CC_id]++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = pcch_sdu_length; + TX_req->segments[0].segment_data = cc[CC_id].PCCH_pdu.payload; + eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; + } else { + LOG_E(MAC,"[eNB %d] CCid %d Frame %d, subframe %d : Cannot add DCI 1A/1C for Paging\n",module_idP, CC_id, frameP, subframeP); + continue; + } + + if (opt_enabled == 1) { + trace_pdu(1, + &eNB->common_channels[CC_id].PCCH_pdu.payload[0], + pcch_sdu_length, + 0xffff, + PCCH, + P_RNTI, + eNB->frame, + eNB->subframe, + 0, + 0); + LOG_D(OPT,"[eNB %d][PCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", + module_idP, frameP, CC_id, 0xffff, pcch_sdu_length); + } + eNB->eNB_stats[CC_id].total_num_pcch_pdu+=1; + eNB->eNB_stats[CC_id].pcch_buffer=pcch_sdu_length; + eNB->eNB_stats[CC_id].total_pcch_buffer+=pcch_sdu_length; + eNB->eNB_stats[CC_id].pcch_mcs=mcs; + //paging first_rb log + LOG_D(MAC,"[eNB %d] Frame %d subframe %d PCH: paging_ue_index %d pcch_sdu_length %d mcs %d first_rb %d\n", + module_idP, frameP, subframeP, UE_PF_PO[CC_id][i].ue_index_value, pcch_sdu_length, mcs, first_rb); + + pthread_mutex_lock(&ue_pf_po_mutex); + memset(&UE_PF_PO[CC_id][i], 0, sizeof(UE_PF_PO_t)); + pthread_mutex_unlock(&ue_pf_po_mutex); } - - if (opt_enabled == 1) { - trace_pdu(1, - &eNB->common_channels[CC_id].PCCH_pdu.payload[0], - pcch_sdu_length, - 0xffff, - PCCH, - P_RNTI, - eNB->frame, - eNB->subframe, - 0, - 0); - LOG_D(OPT,"[eNB %d][PCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", - module_idP, frameP, CC_id, 0xffff, pcch_sdu_length); - } - eNB->eNB_stats[CC_id].total_num_pcch_pdu+=1; - eNB->eNB_stats[CC_id].pcch_buffer=pcch_sdu_length; - eNB->eNB_stats[CC_id].total_pcch_buffer+=pcch_sdu_length; - eNB->eNB_stats[CC_id].pcch_mcs=mcs; - //paging first_rb log - LOG_D(MAC,"[eNB %d] Frame %d subframe %d PCH: paging_ue_index %d pcch_sdu_length %d mcs %d first_rb %d\n", - module_idP, frameP, subframeP, UE_PF_PO[CC_id][i].ue_index_value, pcch_sdu_length, mcs, first_rb); - - pthread_mutex_lock(&ue_pf_po_mutex); - memset(&UE_PF_PO[CC_id][i], 0, sizeof(UE_PF_PO_t)); - pthread_mutex_unlock(&ue_pf_po_mutex); - } } } /* this might be misleading when pcch is inactive */ diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index f841d9d55a..5cdd9d8771 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -72,9 +72,9 @@ extern uint8_t nfapi_mode; // This table holds the allowable PRB sizes for ULSCH transmissions uint8_t rb_table[34] = - { 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, + { 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80, 81, 90, 96, 100 -}; + }; void rx_sdu(const module_id_t enb_mod_idP, @@ -86,746 +86,625 @@ rx_sdu(const module_id_t enb_mod_idP, const uint16_t sdu_lenP, const uint16_t timing_advance, const uint8_t ul_cqi) { - int current_rnti = rntiP; - unsigned char rx_ces[MAX_NUM_CE], num_ce, num_sdu, i, *payload_ptr; - unsigned char rx_lcids[NB_RB_MAX]; - unsigned short rx_lengths[NB_RB_MAX]; - int UE_id = find_UE_id(enb_mod_idP, current_rnti); - int RA_id; - int ii, j; - eNB_MAC_INST *mac = RC.mac[enb_mod_idP]; - int harq_pid = - subframe2harqpid(&mac->common_channels[CC_idP], frameP, subframeP); + int current_rnti = rntiP; + unsigned char rx_ces[MAX_NUM_CE], num_ce, num_sdu, i, *payload_ptr; + unsigned char rx_lcids[NB_RB_MAX]; + unsigned short rx_lengths[NB_RB_MAX]; + int UE_id = find_UE_id(enb_mod_idP, current_rnti); + int RA_id; + int ii, j; + eNB_MAC_INST *mac = RC.mac[enb_mod_idP]; + int harq_pid = + subframe2harqpid(&mac->common_channels[CC_idP], frameP, subframeP); - UE_list_t *UE_list = &mac->UE_list; - int crnti_rx = 0; - int old_buffer_info; - RA_t *ra = - (RA_t *) & RC.mac[enb_mod_idP]->common_channels[CC_idP].ra[0]; - int first_rb = 0; + UE_list_t *UE_list = &mac->UE_list; + int crnti_rx = 0; + int old_buffer_info; + RA_t *ra = + (RA_t *) & RC.mac[enb_mod_idP]->common_channels[CC_idP].ra[0]; + int first_rb = 0; - start_meas(&mac->rx_ulsch_sdu); + start_meas(&mac->rx_ulsch_sdu); - if ((UE_id > NUMBER_OF_UE_MAX) || (UE_id == -1)) - for (ii = 0; ii < NB_RB_MAX; ii++) { - rx_lengths[ii] = 0; - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 1); - if (opt_enabled == 1) { - trace_pdu(0, sduP, sdu_lenP, 0, 3, current_rnti, frameP, subframeP, - 0, 0); - LOG_D(OPT, "[eNB %d][ULSCH] Frame %d rnti %x with size %d\n", - enb_mod_idP, frameP, current_rnti, sdu_lenP); + if ((UE_id > NUMBER_OF_UE_MAX) || (UE_id == -1)) + for (ii = 0; ii < NB_RB_MAX; ii++) { + rx_lengths[ii] = 0; } - if (UE_id != -1) { - LOG_D(MAC, - "[eNB %d][PUSCH %d] CC_id %d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n", - enb_mod_idP, harq_pid, CC_idP, - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid], - current_rnti, UE_id, ul_cqi); - - AssertFatal(UE_list->UE_sched_ctrl[UE_id]. - round_UL[CC_idP][harq_pid] < 8, "round >= 8\n"); - if (sduP != NULL) { - UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= - (~(1 << harq_pid)); - /* Update with smoothing: 3/4 of old value and 1/4 of new. - * This is the logic that was done in the function - * lte_est_timing_advance_pusch, maybe it's not necessary? - * maybe it's even not correct at all? - */ - UE_list->UE_sched_ctrl[UE_id].ta_update = - (UE_list->UE_sched_ctrl[UE_id].ta_update * 3 + - timing_advance) / 4; - UE_list->UE_sched_ctrl[UE_id].pusch_snr[CC_idP] = ul_cqi; - UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors = 0; - first_rb = - UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid]; - - if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0; - mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, - subframeP, UE_RNTI(enb_mod_idP, - UE_id)); - } - } else { // we've got an error - LOG_D(MAC, - "[eNB %d][PUSCH %d] CC_id %d ULSCH in error in round %d, ul_cqi %d\n", - enb_mod_idP, harq_pid, CC_idP, - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid], - ul_cqi); - - // AssertFatal(1==0,"ulsch in error\n"); - if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] == - 3) { - UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= - (~(1 << harq_pid)); - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = - 0; - if (UE_list->UE_sched_ctrl[UE_id]. - ul_consecutive_errors++ == 10) - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 1; - } else - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]++; - return; - - } - } else if ((RA_id = find_RA_id(enb_mod_idP, CC_idP, current_rnti)) != -1) { // Check if this is an RA process for the rnti - AssertFatal(mac->common_channels[CC_idP]. - radioResourceConfigCommon->rach_ConfigCommon. - maxHARQ_Msg3Tx > 1, - "maxHARQ %d should be greater than 1\n", - (int) mac->common_channels[CC_idP]. - radioResourceConfigCommon->rach_ConfigCommon. - maxHARQ_Msg3Tx); - - LOG_D(MAC, - "[eNB %d][PUSCH %d] CC_id %d [RAPROC Msg3] Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n", - enb_mod_idP, harq_pid, CC_idP, ra[RA_id].msg3_round, - current_rnti, RA_id, ul_cqi); - - first_rb = ra->msg3_first_rb; - - if (sduP == NULL) { // we've got an error on Msg3 - LOG_D(MAC, - "[eNB %d] CC_id %d, RA %d ULSCH in error in round %d/%d\n", - enb_mod_idP, CC_idP, RA_id, - ra[RA_id].msg3_round, - (int) mac->common_channels[CC_idP]. - radioResourceConfigCommon->rach_ConfigCommon. - maxHARQ_Msg3Tx); - if (ra[RA_id].msg3_round == - mac->common_channels[CC_idP].radioResourceConfigCommon-> - rach_ConfigCommon.maxHARQ_Msg3Tx - 1) { - cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); - } - - else { - first_rb = - UE_list->UE_template[CC_idP][UE_id]. - first_rb_ul[harq_pid]; - ra[RA_id].msg3_round++; - // prepare handling of retransmission - ra[RA_id].Msg3_frame = (ra[RA_id].Msg3_frame + ((ra[RA_id].Msg3_subframe > 1) ? 1 : 0)) % 1024; - ra[RA_id].Msg3_subframe = (ra[RA_id].Msg3_subframe + 8) % 10; - add_msg3(enb_mod_idP, CC_idP, &ra[RA_id], frameP, - subframeP); - } - return; - } - } else { - LOG_W(MAC, - "Cannot find UE or RA corresponding to ULSCH rnti %x, dropping it\n", - current_rnti); - return; - } - payload_ptr = - parse_ulsch_header(sduP, &num_ce, &num_sdu, rx_ces, rx_lcids, - rx_lengths, sdu_lenP); - - T(T_ENB_MAC_UE_UL_PDU, T_INT(enb_mod_idP), T_INT(CC_idP), - T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), - T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu)); - T(T_ENB_MAC_UE_UL_PDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), - T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), - T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu), - T_BUFFER(sduP, sdu_lenP)); - - mac->eNB_stats[CC_idP].ulsch_bytes_rx = sdu_lenP; - mac->eNB_stats[CC_idP].total_ulsch_bytes_rx += sdu_lenP; - mac->eNB_stats[CC_idP].total_ulsch_pdus_rx += 1; - - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0; - - // control element - for (i = 0; i < num_ce; i++) { - - T(T_ENB_MAC_UE_UL_CE, T_INT(enb_mod_idP), T_INT(CC_idP), - T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), - T_INT(rx_ces[i])); - - switch (rx_ces[i]) { // implement and process BSR + CRNTI + - case POWER_HEADROOM: - if (UE_id != -1) { - UE_list->UE_template[CC_idP][UE_id].phr_info = - (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET; - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d : Received PHR PH = %d (db)\n", - enb_mod_idP, CC_idP, rx_ces[i], - UE_list->UE_template[CC_idP][UE_id].phr_info); - UE_list->UE_template[CC_idP][UE_id].phr_info_configured = - 1; - UE_list->UE_sched_ctrl[UE_id].phr_received = 1; - } - payload_ptr += sizeof(POWER_HEADROOM_CMD); - break; - - case CRNTI: - { - int old_rnti = - (((uint16_t) payload_ptr[0]) << 8) + payload_ptr[1]; - int old_UE_id = find_UE_id(enb_mod_idP, old_rnti); - LOG_D(MAC, - "[eNB %d] Frame %d, Subframe %d CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n", - enb_mod_idP, frameP, subframeP, CC_idP, rx_ces[i], i, - num_ce, old_rnti, old_UE_id); - /* receiving CRNTI means that the current rnti has to go away */ - cancel_ra_proc(enb_mod_idP, CC_idP, frameP, - current_rnti); - if (old_UE_id != -1) { - /* TODO: if the UE did random access (followed by a MAC uplink with - * CRNTI) because none of its scheduling request was granted, then - * according to 36.321 5.4.4 the UE's MAC will notify RRC to release - * PUCCH/SRS. According to 36.331 5.3.13 the UE will then apply - * default configuration for CQI reporting and scheduling requests, - * which basically means that the CQI requests won't work anymore and - * that the UE won't do any scheduling request anymore as long as the - * eNB doesn't reconfigure the UE. - * We have to take care of this. As the code is, nothing is done and - * the UE state in the eNB is wrong. - */ - UE_id = old_UE_id; - UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; - if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0; - mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, - subframeP, old_rnti); - } - current_rnti = old_rnti; - } - crnti_rx = 1; - payload_ptr += 2; - break; - } - - case TRUNCATED_BSR: - case SHORT_BSR: - { - uint8_t lcgid; - lcgid = (payload_ptr[0] >> 6); - - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", - enb_mod_idP, CC_idP, rx_ces[i], lcgid, - payload_ptr[0] & 0x3f); - - if (crnti_rx == 1) - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", - enb_mod_idP, CC_idP, rx_ces[i], lcgid, - payload_ptr[0] & 0x3f); - if (UE_id != -1) { - - UE_list->UE_template[CC_idP][UE_id].bsr_info[lcgid] = - (payload_ptr[0] & 0x3f); - - // update buffer info - - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[lcgid] = - BSR_TABLE[UE_list->UE_template[CC_idP][UE_id]. - bsr_info[lcgid]]; - - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[lcgid]; - - RC.eNB[enb_mod_idP][CC_idP]-> - pusch_stats_bsr[UE_id][(frameP * 10) + subframeP] - = (payload_ptr[0] & 0x3f); - if (UE_id == UE_list->head) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME - (VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, - RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr - [UE_id][(frameP * 10) + subframeP]); - if (UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[lcgid] - == 0) { - UE_list->UE_template[CC_idP] - [UE_id].ul_buffer_creation_time[lcgid] = - frameP; - } - if (mac_eNB_get_rrc_status - (enb_mod_idP, - UE_RNTI(enb_mod_idP, UE_id)) < RRC_CONNECTED) - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d : ul_total_buffer = %d (lcg increment %d)\n", - enb_mod_idP, CC_idP, rx_ces[i], - UE_list->UE_template[CC_idP][UE_id]. - ul_total_buffer, - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[lcgid]); - } else { - - } - payload_ptr += 1; //sizeof(SHORT_BSR); // fixme - } - break; - - case LONG_BSR: - if (UE_id != -1) { - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] = - ((payload_ptr[0] & 0xFC) >> 2); - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] = - ((payload_ptr[0] & 0x03) << 4) | - ((payload_ptr[1] & 0xF0) >> 4); - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] = - ((payload_ptr[1] & 0x0F) << 2) | - ((payload_ptr[2] & 0xC0) >> 6); - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] = - (payload_ptr[2] & 0x3F); - - // update buffer info - old_buffer_info = - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID0]; - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID0] = - BSR_TABLE[UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID0]]; - - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer += - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID0]; - if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= - old_buffer_info) - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= - old_buffer_info; - else - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = - 0; - - old_buffer_info = - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID1]; - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID1] = - BSR_TABLE[UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID1]]; - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer += - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID1]; - if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= - old_buffer_info) - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= - old_buffer_info; - else - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = - 0; - - old_buffer_info = - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID2]; - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID2] = - BSR_TABLE[UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID2]]; - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer += - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID2]; - if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= - old_buffer_info) - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= - old_buffer_info; - else - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = - 0; - - old_buffer_info = - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID3]; - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID3] = - BSR_TABLE[UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID3]]; - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer += - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID3]; - if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= - old_buffer_info) - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= - old_buffer_info; - else - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = - 0; - - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = " - "%u LCGID2 = %u LCGID3 = %u\n", enb_mod_idP, CC_idP, - rx_ces[i], - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0], - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1], - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2], - UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID3]); - if (crnti_rx == 1) - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = " - "%u LCGID2 = %u LCGID3 = %u\n", enb_mod_idP, - CC_idP, rx_ces[i], - UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID0], - UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID1], - UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID2], - UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID3]); - - if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] == - 0) { - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[LCGID0] = 0; - } else if (UE_list->UE_template[CC_idP] - [UE_id].ul_buffer_creation_time[LCGID0] == 0) { - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[LCGID0] = frameP; - } - - if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] == - 0) { - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[LCGID1] = 0; - } else if (UE_list->UE_template[CC_idP] - [UE_id].ul_buffer_creation_time[LCGID1] == 0) { - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[LCGID1] = frameP; - } - - if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] == - 0) { - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[LCGID2] = 0; - } else if (UE_list->UE_template[CC_idP] - [UE_id].ul_buffer_creation_time[LCGID2] == 0) { - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[LCGID2] = frameP; - } - - if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] == - 0) { - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[LCGID3] = 0; - } else if (UE_list->UE_template[CC_idP] - [UE_id].ul_buffer_creation_time[LCGID3] == 0) { - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_creation_time[LCGID3] = frameP; - - } - } - - payload_ptr += 3; ////sizeof(LONG_BSR); - break; - - default: - LOG_E(MAC, - "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", - enb_mod_idP, CC_idP, rx_ces[i]); - break; - } - } - - for (i = 0; i < num_sdu; i++) { - LOG_D(MAC, "SDU Number %d MAC Subheader SDU_LCID %d, length %d\n", - i, rx_lcids[i], rx_lengths[i]); - - T(T_ENB_MAC_UE_UL_SDU, T_INT(enb_mod_idP), T_INT(CC_idP), - T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), - T_INT(rx_lcids[i]), T_INT(rx_lengths[i])); - T(T_ENB_MAC_UE_UL_SDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), - T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), - T_INT(rx_lcids[i]), T_INT(rx_lengths[i]), T_BUFFER(payload_ptr, - rx_lengths - [i])); - - switch (rx_lcids[i]) { - case CCCH: - if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) { - LOG_E(MAC, - "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d, sdu_len %d), dropping packet\n", - enb_mod_idP, CC_idP, frameP, rx_lengths[i], - CCCH_PAYLOAD_SIZE_MAX, sdu_lenP); - break; - } - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH: %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n", - enb_mod_idP, CC_idP, frameP, payload_ptr[0], - payload_ptr[1], payload_ptr[2], payload_ptr[3], - payload_ptr[4], payload_ptr[5], current_rnti); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 1); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 0); - for (ii = 0; ii < NB_RA_PROC_MAX; ii++) { - RA_t *ra = &mac->common_channels[CC_idP].ra[ii]; - - LOG_D(MAC, - "[mac %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), state %d\n", - enb_mod_idP, CC_idP, ii, ra->rnti, - current_rnti, ra->state); - - if ((ra->rnti == current_rnti) && (ra->state != IDLE)) { - - //payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len); - - if (UE_id < 0) { - memcpy(&ra->cont_res_id[0], payload_ptr, 6); - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %ld\n", - enb_mod_idP, CC_idP, frameP, rx_lengths[i], - payload_ptr - sduP); - - if ((UE_id = - add_new_ue(enb_mod_idP, CC_idP, - mac->common_channels[CC_idP]. - ra[ii].rnti, harq_pid -#ifdef Rel14 - , - mac->common_channels[CC_idP]. - ra[ii].rach_resource_type -#endif - )) == -1) { - AssertFatal(1 == 0, - "[MAC][eNB] Max user count reached\n"); - // kill RA procedure - } else - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n", - enb_mod_idP, CC_idP, frameP, ra->rnti, - UE_id); - } else { - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n", - enb_mod_idP, CC_idP, frameP, UE_id, - rx_lengths[i], payload_ptr - sduP); - // kill RA procedure - } - - mac_rrc_data_ind(enb_mod_idP, - CC_idP, - frameP, subframeP, - current_rnti, - CCCH, - (uint8_t *) payload_ptr, - rx_lengths[i], - 0); - - - if (num_ce > 0) { // handle msg3 which is not RRCConnectionRequest - // process_ra_message(msg3,num_ce,rx_lcids,rx_ces); - } - // prepare transmission of Msg4 - ra->state = MSG4; - - - - // Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, // Check if this is ok for BL/CE, or if the rule is different - ra->Msg4_frame = frameP + ((subframeP > 5) ? 1 : 0); - ra->Msg4_subframe = (subframeP + 4) % 10; - - } // if process is active - } // loop on RA processes - - break; - - case DCCH: - case DCCH1: - // if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){ - - -#if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_T(MAC, "offset: %d\n", - (unsigned char) ((unsigned char *) payload_ptr - sduP)); - for (j = 0; j < 32; j++) { - LOG_T(MAC, "%x ", payload_ptr[j]); - } - LOG_T(MAC, "\n"); -#endif - - if (UE_id != -1) { - // adjust buffer occupancy of the correponding logical channel group - if (UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[UE_list->UE_template[CC_idP] - [UE_id].lcgidmap[rx_lcids[i]]] >= - rx_lengths[i]) - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[UE_list->UE_template[CC_idP] - [UE_id].lcgidmap[rx_lcids[i]]] -= - rx_lengths[i]; - else - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[UE_list->UE_template[CC_idP] - [UE_id].lcgidmap[rx_lcids[i]]] = 0; - - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DCCH, received %d bytes form UE %d on LCID %d \n", - enb_mod_idP, CC_idP, frameP, rx_lengths[i], UE_id, - rx_lcids[i]); - - mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); //(unsigned int*)crc_status); - UE_list->eNB_UE_stats[CC_idP][UE_id]. - num_pdu_rx[rx_lcids[i]] += 1; - UE_list->eNB_UE_stats[CC_idP][UE_id]. - num_bytes_rx[rx_lcids[i]] - += rx_lengths[i]; - - - } - - /* UE_id != -1 */ - // } - break; - - // all the DRBS - case DTCH: - default: - -#if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_T(MAC, "offset: %d\n", - (unsigned char) ((unsigned char *) payload_ptr - sduP)); - for (j = 0; j < 32; j++) { - LOG_T(MAC, "%x ", payload_ptr[j]); - } - LOG_T(MAC, "\n"); -#endif - if (rx_lcids[i] < NB_RB_MAX) { - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n", - enb_mod_idP, CC_idP, frameP, rx_lengths[i], UE_id, - rx_lcids[i]); - - if (UE_id != -1) { - // adjust buffer occupancy of the correponding logical channel group - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d, removing from LCGID %ld, %d\n", - enb_mod_idP, CC_idP, frameP, rx_lengths[i], - UE_id, rx_lcids[i], - UE_list->UE_template[CC_idP][UE_id]. - lcgidmap[rx_lcids[i]], - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[UE_list->UE_template[CC_idP] - [UE_id].lcgidmap[rx_lcids[i]]]); - - if (UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[UE_list->UE_template[CC_idP] - [UE_id].lcgidmap[rx_lcids[i]]] - >= rx_lengths[i]) - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[UE_list->UE_template[CC_idP] - [UE_id].lcgidmap[rx_lcids[i]]] - -= rx_lengths[i]; - else - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info - [UE_list->UE_template[CC_idP][UE_id].lcgidmap - [rx_lcids[i]]] = 0; - if ((rx_lengths[i] < SCH_PAYLOAD_SIZE_MAX) - && (rx_lengths[i] > 0)) { // MAX SIZE OF transport block - mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); //(unsigned int*)crc_status); - - UE_list->eNB_UE_stats[CC_idP][UE_id]. - num_pdu_rx[rx_lcids[i]] += 1; - UE_list->eNB_UE_stats[CC_idP][UE_id]. - num_bytes_rx[rx_lcids[i]] += rx_lengths[i]; - //clear uplane_inactivity_timer - UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; - } else { /* rx_length[i] */ - UE_list->eNB_UE_stats[CC_idP][UE_id]. - num_errors_rx += 1; - LOG_E(MAC, - "[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ", - enb_mod_idP, CC_idP, frameP, rx_lcids[i], - UE_id); - } - } else { /*(UE_id != -1 */ - LOG_E(MAC, - "[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ", - enb_mod_idP, CC_idP, frameP, rx_lcids[i], UE_id); - } - } - - break; - } - - payload_ptr += rx_lengths[i]; - } - - // Program ACK for PHICH + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 1); + if (opt_enabled == 1) { + trace_pdu(0, sduP, sdu_lenP, 0, 3, current_rnti, frameP, subframeP, + 0, 0); + LOG_D(OPT, "[eNB %d][ULSCH] Frame %d rnti %x with size %d\n", + enb_mod_idP, frameP, current_rnti, sdu_lenP); + } + + if (UE_id != -1) { LOG_D(MAC, - "Programming PHICH ACK 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 = 1; - 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; + "[eNB %d][PUSCH %d] CC_id %d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n", + enb_mod_idP, harq_pid, CC_idP, + UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid], + current_rnti, UE_id, ul_cqi); - /* NN--> FK: we could either check the payload, or use a phy helper to detect a false msg3 */ - if ((num_sdu == 0) && (num_ce == 0)) { - if (UE_id != -1) - UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx += 1; - /* - if (msg3_flagP != NULL) { - if( *msg3_flagP == 1 ) { - LOG_N(MAC,"[eNB %d] CC_id %d frame %d : false msg3 detection: signal phy to canceling RA and remove the UE\n", enb_mod_idP, CC_idP, frameP); - *msg3_flagP=0; - } - } */ - } else { - if (UE_id != -1) { - UE_list->eNB_UE_stats[CC_idP][UE_id].pdu_bytes_rx = sdu_lenP; - UE_list->eNB_UE_stats[CC_idP][UE_id].total_pdu_bytes_rx += - sdu_lenP; - UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_pdus_rx += 1; + AssertFatal(UE_list->UE_sched_ctrl[UE_id]. + round_UL[CC_idP][harq_pid] < 8, "round >= 8\n"); + if (sduP != NULL) { + UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0; + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; + UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= (~(1 << harq_pid)); + /* Update with smoothing: 3/4 of old value and 1/4 of new. + * This is the logic that was done in the function + * lte_est_timing_advance_pusch, maybe it's not necessary? + * maybe it's even not correct at all? + */ + UE_list->UE_sched_ctrl[UE_id].ta_update = (UE_list->UE_sched_ctrl[UE_id].ta_update * 3 + timing_advance) / 4; + UE_list->UE_sched_ctrl[UE_id].pusch_snr[CC_idP] = ul_cqi; + UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors = 0; + first_rb = UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid]; + + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { + UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0; + mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, + subframeP, UE_RNTI(enb_mod_idP, + UE_id)); + } + } else { // we've got an error + LOG_D(MAC, + "[eNB %d][PUSCH %d] CC_id %d ULSCH in error in round %d, ul_cqi %d\n", + enb_mod_idP, harq_pid, CC_idP, + UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid], + ul_cqi); + + // AssertFatal(1==0,"ulsch in error\n"); + if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] == 3) { + UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= (~(1 << harq_pid)); + UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0; + if (UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors++ == 10) + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 1; + } else + UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]++; + return; + + } + } else if ((RA_id = find_RA_id(enb_mod_idP, CC_idP, current_rnti)) != -1) { // Check if this is an RA process for the rnti + AssertFatal(mac->common_channels[CC_idP]. + radioResourceConfigCommon->rach_ConfigCommon. + maxHARQ_Msg3Tx > 1, + "maxHARQ %d should be greater than 1\n", + (int) mac->common_channels[CC_idP]. + radioResourceConfigCommon->rach_ConfigCommon. + maxHARQ_Msg3Tx); + + LOG_D(MAC, + "[eNB %d][PUSCH %d] CC_id %d [RAPROC Msg3] Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n", + enb_mod_idP, harq_pid, CC_idP, ra[RA_id].msg3_round, + current_rnti, RA_id, ul_cqi); + + first_rb = ra->msg3_first_rb; + + if (sduP == NULL) { // we've got an error on Msg3 + LOG_D(MAC, + "[eNB %d] CC_id %d, RA %d ULSCH in error in round %d/%d\n", + enb_mod_idP, CC_idP, RA_id, + ra[RA_id].msg3_round, + (int) mac->common_channels[CC_idP]. + radioResourceConfigCommon->rach_ConfigCommon. + maxHARQ_Msg3Tx); + if (ra[RA_id].msg3_round == mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx - 1) { + cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); + } + + else { + first_rb = UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid]; + ra[RA_id].msg3_round++; + // prepare handling of retransmission + ra[RA_id].Msg3_frame = (ra[RA_id].Msg3_frame + ((ra[RA_id].Msg3_subframe > 1) ? 1 : 0)) % 1024; + ra[RA_id].Msg3_subframe = (ra[RA_id].Msg3_subframe + 8) % 10; + add_msg3(enb_mod_idP, CC_idP, &ra[RA_id], frameP, subframeP); + } + return; + } + } else { + LOG_W(MAC, + "Cannot find UE or RA corresponding to ULSCH rnti %x, dropping it\n", + current_rnti); + return; + } + payload_ptr = parse_ulsch_header(sduP, &num_ce, &num_sdu, rx_ces, rx_lcids, rx_lengths, sdu_lenP); + + T(T_ENB_MAC_UE_UL_PDU, T_INT(enb_mod_idP), T_INT(CC_idP), + T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), + T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu)); + T(T_ENB_MAC_UE_UL_PDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), + T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), + T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu), + T_BUFFER(sduP, sdu_lenP)); + + mac->eNB_stats[CC_idP].ulsch_bytes_rx = sdu_lenP; + mac->eNB_stats[CC_idP].total_ulsch_bytes_rx += sdu_lenP; + mac->eNB_stats[CC_idP].total_ulsch_pdus_rx += 1; + + UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0; + + // control element + for (i = 0; i < num_ce; i++) { + + T(T_ENB_MAC_UE_UL_CE, T_INT(enb_mod_idP), T_INT(CC_idP), + T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), + T_INT(rx_ces[i])); + + switch (rx_ces[i]) { // implement and process BSR + CRNTI + + case POWER_HEADROOM: + if (UE_id != -1) { + UE_list->UE_template[CC_idP][UE_id].phr_info = + (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET; + LOG_D(MAC, + "[eNB %d] CC_id %d MAC CE_LCID %d : Received PHR PH = %d (db)\n", + enb_mod_idP, CC_idP, rx_ces[i], + UE_list->UE_template[CC_idP][UE_id].phr_info); + UE_list->UE_template[CC_idP][UE_id].phr_info_configured = + 1; + UE_list->UE_sched_ctrl[UE_id].phr_received = 1; + } + payload_ptr += sizeof(POWER_HEADROOM_CMD); + break; + + case CRNTI: + { + int old_rnti = + (((uint16_t) payload_ptr[0]) << 8) + payload_ptr[1]; + int old_UE_id = find_UE_id(enb_mod_idP, old_rnti); + LOG_D(MAC, + "[eNB %d] Frame %d, Subframe %d CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n", + enb_mod_idP, frameP, subframeP, CC_idP, rx_ces[i], i, + num_ce, old_rnti, old_UE_id); + /* receiving CRNTI means that the current rnti has to go away */ + cancel_ra_proc(enb_mod_idP, CC_idP, frameP, + current_rnti); + if (old_UE_id != -1) { + /* TODO: if the UE did random access (followed by a MAC uplink with + * CRNTI) because none of its scheduling request was granted, then + * according to 36.321 5.4.4 the UE's MAC will notify RRC to release + * PUCCH/SRS. According to 36.331 5.3.13 the UE will then apply + * default configuration for CQI reporting and scheduling requests, + * which basically means that the CQI requests won't work anymore and + * that the UE won't do any scheduling request anymore as long as the + * eNB doesn't reconfigure the UE. + * We have to take care of this. As the code is, nothing is done and + * the UE state in the eNB is wrong. + */ + UE_id = old_UE_id; + UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0; + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { + UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0; + mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, + subframeP, old_rnti); + } + current_rnti = old_rnti; } + crnti_rx = 1; + payload_ptr += 2; + break; + } + + case TRUNCATED_BSR: + case SHORT_BSR: + { + uint8_t lcgid; + lcgid = (payload_ptr[0] >> 6); + + LOG_D(MAC, + "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", + enb_mod_idP, CC_idP, rx_ces[i], lcgid, + payload_ptr[0] & 0x3f); + + if (crnti_rx == 1) + LOG_D(MAC, + "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", + enb_mod_idP, CC_idP, rx_ces[i], lcgid, + payload_ptr[0] & 0x3f); + if (UE_id != -1) { + + UE_list->UE_template[CC_idP][UE_id].bsr_info[lcgid] = (payload_ptr[0] & 0x3f); + + // update buffer info + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid] = BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[lcgid]]; + + UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid]; + + RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP * 10) + subframeP] = (payload_ptr[0] & 0x3f); + if (UE_id == UE_list->head) + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, + RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr + [UE_id][(frameP * 10) + subframeP]); + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] = frameP; + } + if (mac_eNB_get_rrc_status(enb_mod_idP,UE_RNTI(enb_mod_idP, UE_id)) < RRC_CONNECTED) + LOG_D(MAC, + "[eNB %d] CC_id %d MAC CE_LCID %d : ul_total_buffer = %d (lcg increment %d)\n", + enb_mod_idP, CC_idP, rx_ces[i], + UE_list->UE_template[CC_idP][UE_id]. + ul_total_buffer, + UE_list->UE_template[CC_idP][UE_id]. + ul_buffer_info[lcgid]); + } else { + + } + payload_ptr += 1; //sizeof(SHORT_BSR); // fixme + } + break; + + case LONG_BSR: + if (UE_id != -1) { + UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] = ((payload_ptr[0] & 0xFC) >> 2); + UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] = ((payload_ptr[0] & 0x03) << 4) | ((payload_ptr[1] & 0xF0) >> 4); + UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] = ((payload_ptr[1] & 0x0F) << 2) | ((payload_ptr[2] & 0xC0) >> 6); + UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] = (payload_ptr[2] & 0x3F); + + // update buffer info + old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0]; + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] = BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0]]; + + UE_list->UE_template[CC_idP][UE_id].ul_total_buffer += UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0]; + if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info) + UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info; + else + UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0; + + old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1]; + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] = BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1]]; + UE_list->UE_template[CC_idP][UE_id].ul_total_buffer += UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1]; + if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info) UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= + old_buffer_info; + else + UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0; + + old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2]; + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] = BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2]]; + UE_list->UE_template[CC_idP][UE_id].ul_total_buffer += UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2]; + if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info) + UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info; + else + UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0; + + old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]; + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3] = BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3]]; + UE_list->UE_template[CC_idP][UE_id].ul_total_buffer += UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]; + if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info) + UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info; + else + UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0; + + LOG_D(MAC, + "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = " + "%u LCGID2 = %u LCGID3 = %u\n", enb_mod_idP, CC_idP, + rx_ces[i], + UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0], + UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1], + UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2], + UE_list->UE_template[CC_idP][UE_id]. + bsr_info[LCGID3]); + if (crnti_rx == 1) + LOG_D(MAC, + "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = " + "%u LCGID2 = %u LCGID3 = %u\n", enb_mod_idP, + CC_idP, rx_ces[i], + UE_list->UE_template[CC_idP][UE_id]. + bsr_info[LCGID0], + UE_list->UE_template[CC_idP][UE_id]. + bsr_info[LCGID1], + UE_list->UE_template[CC_idP][UE_id]. + bsr_info[LCGID2], + UE_list->UE_template[CC_idP][UE_id]. + bsr_info[LCGID3]); + + if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] = 0; + } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] = frameP; + } + + if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] = 0; + } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] = frameP; + } + + if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] = 0; + } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] = frameP; + } + + if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] = 0; + } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] = frameP; + + } + } + + payload_ptr += 3; ////sizeof(LONG_BSR); + break; + + default: + LOG_E(MAC, + "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", + enb_mod_idP, CC_idP, rx_ces[i]); + break; + } + } + + for (i = 0; i < num_sdu; i++) { + LOG_D(MAC, "SDU Number %d MAC Subheader SDU_LCID %d, length %d\n", + i, rx_lcids[i], rx_lengths[i]); + + T(T_ENB_MAC_UE_UL_SDU, T_INT(enb_mod_idP), T_INT(CC_idP), + T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), + T_INT(rx_lcids[i]), T_INT(rx_lengths[i])); + T(T_ENB_MAC_UE_UL_SDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), + T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), + T_INT(rx_lcids[i]), T_INT(rx_lengths[i]), T_BUFFER(payload_ptr, + rx_lengths + [i])); + + switch (rx_lcids[i]) { + case CCCH: + if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) { + LOG_E(MAC, + "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d, sdu_len %d), dropping packet\n", + enb_mod_idP, CC_idP, frameP, rx_lengths[i], + CCCH_PAYLOAD_SIZE_MAX, sdu_lenP); + break; + } + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH: %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n", + enb_mod_idP, CC_idP, frameP, payload_ptr[0], + payload_ptr[1], payload_ptr[2], payload_ptr[3], + payload_ptr[4], payload_ptr[5], current_rnti); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 1); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 0); + for (ii = 0; ii < NB_RA_PROC_MAX; ii++) { + RA_t *ra = &mac->common_channels[CC_idP].ra[ii]; + + LOG_D(MAC, + "[mac %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), state %d\n", + enb_mod_idP, CC_idP, ii, ra->rnti, + current_rnti, ra->state); + + if ((ra->rnti == current_rnti) && (ra->state != IDLE)) { + + //payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len); + + if (UE_id < 0) { + memcpy(&ra->cont_res_id[0], payload_ptr, 6); + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %ld\n", + enb_mod_idP, CC_idP, frameP, rx_lengths[i], + payload_ptr - sduP); + + if ((UE_id = add_new_ue(enb_mod_idP, CC_idP, + mac->common_channels[CC_idP]. + ra[ii].rnti, harq_pid +#ifdef Rel14 + , + mac->common_channels[CC_idP]. + ra[ii].rach_resource_type +#endif + )) == -1) { + AssertFatal(1 == 0, + "[MAC][eNB] Max user count reached\n"); + // kill RA procedure + } else + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n", + enb_mod_idP, CC_idP, frameP, ra->rnti, + UE_id); + } else { + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n", + enb_mod_idP, CC_idP, frameP, UE_id, + rx_lengths[i], payload_ptr - sduP); + // kill RA procedure + } + + mac_rrc_data_ind(enb_mod_idP, + CC_idP, + frameP, subframeP, + current_rnti, + CCCH, + (uint8_t *) payload_ptr, + rx_lengths[i], + 0); + + + if (num_ce > 0) { // handle msg3 which is not RRCConnectionRequest + // process_ra_message(msg3,num_ce,rx_lcids,rx_ces); + } + // prepare transmission of Msg4 + ra->state = MSG4; + + + + // Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, // Check if this is ok for BL/CE, or if the rule is different + ra->Msg4_frame = frameP + ((subframeP > 5) ? 1 : 0); + ra->Msg4_subframe = (subframeP + 4) % 10; + + } // if process is active + } // loop on RA processes + + break; + + case DCCH: + case DCCH1: + // if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){ + + +#if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_T(MAC, "offset: %d\n", + (unsigned char) ((unsigned char *) payload_ptr - sduP)); + for (j = 0; j < 32; j++) { + LOG_T(MAC, "%x ", payload_ptr[j]); + } + LOG_T(MAC, "\n"); +#endif + + if (UE_id != -1) { + // adjust buffer occupancy of the correponding logical channel group + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; + else + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0; + + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DCCH, received %d bytes form UE %d on LCID %d \n", + enb_mod_idP, CC_idP, frameP, rx_lengths[i], UE_id, + rx_lcids[i]); + + mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); //(unsigned int*)crc_status); + UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1; + UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i]; + + + } + + /* UE_id != -1 */ + // } + break; + + // all the DRBS + case DTCH: + default: + +#if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_T(MAC, "offset: %d\n", + (unsigned char) ((unsigned char *) payload_ptr - sduP)); + for (j = 0; j < 32; j++) { + LOG_T(MAC, "%x ", payload_ptr[j]); + } + LOG_T(MAC, "\n"); +#endif + if (rx_lcids[i] < NB_RB_MAX) { + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n", + enb_mod_idP, CC_idP, frameP, rx_lengths[i], UE_id, + rx_lcids[i]); + + if (UE_id != -1) { + // adjust buffer occupancy of the correponding logical channel group + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d, removing from LCGID %ld, %d\n", + enb_mod_idP, CC_idP, frameP, rx_lengths[i], + UE_id, rx_lcids[i], + UE_list->UE_template[CC_idP][UE_id]. + lcgidmap[rx_lcids[i]], + UE_list->UE_template[CC_idP][UE_id]. + ul_buffer_info[UE_list->UE_template[CC_idP] + [UE_id].lcgidmap[rx_lcids[i]]]); + + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; + else + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0; + if ((rx_lengths[i] < SCH_PAYLOAD_SIZE_MAX) && (rx_lengths[i] > 0)) { // MAX SIZE OF transport block + mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); //(unsigned int*)crc_status); + + UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1; + UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i]; + //clear uplane_inactivity_timer + UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; + } else { /* rx_length[i] */ + UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1; + LOG_E(MAC, + "[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ", + enb_mod_idP, CC_idP, frameP, rx_lcids[i], + UE_id); + } + } else { /*(UE_id != -1 */ + LOG_E(MAC, + "[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ", + enb_mod_idP, CC_idP, frameP, rx_lcids[i], UE_id); + } + } + + break; } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 0); - stop_meas(&mac->rx_ulsch_sdu); + payload_ptr += rx_lengths[i]; + } + + // Program ACK for PHICH + LOG_D(MAC, + "Programming PHICH ACK 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 = 1; + 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; + + /* NN--> FK: we could either check the payload, or use a phy helper to detect a false msg3 */ + if ((num_sdu == 0) && (num_ce == 0)) { + if (UE_id != -1) + UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx += 1; + /* + if (msg3_flagP != NULL) { + if( *msg3_flagP == 1 ) { + LOG_N(MAC,"[eNB %d] CC_id %d frame %d : false msg3 detection: signal phy to canceling RA and remove the UE\n", enb_mod_idP, CC_idP, frameP); + *msg3_flagP=0; + } + } */ + } else { + if (UE_id != -1) { + UE_list->eNB_UE_stats[CC_idP][UE_id].pdu_bytes_rx = sdu_lenP; + UE_list->eNB_UE_stats[CC_idP][UE_id].total_pdu_bytes_rx += sdu_lenP; + UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_pdus_rx += 1; + } + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 0); + stop_meas(&mac->rx_ulsch_sdu); } uint32_t bytes_to_bsr_index(int32_t nbytes) { - uint32_t i = 0; + uint32_t i = 0; - if (nbytes < 0) { - return (0); - } + if (nbytes < 0) { + return (0); + } - while ((i < BSR_TABLE_SIZE) && (BSR_TABLE[i] <= nbytes)) { - i++; - } + while ((i < BSR_TABLE_SIZE) && (BSR_TABLE[i] <= nbytes)) { + i++; + } - return (i - 1); + return (i - 1); } void add_ue_ulsch_info(module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframeP, UE_ULSCH_STATUS status) { - eNB_ulsch_info[module_idP][CC_id][UE_id].rnti = - UE_RNTI(module_idP, UE_id); - eNB_ulsch_info[module_idP][CC_id][UE_id].subframe = subframeP; - eNB_ulsch_info[module_idP][CC_id][UE_id].status = status; + eNB_ulsch_info[module_idP][CC_id][UE_id].rnti = UE_RNTI(module_idP, UE_id); + eNB_ulsch_info[module_idP][CC_id][UE_id].subframe = subframeP; + eNB_ulsch_info[module_idP][CC_id][UE_id].status = status; - eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++; + eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++; } unsigned char *parse_ulsch_header(unsigned char *mac_header, @@ -836,77 +715,76 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header, unsigned short *rx_lengths, unsigned short tb_length) { - unsigned char not_done = 1, num_ces = 0, num_sdus = - 0, lcid, num_sdu_cnt; - unsigned char *mac_header_ptr = mac_header; - unsigned short length, ce_len = 0; + unsigned char not_done = 1, num_ces = 0, num_sdus = + 0, lcid, num_sdu_cnt; + unsigned char *mac_header_ptr = mac_header; + unsigned short length, ce_len = 0; - while (not_done == 1) { + while (not_done == 1) { - if (((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E == 0) { - not_done = 0; - } - - lcid = ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID; - - if (lcid < EXTENDED_POWER_HEADROOM) { - if (not_done == 0) { // last MAC SDU, length is implicit - mac_header_ptr++; - length = - tb_length - (mac_header_ptr - mac_header) - ce_len; - - for (num_sdu_cnt = 0; num_sdu_cnt < num_sdus; - num_sdu_cnt++) { - length -= rx_lengths[num_sdu_cnt]; - } - } else { - if (((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F == 0) { - length = ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L; - mac_header_ptr += 2; //sizeof(SCH_SUBHEADER_SHORT); - } else { // F = 1 - length = - ((((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB & - 0x7f) << 8) | (((SCH_SUBHEADER_LONG *) - mac_header_ptr)->L_LSB & 0xff); - mac_header_ptr += 3; //sizeof(SCH_SUBHEADER_LONG); - } - } - - LOG_D(MAC, - "[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n", - num_sdus, lcid, tb_length, length, - mac_header_ptr - mac_header); - rx_lcids[num_sdus] = lcid; - rx_lengths[num_sdus] = length; - num_sdus++; - } else { // This is a control element subheader POWER_HEADROOM, BSR and CRNTI - if (lcid == SHORT_PADDING) { - mac_header_ptr++; - } else { - rx_ces[num_ces] = lcid; - num_ces++; - mac_header_ptr++; - - if (lcid == LONG_BSR) { - ce_len += 3; - } else if (lcid == CRNTI) { - ce_len += 2; - } else if ((lcid == POWER_HEADROOM) - || (lcid == TRUNCATED_BSR) - || (lcid == SHORT_BSR)) { - ce_len++; - } else { - LOG_E(MAC, "unknown CE %d \n", lcid); - AssertFatal(1 == 0, "unknown CE"); - } - } - } + if (((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E == 0) { + not_done = 0; } - *num_ce = num_ces; - *num_sdu = num_sdus; + lcid = ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID; - return (mac_header_ptr); + if (lcid < EXTENDED_POWER_HEADROOM) { + if (not_done == 0) { // last MAC SDU, length is implicit + mac_header_ptr++; + length = tb_length - (mac_header_ptr - mac_header) - ce_len; + + for (num_sdu_cnt = 0; num_sdu_cnt < num_sdus; + num_sdu_cnt++) { + length -= rx_lengths[num_sdu_cnt]; + } + } else { + if (((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F == 0) { + length = ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L; + mac_header_ptr += 2; //sizeof(SCH_SUBHEADER_SHORT); + } else { // F = 1 + length = + ((((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB & + 0x7f) << 8) | (((SCH_SUBHEADER_LONG *) + mac_header_ptr)->L_LSB & 0xff); + mac_header_ptr += 3; //sizeof(SCH_SUBHEADER_LONG); + } + } + + LOG_D(MAC, + "[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n", + num_sdus, lcid, tb_length, length, + mac_header_ptr - mac_header); + rx_lcids[num_sdus] = lcid; + rx_lengths[num_sdus] = length; + num_sdus++; + } else { // This is a control element subheader POWER_HEADROOM, BSR and CRNTI + if (lcid == SHORT_PADDING) { + mac_header_ptr++; + } else { + rx_ces[num_ces] = lcid; + num_ces++; + mac_header_ptr++; + + if (lcid == LONG_BSR) { + ce_len += 3; + } else if (lcid == CRNTI) { + ce_len += 2; + } else if ((lcid == POWER_HEADROOM) + || (lcid == TRUNCATED_BSR) + || (lcid == SHORT_BSR)) { + ce_len++; + } else { + LOG_E(MAC, "unknown CE %d \n", lcid); + AssertFatal(1 == 0, "unknown CE"); + } + } + } + } + + *num_ce = num_ces; + *num_sdu = num_sdus; + + return (mac_header_ptr); } /* This function is called by PHY layer when it schedules some @@ -921,16 +799,16 @@ set_msg3_subframe(module_id_t Mod_id, int subframe, int rnti, int Msg3_frame, int Msg3_subframe) { - eNB_MAC_INST *mac = RC.mac[Mod_id]; - int i; - for (i = 0; i < NB_RA_PROC_MAX; i++) { - if (mac->common_channels[CC_id].ra[i].state != IDLE && - mac->common_channels[CC_id].ra[i].rnti == rnti) { - mac->common_channels[CC_id].ra[i].Msg3_subframe = - Msg3_subframe; - break; - } + eNB_MAC_INST *mac = RC.mac[Mod_id]; + int i; + for (i = 0; i < NB_RA_PROC_MAX; i++) { + if (mac->common_channels[CC_id].ra[i].state != IDLE && + mac->common_channels[CC_id].ra[i].rnti == rnti) { + mac->common_channels[CC_id].ra[i].Msg3_subframe = + Msg3_subframe; + break; } + } } @@ -938,118 +816,118 @@ void schedule_ulsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { - uint16_t first_rb[MAX_NUM_CCs], i; - int CC_id; - eNB_MAC_INST *mac = RC.mac[module_idP]; - COMMON_channels_t *cc; + uint16_t first_rb[MAX_NUM_CCs], i; + int CC_id; + eNB_MAC_INST *mac = RC.mac[module_idP]; + COMMON_channels_t *cc; - start_meas(&mac->schedule_ulsch); + start_meas(&mac->schedule_ulsch); - int sched_subframe = (subframeP + 4) % 10; + int sched_subframe = (subframeP + 4) % 10; - cc = &mac->common_channels[0]; - int tdd_sfa; - // for TDD: check subframes where we have to act and return if nothing should be done now - if (cc->tdd_Config) { - tdd_sfa = cc->tdd_Config->subframeAssignment; - switch (subframeP) { - case 0: - if ((tdd_sfa == 0) || (tdd_sfa == 3) || (tdd_sfa == 6)) - sched_subframe = 4; - else - return; - break; - case 1: - if ((tdd_sfa == 0) || (tdd_sfa == 1)) - sched_subframe = 7; - else if (tdd_sfa == 6) - sched_subframe = 8; - break; - default: - return; + cc = &mac->common_channels[0]; + int tdd_sfa; + // for TDD: check subframes where we have to act and return if nothing should be done now + if (cc->tdd_Config) { + tdd_sfa = cc->tdd_Config->subframeAssignment; + switch (subframeP) { + case 0: + if ((tdd_sfa == 0) || (tdd_sfa == 3) || (tdd_sfa == 6)) + sched_subframe = 4; + else + return; + break; + case 1: + if ((tdd_sfa == 0) || (tdd_sfa == 1)) + sched_subframe = 7; + else if (tdd_sfa == 6) + sched_subframe = 8; + break; + default: + return; - case 2: // Don't schedule UL in subframe 2 for TDD - return; - case 3: - if (tdd_sfa == 2) - sched_subframe = 7; - else - return; - break; - case 4: - if (tdd_sfa == 1) - sched_subframe = 8; - else - return; - break; - case 5: - if (tdd_sfa == 0) - sched_subframe = 9; - else if (tdd_sfa == 6) - sched_subframe = 3; - else - return; - break; - case 6: - if (tdd_sfa == 1) - sched_subframe = 2; - else if (tdd_sfa == 6) - sched_subframe = 3; - else - return; - break; - case 7: - return; - case 8: - if ((tdd_sfa >= 2) || (tdd_sfa <= 5)) - sched_subframe = 2; - else - return; - break; - case 9: - if ((tdd_sfa == 1) || (tdd_sfa == 3) || (tdd_sfa == 4)) - sched_subframe = 3; - else if (tdd_sfa == 6) - sched_subframe = 4; - else - return; - break; - } + case 2: // Don't schedule UL in subframe 2 for TDD + return; + case 3: + if (tdd_sfa == 2) + sched_subframe = 7; + else + return; + break; + case 4: + if (tdd_sfa == 1) + sched_subframe = 8; + else + return; + break; + case 5: + if (tdd_sfa == 0) + sched_subframe = 9; + else if (tdd_sfa == 6) + sched_subframe = 3; + else + return; + break; + case 6: + if (tdd_sfa == 1) + sched_subframe = 2; + else if (tdd_sfa == 6) + sched_subframe = 3; + else + return; + break; + case 7: + return; + case 8: + if ((tdd_sfa >= 2) || (tdd_sfa <= 5)) + sched_subframe = 2; + else + return; + break; + case 9: + if ((tdd_sfa == 1) || (tdd_sfa == 3) || (tdd_sfa == 4)) + sched_subframe = 3; + else if (tdd_sfa == 6) + sched_subframe = 4; + else + return; + break; } - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + } + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - //leave out first RB for PUCCH - first_rb[CC_id] = 1; + //leave out first RB for PUCCH + first_rb[CC_id] = 1; - // UE data info; - // check which UE has data to transmit - // function to decide the scheduling - // e.g. scheduling_rslt = Greedy(granted_UEs, nb_RB) + // UE data info; + // check which UE has data to transmit + // function to decide the scheduling + // e.g. scheduling_rslt = Greedy(granted_UEs, nb_RB) - // default function for default scheduling - // + // default function for default scheduling + // - // output of scheduling, the UE numbers in RBs, where it is in the code??? - // check if RA (Msg3) is active in this subframeP, if so skip the PRBs used for Msg3 - // Msg3 is using 1 PRB so we need to increase first_rb accordingly - // not sure about the break (can there be more than 1 active RA procedure?) + // output of scheduling, the UE numbers in RBs, where it is in the code??? + // check if RA (Msg3) is active in this subframeP, if so skip the PRBs used for Msg3 + // Msg3 is using 1 PRB so we need to increase first_rb accordingly + // not sure about the break (can there be more than 1 active RA procedure?) - for (i = 0; i < NB_RA_PROC_MAX; i++) { - if ((cc->ra[i].state == WAITMSG3) && - (cc->ra[i].Msg3_subframe == sched_subframe)) { - first_rb[CC_id]++; - // cc->ray[i].Msg3_subframe = -1; - break; - } - } + for (i = 0; i < NB_RA_PROC_MAX; i++) { + if ((cc->ra[i].state == WAITMSG3) && + (cc->ra[i].Msg3_subframe == sched_subframe)) { + first_rb[CC_id]++; + // cc->ray[i].Msg3_subframe = -1; + break; + } } + } - schedule_ulsch_rnti(module_idP, frameP, subframeP, sched_subframe, - first_rb); + schedule_ulsch_rnti(module_idP, frameP, subframeP, sched_subframe, + first_rb); - stop_meas(&mac->schedule_ulsch); + stop_meas(&mac->schedule_ulsch); } void @@ -1058,501 +936,467 @@ schedule_ulsch_rnti(module_id_t module_idP, sub_frame_t subframeP, unsigned char sched_subframeP, uint16_t * first_rb) { - int UE_id; - uint8_t aggregation = 2; - rnti_t rnti = -1; - uint8_t round = 0; - uint8_t harq_pid = 0; - uint8_t status = 0; - uint8_t rb_table_index = -1; - uint32_t cqi_req, cshift, ndi, tpc; - int32_t normalized_rx_power; - int32_t target_rx_power = -90; - static int32_t tpc_accumulated = 0; - int n; - int CC_id = 0; - int drop_ue = 0; - int N_RB_UL; - eNB_MAC_INST *mac = RC.mac[module_idP]; - COMMON_channels_t *cc = mac->common_channels; - UE_list_t *UE_list = &mac->UE_list; - UE_TEMPLATE *UE_template; - UE_sched_ctrl *UE_sched_ctrl; - int sched_frame = frameP; - int rvidx_tab[4] = { 0, 2, 3, 1 }; + int UE_id; + uint8_t aggregation = 2; + rnti_t rnti = -1; + uint8_t round = 0; + uint8_t harq_pid = 0; + uint8_t status = 0; + uint8_t rb_table_index = -1; + uint32_t cqi_req, cshift, ndi, tpc; + int32_t normalized_rx_power; + int32_t target_rx_power = -90; + static int32_t tpc_accumulated = 0; + int n; + int CC_id = 0; + int drop_ue = 0; + int N_RB_UL; + eNB_MAC_INST *mac = RC.mac[module_idP]; + COMMON_channels_t *cc = mac->common_channels; + UE_list_t *UE_list = &mac->UE_list; + UE_TEMPLATE *UE_template; + UE_sched_ctrl *UE_sched_ctrl; + int sched_frame = frameP; + int rvidx_tab[4] = { 0, 2, 3, 1 }; - if (sched_subframeP < subframeP) - sched_frame++; + if (sched_subframeP < subframeP) + sched_frame++; - nfapi_hi_dci0_request_t *hi_dci0_req = &mac->HI_DCI0_req[CC_id]; - 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; + nfapi_hi_dci0_request_t *hi_dci0_req = &mac->HI_DCI0_req[CC_id]; + 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; - nfapi_ul_config_request_t *ul_req_tmp = &mac->UL_req_tmp[CC_id][sched_subframeP]; - nfapi_ul_config_request_body_t *ul_req_tmp_body = &ul_req_tmp->ul_config_request_body; + nfapi_ul_config_request_t *ul_req_tmp = &mac->UL_req_tmp[CC_id][sched_subframeP]; + nfapi_ul_config_request_body_t *ul_req_tmp_body = &ul_req_tmp->ul_config_request_body; - //LOG_D(MAC, "entering ulsch preprocesor\n"); - ulsch_scheduler_pre_processor(module_idP, frameP, subframeP, first_rb); + //LOG_D(MAC, "entering ulsch preprocesor\n"); + ulsch_scheduler_pre_processor(module_idP, frameP, subframeP, first_rb); - //LOG_D(MAC, "exiting ulsch preprocesor\n"); + //LOG_D(MAC, "exiting ulsch preprocesor\n"); - hi_dci0_req->sfn_sf = (frameP << 4) + subframeP; + hi_dci0_req->sfn_sf = (frameP << 4) + subframeP; - // loop over all active UEs - for (UE_id = UE_list->head_ul; UE_id >= 0; - UE_id = UE_list->next_ul[UE_id]) { + // loop over all active UEs + for (UE_id = UE_list->head_ul; UE_id >= 0; + UE_id = UE_list->next_ul[UE_id]) { - // don't schedule if Msg4 is not received yet - if (UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id]. - configured == FALSE) { - LOG_D(MAC, - "[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n", - module_idP, frameP, subframeP, UE_id); - continue; - } + // don't schedule if Msg4 is not received yet + if (UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id]. + configured == FALSE) { + LOG_D(MAC, + "[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n", + module_idP, frameP, subframeP, UE_id); + continue; + } - rnti = UE_RNTI(module_idP, UE_id); + rnti = UE_RNTI(module_idP, UE_id); - if (rnti == NOT_A_RNTI) { - LOG_W(MAC, "[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n", - module_idP, frameP, subframeP, UE_id); - continue; - } + if (rnti == NOT_A_RNTI) { + LOG_W(MAC, "[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n", + module_idP, frameP, subframeP, UE_id); + continue; + } - drop_ue = 0; - /* let's drop the UE if get_eNB_UE_stats returns NULL when calling it with any of the UE's active UL CCs */ - /* TODO: refine? + drop_ue = 0; + /* let's drop the UE if get_eNB_UE_stats returns NULL when calling it with any of the UE's active UL CCs */ + /* TODO: refine? - for (n=0; nnumactiveULCCs[UE_id]; n++) { - CC_id = UE_list->ordered_ULCCids[n][UE_id]; + for (n=0; nnumactiveULCCs[UE_id]; n++) { + CC_id = UE_list->ordered_ULCCids[n][UE_id]; - if (mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti) == NULL) { - LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: no PHY context\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id); - drop_ue = 1; - break; - } - } */ - if (drop_ue == 1) { -/* we can't come here, ulsch_scheduler_pre_processor won't put in the list a UE with no PHY context */ - abort(); - /* TODO: this is a hack. Sometimes the UE has no PHY context but - * is still present in the MAC with 'ul_failure_timer' = 0 and - * 'ul_out_of_sync' = 0. It seems wrong and the UE stays there forever. Let's - * start an UL out of sync procedure in this case. - * The root cause of this problem has to be found and corrected. - * In the meantime, this hack... - */ - if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 0 && - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0) { - LOG_W(MAC, - "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: UE in weird state, let's put it 'out of sync'\n", - module_idP, frameP, subframeP, UE_id, rnti, CC_id); - // inform RRC of failure and clear timer - mac_eNB_rrc_ul_failure(module_idP, CC_id, frameP, - subframeP, rnti); - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 1; + if (mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti) == NULL) { + LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: no PHY context\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id); + drop_ue = 1; + break; + } + } */ + if (drop_ue == 1) { + /* we can't come here, ulsch_scheduler_pre_processor won't put in the list a UE with no PHY context */ + abort(); + /* TODO: this is a hack. Sometimes the UE has no PHY context but + * is still present in the MAC with 'ul_failure_timer' = 0 and + * 'ul_out_of_sync' = 0. It seems wrong and the UE stays there forever. Let's + * start an UL out of sync procedure in this case. + * The root cause of this problem has to be found and corrected. + * In the meantime, this hack... + */ + if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 0 && + UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0) { + LOG_W(MAC, + "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: UE in weird state, let's put it 'out of sync'\n", + module_idP, frameP, subframeP, UE_id, rnti, CC_id); + // inform RRC of failure and clear timer + mac_eNB_rrc_ul_failure(module_idP, CC_id, frameP, + subframeP, rnti); + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; + UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 1; + } + continue; + } + // loop over all active UL CC_ids for this UE + for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { + // This is the actual CC_id in the list + CC_id = UE_list->ordered_ULCCids[n][UE_id]; + N_RB_UL = to_prb(cc[CC_id].ul_Bandwidth); + + /* + aggregation=get_aggregation(get_bw_index(module_idP,CC_id), + eNB_UE_stats->dl_cqi, + format0); + */ + + if (CCE_allocation_infeasible + (module_idP, CC_id, 1, subframeP, aggregation, rnti)) { + LOG_W(MAC, + "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: not enough nCCE\n", + module_idP, frameP, subframeP, UE_id, rnti, CC_id); + continue; // break; + } + + /* be sure that there are some free RBs */ + if (first_rb[CC_id] >= N_RB_UL - 1) { + LOG_W(MAC, + "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n", + module_idP, frameP, subframeP, UE_id, rnti, CC_id); + continue; + } + // if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel + + UE_template = &UE_list->UE_template[CC_id][UE_id]; + UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id]; + harq_pid = subframe2harqpid(&cc[CC_id], sched_frame, sched_subframeP); + round = UE_sched_ctrl->round_UL[CC_id][harq_pid]; + AssertFatal(round < 8, "round %d > 7 for UE %d/%x\n", round, + UE_id, rnti); + LOG_D(MAC, + "[eNB %d] frame %d subframe %d (sched_frame %d, sched_subframe %d), Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n", + module_idP, frameP, subframeP, sched_frame, sched_subframeP, harq_pid, UE_id, rnti, + CC_id, aggregation, N_RB_UL); + + RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * + 10) + + subframeP] = + UE_template->ul_total_buffer; + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO,RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * + 10) + + subframeP]); + if (UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0 || round > 0) // || ((frameP%10)==0)) + // if there is information on bsr of DCCH, DTCH or if there is UL_SR, or if there is a packet to retransmit, or we want to schedule a periodic feedback every 10 frames + { + LOG_D(MAC, + "[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n", + module_idP, harq_pid, frameP, subframeP, UE_id, rnti, + round, UE_template->ul_SR, + UE_sched_ctrl->ul_inactivity_timer, + UE_sched_ctrl->ul_failure_timer, + UE_sched_ctrl->cqi_req_timer); + // reset the scheduling request + UE_template->ul_SR = 0; + status = mac_eNB_get_rrc_status(module_idP, rnti); + if (status < RRC_CONNECTED) + cqi_req = 0; + else if (UE_sched_ctrl->cqi_req_timer > 30) { + if (nfapi_mode) { + cqi_req = 0; + } else { + cqi_req = 1; } - continue; - } - // loop over all active UL CC_ids for this UE - for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { - // This is the actual CC_id in the list - CC_id = UE_list->ordered_ULCCids[n][UE_id]; - N_RB_UL = to_prb(cc[CC_id].ul_Bandwidth); + UE_sched_ctrl->cqi_req_timer = 0; + } else + cqi_req = 0; - /* - aggregation=get_aggregation(get_bw_index(module_idP,CC_id), - eNB_UE_stats->dl_cqi, - format0); - */ + //power control + //compute the expected ULSCH RX power (for the stats) - if (CCE_allocation_infeasible - (module_idP, CC_id, 1, subframeP, aggregation, rnti)) { - LOG_W(MAC, - "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: not enough nCCE\n", - module_idP, frameP, subframeP, UE_id, rnti, CC_id); - continue; // break; - } + // this is the normalized RX power and this should be constant (regardless of mcs + normalized_rx_power = UE_sched_ctrl->pusch_snr[CC_id]; + target_rx_power = 178; - /* be sure that there are some free RBs */ - if (first_rb[CC_id] >= N_RB_UL - 1) { - LOG_W(MAC, - "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n", - module_idP, frameP, subframeP, UE_id, rnti, CC_id); - continue; - } - // if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel - - UE_template = &UE_list->UE_template[CC_id][UE_id]; - UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id]; - harq_pid = - subframe2harqpid(&cc[CC_id], sched_frame, sched_subframeP); - round = UE_sched_ctrl->round_UL[CC_id][harq_pid]; - AssertFatal(round < 8, "round %d > 7 for UE %d/%x\n", round, - UE_id, rnti); - LOG_D(MAC, - "[eNB %d] frame %d subframe %d (sched_frame %d, sched_subframe %d), Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n", - module_idP, frameP, subframeP, sched_frame, sched_subframeP, harq_pid, UE_id, rnti, - CC_id, aggregation, N_RB_UL); - - RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * - 10) + - subframeP] = - UE_template->ul_total_buffer; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME - (VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO, - RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * - 10) + - subframeP]); - if (UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0 || round > 0) // || ((frameP%10)==0)) - // if there is information on bsr of DCCH, DTCH or if there is UL_SR, or if there is a packet to retransmit, or we want to schedule a periodic feedback every 10 frames + // this assumes accumulated tpc + // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out + int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame * 10 + UE_template->pusch_tpc_tx_subframe; + if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || //normal case + ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) //frame wrap-around { - LOG_D(MAC, - "[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n", - module_idP, harq_pid, frameP, subframeP, UE_id, rnti, - round, UE_template->ul_SR, - UE_sched_ctrl->ul_inactivity_timer, - UE_sched_ctrl->ul_failure_timer, - UE_sched_ctrl->cqi_req_timer); - // reset the scheduling request - UE_template->ul_SR = 0; - status = mac_eNB_get_rrc_status(module_idP, rnti); - if (status < RRC_CONNECTED) - cqi_req = 0; - else if (UE_sched_ctrl->cqi_req_timer > 30) { - if (nfapi_mode) { - cqi_req = 0; - } else { - cqi_req = 1; - } - UE_sched_ctrl->cqi_req_timer = 0; - } else - cqi_req = 0; + UE_template->pusch_tpc_tx_frame = frameP; + UE_template->pusch_tpc_tx_subframe = subframeP; + if (normalized_rx_power > (target_rx_power + 4)) { + tpc = 0; //-1 + tpc_accumulated--; + } else if (normalized_rx_power < (target_rx_power - 4)) { + tpc = 2; //+1 + tpc_accumulated++; + } else { + tpc = 1; //0 + } + } else { + tpc = 1; //0 + } + //tpc = 1; + if (tpc != 1) { + LOG_D(MAC, + "[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", + module_idP, frameP, subframeP, harq_pid, tpc, + tpc_accumulated, normalized_rx_power, + target_rx_power); + } + // new transmission + if (round == 0) { - //power control - //compute the expected ULSCH RX power (for the stats) + ndi = 1 - UE_template->oldNDI_UL[harq_pid]; + UE_template->oldNDI_UL[harq_pid] = ndi; + UE_list->eNB_UE_stats[CC_id][UE_id]. + normalized_rx_power = normalized_rx_power; + UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power = target_rx_power; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1 = UE_template->pre_assigned_mcs_ul; + UE_template->mcs_UL[harq_pid] = UE_template->pre_assigned_mcs_ul; //cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS + if (UE_template->pre_allocated_rb_table_index_ul >= 0) { + rb_table_index = + UE_template->pre_allocated_rb_table_index_ul; + } else { + UE_template->mcs_UL[harq_pid] = 10; //cmin (10, openair_daq_vars.target_ue_ul_mcs); + rb_table_index = 5; // for PHR + } - // this is the normalized RX power and this should be constant (regardless of mcs - normalized_rx_power = UE_sched_ctrl->pusch_snr[CC_id]; - target_rx_power = 178; - - // this assumes accumulated tpc - // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out - int32_t framex10psubframe = - UE_template->pusch_tpc_tx_frame * 10 + - UE_template->pusch_tpc_tx_subframe; - if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || //normal case - ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) //frame wrap-around - { - UE_template->pusch_tpc_tx_frame = frameP; - UE_template->pusch_tpc_tx_subframe = subframeP; - if (normalized_rx_power > (target_rx_power + 4)) { - tpc = 0; //-1 - tpc_accumulated--; - } else if (normalized_rx_power < (target_rx_power - 4)) { - tpc = 2; //+1 - tpc_accumulated++; - } else { - tpc = 1; //0 - } - } else { - tpc = 1; //0 - } - //tpc = 1; - if (tpc != 1) { - LOG_D(MAC, - "[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", - module_idP, frameP, subframeP, harq_pid, tpc, - tpc_accumulated, normalized_rx_power, - target_rx_power); - } - // new transmission - if (round == 0) { - - ndi = 1 - UE_template->oldNDI_UL[harq_pid]; - UE_template->oldNDI_UL[harq_pid] = ndi; - UE_list->eNB_UE_stats[CC_id][UE_id]. - normalized_rx_power = normalized_rx_power; - UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power = - target_rx_power; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1 = - UE_template->pre_assigned_mcs_ul; - UE_template->mcs_UL[harq_pid] = UE_template->pre_assigned_mcs_ul; //cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS - if (UE_template->pre_allocated_rb_table_index_ul >= 0) { - rb_table_index = - UE_template->pre_allocated_rb_table_index_ul; - } else { - UE_template->mcs_UL[harq_pid] = 10; //cmin (10, openair_daq_vars.target_ue_ul_mcs); - rb_table_index = 5; // for PHR - } - - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = - UE_template->mcs_UL[harq_pid]; - // buffer_occupancy = UE_template->ul_total_buffer; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = UE_template->mcs_UL[harq_pid]; + // buffer_occupancy = UE_template->ul_total_buffer; - while (((rb_table[rb_table_index] > - (N_RB_UL - 1 - first_rb[CC_id])) - || (rb_table[rb_table_index] > 45)) - && (rb_table_index > 0)) { - rb_table_index--; - } + while (((rb_table[rb_table_index] > + (N_RB_UL - 1 - first_rb[CC_id])) + || (rb_table[rb_table_index] > 45)) + && (rb_table_index > 0)) { + rb_table_index--; + } - UE_template->TBS_UL[harq_pid] = - get_TBS_UL(UE_template->mcs_UL[harq_pid], - rb_table[rb_table_index]); - UE_list->eNB_UE_stats[CC_id][UE_id]. - total_rbs_used_rx += rb_table[rb_table_index]; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = - UE_template->TBS_UL[harq_pid]; - // buffer_occupancy -= TBS; + UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid], + rb_table[rb_table_index]); + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += rb_table[rb_table_index]; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = UE_template->TBS_UL[harq_pid]; + // buffer_occupancy -= TBS; - T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), - T_INT(UE_template->mcs_UL[harq_pid]), - T_INT(first_rb[CC_id]), - T_INT(rb_table[rb_table_index]), - T_INT(UE_template->TBS_UL[harq_pid]), T_INT(ndi)); + T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP), + T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), + T_INT(UE_template->mcs_UL[harq_pid]), + T_INT(first_rb[CC_id]), + T_INT(rb_table[rb_table_index]), + T_INT(UE_template->TBS_UL[harq_pid]), T_INT(ndi)); - if (mac_eNB_get_rrc_status(module_idP, rnti) < - RRC_CONNECTED) - LOG_D(MAC, - "[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n", - module_idP, harq_pid, rnti, CC_id, frameP, - subframeP, UE_id, - UE_template->mcs_UL[harq_pid], - first_rb[CC_id], rb_table[rb_table_index], - rb_table_index, - UE_template->TBS_UL[harq_pid], harq_pid); + if (mac_eNB_get_rrc_status(module_idP, rnti) < RRC_CONNECTED) + LOG_D(MAC, + "[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n", + module_idP, harq_pid, rnti, CC_id, frameP, + subframeP, UE_id, + UE_template->mcs_UL[harq_pid], + first_rb[CC_id], rb_table[rb_table_index], + rb_table_index, + UE_template->TBS_UL[harq_pid], harq_pid); - // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB) - //store for possible retransmission - UE_template->nb_rb_ul[harq_pid] = - rb_table[rb_table_index]; - UE_template->first_rb_ul[harq_pid] = first_rb[CC_id]; + // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB) + //store for possible retransmission + UE_template->nb_rb_ul[harq_pid] = rb_table[rb_table_index]; + UE_template->first_rb_ul[harq_pid] = first_rb[CC_id]; - UE_sched_ctrl->ul_scheduled |= (1 << harq_pid); - if (UE_id == UE_list->head) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME - (VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED, - UE_sched_ctrl->ul_scheduled); + UE_sched_ctrl->ul_scheduled |= (1 << harq_pid); + if (UE_id == UE_list->head) + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED, + UE_sched_ctrl->ul_scheduled); - // adjust total UL buffer status by TBS, wait for UL sdus to do final update - LOG_D(MAC, - "[eNB %d] CC_id %d UE %d/%x : adjusting ul_total_buffer, old %d, TBS %d\n", - module_idP, CC_id, UE_id, rnti, - UE_template->ul_total_buffer, - UE_template->TBS_UL[harq_pid]); - if (UE_template->ul_total_buffer > - UE_template->TBS_UL[harq_pid]) - UE_template->ul_total_buffer -= - UE_template->TBS_UL[harq_pid]; - else - UE_template->ul_total_buffer = 0; - LOG_D(MAC, "ul_total_buffer, new %d\n", - UE_template->ul_total_buffer); - // Cyclic shift for DM RS - cshift = 0; // values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1) - // save it for a potential retransmission - UE_template->cshift[harq_pid] = cshift; + // adjust total UL buffer status by TBS, wait for UL sdus to do final update + LOG_D(MAC, + "[eNB %d] CC_id %d UE %d/%x : adjusting ul_total_buffer, old %d, TBS %d\n", + module_idP, CC_id, UE_id, rnti, + UE_template->ul_total_buffer, + UE_template->TBS_UL[harq_pid]); + if (UE_template->ul_total_buffer > UE_template->TBS_UL[harq_pid]) + UE_template->ul_total_buffer -= UE_template->TBS_UL[harq_pid]; + else + UE_template->ul_total_buffer = 0; + LOG_D(MAC, "ul_total_buffer, new %d\n", + UE_template->ul_total_buffer); + // Cyclic shift for DM RS + cshift = 0; // values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1) + // save it for a potential retransmission + UE_template->cshift[harq_pid] = cshift; - 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_DCI_PDU_TYPE; - hi_dci0_pdu->pdu_size = - 2 + sizeof(nfapi_hi_dci0_dci_pdu); - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = - NFAPI_UL_DCI_FORMAT_0; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = - aggregation; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = - 6000; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8. - resource_block_start = first_rb[CC_id]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8. - number_of_resource_block = - rb_table[rb_table_index]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = - UE_template->mcs_UL[harq_pid]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8. - cyclic_shift_2_for_drms = cshift; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8. - frequency_hopping_enabled_flag = 0; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8. - new_data_indication_1 = ndi; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request = - cqi_req; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = - UE_template->DAI_ul[sched_subframeP]; + 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_DCI_PDU_TYPE; + hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_dci_pdu); + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = NFAPI_UL_DCI_FORMAT_0; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = 6000; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start = first_rb[CC_id]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.number_of_resource_block = rb_table[rb_table_index]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = UE_template->mcs_UL[harq_pid]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = cshift; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag = 0; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.new_data_indication_1 = ndi; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request = cqi_req; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = UE_template->DAI_ul[sched_subframeP]; - hi_dci0_req_body->number_of_dci++; - hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP, subframeP, 4); - hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; + hi_dci0_req_body->number_of_dci++; + hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP, subframeP, 4); + hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; - hi_dci0_req->sfn_sf = frameP<<4|subframeP; // sfnsf_add_subframe(sched_frame, sched_subframeP, 0); // sunday! - hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; + hi_dci0_req->sfn_sf = frameP<<4|subframeP; // sfnsf_add_subframe(sched_frame, sched_subframeP, 0); // sunday! + hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; - LOG_D(MAC, - "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", - harq_pid, frameP, subframeP, UE_id, rnti, - sched_frame, sched_subframeP); + LOG_D(MAC, + "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", + harq_pid, frameP, subframeP, UE_id, rnti, + sched_frame, sched_subframeP); - // Add UL_config PDUs - fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_tmp_body->number_of_pdus], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, first_rb[CC_id], // resource_block_start - rb_table[rb_table_index], // number_of_resource_blocks - UE_template->mcs_UL[harq_pid], cshift, // cyclic_shift_2_for_drms - 0, // frequency_hopping_enabled_flag - 0, // frequency_hopping_bits - ndi, // new_data_indication - 0, // redundancy_version - harq_pid, // harq_process_number - 0, // ul_tx_mode - 0, // current_tx_nb - 0, // n_srs - get_TBS_UL - (UE_template-> - mcs_UL[harq_pid], - rb_table - [rb_table_index])); + // Add UL_config PDUs + fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_tmp_body->number_of_pdus], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, first_rb[CC_id], // resource_block_start + rb_table[rb_table_index], // number_of_resource_blocks + UE_template->mcs_UL[harq_pid], cshift, // cyclic_shift_2_for_drms + 0, // frequency_hopping_enabled_flag + 0, // frequency_hopping_bits + ndi, // new_data_indication + 0, // redundancy_version + harq_pid, // harq_process_number + 0, // ul_tx_mode + 0, // current_tx_nb + 0, // n_srs + get_TBS_UL + (UE_template-> + mcs_UL[harq_pid], + rb_table + [rb_table_index])); #ifdef Rel14 - if (UE_template->rach_resource_type > 0) { // This is a BL/CE UE allocation - fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_tmp_body->number_of_pdus], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions - 1, //repetition_number - (frameP * - 10) + - subframeP); - } + if (UE_template->rach_resource_type > 0) { // This is a BL/CE UE allocation + fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_tmp_body->number_of_pdus], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions + 1, //repetition_number + (frameP * + 10) + + subframeP); + } #endif - ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST; - ul_req_tmp_body->number_of_pdus++; - ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - mac->ul_handle++; + ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_req_tmp_body->number_of_pdus++; + ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + mac->ul_handle++; - uint16_t ul_sched_frame = sched_frame; - uint16_t ul_sched_subframeP = sched_subframeP; + uint16_t ul_sched_frame = sched_frame; + uint16_t ul_sched_subframeP = sched_subframeP; - add_subframe(&ul_sched_frame, &ul_sched_subframeP, 2); - ul_req_tmp->sfn_sf = ul_sched_frame<<4|ul_sched_subframeP; + add_subframe(&ul_sched_frame, &ul_sched_subframeP, 2); + ul_req_tmp->sfn_sf = ul_sched_frame<<4|ul_sched_subframeP; - add_ue_ulsch_info(module_idP, - CC_id, UE_id, subframeP, - S_UL_SCHEDULED); + add_ue_ulsch_info(module_idP, + CC_id, UE_id, subframeP, + S_UL_SCHEDULED); - //LOG_D(MAC, "[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP, CC_id, frameP, subframeP, UE_id); - LOG_D(MAC,"[PUSCH %d] SFN/SF:%04d%d UL_CFG:SFN/SF:%04d%d CQI:%d for UE %d/%x\n", harq_pid,frameP,subframeP,ul_sched_frame,ul_sched_subframeP,cqi_req,UE_id,rnti); + //LOG_D(MAC, "[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP, CC_id, frameP, subframeP, UE_id); + LOG_D(MAC,"[PUSCH %d] SFN/SF:%04d%d UL_CFG:SFN/SF:%04d%d CQI:%d for UE %d/%x\n", harq_pid,frameP,subframeP,ul_sched_frame,ul_sched_subframeP,cqi_req,UE_id,rnti); - // increment first rb for next UE allocation - first_rb[CC_id] += rb_table[rb_table_index]; - } else { // round > 0 => retransmission - T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, - T_INT(module_idP), T_INT(CC_id), T_INT(rnti), - T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), - T_INT(UE_template->mcs_UL[harq_pid]), - T_INT(first_rb[CC_id]), - T_INT(rb_table[rb_table_index]), T_INT(round)); + // increment first rb for next UE allocation + first_rb[CC_id] += rb_table[rb_table_index]; + } else { // round > 0 => retransmission + T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, + T_INT(module_idP), T_INT(CC_id), T_INT(rnti), + T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), + T_INT(UE_template->mcs_UL[harq_pid]), + T_INT(first_rb[CC_id]), + T_INT(rb_table[rb_table_index]), T_INT(round)); - // 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]; - 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 = - UE_template->first_rb_ul[harq_pid]; - hi_dci0_pdu->hi_pdu.hi_pdu_rel8. - cyclic_shift_2_for_drms = - UE_template->cshift[harq_pid]; - 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(sched_frame, sched_subframeP, 0); - hi_dci0_req->sfn_sf = frameP<<4|subframeP; - hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; + 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 = UE_template->first_rb_ul[harq_pid]; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = UE_template->cshift[harq_pid]; + 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(sched_frame, sched_subframeP, 0); + hi_dci0_req->sfn_sf = frameP<<4|subframeP; + hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; - LOG_D(MAC, - "[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) UE %d (mcs %d, first rb %d, nb_rb %d, TBS %d, round %d)\n", - module_idP, harq_pid, rnti, CC_id, frameP, - subframeP, UE_id, UE_template->mcs_UL[harq_pid], - UE_template->first_rb_ul[harq_pid], - UE_template->nb_rb_ul[harq_pid], - UE_template->TBS_UL[harq_pid], round); - // 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", - harq_pid, frameP, subframeP, UE_id, rnti, - sched_frame, sched_subframeP); - fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_tmp_body->number_of_pdus], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, UE_template->first_rb_ul[harq_pid], // resource_block_start - UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks - UE_template->mcs_UL[harq_pid], cshift, // cyclic_shift_2_for_drms - 0, // frequency_hopping_enabled_flag - 0, // frequency_hopping_bits - UE_template->oldNDI_UL[harq_pid], // new_data_indication - rvidx_tab[round & 3], // redundancy_version - harq_pid, // harq_process_number - 0, // ul_tx_mode - 0, // current_tx_nb - 0, // n_srs - UE_template-> - TBS_UL[harq_pid]); + LOG_D(MAC, + "[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) UE %d (mcs %d, first rb %d, nb_rb %d, TBS %d, round %d)\n", + module_idP, harq_pid, rnti, CC_id, frameP, + subframeP, UE_id, UE_template->mcs_UL[harq_pid], + UE_template->first_rb_ul[harq_pid], + UE_template->nb_rb_ul[harq_pid], + UE_template->TBS_UL[harq_pid], round); + // 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", + harq_pid, frameP, subframeP, UE_id, rnti, + sched_frame, sched_subframeP); + fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_tmp_body->number_of_pdus], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, UE_template->first_rb_ul[harq_pid], // resource_block_start + UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks + UE_template->mcs_UL[harq_pid], cshift, // cyclic_shift_2_for_drms + 0, // frequency_hopping_enabled_flag + 0, // frequency_hopping_bits + UE_template->oldNDI_UL[harq_pid], // new_data_indication + rvidx_tab[round & 3], // redundancy_version + harq_pid, // harq_process_number + 0, // ul_tx_mode + 0, // current_tx_nb + 0, // n_srs + UE_template-> + TBS_UL[harq_pid]); #ifdef Rel14 - if (UE_template->rach_resource_type > 0) { // This is a BL/CE UE allocation - fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_tmp_body->number_of_pdus], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions - 1, //repetition_number - (frameP * - 10) + - subframeP); - } + if (UE_template->rach_resource_type > 0) { // This is a BL/CE UE allocation + fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_tmp_body->number_of_pdus], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions + 1, //repetition_number + (frameP * + 10) + + subframeP); + } #endif - ul_req_tmp_body->number_of_pdus++; - mac->ul_handle++; + ul_req_tmp_body->number_of_pdus++; + mac->ul_handle++; - ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - ul_req_tmp->sfn_sf = sched_frame<<4|sched_subframeP; - ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_req_tmp->sfn_sf = sched_frame<<4|sched_subframeP; + ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST; - LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d cqi_req %d\n", - harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP,cqi_req); - } /* - else if (round > 0) { //we schedule a retransmission + LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d cqi_req %d\n", + harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP,cqi_req); + } /* + else if (round > 0) { //we schedule a retransmission - ndi = UE_template->oldNDI_UL[harq_pid]; + ndi = UE_template->oldNDI_UL[harq_pid]; - if ((round&3)==0) { - mcs = openair_daq_vars.target_ue_ul_mcs; - } else { - mcs = rvidx_tab[round&3] + 28; //not correct for round==4! + if ((round&3)==0) { + mcs = openair_daq_vars.target_ue_ul_mcs; + } else { + mcs = rvidx_tab[round&3] + 28; //not correct for round==4! - } + } - LOG_I(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE retransmission (mcs %d, first rb %d, nb_rb %d, harq_pid %d, round %d)\n", - module_idP,UE_id,rnti,CC_id,frameP,subframeP,mcs, - first_rb[CC_id],UE_template->nb_rb_ul[harq_pid], - harq_pid, round); + LOG_I(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE retransmission (mcs %d, first rb %d, nb_rb %d, harq_pid %d, round %d)\n", + module_idP,UE_id,rnti,CC_id,frameP,subframeP,mcs, + first_rb[CC_id],UE_template->nb_rb_ul[harq_pid], + harq_pid, round); - rballoc = mac_xface->computeRIV(frame_parms->N_RB_UL, - first_rb[CC_id], - UE_template->nb_rb_ul[harq_pid]); - first_rb[CC_id]+=UE_template->nb_rb_ul[harq_pid]; // increment for next UE allocation + rballoc = mac_xface->computeRIV(frame_parms->N_RB_UL, + first_rb[CC_id], + UE_template->nb_rb_ul[harq_pid]); + first_rb[CC_id]+=UE_template->nb_rb_ul[harq_pid]; // increment for next UE allocation - UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission_rx+=1; - UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx_rx=UE_template->nb_rb_ul[harq_pid]; - UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=UE_template->nb_rb_ul[harq_pid]; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=mcs; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs; - } - */ + UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission_rx+=1; + UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx_rx=UE_template->nb_rb_ul[harq_pid]; + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=UE_template->nb_rb_ul[harq_pid]; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=mcs; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs; + } + */ - } // UE_is_to_be_scheduled - } // loop over UE_id - } // loop of CC_id + } // UE_is_to_be_scheduled + } // loop over UE_id + } // loop of CC_id } From 01f06bcf091b5eb5bfb566cb86af75a30ae05fda Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Sat, 3 Feb 2018 08:11:48 -0800 Subject: [PATCH 100/195] compilation success --- openair2/LAYER2/MAC/config.c | 4 ++-- openair2/LAYER2/MAC/eNB_scheduler.c | 7 +++---- openair2/LAYER2/MAC/eNB_scheduler_RA.c | 3 ++- openair2/LAYER2/MAC/eNB_scheduler_bch.c | 2 +- openair2/LAYER2/MAC/eNB_scheduler_primitives.c | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index 2a74287b7e..07ed0735c2 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -270,12 +270,12 @@ void config_mib(int Mod_idP, LOG_I(MAC, "%s() NFAPI_CONFIG_REQUEST(num_tlv:%u) DL_BW:%u UL_BW:%u Ncp %d,p_eNB %d,earfcn %d,band %d,phich_resource %u phich_duration %u phich_power_offset %u PSS %d SSS %d PCI %d" #ifdef Rel14 - + " PBCH repetition %d" #endif "\n" ,__FUNCTION__ -` ,cfg->num_tlv + ,cfg->num_tlv ,cfg->rf_config.dl_channel_bandwidth.value ,cfg->rf_config.ul_channel_bandwidth.value ,NcpP,p_eNBP diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index e113cedb90..3c6471212a 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -636,7 +636,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, pdcp_run(&ctxt); - rrc_rx_tx(&ctxt, 0, CC_id); + rrc_rx_tx(&ctxt, CC_id); #if defined(Rel10) || defined(Rel14) @@ -681,7 +681,6 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, stop_meas(&RC.mac[module_idP]->eNB_scheduler); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, - VCD_FUNCTION_OUT); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, + VCD_FUNCTION_OUT); } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index a551465e57..51be84526f 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -923,7 +923,8 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, AssertFatal(reps > 2, "Have to handle programming of ACK when PDSCH repetitions is > 2\n"); ul_req = &mac->UL_req_tmp[CC_idP][ackNAK_absSF % 10]; - ul_req_body = &ul_req->ul_config_request_body;l_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; + ul_req_body = &ul_req->ul_config_request_body; + ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_uci_harq_pdu)); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c index 258ca36c02..6b05977d89 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c @@ -698,7 +698,7 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) dl_req->number_pdu++; dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_p du_t)); + sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 740f183486..424459337d 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -1511,7 +1511,7 @@ fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t *ul_config_pd for (int ri = 0; ri < (1 << ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size); ri++) - ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.periodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[ri] = get_dl_cqi_pmi_size_pusch(cc,tmode,1 + ri,physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic); + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[ri] = get_dl_cqi_pmi_size_pusch(cc,tmode,1 + ri,physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic); ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_cqi = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index; ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_ri = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index; From f55cbe475c50ec213781410d18ed99f853fa7f8d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 5 Feb 2018 16:50:52 +0100 Subject: [PATCH 101/195] bugfix: fix initialUEMessage criticality S1AP specs say: initialUEMessage S1AP-ELEMENTARY-PROCEDURE ::= { INITIATING MESSAGE InitialUEMessage PROCEDURE CODE id-initialUEMessage CRITICALITY ignore } So let's use "ignore", not "reject". The online decoder http://asn1-playground.oss.com/ did not decode a message encoded by the eNB because of this. Only the S1AP messages captured while doing a simple connection of one UE have been tested with the online decoder. So, not all the S1AP messages have been checked, maybe some instances of this problem are still there. It does not seem to harm the actual UE<->eNB<->EPC communication (because we don't check the integrity of messages or because asn1c does not do it), so it's not a big deal. --- openair3/S1AP/s1ap_eNB_encoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair3/S1AP/s1ap_eNB_encoder.c b/openair3/S1AP/s1ap_eNB_encoder.c index 9a5f422158..7bd8bc09aa 100644 --- a/openair3/S1AP/s1ap_eNB_encoder.c +++ b/openair3/S1AP/s1ap_eNB_encoder.c @@ -470,7 +470,7 @@ int s1ap_eNB_encode_initial_ue_message( return s1ap_generate_initiating_message(buffer, length, S1ap_ProcedureCode_id_initialUEMessage, - S1ap_Criticality_reject, + S1ap_Criticality_ignore, &asn_DEF_S1ap_InitialUEMessage, initialUEMessage_p); } From a21c0b809f68f1ed3c711cfe376ecbfbe07f6c6f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 5 Feb 2018 17:21:40 +0100 Subject: [PATCH 102/195] bugfix: fix RRC Release 10 compilation The following compilation did not work anymore: ./build_oai --eNB -w USRP -r Rel10 -c (Rel8 still does not work.) --- openair1/PHY/LTE_TRANSPORT/prach.c | 12 ++++++++---- openair1/PHY/LTE_TRANSPORT/proto.h | 7 +++---- openair1/PHY/defs.h | 2 ++ openair1/PHY/impl_defs_lte.h | 4 ++-- openair1/SCHED/fapi_l1.c | 13 ++++++++++++- openair1/SCHED/prach_procedures.c | 3 ++- openair2/LAYER2/MAC/config.c | 8 ++++++-- openair2/LAYER2/MAC/eNB_scheduler_RA.c | 9 +++++++++ openair2/LAYER2/MAC/eNB_scheduler_bch.c | 6 ++++++ openair2/LAYER2/MAC/eNB_scheduler_primitives.c | 4 ++++ openair2/RRC/LITE/rrc_eNB.c | 14 ++++++++++++++ targets/RT/USER/lte-enb.c | 2 ++ 12 files changed, 70 insertions(+), 14 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c index a332670a59..b58aa91636 100644 --- a/openair1/PHY/LTE_TRANSPORT/prach.c +++ b/openair1/PHY/LTE_TRANSPORT/prach.c @@ -1089,6 +1089,10 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1 } //__m128i mmtmpX0,mmtmpX1,mmtmpX2,mmtmpX3; +#ifndef Rel14 +#define rx_prach0 rx_prach +#endif + void rx_prach0(PHY_VARS_eNB *eNB, RU_t *ru, uint16_t *max_preamble, @@ -1764,9 +1768,8 @@ void rx_prach0(PHY_VARS_eNB *eNB, -#ifndef Rel14 -#define rx_prach rx_prach0 -#else +#ifdef Rel14 + void rx_prach(PHY_VARS_eNB *eNB, RU_t *ru, uint16_t *max_preamble, @@ -1806,7 +1809,8 @@ void rx_prach(PHY_VARS_eNB *eNB, } } } -#endif + +#endif /* Rel14 */ void init_prach_tables(int N_ZC) { diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 8afb7b14a3..be6d2861f2 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -2151,11 +2151,10 @@ void rx_prach(PHY_VARS_eNB *phy_vars_eNB,RU_t *ru, uint16_t *max_preamble, uint16_t *max_preamble_energy, uint16_t *max_preamble_delay, -#ifdef Rel14 - uint16_t Nf, uint8_t tdd_mapindex, - uint8_t br_flag -#else uint16_t Nf, uint8_t tdd_mapindex +#ifdef Rel14 + , + uint8_t br_flag #endif ); /*! diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index 6f52867d2d..38da7e4e1e 100644 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -744,8 +744,10 @@ typedef struct RU_t_s{ int (*wakeup_rxtx)(struct PHY_VARS_eNB_s *eNB, struct RU_t_s *ru); /// function pointer to wakeup routine in lte-enb. void (*wakeup_prach_eNB)(struct PHY_VARS_eNB_s *eNB,struct RU_t_s *ru,int frame,int subframe); +#ifdef Rel14 /// function pointer to wakeup routine in lte-enb. void (*wakeup_prach_eNB_br)(struct PHY_VARS_eNB_s *eNB,struct RU_t_s *ru,int frame,int subframe); +#endif /// function pointer to eNB entry routine void (*eNB_top)(struct PHY_VARS_eNB_s *eNB, int frame_rx, int subframe_rx, char *string); /// Timing statistics diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h index ac54be36fb..066dc7012c 100644 --- a/openair1/PHY/impl_defs_lte.h +++ b/openair1/PHY/impl_defs_lte.h @@ -144,8 +144,6 @@ typedef struct { uint8_t prach_hopping_offset[4]; } PRACH_eMTC_CONFIG_INFO; -#endif - /// PRACH-ConfigSIB or PRACH-Config from 36.331 RRC spec typedef struct { /// Parameter: RACH_ROOT_SEQUENCE, see TS 36.211 (5.7.1). \vr{[0..837]} @@ -158,6 +156,8 @@ typedef struct { #endif } PRACH_eMTC_CONFIG_COMMON; +#endif + /// Enumeration for parameter \f$N_\text{ANRep}\f$ \ref PUCCH_CONFIG_DEDICATED::repetitionFactor. typedef enum { n2=0, diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c index 2fa9c9c2cd..b9024bdfbf 100644 --- a/openair1/SCHED/fapi_l1.c +++ b/openair1/SCHED/fapi_l1.c @@ -63,6 +63,7 @@ void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB, } #ifdef Rel14 + void handle_nfapi_mpdcch_pdu(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu) @@ -76,6 +77,7 @@ void handle_nfapi_mpdcch_pdu(PHY_VARS_eNB *eNB, // copy dci configuration into eNB structure fill_mdci_and_dlsch(eNB,proc,&mpdcch_vars->mdci_alloc[mpdcch_vars->num_dci],pdu); } + #endif void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc, @@ -265,14 +267,21 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_pr dlsch0_harq->codeword = 0; dlsch0_harq->pdsch_start = rel10->pdsch_start; } -#endif dlsch0->i0 = rel13->initial_transmission_sf_io; +#endif +#ifdef Rel14 LOG_D(PHY,"dlsch->i0:%04x dlsch0_harq[pdsch_start:%d nb_rb:%d vrb_type:%d rvidx:%d Nl:%d mimo_mode:%d dl_power_off:%d round:%d status:%d TBS:%d Qm:%d codeword:%d rb_alloc:%d] rel8[length:%d]\n", dlsch0->i0, dlsch0_harq->pdsch_start, dlsch0_harq->nb_rb, dlsch0_harq->vrb_type, dlsch0_harq->rvidx, dlsch0_harq->Nl, dlsch0_harq->mimo_mode, dlsch0_harq->dl_power_off, dlsch0_harq->round, dlsch0_harq->status, dlsch0_harq->TBS, dlsch0_harq->Qm, dlsch0_harq->codeword, dlsch0_harq->rb_alloc[0], rel8->length ); +#else + LOG_D(PHY,"dlsch0_harq[pdsch_start:%d nb_rb:%d vrb_type:%d rvidx:%d Nl:%d mimo_mode:%d dl_power_off:%d round:%d status:%d TBS:%d Qm:%d codeword:%d rb_alloc:%d] rel8[length:%d]\n", + dlsch0_harq->pdsch_start, dlsch0_harq->nb_rb, dlsch0_harq->vrb_type, dlsch0_harq->rvidx, dlsch0_harq->Nl, dlsch0_harq->mimo_mode, dlsch0_harq->dl_power_off, dlsch0_harq->round, dlsch0_harq->status, dlsch0_harq->TBS, dlsch0_harq->Qm, dlsch0_harq->codeword, dlsch0_harq->rb_alloc[0], + rel8->length + ); +#endif } uint16_t to_beta_offset_harqack[16]={16,20,25,32,40,50,64,80,101,127,160,248,400,640,1008,8}; @@ -764,8 +773,10 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) break; #ifdef Rel14 case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE: +#ifdef Rel14 handle_nfapi_mpdcch_pdu(eNB,proc,dl_config_pdu); eNB->mpdcch_vars[subframe&1].num_dci++; +#endif break; #endif } diff --git a/openair1/SCHED/prach_procedures.c b/openair1/SCHED/prach_procedures.c index d8c6585074..f3b5644b92 100644 --- a/openair1/SCHED/prach_procedures.c +++ b/openair1/SCHED/prach_procedures.c @@ -52,8 +52,9 @@ extern uint32_t nfapi_mode; -void prach_procedures(PHY_VARS_eNB *eNB, +void prach_procedures(PHY_VARS_eNB *eNB #ifdef Rel14 + , int br_flag #endif ) { diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index d5a09bef85..27b194deb5 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -193,8 +193,12 @@ void config_mib(int Mod_idP, int NcpP, int p_eNBP, uint32_t dl_CarrierFreqP, - uint32_t ul_CarrierFreqP, - uint32_t pbch_repetitionP) { + uint32_t ul_CarrierFreqP +#ifdef Rel14 + , + uint32_t pbch_repetitionP +#endif + ) { nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index 4bf96d3bce..62f42fd297 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -1642,6 +1642,8 @@ initiate_ra_proc(module_id_t module_idP, COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id]; RA_t *ra = &cc->ra[0]; +#ifdef Rel14 + struct PRACH_ConfigSIB_v1310 *ext4_prach = NULL; PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = NULL; @@ -1653,6 +1655,9 @@ initiate_ra_proc(module_id_t module_idP, prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; } + +#endif /* Rel14 */ + LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d Initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, subframeP, preamble_index); @@ -1666,6 +1671,8 @@ initiate_ra_proc(module_id_t module_idP, uint16_t msg2_subframe = subframeP; int offset; +#ifdef Rel14 + if (prach_ParametersListCE_r13 && prach_ParametersListCE_r13->list.count < rach_resource_type) { LOG_E(MAC, @@ -1675,6 +1682,8 @@ initiate_ra_proc(module_id_t module_idP, return; } +#endif /* Rel14 */ + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME (VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c index 9a1046ff26..f6c8a24a34 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c @@ -615,10 +615,16 @@ schedule_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) LOG_D(MAC, "Frame %d, subframe %d: Adding BCH PDU in position %d (length %d)\n", frameP, subframeP, dl_req->number_pdu, mib_sdu_length); if ((frameP & 1023) < 40) +#ifdef Rel14 LOG_D(MAC, "[eNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes (cc->mib->message.schedulingInfoSIB1_BR_r13 %d)\n", module_idP, frameP, CC_id, mib_sdu_length, (int) cc->mib->message.schedulingInfoSIB1_BR_r13); +#else + LOG_D(MAC, + "[eNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n", + module_idP, frameP, CC_id, mib_sdu_length); +#endif dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 3e574a56c3..940cf67319 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -914,6 +914,7 @@ get_dl_cqi_pmi_size_pusch(COMMON_channels_t * cc, uint8_t tmode, else if (ri >= 2 && cc->p_eNB == 4) return (4 + (N << 1) + 4 + (N << 1) + 4); break; +#ifdef Rel14 case CQI_ReportModeAperiodic_rm32_v1250: AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 || tmode == 10, @@ -947,6 +948,7 @@ get_dl_cqi_pmi_size_pusch(COMMON_channels_t * cc, uint8_t tmode, return (4 + 4 + 4); break; +#endif /* Rel14 */ } AssertFatal(1 == 0, "Shouldn't get here\n"); return (0); @@ -4339,6 +4341,7 @@ extract_pusch_csi(module_id_t mod_idP, int CC_idP, int UE_id, } break; +#ifdef Rel14 case CQI_ReportModeAperiodic_rm32_v1250: AssertFatal(tmode == 4 || tmode == 5 || tmode == 6 || tmode == 8 || tmode == 9 @@ -4362,6 +4365,7 @@ extract_pusch_csi(module_id_t mod_idP, int CC_idP, int UE_id, tmode); AssertFatal(1 == 0, "CQI_ReportModeAperiodic_rm11 to be done\n"); break; +#endif /* Rel14 */ } } diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index fbc95c8b74..946da42920 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -416,7 +416,9 @@ init_MCCH( 0,//rnti (BCCH_BCH_Message_t *)NULL, (RadioResourceConfigCommonSIB_t *) NULL, +#ifdef Rel14 (RadioResourceConfigCommonSIB_t *) NULL, +#endif (struct PhysicalConfigDedicated *)NULL, #if defined(Rel10) || defined(Rel14) (SCellToAddMod_r10_t *)NULL, @@ -1169,7 +1171,9 @@ rrc_eNB_generate_RRCConnectionReestablishment( ctxt_pP->rnti, (BCCH_BCH_Message_t *) NULL, (RadioResourceConfigCommonSIB_t *) NULL, +#ifdef Rel14 (RadioResourceConfigCommonSIB_t *) NULL, +#endif (struct PhysicalConfigDedicated* ) ue_context_pP->ue_context.physicalConfigDedicated, #if defined(Rel10) || defined(Rel14) (SCellToAddMod_r10_t *)NULL, @@ -3976,7 +3980,9 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( ue_context_pP->ue_context.rnti, (BCCH_BCH_Message_t *) NULL, (RadioResourceConfigCommonSIB_t*) NULL, +#ifdef Rel14 (RadioResourceConfigCommonSIB_t*) NULL, +#endif ue_context_pP->ue_context.physicalConfigDedicated, #if defined(Rel10) || defined(Rel14) (SCellToAddMod_r10_t *)NULL, @@ -4555,7 +4561,9 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( ue_context_pP->ue_context.rnti, (BCCH_BCH_Message_t *) NULL, (RadioResourceConfigCommonSIB_t *) NULL, +#ifdef Rel14 (RadioResourceConfigCommonSIB_t *) NULL, +#endif ue_context_pP->ue_context.physicalConfigDedicated, #if defined(Rel10) || defined(Rel14) (SCellToAddMod_r10_t *)NULL, @@ -4825,7 +4833,9 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ue_context_pP->ue_context.rnti, (BCCH_BCH_Message_t *) NULL, (RadioResourceConfigCommonSIB_t *) NULL, +#ifdef Rel14 (RadioResourceConfigCommonSIB_t *) NULL, +#endif ue_context_pP->ue_context.physicalConfigDedicated, #if defined(Rel10) || defined(Rel14) (SCellToAddMod_r10_t *)NULL, @@ -4878,7 +4888,9 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ue_context_pP->ue_context.rnti, (BCCH_BCH_Message_t *) NULL, (RadioResourceConfigCommonSIB_t *) NULL, +#ifdef Rel14 (RadioResourceConfigCommonSIB_t *) NULL, +#endif ue_context_pP->ue_context.physicalConfigDedicated, #if defined(Rel10) || defined(Rel14) (SCellToAddMod_r10_t *)NULL, @@ -4994,7 +5006,9 @@ rrc_eNB_generate_RRCConnectionSetup( ue_context_pP->ue_context.rnti, (BCCH_BCH_Message_t *) NULL, (RadioResourceConfigCommonSIB_t *) NULL, +#ifdef Rel14 (RadioResourceConfigCommonSIB_t *) NULL, +#endif ue_context_pP->ue_context.physicalConfigDedicated, #if defined(Rel10) || defined(Rel14) (SCellToAddMod_r10_t *)NULL, diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 79973d3814..f447f6589d 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -1050,7 +1050,9 @@ void init_eNB_afterRU(void) { RC.ru[ru_id]->wakeup_rxtx = wakeup_rxtx; RC.ru[ru_id]->wakeup_prach_eNB = wakeup_prach_eNB; +#ifdef Rel14 RC.ru[ru_id]->wakeup_prach_eNB_br = wakeup_prach_eNB_br; +#endif RC.ru[ru_id]->eNB_top = eNB_top; } } From eccb96c4c2e3a1011af53a7466eb31741047e53f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 6 Feb 2018 14:37:03 +0100 Subject: [PATCH 103/195] bugfix: fix UL over scheduling There is too much UL scheduling because the buffer status is overestimated. This commit tries to make things simpler. --- openair2/LAYER2/MAC/defs.h | 12 +- .../LAYER2/MAC/eNB_scheduler_primitives.c | 7 +- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 276 +++++++----------- openair2/LAYER2/MAC/pre_processor.c | 21 +- openair2/LAYER2/openair2_proc.c | 10 +- 5 files changed, 140 insertions(+), 186 deletions(-) diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index 1afb0d6c43..3f721288b4 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -665,7 +665,7 @@ typedef struct { /// mcs from last UL scheduling uint8_t mcs_UL[8]; /// TBS from last UL scheduling - uint8_t TBS_UL[8]; + int TBS_UL[8]; /// Flag to indicate UL has been scheduled at least once boolean_t ul_active; /// Flag to indicate UE has been configured (ACK from RRCConnectionSetup received) @@ -720,9 +720,6 @@ typedef struct { // Logical channel info for link with RLC - /// Last received UE BSR info for each logical channel group id - uint8_t bsr_info[MAX_NUM_LCGID]; - /// LCGID mapping long lcgidmap[11]; @@ -749,8 +746,6 @@ typedef struct { /// size of remaining size to send for the downlink head SDU uint32_t dl_buffer_head_sdu_remaining_size_to_send[MAX_NUM_LCID]; - /// total uplink buffer size - uint32_t ul_total_buffer; /// uplink buffer creation time for each LCID uint32_t ul_buffer_creation_time[MAX_NUM_LCGID]; /// maximum uplink buffer creation time across all the LCIDs @@ -758,6 +753,11 @@ typedef struct { /// uplink buffer size per LCID uint32_t ul_buffer_info[MAX_NUM_LCGID]; + /// uplink bytes that are currently scheduled + int scheduled_ul_bytes; + /// estimation of the UL buffer size + int estimated_ul_buffer; + /// UE tx power int32_t ue_tx_power; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 3e574a56c3..653ea4b665 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -2483,14 +2483,15 @@ UE_is_to_be_scheduled(module_id_t module_idP, int CC_id, uint8_t UE_id) LOG_D(MAC, "[eNB %d][PUSCH] Checking UL requirements UE %d/%x\n", module_idP, UE_id, UE_RNTI(module_idP, UE_id)); - if ((UE_template->bsr_info[LCGID0] > 0) || (UE_template->bsr_info[LCGID1] > 0) || (UE_template->bsr_info[LCGID2] > 0) || (UE_template->bsr_info[LCGID3] > 0) || (UE_template->ul_SR > 0) || // uplink scheduling request + if ((UE_template->scheduled_ul_bytes < UE_template->estimated_ul_buffer) || + (UE_template->ul_SR > 0) || // uplink scheduling request ((UE_sched_ctl->ul_inactivity_timer > 20) && (UE_sched_ctl->ul_scheduled == 0)) || // every 2 frames when RRC_CONNECTED ((UE_sched_ctl->ul_inactivity_timer > 10) && (UE_sched_ctl->ul_scheduled == 0) && (mac_eNB_get_rrc_status(module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED))) // every Frame when not RRC_CONNECTED { LOG_D(MAC, - "[eNB %d][PUSCH] UE %d/%x should be scheduled (BSR0 %d,SR %d)\n", + "[eNB %d][PUSCH] UE %d/%x should be scheduled (SRB0 estimated size %d,SR %d)\n", module_idP, UE_id, UE_RNTI(module_idP, UE_id), - UE_template->bsr_info[LCGID0], UE_template->ul_SR); + UE_template->ul_buffer_info[LCGID0], UE_template->ul_SR); return (1); } else { return (0); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index f841d9d55a..e726ed7738 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -96,10 +96,10 @@ rx_sdu(const module_id_t enb_mod_idP, eNB_MAC_INST *mac = RC.mac[enb_mod_idP]; int harq_pid = subframe2harqpid(&mac->common_channels[CC_idP], frameP, subframeP); + int lcgid_updated[4] = {0, 0, 0, 0}; UE_list_t *UE_list = &mac->UE_list; int crnti_rx = 0; - int old_buffer_info; RA_t *ra = (RA_t *) & RC.mac[enb_mod_idP]->common_channels[CC_idP].ra[0]; int first_rb = 0; @@ -153,6 +153,12 @@ rx_sdu(const module_id_t enb_mod_idP, subframeP, UE_RNTI(enb_mod_idP, UE_id)); } + + /* update scheduled bytes */ + UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes -= + UE_list->UE_template[CC_idP][UE_id].TBS_UL[harq_pid]; + if (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 { // we've got an error LOG_D(MAC, "[eNB %d][PUSCH %d] CC_id %d ULSCH in error in round %d, ul_cqi %d\n", @@ -161,15 +167,16 @@ rx_sdu(const module_id_t enb_mod_idP, ul_cqi); // AssertFatal(1==0,"ulsch in error\n"); - if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] == - 3) { - UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= - (~(1 << harq_pid)); - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = - 0; - if (UE_list->UE_sched_ctrl[UE_id]. - ul_consecutive_errors++ == 10) + if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] == 3) { + UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= (~(1 << harq_pid)); + UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0; + if (UE_list->UE_sched_ctrl[UE_id]. ul_consecutive_errors++ == 10) UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 1; + /* update scheduled bytes */ + UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes -= + UE_list->UE_template[CC_idP][UE_id].TBS_UL[harq_pid]; + if (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 UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]++; return; @@ -321,20 +328,19 @@ rx_sdu(const module_id_t enb_mod_idP, enb_mod_idP, CC_idP, rx_ces[i], lcgid, payload_ptr[0] & 0x3f); if (UE_id != -1) { + int bsr = payload_ptr[0] & 0x3f; - UE_list->UE_template[CC_idP][UE_id].bsr_info[lcgid] = - (payload_ptr[0] & 0x3f); + lcgid_updated[lcgid] = 1; // update buffer info + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid] = BSR_TABLE[bsr]; - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[lcgid] = - BSR_TABLE[UE_list->UE_template[CC_idP][UE_id]. - bsr_info[lcgid]]; - - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[lcgid]; + UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[0] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[1] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[2] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[3]; + //UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer += UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer / 4; RC.eNB[enb_mod_idP][CC_idP]-> pusch_stats_bsr[UE_id][(frameP * 10) + subframeP] @@ -355,12 +361,10 @@ rx_sdu(const module_id_t enb_mod_idP, (enb_mod_idP, UE_RNTI(enb_mod_idP, UE_id)) < RRC_CONNECTED) LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d : ul_total_buffer = %d (lcg increment %d)\n", + "[eNB %d] CC_id %d MAC CE_LCID %d : estimated_ul_buffer = %d (lcg increment %d)\n", enb_mod_idP, CC_idP, rx_ces[i], - UE_list->UE_template[CC_idP][UE_id]. - ul_total_buffer, - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[lcgid]); + UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer, + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid]); } else { } @@ -370,115 +374,48 @@ rx_sdu(const module_id_t enb_mod_idP, case LONG_BSR: if (UE_id != -1) { - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] = - ((payload_ptr[0] & 0xFC) >> 2); - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] = - ((payload_ptr[0] & 0x03) << 4) | - ((payload_ptr[1] & 0xF0) >> 4); - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] = - ((payload_ptr[1] & 0x0F) << 2) | - ((payload_ptr[2] & 0xC0) >> 6); - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] = - (payload_ptr[2] & 0x3F); + int bsr0 = (payload_ptr[0] & 0xFC) >> 2; + int bsr1 = ((payload_ptr[0] & 0x03) << 4) | ((payload_ptr[1] & 0xF0) >> 4); + int bsr2 = ((payload_ptr[1] & 0x0F) << 2) | ((payload_ptr[2] & 0xC0) >> 6); + int bsr3 = payload_ptr[2] & 0x3F; + + lcgid_updated[0] = 1; + lcgid_updated[1] = 1; + lcgid_updated[2] = 1; + lcgid_updated[3] = 1; // update buffer info - old_buffer_info = - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID0]; - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID0] = - BSR_TABLE[UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID0]]; + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] = BSR_TABLE[bsr0]; + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] = BSR_TABLE[bsr1]; + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] = BSR_TABLE[bsr2]; + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3] = BSR_TABLE[bsr3]; - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer += - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID0]; - if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= - old_buffer_info) - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= - old_buffer_info; - else - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = - 0; - - old_buffer_info = - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID1]; - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID1] = - BSR_TABLE[UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID1]]; - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer += - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID1]; - if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= - old_buffer_info) - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= - old_buffer_info; - else - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = - 0; - - old_buffer_info = - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID2]; - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID2] = - BSR_TABLE[UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID2]]; - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer += - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID2]; - if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= - old_buffer_info) - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= - old_buffer_info; - else - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = - 0; - - old_buffer_info = - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID3]; - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID3] = - BSR_TABLE[UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID3]]; - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer += - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[LCGID3]; - if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= - old_buffer_info) - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= - old_buffer_info; - else - UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = - 0; + UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[0] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[1] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[2] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[3]; + //UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer += UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer / 4; LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = " + "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR. Size is LCGID0 = %u LCGID1 = " "%u LCGID2 = %u LCGID3 = %u\n", enb_mod_idP, CC_idP, rx_ces[i], - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0], - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1], - UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2], - UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID3]); + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0], + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1], + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2], + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]); if (crnti_rx == 1) LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = " + "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR. Size is LCGID0 = %u LCGID1 = " "%u LCGID2 = %u LCGID3 = %u\n", enb_mod_idP, CC_idP, rx_ces[i], - UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID0], - UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID1], - UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID2], - UE_list->UE_template[CC_idP][UE_id]. - bsr_info[LCGID3]); + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0], + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1], + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2], + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]); - if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] == + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] == 0) { UE_list->UE_template[CC_idP][UE_id]. ul_buffer_creation_time[LCGID0] = 0; @@ -488,7 +425,7 @@ rx_sdu(const module_id_t enb_mod_idP, ul_buffer_creation_time[LCGID0] = frameP; } - if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] == + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] == 0) { UE_list->UE_template[CC_idP][UE_id]. ul_buffer_creation_time[LCGID1] = 0; @@ -498,7 +435,7 @@ rx_sdu(const module_id_t enb_mod_idP, ul_buffer_creation_time[LCGID1] = frameP; } - if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] == + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] == 0) { UE_list->UE_template[CC_idP][UE_id]. ul_buffer_creation_time[LCGID2] = 0; @@ -508,7 +445,7 @@ rx_sdu(const module_id_t enb_mod_idP, ul_buffer_creation_time[LCGID2] = frameP; } - if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] == + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3] == 0) { UE_list->UE_template[CC_idP][UE_id]. ul_buffer_creation_time[LCGID3] = 0; @@ -649,19 +586,28 @@ rx_sdu(const module_id_t enb_mod_idP, #endif if (UE_id != -1) { - // adjust buffer occupancy of the correponding logical channel group - if (UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[UE_list->UE_template[CC_idP] - [UE_id].lcgidmap[rx_lcids[i]]] >= - rx_lengths[i]) - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[UE_list->UE_template[CC_idP] - [UE_id].lcgidmap[rx_lcids[i]]] -= - rx_lengths[i]; - else - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[UE_list->UE_template[CC_idP] - [UE_id].lcgidmap[rx_lcids[i]]] = 0; + if (lcgid_updated[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] == 0) { + // adjust buffer occupancy of the correponding logical channel group + if (UE_list->UE_template[CC_idP][UE_id]. + ul_buffer_info[UE_list->UE_template[CC_idP] + [UE_id].lcgidmap[rx_lcids[i]]] >= + rx_lengths[i]) + UE_list->UE_template[CC_idP][UE_id]. + ul_buffer_info[UE_list->UE_template[CC_idP] + [UE_id].lcgidmap[rx_lcids[i]]] -= + rx_lengths[i]; + else + UE_list->UE_template[CC_idP][UE_id]. + ul_buffer_info[UE_list->UE_template[CC_idP] + [UE_id].lcgidmap[rx_lcids[i]]] = 0; + + UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[0] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[1] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[2] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[3]; + //UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer += UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer / 4; + } LOG_D(MAC, "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DCCH, received %d bytes form UE %d on LCID %d \n", @@ -712,18 +658,28 @@ rx_sdu(const module_id_t enb_mod_idP, ul_buffer_info[UE_list->UE_template[CC_idP] [UE_id].lcgidmap[rx_lcids[i]]]); - if (UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[UE_list->UE_template[CC_idP] - [UE_id].lcgidmap[rx_lcids[i]]] - >= rx_lengths[i]) - UE_list->UE_template[CC_idP][UE_id]. + if (lcgid_updated[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] == 0) { + if (UE_list->UE_template[CC_idP][UE_id]. ul_buffer_info[UE_list->UE_template[CC_idP] - [UE_id].lcgidmap[rx_lcids[i]]] - -= rx_lengths[i]; - else - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info - [UE_list->UE_template[CC_idP][UE_id].lcgidmap - [rx_lcids[i]]] = 0; + [UE_id].lcgidmap[rx_lcids[i]]] + >= rx_lengths[i]) + UE_list->UE_template[CC_idP][UE_id]. + ul_buffer_info[UE_list->UE_template[CC_idP] + [UE_id].lcgidmap[rx_lcids[i]]] + -= rx_lengths[i]; + else + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info + [UE_list->UE_template[CC_idP][UE_id].lcgidmap + [rx_lcids[i]]] = 0; + + UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[0] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[1] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[2] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[3]; + //UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer += UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer / 4; + } + if ((rx_lengths[i] < SCH_PAYLOAD_SIZE_MAX) && (rx_lengths[i] > 0)) { // MAX SIZE OF transport block mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); //(unsigned int*)crc_status); @@ -1196,10 +1152,7 @@ schedule_ulsch_rnti(module_id_t module_idP, module_idP, frameP, subframeP, sched_frame, sched_subframeP, harq_pid, UE_id, rnti, CC_id, aggregation, N_RB_UL); - RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * - 10) + - subframeP] = - UE_template->ul_total_buffer; + RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * 10) + subframeP] = UE_template->estimated_ul_buffer; VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME (VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO, RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * @@ -1289,8 +1242,6 @@ schedule_ulsch_rnti(module_id_t module_idP, UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = UE_template->mcs_UL[harq_pid]; - // buffer_occupancy = UE_template->ul_total_buffer; - while (((rb_table[rb_table_index] > (N_RB_UL - 1 - first_rb[CC_id])) @@ -1341,18 +1292,15 @@ schedule_ulsch_rnti(module_id_t module_idP, // adjust total UL buffer status by TBS, wait for UL sdus to do final update LOG_D(MAC, - "[eNB %d] CC_id %d UE %d/%x : adjusting ul_total_buffer, old %d, TBS %d\n", + "[eNB %d] CC_id %d UE %d/%x : adjusting scheduled_ul_bytes, old %d, TBS %d\n", module_idP, CC_id, UE_id, rnti, - UE_template->ul_total_buffer, + UE_template->scheduled_ul_bytes, UE_template->TBS_UL[harq_pid]); - if (UE_template->ul_total_buffer > - UE_template->TBS_UL[harq_pid]) - UE_template->ul_total_buffer -= - UE_template->TBS_UL[harq_pid]; - else - UE_template->ul_total_buffer = 0; - LOG_D(MAC, "ul_total_buffer, new %d\n", - UE_template->ul_total_buffer); + + UE_template->scheduled_ul_bytes += UE_template->TBS_UL[harq_pid]; + + LOG_D(MAC, "scheduled_ul_bytes, new %d\n", UE_template->scheduled_ul_bytes); + // Cyclic shift for DM RS cshift = 0; // values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1) // save it for a potential retransmission diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index ff8939d82b..0d6a6ec388 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -1590,9 +1590,11 @@ assign_max_mcs_min_rb(module_id_t module_idP, int frameP, to_prb(RC.mac[module_idP]->common_channels[CC_id]. ul_Bandwidth); // if this UE has UL traffic - if (UE_template->ul_total_buffer > 0) { - + int bytes_to_schedule = UE_template->estimated_ul_buffer - UE_template->scheduled_ul_bytes; + if (bytes_to_schedule < 0) bytes_to_schedule = 0; + int bits_to_schedule = bytes_to_schedule * 8; + if (bits_to_schedule > 0) { tbs = get_TBS_UL(mcs, 3) << 3; // 1 or 2 PRB with cqi enabled does not work well! rb_table_index = 2; @@ -1602,7 +1604,7 @@ assign_max_mcs_min_rb(module_id_t module_idP, int frameP, Ncp, 0); while ((((UE_template->phr_info - tx_power) < 0) - || (tbs > UE_template->ul_total_buffer)) + || (tbs > bits_to_schedule)) && (mcs > 3)) { // LOG_I(MAC,"UE_template->phr_info %d tx_power %d mcs %d\n", UE_template->phr_info,tx_power, mcs); mcs--; @@ -1610,7 +1612,7 @@ assign_max_mcs_min_rb(module_id_t module_idP, int frameP, tx_power = estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, Ncp, 0); // fixme: set use_srs } - while ((tbs < UE_template->ul_total_buffer) && + while ((tbs < bits_to_schedule) && (rb_table[rb_table_index] < (N_RB_UL - first_rb[CC_id])) && ((UE_template->phr_info - tx_power) > 0) @@ -1700,11 +1702,14 @@ static int ue_ul_compare(const void *_a, const void *_b, void *_params) UE_list->UE_template[pCCid2][UE_id2].ul_buffer_info[LCGID0]) return 1; - if (UE_list->UE_template[pCCid1][UE_id1].ul_total_buffer > - UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer) + int bytes_to_schedule1 = UE_list->UE_template[pCCid1][UE_id1].estimated_ul_buffer - UE_list->UE_template[pCCid1][UE_id1].scheduled_ul_bytes; + if (bytes_to_schedule1 < 0) bytes_to_schedule1 = 0; + int bytes_to_schedule2 = UE_list->UE_template[pCCid2][UE_id2].estimated_ul_buffer - UE_list->UE_template[pCCid2][UE_id2].scheduled_ul_bytes; + if (bytes_to_schedule2 < 0) bytes_to_schedule2 = 0; + + if (bytes_to_schedule1 > bytes_to_schedule2) return -1; - if (UE_list->UE_template[pCCid1][UE_id1].ul_total_buffer < - UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer) + if (bytes_to_schedule1 < bytes_to_schedule2) return 1; if (UE_list->UE_template[pCCid1][UE_id1].pre_assigned_mcs_ul > diff --git a/openair2/LAYER2/openair2_proc.c b/openair2/LAYER2/openair2_proc.c index 34c06a9c53..f66d1142ab 100644 --- a/openair2/LAYER2/openair2_proc.c +++ b/openair2/LAYER2/openair2_proc.c @@ -217,11 +217,11 @@ int dump_eNB_l2_stats(char *buffer, int length) UE_list->eNB_UE_stats[CC_id][UE_id].num_errors_rx); len+= sprintf(&buffer[len],"[MAC] Received PHR PH = %d (db)\n", UE_list->UE_template[CC_id][UE_id].phr_info); - len+= sprintf(&buffer[len],"[MAC] Received BSR LCGID[0][1][2][3] = %u %u %u %u\n", - UE_list->UE_template[CC_id][UE_id].bsr_info[LCGID0], - UE_list->UE_template[CC_id][UE_id].bsr_info[LCGID1], - UE_list->UE_template[CC_id][UE_id].bsr_info[LCGID2], - UE_list->UE_template[CC_id][UE_id].bsr_info[LCGID3] + len+= sprintf(&buffer[len],"[MAC] Estimated size LCGID[0][1][2][3] = %u %u %u %u\n", + UE_list->UE_template[CC_id][UE_id].ul_buffer_info[LCGID0], + UE_list->UE_template[CC_id][UE_id].ul_buffer_info[LCGID1], + UE_list->UE_template[CC_id][UE_id].ul_buffer_info[LCGID2], + UE_list->UE_template[CC_id][UE_id].ul_buffer_info[LCGID3] ); } From 9b7364a3ca6caf3ecbfb4284e9eb254f69076fd0 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 7 Feb 2018 12:30:00 +0100 Subject: [PATCH 104/195] minor: fix AssertFatal --- openair2/LAYER2/MAC/eNB_scheduler_primitives.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 3e574a56c3..e0e0f0a5fa 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -3716,7 +3716,7 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id, sched_ctl->round[CC_idP][harq_pid]++; // increment round } else { // one or two ACK/NAK bits - AssertFatal(num_ack_nak > 2, + AssertFatal(num_ack_nak <= 2, "num_ack_nak %d > 2 for 1 CC and TM3/4/8/9/10\n", num_ack_nak); if ((num_ack_nak == 2) From c0bcd786735c26ef6dbd5c8e381a307ca3d49194 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 7 Feb 2018 12:31:26 +0100 Subject: [PATCH 105/195] bugfix: don't take into account report CQI in case of NACK or DTX The problem that may happen is that when the UE does not transmit on PUCCH (for whatever reason) we may get no signal at all, and thus compute a very low CQI. Later on we may ask the UE to transmit louder which may lead to saturation and more problems. The solution is simple: don't care about CQI in case of DTX (and NACK also, as done for PUSCH). Only FDD case done. For TDD it seems that: - nfapi structures are not correct. See nfapi_harq_indication_tdd_rel13_t in nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h, all the cases (bundling, multiplex, ...) use nfapi_harq_indication_tdd_harq_data_t - the function extract_harq does not handle TDD --- .../LAYER2/MAC/eNB_scheduler_primitives.c | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index e0e0f0a5fa..867b6d7e8b 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -4472,6 +4472,24 @@ UL_failure_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, } } +static int nack_or_dtx_reported( + COMMON_channels_t *cc, + nfapi_harq_indication_pdu_t *harq_pdu) +{ + int i; + + if (cc->tdd_Config) { + AssertFatal(0==1, "TDD to be done. FAPI structures (see nfapi_harq_indication_tdd_rel13_t) are not clean. To be cleaned as well?\n"); + abort(); + } else { + nfapi_harq_indication_fdd_rel13_t *hi = &harq_pdu->harq_indication_fdd_rel13; + for (i = 0; i < hi->number_of_ack_nack; hi++) + if (hi->harq_tb_n[i] != 1) + return 1; + return 0; + } +} + void harq_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, sub_frame_t subframeP, @@ -4500,7 +4518,8 @@ harq_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, extract_harq(mod_idP, CC_idP, UE_id, frameP, subframeP, (void *) &harq_pdu->harq_indication_fdd_rel13, channel); - if (channel == 0) { + /* don't care about cqi reporting if NACK/DTX is there */ + if (channel == 0 && !nack_or_dtx_reported(cc, harq_pdu)) { sched_ctl->pucch1_snr[CC_idP] = ul_cqi; sched_ctl->pucch1_cqi_update[CC_idP] = 1; } From 1fce1bbf82d4f5569f8a65ff4e24b0002c2a71f1 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 7 Feb 2018 14:51:50 +0100 Subject: [PATCH 106/195] bugfix: fix SIB3 encoding The unused bits are the lower bits, so we need to shift. Not sure that the value 1 is what we want though. --- openair2/RRC/LITE/MESSAGES/asn1_msg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c index b8a4148b11..77ba0c4cad 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c @@ -876,7 +876,7 @@ uint8_t do_SIB23(uint8_t Mod_id, (*sib3)->intraFreqCellReselectionInfo.presenceAntennaPort1 = 0; (*sib3)->intraFreqCellReselectionInfo.neighCellConfig.buf = CALLOC(8,1); (*sib3)->intraFreqCellReselectionInfo.neighCellConfig.size = 1; - (*sib3)->intraFreqCellReselectionInfo.neighCellConfig.buf[0] = 1; + (*sib3)->intraFreqCellReselectionInfo.neighCellConfig.buf[0] = 1 << 6; (*sib3)->intraFreqCellReselectionInfo.neighCellConfig.bits_unused = 6; (*sib3)->intraFreqCellReselectionInfo.t_ReselectionEUTRA = 1; (*sib3)->intraFreqCellReselectionInfo.t_ReselectionEUTRA_SF = (struct SpeedStateScaleFactors *)NULL; From c8ae5b7c09bd7d0c77f97c731e8c5825f23344da Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 8 Feb 2018 18:55:23 +0100 Subject: [PATCH 107/195] decrease warning --- targets/RT/USER/lte-ru.c | 1 - 1 file changed, 1 deletion(-) diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index e553fc3702..5f60553fe1 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -2161,7 +2161,6 @@ void init_RU(char *rf_config_file) { int ru_id; RU_t *ru; - int ret; PHY_VARS_eNB *eNB0= (PHY_VARS_eNB *)NULL; int i; int CC_id; From 1a1ad6ed8f3e1ad9c7e55a661aa1e9ddfc423d0e Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 8 Feb 2018 19:11:57 +0100 Subject: [PATCH 108/195] remove non-existing files from build description file --- cmake_targets/CMakeLists.txt | 8 -------- 1 file changed, 8 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 120d029a0c..44d80d4633 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1394,14 +1394,6 @@ add_library(L2_UE include_directories(${NFAPI_USER_DIR}) -if (FLEXRAN_AGENT_SB_IF) - -#Test for adding a shared library -add_library(default_sched SHARED ${MAC_DIR}/flexran_agent_scheduler_dlsch_ue.c) -add_library(remote_sched SHARED ${MAC_DIR}/flexran_agent_scheduler_dlsch_ue_remote.c) - -endif() - # L3 Libs ########################## From c518ed89e288767ca030991f1b2354684da7fcd3 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 8 Feb 2018 19:12:20 +0100 Subject: [PATCH 109/195] bugfix after merge --- openair2/RRC/LITE/rrc_eNB.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index 9526be83f4..f51ac31a79 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -6694,7 +6694,7 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { #if defined(FLEXRAN_AGENT_SB_IF) //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future if (mac_agent_registered[ctxt_pP->module_id]) { - agent_mac_xface[ctxt_pP->eNB_index]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, + agent_rrc_xface[ctxt_pP->eNB_index]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, ue_context_p->ue_id_rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED); } From 11fe5f97c7db2f1aa65c61ffb85212c3f3853654 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 9 Feb 2018 10:49:50 +0100 Subject: [PATCH 110/195] bugfix: fix eNB name in configuration files '_' is not a valid character. S1AP specs say: ENBname ::= PrintableString (SIZE (1..150,...)) And X.680 (08/2015) 41.4 table 10 lists the valid characters for PrintableString. '_' is not there. We replace by '-' which is there. Connection of eNB to ppenair-cn has not been tested. There is no reason why it would fail. --- .../v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf | 4 ++-- .../v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf | 4 ++-- .../autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf | 4 ++-- .../autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf | 4 ++-- .../autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf | 4 ++-- .../autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf | 4 ++-- .../autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf | 4 ++-- .../autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf | 4 ++-- .../autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf | 4 ++-- .../v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf | 4 ++-- .../v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf | 4 ++-- .../v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf | 4 ++-- .../GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf | 4 ++-- .../GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf | 4 ++-- .../GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf | 4 ++-- .../GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf | 4 ++-- 16 files changed, 32 insertions(+), 32 deletions(-) diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf index e09e068c63..0994acdf9d 100644 --- a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf index 1f992daba2..5e8cd8007e 100644 --- a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf index bb7df8b72d..53eae1d531 100644 --- a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf index ff97827b57..d30a57041c 100644 --- a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf index ebb9e417e7..e90eb3fe51 100644 --- a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf index 4e89102766..5dbecd3813 100644 --- a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf index beaf5ae0f1..1397184cc7 100644 --- a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf +++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf index b0efe66e14..caebb36eb2 100644 --- a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf +++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf index 1b33c7b3c2..fe90cdb338 100644 --- a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf +++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf index dc64a69c00..5d9027ce15 100644 --- a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf +++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf index c93ce24d08..539f0bd744 100644 --- a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf +++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf index 57f7ef83b9..58b088002f 100644 --- a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf +++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf index ff302811e9..cf322bc7f3 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf index 1c9ad09141..bc2b3b219c 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -10,7 +10,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf index 772e13fe6f..42ab1e81c7 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -13,7 +13,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf index e60e793438..aacc87e5b0 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf @@ -1,4 +1,4 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); +Active_eNBs = ( "eNB-Eurecom-LTEBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -13,7 +13,7 @@ eNBs = cell_type = "CELL_MACRO_ENB"; - eNB_name = "eNB_Eurecom_LTEBox"; + eNB_name = "eNB-Eurecom-LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = "1"; From 6cff88b9c8e7d8291bd754a3ac4877fd9baa45ec Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 9 Feb 2018 10:56:14 +0100 Subject: [PATCH 111/195] free memory on teardown after all RU/eNB threads have been released --- targets/RT/USER/lte-enb.c | 5 ----- targets/RT/USER/lte-ru.c | 2 -- targets/RT/USER/lte-softmodem.c | 11 +++++++++++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 928b41ad44..58967612dc 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -1139,10 +1139,5 @@ void stop_eNB(int nb_inst) { for (int inst=0;inst Date: Fri, 9 Feb 2018 10:59:59 +0100 Subject: [PATCH 112/195] free all memory for lte_ul_ref* structures --- openair1/PHY/LTE_REFSIG/lte_ul_ref.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/LTE_REFSIG/lte_ul_ref.c b/openair1/PHY/LTE_REFSIG/lte_ul_ref.c index cacd0f4292..93ca7646e6 100644 --- a/openair1/PHY/LTE_REFSIG/lte_ul_ref.c +++ b/openair1/PHY/LTE_REFSIG/lte_ul_ref.c @@ -185,12 +185,12 @@ void free_ul_ref_sigs(void) unsigned int u,v,Msc_RS; - for (Msc_RS=2; Msc_RS<33; Msc_RS++) { + for (Msc_RS=0; Msc_RS<33; Msc_RS++) { for (u=0; u<30; u++) { for (v=0; v<2; v++) { if (ul_ref_sigs[u][v][Msc_RS]) { free16(ul_ref_sigs[u][v][Msc_RS],2*sizeof(int16_t)*dftsizes[Msc_RS]); - ul_ref_sigs_rx[u][v][Msc_RS] = NULL; + ul_ref_sigs[u][v][Msc_RS] = NULL; } if (ul_ref_sigs_rx[u][v][Msc_RS]) { From 386fd21c937215bf43b02f2ca8e6d7334a3998ea Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 9 Feb 2018 15:31:59 +0100 Subject: [PATCH 113/195] free_eNB_{d,u}lsch(): remove log, complete function dlsch --- openair1/PHY/LTE_TRANSPORT/dlsch_coding.c | 37 ++++------------------- openair1/PHY/LTE_TRANSPORT/ulsch_coding.c | 22 -------------- 2 files changed, 6 insertions(+), 53 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index bd3c92454f..f1cb58ba26 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -56,42 +56,20 @@ void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch) { - int i; - int r; + int i, r, aa, layer; if (dlsch) { -#ifdef DEBUG_DLSCH_FREE - printf("Freeing dlsch %p\n",dlsch); -#endif - + for (layer=0; layer<4; layer++) { + for (aa=0; aa<64; aa++) free16(dlsch->ue_spec_bf_weights[layer][aa], OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t)); + free16(dlsch->ue_spec_bf_weights[layer], 64*sizeof(int32_t*)); + } for (i=0; iMdlharq; i++) { -#ifdef DEBUG_DLSCH_FREE - printf("Freeing dlsch process %d\n",i); -#endif - if (dlsch->harq_processes[i]) { -#ifdef DEBUG_DLSCH_FREE - printf("Freeing dlsch process %d (%p)\n",i,dlsch->harq_processes[i]); -#endif - if (dlsch->harq_processes[i]->b) { free16(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES); dlsch->harq_processes[i]->b = NULL; -#ifdef DEBUG_DLSCH_FREE - printf("Freeing dlsch process %d b (%p)\n",i,dlsch->harq_processes[i]->b); -#endif } - -#ifdef DEBUG_DLSCH_FREE - printf("Freeing dlsch process %d c (%p)\n",i,dlsch->harq_processes[i]->c); -#endif - for (r=0; rharq_processes[i]->c[r]); -#endif - if (dlsch->harq_processes[i]->c[r]) { free16(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768); dlsch->harq_processes[i]->c[r] = NULL; @@ -100,17 +78,14 @@ void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch) free16(dlsch->harq_processes[i]->d[r],(96+12+3+(3*6144))); dlsch->harq_processes[i]->d[r] = NULL; } - } free16(dlsch->harq_processes[i],sizeof(LTE_DL_eNB_HARQ_t)); dlsch->harq_processes[i] = NULL; } } - free16(dlsch,sizeof(LTE_eNB_DLSCH_t)); dlsch = NULL; - } - + } } LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_t Nsoft,unsigned char N_RB_DL, uint8_t abstraction_flag, LTE_DL_FRAME_PARMS* frame_parms) diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c index 87209e190b..9b761f3cc3 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c @@ -66,33 +66,12 @@ void free_ue_ulsch(LTE_UE_ULSCH_t *ulsch) #endif for (i=0; i<8; i++) { -#ifdef DEBUG_ULSCH_FREE - printf("Freeing ulsch process %d\n",i); -#endif - if (ulsch->harq_processes[i]) { -#ifdef DEBUG_ULSCH_FREE - printf("Freeing ulsch process %d (%p)\n",i,ulsch->harq_processes[i]); -#endif - if (ulsch->harq_processes[i]->b) { free16(ulsch->harq_processes[i]->b,MAX_ULSCH_PAYLOAD_BYTES); ulsch->harq_processes[i]->b = NULL; -#ifdef DEBUG_ULSCH_FREE - printf("Freeing ulsch process %d b (%p)\n",i,ulsch->harq_processes[i]->b); -#endif } - -#ifdef DEBUG_ULSCH_FREE - printf("Freeing ulsch process %d c (%p)\n",i,ulsch->harq_processes[i]->c); -#endif - for (r=0; rharq_processes[i]->c[r]); -#endif - if (ulsch->harq_processes[i]->c[r]) { free16(ulsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768); ulsch->harq_processes[i]->c[r] = NULL; @@ -103,7 +82,6 @@ void free_ue_ulsch(LTE_UE_ULSCH_t *ulsch) ulsch->harq_processes[i] = NULL; } } - free16(ulsch,sizeof(LTE_UE_ULSCH_t)); ulsch = NULL; } From 1eabadb137b9c8c534cb5782ae410afa76f070e2 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 9 Feb 2018 15:47:59 +0100 Subject: [PATCH 114/195] remove unnecessary code from lte-enb.c --- targets/RT/USER/lte-enb.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 58967612dc..5ccc99c041 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -859,15 +859,6 @@ void kill_eNB_proc(int inst) { pthread_cond_destroy( &proc_rxtx[i].cond_rxtx ); } } - - LOG_D(PHY, "joining pthread_asynch_rxtx\n"); - pthread_join(proc->pthread_asynch_rxtx, (void**)&status ); - pthread_mutex_destroy(&proc->mutex_asynch_rxtx); - pthread_cond_destroy(&proc->cond_asynch_rxtx); - - LOG_D(PHY, "joining pthread_single\n"); - pthread_join(proc->pthread_single, (void**)&status ); - LOG_D(PHY, "joined all eNB threads\n"); } } From d746ff61274b101f53728b114f0aa4f62e38ea85 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 9 Feb 2018 16:29:59 +0100 Subject: [PATCH 115/195] update comments in restart_L1L2() --- targets/RT/USER/lte-softmodem.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 3aebf6d279..42a4a7c950 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -969,8 +969,6 @@ int restart_L1L2(module_id_t enb_id) RC.eNB[enb_id][cc_id]->configured = 0; } - - /* TODO undo malloc_IF4p5_buffer() */ RC.ru_mask |= (1 << ru->idx); /* copy the changed frame parameters to the RU */ /* TODO this should be done for all RUs associated to this eNB */ @@ -997,11 +995,9 @@ int restart_L1L2(module_id_t enb_id) RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[enb_id]->configuration; itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); - /* TODO XForms here */ + /* TODO XForms might need to be restarted, but it is currently (09/02/18) + * broken, so we cannot test it */ - /* TODO check for memory leaks */ - /* TODO wait_eNBs() would wait for phy_config_request()? */ - //init_eNB(single_thread_flag,wait_for_sync); wait_eNBs(); init_RU_proc(ru); ru->rf_map.card = 0; @@ -1009,7 +1005,6 @@ int restart_L1L2(module_id_t enb_id) wait_RUs(); init_eNB_afterRU(); - printf("Sending sync to all threads\n"); pthread_mutex_lock(&sync_mutex); sync_var=0; From 8877b18a9a59342905f0c3c4ca3969f1bbd2d717 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 9 Feb 2018 19:05:36 +0100 Subject: [PATCH 116/195] fix eNB_ulsch_dlsch_scheduler() broken by merge 2c8443121d65c2a48 --- openair2/LAYER2/MAC/eNB_scheduler.c | 71 +++++++++++------------------ 1 file changed, 26 insertions(+), 45 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index cf7f84eed2..0e2f84b25b 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -504,22 +504,20 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, int mbsfn_status[MAX_NUM_CCs]; protocol_ctxt_t ctxt; - int CC_id, i; + int CC_id, i = -1; UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; rnti_t rnti; COMMON_channels_t *cc = RC.mac[module_idP]->common_channels; -#if defined(FLEXRAN_AGENT_SB_IF) - Protocol__FlexranMessage *msg; -#endif - - start_meas(&RC.mac[module_idP]->eNB_scheduler); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME (VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, VCD_FUNCTION_IN); + RC.mac[module_idP]->frame = frameP; + RC.mac[module_idP]->subframe = subframeP; + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { mbsfn_status[CC_id] = 0; @@ -531,9 +529,29 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, #if defined(Rel10) || defined(Rel14) cc[CC_id].mcch_active = 0; #endif - RC.mac[module_idP]->frame = frameP; - RC.mac[module_idP]->subframe = subframeP; + clear_nfapi_information(RC.mac[module_idP], CC_id, frameP, subframeP); + } + + // refresh UE list based on UEs dropped by PHY in previous subframe + for (i = 0; i < NUMBER_OF_UE_MAX; i++) { + if (UE_list->active[i] != TRUE) + continue; + + rnti = UE_RNTI(module_idP, i); + CC_id = UE_PCCID(module_idP, i); + + if ((frameP == 0) && (subframeP == 0)) { + LOG_I(MAC, + "UE rnti %x : %s, PHR %d dB DL CQI %d PUSCH SNR %d PUCCH SNR %d\n", + rnti, + UE_list->UE_sched_ctrl[i].ul_out_of_sync == + 0 ? "in synch" : "out of sync", + UE_list->UE_template[CC_id][i].phr_info, + UE_list->UE_sched_ctrl[i].dl_cqi[CC_id], + (UE_list->UE_sched_ctrl[i].pusch_snr[CC_id] - 128) / 2, + (UE_list->UE_sched_ctrl[i].pucch1_snr[CC_id] - 128) / 2); + } RC.eNB[module_idP][CC_id]->pusch_stats_bsr[i][(frameP * 10) + subframeP] = -63; @@ -601,42 +619,6 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, } } - // refresh UE list based on UEs dropped by PHY in previous subframe - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { - if (UE_list->active[i] != TRUE) continue; - - rnti = UE_RNTI(module_idP, i); - CC_id = UE_PCCID(module_idP, i); - - if ((frameP == 0) && (subframeP == 0)) { - LOG_I(MAC, - "UE rnti %x : %s, PHR %d dB DL CQI %d PUSCH SNR %d PUCCH SNR %d\n", - rnti, - UE_list->UE_sched_ctrl[i].ul_out_of_sync == - 0 ? "in synch" : "out of sync", - UE_list->UE_template[CC_id][i].phr_info, - UE_list->UE_sched_ctrl[i].dl_cqi[CC_id], - (UE_list->UE_sched_ctrl[i].pusch_snr[CC_id] - 128) / 2, - (UE_list->UE_sched_ctrl[i].pucch1_snr[CC_id] - 128) / 2); - } - - RC.eNB[module_idP][CC_id]->pusch_stats_bsr[i][(frameP * 10) + subframeP] = -63; - if (i == UE_list->head) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME - (VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, - RC.eNB[module_idP][CC_id]-> - pusch_stats_bsr[i][(frameP * 10) + subframeP]); - // increment this, it is cleared when we receive an sdu - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ul_inactivity_timer++; - - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer++; - LOG_D(MAC, "UE %d/%x : ul_inactivity %d, cqi_req %d\n", i, rnti, - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i]. - ul_inactivity_timer, - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer); - check_ul_failure(module_idP, CC_id, i, frameP, subframeP); - } - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frameP, subframeP, module_idP); @@ -687,7 +669,6 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) allocate_CCEs(module_idP, CC_id, subframeP, 0); - stop_meas(&RC.mac[module_idP]->eNB_scheduler); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME From b073445f9986ae48b2764108aa969fbe540b6e7d Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Fri, 9 Feb 2018 19:15:30 +0100 Subject: [PATCH 117/195] removed NFAPI libraries from oaisim target. added #define to allow ue_ip.ko to compile. This should be revisited, there's a problem in CMakelists.txt, no flags.cmake generate for all 3 kernel modules. --- cmake_targets/CMakeLists.txt | 5 +---- openair2/NETWORK_DRIVER/UE_IP/local.h | 1 + 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 616adf3a82..09dfbf7483 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2065,7 +2065,6 @@ add_executable(oaisim ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c - ${GTPU_need_ITTI} ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c ${XFORMS_SOURCE} ${T_SOURCE} @@ -2077,9 +2076,7 @@ add_executable(oaisim target_include_directories(oaisim PUBLIC ${OPENAIR_TARGETS}/SIMU/USER) target_link_libraries (oaisim -Wl,-ldl,--start-group - RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB GTPV1U SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_UE_LIB PHY_UE LFDS L2 ${MSC_LIB} LIB_NAS_UE SIMU SECU_OSA ${ITTI_LIB} ${MIH_LIB} - NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB - NFAPI_USER_LIB + RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_UE_LIB PHY_UE LFDS L2_UE ${MSC_LIB} LIB_NAS_UE SIMU SECU_OSA ${ITTI_LIB} ${MIH_LIB} -Wl,--end-group z dl) target_link_libraries (oaisim ${LIBXML2_LIBRARIES} ${LAPACK_LIBRARIES}) diff --git a/openair2/NETWORK_DRIVER/UE_IP/local.h b/openair2/NETWORK_DRIVER/UE_IP/local.h index ac3b040995..15fa7a0f91 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/local.h +++ b/openair2/NETWORK_DRIVER/UE_IP/local.h @@ -57,6 +57,7 @@ #include "platform_types.h" #include "sap.h" +#define OAI_NW_DRIVER_USE_NETLINK 1 typedef struct ue_ip_priv_s { int irq; From a78aaa451cfc6452c4f95f4747d09a77488300c8 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 9 Feb 2018 19:08:59 +0100 Subject: [PATCH 118/195] fix slicing capability in ulsch scheduler --- openair2/LAYER2/MAC/defs.h | 3 +- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 15 +- openair2/LAYER2/MAC/pre_processor.c | 496 +++++++++++----------- 3 files changed, 248 insertions(+), 266 deletions(-) diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index 8d99433eb0..de53479e6f 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -692,7 +692,7 @@ typedef struct { uint16_t cshift[8]; // num_max_harq /// Number of Allocated RBs by the ulsch preprocessor - uint8_t pre_allocated_nb_rb_ul; + uint8_t pre_allocated_nb_rb_ul[MAX_NUM_SLICES]; /// index of Allocated RBs by the ulsch preprocessor int8_t pre_allocated_rb_table_index_ul; @@ -804,6 +804,7 @@ typedef struct { uint8_t mac_ContentionResolutionTimer; uint16_t max_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES]; + uint16_t max_rbs_allowed_slice_uplink[MAX_NUM_CCs][MAX_NUM_SLICES]; uint8_t max_mcs[MAX_NUM_LCID]; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 72b9013d93..b24a3f42ac 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -850,7 +850,7 @@ set_msg3_subframe(module_id_t mod_id, int subframe, int rnti, int Msg3_frame, int Msg3_subframe) { - eNB_MAC_INST *mac = RC.mac[Mod_id]; + eNB_MAC_INST *mac = RC.mac[mod_id]; int i; for (i = 0; i < NB_RA_PROC_MAX; i++) { if (mac->common_channels[CC_id].ra[i].state != IDLE && @@ -1069,7 +1069,6 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, } // Run each enabled slice-specific schedulers one by one - /* TODO Navid What is the right call for this message? */ slice_sched_ul[i](module_idP, i, frameP, subframeP, sched_subframe, first_rb); } @@ -1296,10 +1295,9 @@ schedule_ulsch_rnti(module_id_t module_idP, normalized_rx_power = normalized_rx_power; UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power = target_rx_power; UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1 = UE_template->pre_assigned_mcs_ul; - UE_template->mcs_UL[harq_pid] = UE_template->pre_assigned_mcs_ul; //cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS + UE_template->mcs_UL[harq_pid] = cmin(UE_template->pre_assigned_mcs_ul, slice_maxmcs_uplink[slice_id]);//cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS if (UE_template->pre_allocated_rb_table_index_ul >= 0) { - rb_table_index = - UE_template->pre_allocated_rb_table_index_ul; + rb_table_index = UE_template->pre_allocated_rb_table_index_ul; } else { UE_template->mcs_UL[harq_pid] = 10; //cmin (10, openair_daq_vars.target_ue_ul_mcs); rb_table_index = 5; // for PHR @@ -1309,10 +1307,9 @@ schedule_ulsch_rnti(module_id_t module_idP, // buffer_occupancy = UE_template->ul_total_buffer; - while (((rb_table[rb_table_index] > - (N_RB_UL - 1 - first_rb[CC_id])) - || (rb_table[rb_table_index] > 45)) - && (rb_table_index > 0)) { + while (((rb_table[rb_table_index] > (N_RB_UL - 1 - first_rb[CC_id])) + || (rb_table[rb_table_index] > 45)) + && (rb_table_index > 0)) { rb_table_index--; } diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 544a48b80b..6d0d56668d 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -58,6 +58,7 @@ //#define DEBUG_PACKET_TRACE 1 extern float slice_percentage[MAX_NUM_SLICES]; +extern float slice_percentage_uplink[MAX_NUM_SLICES]; //#define ICIC 0 @@ -1377,13 +1378,13 @@ ulsch_scheduler_pre_processor(module_id_t module_idP, total_allocated_rbs[MAX_NUM_CCs], average_rbs_per_user[MAX_NUM_CCs]; int16_t total_remaining_rbs[MAX_NUM_CCs]; - uint16_t max_num_ue_to_be_scheduled = 0; - uint16_t total_ue_count = 0; + uint16_t total_ue_count[MAX_NUM_CCs]; rnti_t rnti = -1; UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; UE_TEMPLATE *UE_template = 0; - int N_RB_DL; - int N_RB_UL; + UE_sched_ctrl *ue_sched_ctl; + int N_RB_UL = 0; + LOG_D(MAC, "In ulsch_preprocessor: assign max mcs min rb\n"); // maximize MCS and then allocate required RB according to the buffer occupancy with the limit of max available UL RB assign_max_mcs_min_rb(module_idP, slice_id, frameP, subframeP, first_rb); @@ -1396,186 +1397,180 @@ ulsch_scheduler_pre_processor(module_id_t module_idP, // we need to distribute RBs among UEs // step1: reset the vars for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - N_RB_DL = - to_prb(RC.mac[module_idP]->common_channels[CC_id].mib-> - message.dl_Bandwidth); - N_RB_UL = - to_prb(RC.mac[module_idP]->common_channels[CC_id]. - ul_Bandwidth); - total_allocated_rbs[CC_id] = 0; - total_remaining_rbs[CC_id] = 0; - average_rbs_per_user[CC_id] = 0; + total_allocated_rbs[CC_id] = 0; + total_remaining_rbs[CC_id] = 0; + average_rbs_per_user[CC_id] = 0; + total_ue_count[CC_id] = 0; + } - for (i = UE_list->head_ul; i >= 0; i = UE_list->next_ul[i]) { - nb_allocated_rbs[CC_id][i] = 0; - } + // Step 1.5: Calculate total_ue_count + for (i = UE_list->head_ul; i >= 0; i = UE_list->next_ul[i]) { + for (n = 0; n < UE_list->numactiveULCCs[i]; n++) { + // This is the actual CC_id in the list + CC_id = UE_list->ordered_ULCCids[n][i]; + UE_template = &UE_list->UE_template[CC_id][i]; + if (flexran_slice_member(i, slice_id) == 0) + continue; + if (UE_template->pre_allocated_nb_rb_ul[slice_id] > 0) { + total_ue_count[CC_id] += 1; + } + } } LOG_D(MAC, "In ulsch_preprocessor: step2 \n"); // step 2: calculate the average rb per UE - total_ue_count = 0; - max_num_ue_to_be_scheduled = 0; - for (i = UE_list->head_ul; i >= 0; i = UE_list->next_ul[i]) { - rnti = UE_RNTI(module_idP, i); + rnti = UE_RNTI(module_idP, i); - if (rnti == NOT_A_RNTI) - continue; + if (rnti == NOT_A_RNTI) + continue; - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; + if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) + continue; + + if (flexran_slice_member(UE_id, slice_id) == 0) + continue; + + UE_id = i; + + LOG_D(MAC, "In ulsch_preprocessor: handling UE %d/%x\n", UE_id, + rnti); + for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { + // This is the actual CC_id in the list + CC_id = UE_list->ordered_ULCCids[n][UE_id]; + LOG_D(MAC, + "In ulsch_preprocessor: handling UE %d/%x CCid %d\n", + UE_id, rnti, CC_id); + + average_rbs_per_user[CC_id] = 0; + + /* + if((mac_xface->get_nCCE_max(module_idP,CC_id,3,subframeP) - nCCE_to_be_used[CC_id]) > (1<numactiveULCCs[UE_id]; n++) { - // This is the actual CC_id in the list - CC_id = UE_list->ordered_ULCCids[n][UE_id]; - LOG_D(MAC, - "In ulsch_preprocessor: handling UE %d/%x CCid %d\n", - UE_id, rnti, CC_id); - UE_template = &UE_list->UE_template[CC_id][UE_id]; - average_rbs_per_user[CC_id] = 0; + N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth); + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] = flexran_nb_rbs_allowed_slice(slice_percentage_uplink[slice_id],N_RB_UL); - if (UE_template->pre_allocated_nb_rb_ul > 0) { - total_ue_count += 1; - } - /* - if((mac_xface->get_nCCE_max(module_idP,CC_id,3,subframeP) - nCCE_to_be_used[CC_id]) > (1< 0) { - average_rbs_per_user[CC_id] = - (uint16_t) floor((N_RB_UL - first_rb[CC_id]) / - max_num_ue_to_be_scheduled); - } else { - average_rbs_per_user[CC_id] = 1; - LOG_W(MAC, - "[eNB %d] frame %d subframe %d: UE %d CC %d: can't get average rb per user (should not be here)\n", - module_idP, frameP, subframeP, UE_id, CC_id); - } - } + if (total_ue_count[CC_id] == 0) { + average_rbs_per_user[CC_id] = 0; + } else if (total_ue_count[CC_id] == 1) { // increase the available RBs, special case, + average_rbs_per_user[CC_id] = ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id] + 1; + } else if (total_ue_count[CC_id] <= (ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id])) { + average_rbs_per_user[CC_id] = (uint16_t) floor((ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id]) / total_ue_count[CC_id]); + } else { + average_rbs_per_user[CC_id] = 1; + LOG_W(MAC, + "[eNB %d] frame %d subframe %d: UE %d CC %d: can't get average rb per user (should not be here)\n", + module_idP, frameP, subframeP, UE_id, CC_id); + } + if (total_ue_count[CC_id] > 0) + LOG_D(MAC, "[eNB %d] Frame %d subframe %d: total ue to be scheduled %d\n", + module_idP, frameP, subframeP, total_ue_count[CC_id]); + } } - if (total_ue_count > 0) - LOG_D(MAC, - "[eNB %d] Frame %d subframe %d: total ue to be scheduled %d/%d\n", - module_idP, frameP, subframeP, total_ue_count, - max_num_ue_to_be_scheduled); - - //LOG_D(MAC,"step3\n"); // step 3: assigne RBS for (i = UE_list->head_ul; i >= 0; i = UE_list->next_ul[i]) { - rnti = UE_RNTI(module_idP, i); + rnti = UE_RNTI(module_idP, i); - if (rnti == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; - - UE_id = i; - - for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { - // This is the actual CC_id in the list - CC_id = UE_list->ordered_ULCCids[n][UE_id]; - harq_pid = - subframe2harqpid(&RC.mac[module_idP]-> - common_channels[CC_id], frameP, - subframeP); + if (rnti == NOT_A_RNTI) + continue; + if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) + continue; + if (flexran_slice_member(i, slice_id) == 0) + continue; - // mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL); + UE_id = i; - if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_id] > 0) { - nb_allocated_rbs[CC_id][UE_id] = - UE_list->UE_template[CC_id][UE_id].nb_rb_ul[harq_pid]; - } else { - nb_allocated_rbs[CC_id][UE_id] = - cmin(UE_list-> - UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul, - average_rbs_per_user[CC_id]); - } + for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { + // This is the actual CC_id in the list + CC_id = UE_list->ordered_ULCCids[n][UE_id]; + UE_template = &UE_list->UE_template[CC_id][UE_id]; + harq_pid = subframe2harqpid(&RC.mac[module_idP]->common_channels[CC_id], + frameP, subframeP); - total_allocated_rbs[CC_id] += nb_allocated_rbs[CC_id][UE_id]; - LOG_D(MAC, - "In ulsch_preprocessor: assigning %d RBs for UE %d/%x CCid %d, harq_pid %d\n", - nb_allocated_rbs[CC_id][UE_id], UE_id, rnti, CC_id, - harq_pid); - } + // mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL); + + if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_id] > 0) { + nb_allocated_rbs[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb_ul[harq_pid]; + } else { + nb_allocated_rbs[CC_id][UE_id] = + cmin(UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[slice_id], + average_rbs_per_user[CC_id]); + } + + total_allocated_rbs[CC_id] += nb_allocated_rbs[CC_id][UE_id]; + LOG_D(MAC, + "In ulsch_preprocessor: assigning %d RBs for UE %d/%x CCid %d, harq_pid %d\n", + nb_allocated_rbs[CC_id][UE_id], UE_id, rnti, CC_id, + harq_pid); + } } // step 4: assigne the remaining RBs and set the pre_allocated rbs accordingly - for (r = 0; r < 2; r++) { + for (r = 0; r < 2; r++) { - for (i = UE_list->head_ul; i >= 0; i = UE_list->next_ul[i]) { - rnti = UE_RNTI(module_idP, i); + for (i = UE_list->head_ul; i >= 0; i = UE_list->next_ul[i]) { + rnti = UE_RNTI(module_idP, i); - if (rnti == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; - UE_id = i; + if (rnti == NOT_A_RNTI) + continue; + if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) + continue; + if (flexran_slice_member(i, slice_id) == 0) + continue; - for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { - // This is the actual CC_id in the list - CC_id = UE_list->ordered_ULCCids[n][UE_id]; - UE_template = &UE_list->UE_template[CC_id][UE_id]; - total_remaining_rbs[CC_id] = - N_RB_UL - first_rb[CC_id] - total_allocated_rbs[CC_id]; + UE_id = i; - if (total_ue_count == 1) { - total_remaining_rbs[CC_id] += 1; - } + for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { + // This is the actual CC_id in the list + CC_id = UE_list->ordered_ULCCids[n][UE_id]; + UE_template = &UE_list->UE_template[CC_id][UE_id]; + total_remaining_rbs[CC_id] = + ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id] - total_allocated_rbs[CC_id]; - if (r == 0) { - while ((UE_template->pre_allocated_nb_rb_ul > 0) && - (nb_allocated_rbs[CC_id][UE_id] < - UE_template->pre_allocated_nb_rb_ul) - && (total_remaining_rbs[CC_id] > 0)) { - nb_allocated_rbs[CC_id][UE_id] = - cmin(nb_allocated_rbs[CC_id][UE_id] + 1, - UE_template->pre_allocated_nb_rb_ul); - total_remaining_rbs[CC_id]--; - total_allocated_rbs[CC_id]++; - } - } else { - UE_template->pre_allocated_nb_rb_ul = - nb_allocated_rbs[CC_id][UE_id]; - LOG_D(MAC, - "******************UL Scheduling Information for UE%d CC_id %d ************************\n", - UE_id, CC_id); - LOG_D(MAC, - "[eNB %d] total RB allocated for UE%d CC_id %d = %d\n", - module_idP, UE_id, CC_id, - UE_template->pre_allocated_nb_rb_ul); - } - } - } + if (total_ue_count[CC_id] == 1) { + total_remaining_rbs[CC_id] += 1; + } + + if (r == 0) { + while ((UE_template->pre_allocated_nb_rb_ul[slice_id] > 0) + && (nb_allocated_rbs[CC_id][UE_id] < UE_template->pre_allocated_nb_rb_ul[slice_id]) + && (total_remaining_rbs[CC_id] > 0)) { + nb_allocated_rbs[CC_id][UE_id] = + cmin(nb_allocated_rbs[CC_id][UE_id] + 1, + UE_template->pre_allocated_nb_rb_ul[slice_id]); + total_remaining_rbs[CC_id]--; + total_allocated_rbs[CC_id]++; + } + } else { + UE_template->pre_allocated_nb_rb_ul[slice_id] = + nb_allocated_rbs[CC_id][UE_id]; + LOG_D(MAC, + "******************UL Scheduling Information for UE%d CC_id %d ************************\n", + UE_id, CC_id); + LOG_D(MAC, + "[eNB %d] total RB allocated for UE%d CC_id %d = %d\n", + module_idP, UE_id, CC_id, + UE_template->pre_allocated_nb_rb_ul[slice_id]); + } + } } + } for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { if (total_allocated_rbs[CC_id] > 0) { LOG_D(MAC, "[eNB %d] total RB allocated for all UEs = %d/%d\n", module_idP, total_allocated_rbs[CC_id], - N_RB_UL - first_rb[CC_id]); + ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id]); } } } @@ -1586,134 +1581,123 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, sub_frame_t subframeP, uint16_t * first_rb) { - int i; - uint16_t n, UE_id; - uint8_t CC_id; - rnti_t rnti = -1; - int mcs; - int rb_table_index = 0, tbs, tx_power; - eNB_MAC_INST *eNB = RC.mac[module_idP]; - UE_list_t *UE_list = &eNB->UE_list; + int i; + uint16_t n, UE_id; + uint8_t CC_id; + rnti_t rnti = -1; + int mcs; + int rb_table_index = 0, tbs, tx_power; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &eNB->UE_list; - UE_TEMPLATE *UE_template; - int Ncp; - int N_RB_UL; + UE_TEMPLATE *UE_template; + UE_sched_ctrl *ue_sched_ctl; + int Ncp; + int N_RB_UL; - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { - if (UE_list->active[i] != TRUE) - continue; + for (i = 0; i < NUMBER_OF_UE_MAX; i++) { + if (UE_list->active[i] != TRUE) + continue; - rnti = UE_RNTI(module_idP, i); + rnti = UE_RNTI(module_idP, i); - if (rnti == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; + if (rnti == NOT_A_RNTI) + continue; + if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) + continue; + if (flexran_slice_member(i, slice_id) == 0) + continue; - if (UE_list->UE_sched_ctrl[i].phr_received == 1) - mcs = 20; // if we've received the power headroom information the UE, we can go to maximum mcs - else - mcs = 10; // otherwise, limit to QPSK PUSCH + if (UE_list->UE_sched_ctrl[i].phr_received == 1) + mcs = 20; // if we've received the power headroom information the UE, we can go to maximum mcs + else + mcs = 10; // otherwise, limit to QPSK PUSCH - UE_id = i; + UE_id = i; - for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { - // This is the actual CC_id in the list - CC_id = UE_list->ordered_ULCCids[n][UE_id]; + for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { + // This is the actual CC_id in the list + CC_id = UE_list->ordered_ULCCids[n][UE_id]; - if (CC_id >= MAX_NUM_CCs) { - LOG_E(MAC, - "CC_id %u should be < %u, loop n=%u < numactiveULCCs[%u]=%u", - CC_id, MAX_NUM_CCs, n, UE_id, - UE_list->numactiveULCCs[UE_id]); - } + if (CC_id >= MAX_NUM_CCs) { + LOG_E(MAC, "CC_id %u should be < %u, loop n=%u < numactiveULCCs[%u]=%u", + CC_id, MAX_NUM_CCs, n, UE_id, UE_list->numactiveULCCs[UE_id]); + } - AssertFatal(CC_id < MAX_NUM_CCs, - "CC_id %u should be < %u, loop n=%u < numactiveULCCs[%u]=%u", - CC_id, MAX_NUM_CCs, n, UE_id, - UE_list->numactiveULCCs[UE_id]); + AssertFatal(CC_id < MAX_NUM_CCs, + "CC_id %u should be < %u, loop n=%u < numactiveULCCs[%u]=%u", + CC_id, MAX_NUM_CCs, n, UE_id, + UE_list->numactiveULCCs[UE_id]); - UE_template = &UE_list->UE_template[CC_id][UE_id]; + UE_template = &UE_list->UE_template[CC_id][UE_id]; + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - Ncp = RC.mac[module_idP]->common_channels[CC_id].Ncp; - N_RB_UL = - to_prb(RC.mac[module_idP]->common_channels[CC_id]. - ul_Bandwidth); - // if this UE has UL traffic - int bytes_to_schedule = UE_template->estimated_ul_buffer - UE_template->scheduled_ul_bytes; - if (bytes_to_schedule < 0) bytes_to_schedule = 0; - int bits_to_schedule = bytes_to_schedule * 8; + Ncp = RC.mac[module_idP]->common_channels[CC_id].Ncp; + N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth); + ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] = flexran_nb_rbs_allowed_slice(slice_percentage_uplink[slice_id],N_RB_UL); - if (bits_to_schedule > 0) { - tbs = get_TBS_UL(mcs, 3) << 3; // 1 or 2 PRB with cqi enabled does not work well! - rb_table_index = 2; + // if this UE has UL traffic + if (UE_template->ul_total_buffer > 0) { + tbs = get_TBS_UL(mcs, 3) << 3; // 1 or 2 PRB with cqi enabled does not work well! + rb_table_index = 2; - // fixme: set use_srs flag - tx_power = - estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, - Ncp, 0); + // fixme: set use_srs flag + tx_power = estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, Ncp, 0); - while ((((UE_template->phr_info - tx_power) < 0) - || (tbs > bits_to_schedule)) - && (mcs > 3)) { - // LOG_I(MAC,"UE_template->phr_info %d tx_power %d mcs %d\n", UE_template->phr_info,tx_power, mcs); - mcs--; - tbs = get_TBS_UL(mcs, rb_table[rb_table_index]) << 3; - tx_power = estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, Ncp, 0); // fixme: set use_srs - } + while ((((UE_template->phr_info - tx_power) < 0) + || (tbs > UE_template->ul_total_buffer)) + && (mcs > 3)) { + // LOG_I(MAC,"UE_template->phr_info %d tx_power %d mcs %d\n", UE_template->phr_info,tx_power, mcs); + mcs--; + tbs = get_TBS_UL(mcs, rb_table[rb_table_index]) << 3; + tx_power = estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, Ncp, 0); // fixme: set use_srs + } - while ((tbs < bits_to_schedule) && - (rb_table[rb_table_index] < - (N_RB_UL - first_rb[CC_id])) - && ((UE_template->phr_info - tx_power) > 0) - && (rb_table_index < 32)) { + while ((tbs < bits_to_schedule) + && (rb_table[rb_table_index] < (ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id] - first_rb[CC_id])) + && ((UE_template->phr_info - tx_power) > 0) + && (rb_table_index < 32)) { + rb_table_index++; + tbs = get_TBS_UL(mcs, rb_table[rb_table_index]) << 3; + tx_power = estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, Ncp, 0); + } - rb_table_index++; - tbs = get_TBS_UL(mcs, rb_table[rb_table_index]) << 3; - tx_power = - estimate_ue_tx_power(tbs, rb_table[rb_table_index], - 0, Ncp, 0); - } + UE_template->ue_tx_power = tx_power; - UE_template->ue_tx_power = tx_power; + if (rb_table[rb_table_index] > (ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id] - first_rb[CC_id] - 1)) { + rb_table_index--; + } + // 1 or 2 PRB with cqi enabled does not work well + if (rb_table[rb_table_index] < 3) { + rb_table_index = 2; //3PRB + } - if (rb_table[rb_table_index] > - (N_RB_UL - first_rb[CC_id] - 1)) { - rb_table_index--; - } - // 1 or 2 PRB with cqi enabled does not work well - if (rb_table[rb_table_index] < 3) { - rb_table_index = 2; //3PRB - } - - UE_template->pre_assigned_mcs_ul = mcs; - UE_template->pre_allocated_rb_table_index_ul = - rb_table_index; - UE_template->pre_allocated_nb_rb_ul = - rb_table[rb_table_index]; - LOG_D(MAC, - "[eNB %d] frame %d subframe %d: for UE %d CC %d: pre-assigned mcs %d, pre-allocated rb_table[%d]=%d RBs (phr %d, tx power %d)\n", - module_idP, frameP, subframeP, UE_id, CC_id, - UE_template->pre_assigned_mcs_ul, - UE_template->pre_allocated_rb_table_index_ul, - UE_template->pre_allocated_nb_rb_ul, - UE_template->phr_info, tx_power); - } else { - /* if UE has pending scheduling request then pre-allocate 3 RBs */ - //if (UE_template->ul_active == 1 && UE_template->ul_SR == 1) { - if (UE_is_to_be_scheduled(module_idP, CC_id, i)) { - /* use QPSK mcs */ - UE_template->pre_assigned_mcs_ul = 10; - UE_template->pre_allocated_rb_table_index_ul = 2; - UE_template->pre_allocated_nb_rb_ul = 3; - } else { - UE_template->pre_assigned_mcs_ul = 0; - UE_template->pre_allocated_rb_table_index_ul = -1; - UE_template->pre_allocated_nb_rb_ul = 0; - } - } - } + UE_template->pre_assigned_mcs_ul = mcs; + UE_template->pre_allocated_rb_table_index_ul = rb_table_index; + UE_template->pre_allocated_nb_rb_ul[slice_id] = rb_table[rb_table_index]; + LOG_D(MAC, + "[eNB %d] frame %d subframe %d: for UE %d CC %d: pre-assigned mcs %d, pre-allocated rb_table[%d]=%d RBs (phr %d, tx power %d)\n", + module_idP, frameP, subframeP, UE_id, CC_id, + UE_template->pre_assigned_mcs_ul, + UE_template->pre_allocated_rb_table_index_ul, + UE_template->pre_allocated_nb_rb_ul[slice_id], + UE_template->phr_info, tx_power); + } else { + /* if UE has pending scheduling request then pre-allocate 3 RBs */ + //if (UE_template->ul_active == 1 && UE_template->ul_SR == 1) { + if (UE_is_to_be_scheduled(module_idP, CC_id, i)) { + /* use QPSK mcs */ + UE_template->pre_assigned_mcs_ul = 10; + UE_template->pre_allocated_rb_table_index_ul = 2; + UE_template->pre_allocated_nb_rb_ul[slice_id] = 3; + } else { + UE_template->pre_assigned_mcs_ul = 0; + UE_template->pre_allocated_rb_table_index_ul = -1; + UE_template->pre_allocated_nb_rb_ul[slice_id] = 0; + } + } } + } } struct sort_ue_ul_params { From cf0a5ca9205e2a9fb8650e6c06373257921d2e0f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 9 Feb 2018 19:10:41 +0100 Subject: [PATCH 119/195] fix RAN API due to merge + repair functions --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 2 +- openair2/ENB_APP/flexran_agent_common.c | 4 +-- openair2/ENB_APP/flexran_agent_ran_api.c | 30 +++++++------------ openair2/ENB_APP/flexran_agent_ran_api.h | 10 +++---- 4 files changed, 18 insertions(+), 28 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 4f5d8af250..f875264967 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -83,7 +83,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, goto error; for (j = 0; j < ue_report[i]->n_bsr; j++) { // NN: we need to know the cc_id here, consider the first one - elem[j] = flexran_get_ue_bsr (enb_id, i, j); + elem[j] = flexran_get_ue_bsr_ul_buffer_info (enb_id, i, j); } ue_report[i]->bsr = elem; diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index de0de15c0a..f837d575d5 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -489,10 +489,10 @@ int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__Fl lc_config[j]->has_lcid = 1; lc_config[j]->lcid = j+1; - int lcg = flexran_get_lcg(i, j+1); + int lcg = flexran_get_lcg(mod_id, i, j+1); if (lcg >= 0 && lcg <= 3) { lc_config[j]->has_lcg = 1; - lc_config[j]->lcg = flexran_get_lcg(i,j+1); + lc_config[j]->lcg = flexran_get_lcg(mod_id, i,j+1); } lc_config[j]->has_direction = 1; diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index ddbc3ad869..97a77a634c 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -117,10 +117,10 @@ rnti_t flexran_get_ue_crnti(mid_t mod_id, mid_t ue_id) return UE_RNTI(mod_id, ue_id); } -uint8_t flexran_get_ue_bsr(mid_t mod_id, mid_t ue_id, lcid_t lcid) +int flexran_get_ue_bsr_ul_buffer_info(mid_t mod_id, mid_t ue_id, lcid_t lcid) { - if (!mac_is_present(mod_id)) return 0; - return RC.mac[mod_id]->UE_list.UE_template[UE_PCCID(mod_id, ue_id)][ue_id].bsr_info[lcid]; + if (!mac_is_present(mod_id)) return -1; + return RC.mac[mod_id]->UE_list.UE_template[UE_PCCID(mod_id, ue_id)][ue_id].ul_buffer_info[lcid]; } int8_t flexran_get_ue_phr(mid_t mod_id, mid_t ue_id) @@ -390,7 +390,6 @@ PHICH_DURATION_t flexran_get_phich_duration(mid_t mod_id, uint8_t cc_id) int flexran_get_phich_resource(mid_t mod_id, uint8_t cc_id) { if (!phy_is_present(mod_id, cc_id)) return 0; - /* TODO why don't we return phich_resource? */ switch (RC.eNB[mod_id][cc_id]->frame_parms.phich_config_common.phich_resource) { case oneSixth: return 0; @@ -544,12 +543,10 @@ uint8_t flexran_get_sib1_length(mid_t mod_id, uint8_t cc_id) return RC.rrc[mod_id]->carrier[cc_id].sizeof_SIB1; } -uint8_t flexran_get_num_pdcch_symb(mid_t mod_id, uint8_t cc_id) { - /* TODO: This should return the number of PDCCH symbols initially used by the - * cell cc_id -> is the correction right? */ +uint8_t flexran_get_num_pdcch_symb(mid_t mod_id, uint8_t cc_id) +{ if (!phy_is_present(mod_id, cc_id)) return 0; return RC.eNB[mod_id][cc_id]->pdcch_vars[0].num_pdcch_symbols; - //(PHY_vars_UE_g[mod_id][cc_id]->lte_ue_pdcch_vars[mod_id]->num_pdcch_symbols); } @@ -614,12 +611,11 @@ long flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id) } } -/* TODO is there a reason we take the RNTI and not the UE ID? */ -/* TODO return type is unsigned, so we cannot return -1 in case of error! */ -uint8_t flexran_get_rrc_status(mid_t mod_id, rnti_t rnti) +uint8_t flexran_get_rrc_status(mid_t mod_id, mid_t ue_id) { if (!rrc_is_present(mod_id)) return 0; + rnti_t rnti = flexran_get_ue_crnti(mod_id, ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return RRC_INACTIVE; @@ -893,14 +889,10 @@ int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id) } } -/* TODO Navid: Get the same for eNB */ -long flexran_get_lcg(mid_t ue_id, mid_t lc_id) +long flexran_get_lcg(mid_t mod_id, mid_t ue_id, mid_t lc_id) { - if (!UE_mac_inst) return -1; - if (!UE_mac_inst[ue_id].logicalChannelConfig[lc_id]) return -1; - if (!UE_mac_inst[ue_id].logicalChannelConfig[lc_id]->ul_SpecificParameters) return -1; - if (!UE_mac_inst[ue_id].logicalChannelConfig[lc_id]->ul_SpecificParameters->logicalChannelGroup) return -1; - return *(UE_mac_inst[ue_id].logicalChannelConfig[lc_id]->ul_SpecificParameters->logicalChannelGroup); + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.UE_template[UE_PCCID(mod_id, ue_id)][ue_id].lcgidmap[lc_id]; } /* TODO Navid: needs to be revised */ @@ -923,14 +915,12 @@ uint8_t flexran_get_antenna_ports(mid_t mod_id, uint8_t cc_id) return RC.eNB[mod_id][cc_id]->frame_parms.nb_antenna_ports_eNB; } -/* TODO better give real value (without division)? */ uint32_t flexran_agent_get_operating_dl_freq(mid_t mod_id, uint8_t cc_id) { if (!phy_is_present(mod_id, cc_id)) return 0; return RC.eNB[mod_id][cc_id]->frame_parms.dl_CarrierFreq / 1000000; } -/* TODO better give real value (without division)? */ uint32_t flexran_agent_get_operating_ul_freq(mid_t mod_id, uint8_t cc_id) { if (!phy_is_present(mod_id, cc_id)) return 0; diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 62752f1308..b3515c9c6c 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -77,9 +77,9 @@ int flexran_get_num_ues(mid_t mod_id); /* Get the rnti of a UE with id ue_id */ rnti_t flexran_get_ue_crnti(mid_t mod_id, mid_t ue_id); -/* Get the RLC buffer status report of a ue for a designated - logical channel id */ -uint8_t flexran_get_ue_bsr(mid_t mod_id, mid_t ue_id, lcid_t lcid); +/* Get the RLC buffer status report in bytes of a ue for a designated + * logical channel id */ +int flexran_get_ue_bsr_ul_buffer_info(mid_t mod_id, mid_t ue_id, lcid_t lcid); /* Get power headroom of UE with id ue_id */ int8_t flexran_get_ue_phr(mid_t mod_id, mid_t ue_id); @@ -302,7 +302,7 @@ long flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id); int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id); /* Get logical channel group of a channel with id lc_id */ -long flexran_get_lcg(mid_t ue_id, mid_t lc_id); +long flexran_get_lcg(mid_t mod_id, mid_t ue_id, mid_t lc_id); /* Get direction of logical channel with id lc_id */ int flexran_get_direction(mid_t ue_id, mid_t lc_id); @@ -338,7 +338,7 @@ void flexran_agent_set_operating_bandwidth(mid_t mod_id, uint8_t cc_id, uint8_t void flexran_agent_set_operating_frame_type(mid_t mod_id, uint8_t cc_id, lte_frame_type_t frame_type); /*RRC status flexRAN*/ -uint8_t flexran_get_rrc_status(const mid_t mod_id, const rnti_t rntiP); +uint8_t flexran_get_rrc_status(mid_t mod_id, mid_t ue_id); /***************************** PDCP ***********************/ From 8108d59a0bdb2eba243173b5fa8b9548631e617e Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 12 Feb 2018 12:10:21 +0100 Subject: [PATCH 120/195] no regression, fixes compilation warnings&errors --- openair2/LAYER2/MAC/pre_processor.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 6d0d56668d..12c80e9efe 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -1422,6 +1422,7 @@ ulsch_scheduler_pre_processor(module_id_t module_idP, for (i = UE_list->head_ul; i >= 0; i = UE_list->next_ul[i]) { rnti = UE_RNTI(module_idP, i); + UE_id = i; if (rnti == NOT_A_RNTI) continue; @@ -1432,8 +1433,6 @@ ulsch_scheduler_pre_processor(module_id_t module_idP, if (flexran_slice_member(UE_id, slice_id) == 0) continue; - UE_id = i; - LOG_D(MAC, "In ulsch_preprocessor: handling UE %d/%x\n", UE_id, rnti); for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { @@ -1528,6 +1527,7 @@ ulsch_scheduler_pre_processor(module_id_t module_idP, continue; UE_id = i; + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { // This is the actual CC_id in the list @@ -1636,8 +1636,12 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth); ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] = flexran_nb_rbs_allowed_slice(slice_percentage_uplink[slice_id],N_RB_UL); + int bytes_to_schedule = UE_template->estimated_ul_buffer - UE_template->scheduled_ul_bytes; + if (bytes_to_schedule < 0) bytes_to_schedule = 0; + int bits_to_schedule = bytes_to_schedule * 8; + // if this UE has UL traffic - if (UE_template->ul_total_buffer > 0) { + if (bits_to_schedule > 0) { tbs = get_TBS_UL(mcs, 3) << 3; // 1 or 2 PRB with cqi enabled does not work well! rb_table_index = 2; @@ -1645,7 +1649,7 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, tx_power = estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, Ncp, 0); while ((((UE_template->phr_info - tx_power) < 0) - || (tbs > UE_template->ul_total_buffer)) + || (tbs > bits_to_schedule)) && (mcs > 3)) { // LOG_I(MAC,"UE_template->phr_info %d tx_power %d mcs %d\n", UE_template->phr_info,tx_power, mcs); mcs--; @@ -1654,7 +1658,7 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, } while ((tbs < bits_to_schedule) - && (rb_table[rb_table_index] < (ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id] - first_rb[CC_id])) + && (rb_table[rb_table_index] < (ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id])) && ((UE_template->phr_info - tx_power) > 0) && (rb_table_index < 32)) { rb_table_index++; @@ -1664,7 +1668,7 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, UE_template->ue_tx_power = tx_power; - if (rb_table[rb_table_index] > (ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id] - first_rb[CC_id] - 1)) { + if (rb_table[rb_table_index] > (ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id] - 1)) { rb_table_index--; } // 1 or 2 PRB with cqi enabled does not work well From ceece5694dda2a80f1a36abf18bccd6b6c2b50ef Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 12 Feb 2018 12:30:36 +0100 Subject: [PATCH 121/195] rename flexran_slice_member() -> ue_slice_membership() --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 2 +- .../LAYER2/MAC/eNB_scheduler_primitives.c | 2 +- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 2 +- openair2/LAYER2/MAC/pre_processor.c | 24 +++++++++---------- openair2/LAYER2/MAC/proto.h | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 7c836c9e72..bed97e47c6 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -710,7 +710,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, LOG_D(MAC, "[eNB] Cannot find eNB_UE_stats\n"); continue_flag = 1; } - if (flexran_slice_member(UE_id, slice_idP) == 0) + if (!ue_slice_membership(UE_id, slice_idP)) continue; if (continue_flag != 1) { diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 046a823a87..341db67934 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -4050,7 +4050,7 @@ uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, int total_rbs) return (uint16_t) floor(rb_percentage * total_rbs); } -int flexran_slice_member(int UE_id, int slice_id) +int ue_slice_membership(int UE_id, int slice_id) { if ((slice_id < 0) || (slice_id > n_active_slices)) LOG_W(MAC, "out of range slice id %d\n", slice_id); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index b24a3f42ac..2403ec2d13 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -1126,7 +1126,7 @@ schedule_ulsch_rnti(module_id_t module_idP, for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) { - if (flexran_slice_member(UE_id, slice_id) == 0) + if (!ue_slice_membership(UE_id, slice_id)) continue; // don't schedule if Msg4 is not received yet diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 12c80e9efe..c179c211b2 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -107,7 +107,7 @@ store_dlsch_buffer(module_id_t Mod_id, slice_id_t slice_id, frame_t frameP, if (UE_list->active[UE_id] != TRUE) continue; - if (flexran_slice_member(UE_id, slice_id) == 0) + if (!ue_slice_membership(UE_id, slice_id)) continue; UE_template = @@ -201,7 +201,7 @@ assign_rbs_required(module_id_t Mod_id, for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { if (UE_list->active[UE_id] != TRUE) continue; - if (flexran_slice_member(UE_id, slice_id) == 0) + if (!ue_slice_membership(UE_id, slice_id)) continue; pCCid = UE_PCCID(Mod_id, UE_id); @@ -610,7 +610,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, if (UE_list->active[i] != TRUE) continue; - if (!flexran_slice_member(i, slice_id)) + if (!ue_slice_membership(i, slice_id)) continue; UE_id = i; @@ -659,7 +659,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; UE_id = i; - if (flexran_slice_member(UE_id, slice_id) == 0) + if (!ue_slice_membership(UE_id, slice_id)) continue; for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { @@ -698,7 +698,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; UE_id = i; - if (flexran_slice_member(UE_id, slice_id) == 0) + if (!ue_slice_membership(UE_id, slice_id)) continue; for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { @@ -743,7 +743,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, continue; if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (flexran_slice_member(i, slice_id) == 0) + if (!ue_slice_membership(i, slice_id)) continue; for (ii = 0; ii < UE_num_active_CC(UE_list, i); ii++) { @@ -820,7 +820,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; - if (flexran_slice_member(i, slice_id) == 0) + if (!ue_slice_membership(i, slice_id)) continue; transmission_mode = get_tmode(Mod_id, CC_id, UE_id); @@ -1409,7 +1409,7 @@ ulsch_scheduler_pre_processor(module_id_t module_idP, // This is the actual CC_id in the list CC_id = UE_list->ordered_ULCCids[n][i]; UE_template = &UE_list->UE_template[CC_id][i]; - if (flexran_slice_member(i, slice_id) == 0) + if (!ue_slice_membership(i, slice_id)) continue; if (UE_template->pre_allocated_nb_rb_ul[slice_id] > 0) { total_ue_count[CC_id] += 1; @@ -1430,7 +1430,7 @@ ulsch_scheduler_pre_processor(module_id_t module_idP, if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (flexran_slice_member(UE_id, slice_id) == 0) + if (!ue_slice_membership(UE_id, slice_id)) continue; LOG_D(MAC, "In ulsch_preprocessor: handling UE %d/%x\n", UE_id, @@ -1482,7 +1482,7 @@ ulsch_scheduler_pre_processor(module_id_t module_idP, continue; if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (flexran_slice_member(i, slice_id) == 0) + if (!ue_slice_membership(i, slice_id)) continue; @@ -1523,7 +1523,7 @@ ulsch_scheduler_pre_processor(module_id_t module_idP, continue; if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (flexran_slice_member(i, slice_id) == 0) + if (!ue_slice_membership(i, slice_id)) continue; UE_id = i; @@ -1605,7 +1605,7 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, continue; if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (flexran_slice_member(i, slice_id) == 0) + if (!ue_slice_membership(i, slice_id)) continue; if (UE_list->UE_sched_ctrl[i].phr_received == 1) diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/proto.h index ba13f45e26..c0d294ded6 100644 --- a/openair2/LAYER2/MAC/proto.h +++ b/openair2/LAYER2/MAC/proto.h @@ -1197,7 +1197,7 @@ int l2_init_ue(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, /*Slice related functions */ uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, int total_rbs); -int flexran_slice_member(int UE_id, int slice_id); +int ue_slice_membership(int UE_id, int slice_id); #endif /** @}*/ From 3768723c62e0bc3871ff211d9ac20e97bcc83fb5 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 12 Feb 2018 12:40:27 +0100 Subject: [PATCH 122/195] remove unnecessary comments --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 1 - openair2/LAYER2/MAC/proto.h | 9 ++------- openair2/RRC/LITE/rrc_eNB.c | 1 - 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index bed97e47c6..fb123134f8 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -541,7 +541,6 @@ schedule_dlsch(module_id_t module_idP, } // Run each enabled slice-specific schedulers one by one - /* TODO Navid took out the dl_info additional information */ slice_sched_dl[i](module_idP, i, frameP, subframeP, mbsfn_flag/*, dl_info*/); } diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/proto.h index c0d294ded6..be09385ac9 100644 --- a/openair2/LAYER2/MAC/proto.h +++ b/openair2/LAYER2/MAC/proto.h @@ -38,23 +38,18 @@ /** * slice specific scheduler */ -/* TODO Navid: Protocol__FlexranMessage -> unknown when compiling without - * FlexRAN, what to do with it? Matches schedule_ue_spec now */ typedef void (*slice_scheduler_dl)(module_id_t mod_id, slice_id_t slice_id, frame_t frame, sub_frame_t subframe, - int *mbsfn_flag - /* Protocol__FlexranMessage **dl_info*/); + int *mbsfn_flag); -/* TODO Navid: the same as above, matches schedule_ulsch_rnti now */ typedef void (*slice_scheduler_ul)(module_id_t mod_id, slice_id_t slice_id, frame_t frame, sub_frame_t subframe, unsigned char sched_subframe, - uint16_t *first_rb - /* Protocol__FlexranMessage **ul_info*/); + uint16_t *first_rb); /** \fn void schedule_mib(module_id_t module_idP,frame_t frameP,sub_frame_t subframe); \brief MIB scheduling for PBCH. This function requests the MIB from RRC and provides it to L1. diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index 6f35f28ebd..c49b9283e2 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -3362,7 +3362,6 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons } #if defined(FLEXRAN_AGENT_SB_IF) -/* TODO Navid: does this belong here? */ //----------------------------------------------------------------------------- void flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* const ctxt_pP, From adec4e39df7dcb692c4c4ce27bc6703d2a68ca60 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 12 Feb 2018 14:38:44 +0100 Subject: [PATCH 123/195] remove all conditional FlexRAN-related compilation directives --- common/ran_context.h | 4 ---- openair2/ENB_APP/enb_config.c | 2 -- openair2/ENB_APP/enb_config.h | 2 -- openair2/LAYER2/MAC/eNB_scheduler.c | 6 ------ openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 2 -- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 2 -- openair2/RRC/LITE/L2_interface.c | 4 ---- openair2/RRC/LITE/proto.h | 6 ------ openair2/RRC/LITE/rrc_eNB.c | 13 ------------- targets/RT/USER/lte-softmodem.c | 3 +-- targets/RT/USER/lte-softmodem.h | 6 ++---- targets/SIMU/USER/oaisim.c | 4 +--- 12 files changed, 4 insertions(+), 50 deletions(-) diff --git a/common/ran_context.h b/common/ran_context.h index d5e2a1f172..f59fd8a79c 100644 --- a/common/ran_context.h +++ b/common/ran_context.h @@ -40,9 +40,7 @@ #include "PHY/impl_defs_top.h" #include "PHY/impl_defs_lte.h" #include "RRC/LITE/defs.h" -#ifdef FLEXRAN_AGENT_SB_IF #include "flexran_agent_defs.h" -#endif #include "gtpv1u.h" #include "NwGtpv1u.h" @@ -67,10 +65,8 @@ typedef struct { int *nb_L1_CC; /// Number of RU instances in this node int nb_RU; -#ifdef FLEXRAN_AGENT_SB_IF /// FlexRAN context variables flexran_agent_info_t **flexran; -#endif /// eNB context variables struct PHY_VARS_eNB_s ***eNB; /// RRC context variables diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index d6f676b83a..1bf2807e81 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -98,7 +98,6 @@ static int enb_check_band_frequencies(char* lib_config_file_name_pP, return errors; } -#ifdef FLEXRAN_AGENT_SB_IF void RCconfig_flexran() { int i; @@ -134,7 +133,6 @@ void RCconfig_flexran() /* TODO: show FlexRAN config now? */ } -#endif void RCconfig_L1(void) { int i,j; diff --git a/openair2/ENB_APP/enb_config.h b/openair2/ENB_APP/enb_config.h index 4e4434ad70..42bef9c4e9 100644 --- a/openair2/ENB_APP/enb_config.h +++ b/openair2/ENB_APP/enb_config.h @@ -94,9 +94,7 @@ typedef struct ru_config_s { } ru_config_t; extern void RCconfig_RU(void); -#ifdef FLEXRAN_AGENT_SB_IF extern void RCconfig_flexran(void); -#endif extern void RCconfig_L1(void); extern void RCconfig_macrlc(void); extern int RCconfig_gtpu(void ); diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 0e2f84b25b..45c1a422dd 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -52,11 +52,9 @@ //#include "LAYER2/MAC/pre_processor.c" #include "pdcp.h" -#if defined(FLEXRAN_AGENT_SB_IF) //Agent-related headers #include "flexran_agent_extern.h" #include "flexran_agent_mac.h" -#endif #if defined(ENABLE_ITTI) #include "intertask_interface.h" @@ -419,12 +417,10 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id, } // ul_failure_timer>0 //Inform the controller about the UE deactivation. Should be moved to RRC agent in the future -#if defined(FLEXRAN_AGENT_SB_IF) if (rrc_agent_registered[module_idP]) { agent_rrc_xface[module_idP]->flexran_agent_notify_ue_state_change(module_idP, rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); } -#endif 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))){ @@ -661,9 +657,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, // This schedules DLSCH in subframeP schedule_dlsch(module_idP, frameP, subframeP, mbsfn_status); -#if defined(FLEXRAN_AGENT_SB_IF) flexran_agent_send_update_stats(module_idP); -#endif // Allocate CCEs for good after scheduling is done for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index fb123134f8..0936a9d0ef 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -57,12 +57,10 @@ #include "intertask_interface.h" #endif -#if defined FLEXRAN_AGENT_SB_IF #include "ENB_APP/flexran_agent_defs.h" #include "flexran_agent_ran_api.h" #include "header.pb-c.h" #include "flexran.pb-c.h" -#endif #include #include "T.h" diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 2403ec2d13..47b6a075cf 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -57,13 +57,11 @@ #include "intertask_interface.h" #endif -#if defined FLEXRAN_AGENT_SB_IF #include "ENB_APP/flexran_agent_defs.h" #include "flexran_agent_ran_api.h" #include "header.pb-c.h" #include "flexran.pb-c.h" #include "flexran_agent_mac.h" -#endif #include #include "T.h" diff --git a/openair2/RRC/LITE/L2_interface.c b/openair2/RRC/LITE/L2_interface.c index f285330854..91834d9c9d 100644 --- a/openair2/RRC/LITE/L2_interface.c +++ b/openair2/RRC/LITE/L2_interface.c @@ -53,9 +53,7 @@ extern UE_MAC_INST *UE_mac_inst; # include "intertask_interface.h" #endif -#if defined(FLEXRAN_AGENT_SB_IF) #include "flexran_agent_extern.h" -#endif //#define RRC_DATA_REQ_DEBUG //#define DEBUG_RRC 1 @@ -470,13 +468,11 @@ void mac_eNB_rrc_ul_failure(const module_id_t Mod_instP, else { LOG_W(RRC,"Frame %d, Subframe %d: UL failure: UE %x unknown \n",frameP,subframeP,rntiP); } -#if defined(FLEXRAN_AGENT_SB_IF) if (rrc_agent_registered[Mod_instP]) { agent_rrc_xface[Mod_instP]->flexran_agent_notify_ue_state_change(Mod_instP, rntiP, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); } -#endif // rrc_mac_remove_ue(Mod_instP,rntiP); } diff --git a/openair2/RRC/LITE/proto.h b/openair2/RRC/LITE/proto.h index 0f5ccdef1b..9ece5bcfdd 100644 --- a/openair2/RRC/LITE/proto.h +++ b/openair2/RRC/LITE/proto.h @@ -33,9 +33,7 @@ #include "RRC/LITE/defs.h" -#if defined(FLEXRAN_AGENT_SB_IF) #include "flexran_agent_extern.h" -#endif //main.c int rrc_init_global_param(void); @@ -274,8 +272,6 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration( ); -#if defined(FLEXRAN_AGENT_SB_IF) - void flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration( const protocol_ctxt_t* const ctxt_pP, @@ -284,8 +280,6 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration( agent_reconf_rrc * trig_param ); -#endif - int freq_to_arfcn10(int band, unsigned long freq); void diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index c49b9283e2..2c8be5cfc6 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -871,12 +871,10 @@ rrc_eNB_free_UE(const module_id_t enb_mod_idP,const struct rrc_eNB_ue_context_s* } } -#if defined(FLEXRAN_AGENT_SB_IF) if (rrc_agent_registered[enb_mod_idP]) { agent_rrc_xface[enb_mod_idP]->flexran_agent_notify_ue_state_change(enb_mod_idP, rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); } -#endif for(j = 0; j < 10; j++){ ul_req_tmp = &eNB_MAC->UL_req_tmp[CC_id][j].ul_config_request_body; @@ -3361,7 +3359,6 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons PDCP_TRANSMISSION_MODE_CONTROL); } -#if defined(FLEXRAN_AGENT_SB_IF) //----------------------------------------------------------------------------- void flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* const ctxt_pP, @@ -3952,8 +3949,6 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt PDCP_TRANSMISSION_MODE_CONTROL); } -#endif - //----------------------------------------------------------------------------- int @@ -6294,13 +6289,11 @@ rrc_eNB_decode_ccch( } else { // no context available -#if defined(FLEXRAN_AGENT_SB_IF) if (rrc_agent_registered[ctxt_pP->module_id]) { agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, ctxt_pP->rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); } -#endif LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Can't create new context for UE random UE identity (0x%" PRIx64 ")\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), random_value); @@ -6562,14 +6555,12 @@ rrc_eNB_decode_dcch( ue_context_p, ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); -#if defined(FLEXRAN_AGENT_SB_IF) //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future if (rrc_agent_registered[ctxt_pP->module_id]) { agent_rrc_xface[ctxt_pP->eNB_index]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, ue_context_p->ue_id_rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_UPDATED); } -#endif } #if defined(ENABLE_ITTI) # if defined(ENABLE_USE_MME) @@ -6704,14 +6695,12 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.rrc_TransactionIdentifier, &ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.criticalExtensions.choice.rrcConnectionReestablishmentComplete_r8); -#if defined(FLEXRAN_AGENT_SB_IF) //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future if (mac_agent_registered[ctxt_pP->module_id]) { agent_rrc_xface[ctxt_pP->eNB_index]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, ue_context_p->ue_id_rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED); } -#endif } //ue_context_p->ue_context.ue_release_timer = 0; ue_context_p->ue_context.ue_reestablishment_timer = 1; @@ -6761,14 +6750,12 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_CONNECTED \n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); -#if defined(FLEXRAN_AGENT_SB_IF) //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future if (rrc_agent_registered[ctxt_pP->module_id]) { agent_rrc_xface[ctxt_pP->eNB_index]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, ue_context_p->ue_id_rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED); } -#endif } } diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 42a4a7c950..f6789086b4 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1319,12 +1319,11 @@ int main( int argc, char **argv ) } #endif -#ifdef FLEXRAN_AGENT_SB_IF + /* Start the agent. If it is turned off in the configuration, it won't start */ RCconfig_flexran(); for (i = 0; i < RC.nb_L1_inst; i++) { flexran_agent_start(i); } -#endif // init UE_PF_PO and mutex lock pthread_mutex_init(&ue_pf_po_mutex, NULL); diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index d8f6e3c7e9..5cc4d5fea2 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -31,6 +31,8 @@ #include "PHY/defs.h" #include "SIMULATION/ETH_TRANSPORT/proto.h" +#include "flexran_agent.h" + #if defined(ENABLE_ITTI) #if defined(ENABLE_USE_MME) #include "s1ap_eNB.h" @@ -271,8 +273,4 @@ void init_eNB_afterRU(void); extern int stop_L1L2(module_id_t enb_id); extern int restart_L1L2(module_id_t enb_id); -#ifdef FLEXRAN_AGENT_SB_IF -#include "flexran_agent.h" -#endif - #endif diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index 7d8b33f12c..302b77b60f 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -76,9 +76,7 @@ uint8_t config_smbv = 0; char smbv_ip[16]; #endif -#if defined(FLEXRAN_AGENT_SB_IF) -# include "flexran_agent.h" -#endif +#include "flexran_agent.h" #include "oaisim_functions.h" From 219b5bc92f25bca7203ac42bc3203381170cb50b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 12 Feb 2018 15:11:19 +0100 Subject: [PATCH 124/195] make FlexRAN Agent activation configurable --- openair2/ENB_APP/enb_config.c | 7 ++----- openair2/ENB_APP/enb_paramdef.h | 13 ++++++++----- openair2/ENB_APP/flexran_agent.c | 6 ++++++ openair2/ENB_APP/flexran_agent_defs.h | 1 + 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 1bf2807e81..a30dc28c94 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -119,19 +119,16 @@ void RCconfig_flexran() AssertFatal(RC.flexran[i] != NULL, "can't ALLOCATE %zu Bytes for flexran agent info (iteration %d/%d)\n", sizeof(flexran_agent_info_t), i + 1, RC.nb_L1_inst); + /* 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]->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); - //strcpy(in_ip, DEFAULT_FLEXRAN_AGENT_IPv4_ADDRESS ); RC.flexran[i]->remote_ipv4_addr = strdup(*(flexranParams[FLEXRAN_IPV4_ADDRESS_IDX].strptr)); - // DEFAULT_FLEXRAN_AGENT_PORT RC.flexran[i]->remote_port = *(flexranParams[FLEXRAN_PORT_IDX].uptr); - // DEFAULT_FLEXRAN_AGENT_CACHE 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; } - - /* TODO: show FlexRAN config now? */ } void RCconfig_L1(void) { diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index 0203380314..2d65e09b58 100755 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -613,19 +613,22 @@ static int DEFENBS[] = {0}; /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ #define CONFIG_STRING_NETWORK_CONTROLLER_CONFIG "NETWORK_CONTROLLER" +#define CONFIG_STRING_FLEXRAN_ENABLED "FLEXRAN_ENABLED" #define CONFIG_STRING_FLEXRAN_INTERFACE_NAME "FLEXRAN_INTERFACE_NAME" #define CONFIG_STRING_FLEXRAN_IPV4_ADDRESS "FLEXRAN_IPV4_ADDRESS" #define CONFIG_STRING_FLEXRAN_PORT "FLEXRAN_PORT" #define CONFIG_STRING_FLEXRAN_CACHE "FLEXRAN_CACHE" #define CONFIG_STRING_FLEXRAN_AWAIT_RECONF "FLEXRAN_AWAIT_RECONF" -#define FLEXRAN_INTERFACE_NAME_IDX 0 -#define FLEXRAN_IPV4_ADDRESS_IDX 1 -#define FLEXRAN_PORT_IDX 2 -#define FLEXRAN_CACHE_IDX 3 -#define FLEXRAN_AWAIT_RECONF_IDX 4 +#define FLEXRAN_ENABLED 0 +#define FLEXRAN_INTERFACE_NAME_IDX 1 +#define FLEXRAN_IPV4_ADDRESS_IDX 2 +#define FLEXRAN_PORT_IDX 3 +#define FLEXRAN_CACHE_IDX 4 +#define FLEXRAN_AWAIT_RECONF_IDX 5 #define FLEXRANPARAMS_DESC { \ +{CONFIG_STRING_FLEXRAN_ENABLED, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \ {CONFIG_STRING_FLEXRAN_INTERFACE_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ {CONFIG_STRING_FLEXRAN_IPV4_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ {CONFIG_STRING_FLEXRAN_PORT, NULL, 0, uptr:NULL, defintval:2210, TYPE_UINT, 0}, \ diff --git a/openair2/ENB_APP/flexran_agent.c b/openair2/ENB_APP/flexran_agent.c index d32f3e660f..bd46ecc49d 100644 --- a/openair2/ENB_APP/flexran_agent.c +++ b/openair2/ENB_APP/flexran_agent.c @@ -184,6 +184,12 @@ int flexran_agent_start(mid_t mod_id) int channel_id; char *in_ip = flexran->remote_ipv4_addr; uint16_t in_port = flexran->remote_port; + + /* if this agent is disabled, return and don't do anything */ + if (!flexran->enabled) { + 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 diff --git a/openair2/ENB_APP/flexran_agent_defs.h b/openair2/ENB_APP/flexran_agent_defs.h index fd22b01e61..6364bc6281 100644 --- a/openair2/ENB_APP/flexran_agent_defs.h +++ b/openair2/ENB_APP/flexran_agent_defs.h @@ -153,6 +153,7 @@ typedef enum { typedef struct { /* general info */ + int enabled; char *interface_name; char *remote_ipv4_addr; uint16_t remote_port; From 1056604b25eb8ba2e0469842818d1a8dc26e1b72 Mon Sep 17 00:00:00 2001 From: Emad Date: Mon, 12 Feb 2018 13:56:08 +0100 Subject: [PATCH 125/195] I tried to change rx and tx attenuation by the config file, but they are not changed. The bug is because att_rx and att_tx do not put in RC.rru when local_rf is "yes" in config file. We need to put att_rx and att_rx for both local_rf = "yes" and "no". Also RF config which send to RF device must be fill by this parameters. --- targets/RT/USER/lte-ru.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 65d945dd7e..d2455266ce 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -1273,8 +1273,8 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { cfg->tx_freq[i] = (double)fp->dl_CarrierFreq; cfg->rx_freq[i] = (double)fp->ul_CarrierFreq; - cfg->tx_gain[i] = (double)fp->att_tx; - cfg->rx_gain[i] = ru->max_rxgain-(double)fp->att_rx; + cfg->tx_gain[i] = ru->att_tx; + cfg->rx_gain[i] = ru->max_rxgain-ru->att_rx; cfg->configFilename = rf_config_file; printf("channel %d, Setting tx_gain offset %f, rx_gain offset %f, tx_freq %f, rx_freq %f\n", @@ -2256,13 +2256,13 @@ void RCconfig_RU(void) { RC.ru[j]->if_timing = synch_to_other; RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF5_MOBIPASS; } - RC.ru[j]->att_tx = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr); - RC.ru[j]->att_rx = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr); } /* strcmp(local_rf, "yes") != 0 */ RC.ru[j]->nb_tx = *(RUParamList.paramarray[j][RU_NB_TX_IDX].uptr); RC.ru[j]->nb_rx = *(RUParamList.paramarray[j][RU_NB_RX_IDX].uptr); + RC.ru[j]->att_tx = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr); + RC.ru[j]->att_rx = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr); }// j=0..num_rus } else { RC.nb_RU = 0; From 135b06ae66ab485a1cd0ca7945a57e3a6675f664 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 12 Feb 2018 15:21:02 +0100 Subject: [PATCH 126/195] bugfix: only send eNB stats to controller if agent enabled --- openair2/LAYER2/MAC/eNB_scheduler.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 45c1a422dd..fb4fd6553b 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -657,7 +657,8 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, // This schedules DLSCH in subframeP schedule_dlsch(module_idP, frameP, subframeP, mbsfn_status); - flexran_agent_send_update_stats(module_idP); + if (RC.flexran[module_idP]->enabled) + flexran_agent_send_update_stats(module_idP); // Allocate CCEs for good after scheduling is done for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) From 54e803e71a3647f3e109e74cf75de9cc01eed8d3 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 12 Feb 2018 15:21:44 +0100 Subject: [PATCH 127/195] Sample configuration FlexRAN: Agent is disabled --- .../GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf index 227decbcd6..c4307f8ff2 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf @@ -191,6 +191,7 @@ RUs = ( NETWORK_CONTROLLER : { + FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "lo"; FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; FLEXRAN_PORT = 2210; From 6210eb056f880a52edfe9de64c6839154a5c7429 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 12 Feb 2018 15:26:45 +0100 Subject: [PATCH 128/195] bugfix: fix ue_ip.ko compilation Not sure that the use of __KERNEL__ is the correct solution. To be checked at some point. After this commit, the following works: ./build_oai --UE -c --- cmake_targets/CMakeLists.txt | 2 +- common/utils/itti/itti_types.h | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 616adf3a82..31b3f8e4c7 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2297,7 +2297,7 @@ add_custom_command ( # retrieve the compiler options to send it to gccxml get_directory_property(DirDefs COMPILE_DEFINITIONS ) foreach( d ${DirDefs} ) - set(module_cc_opt_tmp "${module_cc_opt_tmp} -D${d}") + set(module_cc_opt "${module_cc_opt} -D${d}") endforeach() get_directory_property( DirDefs INCLUDE_DIRECTORIES ) foreach( d ${DirDefs} ) diff --git a/common/utils/itti/itti_types.h b/common/utils/itti/itti_types.h index d07853133b..2607c003b1 100644 --- a/common/utils/itti/itti_types.h +++ b/common/utils/itti/itti_types.h @@ -27,7 +27,18 @@ #ifndef _ITTI_TYPES_H_ #define _ITTI_TYPES_H_ -#include +/* The current file is included in the ue_ip.ko compilation. + * For it to work we need to include linux/types.h and + * not stdint.h. + * A solution to this problem is to use #ifndef __KERNEL__. + * Maybe a better solution would be to clean things up + * so that ue_ip.ko does not include the current file. + */ +#ifndef __KERNEL__ +# include +#else +# include +#endif #define CHARS_TO_UINT32(c1, c2, c3, c4) (((c4) << 24) | ((c3) << 16) | ((c2) << 8) | (c1)) From 4bf4ad8e98b4a9d920e165cf46c38ec4ddea3608 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 12 Feb 2018 15:30:30 +0100 Subject: [PATCH 129/195] change build scripts: always compile FlexRAN --- cmake_targets/CMakeLists.txt | 158 +++++++++++++++++------------------ cmake_targets/build_oai | 23 +---- 2 files changed, 81 insertions(+), 100 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 44d80d4633..56c3ea651b 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -599,8 +599,6 @@ add_boolean_option(MESSAGE_CHART_GENERATOR False "For generating sequenc add_boolean_option(MESSAGE_CHART_GENERATOR_RLC_MAC False "trace RLC-MAC exchanges in sequence diagrams") add_boolean_option(MESSAGE_CHART_GENERATOR_PHY False "trace some PHY exchanges in sequence diagrams") -add_boolean_option(FLEXRAN_AGENT_SB_IF False "enable FlexRAN agent to inteface with a SDN controller") - ######################## # Include order ########################## @@ -789,96 +787,94 @@ include_directories("${OPENAIR_DIR}") # Utilities Library ################ -if (FLEXRAN_AGENT_SB_IF) - # set the version of protobuf messages, V3 not supported yet - add_list1_option(FLPT_VERSION V2 "FLPT MSG protobuf grammar version" V2 V3) +# set the version of protobuf messages, V3 not supported yet +add_list1_option(FLPT_VERSION V2 "FLPT MSG protobuf grammar version" V2 V3) - if (${FLPT_VERSION} STREQUAL "V2") - set (FLPTDIR V2) - elseif (${FLPT_VERSION} STREQUAL "V3") - set (FLPTDIR V3) - endif(${FLPT_VERSION} STREQUAL "V2") +if (${FLPT_VERSION} STREQUAL "V2") + set (FLPTDIR V2) +elseif (${FLPT_VERSION} STREQUAL "V3") + set (FLPTDIR V3) +endif(${FLPT_VERSION} STREQUAL "V2") - set(FLPT_MSG_DIR ${OPENAIR2_DIR}/ENB_APP/MESSAGES/${FLPTDIR} ) - set(FLPT_MSG_FILES - ${FLPT_MSG_DIR}/header.proto - ${FLPT_MSG_DIR}/flexran.proto - ${FLPT_MSG_DIR}/stats_common.proto - ${FLPT_MSG_DIR}/stats_messages.proto - ${FLPT_MSG_DIR}/time_common.proto - ${FLPT_MSG_DIR}/controller_commands.proto - ${FLPT_MSG_DIR}/mac_primitives.proto - ${FLPT_MSG_DIR}/config_messages.proto - ${FLPT_MSG_DIR}/config_common.proto - ${FLPT_MSG_DIR}/control_delegation.proto - ) +set(FLPT_MSG_DIR ${OPENAIR2_DIR}/ENB_APP/MESSAGES/${FLPTDIR} ) +set(FLPT_MSG_FILES + ${FLPT_MSG_DIR}/header.proto + ${FLPT_MSG_DIR}/flexran.proto + ${FLPT_MSG_DIR}/stats_common.proto + ${FLPT_MSG_DIR}/stats_messages.proto + ${FLPT_MSG_DIR}/time_common.proto + ${FLPT_MSG_DIR}/controller_commands.proto + ${FLPT_MSG_DIR}/mac_primitives.proto + ${FLPT_MSG_DIR}/config_messages.proto + ${FLPT_MSG_DIR}/config_common.proto + ${FLPT_MSG_DIR}/control_delegation.proto + ) - set(FLPT_C_DIR ${protobuf_generated_dir}/${FLPTDIR}) - #message("calling protoc_call=${protoc_call} FLPT_C_DIR=${FLPT_C_DIR} FLPT_MSG_FILES=${FLPT_MSG_FILES}") - execute_process(COMMAND ${protoc_call} ${FLPT_C_DIR} ${FLPT_MSG_DIR} ${FLPT_MSG_FILES}) - file(GLOB FLPT_source ${FLPT_C_DIR}/*.c) - set(FLPT_OAI_generated - ${FLPT_C_DIR}/header.pb-c.c - ${FLPT_C_DIR}/flexran.pb-c.c - ${FLPT_C_DIR}/stats_common.pb-c.c - ${FLPT_C_DIR}/stats_messages.pb-c.c - ${FLPT_C_DIR}/time_common.pb-c.c - ${FLPT_C_DIR}/controller_commands.pb-c.c - ${FLPT_C_DIR}/mac_primitives.pb-c.c - ${FLPT_C_DIR}/config_messages.pb-c.c - ${FLPT_C_DIR}/config_common.pb-c.c - ${FLPT_C_DIR}/control_delegation.pb-c.c - ) +set(FLPT_C_DIR ${protobuf_generated_dir}/${FLPTDIR}) +#message("calling protoc_call=${protoc_call} FLPT_C_DIR=${FLPT_C_DIR} FLPT_MSG_FILES=${FLPT_MSG_FILES}") +execute_process(COMMAND ${protoc_call} ${FLPT_C_DIR} ${FLPT_MSG_DIR} ${FLPT_MSG_FILES}) +file(GLOB FLPT_source ${FLPT_C_DIR}/*.c) +set(FLPT_OAI_generated + ${FLPT_C_DIR}/header.pb-c.c + ${FLPT_C_DIR}/flexran.pb-c.c + ${FLPT_C_DIR}/stats_common.pb-c.c + ${FLPT_C_DIR}/stats_messages.pb-c.c + ${FLPT_C_DIR}/time_common.pb-c.c + ${FLPT_C_DIR}/controller_commands.pb-c.c + ${FLPT_C_DIR}/mac_primitives.pb-c.c + ${FLPT_C_DIR}/config_messages.pb-c.c + ${FLPT_C_DIR}/config_common.pb-c.c + ${FLPT_C_DIR}/control_delegation.pb-c.c + ) - file(GLOB flpt_h ${FLPT_C_DIR}/*.h) - set(flpt_h ${flpt_h} ) +file(GLOB flpt_h ${FLPT_C_DIR}/*.h) +set(flpt_h ${flpt_h} ) - add_library(FLPT_MSG - ${FLPT_OAI_generated} - ${FLPT_source} - ) - set(FLPT_MSG_LIB FLPT_MSG) - #message("prpt c dir is : ${FLPT_C_DIR}") - include_directories (${FLPT_C_DIR}) +add_library(FLPT_MSG + ${FLPT_OAI_generated} + ${FLPT_source} + ) +set(FLPT_MSG_LIB FLPT_MSG) +#message("prpt c dir is : ${FLPT_C_DIR}") +include_directories (${FLPT_C_DIR}) - add_library(ASYNC_IF - ${OPENAIR2_DIR}/UTIL/ASYNC_IF/socket_link.c - ${OPENAIR2_DIR}/UTIL/ASYNC_IF/link_manager.c - ${OPENAIR2_DIR}/UTIL/ASYNC_IF/message_queue.c - ${OPENAIR2_DIR}/UTIL/ASYNC_IF/ringbuffer_queue.c - ) - set(ASYNC_IF_LIB ASYNC_IF) - include_directories(${OPENAIR2_DIR}/UTIL/ASYNC_IF) +add_library(ASYNC_IF + ${OPENAIR2_DIR}/UTIL/ASYNC_IF/socket_link.c + ${OPENAIR2_DIR}/UTIL/ASYNC_IF/link_manager.c + ${OPENAIR2_DIR}/UTIL/ASYNC_IF/message_queue.c + ${OPENAIR2_DIR}/UTIL/ASYNC_IF/ringbuffer_queue.c + ) +set(ASYNC_IF_LIB ASYNC_IF) +include_directories(${OPENAIR2_DIR}/UTIL/ASYNC_IF) - add_library(FLEXRAN_AGENT - ${OPENAIR2_DIR}/ENB_APP/flexran_agent_handler.c - ${OPENAIR2_DIR}/ENB_APP/flexran_agent_common.c - ${OPENAIR2_DIR}/ENB_APP/flexran_agent_ran_api.c - ${OPENAIR2_DIR}/ENB_APP/flexran_agent_timer.c - ${OPENAIR2_DIR}/ENB_APP/flexran_agent_common_internal.c - ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c - ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c - ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c - ${OPENAIR2_DIR}/ENB_APP/flexran_agent.c - ${OPENAIR2_DIR}/ENB_APP/flexran_agent_task_manager.c - ${OPENAIR2_DIR}/ENB_APP/flexran_agent_net_comm.c - ${OPENAIR2_DIR}/ENB_APP/flexran_agent_async.c - ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c - ) - set(FLEXRAN_AGENT_LIB FLEXRAN_AGENT) - #include_directories(${OPENAIR2_DIR}/ENB_APP) +add_library(FLEXRAN_AGENT + ${OPENAIR2_DIR}/ENB_APP/flexran_agent_handler.c + ${OPENAIR2_DIR}/ENB_APP/flexran_agent_common.c + ${OPENAIR2_DIR}/ENB_APP/flexran_agent_ran_api.c + ${OPENAIR2_DIR}/ENB_APP/flexran_agent_timer.c + ${OPENAIR2_DIR}/ENB_APP/flexran_agent_common_internal.c + ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c + ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c + ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c + ${OPENAIR2_DIR}/ENB_APP/flexran_agent.c + ${OPENAIR2_DIR}/ENB_APP/flexran_agent_task_manager.c + ${OPENAIR2_DIR}/ENB_APP/flexran_agent_net_comm.c + ${OPENAIR2_DIR}/ENB_APP/flexran_agent_async.c + ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c + ) +set(FLEXRAN_AGENT_LIB FLEXRAN_AGENT) +#include_directories(${OPENAIR2_DIR}/ENB_APP) - set(PROTOBUF_LIB "protobuf-c") +set(PROTOBUF_LIB "protobuf-c") - FIND_PATH(LIBYAML_INCLUDE_DIR NAMES yaml.h) - FIND_LIBRARY(LIBYAML_LIBRARIES NAMES yaml libyaml) +FIND_PATH(LIBYAML_INCLUDE_DIR NAMES yaml.h) +FIND_LIBRARY(LIBYAML_LIBRARIES NAMES yaml libyaml) - INCLUDE(FindPackageHandleStandardArgs) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(Yaml DEFAULT_MSG LIBYAML_LIBRARIES LIBYAML_INCLUDE_DIR) - MARK_AS_ADVANCED(LIBYAML_INCLUDE_DIR LIBYAML_LIBRARIES) +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Yaml DEFAULT_MSG LIBYAML_LIBRARIES LIBYAML_INCLUDE_DIR) +MARK_AS_ADVANCED(LIBYAML_INCLUDE_DIR LIBYAML_LIBRARIES) - #set(PROTOBUF_LIB "protobuf") #for Cpp -endif() +#set(PROTOBUF_LIB "protobuf") #for Cpp add_library(HASHTABLE diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 0d48f51df9..7e0c0ca169 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -42,7 +42,6 @@ conf_nvram_path=$OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf MSC_GEN="False" XFORMS="True" -FLEXRAN_AGENT_SB_IF="True" PRINT_STATS="False" VCD_TIMING="False" DEADLINE_SCHEDULER_FLAG_USER="False" @@ -100,8 +99,6 @@ Options Specify conf_nvram_path (default \"$conf_nvram_path\") --UE-gen-nvram [output path] Specify gen_nvram_path (default \"$gen_nvram_path\") --a | --agent - Enables agent for software-defined control of the eNB -r | --3gpp-release default is Rel14, Rel8 limits the implementation to 3GPP Release 8 version @@ -204,8 +201,7 @@ function main() { echo_info "Will compile eNB" shift;; -a | --agent) - FLEXRAN_AGENT=1 - echo_info "Will compile eNB with agent support" + echo_info "FlexRAN support is always compiled into the eNB" shift;; --UE) UE=1 @@ -465,11 +461,9 @@ function main() { flash_firmware_bladerf fi fi - if [ "$FLEXRAN_AGENT" == "1" ] ; then - echo_info "installing protobuf/protobuf-c for flexran agent support" - install_protobuf_from_source - install_protobuf_c_from_source - fi + echo_info "installing protobuf/protobuf-c for flexran agent support" + install_protobuf_from_source + install_protobuf_c_from_source fi if [ "$INSTALL_OPTIONAL" = "1" ] ; then @@ -517,9 +511,6 @@ function main() { echo "set ( CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE )" >> $cmake_file echo "set ( CFLAGS_PROCESSOR_USER \"$CFLAGS_PROCESSOR_USER\" )" >> $cmake_file echo "set ( XFORMS $XFORMS )" >> $cmake_file - if [ "$FLEXRAN_AGENT" = "1" ] ; then - echo "set ( FLEXRAN_AGENT_SB_IF $FLEXRAN_AGENT_SB_IF )" >> $cmake_file - fi echo "set ( RRC_ASN1_VERSION \"${REL}\")" >> $cmake_file echo "set ( ENABLE_VCD_FIFO $VCD_TIMING )" >> $cmake_file echo "set ( RF_BOARD \"${HW}\")" >> $cmake_file @@ -679,9 +670,6 @@ function main() { echo "set ( CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE )" >> $cmake_file echo "set ( CFLAGS_PROCESSOR_USER \"$CFLAGS_PROCESSOR_USER\" )" >> $cmake_file echo "set ( XFORMS $XFORMS )" >> $cmake_file - if [ "$FLEXRAN_AGENT" = "1" ] ; then - echo "set ( FLEXRAN_AGENT_SB_IF $FLEXRAN_AGENT_SB_IF )" >> $cmake_file - fi echo "set ( PRINT_STATS $PRINT_STATS )" >> $cmake_file echo "set ( RRC_ASN1_VERSION \"${REL}\")" >> $cmake_file echo "set ( ENABLE_VCD_FIFO $VCD_TIMING )" >> $cmake_file @@ -762,9 +750,6 @@ function main() { cp $DIR/oaisim_mme_build_oai/CMakeLists.template $cmake_file echo "set ( CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE )" >> $cmake_file echo "set ( XFORMS $XFORMS )" >> $cmake_file - if [ "$FLEXRAN_AGENT" = "1" ] ; then - echo "set ( FLEXRAN_AGENT_SB_IF $FLEXRAN_AGENT_SB_IF )" >> $cmake_file - fi echo "set ( RRC_ASN1_VERSION \"${REL}\")" >> $cmake_file echo "set ( ENABLE_VCD_FIFO $VCD_TIMING )" >> $cmake_file echo "set ( T_TRACER $T_TRACER )" >> $cmake_file From ddd3e97f141917e7868a953b918915f6cdb11d94 Mon Sep 17 00:00:00 2001 From: Emad Date: Thu, 8 Feb 2018 07:54:47 +0100 Subject: [PATCH 130/195] srb_id must be between [1,3] --- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 91621ab50f..bb264a8906 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -993,7 +993,7 @@ pdcp_remove_UE( } } - for (srb_id=0; srb_id<2; srb_id++) { + for (srb_id=1; srb_id<3; srb_id++) { key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, srb_id, SRB_FLAG_YES); h_rc = hashtable_remove(pdcp_coll_p, key); } From e794f920c73ff0d891ae8c3033027be9d649a2ab Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 12 Feb 2018 16:13:04 +0100 Subject: [PATCH 131/195] integration fix: remove definition of OAI_NW_DRIVER_USE_NETLINK in source file This is done better by commit 6210eb056f880a52edfe9de64c6839154a5c7429. --- openair2/NETWORK_DRIVER/UE_IP/local.h | 1 - 1 file changed, 1 deletion(-) diff --git a/openair2/NETWORK_DRIVER/UE_IP/local.h b/openair2/NETWORK_DRIVER/UE_IP/local.h index 15fa7a0f91..ac3b040995 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/local.h +++ b/openair2/NETWORK_DRIVER/UE_IP/local.h @@ -57,7 +57,6 @@ #include "platform_types.h" #include "sap.h" -#define OAI_NW_DRIVER_USE_NETLINK 1 typedef struct ue_ip_priv_s { int irq; From 5865c141d03a89aed04c8496cd2b260e1800b017 Mon Sep 17 00:00:00 2001 From: Navid Nikaein Date: Tue, 13 Feb 2018 11:45:16 +0100 Subject: [PATCH 132/195] Improve UL/DL MCS assignment --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 8 ++++---- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 8 ++++---- openair2/LAYER2/MAC/pre_processor.c | 24 ++++++++++++----------- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 0936a9d0ef..7d0a93c2bf 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -789,12 +789,12 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE); */ if (nfapi_mode) { - eNB_UE_stats->dlsch_mcs1 = 10;//cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; + eNB_UE_stats->dlsch_mcs1 = 10;//cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; } - else { - eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; + else { // this operation is also done in the preprocessor + eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, slice_maxmcs[slice_idP]); //cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); } - eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, slice_maxmcs[slice_idP]); //cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); + // store stats diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 47b6a075cf..a8d686dac9 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -1289,11 +1289,11 @@ schedule_ulsch_rnti(module_id_t module_idP, ndi = 1 - UE_template->oldNDI_UL[harq_pid]; UE_template->oldNDI_UL[harq_pid] = ndi; - UE_list->eNB_UE_stats[CC_id][UE_id]. - normalized_rx_power = normalized_rx_power; + UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power = normalized_rx_power; UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power = target_rx_power; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1 = UE_template->pre_assigned_mcs_ul; - UE_template->mcs_UL[harq_pid] = cmin(UE_template->pre_assigned_mcs_ul, slice_maxmcs_uplink[slice_id]);//cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS + UE_template->mcs_UL[harq_pid] = cmin(UE_template->pre_assigned_mcs_ul, slice_maxmcs_uplink[slice_id]); + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1= UE_template->mcs_UL[harq_pid]; + //cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS if (UE_template->pre_allocated_rb_table_index_ul >= 0) { rb_table_index = UE_template->pre_allocated_rb_table_index_ul; } else { diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index c179c211b2..3a27f70009 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -60,6 +60,10 @@ extern float slice_percentage[MAX_NUM_SLICES]; extern float slice_percentage_uplink[MAX_NUM_SLICES]; +extern int slice_maxmcs[MAX_NUM_SLICES]; +extern int slice_maxmcs_uplink[MAX_NUM_SLICES]; + + //#define ICIC 0 /* this function checks that get_eNB_UE_stats returns @@ -211,8 +215,8 @@ assign_rbs_required(module_id_t Mod_id, CC_id = UE_list->ordered_CCids[n][UE_id]; eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; - eNB_UE_stats->dlsch_mcs1 = - cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]]; + eNB_UE_stats->dlsch_mcs1 =cmin(cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]], + slice_maxmcs[slice_id]); } @@ -1585,7 +1589,6 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, uint16_t n, UE_id; uint8_t CC_id; rnti_t rnti = -1; - int mcs; int rb_table_index = 0, tbs, tx_power; eNB_MAC_INST *eNB = RC.mac[module_idP]; UE_list_t *UE_list = &eNB->UE_list; @@ -1609,9 +1612,9 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, continue; if (UE_list->UE_sched_ctrl[i].phr_received == 1) - mcs = 20; // if we've received the power headroom information the UE, we can go to maximum mcs + UE_template->pre_assigned_mcs_ul = cmin(20, slice_maxmcs_uplink[slice_id]); // if we've received the power headroom information the UE, we can go to maximum mcs else - mcs = 10; // otherwise, limit to QPSK PUSCH + UE_template->pre_assigned_mcs_ul = cmin(10, slice_maxmcs_uplink[slice_id]); // otherwise, limit to QPSK PUSCH UE_id = i; @@ -1642,7 +1645,7 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, // if this UE has UL traffic if (bits_to_schedule > 0) { - tbs = get_TBS_UL(mcs, 3) << 3; // 1 or 2 PRB with cqi enabled does not work well! + tbs = get_TBS_UL(UE_template->pre_assigned_mcs_ul, 3) << 3; // 1 or 2 PRB with cqi enabled does not work well! rb_table_index = 2; // fixme: set use_srs flag @@ -1650,10 +1653,10 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, while ((((UE_template->phr_info - tx_power) < 0) || (tbs > bits_to_schedule)) - && (mcs > 3)) { + && (UE_template->pre_assigned_mcs_ul > 3)) { // LOG_I(MAC,"UE_template->phr_info %d tx_power %d mcs %d\n", UE_template->phr_info,tx_power, mcs); - mcs--; - tbs = get_TBS_UL(mcs, rb_table[rb_table_index]) << 3; + UE_template->pre_assigned_mcs_ul--; + tbs = get_TBS_UL(UE_template->pre_assigned_mcs_ul, rb_table[rb_table_index]) << 3; tx_power = estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, Ncp, 0); // fixme: set use_srs } @@ -1662,7 +1665,7 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, && ((UE_template->phr_info - tx_power) > 0) && (rb_table_index < 32)) { rb_table_index++; - tbs = get_TBS_UL(mcs, rb_table[rb_table_index]) << 3; + tbs = get_TBS_UL(UE_template->pre_assigned_mcs_ul, rb_table[rb_table_index]) << 3; tx_power = estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, Ncp, 0); } @@ -1676,7 +1679,6 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, rb_table_index = 2; //3PRB } - UE_template->pre_assigned_mcs_ul = mcs; UE_template->pre_allocated_rb_table_index_ul = rb_table_index; UE_template->pre_allocated_nb_rb_ul[slice_id] = rb_table[rb_table_index]; LOG_D(MAC, From a68d70a13d2768fdfb6eb6614d403eccde48e0c4 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 13 Feb 2018 14:23:54 +0100 Subject: [PATCH 133/195] bugfix: prevent segfault in pre_processor.c --- openair2/LAYER2/MAC/pre_processor.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 3a27f70009..8f7a6bddff 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -1589,6 +1589,7 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, uint16_t n, UE_id; uint8_t CC_id; rnti_t rnti = -1; + int mcs; int rb_table_index = 0, tbs, tx_power; eNB_MAC_INST *eNB = RC.mac[module_idP]; UE_list_t *UE_list = &eNB->UE_list; @@ -1611,10 +1612,14 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, if (!ue_slice_membership(i, slice_id)) continue; - if (UE_list->UE_sched_ctrl[i].phr_received == 1) - UE_template->pre_assigned_mcs_ul = cmin(20, slice_maxmcs_uplink[slice_id]); // if we've received the power headroom information the UE, we can go to maximum mcs - else - UE_template->pre_assigned_mcs_ul = cmin(10, slice_maxmcs_uplink[slice_id]); // otherwise, limit to QPSK PUSCH + if (UE_list->UE_sched_ctrl[i].phr_received == 1) { + /* if we've received the power headroom information the UE, we can go to + * maximum mcs */ + mcs = cmin(20, slice_maxmcs_uplink[slice_id]); + } else { + /* otherwise, limit to QPSK PUSCH */ + mcs = cmin(10, slice_maxmcs_uplink[slice_id]); + } UE_id = i; @@ -1633,6 +1638,7 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, UE_list->numactiveULCCs[UE_id]); UE_template = &UE_list->UE_template[CC_id][UE_id]; + UE_template->pre_assigned_mcs_ul = mcs; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; Ncp = RC.mac[module_idP]->common_channels[CC_id].Ncp; From c33e184ddeee3f80de691146e8dbd3a8b27cf210 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 13 Feb 2018 14:25:50 +0100 Subject: [PATCH 134/195] bugfix: selectively inform FlexRAN RTController of UE state change --- openair2/LAYER2/MAC/eNB_scheduler.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index fb4fd6553b..a7c79a70d5 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -413,15 +413,16 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id, mac_eNB_rrc_ul_failure(module_idP, CC_id, frameP, subframeP,rnti); UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 1; + + //Inform the controller about the UE deactivation. Should be moved to RRC agent in the future + if (rrc_agent_registered[module_idP]) { + LOG_W(MAC, "notify flexran Agent of UE state change\n"); + agent_rrc_xface[module_idP]->flexran_agent_notify_ue_state_change(module_idP, + rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); + } } } // ul_failure_timer>0 - //Inform the controller about the UE deactivation. Should be moved to RRC agent in the future - if (rrc_agent_registered[module_idP]) { - agent_rrc_xface[module_idP]->flexran_agent_notify_ue_state_change(module_idP, - rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); - } - 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); From 12ac8b180da8f919dc2d2d7105bade4561be235d Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 12 Feb 2018 18:34:56 +0100 Subject: [PATCH 135/195] prevent warnings: init Protocol__FlexHeader to NULL --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 8 ++++---- .../MAC/flexran_agent_mac_internal.c | 2 +- .../CONTROL_MODULES/RRC/flexran_agent_rrc.c | 4 ++-- openair2/ENB_APP/flexran_agent_common.c | 14 +++++++------- openair2/ENB_APP/flexran_agent_handler.c | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index f875264967..230917f673 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -670,7 +670,7 @@ int flexran_agent_mac_destroy_stats_reply(Protocol__FlexranMessage *msg) { } int flexran_agent_mac_sr_info(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { - Protocol__FlexHeader *header; + Protocol__FlexHeader *header = NULL; int i; const int xid = *((int *)params); @@ -738,7 +738,7 @@ int flexran_agent_mac_destroy_sr_info(Protocol__FlexranMessage *msg) { } int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { - Protocol__FlexHeader *header; + Protocol__FlexHeader *header = NULL; int i, j, UE_id; int available_harq[NUMBER_OF_UE_MAX]; @@ -954,7 +954,7 @@ int flexran_agent_mac_destroy_sf_trigger(Protocol__FlexranMessage *msg) { int flexran_agent_mac_create_empty_dl_config(mid_t mod_id, Protocol__FlexranMessage **msg) { int xid = 0; - Protocol__FlexHeader *header; + Protocol__FlexHeader *header = NULL; if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_DL_MAC_CONFIG, &header) != 0) goto error; @@ -1049,7 +1049,7 @@ int flexran_agent_mac_destroy_dl_config(Protocol__FlexranMessage *msg) { int flexran_agent_mac_create_empty_ul_config(mid_t mod_id, Protocol__FlexranMessage **msg) { int xid = 0; - Protocol__FlexHeader *header; + Protocol__FlexHeader *header = NULL; if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_UL_MAC_CONFIG, &header) != 0) goto error; diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index b7a93b8491..2acee0686f 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -101,7 +101,7 @@ Protocol__FlexranMessage * flexran_agent_generate_diff_mac_stats_report(Protocol if (n_cell_report > 0 || n_ue_report > 0) { /*Create header*/ int xid = old_report->header->xid; - Protocol__FlexHeader *header; + Protocol__FlexHeader *header = NULL; if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_STATS_REPLY, &header) != 0) { goto error; } diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c index 590e9c870f..e88c4eaccf 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c @@ -45,8 +45,8 @@ AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB]; void flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_change) { int size; - Protocol__FlexranMessage *msg; - Protocol__FlexHeader *header; + Protocol__FlexranMessage *msg = NULL; + Protocol__FlexHeader *header = NULL; void *data; int priority = 0; err_code_t err_code; diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index f837d575d5..2df5959815 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -106,7 +106,7 @@ int flexran_create_header(xid_t xid, Protocol__FlexType type, Protocol__FlexHea int flexran_agent_hello(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { - Protocol__FlexHeader *header; + Protocol__FlexHeader *header = NULL; /*TODO: Need to set random xid or xid from received hello message*/ xid_t xid = 1; @@ -161,7 +161,7 @@ int flexran_agent_destroy_hello(Protocol__FlexranMessage *msg) { int flexran_agent_echo_request(mid_t mod_id, const void* params, Protocol__FlexranMessage **msg) { - Protocol__FlexHeader *header; + Protocol__FlexHeader *header = NULL; /*TODO: Need to set a random xid*/ xid_t xid = 1; @@ -216,6 +216,7 @@ int flexran_agent_destroy_echo_request(Protocol__FlexranMessage *msg) { int flexran_agent_echo_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { xid_t xid; + Protocol__FlexHeader *header = NULL; Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; Protocol__FlexEchoRequest *echo_req = input->echo_request_msg; xid = (echo_req->header)->xid; @@ -226,7 +227,6 @@ int flexran_agent_echo_reply(mid_t mod_id, const void *params, Protocol__Flexran goto error; protocol__flex_echo_reply__init(echo_reply_msg); - Protocol__FlexHeader *header; if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_ECHO_REPLY, &header) != 0) goto error; @@ -429,6 +429,7 @@ int flexran_agent_destroy_agent_reconfiguration(Protocol__FlexranMessage *msg) { int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { xid_t xid; + Protocol__FlexHeader *header = NULL; Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; Protocol__FlexLcConfigRequest *lc_config_request_msg = input->lc_config_request_msg; xid = (lc_config_request_msg->header)->xid; @@ -441,7 +442,6 @@ int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__Fl goto error; protocol__flex_lc_config_reply__init(lc_config_reply_msg); - Protocol__FlexHeader *header; if(flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_GET_LC_CONFIG_REPLY, &header) != 0) goto error; @@ -557,6 +557,7 @@ int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__Fl int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { xid_t xid; + Protocol__FlexHeader *header = NULL; Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; Protocol__FlexUeConfigRequest *ue_config_request_msg = input->ue_config_request_msg; xid = (ue_config_request_msg->header)->xid; @@ -569,7 +570,6 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl goto error; protocol__flex_ue_config_reply__init(ue_config_reply_msg); - Protocol__FlexHeader *header; if(flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_GET_UE_CONFIG_REPLY, &header) != 0) goto error; @@ -762,7 +762,7 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl int flexran_agent_enb_config_request(mid_t mod_id, const void* params, Protocol__FlexranMessage **msg) { - Protocol__FlexHeader *header; + Protocol__FlexHeader *header = NULL; xid_t xid = 1; Protocol__FlexEnbConfigRequest *enb_config_request_msg; @@ -801,6 +801,7 @@ int flexran_agent_enb_config_request(mid_t mod_id, const void* params, Protocol_ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { xid_t xid; + Protocol__FlexHeader *header = NULL; Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; Protocol__FlexEnbConfigRequest *enb_config_req_msg = input->enb_config_request_msg; xid = (enb_config_req_msg->header)->xid; @@ -814,7 +815,6 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F goto error; protocol__flex_enb_config_reply__init(enb_config_reply_msg); - Protocol__FlexHeader *header; if(flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_GET_ENB_CONFIG_REPLY, &header) != 0) goto error; diff --git a/openair2/ENB_APP/flexran_agent_handler.c b/openair2/ENB_APP/flexran_agent_handler.c index 3597463ae3..6c20c635a1 100644 --- a/openair2/ENB_APP/flexran_agent_handler.c +++ b/openair2/ENB_APP/flexran_agent_handler.c @@ -393,7 +393,7 @@ int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__Flexr int flexran_agent_stats_reply(mid_t enb_id, xid_t xid, const report_config_t *report_config, Protocol__FlexranMessage **msg){ - Protocol__FlexHeader *header; + Protocol__FlexHeader *header = NULL; err_code_t err_code; int i; @@ -514,7 +514,7 @@ int flexran_agent_stats_request(mid_t mod_id, xid_t xid, const stats_request_config_t *report_config, Protocol__FlexranMessage **msg) { - Protocol__FlexHeader *header; + Protocol__FlexHeader *header = NULL; int i; Protocol__FlexStatsRequest *stats_request_msg; From 22742a4c9c771441dd4d3de8c635584421d53092 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 13 Feb 2018 15:30:39 +0100 Subject: [PATCH 136/195] hack: get oaisim to compile on Ubuntu 17.10 The following did not work before this commit on ubuntu 17.10: ./build_oai --oaisim -c oaisim has not been tested. It may fail to work. To be tested. --- cmake_targets/CMakeLists.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 8d62652556..3bfc2d54ee 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1880,6 +1880,16 @@ if(EXISTS "/usr/include/atlas/cblas.h" OR EXISTS "/usr/include/cblas.h") endif() list(APPEND ATLAS_LIBRARIES lapack) + +# for ubuntu 17.10, directories are different +elseif(EXISTS "/usr/include/x86_64-linux-gnu/cblas.h") + + include_directories("/usr/include/x86_64-linux-gnu") + LINK_DIRECTORIES("/usr/lib/x86_64-linux-gnu") + list(APPEND ATLAS_LIBRARIES cblas) + list(APPEND ATLAS_LIBRARIES atlas) + list(APPEND ATLAS_LIBRARIES lapack) + else() message("No Blas/Atlas libs found, some targets will fail") endif() From e9d536972c18dae7bbbccd132b234ceccd6146de Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Tue, 13 Feb 2018 07:18:52 -0800 Subject: [PATCH 137/195] updated dlsim to FAPI interfaces --- cmake_targets/CMakeLists.txt | 3 +- openair1/PHY/CODING/crc_byte.c | 3 +- openair1/PHY/INIT/defs.h | 21 +- openair1/PHY/INIT/lte_param_init.c | 49 +- openair1/PHY/LTE_TRANSPORT/dci.c | 41 +- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 53 +- openair1/PHY/LTE_TRANSPORT/dlsch_coding.c | 3 +- openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c | 6 + .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 14 +- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 1 + openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c | 13 +- openair1/PHY/LTE_TRANSPORT/power_control.c | 32 +- openair1/PHY/LTE_TRANSPORT/proto.h | 10 +- openair1/PHY/vars.h | 1 + openair1/SCHED/fapi_l1.c | 13 +- openair1/SCHED/phy_procedures_lte_eNb.c | 8 +- openair1/SCHED/phy_procedures_lte_ue.c | 13 +- openair1/SIMULATION/LTE_PHY/dlsim.c | 1636 ++++------------- openair2/LAYER2/MAC/defs.h | 2 +- 19 files changed, 582 insertions(+), 1340 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 616adf3a82..c530eaaaab 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2157,11 +2157,12 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr ${OPENAIR1_DIR}/SIMULATION/LTE_PHY/${myExe}.c ${XFORMS_SOURCE} ${T_SOURCE} + ${CONFIG_SOURCES} ) target_link_libraries (${myExe} -Wl,--start-group SIMU UTIL SCHED_LIB PHY LFDS ${ITTI_LIB} LFDS7 -Wl,--end-group - pthread m rt ${CONFIG_LIBRARIES} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} + pthread m rt ${CONFIG_LIBRARIES} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} dl ) endforeach(myExe) diff --git a/openair1/PHY/CODING/crc_byte.c b/openair1/PHY/CODING/crc_byte.c index 5ec4fcaaa4..21427de19b 100644 --- a/openair1/PHY/CODING/crc_byte.c +++ b/openair1/PHY/CODING/crc_byte.c @@ -109,7 +109,7 @@ crc24a (unsigned char * inptr, int bitlen) resbit = (bitlen % 8); while (octetlen-- > 0) { - // printf("in %x => crc %x\n",crc,*inptr); + // printf("crc24a: in %x => crc %x\n",crc,*inptr); crc = (crc << 8) ^ crc24aTable[(*inptr++) ^ (crc >> 24)]; } @@ -128,6 +128,7 @@ unsigned int crc24b (unsigned char * inptr, int bitlen) resbit = (bitlen % 8); while (octetlen-- > 0) { + // printf("crc24b: in %x => crc %x (%x)\n",crc,*inptr,crc24bTable[(*inptr) ^ (crc >> 24)]); crc = (crc << 8) ^ crc24bTable[(*inptr++) ^ (crc >> 24)]; } diff --git a/openair1/PHY/INIT/defs.h b/openair1/PHY/INIT/defs.h index 744fb3d3ce..d23f342d18 100644 --- a/openair1/PHY/INIT/defs.h +++ b/openair1/PHY/INIT/defs.h @@ -322,8 +322,11 @@ void init_lte_top(LTE_DL_FRAME_PARMS *lte_frame_parms); //void copy_lte_parms_to_phy_framing(LTE_DL_FRAME_PARMS *frame_parm, PHY_FRAMING *phy_framing); -void lte_param_init(unsigned char N_tx_port_eNB, - unsigned char N_tx, +void lte_param_init(PHY_VARS_eNB **eNBp, + PHY_VARS_UE **UEp, + RU_t **rup, + unsigned char N_tx_port_eNB, + unsigned char N_tx_phy, unsigned char N_rx, unsigned char transmission_mode, uint8_t extended_prefix_flag, @@ -331,10 +334,12 @@ void lte_param_init(unsigned char N_tx_port_eNB, uint16_t Nid_cell, uint8_t tdd_config, uint8_t N_RB_DL, + uint8_t pa, uint8_t threequarter_fs, uint8_t osf, uint32_t perfect_ce); + #if defined(Rel10) || defined(Rel14) void phy_config_dedicated_scell_ue(uint8_t Mod_id, uint8_t eNB_index, @@ -359,18 +364,6 @@ void phy_config_request(PHY_Config_t *phy_config); int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf); void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms); -void lte_param_init(unsigned char N_tx_port_eNB, - unsigned char N_tx_phy, - unsigned char N_rx, - unsigned char transmission_mode, - uint8_t extended_prefix_flag, - frame_t frame_type, - uint16_t Nid_cell, - uint8_t tdd_config, - uint8_t N_RB_DL, - uint8_t threequarter_fs, - uint8_t osf, - uint32_t perfect_ce); /** @} */ #endif diff --git a/openair1/PHY/INIT/lte_param_init.c b/openair1/PHY/INIT/lte_param_init.c index d510fc7261..90b7bcee31 100644 --- a/openair1/PHY/INIT/lte_param_init.c +++ b/openair1/PHY/INIT/lte_param_init.c @@ -32,8 +32,12 @@ extern PHY_VARS_eNB *eNB; extern PHY_VARS_UE *UE; +extern RU_t *ru; -void lte_param_init(unsigned char N_tx_port_eNB, +void lte_param_init(PHY_VARS_eNB **eNBp, + PHY_VARS_UE **UEp, + RU_t **rup, + unsigned char N_tx_port_eNB, unsigned char N_tx_phy, unsigned char N_rx, unsigned char transmission_mode, @@ -42,6 +46,7 @@ void lte_param_init(unsigned char N_tx_port_eNB, uint16_t Nid_cell, uint8_t tdd_config, uint8_t N_RB_DL, + uint8_t pa, uint8_t threequarter_fs, uint8_t osf, uint32_t perfect_ce) @@ -49,13 +54,27 @@ void lte_param_init(unsigned char N_tx_port_eNB, LTE_DL_FRAME_PARMS *frame_parms; int i; - + PHY_VARS_eNB *eNB; + PHY_VARS_UE *UE; + RU_t *ru; printf("Start lte_param_init\n"); - eNB = malloc(sizeof(PHY_VARS_eNB)); - UE = malloc(sizeof(PHY_VARS_UE)); + *eNBp = malloc(sizeof(PHY_VARS_eNB)); + *UEp = malloc(sizeof(PHY_VARS_UE)); + *rup = malloc(sizeof(RU_t)); + eNB = *eNBp; + UE = *UEp; + ru = *rup; + printf("eNB %p, UE %p, ru %p\n",eNB,UE,ru); + + + memset((void*)eNB,0,sizeof(PHY_VARS_eNB)); memset((void*)UE,0,sizeof(PHY_VARS_UE)); + memset((void*)ru,0,sizeof(RU_t)); + ru->eNB_list[0] = eNB; + eNB->RU_list[0] = ru; + ru->num_eNB=1; srand(0); randominit(0); @@ -90,12 +109,17 @@ void lte_param_init(unsigned char N_tx_port_eNB, UE->is_secondary_ue = 0; UE->frame_parms = *frame_parms; - eNB->frame_parms = *frame_parms; + // eNB->frame_parms = *frame_parms; + ru->frame_parms = *frame_parms; + ru->nb_tx = N_tx_phy; + ru->nb_rx = 1; + ru->if_south = LOCAL_RF; + + eNB->configured=1; eNB->transmission_mode[0] = transmission_mode; UE->transmission_mode[0] = transmission_mode; - init_lte_top(frame_parms); dump_frame_parms(frame_parms); UE->measurements.n_adj_cells=0; @@ -105,23 +129,24 @@ void lte_param_init(unsigned char N_tx_port_eNB, for (i=0; i<3; i++) lte_gold(frame_parms,UE->lte_gold_table[i],Nid_cell+i); - init_lte_ue(UE,1,0); + printf("Calling init_lte_ue_signal\n"); + init_lte_ue_signal(UE,1,0); + printf("Calling phy_init_lte_eNB\n"); phy_init_lte_eNB(eNB,0,0); - + printf("Calling phy_init_RU (%p)\n",ru); + phy_init_RU(ru); generate_pcfich_reg_mapping(&UE->frame_parms); generate_phich_reg_mapping(&UE->frame_parms); // DL power control init //if (transmission_mode == 1) { + UE->pdsch_config_dedicated->p_a = pa; + if (transmission_mode == 1 || transmission_mode ==7) { - eNB->pdsch_config_dedicated->p_a = dB0; // 4 = 0dB ((eNB->frame_parms).pdsch_config_common).p_b = 0; - UE->pdsch_config_dedicated->p_a = dB0; // 4 = 0dB ((UE->frame_parms).pdsch_config_common).p_b = 0; } else { // rho_a = rhob - eNB->pdsch_config_dedicated->p_a = dBm3; // 4 = 0dB ((eNB->frame_parms).pdsch_config_common).p_b = 1; - UE->pdsch_config_dedicated->p_a = dBm3; // 4 = 0dB ((UE->frame_parms).pdsch_config_common).p_b = 1; } diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c index 18860d729c..f75ae326e9 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci.c +++ b/openair1/PHY/LTE_TRANSPORT/dci.c @@ -52,6 +52,9 @@ //extern uint16_t phich_reg[MAX_NUM_PHICH_GROUPS][3]; //extern uint16_t pcfich_reg[4]; +//#undef LOG_D +//#define LOG_D(A,B,C...) printf(B,C) + uint32_t check_phich_reg(LTE_DL_FRAME_PARMS *frame_parms,uint32_t kprime,uint8_t lprime,uint8_t mi) { @@ -177,7 +180,7 @@ void dci_encoding(uint8_t *a, // encode dci #ifdef DEBUG_DCI_ENCODING - printf("Doing DCI encoding for %d bits, e %p, rnti %x\n",A,e,rnti); + printf("Doing DCI encoding for %d bits, e %p, rnti %x, E %d\n",A,e,rnti,E); #endif memset((void *)d,LTE_NULL,96); @@ -231,18 +234,23 @@ uint8_t *generate_dci0(uint8_t *dci, coded_bits = 72 * aggregation_level; - /* + #ifdef DEBUG_DCI_ENCODING - for (i=0;i<1+((DCI_LENGTH+16)/8);i++) + for (int i=0;i<1+((DCI_LENGTH+16)/8);i++) printf("i %d : %x\n",i,dci[i]); #endif - */ + if (DCI_LENGTH<=32) { dci_flip[0] = dci[3]; dci_flip[1] = dci[2]; dci_flip[2] = dci[1]; dci_flip[3] = dci[0]; +#ifdef DEBUG_DCI_ENCODING + printf("DCI => %x,%x,%x,%x\n", + dci_flip[0],dci_flip[1],dci_flip[2],dci_flip[3]); + +#endif } else { dci_flip[0] = dci[7]; dci_flip[1] = dci[6]; @@ -2271,7 +2279,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, /* clear all bits, the above code may generate too much false detections * (not sure about this, to be checked somehow) */ - // memset(e, 0, DCI_BITS_MAX); + // memset(e, 0, DCI_BITS_MAX); e_ptr = e; @@ -2285,11 +2293,11 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, if (dci_alloc[i].L == (uint8_t)L) { #ifdef DEBUG_DCI_ENCODING - if (dci_alloc[i].rnti==0x02) - LOG_I(PHY,"Generating DCI %d/%d (nCCE %d) of length %d, aggregation %d (%x), rnti %x\n",i,num_dci,dci_alloc[i].firstCCE,dci_alloc[i].dci_length,dci_alloc[i].L, + if (dci_alloc[i].rnti==0x1234) + LOG_D(PHY,"Generating DCI %d/%d (nCCE %d) of length %d, aggregation %d (%x), rnti %x\n",i,num_dci,dci_alloc[i].firstCCE,dci_alloc[i].dci_length,dci_alloc[i].L, *(unsigned int*)dci_alloc[i].dci_pdu, dci_alloc[i].rnti); - //dump_dci(frame_parms,&dci_alloc[i]); + dump_dci(frame_parms,&dci_alloc[i]); #endif if (dci_alloc[i].firstCCE>=0) { @@ -2894,17 +2902,17 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars, LOG_D(PHY,"[DCI search nPdcch %d - common] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x)\n", pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask); else - LOG_D(PHY,"[DCI search nPdcch %d - ue spec] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x) format %d\n", - pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask,format_c); + LOG_D(PHY,"[DCI search nPdcch %d - ue spec %x] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x) format %d\n", + pdcch_vars[eNB_id]->num_pdcch_symbols,pdcch_vars[eNB_id]->crnti,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask,format_c); dci_decoding(sizeof_bits, L, &pdcch_vars[eNB_id]->e_rx[CCEind*72], &dci_decoded_output[current_thread_id][0]); - /* + /* for (i=0;i<3+(sizeof_bits>>3);i++) - printf("dci_decoded_output[%d] => %x\n",i,dci_decoded_output[i]); - */ + printf("dci_decoded_output[%d][%d] => %x\n",current_thread_id,i,dci_decoded_output[current_thread_id][i]); + */ crc = (crc16(&dci_decoded_output[current_thread_id][0],sizeof_bits)>>16) ^ extract_crc(&dci_decoded_output[current_thread_id][0],sizeof_bits); #ifdef DEBUG_DCI_DECODING @@ -3823,7 +3831,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, } else if (tmode == 3) { - LOG_D(PHY," Now check UE_SPEC format 2A_2A search aggregation 1 dci length: %d[bits] %d[bytes]\n",format2A_size_bits,format2A_size_bytes); + // LOG_D(PHY," Now check UE_SPEC format 2A_2A search aggregation 1 dci length: %d[bits] %d[bytes]\n",format2A_size_bits,format2A_size_bytes); // Now check UE_SPEC format 2A_2A search spaces at aggregation 1 old_dci_cnt=dci_cnt; dci_decoding_procedure0(pdcch_vars,0,mode, @@ -3895,7 +3903,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, return(dci_cnt); // Now check UE_SPEC format 2_2A search spaces at aggregation 4 - LOG_D(PHY," Now check UE_SPEC format 2_2A search spaces at aggregation 4 \n"); + // LOG_D(PHY," Now check UE_SPEC format 2_2A search spaces at aggregation 4 \n"); old_dci_cnt=dci_cnt; dci_decoding_procedure0(pdcch_vars,0,mode, subframe, @@ -4238,3 +4246,6 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, return(dci_cnt); } + + + diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index c6c1322504..4adcc130dd 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -44,6 +44,11 @@ #include "LAYER2/MAC/extern.h" #include "LAYER2/MAC/defs.h" +//#undef LOG_D +//#define LOG_D(A,B,C...) printf(B,C) +//#undef LOG_I +//#define LOG_I(A,B,C...) printf(B,C) + //#define DEBUG_DCI uint32_t localRIV2alloc_LUT6[32]; @@ -4680,13 +4685,13 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format, if(harq_pid>=8) { - LOG_I(PHY,"bad harq id \n"); + // LOG_I(PHY,"bad harq id \n"); return(0); } if(dci_format == format1 && ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) ) { - LOG_I(PHY,"bad dci format \n"); + // LOG_I(PHY,"bad dci format \n"); return(0); } @@ -4695,13 +4700,13 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format, { if(pdlsch0_harq->round == 0) { - LOG_I(PHY,"bad dci mcs + round \n"); + // LOG_I(PHY,"bad dci mcs + round \n"); return(0); } if((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) { - LOG_I(PHY,"bad dci mcs + rnti \n"); + // LOG_I(PHY,"bad dci mcs + rnti \n"); return(0); } } @@ -4767,7 +4772,7 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format, if(rballoc > RIV_max) { - LOG_I(PHY,"bad dci rballoc rballoc %d RIV_max %lld \n",rballoc, RIV_max); + // LOG_I(PHY,"bad dci rballoc rballoc %d RIV_max %lld \n",rballoc, RIV_max); // DCI false detection return(0); } @@ -4775,7 +4780,7 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format, if(NPRB == 0) { // DCI false detection - LOG_I(PHY,"bad NPRB = 0 \n"); + // LOG_I(PHY,"bad NPRB = 0 \n"); return(0); } @@ -4894,13 +4899,13 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format, // I- check dci content minimum coherency if(harq_pid>=8) { - LOG_I(PHY,"bad harq pid\n"); + // LOG_I(PHY,"bad harq pid\n"); return(0); } if( (rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti) ) { - LOG_I(PHY,"bad rnti\n"); + // LOG_I(PHY,"bad rnti\n"); return(0); } @@ -4909,7 +4914,7 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format, { if(pdlsch0_harq->round == 0) { - LOG_I(PHY,"bad mcs1\n"); + // LOG_I(PHY,"bad mcs1\n"); return(0); } } @@ -4918,7 +4923,7 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format, { if(pdlsch1_harq->round == 0) { - LOG_I(PHY,"bad mcs2\n"); + // LOG_I(PHY,"bad mcs2\n"); return(0); } } @@ -4927,14 +4932,14 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format, if((pdlsch0_harq->round == 0) && (rv1 > 0) && (mcs1 != 0)) { // DCI false detection - LOG_I(PHY,"bad rv1\n"); + // LOG_I(PHY,"bad rv1\n"); return(0); } if((pdlsch1_harq->round == 0) && (rv2 > 0) && (mcs2 != 0)) { // DCI false detection - LOG_I(PHY,"bad rv2\n"); + // LOG_I(PHY,"bad rv2\n"); return(0); } @@ -4995,14 +5000,14 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format, if( (rballoc > RIV_max) && (rah == 1) ) { // DCI false detection - LOG_I(PHY,"bad rballoc %d RIV_max %lld\n", rballoc, RIV_max); + // LOG_I(PHY,"bad rballoc %d RIV_max %lld\n", rballoc, RIV_max); return(0); } if(NPRB == 0) { // DCI false detection - LOG_I(PHY,"bad NPRB\n"); + // LOG_I(PHY,"bad NPRB\n"); return(0); } @@ -5026,7 +5031,7 @@ void compute_llr_offset(LTE_DL_FRAME_PARMS *frame_parms, pdsch_vars->llr_offset[pdcch_vars->num_pdcch_symbols] = 0; - //LOG_I(PHY,"compute_llr_offset: nb RB %d - Qm %d \n", nb_rb_alloc, dlsch0_harq->Qm); + LOG_I(PHY,"compute_llr_offset: nb RB %d - Qm %d \n", nb_rb_alloc, dlsch0_harq->Qm); //dlsch0_harq->rb_alloc_even; //dlsch0_harq->rb_alloc_odd; @@ -5056,15 +5061,15 @@ void compute_llr_offset(LTE_DL_FRAME_PARMS *frame_parms, if(symbol < (frame_parms->symbols_per_tti-1)) pdsch_vars->llr_offset[symbol+1] = pdsch_vars->llr_offset[symbol] + llr_offset; - // LOG_I(PHY,"Granted Re subframe %d / symbol %d => %d (%d RBs)\n", subframe, symbol_mod, granted_re,dlsch0_harq->nb_rb); - // LOG_I(PHY,"Pbch/PSS/SSS Re subframe %d / symbol %d => %d \n", subframe, symbol_mod, pbch_pss_sss_re); - // LOG_I(PHY,"CRS Re Per PRB subframe %d / symbol %d => %d \n", subframe, symbol_mod, crs_re); - // LOG_I(PHY,"Data Re subframe %d / symbol %d => %d \n", subframe, symbol_mod, data_re); + LOG_I(PHY,"Granted Re subframe %d / symbol %d => %d (%d RBs)\n", subframe, symbol_mod, granted_re,dlsch0_harq->nb_rb); + LOG_I(PHY,"Pbch/PSS/SSS Re subframe %d / symbol %d => %d \n", subframe, symbol_mod, pbch_pss_sss_re); + LOG_I(PHY,"CRS Re Per PRB subframe %d / symbol %d => %d \n", subframe, symbol_mod, crs_re); + LOG_I(PHY,"Data Re subframe %d / symbol %d => %d \n", subframe, symbol_mod, data_re); - //LOG_I(PHY,"Data Re subframe %d-symbol %d => llr length %d, llr offset %d \n", subframe, symbol, - // pdsch_vars->llr_length[symbol], pdsch_vars->llr_offset[symbol]); + LOG_I(PHY,"Data Re subframe %d-symbol %d => llr length %d, llr offset %d \n", subframe, symbol, + pdsch_vars->llr_length[symbol], pdsch_vars->llr_offset[symbol]); } } void prepare_dl_decoding_format1_1A(DCI_format_t dci_format, @@ -5179,7 +5184,7 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format, //packet was actually decoded in previous transmission (ACK was missed by eNB) //However, the round is not a good check as it might have been decoded in a retransmission prior to this one. { - LOG_D(PHY,"skip pdsch decoding and report ack\n"); + // LOG_D(PHY,"skip pdsch decoding and report ack\n"); // skip pdsch decoding and report ack //pdlsch0_harq->status = SCH_IDLE; pdlsch0->active = 0; @@ -5804,7 +5809,7 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format, //LOG_I(PHY,"[UE] DLSCH: New Data Indicator CW0 subframe %d (pid %d, round %d)\n", // subframe,harq_pid,dlsch0_harq->round); if ( dlsch0_harq->first_tx==1) { - LOG_D(PHY,"Format 2 DCI First TX0: Clearing flag\n"); + // LOG_D(PHY,"Format 2 DCI First TX0: Clearing flag\n"); dlsch0_harq->first_tx = 0; } } @@ -5852,7 +5857,7 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format, //LOG_I(PHY,"[UE] DLSCH: New Data Indicator CW1 subframe %d (pid %d, round %d)\n", // subframe,harq_pid,dlsch0_harq->round); if (dlsch1_harq->first_tx==1) { - LOG_D(PHY,"Format 2 DCI First TX1: Clearing flag\n"); + // LOG_D(PHY,"Format 2 DCI First TX1: Clearing flag\n"); dlsch1_harq->first_tx = 0; } } diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index bd3c92454f..89225a573a 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -604,7 +604,7 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, // if (dlsch->harq_processes[harq_pid]->Ndi == 1) { // this is a new packet if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet #ifdef DEBUG_DLSCH_CODING - printf("encoding thinks this is a new packet \n"); + printf("encoding thinks this is a new packet for harq_pid %d (%p) \n",harq_pid,dlsch->harq_processes[harq_pid]->b); #endif /* int i; @@ -614,6 +614,7 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, printf("\n"); */ // Add 24-bit crc (polynomial A) to payload + crc = crc24a(a, A)>>8; a[A>>3] = ((uint8_t*)&crc)[2]; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c index 7acf6480eb..71399c2652 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c @@ -37,6 +37,12 @@ #include "SCHED/extern.h" #include "SIMULATION/TOOLS/defs.h" //#define DEBUG_DLSCH_DECODING +//#define UE_DEBUG_TRACE 1 + +//#undef LOG_D +//#define LOG_D(A,B,C...) printf(B,C) +//#undef LOG_I +//#define LOG_I(A,B,C...) printf(B,C) extern double cpuf; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index c805d9408f..062cb8d299 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -49,12 +49,14 @@ int16_t interf_unaw_shift = 13; //#define DEBUG_HARQ //#undef LOG_D -//#define LOG_D LOG_I +//#define LOG_D(A,B,C...) printf(B,C) +//#undef LOG_I +//#define LOG_I(A,B,C...) printf(B,C) -//#define DEBUG_PHY 1 +#define DEBUG_PHY 1 //#define DEBUG_DLSCH_DEMOD 1 - +//#define DISABLE_LOG_X // [MCS][i_mod (0,1,2) = (2,4,6)] unsigned char offset_mumimo_llr_drange_fix=0; @@ -370,7 +372,7 @@ int rx_pdsch(PHY_VARS_UE *ue, //printf("nb_rb = %d, eNB_id %d\n",nb_rb,eNB_id); if (nb_rb==0) { - LOG_D(PHY,"dlsch_demodulation.c: nb_rb=0\n"); + // LOG_D(PHY,"dlsch_demodulation.c: nb_rb=0\n"); return(-1); } @@ -845,7 +847,7 @@ int rx_pdsch(PHY_VARS_UE *ue, pllr_symbol_cw1 = (int8_t*)pdsch_vars[eNB_id]->llr[1]; pllr_symbol_cw0 += llr_offset_symbol; pllr_symbol_cw1 += llr_offset_symbol; - /* + LOG_I(PHY,"compute LLRs [AbsSubframe %d.%d-%d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %x @LLR Buff(symb) %x\n", frame, subframe,symbol, nb_rb,dlsch0_harq->Qm, @@ -853,7 +855,7 @@ int rx_pdsch(PHY_VARS_UE *ue, pdsch_vars[eNB_id]->llr_offset[symbol], (int16_t*)pdsch_vars[eNB_id]->llr[0], pllr_symbol_cw0); - */ + switch (dlsch0_harq->Qm) { case 2 : if ((rx_type==rx_standard) || (codeword_TB1 == -1)) { diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 49b41615f4..f3a9a05ae5 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -2125,6 +2125,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, amp_rho_b = (int16_t)(((int32_t)amp*dlsch1->sqrt_rho_b)>>13); } + if (mod_order0 == 4) for (i=0;i<4; i++) { qam16_table_a0[i] = (int16_t)(((int32_t)qam16_table[i]*amp_rho_a)>>15); diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c index d90f4c66d2..8d650bbe21 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c @@ -124,14 +124,18 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, } #ifdef DEBUG_SCRAMBLING +#ifdef Rel14 printf("scrambling: i0 %d rnti %x, q %d, Ns %d, Nid_cell %d, G %d x2 %x\n",dlsch->i0,dlsch->rnti,q,Ns,frame_parms->Nid_cell, G, x2); +#else + printf("scrambling: rnti %x, q %d, Ns %d, Nid_cell %d, G %d x2 %x\n",dlsch->rnti,q,Ns,frame_parms->Nid_cell, G, x2); +#endif #endif s = lte_gold_scram(&x1, &x2, 1); for (n=0; n<(1+(G>>5)); n++) { #ifdef DEBUG_SCRAMBLING - printf("scrambling %d : %d => ",k,e[k]); + for (int k=0;k<32;k++) printf("scrambling %d : %d xor %d = %d\n",k+(n<<5),e[k],(s>>k)&1,e[k]^((s>>k)&1)); #endif @@ -171,9 +175,8 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, // This is not faster for some unknown reason // ((__m128i *)e)[0] = _mm_xor_si128(((__m128i *)e)[0],((__m128i *)scrambling_lut)[s&65535]); // ((__m128i *)e)[1] = _mm_xor_si128(((__m128i *)e)[1],((__m128i *)scrambling_lut)[s>>16]); -#ifdef DEBUG_SCRAMBLING - printf("%d\n",e[k]); -#endif + + s = lte_gold_scram(&x1, &x2, 0); @@ -213,7 +216,7 @@ void dlsch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms, for (i=0; i<(1+(G>>5)); i++) { for (j=0; j<32; j++,k++) { #ifdef DEBUG_SCRAMBLING - printf("unscrambling %d : %d => ",k,llr[k]); + printf("unscrambling %d : %d xor %d =",k,llr[k],(s>>j)&1); #endif llr[k] = ((2*((s>>j)&1))-1)*llr[k]; #ifdef DEBUG_SCRAMBLING diff --git a/openair1/PHY/LTE_TRANSPORT/power_control.c b/openair1/PHY/LTE_TRANSPORT/power_control.c index 10f0c1490c..36b2bfbeab 100644 --- a/openair1/PHY/LTE_TRANSPORT/power_control.c +++ b/openair1/PHY/LTE_TRANSPORT/power_control.c @@ -33,20 +33,20 @@ double ratioPB[2][4]={{ 0.00000, -0.96910, -2.21849, -3.97940}, //in db double pa_values[8]={-6.0,-4.77,-3.0,-1.77,0.0,1.0,2.0,3.0}; //reported by higher layers -double get_pa_dB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated) +double get_pa_dB(uint8_t pa) { - if (pdsch_config_dedicated) - return(pa_values[ pdsch_config_dedicated->p_a]); - else - return(0.0); + AssertFatal(pa<8,"pa %d is not in (0...7)\n",pa); + + return(pa_values[pa]); + } -double computeRhoA_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, +double computeRhoA_eNB(uint8_t pa, LTE_eNB_DLSCH_t *dlsch_eNB, int dl_power_off, uint8_t n_antenna_port){ double rho_a_dB; double sqrt_rho_a_lin; - rho_a_dB = get_pa_dB(pdsch_config_dedicated); + rho_a_dB = get_pa_dB(pa); if(!dl_power_off) //if dl_power_offset is 0, this is for MU-interference, TM5 rho_a_dB-=10*log10(2); @@ -59,14 +59,14 @@ double computeRhoA_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, dlsch_eNB->sqrt_rho_a= (short) (sqrt_rho_a_lin*pow(2,13)); #if DEBUG_PC - printf("eNB: p_a=%d, value=%f, sqrt_rho_a=%d\n",pdsch_config_dedicated->p_a,pa_values[ pdsch_config_dedicated->p_a],dlsch_eNB->sqrt_rho_a); + printf("eNB: p_a=%d, value=%f, sqrt_rho_a=%d\n",p_a,pa_values[ pdsch_config_dedicated->p_a],dlsch_eNB->sqrt_rho_a); #endif return(rho_a_dB); } -double computeRhoB_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, - PDSCH_CONFIG_COMMON *pdsch_config_common, +double computeRhoB_eNB(uint8_t pa, + uint8_t pb, uint8_t n_antenna_port, LTE_eNB_DLSCH_t *dlsch_eNB, int dl_power_off) @@ -75,19 +75,21 @@ double computeRhoB_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, double rho_a_dB, rho_b_dB; double sqrt_rho_b_lin; - rho_a_dB= computeRhoA_eNB(pdsch_config_dedicated,dlsch_eNB,dl_power_off, n_antenna_port); + AssertFatal(pa<8,"pa %d is not in (0...7)\n",pa); + AssertFatal(pb<4,"pb %d is not in (0...3)\n",pb); + rho_a_dB= computeRhoA_eNB(pa,dlsch_eNB,dl_power_off, n_antenna_port); if(n_antenna_port>1) - rho_b_dB= ratioPB[1][pdsch_config_common->p_b] + rho_a_dB; + rho_b_dB= ratioPB[1][pb] + rho_a_dB; else - rho_b_dB= ratioPB[0][pdsch_config_common->p_b] + rho_a_dB; + rho_b_dB= ratioPB[0][pb] + rho_a_dB; sqrt_rho_b_lin= pow(10,(0.05*rho_b_dB)); dlsch_eNB->sqrt_rho_b= (short) (sqrt_rho_b_lin*pow(2,13)); #ifdef DEBUG_PC - printf("eNB: n_ant=%d, p_b=%d -> rho_b/rho_a=%f -> sqrt_rho_b=%d\n",n_antenna_port,pdsch_config_common->p_b,ratioPB[1][pdsch_config_common->p_b],dlsch_eNB->sqrt_rho_b); + printf("eNB: n_ant=%d, p_b=%d -> rho_b/rho_a=%f -> sqrt_rho_b=%d\n",n_antenna_port,pb,ratioPB[1][pb],dlsch_eNB->sqrt_rho_b); #endif return(rho_b_dB); } @@ -102,7 +104,7 @@ double computeRhoA_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, double rho_a_dB; double sqrt_rho_a_lin; - rho_a_dB = get_pa_dB(pdsch_config_dedicated); + rho_a_dB = get_pa_dB(pdsch_config_dedicated->p_a); if(!dl_power_off) rho_a_dB-=10*log10(2); diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index be6d2861f2..c67820d0dd 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -2221,15 +2221,15 @@ uint32_t dlsch_decoding_abstraction(double *dlsch_MIPB, uint8_t num_pdcch_symbols); // DL power control functions -double get_pa_dB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated); +double get_pa_dB(uint8_t pa); -double computeRhoA_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, - LTE_eNB_DLSCH_t *dlsch_eNB, +double computeRhoA_eNB(uint8_t pa, + LTE_eNB_DLSCH_t *dlsch_eNB, int dl_power_off, uint8_t n_antenna_port); -double computeRhoB_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, - PDSCH_CONFIG_COMMON *pdsch_config_common, +double computeRhoB_eNB(uint8_t pa, + uint8_t pb, uint8_t n_antenna_port, LTE_eNB_DLSCH_t *dlsch_eNB, int dl_power_off); diff --git a/openair1/PHY/vars.h b/openair1/PHY/vars.h index f78cb92bcd..45af058308 100644 --- a/openair1/PHY/vars.h +++ b/openair1/PHY/vars.h @@ -24,6 +24,7 @@ #include "PHY/types.h" #include "PHY/defs.h" +#include "common/ran_context.h" char* namepointer_chMag ; char fmageren_name2[512]; diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c index b9024bdfbf..6cb6e66aac 100644 --- a/openair1/SCHED/fapi_l1.c +++ b/openair1/SCHED/fapi_l1.c @@ -37,6 +37,11 @@ #include "nfapi_interface.h" #include "fapi_l1.h" +//#undef LOG_D +//#define LOG_D(A,B,C...) printf(B,C) +//#undef LOG_I +//#define LOG_I(A,B,C...) printf(B,C) + int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req); int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req); int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req); @@ -190,12 +195,12 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_pr eNB->pdsch_config_dedicated[UE_id].p_a = rel8->pa; if (dlsch0->active){ - computeRhoA_eNB(&eNB->pdsch_config_dedicated[UE_id], dlsch0,dlsch0_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB); - computeRhoB_eNB(&eNB->pdsch_config_dedicated[UE_id],&(eNB->frame_parms.pdsch_config_common),eNB->frame_parms.nb_antenna_ports_eNB,dlsch0,dlsch0_harq->dl_power_off); + computeRhoA_eNB(rel8->pa, dlsch0,dlsch0_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB); + computeRhoB_eNB(rel8->pa,eNB->frame_parms.pdsch_config_common.p_b,eNB->frame_parms.nb_antenna_ports_eNB,dlsch0,dlsch0_harq->dl_power_off); } if (dlsch1->active){ - computeRhoA_eNB(&eNB->pdsch_config_dedicated[UE_id], dlsch1,dlsch1_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB); - computeRhoB_eNB(&eNB->pdsch_config_dedicated[UE_id],&(eNB->frame_parms.pdsch_config_common),eNB->frame_parms.nb_antenna_ports_eNB,dlsch1,dlsch1_harq->dl_power_off); + computeRhoA_eNB(rel8->pa, dlsch1,dlsch1_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB); + computeRhoB_eNB(rel8->pa,eNB->frame_parms.pdsch_config_common.p_b,eNB->frame_parms.nb_antenna_ports_eNB,dlsch1,dlsch1_harq->dl_power_off); } dlsch0_harq->pdsch_start = eNB->pdcch_vars[subframe & 1].num_pdcch_symbols; diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 2ae79b53b6..f771288f35 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -50,6 +50,9 @@ # include "intertask_interface.h" #endif +//#undef LOG_D +//#define LOG_D(A,B,C...) printf(B,C) + extern uint8_t nfapi_mode; int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); @@ -395,6 +398,7 @@ void pdsch_procedures(PHY_VARS_eNB *eNB, + void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, relaying_type_t r_type, @@ -416,7 +420,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, int offset = eNB->CC_id;//proc == &eNB->proc.proc_rxtx[0] ? 0 : 1; - + if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)==SF_UL)) return; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,1); @@ -429,6 +433,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, } + if (nfapi_mode == 0 || nfapi_mode == 1) { if (is_pmch_subframe(frame,subframe,fp)) { pmch_procedures(eNB,proc,rn,r_type); @@ -439,6 +444,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, } } + // clear existing ulsch dci allocations before applying info from MAC (this is table ul_subframe = pdcch_alloc2ul_subframe(fp,subframe); ul_frame = pdcch_alloc2ul_frame(fp,frame,subframe); diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 2e6bdc8a14..0085a31e28 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -73,6 +73,9 @@ extern double cpuf; +//#undef LOG_D +//#define LOG_D(A,B,C...) printf(B,C) + void Msg1_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id); void Msg3_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id); @@ -1373,7 +1376,7 @@ void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin if (ue->mac_enabled==1){ // ask L2 for RACH transport if ((mode != rx_calib_ue) && (mode != rx_calib_ue_med) && (mode != rx_calib_ue_byp) && (mode != no_L2_connect) ) { - LOG_D(PHY,"Getting PRACH resources\n"); + //LOG_D(PHY,"Getting PRACH resources\n"); ue->prach_resources[eNB_id] = ue_get_rach(ue->Mod_id, ue->CC_id, @@ -1590,7 +1593,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB LOG_D(PHY,"Generating PUSCH (Abssubframe: %d.%d): harq-Id: %d, round: %d, MaxReTrans: %d \n",frame_tx,subframe_tx,harq_pid,ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,ue->ulsch[eNB_id]->Mlimit); if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round >= (ue->ulsch[eNB_id]->Mlimit - 1)) { - LOG_D(PHY,"PUSCH MAX Retransmission achieved ==> send last pusch\n"); + // LOG_D(PHY,"PUSCH MAX Retransmission achieved ==> send last pusch\n"); ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0; ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0; } @@ -2070,10 +2073,10 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin (bundling_flag==bundling) || ((frame_parms->frame_type==TDD)&&(frame_parms->tdd_config==1)&&((subframe_tx!=2)||(subframe_tx!=7)))) { format = pucch_format1a; - LOG_D(PHY,"[UE] PUCCH 1a\n"); + // LOG_D(PHY,"[UE] PUCCH 1a\n"); } else { format = pucch_format1b; - LOG_D(PHY,"[UE] PUCCH 1b\n"); + // LOG_D(PHY,"[UE] PUCCH 1b\n"); } // Part - I @@ -3108,7 +3111,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs int ret=0; if (is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms)) { - LOG_D(PHY,"ue calling pmch subframe ..\n "); + // LOG_D(PHY,"ue calling pmch subframe ..\n "); LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Querying for PMCH demodulation\n", ue->Mod_id,(subframe_rx==9?-1:0)+frame_rx,subframe_rx); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 34055517b2..128fca79e1 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -54,8 +54,9 @@ #include "PHY/TOOLS/lte_phy_scope.h" -PHY_VARS_eNB *eNB; -PHY_VARS_UE *UE; +#include "dummy_functions.c" + + double cpuf; @@ -123,7 +124,7 @@ void do_OFDM_mod_l(int32_t **txdataF, int32_t **txdata, uint16_t next_slot, LTE_ } -void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,double SNR, int tx_lev,int hold_channel,int abstx, int num_rounds, int trials, int round, channel_desc_t *eNB2UE[4], +void DL_channel(RU_t *ru,PHY_VARS_UE *UE,uint subframe,int awgn_flag,double SNR, int tx_lev,int hold_channel,int abstx, int num_rounds, int trials, int round, channel_desc_t *eNB2UE[4], double *s_re[2],double *s_im[2],double *r_re[2],double *r_im[2],FILE *csv_fd) { int i,u; @@ -134,18 +135,18 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou // printf("Copying tx ..., nsymb %d (n_tx %d), awgn %d\n",nsymb,eNB->frame_parms.nb_antennas_tx,awgn_flag); for (i=0; i<2*UE->frame_parms.samples_per_tti; i++) { - for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { + for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { if (awgn_flag == 0) { - s_re[aa][i] = ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) + (i<<1)]); - s_im[aa][i] = ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); + s_re[aa][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) + (i<<1)]); + s_im[aa][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); } else { for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { if (aa==0) { - r_re[aarx][i] = ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]); - r_im[aarx][i] = ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); + r_re[aarx][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]); + r_im[aarx][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); } else { - r_re[aarx][i] += ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]); - r_im[aarx][i] += ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); + r_re[aarx][i] += ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]); + r_im[aarx][i] += ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); } } @@ -180,11 +181,11 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou if(abstx) { if (trials==0 && round==0) { // calculate freq domain representation to compute SINR - freq_channel(eNB2UE[0], eNB->frame_parms.N_RB_DL,2*eNB->frame_parms.N_RB_DL + 1); + freq_channel(eNB2UE[0], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1); // snr=pow(10.0,.1*SNR); fprintf(csv_fd,"%f,",SNR); - for (u=0; u<2*eNB->frame_parms.N_RB_DL; u++) { + for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) { for (aarx=0; aarxnb_rx; aarx++) { for (aatx=0; aatxnb_tx; aatx++) { channelx = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].x; @@ -195,9 +196,9 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou } if(num_rounds>1) { - freq_channel(eNB2UE[1], eNB->frame_parms.N_RB_DL,2*eNB->frame_parms.N_RB_DL + 1); + freq_channel(eNB2UE[1], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1); - for (u=0; u<2*eNB->frame_parms.N_RB_DL; u++) { + for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) { for (aarx=0; aarxnb_rx; aarx++) { for (aatx=0; aatxnb_tx; aatx++) { channelx = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].x; @@ -207,9 +208,9 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou } } - freq_channel(eNB2UE[2], eNB->frame_parms.N_RB_DL,2*eNB->frame_parms.N_RB_DL + 1); + freq_channel(eNB2UE[2], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1); - for (u=0; u<2*eNB->frame_parms.N_RB_DL; u++) { + for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) { for (aarx=0; aarxnb_rx; aarx++) { for (aatx=0; aatxnb_tx; aatx++) { channelx = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].x; @@ -219,9 +220,9 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou } } - freq_channel(eNB2UE[3], eNB->frame_parms.N_RB_DL,2*eNB->frame_parms.N_RB_DL + 1); + freq_channel(eNB2UE[3], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1); - for (u=0; u<2*eNB->frame_parms.N_RB_DL; u++) { + for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) { for (aarx=0; aarxnb_rx; aarx++) { for (aatx=0; aatxnb_tx; aatx++) { channelx = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].x; @@ -237,11 +238,11 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou //AWGN // tx_lev is the average energy over the whole subframe // but SNR should be better defined wrt the energy in the reference symbols - sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)eNB->frame_parms.ofdm_symbol_size/(double)(eNB->frame_parms.N_RB_DL*12)) - SNR; + sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)ru->frame_parms.ofdm_symbol_size/(double)(ru->frame_parms.N_RB_DL*12)) - SNR; sigma2 = pow(10,sigma2_dB/10); for (i=0; i<2*UE->frame_parms.samples_per_tti; i++) { - for (aa=0; aaframe_parms.nb_antennas_rx; aa++) { + for (aa=0; aaframe_parms.nb_antennas_rx; aa++) { //printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]); ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i] = (short) (r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); @@ -251,28 +252,118 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou } } +uint16_t +fill_tx_req(nfapi_tx_request_body_t *tx_req_body, + uint16_t absSF, + uint16_t pdu_length, + uint16_t pdu_index, + uint8_t *pdu) +{ + nfapi_tx_request_pdu_t *TX_req = &tx_req_body->tx_pdu_list[tx_req_body->number_of_pdus]; + LOG_D(MAC, "Filling TX_req %d for pdu length %d\n", + tx_req_body->number_of_pdus, pdu_length); + + TX_req->pdu_length = pdu_length; + TX_req->pdu_index = pdu_index; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = pdu_length; + TX_req->segments[0].segment_data = pdu; + tx_req_body->tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + tx_req_body->number_of_pdus++; + + return (((absSF / 10) << 4) + (absSF % 10)); +} + +void +fill_dlsch_config(nfapi_dl_config_request_body_t * dl_req, + uint16_t length, + uint16_t pdu_index, + uint16_t rnti, + uint8_t resource_allocation_type, + uint8_t virtual_resource_block_assignment_flag, + uint16_t resource_block_coding, + uint8_t modulation, + uint8_t redundancy_version, + uint8_t transport_blocks, + uint8_t transport_block_to_codeword_swap_flag, + uint8_t transmission_scheme, + uint8_t number_of_layers, + uint8_t number_of_subbands, + // uint8_t codebook_index, + uint8_t ue_category_capacity, + uint8_t pa, + uint8_t delta_power_offset_index, + uint8_t ngap, + uint8_t nprb, + uint8_t transmission_mode, + uint8_t num_bf_prb_per_subband, + uint8_t num_bf_vector) +{ + nfapi_dl_config_request_pdu_t *dl_config_pdu = + &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = length; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = pdu_index; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = rnti; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = resource_allocation_type; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = virtual_resource_block_assignment_flag; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = resource_block_coding; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = modulation; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = redundancy_version; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = transport_blocks; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = transport_block_to_codeword_swap_flag; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = transmission_scheme; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = number_of_layers; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = number_of_subbands; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = codebook_index; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = ue_category_capacity; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = pa; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = delta_power_offset_index; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = ngap; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = nprb; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = transmission_mode; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = num_bf_prb_per_subband; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = num_bf_vector; + dl_req->number_pdu++; +} void fill_DCI(PHY_VARS_eNB *eNB, - DCI_ALLOC_t *dci_alloc, + int frame, int subframe, + Sched_Rsp_t *sched_resp, + uint8_t input_buffer[NUMBER_OF_UE_MAX][20000], int n_rnti, int n_users, int transmission_mode, + int retrans, int common_flag, + int NB_RB, int DLSCH_RB_ALLOC, int TPC, int mcs1, int mcs2, int ndi, int rv, + int pa, int *num_common_dci, int *num_ue_spec_dci, int *num_dci) { int k; - int dci_length = -1,dci_length_bytes = -1; - // printf("Generating DCIs for %d users, TM %d, mcs1 %d\n",n_users,transmission_mode,mcs1); + nfapi_dl_config_request_body_t *dl_req=&sched_resp->DL_req->dl_config_request_body; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + nfapi_tx_request_body_t *TX_req=&sched_resp->TX_req->tx_request_body; + + dl_req->number_dci=0; + dl_req->number_pdu=0; + TX_req->number_of_pdus=0; + for(k=0; kframe_parms.frame_type == TDD) { - - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1_1_5MHz_TDD_t; - dci_length_bytes = sizeof(DCI1_1_5MHz_TDD_t); - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = ndi; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = rv; - break; - - case 25: - dci_length = sizeof_DCI1_5MHz_TDD_t; - dci_length_bytes = sizeof(DCI1_5MHz_TDD_t); - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = ndi; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = rv; - break; - - case 50: - dci_length = sizeof_DCI1_10MHz_TDD_t; - dci_length_bytes = sizeof(DCI1_10MHz_TDD_t); - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = ndi; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = rv; - break; - - case 100: - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = ndi; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = rv; - dci_length = sizeof_DCI1_20MHz_TDD_t; - dci_length_bytes = sizeof(DCI1_20MHz_TDD_t); - break; - } - } else { - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1_1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1_1_5MHz_FDD_t); - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = ndi; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = rv; - break; - - case 25: - dci_length = sizeof_DCI1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1_5MHz_FDD_t); - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = ndi; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = rv; - break; - - case 50: - dci_length = sizeof_DCI1_10MHz_FDD_t; - dci_length_bytes = sizeof(DCI1_10MHz_FDD_t); - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = ndi; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = rv; - break; - - case 100: - dci_length = sizeof_DCI1_20MHz_FDD_t; - dci_length_bytes = sizeof(DCI1_20MHz_FDD_t); - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = ndi; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = rv; - break; - } - } - - memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[*num_dci].dci_length = dci_length; - dci_alloc[*num_dci].L = 1; - dci_alloc[*num_dci].rnti = n_rnti+k; - dci_alloc[*num_dci].format = format1; - dci_alloc[*num_dci].search_space = DCI_UE_SPACE; - dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]); - - // printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - n_rnti+k, - format1, - eNB->dlsch[0], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - transmission_mode>=7?transmission_mode:0); - - *num_dci = *num_dci+1; - *num_ue_spec_dci = *num_ue_spec_dci+1; - } else { - if (eNB->frame_parms.frame_type == TDD) { - - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 50: - dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); - break; - } - } else { - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1A_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 50: - dci_length = sizeof_DCI1A_10MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - dci_length = sizeof_DCI1A_20MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - } - } - - memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[*num_dci].dci_length = dci_length; - dci_alloc[*num_dci].L = 1; - dci_alloc[*num_dci].rnti = SI_RNTI; - dci_alloc[*num_dci].format = format1A; - dci_alloc[*num_dci].firstCCE = 0; - dci_alloc[*num_dci].search_space = DCI_COMMON_SPACE; - dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]); - - printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - SI_RNTI, - format1A, - eNB->dlsch[0], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - transmission_mode>=7?transmission_mode:0); - - *num_common_dci=*num_common_dci+1; - *num_dci = *num_dci + 1; - - } - - break; - - case 3: - if (common_flag == 0) { - - if (eNB->frame_parms.nb_antennas_tx == 2) { - - if (eNB->frame_parms.frame_type == TDD) { - - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI2A_1_5MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2A_1_5MHz_2A_TDD_t); - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 25: - dci_length = sizeof_DCI2A_5MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2A_5MHz_2A_TDD_t); - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 50: - dci_length = sizeof_DCI2A_10MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2A_10MHz_2A_TDD_t); - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 100: - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - dci_length = sizeof_DCI2A_20MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2A_20MHz_2A_TDD_t); - break; - } - } - - else { - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI2A_1_5MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2A_1_5MHz_2A_FDD_t); - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 25: - dci_length = sizeof_DCI2A_5MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2A_5MHz_2A_FDD_t); - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 50: - dci_length = sizeof_DCI2A_10MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2A_10MHz_2A_FDD_t); - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 100: - dci_length = sizeof_DCI2A_20MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2A_20MHz_2A_FDD_t); - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - } - } - } else if (eNB->frame_parms.nb_antennas_tx == 4) { - - } - - memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[*num_dci].dci_length = dci_length; - dci_alloc[*num_dci].L = 1; - dci_alloc[*num_dci].rnti = n_rnti+k; - dci_alloc[*num_dci].format = format2A; - dci_alloc[*num_dci].search_space = DCI_UE_SPACE; - dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]); - - //printf("Generating dlsch params for user %d / format 2A (%d)\n",k,format2A); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - n_rnti+k, - format2A, - eNB->dlsch[0], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - transmission_mode>=7?transmission_mode:0); - - *num_dci = *num_dci + 1; - *num_ue_spec_dci = *num_ue_spec_dci + 1; - } else { - if (eNB->frame_parms.frame_type == TDD) { - - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 50: - dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); - break; - } - } else { - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1A_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 50: - dci_length = sizeof_DCI1A_10MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - dci_length = sizeof_DCI1A_20MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - } - } - - memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[*num_dci].dci_length = dci_length; - dci_alloc[*num_dci].L = 1; - dci_alloc[*num_dci].rnti = SI_RNTI; - dci_alloc[*num_dci].format = format1A; - dci_alloc[*num_dci].firstCCE = 0; - dci_alloc[*num_dci].search_space = DCI_COMMON_SPACE; - dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]); - - //printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - SI_RNTI, - format1A, - eNB->dlsch[0], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - transmission_mode>=7?transmission_mode:0); - - *num_common_dci = *num_common_dci + 1; - *num_dci = *num_dci + 1; - - } - - //printf("Generated DCI format 2A (Transmission Mode 3)\n"); - break; - - case 4: - if (common_flag == 0) { - - if (eNB->frame_parms.nb_antennas_tx == 2) { - - if (eNB->frame_parms.frame_type == TDD) { - - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI2_1_5MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2_1_5MHz_2A_TDD_t); - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 25: - dci_length = sizeof_DCI2_5MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2_5MHz_2A_TDD_t); - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 50: - dci_length = sizeof_DCI2_10MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2_10MHz_2A_TDD_t); - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 100: - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - dci_length = sizeof_DCI2_20MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2_20MHz_2A_TDD_t); - break; - } - } - - else { - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI2_1_5MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2_1_5MHz_2A_FDD_t); - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 25: - dci_length = sizeof_DCI2_5MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2_5MHz_2A_FDD_t); - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 50: - dci_length = sizeof_DCI2_10MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2_10MHz_2A_FDD_t); - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 100: - dci_length = sizeof_DCI2_20MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2_20MHz_2A_FDD_t); - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - } - } - } else if (eNB->frame_parms.nb_antennas_tx == 4) { - - } - - memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[*num_dci].dci_length = dci_length; - dci_alloc[*num_dci].L = 1; - dci_alloc[*num_dci].rnti = n_rnti+k; - dci_alloc[*num_dci].format = format2; - dci_alloc[*num_dci].search_space = DCI_UE_SPACE; - dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]); - - printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - n_rnti+k, - format2, - eNB->dlsch[0], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - transmission_mode>=7?transmission_mode:0); - - *num_dci = *num_dci + 1; - *num_ue_spec_dci = *num_ue_spec_dci + 1; - } else { - if (eNB->frame_parms.frame_type == TDD) { - - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 50: - dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); - break; - } - } else { - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1A_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 50: - dci_length = sizeof_DCI1A_10MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - dci_length = sizeof_DCI1A_20MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - } - } - - memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[*num_dci].dci_length = dci_length; - dci_alloc[*num_dci].L = 1; - dci_alloc[*num_dci].rnti = SI_RNTI; - dci_alloc[*num_dci].format = format1A; - dci_alloc[*num_dci].firstCCE = 0; - dci_alloc[*num_dci].search_space = DCI_COMMON_SPACE; - dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]); - - printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - SI_RNTI, - format1A, - eNB->dlsch[0], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - transmission_mode>=7?transmission_mode:0); - - *num_common_dci = *num_common_dci + 1; - *num_dci = *num_dci + 1; + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = n_rnti+k; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = TPC; // dont adjust power when retransmitting + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = ndi; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = rv; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = DLSCH_RB_ALLOC; + //deactivate second codeword + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1; + + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = 0; + + dl_req->number_dci++; + dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + + + fill_dlsch_config(dl_req, + get_TBS_DL(mcs1,NB_RB), + (retrans > 0) ? -1 : 0, /* retransmission, no pdu_index */ + n_rnti, + 0, // type 0 allocation from 7.1.6 in 36.213 + 0, // virtual_resource_block_assignment_flag, unused here + DLSCH_RB_ALLOC, // resource_block_coding, + get_Qm(mcs1), + rv, // redundancy version + 1, // transport blocks + 0, // transport block to codeword swap flag + transmission_mode == 1 ? 0 : 1, // transmission_scheme + 1, // number of layers + 1, // number of subbands + // uint8_t codebook_index, + 4, // UE category capacity + pa, // pa + 0, // delta_power_offset for TM5 + 0, // ngap + 0, // nprb + transmission_mode, + 0, //number of PRBs treated as one subband, not used here + 0 // number of beamforming vectors, not used here + ); + fill_tx_req(TX_req, + (frame * 10) + subframe, + get_TBS_DL(mcs1,NB_RB), + 0, + input_buffer[k]); + } + else { + + } + + break; + + case 3: + if (common_flag == 0) { + + if (eNB->frame_parms.nb_antennas_tx == 2) { + + if (eNB->frame_parms.frame_type == TDD) { + + } + else { + + } + } + } + break; + + case 4: + if (common_flag == 0) { + + if (eNB->frame_parms.nb_antennas_tx == 2) { + + if (eNB->frame_parms.frame_type == TDD) { + + + } + + else { + + } + } else if (eNB->frame_parms.nb_antennas_tx == 4) { + + } + + } + else { } @@ -1186,90 +480,31 @@ void fill_DCI(PHY_VARS_eNB *eNB, case 5: case 6: - memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu2_1E[k],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); - dci_alloc[*num_dci].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t; - dci_alloc[*num_dci].L = 1; - dci_alloc[*num_dci].rnti = n_rnti+k; - dci_alloc[*num_dci].format = format1E_2A_M10PRB; - dci_alloc[*num_dci].firstCCE = 4*k; - dci_alloc[*num_dci].search_space = DCI_UE_SPACE; - printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu2_1E[k], - n_rnti+k, - format1E_2A_M10PRB, - eNB->dlsch[k], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[k].DL_pmi_single, - transmission_mode>=7?transmission_mode:0); - - dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]); - *num_ue_spec_dci = *num_ue_spec_dci + 1; - *num_dci = *num_dci + 1; break; - default: - printf("Unsupported Transmission Mode!!!"); - exit(-1); - break; - } + default: + printf("Unsupported Transmission Mode %d!!!\n",transmission_mode); + exit(-1); + break; } + } + *num_dci = dl_req->number_dci; + *num_ue_spec_dci = dl_req->number_dci; + *num_common_dci = 0; } int n_users = 1; sub_frame_t subframe=7; -DCI_PDU DCI_pdu; int num_common_dci=0,num_ue_spec_dci=0,num_dci=0,num_pdcch_symbols=1; - - -DCI_PDU *get_dci_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subframeP) { - - if (subframeP == subframe) { - DCI_pdu.Num_dci = num_ue_spec_dci + num_common_dci; - DCI_pdu.num_pdcch_symbols = num_pdcch_symbols; - } else { - DCI_pdu.Num_dci = 0; - DCI_pdu.num_pdcch_symbols = num_pdcch_symbols; - } - - return &DCI_pdu; -} - -void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, uint8_t cooperation_flag, frame_t frameP, sub_frame_t subframeP) { - - return; -} - uint16_t n_rnti=0x1234; -unsigned char *input_buffer0[2],*input_buffer1[2]; -unsigned short input_buffer_length0,input_buffer_length1; - -uint8_t *get_dlsch_sdu(module_id_t module_idP,int CC_id,frame_t frameP,rnti_t rnti,uint8_t TBindex) { - - int k; - - for (k=0;kuse_ia_receiver = 1; if ((n_tx_port!=2) || (transmission_mode!=5)) { - msg("IA receiver only supported for TM5!"); + printf("IA receiver only supported for TM5!"); exit(-1); } @@ -1644,7 +910,7 @@ int main(int argc, char **argv) i_mod = atoi(optarg); if (i_mod!=2 && i_mod!=4 && i_mod!=6) { - msg("Wrong i_mod %d, should be 2,4 or 6\n",i_mod); + printf("Wrong i_mod %d, should be 2,4 or 6\n",i_mod); exit(-1); } @@ -1658,7 +924,7 @@ int main(int argc, char **argv) n_tx_port=atoi(optarg); if ((n_tx_port==0) || ((n_tx_port>2))) { - msg("Unsupported number of cell specific antennas ports %d\n",n_tx_port); + printf("Unsupported number of cell specific antennas ports %d\n",n_tx_port); exit(-1); } @@ -1675,7 +941,7 @@ int main(int argc, char **argv) (transmission_mode!=5) && (transmission_mode!=6) && (transmission_mode!=7)) { - msg("Unsupported transmission mode %d\n",transmission_mode); + printf("Unsupported transmission mode %d\n",transmission_mode); exit(-1); } @@ -1689,17 +955,17 @@ int main(int argc, char **argv) n_tx_phy=atoi(optarg); if (n_tx_phy < n_tx_port) { - msg("n_tx_phy mush not be smaller than n_tx_port"); + printf("n_tx_phy mush not be smaller than n_tx_port"); exit(-1); } if ((transmission_mode>1 && transmission_mode<7) && n_tx_port<2) { - msg("n_tx_port must be >1 for transmission_mode %d\n",transmission_mode); + printf("n_tx_port must be >1 for transmission_mode %d\n",transmission_mode); exit(-1); } if (transmission_mode==7 && (n_tx_phy!=1 && n_tx_phy!=2 && n_tx_phy!=4 && n_tx_phy!=8 && n_tx_phy!=16 && n_tx_phy!=64 && n_tx_phy!=128)) { - msg("Physical number of antennas not supported for TM7.\n"); + printf("Physical number of antennas not supported for TM7.\n"); exit(-1); } @@ -1718,7 +984,7 @@ int main(int argc, char **argv) n_rx=atoi(optarg); if ((n_rx==0) || (n_rx>2)) { - msg("Unsupported number of rx antennas %d\n",n_rx); + printf("Unsupported number of rx antennas %d\n",n_rx); exit(-1); } @@ -1770,9 +1036,14 @@ int main(int argc, char **argv) } } + if (transmission_mode>1) pa=dBm3; + printf("dlsim: tmode %d, pa %d\n",transmission_mode,pa); + + AssertFatal(load_configmodule(argc,argv) != NULL, + "cannot load configuration module, exiting\n"); logInit(); // enable these lines if you need debug info - set_comp_log(PHY,LOG_DEBUG,LOG_HIGH,1); + set_comp_log(PHY,LOG_INFO,LOG_HIGH,1); set_glog(log_level,LOG_HIGH); // moreover you need to init itti with the following line // however itti will catch all signals, so ctrl-c won't work anymore @@ -1822,8 +1093,11 @@ int main(int argc, char **argv) n_users = 2; printf("dual_stream_UE=%d\n", dual_stream_UE); } + RC.nb_L1_inst = 1; + RC.nb_RU = 1; - lte_param_init(n_tx_port, + lte_param_init(&eNB,&UE,&ru, + n_tx_port, n_tx_phy, n_rx, transmission_mode, @@ -1832,20 +1106,26 @@ int main(int argc, char **argv) Nid_cell, tdd_config, N_RB_DL, + pa, threequarter_fs, osf, perfect_ce); - + RC.eNB = (PHY_VARS_eNB ***)malloc(sizeof(PHY_VARS_eNB **)); + RC.eNB[0] = (PHY_VARS_eNB **)malloc(sizeof(PHY_VARS_eNB *)); + RC.ru = (RU_t **)malloc(sizeof(RC.ru)); + RC.eNB[0][0] = eNB; + RC.ru[0] = ru; + printf("lte_param_init done\n"); if ((transmission_mode==1) || (transmission_mode==7)) { - for (aa=0; aaframe_parms.nb_antennas_tx; aa++) - for (re=0; reframe_parms.ofdm_symbol_size; re++) - eNB->common_vars.beam_weights[0][0][aa][re] = 0x00007fff/eNB->frame_parms.nb_antennas_tx; + for (aa=0; aanb_tx; aa++) + for (re=0; reframe_parms.ofdm_symbol_size; re++) + ru->beam_weights[0][0][aa][re] = 0x00007fff/eNB->frame_parms.nb_antennas_tx; } if (transmission_mode<7) - eNB->do_precoding=0; + ru->do_precoding=0; else - eNB->do_precoding=1; + ru->do_precoding=1; eNB->mac_enabled=1; if (two_thread_flag == 0) { @@ -1860,9 +1140,6 @@ int main(int argc, char **argv) } // callback functions required for phy_procedures_tx - mac_xface->get_dci_sdu = get_dci_sdu; - mac_xface->get_dlsch_sdu = get_dlsch_sdu; - mac_xface->eNB_dlsch_ulsch_scheduler = eNB_dlsch_ulsch_scheduler; // eNB_id_i = UE->n_connected_eNB; @@ -1875,7 +1152,10 @@ int main(int argc, char **argv) snr1 = snr0+snr_int; printf("SNR0 %f, SNR1 %f\n",snr0,snr1); + uint8_t input_buffer[NUMBER_OF_UE_MAX][20000]; + for (i=0;iframe_parms; @@ -2024,48 +1304,6 @@ int main(int argc, char **argv) UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti = n_rnti; - // Fill in UL_alloc - UL_alloc_pdu.type = 0; - UL_alloc_pdu.hopping = 0; - UL_alloc_pdu.rballoc = UL_RB_ALLOC; - UL_alloc_pdu.mcs = 1; - UL_alloc_pdu.ndi = 1; - UL_alloc_pdu.TPC = 0; - UL_alloc_pdu.cqi_req = 1; - - CCCH_alloc_pdu.type = 0; - CCCH_alloc_pdu.vrb_type = 0; - CCCH_alloc_pdu.rballoc = CCCH_RB_ALLOC; - CCCH_alloc_pdu.ndi = 1; - CCCH_alloc_pdu.mcs = 1; - CCCH_alloc_pdu.harq_pid = 0; - - DLSCH_alloc_pdu2_1E[0].rah = 0; - DLSCH_alloc_pdu2_1E[0].rballoc = DLSCH_RB_ALLOC; - DLSCH_alloc_pdu2_1E[0].TPC = 0; - DLSCH_alloc_pdu2_1E[0].dai = 0; - DLSCH_alloc_pdu2_1E[0].harq_pid = 0; - //DLSCH_alloc_pdu2_1E[0].tb_swap = 0; - DLSCH_alloc_pdu2_1E[0].mcs = mcs1; - DLSCH_alloc_pdu2_1E[0].ndi = 1; - DLSCH_alloc_pdu2_1E[0].rv = 0; - // Forget second codeword - DLSCH_alloc_pdu2_1E[0].tpmi = (transmission_mode>=5 ? 5 : 0); // precoding - DLSCH_alloc_pdu2_1E[0].dl_power_off = (transmission_mode==5 ? 0 : 1); - - DLSCH_alloc_pdu2_1E[1].rah = 0; - DLSCH_alloc_pdu2_1E[1].rballoc = DLSCH_RB_ALLOC; - DLSCH_alloc_pdu2_1E[1].TPC = 0; - DLSCH_alloc_pdu2_1E[1].dai = 0; - DLSCH_alloc_pdu2_1E[1].harq_pid = 0; - //DLSCH_alloc_pdu2_1E[1].tb_swap = 0; - DLSCH_alloc_pdu2_1E[1].mcs = mcs_i; - DLSCH_alloc_pdu2_1E[1].ndi = 1; - DLSCH_alloc_pdu2_1E[1].rv = 0; - // Forget second codeword - DLSCH_alloc_pdu2_1E[1].tpmi = (transmission_mode>=5 ? 5 : 0) ; // precoding - DLSCH_alloc_pdu2_1E[1].dl_power_off = (transmission_mode==5 ? 0 : 1); - eNB2UE[0] = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx, UE->frame_parms.nb_antennas_rx, channel_model, @@ -2088,7 +1326,7 @@ int main(int argc, char **argv) } if (eNB2UE[0]==NULL) { - msg("Problem generating channel model. Exiting.\n"); + printf("Problem generating channel model. Exiting.\n"); exit(-1); } @@ -2114,7 +1352,7 @@ int main(int argc, char **argv) break; } - for (k=0; kdlsch[k][i] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&eNB->frame_parms); @@ -2166,24 +1404,31 @@ int main(int argc, char **argv) eNB->UE_stats[1].DL_pmi_single = 0; } + eNB_rxtx_proc_t *proc_eNB = &eNB->proc.proc_rxtx[0];//UE->current_thread_id[subframe]]; if (input_fd==NULL) { - + DL_req.dl_config_request_body.number_pdcch_ofdm_symbols = num_pdcch_symbols; + DL_req.sfn_sf = (proc_eNB->frame_tx*10)+subframe; + TX_req.sfn_sf = (proc_eNB->frame_tx*10)+subframe; // UE specific DCI fill_DCI(eNB, - &dci_alloc[0], - subframe, + proc_eNB->frame_tx,subframe, + &sched_resp, + input_buffer, n_rnti, n_users, transmission_mode, + 0, common_flag, + NB_RB, DLSCH_RB_ALLOC, TPC, mcs1, mcs2, 1, 0, + pa, &num_common_dci, &num_ue_spec_dci, &num_dci); @@ -2194,65 +1439,8 @@ int main(int argc, char **argv) - - for (k=0; kdlsch[k][0]->harq_processes[0]->TBS/8; - input_buffer0[k] = (unsigned char *)malloc(input_buffer_length0+4); - memset(input_buffer0[k],0,input_buffer_length0+4); - input_buffer_length1 = eNB->dlsch[k][1]->harq_processes[0]->TBS/8; - input_buffer1[k] = (unsigned char *)malloc(input_buffer_length1+4); - memset(input_buffer1[k],0,input_buffer_length1+4); - - if (input_trch_file==0) { - for (i=0; i>3]+=(1<<(7-(i&7))); - - if (i<16) - printf("input_trch_val %d : %c\n",i,input_trch_val[0]); - - i++; - - if (((i%8) == 0) && (i<17)) - printf("%x\n",input_buffer0[k][(i-1)>>3]); - } - - printf("Read in %d bits\n",i); - } - } } - // this is for user 0 only - coded_bits_per_codeword = get_G(&eNB->frame_parms, - eNB->dlsch[0][0]->harq_processes[0]->nb_rb, - eNB->dlsch[0][0]->harq_processes[0]->rb_alloc, - get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs), - eNB->dlsch[0][0]->harq_processes[0]->Nl, - num_pdcch_symbols, - 0, - subframe, - transmission_mode>=7?transmission_mode:0); - - uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword); - printf("uncoded_ber_bit=%p\n",uncoded_ber_bit); - snr_step = input_snr_step; UE->high_speed_flag = 1; UE->ch_est_alpha=0; @@ -2332,7 +1520,7 @@ int main(int argc, char **argv) struct list time_vector_rx_dec; initialize(&time_vector_rx_dec); - eNB_rxtx_proc_t *proc_eNB = &eNB->proc.proc_rxtx[UE->current_thread_id[subframe]]; + for (trials = 0; trialsframe_parms.nb_antennas_tx; aa++) { - memset(&eNB->common_vars.txdataF[eNB_id][aa][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); + memset(&eNB->common_vars.txdataF[aa][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); } if (input_fd==NULL) { @@ -2383,108 +1571,73 @@ int main(int argc, char **argv) TB0_active = 1; eNB->dlsch[0][0]->harq_processes[0]->rvidx = round&3; - - fill_DCI(eNB,&dci_alloc[0],subframe,n_rnti,n_users,transmission_mode,common_flag,DLSCH_RB_ALLOC,TPC, - mcs1,mcs2,!(trials&1),round&3,&num_common_dci,&num_ue_spec_dci,&num_dci); + DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + fill_DCI(eNB,proc_eNB->frame_tx,subframe,&sched_resp,input_buffer,n_rnti,n_users,transmission_mode,0,common_flag,NB_RB,DLSCH_RB_ALLOC,TPC, + mcs1,mcs2,!(trials&1),round&3,pa,&num_common_dci,&num_ue_spec_dci,&num_dci); } else { - fill_DCI(eNB,&dci_alloc[0],subframe,n_rnti,n_users,transmission_mode,common_flag,DLSCH_RB_ALLOC,TPC, - (TB0_active==1)?mcs1:0,mcs2,!(trials&1),(TB0_active==1)?round&3:0,&num_common_dci,&num_ue_spec_dci,&num_dci); + DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + fill_DCI(eNB,proc_eNB->frame_tx,subframe,&sched_resp,input_buffer,n_rnti,n_users,transmission_mode,1,common_flag,NB_RB,DLSCH_RB_ALLOC,TPC, + (TB0_active==1)?mcs1:0,mcs2,!(trials&1),(TB0_active==1)?round&3:0,pa,&num_common_dci,&num_ue_spec_dci,&num_dci); } - for (i=num_common_dci; i %e + j%e (%d +j%d)\n",i/4,strtod(input_val_str,NULL),strtod(input_val_str2,NULL),((short*)txdata[0])[i/4],((short*)txdata[0])[(i/4)+1]);//1,input_val2,); - } - i++; - if (i>(FRAME_LENGTH_SAMPLES)) - break; - } - printf("Read in %d samples\n",i/4); - write_output("txsig0.m","txs0", txdata[0],2*frame_parms->samples_per_tti,1,1); - // write_output("txsig1.m","txs1", txdata[1],FRAME_LENGTH_COMPLEX_SAMPLES,1,1); - tx_lev = signal_energy(&txdata[0][0], - OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES); - tx_lev_dB = (unsigned int) dB_fixed(tx_lev); - } - */ - - + } + proc_eNB->subframe_tx = subframe; + sched_resp.subframe=subframe; + sched_resp.frame=proc_eNB->frame_tx; + eNB->abstraction_flag=0; + schedule_response(&sched_resp); + phy_procedures_eNB_TX(eNB,proc_eNB,no_relay,NULL,1); - phy_procedures_eNB_TX(eNB,proc_eNB,no_relay,NULL,1,dci_flag); + if (uncoded_ber_bit == NULL) { + // this is for user 0 only + printf("nb_rb %d, rb_alloc %x, mcs %d\n", + eNB->dlsch[0][0]->harq_processes[0]->nb_rb, + eNB->dlsch[0][0]->harq_processes[0]->rb_alloc, + eNB->dlsch[0][0]->harq_processes[0]->mcs); + coded_bits_per_codeword = get_G(&eNB->frame_parms, + eNB->dlsch[0][0]->harq_processes[0]->nb_rb, + eNB->dlsch[0][0]->harq_processes[0]->rb_alloc, + get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs), + eNB->dlsch[0][0]->harq_processes[0]->Nl, + num_pdcch_symbols, + 0, + subframe, + transmission_mode>=7?transmission_mode:0); + + uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword); + printf("uncoded_ber_bit=%p\n",uncoded_ber_bit); + } start_meas(&eNB->ofdm_mod_stats); - /* - do_OFDM_mod_l(eNB->common_vars.txdataF[eNB_id], - eNB->common_vars.txdata[eNB_id], - (subframe*2), - &eNB->frame_parms); - - do_OFDM_mod_l(eNB->common_vars.txdataF[eNB_id], - eNB->common_vars.txdata[eNB_id], - (subframe*2)+1, - &eNB->frame_parms); - */ - - do_OFDM_mod_symbol(&eNB->common_vars, - eNB_id, - (subframe*2), - &eNB->frame_parms, - eNB->do_precoding); - - do_OFDM_mod_symbol(&eNB->common_vars, - eNB_id, - (subframe*2)+1, - &eNB->frame_parms, - eNB->do_precoding); - + ru->proc.subframe_tx=subframe; + memcpy((void*)&ru->frame_parms,(void*)&eNB->frame_parms,sizeof(LTE_DL_FRAME_PARMS)); + feptx_prec(ru); + feptx_ofdm(ru); stop_meas(&eNB->ofdm_mod_stats); + + // generate next subframe for channel estimation + DL_req.dl_config_request_body.number_dci=0; + DL_req.dl_config_request_body.number_pdu=0; + TX_req.tx_request_body.number_of_pdus=0; proc_eNB->subframe_tx = subframe+1; + sched_resp.subframe=subframe+1; + schedule_response(&sched_resp); + phy_procedures_eNB_TX(eNB,proc_eNB,no_relay,NULL,0); - phy_procedures_eNB_TX(eNB,proc_eNB,no_relay,NULL,0,dci_flag); - do_OFDM_mod_l(eNB->common_vars.txdataF[eNB_id], - eNB->common_vars.txdata[eNB_id], - (subframe*2)+2, - &eNB->frame_parms); + ru->proc.subframe_tx=(subframe+1)%10; + feptx_prec(ru); + feptx_ofdm(ru); proc_eNB->frame_tx++; @@ -2492,7 +1645,7 @@ int main(int argc, char **argv) tx_lev = 0; for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { - tx_lev += signal_energy(&eNB->common_vars.txdata[eNB_id][aa] + tx_lev += signal_energy(&ru->common.txdata[aa] [subframe*eNB->frame_parms.samples_per_tti], eNB->frame_parms.samples_per_tti); } @@ -2500,21 +1653,22 @@ int main(int argc, char **argv) tx_lev_dB = (unsigned int) dB_fixed(tx_lev); + if (n_frames==1) { printf("tx_lev = %d (%d dB)\n",tx_lev,tx_lev_dB); - write_output("txsig0.m","txs0", &eNB->common_vars.txdata[eNB_id][0][subframe* eNB->frame_parms.samples_per_tti], eNB->frame_parms.samples_per_tti,1,1); + write_output("txsig0.m","txs0", &ru->common.txdata[0][subframe* eNB->frame_parms.samples_per_tti], eNB->frame_parms.samples_per_tti,1,1); if (transmission_mode<7) { - write_output("txsigF0.m","txsF0", &eNB->common_vars.txdataF[eNB_id][0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); + write_output("txsigF0.m","txsF0x", &ru->common.txdataF_BF[0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); } else if (transmission_mode == 7) { - write_output("txsigF0.m","txsF0", &eNB->common_vars.txdataF[eNB_id][5][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); - write_output("txsigF0_BF.m","txsF0_BF", &eNB->common_vars.txdataF_BF[eNB_id][0][0],eNB->frame_parms.ofdm_symbol_size,1,1); + write_output("txsigF0.m","txsF0", &ru->common.txdataF_BF[5][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); + write_output("txsigF0_BF.m","txsF0_BF", &ru->common.txdataF_BF[0][0],eNB->frame_parms.ofdm_symbol_size,1,1); } } } - DL_channel(eNB,UE,subframe,awgn_flag,SNR,tx_lev,hold_channel,abstx,num_rounds,trials,round,eNB2UE,s_re,s_im,r_re,r_im,csv_fd); + DL_channel(ru,UE,subframe,awgn_flag,SNR,tx_lev,hold_channel,abstx,num_rounds,trials,round,eNB2UE,s_re,s_im,r_re,r_im,csv_fd); UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[UE->current_thread_id[subframe]]; @@ -2532,6 +1686,8 @@ int main(int argc, char **argv) if (n_frames==1) printf("Running phy_procedures_UE_RX\n"); if (dci_flag==0) { + memcpy(dci_alloc,eNB->pdcch_vars[subframe&1].dci_alloc,num_dci*sizeof(DCI_ALLOC_t)); + UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->num_pdcch_symbols = num_pdcch_symbols; if (n_frames==1) printf("bypassing PDCCH/DCI detection\n"); if (generate_ue_dlsch_params_from_dci(proc->frame_rx, @@ -2541,7 +1697,7 @@ int main(int argc, char **argv) dci_alloc[0].format, UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id], UE->pdsch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id], - UE->dlsch[UE->current_thread_id[proc->subframe_rx]][0], + UE->dlsch[UE->current_thread_id[proc->subframe_rx]][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -2570,28 +1726,52 @@ int main(int argc, char **argv) dci_received = dci_received - UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->dci_received; if (dci_flag && (dci_received == 0)) { - //printf("DCI not received\n"); + printf("DCI not received\n"); dci_errors[round]++; - /* - write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); - write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[eNB_id]->dl_ch_estimates_ext[0],12*UE->frame_parms.N_RB_DL*3,1,1); - - write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[eNB_id]->rxdataF_comp[0],4*12*UE->frame_parms.N_RB_DL,1,1); - write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[eNB_id]->llr,12*UE->frame_parms.N_RB_DL*4*2,1,4); - write_output("txsigF0.m","txsF0", &eNB->common_vars.txdataF[eNB_id][0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size], - nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); + write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); + write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); + write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[0][eNB_id]->rxdataF_comp[0],4*300,1,1); + write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[0][eNB_id]->llr,2400,1,4); + write_output("rxsig0.m","rxs0", &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1); - write_output("rxsigF0.m","rxsF0", &UE->common_vars.rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + write_output("rxsigF0.m","rxsF0", &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + exit(-1); - */ + } + int bit_errors=0; if ((test_perf ==0 ) && (n_frames==1)) { - write_output("ch0.m","ch0",eNB2UE[0]->ch[0],eNB2UE[0]->channel_length,1,8); + dlsch_unscrambling(&eNB->frame_parms, + 0, + UE->dlsch[UE->current_thread_id[subframe]][0][0], + coded_bits_per_codeword, + UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0], + 0, + subframe<<1); + for (i=0;idlsch[0][0]->harq_processes[0]->e[i]==1 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] > 0)|| + (eNB->dlsch[0][0]->harq_processes[0]->e[i]==0 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] < 0)) { + uncoded_ber_bit[bit_errors++] = 1; + printf("error in pos %d : %d => %d\n",i, + eNB->dlsch[0][0]->harq_processes[0]->e[i], + UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i]); + } + else { + /* + printf("no error in pos %d : %d => %d\n",i, + eNB->dlsch[0][0]->harq_processes[0]->e[i], + UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i]); + */ + } + + write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); + write_output("ch0.m","ch0",eNB2UE[0]->ch[0],eNB2UE[0]->channel_length,1,8); + if (eNB->frame_parms.nb_antennas_tx>1) write_output("ch1.m","ch1",eNB2UE[0]->ch[eNB->frame_parms.nb_antennas_rx],eNB2UE[0]->channel_length,1,8); @@ -2625,6 +1805,7 @@ int main(int argc, char **argv) UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1); //pdsch_vars + printf("coded_bits_per_codeword %d\n",coded_bits_per_codeword); dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid); @@ -2648,7 +1829,7 @@ int main(int argc, char **argv) iter_trials++; if (n_frames==1) - printf("No DLSCH errors found (round %d),uncoded ber %f\n",round,uncoded_ber); + printf("No DLSCH errors found (round %d),uncoded ber %f\n",round,(double)bit_errors/coded_bits_per_codeword); UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->TBS; TB0_active = 0; @@ -2662,8 +1843,10 @@ int main(int argc, char **argv) iter_trials++; if (n_frames==1) { + + //if ((n_frames==1) || (SNR>=30)) { - printf("DLSCH errors found (round %d), uncoded ber %f\n",round,uncoded_ber); + printf("DLSCH errors found (round %d), uncoded ber %f\n",round,(double)bit_errors/coded_bits_per_codeword); for (s=0; sdlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->C; s++) { if (sdlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus) @@ -3292,13 +2475,6 @@ int main(int argc, char **argv) uncoded_ber_bit = NULL; - for (k=0; k Date: Tue, 13 Feb 2018 19:00:34 +0100 Subject: [PATCH 138/195] send UE Capabilities to Flexran RTController --- openair2/ENB_APP/flexran_agent_common.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index 2df5959815..c663d5cad1 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -630,21 +630,16 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl Protocol__FlexUeCapabilities *capabilities; capabilities = malloc(sizeof(Protocol__FlexUeCapabilities)); protocol__flex_ue_capabilities__init(capabilities); - //TODO: Set half duplex (FDD operation) - capabilities->has_half_duplex = 0; - capabilities->half_duplex = 0;//flexran_get_half_duplex(i); - //TODO: Set intra-frame hopping flag - capabilities->has_intra_sf_hopping = 0; - capabilities->intra_sf_hopping = 1;//flexran_get_intra_sf_hopping(i); - //TODO: Set support for type 2 hopping with n_sb > 1 - capabilities->has_type2_sb_1 = 0; - capabilities->type2_sb_1 = 1;//flexran_get_type2_sb_1(i); - //TODO: Set ue category - capabilities->has_ue_category = 0; - capabilities->ue_category = 1;//flexran_get_ue_category(i); - //TODO: Set UE support for resource allocation type 1 - capabilities->has_res_alloc_type1 = 0; - capabilities->res_alloc_type1 = 1;//flexran_get_res_alloc_type1(i); + capabilities->has_half_duplex = 1; + capabilities->half_duplex = flexran_get_half_duplex(mod_id, i); + capabilities->has_intra_sf_hopping = 1; + capabilities->intra_sf_hopping = flexran_get_intra_sf_hopping(mod_id, i); + capabilities->has_type2_sb_1 = 1; + capabilities->type2_sb_1 = flexran_get_type2_sb_1(mod_id, i); + capabilities->has_ue_category = 1; + capabilities->ue_category = flexran_get_ue_category(mod_id, i); + capabilities->has_res_alloc_type1 = 1; + capabilities->res_alloc_type1 = flexran_get_res_alloc_type1(mod_id, i); //Set the capabilites to the message ue_config[i]->capabilities = capabilities; From 9d05a9a3b10e6959a68228883e4670d2dba7e65e Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 13 Feb 2018 16:08:35 +0100 Subject: [PATCH 139/195] track IMSIs by decoding NAS messages Original Author: Xenofon Foukas Changed formatting does not compile RS: cast to get rid of compiler warning -> ImsiEpsMobileIdentity_t to ImsiMobileIdentity_t which is defined the same way --- openair2/RRC/LITE/rrc_eNB_S1AP.c | 228 +++++++++++++++++++++++++++++-- 1 file changed, 219 insertions(+), 9 deletions(-) diff --git a/openair2/RRC/LITE/rrc_eNB_S1AP.c b/openair2/RRC/LITE/rrc_eNB_S1AP.c index d2c0d0acbe..a2c570c009 100644 --- a/openair2/RRC/LITE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LITE/rrc_eNB_S1AP.c @@ -59,6 +59,10 @@ #include "gtpv1u_eNB_task.h" #include "RRC/LITE/rrc_eNB_GTPV1U.h" +#include "TLVDecoder.h" +#include "S1ap-NAS-PDU.h" +#include "flexran_agent_common_internal.h" + extern RAN_CONTEXT_t RC; /* Value to indicate an invalid UE initial id */ @@ -542,6 +546,74 @@ rrc_eNB_send_S1AP_UPLINK_NAS( S1AP_UPLINK_NAS (msg_p).nas_pdu.length = pdu_length; S1AP_UPLINK_NAS (msg_p).nas_pdu.buffer = pdu_buffer; + /* Process NAS message locally to get the IMSI */ + nas_message_t nas_msg; + memset(&nas_msg, 0, sizeof(nas_message_t)); + int size = 0; + uint32_t pdu_len = S1AP_UPLINK_NAS (msg_p).nas_pdu.length; + uint8_t *pdu_buff = malloc(pdu_len * sizeof(uint8_t)); + memcpy(pdu_buff, S1AP_UPLINK_NAS (msg_p).nas_pdu.buffer, pdu_len * sizeof(uint8_t)); + + nas_message_security_header_t *header = &nas_msg.header; + /* Decode the first octet of the header (security header type or EPS + * bearer identity, and protocol discriminator) */ + DECODE_U8((char *) pdu_buff, *(uint8_t*) (header), size); + + /* Decode NAS message */ + if (header->security_header_type <= SECURITY_HEADER_TYPE_INTEGRITY_PROTECTED + && header->protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE + && pdu_len > NAS_MESSAGE_SECURITY_HEADER_SIZE) { + + if (header->security_header_type != SECURITY_HEADER_TYPE_NOT_PROTECTED) { + /* Decode the message authentication code */ + DECODE_U32((char *) pdu_buff+size, header->message_authentication_code, size); + /* Decode the sequence number */ + DECODE_U8((char *) pdu_buff+size, header->sequence_number, size); + } + + if (size > 1) { + pdu_buff += size; + pdu_len -= size; + } + + /* Decode plain NAS message */ + EMM_msg *e_msg = &nas_msg.plain.emm; + emm_msg_header_t *emm_header = &e_msg->header; + + /* First decode the EMM message header */ + int e_head_size = 0; + + /* Check the buffer length */ + if (pdu_len > sizeof(emm_msg_header_t)) { + + /* Decode the security header type and the protocol discriminator */ + DECODE_U8(pdu_buff + e_head_size, *(uint8_t *)(emm_header), e_head_size); + /* Decode the message type */ + DECODE_U8(pdu_buff + e_head_size, emm_header->message_type, e_head_size); + + /* Check the protocol discriminator */ + if (emm_header->protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE) { + + pdu_buff += e_head_size; + pdu_len -= e_head_size; + + if (emm_header->message_type == IDENTITY_RESPONSE) { + decode_identity_response(&e_msg->identity_response, pdu_buff, pdu_len); + + if (e_msg->identity_response.mobileidentity.imsi.typeofidentity == MOBILE_IDENTITY_IMSI) { + ue_context_pP->ue_context.imsi = compute_imsi(&(e_msg->identity_response.mobileidentity.imsi)); + } + } + + pdu_buff -= e_head_size; + if (size > 1) { + pdu_buff -= size; + } + } + } + } + free(pdu_buff); + itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p); } } @@ -563,16 +635,82 @@ rrc_eNB_send_S1AP_UPLINK_NAS( &ulInformationTransfer->criticalExtensions.choice. c1.choice.ulInformationTransfer_r8; - if (ulInformationTransferR8->dedicatedInfoType. - present == - ULInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS) + if (ulInformationTransferR8->dedicatedInfoType.present == + ULInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS) { + + /* Process NAS message locally to get the IMSI */ + nas_message_t nas_msg; + memset(&nas_msg, 0, sizeof(nas_message_t)); + + int size = 0; + uint32_t pdu_len = ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.size; + uint8_t *pdu_buff = malloc(pdu_len * sizeof(uint8_t)); + memcpy(pdu_buff, ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.buf, pdu_len * sizeof(uint8_t)); + + nas_message_security_header_t *header = &nas_msg.header; + /* Decode the first octet of the header (security header type or EPS + * bearer identity, and protocol discriminator) */ + DECODE_U8((char *) pdu_buff, *(uint8_t*) (header), size); + + /* Decode NAS message */ + if (header->security_header_type <= SECURITY_HEADER_TYPE_INTEGRITY_PROTECTED && + header->protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE && + pdu_len > NAS_MESSAGE_SECURITY_HEADER_SIZE) { + + if (header->security_header_type != SECURITY_HEADER_TYPE_NOT_PROTECTED) { + /* Decode the message authentication code */ + DECODE_U32((char *) pdu_buff+size, header->message_authentication_code, size); + /* Decode the sequence number */ + DECODE_U8((char *) pdu_buff+size, header->sequence_number, size); + } + + if (size > 1) { + pdu_buff += size; + pdu_len -= size; + } + + /* Decode plain NAS message */ + EMM_msg *e_msg = &nas_msg.plain.emm; + emm_msg_header_t *emm_header = &e_msg->header; + + /* First decode the EMM message header */ + int e_head_size = 0; + + /* Check the buffer length */ + if (pdu_len > sizeof(emm_msg_header_t)) { + + /* Decode the security header type and the protocol discriminator */ + DECODE_U8(pdu_buff + e_head_size, *(uint8_t *)(emm_header), e_head_size); + /* Decode the message type */ + DECODE_U8(pdu_buff + e_head_size, emm_header->message_type, e_head_size); + + /* Check the protocol discriminator */ + if (emm_header->protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE) { + + pdu_buff += e_head_size; + pdu_len -= e_head_size; + + if (emm_header->message_type == IDENTITY_RESPONSE) { + decode_identity_response(&e_msg->identity_response, pdu_buff, pdu_len); + + if (e_msg->identity_response.mobileidentity.imsi.typeofidentity == MOBILE_IDENTITY_IMSI) { + ue_context_pP->ue_context.imsi = compute_imsi(&(e_msg->identity_response.mobileidentity.imsi)); + } + } + + pdu_buff -= e_head_size; + if (size > 1) { + pdu_buff -= size; + } + } + } + } + free(pdu_buff); + s1ap_eNB_new_data_request (mod_id, ue_index, - ulInformationTransferR8-> - dedicatedInfoType.choice. - dedicatedInfoNAS.buf, - ulInformationTransferR8-> - dedicatedInfoType.choice. - dedicatedInfoNAS.size); + ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.buf, + ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.size); + } } } } @@ -674,6 +812,78 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ( rrcConnectionSetupComplete->dedicatedInfoNAS.buf; S1AP_NAS_FIRST_REQ (message_p).nas_pdu.length = rrcConnectionSetupComplete->dedicatedInfoNAS.size; + // Process NAS message locally to get the IMSI + nas_message_t nas_msg; + memset(&nas_msg, 0, sizeof(nas_message_t)); + + int size = 0; + uint32_t pdu_len = S1AP_NAS_FIRST_REQ (message_p).nas_pdu.length; + uint8_t *pdu_buff = malloc(pdu_len * sizeof(uint8_t)); + memcpy(pdu_buff, S1AP_NAS_FIRST_REQ (message_p).nas_pdu.buffer, pdu_len * sizeof(uint8_t)); + + nas_message_security_header_t *header = &nas_msg.header; + /* Decode the first octet of the header (security header type or EPS + * bearer identity, and protocol discriminator) */ + DECODE_U8((char *) pdu_buff, *(uint8_t*) (header), size); + + /* Decode NAS message */ + if (header->security_header_type <= SECURITY_HEADER_TYPE_INTEGRITY_PROTECTED && + header->protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE && + pdu_len > NAS_MESSAGE_SECURITY_HEADER_SIZE) { + + if (header->security_header_type != SECURITY_HEADER_TYPE_NOT_PROTECTED) { + /* Decode the message authentication code */ + DECODE_U32((char *) pdu_buff+size, header->message_authentication_code, size); + /* Decode the sequence number */ + DECODE_U8((char *) pdu_buff+size, header->sequence_number, size); + } + + if (size > 1) { + pdu_buff += size; + pdu_len -= size; + } + + /* Decode plain NAS message */ + EMM_msg *e_msg = &nas_msg.plain.emm; + emm_msg_header_t *emm_header = &e_msg->header; + + /* First decode the EMM message header */ + int e_head_size = 0; + + /* Check the buffer length */ + if (pdu_len > sizeof(emm_msg_header_t)) { + + /* Decode the security header type and the protocol discriminator */ + DECODE_U8(pdu_buff + e_head_size, *(uint8_t *)(emm_header), e_head_size); + /* Decode the message type */ + DECODE_U8(pdu_buff + e_head_size, emm_header->message_type, e_head_size); + + /* Check the protocol discriminator */ + if (emm_header->protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE) { + + pdu_buff += e_head_size; + pdu_len -= e_head_size; + + if (emm_header->message_type == ATTACH_REQUEST) { + decode_attach_request(&e_msg->attach_request, pdu_buff, pdu_len); + + if (e_msg->attach_request.oldgutiorimsi.imsi.typeofidentity == MOBILE_IDENTITY_IMSI) { + /* the following is very dirty, we cast from + * ImsiEpsMobileIdentity_t to ImsiMobileIdentity_t*/ + ue_context_pP->ue_context.imsi = compute_imsi((ImsiMobileIdentity_t *)&(e_msg->attach_request.oldgutiorimsi.imsi)); + } else { + ue_context_pP->ue_context.imsi = e_msg->attach_request.oldgutiorimsi.guti.mtmsi; + } + } + pdu_buff -= e_head_size; + if (size > 1) { + pdu_buff -= size; + } + } + } + } + free(pdu_buff); + /* Fill UE identities with available information */ { S1AP_NAS_FIRST_REQ (message_p).ue_identity.presenceMask = UE_IDENTITIES_NONE; From d8a6715395e2094a0c1761e180daf3351cb1e963 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 7 Feb 2018 18:57:06 +0100 Subject: [PATCH 140/195] store IMSI information + provide FlexRAN API to query UE's IMSI --- openair2/ENB_APP/flexran_agent_ran_api.c | 11 +++++++++++ openair2/ENB_APP/flexran_agent_ran_api.h | 3 +++ openair2/RRC/LITE/defs.h | 3 ++- openair2/RRC/LITE/rrc_eNB_S1AP.c | 21 +++++++++++++++++++-- 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 97a77a634c..b81d030c43 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -889,6 +889,17 @@ int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id) } } +uint64_t flexran_get_ue_imsi(mid_t mod_id, mid_t ue_id) +{ + if (!rrc_is_present(mod_id)) return -1; + + rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); + + if (!ue_context_p) return -1; + return ue_context_p->ue_context.imsi; +} + long flexran_get_lcg(mid_t mod_id, mid_t ue_id, mid_t lc_id) { if (!mac_is_present(mod_id)) return 0; diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index b3515c9c6c..aafb82077e 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -301,6 +301,9 @@ long flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id); /* Get number of UE transmission antennas */ int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id); +/* Get the IMSI of UE */ +uint64_t flexran_get_ue_imsi(mid_t mod_id, mid_t ue_id); + /* Get logical channel group of a channel with id lc_id */ long flexran_get_lcg(mid_t mod_id, mid_t ue_id, mid_t lc_id); diff --git a/openair2/RRC/LITE/defs.h b/openair2/RRC/LITE/defs.h index 9a9840273b..763a55c559 100644 --- a/openair2/RRC/LITE/defs.h +++ b/openair2/RRC/LITE/defs.h @@ -394,7 +394,8 @@ typedef struct eNB_RRC_UE_s { MeasResults_t* measResults; UE_EUTRA_Capability_t* UE_Capability; - + uint64_t imsi; + #if defined(ENABLE_SECURITY) /* KeNB as derived from KASME received from EPC */ uint8_t kenb[32]; diff --git a/openair2/RRC/LITE/rrc_eNB_S1AP.c b/openair2/RRC/LITE/rrc_eNB_S1AP.c index a2c570c009..87bbe8857d 100644 --- a/openair2/RRC/LITE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LITE/rrc_eNB_S1AP.c @@ -86,8 +86,25 @@ static const uint16_t S1AP_INTEGRITY_EIA2_MASK = 0x4000; #endif #endif - - +uint64_t compute_imsi(ImsiMobileIdentity_t *id) { + uint64_t imsi; + imsi = id->digit15; + imsi += id->digit14 * 10; // pow(10, 1) + imsi += id->digit13 * 100; // pow(10, 2) + imsi += id->digit12 * 1000; // pow(10, 3) + imsi += id->digit11 * 10000; // pow(10, 4) + imsi += id->digit10 * 100000; // pow(10, 5) + imsi += id->digit9 * 1000000; // pow(10, 6) + imsi += id->digit8 * 10000000; // pow(10, 7) + imsi += id->digit7 * 100000000; // pow(10, 8) + imsi += id->digit6 * 1000000000; // pow(10, 9) + imsi += id->digit5 * 10000000000; // pow(10, 10) + imsi += id->digit4 * 100000000000; // pow(10, 11) + imsi += id->digit3 * 1000000000000; // pow(10, 12) + imsi += id->digit2 * 10000000000000; // pow(10, 13) + imsi += id->digit1 * 100000000000000; // pow(10, 14) + return imsi; +} # if defined(ENABLE_ITTI) //------------------------------------------------------------------------------ From df43d19c356f0b9cb1642b9c409b3c3e97011d77 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 13 Feb 2018 15:02:38 +0100 Subject: [PATCH 141/195] refactoring of the original IMSI extraction code - move IMSI extraction code to function, remove FLEXRAN comp. directive - refactor the code, esp. don't do deep if-nesting - remove m-tmsi part (does not give correct value) - copy complete IMSI info to UE context, decode in RAN API --- openair2/ENB_APP/flexran_agent_ran_api.c | 19 +- openair2/RRC/LITE/defs.h | 2 +- openair2/RRC/LITE/rrc_eNB_S1AP.c | 306 ++++++----------------- 3 files changed, 101 insertions(+), 226 deletions(-) diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index b81d030c43..3c98d63fcf 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -891,13 +891,30 @@ int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id) uint64_t flexran_get_ue_imsi(mid_t mod_id, mid_t ue_id) { + uint64_t imsi; if (!rrc_is_present(mod_id)) return -1; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return -1; - return ue_context_p->ue_context.imsi; + + imsi = ue_context_p->ue_context.imsi.digit15; + imsi += ue_context_p->ue_context.imsi.digit14 * 10; // pow(10, 1) + imsi += ue_context_p->ue_context.imsi.digit13 * 100; // pow(10, 2) + imsi += ue_context_p->ue_context.imsi.digit12 * 1000; // pow(10, 3) + imsi += ue_context_p->ue_context.imsi.digit11 * 10000; // pow(10, 4) + imsi += ue_context_p->ue_context.imsi.digit10 * 100000; // pow(10, 5) + imsi += ue_context_p->ue_context.imsi.digit9 * 1000000; // pow(10, 6) + imsi += ue_context_p->ue_context.imsi.digit8 * 10000000; // pow(10, 7) + imsi += ue_context_p->ue_context.imsi.digit7 * 100000000; // pow(10, 8) + imsi += ue_context_p->ue_context.imsi.digit6 * 1000000000; // pow(10, 9) + imsi += ue_context_p->ue_context.imsi.digit5 * 10000000000; // pow(10, 10) + imsi += ue_context_p->ue_context.imsi.digit4 * 100000000000; // pow(10, 11) + imsi += ue_context_p->ue_context.imsi.digit3 * 1000000000000; // pow(10, 12) + imsi += ue_context_p->ue_context.imsi.digit2 * 10000000000000; // pow(10, 13) + imsi += ue_context_p->ue_context.imsi.digit1 * 100000000000000; // pow(10, 14) + return imsi; } long flexran_get_lcg(mid_t mod_id, mid_t ue_id, mid_t lc_id) diff --git a/openair2/RRC/LITE/defs.h b/openair2/RRC/LITE/defs.h index 763a55c559..01475715f4 100644 --- a/openair2/RRC/LITE/defs.h +++ b/openair2/RRC/LITE/defs.h @@ -394,7 +394,7 @@ typedef struct eNB_RRC_UE_s { MeasResults_t* measResults; UE_EUTRA_Capability_t* UE_Capability; - uint64_t imsi; + ImsiMobileIdentity_t imsi; #if defined(ENABLE_SECURITY) /* KeNB as derived from KASME received from EPC */ diff --git a/openair2/RRC/LITE/rrc_eNB_S1AP.c b/openair2/RRC/LITE/rrc_eNB_S1AP.c index 87bbe8857d..80ae1c9ba5 100644 --- a/openair2/RRC/LITE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LITE/rrc_eNB_S1AP.c @@ -86,24 +86,79 @@ static const uint16_t S1AP_INTEGRITY_EIA2_MASK = 0x4000; #endif #endif -uint64_t compute_imsi(ImsiMobileIdentity_t *id) { - uint64_t imsi; - imsi = id->digit15; - imsi += id->digit14 * 10; // pow(10, 1) - imsi += id->digit13 * 100; // pow(10, 2) - imsi += id->digit12 * 1000; // pow(10, 3) - imsi += id->digit11 * 10000; // pow(10, 4) - imsi += id->digit10 * 100000; // pow(10, 5) - imsi += id->digit9 * 1000000; // pow(10, 6) - imsi += id->digit8 * 10000000; // pow(10, 7) - imsi += id->digit7 * 100000000; // pow(10, 8) - imsi += id->digit6 * 1000000000; // pow(10, 9) - imsi += id->digit5 * 10000000000; // pow(10, 10) - imsi += id->digit4 * 100000000000; // pow(10, 11) - imsi += id->digit3 * 1000000000000; // pow(10, 12) - imsi += id->digit2 * 10000000000000; // pow(10, 13) - imsi += id->digit1 * 100000000000000; // pow(10, 14) - return imsi; +void extract_imsi(uint8_t *pdu_buf, uint32_t pdu_len, rrc_eNB_ue_context_t *ue_context_pP) +{ + /* Process NAS message locally to get the IMSI */ + nas_message_t nas_msg; + memset(&nas_msg, 0, sizeof(nas_message_t)); + + int size = 0; + + nas_message_security_header_t *header = &nas_msg.header; + /* Decode the first octet of the header (security header type or EPS + * bearer identity, and protocol discriminator) */ + DECODE_U8((char *) pdu_buf, *(uint8_t*) (header), size); + + /* Decode NAS message only if decodable*/ + if (!(header->security_header_type <= SECURITY_HEADER_TYPE_INTEGRITY_PROTECTED + && header->protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE + && pdu_len > NAS_MESSAGE_SECURITY_HEADER_SIZE)) + return; + + if (header->security_header_type != SECURITY_HEADER_TYPE_NOT_PROTECTED) { + /* Decode the message authentication code */ + DECODE_U32((char *) pdu_buf+size, header->message_authentication_code, size); + /* Decode the sequence number */ + DECODE_U8((char *) pdu_buf+size, header->sequence_number, size); + } + + /* Note: the value of the pointer (i.e. the address) is given by value, so we + * can modify it as we want. The callee retains the original address! */ + pdu_buf += size; + pdu_len -= size; + + /* Decode plain NAS message */ + EMM_msg *e_msg = &nas_msg.plain.emm; + emm_msg_header_t *emm_header = &e_msg->header; + + /* First decode the EMM message header */ + int e_head_size = 0; + + /* Check that buffer contains more than only the header */ + if (pdu_len <= sizeof(emm_msg_header_t)) + return; + + /* Decode the security header type and the protocol discriminator */ + DECODE_U8(pdu_buf + e_head_size, *(uint8_t *)(emm_header), e_head_size); + /* Decode the message type */ + DECODE_U8(pdu_buf + e_head_size, emm_header->message_type, e_head_size); + + /* Check that this is the right message */ + if (emm_header->protocol_discriminator != EPS_MOBILITY_MANAGEMENT_MESSAGE) + return; + + pdu_buf += e_head_size; + pdu_len -= e_head_size; + + if (emm_header->message_type == IDENTITY_RESPONSE) { + decode_identity_response(&e_msg->identity_response, pdu_buf, pdu_len); + + if (e_msg->identity_response.mobileidentity.imsi.typeofidentity == MOBILE_IDENTITY_IMSI) { + memcpy(&ue_context_pP->ue_context.imsi, + &e_msg->identity_response.mobileidentity.imsi, + sizeof(ImsiMobileIdentity_t)); + } + } else if (emm_header->message_type == ATTACH_REQUEST) { + decode_attach_request(&e_msg->attach_request, pdu_buf, pdu_len); + + if (e_msg->attach_request.oldgutiorimsi.imsi.typeofidentity == MOBILE_IDENTITY_IMSI) { + /* the following is very dirty, we cast (implicitly) from + * ImsiEpsMobileIdentity_t to ImsiMobileIdentity_t*/ + memcpy(&ue_context_pP->ue_context.imsi, + &e_msg->attach_request.oldgutiorimsi.imsi, + sizeof(ImsiMobileIdentity_t)); + } + } } # if defined(ENABLE_ITTI) @@ -563,73 +618,9 @@ rrc_eNB_send_S1AP_UPLINK_NAS( S1AP_UPLINK_NAS (msg_p).nas_pdu.length = pdu_length; S1AP_UPLINK_NAS (msg_p).nas_pdu.buffer = pdu_buffer; - /* Process NAS message locally to get the IMSI */ - nas_message_t nas_msg; - memset(&nas_msg, 0, sizeof(nas_message_t)); - int size = 0; - uint32_t pdu_len = S1AP_UPLINK_NAS (msg_p).nas_pdu.length; - uint8_t *pdu_buff = malloc(pdu_len * sizeof(uint8_t)); - memcpy(pdu_buff, S1AP_UPLINK_NAS (msg_p).nas_pdu.buffer, pdu_len * sizeof(uint8_t)); - - nas_message_security_header_t *header = &nas_msg.header; - /* Decode the first octet of the header (security header type or EPS - * bearer identity, and protocol discriminator) */ - DECODE_U8((char *) pdu_buff, *(uint8_t*) (header), size); - - /* Decode NAS message */ - if (header->security_header_type <= SECURITY_HEADER_TYPE_INTEGRITY_PROTECTED - && header->protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE - && pdu_len > NAS_MESSAGE_SECURITY_HEADER_SIZE) { - - if (header->security_header_type != SECURITY_HEADER_TYPE_NOT_PROTECTED) { - /* Decode the message authentication code */ - DECODE_U32((char *) pdu_buff+size, header->message_authentication_code, size); - /* Decode the sequence number */ - DECODE_U8((char *) pdu_buff+size, header->sequence_number, size); - } - - if (size > 1) { - pdu_buff += size; - pdu_len -= size; - } - - /* Decode plain NAS message */ - EMM_msg *e_msg = &nas_msg.plain.emm; - emm_msg_header_t *emm_header = &e_msg->header; - - /* First decode the EMM message header */ - int e_head_size = 0; - - /* Check the buffer length */ - if (pdu_len > sizeof(emm_msg_header_t)) { - - /* Decode the security header type and the protocol discriminator */ - DECODE_U8(pdu_buff + e_head_size, *(uint8_t *)(emm_header), e_head_size); - /* Decode the message type */ - DECODE_U8(pdu_buff + e_head_size, emm_header->message_type, e_head_size); - - /* Check the protocol discriminator */ - if (emm_header->protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE) { - - pdu_buff += e_head_size; - pdu_len -= e_head_size; - - if (emm_header->message_type == IDENTITY_RESPONSE) { - decode_identity_response(&e_msg->identity_response, pdu_buff, pdu_len); - - if (e_msg->identity_response.mobileidentity.imsi.typeofidentity == MOBILE_IDENTITY_IMSI) { - ue_context_pP->ue_context.imsi = compute_imsi(&(e_msg->identity_response.mobileidentity.imsi)); - } - } - - pdu_buff -= e_head_size; - if (size > 1) { - pdu_buff -= size; - } - } - } - } - free(pdu_buff); + extract_imsi(S1AP_UPLINK_NAS (msg_p).nas_pdu.buffer, + S1AP_UPLINK_NAS (msg_p).nas_pdu.length, + ue_context_pP); itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p); } @@ -655,74 +646,9 @@ rrc_eNB_send_S1AP_UPLINK_NAS( if (ulInformationTransferR8->dedicatedInfoType.present == ULInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS) { - /* Process NAS message locally to get the IMSI */ - nas_message_t nas_msg; - memset(&nas_msg, 0, sizeof(nas_message_t)); - - int size = 0; - uint32_t pdu_len = ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.size; - uint8_t *pdu_buff = malloc(pdu_len * sizeof(uint8_t)); - memcpy(pdu_buff, ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.buf, pdu_len * sizeof(uint8_t)); - - nas_message_security_header_t *header = &nas_msg.header; - /* Decode the first octet of the header (security header type or EPS - * bearer identity, and protocol discriminator) */ - DECODE_U8((char *) pdu_buff, *(uint8_t*) (header), size); - - /* Decode NAS message */ - if (header->security_header_type <= SECURITY_HEADER_TYPE_INTEGRITY_PROTECTED && - header->protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE && - pdu_len > NAS_MESSAGE_SECURITY_HEADER_SIZE) { - - if (header->security_header_type != SECURITY_HEADER_TYPE_NOT_PROTECTED) { - /* Decode the message authentication code */ - DECODE_U32((char *) pdu_buff+size, header->message_authentication_code, size); - /* Decode the sequence number */ - DECODE_U8((char *) pdu_buff+size, header->sequence_number, size); - } - - if (size > 1) { - pdu_buff += size; - pdu_len -= size; - } - - /* Decode plain NAS message */ - EMM_msg *e_msg = &nas_msg.plain.emm; - emm_msg_header_t *emm_header = &e_msg->header; - - /* First decode the EMM message header */ - int e_head_size = 0; - - /* Check the buffer length */ - if (pdu_len > sizeof(emm_msg_header_t)) { - - /* Decode the security header type and the protocol discriminator */ - DECODE_U8(pdu_buff + e_head_size, *(uint8_t *)(emm_header), e_head_size); - /* Decode the message type */ - DECODE_U8(pdu_buff + e_head_size, emm_header->message_type, e_head_size); - - /* Check the protocol discriminator */ - if (emm_header->protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE) { - - pdu_buff += e_head_size; - pdu_len -= e_head_size; - - if (emm_header->message_type == IDENTITY_RESPONSE) { - decode_identity_response(&e_msg->identity_response, pdu_buff, pdu_len); - - if (e_msg->identity_response.mobileidentity.imsi.typeofidentity == MOBILE_IDENTITY_IMSI) { - ue_context_pP->ue_context.imsi = compute_imsi(&(e_msg->identity_response.mobileidentity.imsi)); - } - } - - pdu_buff -= e_head_size; - if (size > 1) { - pdu_buff -= size; - } - } - } - } - free(pdu_buff); + extract_imsi(ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.buf, + ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.size, + ue_context_pP); s1ap_eNB_new_data_request (mod_id, ue_index, ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.buf, @@ -829,77 +755,9 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ( rrcConnectionSetupComplete->dedicatedInfoNAS.buf; S1AP_NAS_FIRST_REQ (message_p).nas_pdu.length = rrcConnectionSetupComplete->dedicatedInfoNAS.size; - // Process NAS message locally to get the IMSI - nas_message_t nas_msg; - memset(&nas_msg, 0, sizeof(nas_message_t)); - - int size = 0; - uint32_t pdu_len = S1AP_NAS_FIRST_REQ (message_p).nas_pdu.length; - uint8_t *pdu_buff = malloc(pdu_len * sizeof(uint8_t)); - memcpy(pdu_buff, S1AP_NAS_FIRST_REQ (message_p).nas_pdu.buffer, pdu_len * sizeof(uint8_t)); - - nas_message_security_header_t *header = &nas_msg.header; - /* Decode the first octet of the header (security header type or EPS - * bearer identity, and protocol discriminator) */ - DECODE_U8((char *) pdu_buff, *(uint8_t*) (header), size); - - /* Decode NAS message */ - if (header->security_header_type <= SECURITY_HEADER_TYPE_INTEGRITY_PROTECTED && - header->protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE && - pdu_len > NAS_MESSAGE_SECURITY_HEADER_SIZE) { - - if (header->security_header_type != SECURITY_HEADER_TYPE_NOT_PROTECTED) { - /* Decode the message authentication code */ - DECODE_U32((char *) pdu_buff+size, header->message_authentication_code, size); - /* Decode the sequence number */ - DECODE_U8((char *) pdu_buff+size, header->sequence_number, size); - } - - if (size > 1) { - pdu_buff += size; - pdu_len -= size; - } - - /* Decode plain NAS message */ - EMM_msg *e_msg = &nas_msg.plain.emm; - emm_msg_header_t *emm_header = &e_msg->header; - - /* First decode the EMM message header */ - int e_head_size = 0; - - /* Check the buffer length */ - if (pdu_len > sizeof(emm_msg_header_t)) { - - /* Decode the security header type and the protocol discriminator */ - DECODE_U8(pdu_buff + e_head_size, *(uint8_t *)(emm_header), e_head_size); - /* Decode the message type */ - DECODE_U8(pdu_buff + e_head_size, emm_header->message_type, e_head_size); - - /* Check the protocol discriminator */ - if (emm_header->protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE) { - - pdu_buff += e_head_size; - pdu_len -= e_head_size; - - if (emm_header->message_type == ATTACH_REQUEST) { - decode_attach_request(&e_msg->attach_request, pdu_buff, pdu_len); - - if (e_msg->attach_request.oldgutiorimsi.imsi.typeofidentity == MOBILE_IDENTITY_IMSI) { - /* the following is very dirty, we cast from - * ImsiEpsMobileIdentity_t to ImsiMobileIdentity_t*/ - ue_context_pP->ue_context.imsi = compute_imsi((ImsiMobileIdentity_t *)&(e_msg->attach_request.oldgutiorimsi.imsi)); - } else { - ue_context_pP->ue_context.imsi = e_msg->attach_request.oldgutiorimsi.guti.mtmsi; - } - } - pdu_buff -= e_head_size; - if (size > 1) { - pdu_buff -= size; - } - } - } - } - free(pdu_buff); + extract_imsi(S1AP_NAS_FIRST_REQ (message_p).nas_pdu.buffer, + S1AP_NAS_FIRST_REQ (message_p).nas_pdu.length, + ue_context_pP); /* Fill UE identities with available information */ { From d741b951fa22426d668169872c4dcddb5d682b7a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 13 Feb 2018 18:51:36 +0100 Subject: [PATCH 142/195] define&send IMSI in Protobuf --- openair2/ENB_APP/MESSAGES/V2/config_messages.proto | 1 + openair2/ENB_APP/flexran_agent_common.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto index 995865f1ab..f734686f01 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto @@ -81,6 +81,7 @@ message flex_ue_config { optional uint32 pcell_carrier_index = 27; // Index of primary cell repeated flex_scell_config scell_config = 28; // Secondary cells configuration optional uint32 scell_deactivation_timer = 29;// Deactivation timer for secondary cell + optional uint64 imsi = 30; } message flex_lc_ue_config { diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index c663d5cad1..6d32aeedbb 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -589,6 +589,8 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl ue_config[i]->rnti = flexran_get_ue_crnti(mod_id,i); ue_config[i]->has_rnti = 1; + ue_config[i]->imsi = flexran_get_ue_imsi(mod_id, i); + ue_config[i]->has_imsi = 1; //TODO: Set the DRX configuration (optional) //Not supported for now, so we do not set it From 50f7053159558287031df145b3a7c153be22a2fb Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 14 Feb 2018 16:44:29 +0100 Subject: [PATCH 143/195] return 0 for unsigned in RAN API --- openair2/ENB_APP/flexran_agent_ran_api.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 3c98d63fcf..c1743bf744 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -892,12 +892,12 @@ int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id) uint64_t flexran_get_ue_imsi(mid_t mod_id, mid_t ue_id) { uint64_t imsi; - if (!rrc_is_present(mod_id)) return -1; + if (!rrc_is_present(mod_id)) return 0; rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; + if (!ue_context_p) return 0; imsi = ue_context_p->ue_context.imsi.digit15; imsi += ue_context_p->ue_context.imsi.digit14 * 10; // pow(10, 1) From 9dcd1f9b89198057d6c8309bb0fd3135108d77ec Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 14 Feb 2018 14:25:18 +0100 Subject: [PATCH 144/195] bugfix: max_allowed_rbs has been renamed max_rbs_allowed_slice --- targets/SIMU/USER/event_handler.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/targets/SIMU/USER/event_handler.c b/targets/SIMU/USER/event_handler.c index 7c9f6b73fc..dbdce23df2 100644 --- a/targets/SIMU/USER/event_handler.c +++ b/targets/SIMU/USER/event_handler.c @@ -524,9 +524,9 @@ void update_mac(Event_t event) for(j=0; jmac_config[i].max_allowed_rbs[j]= mac_config[i].max_allowed_rbs[j]; - UE_list->UE_sched_ctrl[i].max_allowed_rbs[j] = oai_emulation->mac_config[i].max_allowed_rbs[j]; + UE_list->UE_sched_ctrl[i].max_rbs_allowed_slice[j][0] = oai_emulation->mac_config[i].max_allowed_rbs[j]; LOG_I(EMU,"max_allowed_rbs UE %d LCID %d:",i,j); - LOG_I(EMU,"%" PRIu16 "\n",UE_list->UE_sched_ctrl[i].max_allowed_rbs[j]); + LOG_I(EMU,"%" PRIu16 "\n",UE_list->UE_sched_ctrl[i].max_rbs_allowed_slice[j][0]); } } @@ -646,9 +646,9 @@ void update_mac(Event_t event) if(mac_config->max_allowed_rbs !=NULL) { oai_emulation->mac_config[i].max_allowed_rbs[j]= mac_config[i].max_allowed_rbs[j]; - UE_list->UE_sched_ctrl[i].max_allowed_rbs[j] = oai_emulation->mac_config[i].max_allowed_rbs[j]; + UE_list->UE_sched_ctrl[i].max_rbs_allowed_slice[j][0] = oai_emulation->mac_config[i].max_allowed_rbs[j]; LOG_I(EMU,"max_allowed_rbs UE %d LCID %d:",i,j); - LOG_I(EMU,"%" PRIu16 "\n",UE_list->UE_sched_ctrl[i].max_allowed_rbs[j]); + LOG_I(EMU,"%" PRIu16 "\n",UE_list->UE_sched_ctrl[i].max_rbs_allowed_slice[j][0]); } @@ -951,18 +951,18 @@ void update_mac(Event_t event) if(&mac_config[i].max_allowed_rbs[j]!=NULL) { oai_emulation->mac_config[i].max_allowed_rbs[j]= mac_config[i].max_allowed_rbs[j]; - UE_list->UE_sched_ctrl[i].max_allowed_rbs[j] = oai_emulation->mac_config[i].max_allowed_rbs[j]; + UE_list->UE_sched_ctrl[i].max_rbs_allowed_slice[j][0] = oai_emulation->mac_config[i].max_allowed_rbs[j]; LOG_I(EMU,"max_allowed_rbs UE %d LCID %d:",i,j); - LOG_I(EMU,"%" PRIu16 "\n",UE_list->UE_sched_ctrl[i].max_allowed_rbs[j]); + LOG_I(EMU,"%" PRIu16 "\n",UE_list->UE_sched_ctrl[i].max_rbs_allowed_slice[j][0]); } } } } } else { oai_emulation->mac_config[event.ue].max_allowed_rbs[event.lcid]= mac_config[event.ue].max_allowed_rbs[event.lcid]; - UE_list->UE_sched_ctrl[event.ue].max_allowed_rbs[event.lcid] = oai_emulation->mac_config[event.ue].max_allowed_rbs[event.lcid]; + UE_list->UE_sched_ctrl[event.ue].max_rbs_allowed_slice[event.lcid][0] = oai_emulation->mac_config[event.ue].max_allowed_rbs[event.lcid]; LOG_I(EMU,"max_allowed_rbs UE %d LCID %d:",event.ue,event.lcid); - LOG_I(EMU,"%" PRIu16 "\n",UE_list->UE_sched_ctrl[event.ue].max_allowed_rbs[event.lcid]); + LOG_I(EMU,"%" PRIu16 "\n",UE_list->UE_sched_ctrl[event.ue].max_rbs_allowed_slice[event.lcid][0]); } } else if(!strcmp((char *) event.key, "max_mcs") && event.value!=NULL && validate_mac(event)) { From 7b1afbb0bfb2defebbf0e60b4331309513cfee43 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 14 Feb 2018 12:07:42 +0100 Subject: [PATCH 145/195] provide stop_L1L2()/restart_L1L2() in oaisim the functions are meant to restart the lte-softmodem (lower layers) and are not supported in oaisim. They are provided to make oaisim compile. --- targets/SIMU/USER/oaisim.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index 302b77b60f..9434b2dd83 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -988,6 +988,25 @@ l2l1_task (void *args_p) return NULL; } +#if defined(FLEXRAN_AGENT_SB_IF) +/* + * The following two functions are meant to restart *the lte-softmodem* and are + * here to make oaisim compile. A restart command from the controller will be + * ignored in oaisim. + */ +int stop_L1L2(int enb_id) +{ + LOG_W(FLEXRAN_AGENT, "stop_L1L2() not supported in oaisim\n"); + return 0; +} + +int restart_L1L2(int enb_id) +{ + LOG_W(FLEXRAN_AGENT, "restart_L1L2() not supported in oaisim\n"); + return 0; +} +#endif + #if T_TRACER int T_wait = 1; /* by default we wait for the tracer */ int T_port = 2021; /* default port to listen to to wait for the tracer */ From 7e3b1f5d0a765626b8f3ccc32ffea9f1bb386ae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Iardella?= Date: Tue, 13 Feb 2018 13:20:58 +0100 Subject: [PATCH 146/195] Niccolo: Add sorting policy --- openair2/COMMON/platform_types.h | 9 ++ openair2/LAYER2/MAC/defs.h | 4 + openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 15 +- openair2/LAYER2/MAC/pre_processor.c | 162 +++++++++++++--------- openair2/LAYER2/MAC/proto.h | 2 +- 5 files changed, 126 insertions(+), 66 deletions(-) diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index 1236b93366..0ab8d96701 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -100,6 +100,15 @@ typedef enum rb_type_e { RADIO_ACCESS_BEARER = 2 } rb_type_t; +typedef enum { + CR_ROUND = 0, + CR_SRB12 = 1, + CR_HOL = 2, + CR_LC = 3, + CR_CQI = 4, + CR_NUM = 5 +} sorting_criterion_t; + //----------------------------------------------------------------------------- // PHY TYPES //----------------------------------------------------------------------------- diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index de53479e6f..ef1d710138 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -963,6 +963,10 @@ typedef struct { int avail; int num_UEs; boolean_t active[NUMBER_OF_UE_MAX]; + + /// Sorting criteria for the UE list in the MAC preprocessor + uint16_t sorting_criteria[MAX_NUM_SLICES][CR_NUM]; + } UE_list_t; /*! \brief eNB common channels */ diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 7d0a93c2bf..48b19b0919 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -98,6 +98,10 @@ char *dl_scheduler_type[MAX_NUM_SLICES] = "schedule_ue_spec" }; +// The lists of criteria that enforce the sorting policies of the slices +uint32_t sorting_policy[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234}; +uint32_t sorting_policy_current[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234}; + // pointer to the slice specific scheduler slice_scheduler_dl slice_sched_dl[MAX_NUM_SLICES] = {0}; @@ -447,7 +451,7 @@ schedule_dlsch(module_id_t module_idP, //------------------------------------------------------------------------------{ { - int i=0; + int i = 0; total_slice_percentage=0; avg_slice_percentage=1.0/n_active_slices; @@ -470,7 +474,7 @@ schedule_dlsch(module_id_t module_idP, // Load any updated functions if (update_dl_scheduler[i] > 0 ) { slice_sched_dl[i] = dlsym(NULL, dl_scheduler_type[i]); - update_dl_scheduler[i] = 0; + update_dl_scheduler[i] = 0 ; update_dl_scheduler_current[i] = 0; LOG_N(MAC,"update dl scheduler slice %d\n", i); } @@ -538,6 +542,13 @@ schedule_dlsch(module_id_t module_idP, } } + // Check for new sorting policy + if (sorting_policy_current[i] != sorting_policy[i]) { + LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n", + module_idP, i, frameP, subframeP, sorting_policy_current[i], sorting_policy[i]); + sorting_policy_current[i] = sorting_policy[i]; + } + // Run each enabled slice-specific schedulers one by one slice_sched_dl[i](module_idP, i, frameP, subframeP, mbsfn_flag/*, dl_info*/); } diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 8f7a6bddff..759bc591dd 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -52,13 +52,13 @@ #include "rlc.h" - #define DEBUG_eNB_SCHEDULER 1 #define DEBUG_HEADER_PARSING 1 //#define DEBUG_PACKET_TRACE 1 extern float slice_percentage[MAX_NUM_SLICES]; extern float slice_percentage_uplink[MAX_NUM_SLICES]; +extern uint32_t sorting_policy[MAX_NUM_SLICES]; extern int slice_maxmcs[MAX_NUM_SLICES]; extern int slice_maxmcs_uplink[MAX_NUM_SLICES]; @@ -352,6 +352,7 @@ struct sort_ue_dl_params { int Mod_idP; int frameP; int subframeP; + int slice_id; }; static int ue_dl_compare(const void *_a, const void *_b, void *_params) @@ -359,62 +360,73 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params) struct sort_ue_dl_params *params = _params; UE_list_t *UE_list = &RC.mac[params->Mod_idP]->UE_list; + int i; + int slice_id = params->slice_id; int UE_id1 = *(const int *) _a; int UE_id2 = *(const int *) _b; int rnti1 = UE_RNTI(params->Mod_idP, UE_id1); int pCC_id1 = UE_PCCID(params->Mod_idP, UE_id1); - int round1 = - maxround(params->Mod_idP, rnti1, params->frameP, params->subframeP, - 1); + int round1 = maxround(params->Mod_idP, rnti1, params->frameP, params->subframeP, 1); int rnti2 = UE_RNTI(params->Mod_idP, UE_id2); int pCC_id2 = UE_PCCID(params->Mod_idP, UE_id2); - int round2 = - maxround(params->Mod_idP, rnti2, params->frameP, params->subframeP, - 1); + int round2 = maxround(params->Mod_idP, rnti2, params->frameP, params->subframeP, 1); int cqi1 = maxcqi(params->Mod_idP, UE_id1); int cqi2 = maxcqi(params->Mod_idP, UE_id2); - if (round1 > round2) - return -1; - if (round1 < round2) - return 1; + for (i = 0; i < CR_NUM; ++i) { + switch (UE_list->sorting_criteria[slice_id][i]) { - if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] + - UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2] > - UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] + - UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2]) - return -1; - if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] + - UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2] < - UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] + - UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2]) - return 1; + case CR_ROUND : + if (round1 > round2) + return -1; + if (round1 < round2) + return 1; + break; - if (UE_list-> - UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max > - UE_list-> - UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max) - return -1; - if (UE_list-> - UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max < - UE_list-> - UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max) - return 1; + case CR_SRB12 : + if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] + + UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2] > + UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] + + UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2]) + return -1; + if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] + + UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2] < + UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] + + UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2]) + return 1; + break; - if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total > - UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total) - return -1; - if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total < - UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total) - return 1; + case CR_HOL : + if (UE_list-> UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max > + UE_list-> UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max) + return -1; + if (UE_list-> UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max < + UE_list-> UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max) + return 1; + break; - if (cqi1 > cqi2) - return -1; - if (cqi1 < cqi2) - return 1; + case CR_LC : + if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total > + UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total) + return -1; + if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total < + UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total) + return 1; + break; + + case CR_CQI : + if (cqi1 > cqi2) + return -1; + if (cqi1 < cqi2) + return 1; + + default : + break; + } + } return 0; #if 0 @@ -449,40 +461,64 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params) #endif } +void decode_sorting_policy(module_id_t Mod_idP, slice_id_t slice_id) { + int i; + + UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; + uint32_t policy = sorting_policy[slice_id]; + uint32_t mask = 0x0000000F; + uint16_t criterion; + + for(i = 0; i < CR_NUM; ++i) { + criterion = (uint16_t)(policy >> 4*(CR_NUM - 1 - i) & mask); + if (criterion >= CR_NUM) { + LOG_W(MAC, "Invalid criterion in slice %d policy, revert to default policy \n", slice_id); + sorting_policy[slice_id] = 0x1234; + break; + } + UE_list->sorting_criteria[slice_id][i] = criterion; + } +} + + // This fuction sorts the UE in order their dlsch buffer and CQI -void sort_UEs(module_id_t Mod_idP, int frameP, sub_frame_t subframeP) +void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t subframeP) { int i; int list[NUMBER_OF_UE_MAX]; int list_size = 0; int rnti; - struct sort_ue_dl_params params = { Mod_idP, frameP, subframeP }; + struct sort_ue_dl_params params = { Mod_idP, frameP, subframeP, slice_id }; UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { + for (i = 0; i < NUMBER_OF_UE_MAX; i++) { - if (UE_list->active[i] == FALSE) - continue; - if ((rnti = UE_RNTI(Mod_idP, i)) == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; + if (UE_list->active[i] == FALSE) + continue; + if ((rnti = UE_RNTI(Mod_idP, i)) == NOT_A_RNTI) + continue; + if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) + continue; + if (!ue_slice_membership(i, slice_id)) + continue; - list[list_size] = i; - list_size++; - } + list[list_size] = i; + list_size++; + } - qsort_r(list, list_size, sizeof(int), ue_dl_compare, ¶ms); + decode_sorting_policy(Mod_idP, slice_id); - if (list_size) { - for (i = 0; i < list_size - 1; i++) - UE_list->next[list[i]] = list[i + 1]; - UE_list->next[list[list_size - 1]] = -1; - UE_list->head = list[0]; - } else { - UE_list->head = -1; - } + qsort_r(list, list_size, sizeof(int), ue_dl_compare, ¶ms); + + if (list_size) { + for (i = 0; i < list_size - 1; i++) + UE_list->next[list[i]] = list[i + 1]; + UE_list->next[list[list_size - 1]] = -1; + UE_list->head = list[0]; + } else { + UE_list->head = -1; + } #if 0 @@ -651,7 +687,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, // Sorts the user on the basis of dlsch logical channel buffer and CQI - sort_UEs(Mod_id, frameP, subframeP); + sort_UEs(Mod_id, slice_id, frameP, subframeP); // loop over all active UEs diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/proto.h index be09385ac9..348b080d1e 100644 --- a/openair2/LAYER2/MAC/proto.h +++ b/openair2/LAYER2/MAC/proto.h @@ -675,7 +675,7 @@ void assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP, void adjust_bsr_info(int buffer_occupancy, uint16_t TBS, UE_TEMPLATE * UE_template); int phy_stats_exist(module_id_t Mod_id, int rnti); -void sort_UEs (module_id_t Mod_idP, int frameP, sub_frame_t subframeP); +void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t subframeP); /*! \fn UE_L2_state_t ue_scheduler(const module_id_t module_idP,const frame_t frameP, const sub_frame_t subframe, const lte_subframe_t direction,const uint8_t eNB_index) \brief UE scheduler where all the ue background tasks are done. This function performs the following: 1) Trigger PDCP every 5ms 2) Call RRC for link status return to PHY3) Perform SR/BSR procedures for scheduling feedback 4) Perform PHR procedures. From a4f260f5a4d1e345b34485b23731d9d2d67339bb Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 14 Feb 2018 17:50:41 +0100 Subject: [PATCH 147/195] fix: no FLEXRAN_AGENT_SB_IF compilation directive --- targets/SIMU/USER/oaisim.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index 9434b2dd83..3a282e1d44 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -988,7 +988,6 @@ l2l1_task (void *args_p) return NULL; } -#if defined(FLEXRAN_AGENT_SB_IF) /* * The following two functions are meant to restart *the lte-softmodem* and are * here to make oaisim compile. A restart command from the controller will be @@ -1005,7 +1004,6 @@ int restart_L1L2(int enb_id) LOG_W(FLEXRAN_AGENT, "restart_L1L2() not supported in oaisim\n"); return 0; } -#endif #if T_TRACER int T_wait = 1; /* by default we wait for the tracer */ From 91332d3906e577df9032a766af4fd4600e2fc2fe Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 14 Feb 2018 17:49:50 +0100 Subject: [PATCH 148/195] fixup previous bad merge (UE disconnection did not work properly anymore) Doing airplane mode off to connect a cots UE followed by airplane mode on to disconnect it gives very bad results (bad disconnection with lots of UL failures followed by lots of logs in the eNB). It used to work properly after the work done by Xu Bo. It turns out that in 2018.w04 things were still working okay. But in 2018.w05 no. So I ran: git diff 2018.w04 2018.w05 And I checked all the modifications that I thought were relevant (everything related to the UE, oaisim, if4 and fapi has not been checked). This commits takes back the version of 2018.w04. The modifications in openair2/RRC/LITE/rrc_eNB.c are necessary, I think. The other modifications may not be necessary or even wrong. To be checked at some point. --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 2 +- openair1/SCHED/fapi_l1.c | 9 +++-- openair1/SCHED/phy_procedures_lte_eNb.c | 6 ++- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 1 + openair2/RRC/LITE/rrc_eNB.c | 50 +++++++++++++++++++++++-- 5 files changed, 58 insertions(+), 10 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index c6c1322504..086f77e14c 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -6556,7 +6556,7 @@ uint8_t pdcch_alloc2ul_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n) else ul_subframe = ((n+4)%10); - // AssertFatal(frame_parms->frame_type == FDD || subframe_select(frame_parms,ul_subframe) == SF_UL,"illegal ul_subframe %d (n %d)\n",ul_subframe,n); + AssertFatal(frame_parms->frame_type == FDD || subframe_select(frame_parms,ul_subframe) == SF_UL,"illegal ul_subframe %d (n %d)\n",ul_subframe,n); LOG_D(PHY, "subframe %d: PUSCH subframe = %d\n", n, ul_subframe); return ul_subframe; diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c index b9024bdfbf..9c855d0ac8 100644 --- a/openair1/SCHED/fapi_l1.c +++ b/openair1/SCHED/fapi_l1.c @@ -629,7 +629,8 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) fp = &eNB->frame_parms; proc = &eNB->proc.proc_rxtx[0]; - if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)==SF_UL)) return; + /* TODO: check that following line is correct - in the meantime it is disabled */ + //if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)==SF_UL)) return; ul_subframe = pdcch_alloc2ul_subframe(fp,subframe); ul_frame = pdcch_alloc2ul_frame(fp,frame,subframe); @@ -664,8 +665,10 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) int do_oai =0; int dont_send =0; - if ((ul_subframe<10)&& - (subframe_select(fp,ul_subframe)==SF_UL)) { // This means that there is an ul_subframe that can be configured here + /* TODO: check the following test - in the meantime it is put back as it was before */ + //if ((ul_subframe<10)&& + // (subframe_select(fp,ul_subframe)==SF_UL)) { // This means that there is an ul_subframe that can be configured here + if (ul_subframe<10) { // This means that there is an ul_subframe that can be configured here LOG_D(PHY,"NFAPI: Clearing dci allocations for potential UL subframe %d\n",ul_subframe); harq_pid = subframe2harq_pid(fp,ul_frame,ul_subframe); diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 2ae79b53b6..9aaf6752fb 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -452,8 +452,10 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, } /* save old HARQ information needed for PHICH generation */ - if ((ul_subframe < 10)&& - (subframe_select(fp,ul_subframe)==SF_UL)) { // This means that there is a potential UL subframe that will be scheduled here + /* TODO: check the following test - in the meantime it is put back as it was before */ + //if ((ul_subframe < 10)&& + // (subframe_select(fp,ul_subframe)==SF_UL)) { // This means that there is a potential UL subframe that will be scheduled here + if (ul_subframe < 10) { // This means that there is a potential UL subframe that will be scheduled here for (i=0; iulsch[i]) { diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index bb264a8906..d5d5da8741 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -634,6 +634,7 @@ pdcp_data_ind( rb_id, sdu_buffer_sizeP - pdcp_header_len - pdcp_tailer_len, (uint8_t*)&sdu_buffer_pP->data[pdcp_header_len]); + free_mem_block(sdu_buffer_pP, __func__); // free_mem_block(new_sdu, __func__); diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index 946da42920..25c04b8cfb 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -6682,26 +6682,58 @@ rrc_rx_tx( RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) { if ((ctxt_pP->frame == 0) && (ctxt_pP->subframe==0)) { if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) { - LOG_I(RRC,"UE rnti %x:S-TMSI %x failure timer %d/20000\n", + LOG_I(RRC,"UE rnti %x:S-TMSI %x failure timer %d/8\n", ue_context_p->ue_context.rnti, ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, ue_context_p->ue_context.ul_failure_timer); } else { - LOG_I(RRC,"UE rnti %x failure timer %d/20000\n", + LOG_I(RRC,"UE rnti %x failure timer %d/8\n", ue_context_p->ue_context.rnti, ue_context_p->ue_context.ul_failure_timer); } } if (ue_context_p->ue_context.ul_failure_timer>0) { ue_context_p->ue_context.ul_failure_timer++; - if (ue_context_p->ue_context.ul_failure_timer >= 20000) { + if (ue_context_p->ue_context.ul_failure_timer >= 8) { // remove UE after 20 seconds after MAC has indicated UL failure LOG_I(RRC,"Removing UE %x instance\n",ue_context_p->ue_context.rnti); ue_to_be_removed = ue_context_p; break; } } + if (ue_context_p->ue_context.ue_release_timer_s1>0) { + ue_context_p->ue_context.ue_release_timer_s1++; + if (ue_context_p->ue_context.ue_release_timer_s1 >= + ue_context_p->ue_context.ue_release_timer_thres_s1) { + LOG_I(RRC,"Removing UE %x instance Because of UE_CONTEXT_RELEASE_COMMAND not received after %d ms from sending request\n", + ue_context_p->ue_context.rnti, ue_context_p->ue_context.ue_release_timer_thres_s1); + ue_to_be_removed = ue_context_p; + break; + } + } + + if (ue_context_p->ue_context.ue_release_timer_rrc>0) { + ue_context_p->ue_context.ue_release_timer_rrc++; + if (ue_context_p->ue_context.ue_release_timer_rrc >= + ue_context_p->ue_context.ue_release_timer_thres_rrc) { + LOG_I(RRC,"Removing UE %x instance After UE_CONTEXT_RELEASE_Complete\n", ue_context_p->ue_context.rnti); + ue_to_be_removed = ue_context_p; + break; + } + } + + if (ue_context_p->ue_context.ue_reestablishment_timer>0) { + ue_context_p->ue_context.ue_reestablishment_timer++; + if (ue_context_p->ue_context.ue_reestablishment_timer >= + ue_context_p->ue_context.ue_reestablishment_timer_thres) { + LOG_I(RRC,"UE %d reestablishment_timer max\n",ue_context_p->ue_context.rnti); + ue_context_p->ue_context.ul_failure_timer = 20000; + ue_to_be_removed = ue_context_p; + ue_context_p->ue_context.ue_reestablishment_timer = 0; + break; + } + } if (ue_context_p->ue_context.ue_release_timer>0) { ue_context_p->ue_context.ue_release_timer++; if (ue_context_p->ue_context.ue_release_timer >= @@ -6712,8 +6744,18 @@ rrc_rx_tx( } } } - if (ue_to_be_removed) + if (ue_to_be_removed) { + if(ue_to_be_removed->ue_context.ul_failure_timer >= 8) { + ue_to_be_removed->ue_context.ue_release_timer_s1 = 1; + ue_to_be_removed->ue_context.ue_release_timer_thres_s1 = 100; + ue_to_be_removed->ue_context.ue_release_timer = 0; + ue_to_be_removed->ue_context.ue_reestablishment_timer = 0; + } rrc_eNB_free_UE(ctxt_pP->module_id,ue_to_be_removed); + if(ue_to_be_removed->ue_context.ul_failure_timer >= 8){ + ue_to_be_removed->ue_context.ul_failure_timer = 0; + } + } #ifdef RRC_LOCALIZATION From e4a5470d4754b674d833b7af85f74dda0c742bcc Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 15 Feb 2018 11:34:53 +0100 Subject: [PATCH 149/195] integration fix: noS1 compilation The following compilation did not work anymore: ./build_oai --eNB -c -w USRP --noS1 Neither did: ./build_oai --UE --noS1 --- openair2/RRC/LITE/defs.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openair2/RRC/LITE/defs.h b/openair2/RRC/LITE/defs.h index 01475715f4..08ac30f836 100644 --- a/openair2/RRC/LITE/defs.h +++ b/openair2/RRC/LITE/defs.h @@ -65,6 +65,9 @@ #include "UE-EUTRA-Capability.h" #include "MeasResults.h" +/* for ImsiMobileIdentity_t */ +#include "MobileIdentity.h" + /* correct Rel(8|10)/Rel14 differences * the code is in favor of Rel14, those defines do the translation */ From b2ac257ef5b728c52912ba7156ad2ff01f1c346f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 15 Feb 2018 13:40:34 +0100 Subject: [PATCH 150/195] integration fix: compilation failed The following compilation failed before this commit: ./build_oai --eNB -w USRP -c --T-tracer --- openair2/ENB_APP/enb_app.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index a1d3da9ccc..481bfaa521 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -204,7 +204,7 @@ void *eNB_app_task(void *args_p) switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: - LOG_W(TASK_ENB_APP, " *** Exiting ENB_APP thread\n"); + LOG_W(ENB_APP, " *** Exiting ENB_APP thread\n"); itti_exit_task (); break; From c0be5a129cae522ea29c29039403ca775128b587 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 15 Feb 2018 16:50:30 +0100 Subject: [PATCH 151/195] integration fix: set default max MCS for UL back to 20 Doing an iperf UDP uplink test, we could reach only 6Mb/s with very good radio conditions instead of around 8Mb/s. It turns out the MCS was limited to 16. With this commit, we are back to a bit more than 8Mb/s as it used to be. (This is with a 5MHz bandwidth.) --- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index a8d686dac9..ac87498560 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -95,8 +95,8 @@ float total_slice_percentage_uplink = 0; float total_slice_percentage_current_uplink = 0; // MAX MCS for each slice for past and current time -int slice_maxmcs_uplink[MAX_NUM_SLICES] = {16, 16, 16, 16}; -int slice_maxmcs_current_uplink[MAX_NUM_SLICES] = {16,16,16,16}; +int slice_maxmcs_uplink[MAX_NUM_SLICES] = {20, 20, 20, 20}; +int slice_maxmcs_current_uplink[MAX_NUM_SLICES] = {20,20,20,20}; /*resource blocks allowed*/ uint16_t nb_rbs_allowed_slice_uplink[MAX_NUM_CCs][MAX_NUM_SLICES]; From 2d6dd02b95321cef2349dbc17dc8fb3461f6c4c6 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 16 Feb 2018 11:08:39 +0100 Subject: [PATCH 152/195] bugfix: fix bad conflict resolutions from previous commits Some more fixes for some bad conflict resolutions. I ran: git diff 2018.w04 2018.w05 And saw some problems with config_sib2. There was also something strange in openair2/LAYER2/openair2_proc.c in the function dump_eNB_l2_stats. Maybe the fix is wrong for this one. To be checked. --- openair2/LAYER2/MAC/config.c | 242 ++++++++++++++++++++------------ openair2/LAYER2/openair2_proc.c | 4 +- 2 files changed, 156 insertions(+), 90 deletions(-) diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index 55585acd23..f45cc45af1 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -437,59 +437,31 @@ config_sib2(int Mod_idP, cfg->num_tlv++; - nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; - - cfg->subframe_config.pb.value = radioResourceConfigCommonP->pdsch_ConfigCommon.p_b; - cfg->rf_config.reference_signal_power.value = radioResourceConfigCommonP->pdsch_ConfigCommon.referenceSignalPower; - cfg->nfapi_config.max_transmit_power.value = cfg->rf_config.reference_signal_power.value + - power_off_dB[cfg->rf_config.dl_channel_bandwidth.value]; - - cfg->prach_config.configuration_index.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.prach_ConfigIndex; - cfg->prach_config.root_sequence_index.value = radioResourceConfigCommonP->prach_Config.rootSequenceIndex; - cfg->prach_config.zero_correlation_zone_configuration.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig; - cfg->prach_config.high_speed_flag.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.highSpeedFlag; - cfg->prach_config.frequency_offset.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.prach_FreqOffset; - - cfg->pusch_config.hopping_mode.value = radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode; - cfg->pusch_config.number_of_subbands.value = radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.n_SB; - cfg->pusch_config.hopping_offset.value = radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset; - - cfg->pucch_config.delta_pucch_shift.value = radioResourceConfigCommonP->pucch_ConfigCommon.deltaPUCCH_Shift; - cfg->pucch_config.n_cqi_rb.value = radioResourceConfigCommonP->pucch_ConfigCommon.nRB_CQI; - cfg->pucch_config.n_an_cs.value = radioResourceConfigCommonP->pucch_ConfigCommon.nCS_AN; - cfg->pucch_config.n1_pucch_an.value = radioResourceConfigCommonP->pucch_ConfigCommon.n1PUCCH_AN; - - if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled == true) - cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 1; - else if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled == true) - cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 2; - else // No hopping - cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 0; - - cfg->uplink_reference_signal_config.group_assignment.value = radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH; - cfg->uplink_reference_signal_config.cyclic_shift_1_for_drms.value = radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift; - - // how to enable/disable SRS? - if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.present == SoundingRS_UL_ConfigCommon_PR_setup) { - cfg->srs_config.bandwidth_configuration.value = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig; - cfg->srs_config.srs_subframe_configuration.value = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig; - cfg->srs_config.srs_acknack_srs_simultaneous_transmission.value = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; - - if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts) - cfg->srs_config.max_up_pts.value = 1; - else - cfg->srs_config.max_up_pts.value = 0; + if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts) { + cfg->srs_config.max_up_pts.value = 1; } + else { + cfg->srs_config.max_up_pts.value = 0; + } + cfg->srs_config.max_up_pts.tl.tag = NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG; + cfg->num_tlv++; } + #ifdef Rel14 if (RC.mac[Mod_idP]->common_channels[CC_idP].mib->message.schedulingInfoSIB1_BR_r13 > 0) { - AssertFatal(radioResourceConfigCommon_BRP != NULL, - "radioResource rou is missing\n"); - AssertFatal(radioResourceConfigCommon_BRP->ext4 != NULL, - "ext4 is missing\n"); + AssertFatal(radioResourceConfigCommon_BRP != NULL, "radioResource rou is missing\n"); + AssertFatal(radioResourceConfigCommon_BRP->ext4 != NULL, "ext4 is missing\n"); cfg->emtc_config.prach_catm_root_sequence_index.value = radioResourceConfigCommon_BRP->prach_Config.rootSequenceIndex; + cfg->emtc_config.prach_catm_root_sequence_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_ROOT_SEQUENCE_INDEX_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.value = radioResourceConfigCommon_BRP->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig; + cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_catm_high_speed_flag.value = radioResourceConfigCommon_BRP->prach_Config.prach_ConfigInfo.highSpeedFlag; + cfg->emtc_config.prach_catm_high_speed_flag.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_HIGH_SPEED_FLAG; + cfg->num_tlv++; struct PRACH_ConfigSIB_v1310 *ext4_prach = radioResourceConfigCommon_BRP->ext4->prach_ConfigCommon_v1310; @@ -497,94 +469,186 @@ config_sib2(int Mod_idP, PRACH_ParametersCE_r13_t *p; cfg->emtc_config.prach_ce_level_0_enable.value = 0; + cfg->emtc_config.prach_ce_level_0_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_1_enable.value = 0; + cfg->emtc_config.prach_ce_level_1_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_2_enable.value = 0; + cfg->emtc_config.prach_ce_level_2_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_3_enable.value = 0; + cfg->emtc_config.prach_ce_level_3_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG; + cfg->num_tlv++; + switch (prach_ParametersListCE_r13->list.count) { case 4: p = prach_ParametersListCE_r13->list.array[3]; cfg->emtc_config.prach_ce_level_3_enable.value = 1; + cfg->emtc_config.prach_ce_level_3_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_3_configuration_index.value = p->prach_ConfigIndex_r13; + cfg->emtc_config.prach_ce_level_3_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_CONFIGURATION_INDEX_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_3_frequency_offset.value = p->prach_FreqOffset_r13; + cfg->emtc_config.prach_ce_level_3_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_FREQUENCY_OFFSET_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13; - if (p->prach_StartingSubframe_r13) + cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + cfg->num_tlv++; + + if (p->prach_StartingSubframe_r13) { cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.value = *p->prach_StartingSubframe_r13; + cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_STARTING_SUBFRAME_PERIODICITY_TAG; + cfg->num_tlv++; + } + cfg->emtc_config.prach_ce_level_3_hopping_enable.value = p->prach_HoppingConfig_r13; + cfg->emtc_config.prach_ce_level_3_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_3_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value - 6; + cfg->emtc_config.prach_ce_level_3_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_OFFSET_TAG; + cfg->num_tlv++; + case 3: p = prach_ParametersListCE_r13->list.array[2]; cfg->emtc_config.prach_ce_level_2_enable.value = 1; + cfg->emtc_config.prach_ce_level_2_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_2_configuration_index.value = p->prach_ConfigIndex_r13; + cfg->emtc_config.prach_ce_level_2_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_CONFIGURATION_INDEX_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_2_frequency_offset.value = p->prach_FreqOffset_r13; + cfg->emtc_config.prach_ce_level_2_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_FREQUENCY_OFFSET_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13; - if (p->prach_StartingSubframe_r13) + cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + cfg->num_tlv++; + + if (p->prach_StartingSubframe_r13) { cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.value = *p->prach_StartingSubframe_r13; + cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_STARTING_SUBFRAME_PERIODICITY_TAG; + cfg->num_tlv++; + } + cfg->emtc_config.prach_ce_level_2_hopping_enable.value = p->prach_HoppingConfig_r13; + cfg->emtc_config.prach_ce_level_2_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_2_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value - 6; + cfg->emtc_config.prach_ce_level_2_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_OFFSET_TAG; + cfg->num_tlv++; + case 2: p = prach_ParametersListCE_r13->list.array[1]; cfg->emtc_config.prach_ce_level_1_enable.value = 1; + cfg->emtc_config.prach_ce_level_1_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_1_configuration_index.value = p->prach_ConfigIndex_r13; + cfg->emtc_config.prach_ce_level_1_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_CONFIGURATION_INDEX_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_1_frequency_offset.value = p->prach_FreqOffset_r13; + cfg->emtc_config.prach_ce_level_1_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_FREQUENCY_OFFSET_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13; - if (p->prach_StartingSubframe_r13) + cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + cfg->num_tlv++; + + if (p->prach_StartingSubframe_r13) { cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.value = *p->prach_StartingSubframe_r13; + cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_STARTING_SUBFRAME_PERIODICITY_TAG; + cfg->num_tlv++; + } + cfg->emtc_config.prach_ce_level_1_hopping_enable.value = p->prach_HoppingConfig_r13; + cfg->emtc_config.prach_ce_level_1_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_1_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value - 6; + cfg->emtc_config.prach_ce_level_1_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_OFFSET_TAG; + cfg->num_tlv++; + case 1: p = prach_ParametersListCE_r13->list.array[0]; cfg->emtc_config.prach_ce_level_0_enable.value = 1; + cfg->emtc_config.prach_ce_level_0_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_0_configuration_index.value = p->prach_ConfigIndex_r13; + cfg->emtc_config.prach_ce_level_0_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_CONFIGURATION_INDEX_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_0_frequency_offset.value = p->prach_FreqOffset_r13; + cfg->emtc_config.prach_ce_level_0_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_FREQUENCY_OFFSET_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13; - if (p->prach_StartingSubframe_r13) + cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + cfg->num_tlv++; + + if (p->prach_StartingSubframe_r13) { cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.value = *p->prach_StartingSubframe_r13; + cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_STARTING_SUBFRAME_PERIODICITY_TAG; + cfg->num_tlv++; + } + cfg->emtc_config.prach_ce_level_0_hopping_enable.value = p->prach_HoppingConfig_r13; + cfg->emtc_config.prach_ce_level_0_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_0_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value - 6; + cfg->emtc_config.prach_ce_level_0_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_OFFSET_TAG; + cfg->num_tlv++; } struct FreqHoppingParameters_r13 *ext4_freqHoppingParameters = radioResourceConfigCommonP->ext4->freqHoppingParameters_r13; - if ((ext4_freqHoppingParameters)&& - (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13)) - { - switch (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->present) { - case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_NOTHING: /* No components present */ - break; - case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_FDD_r13: - cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = - ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13-> - choice.interval_FDD_r13; - break; - case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_TDD_r13: - cfg->emtc_config. - pucch_interval_ulhoppingconfigcommonmodea.value = - ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13-> - choice.interval_TDD_r13; - break; - } - } if ((ext4_freqHoppingParameters) && - (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13)) - { - switch - (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13-> - present) { - case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_NOTHING: /* No components present */ - break; - case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_FDD_r13: - cfg->emtc_config. - pucch_interval_ulhoppingconfigcommonmodeb.value = - ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13-> - choice.interval_FDD_r13; - break; - case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_TDD_r13: - cfg->emtc_config. - pucch_interval_ulhoppingconfigcommonmodeb.value = - ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13-> - choice.interval_TDD_r13; - break; - } + (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13)){ + switch(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->present) { + case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_NOTHING: /* No components present */ + break; + case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_FDD_r13: + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_FDD_r13; + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG; + cfg->num_tlv++; + break; + case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_TDD_r13: + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_TDD_r13; + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG; + cfg->num_tlv++; + break; } + } + if ((ext4_freqHoppingParameters) && + (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13)){ + switch(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->present) { + case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_NOTHING: /* No components present */ + break; + case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_FDD_r13: + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_FDD_r13; + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG; + cfg->num_tlv++; + break; + case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_TDD_r13: + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_TDD_r13; + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG; + cfg->num_tlv++; + break; + } + } } #endif diff --git a/openair2/LAYER2/openair2_proc.c b/openair2/LAYER2/openair2_proc.c index f66d1142ab..7cb6ce0d2c 100644 --- a/openair2/LAYER2/openair2_proc.c +++ b/openair2/LAYER2/openair2_proc.c @@ -228,7 +228,9 @@ int dump_eNB_l2_stats(char *buffer, int length) PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, eNB_id, ENB_FLAG_YES, - UE_list->eNB_UE_stats[0][UE_id].crnti,//UE_PCCID(eNB_id,UE_id)][UE_id].crnti, + /* the following is suspicious, let's put back what was there before */ + /*UE_list->eNB_UE_stats[0][UE_id].crnti,//UE_PCCID(eNB_id,UE_id)][UE_id].crnti, */ + UE_list->eNB_UE_stats[UE_PCCID(eNB_id,UE_id)][UE_id].crnti, eNB->frame, eNB->subframe, eNB_id); From f7c58f27cada6dd0ad1ca478b566f1fac9962e2e Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Sat, 17 Feb 2018 11:08:56 -0800 Subject: [PATCH 153/195] dlsim and ulsim functional. dlsim 1-2 antenna ports, TM1/2. ulsim 1-2 antenna ports. --- openair1/PHY/CODING/lte_rate_matching.c | 4 + openair1/PHY/INIT/lte_init.c | 4 +- openair1/PHY/INIT/lte_init_ru.c | 11 +- openair1/PHY/INIT/lte_param_init.c | 10 +- .../PHY/LTE_ESTIMATION/freq_equalization.c | 2 +- .../lte_ul_channel_estimation.c | 5 +- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 14 +- openair1/PHY/LTE_TRANSPORT/drs_modulation.c | 6 +- openair1/PHY/LTE_TRANSPORT/proto.h | 2 +- .../PHY/LTE_TRANSPORT/ulsch_demodulation.c | 76 ++-- openair1/PHY/MODULATION/slot_fep_ul.c | 5 +- openair1/PHY/MODULATION/ul_7_5_kHz.c | 2 +- openair1/SCHED/fapi_l1.c | 13 +- openair1/SCHED/phy_procedures_lte_eNb.c | 12 +- openair1/SCHED/phy_procedures_lte_ue.c | 26 +- openair1/SCHED/ru_procedures.c | 3 +- openair1/SIMULATION/LTE_PHY/dlsim.c | 4 +- openair1/SIMULATION/LTE_PHY/ulsim.c | 382 ++++++++++++------ 18 files changed, 386 insertions(+), 195 deletions(-) diff --git a/openair1/PHY/CODING/lte_rate_matching.c b/openair1/PHY/CODING/lte_rate_matching.c index 13870e3303..f96e5dbb17 100644 --- a/openair1/PHY/CODING/lte_rate_matching.c +++ b/openair1/PHY/CODING/lte_rate_matching.c @@ -749,6 +749,10 @@ int lte_rate_matching_turbo_rx(uint32_t RTC, for (; (ind0 && soft_input2[k]<0) || + (w[ind]<0 && soft_input2[k]>0)) + printf("ind %d: w %d => soft_in %d\n",ind,w[ind],soft_input2[k]);*/ w[ind] += soft_input2[k++]; #ifdef RM_DEBUG printf("RM_RX k%d Ind: %d (%d)\n",k-1,ind,w[ind]); diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index 377a235da6..687395ab9b 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -883,10 +883,10 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, for (i=0; i<2; i++) { // RK 2 times because of output format of FFT! // FIXME We should get rid of this - pusch_vars[UE_id]->rxdataF_ext[i] = (int32_t*)malloc16_clear( 2*sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti ); + pusch_vars[UE_id]->rxdataF_ext[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti ); pusch_vars[UE_id]->rxdataF_ext2[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti ); pusch_vars[UE_id]->drs_ch_estimates[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti ); - pusch_vars[UE_id]->drs_ch_estimates_time[i] = (int32_t*)malloc16_clear( 2*2*sizeof(int32_t)*fp->ofdm_symbol_size ); + pusch_vars[UE_id]->drs_ch_estimates_time[i] = (int32_t*)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size ); pusch_vars[UE_id]->rxdataF_comp[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti ); pusch_vars[UE_id]->ul_ch_mag[i] = (int32_t*)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 ); pusch_vars[UE_id]->ul_ch_magb[i] = (int32_t*)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 ); diff --git a/openair1/PHY/INIT/lte_init_ru.c b/openair1/PHY/INIT/lte_init_ru.c index 2d139e0afa..e8bffef6d8 100644 --- a/openair1/PHY/INIT/lte_init_ru.c +++ b/openair1/PHY/INIT/lte_init_ru.c @@ -32,6 +32,11 @@ #include "assertions.h" #include +#undef LOG_I +#define LOG_I(A,B,C...) printf(B,C) +#undef LOG_D +#define LOG_D(A,B,C...) printf(B,C) + int phy_init_RU(RU_t *ru) { LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; @@ -60,7 +65,7 @@ int phy_init_RU(RU_t *ru) { } } // IF5 or local RF else { - LOG_I(PHY,"No rxdata/txdata for RU\n"); + // LOG_I(PHY,"No rxdata/txdata for RU\n"); ru->common.txdata = (int32_t**)NULL; ru->common.rxdata = (int32_t**)NULL; @@ -91,8 +96,8 @@ int phy_init_RU(RU_t *ru) { } /* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) */ - AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]), - "nb_antennas_rx too large"); + // AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]), + // "nb_antennas_rx too large"); ru->prach_rxsigF = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*)); for (j=0;j<4;j++) ru->prach_rxsigF_br[j] = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*)); diff --git a/openair1/PHY/INIT/lte_param_init.c b/openair1/PHY/INIT/lte_param_init.c index 90b7bcee31..d9b7b12249 100644 --- a/openair1/PHY/INIT/lte_param_init.c +++ b/openair1/PHY/INIT/lte_param_init.c @@ -109,10 +109,11 @@ void lte_param_init(PHY_VARS_eNB **eNBp, UE->is_secondary_ue = 0; UE->frame_parms = *frame_parms; + UE->frame_parms.nb_antennas_rx=1; // eNB->frame_parms = *frame_parms; ru->frame_parms = *frame_parms; ru->nb_tx = N_tx_phy; - ru->nb_rx = 1; + ru->nb_rx = N_rx; ru->if_south = LOCAL_RF; eNB->configured=1; @@ -155,6 +156,13 @@ void lte_param_init(PHY_VARS_eNB **eNBp, /* the UE code is multi-thread "aware", we need to setup this array */ for (i = 0; i < 10; i++) UE->current_thread_id[i] = i % 2; + if (eNB->frame_parms.frame_type == TDD) { + if (eNB->frame_parms.N_RB_DL == 100) ru->N_TA_offset = 624; + else if (eNB->frame_parms.N_RB_DL == 50) ru->N_TA_offset = 624/2; + else if (eNB->frame_parms.N_RB_DL == 25) ru->N_TA_offset = 624/4; + } + else ru->N_TA_offset=0; + printf("Done lte_param_init\n"); diff --git a/openair1/PHY/LTE_ESTIMATION/freq_equalization.c b/openair1/PHY/LTE_ESTIMATION/freq_equalization.c index 74a844da8a..2c318d85e4 100644 --- a/openair1/PHY/LTE_ESTIMATION/freq_equalization.c +++ b/openair1/PHY/LTE_ESTIMATION/freq_equalization.c @@ -306,7 +306,7 @@ void freq_equalization(LTE_DL_FRAME_PARMS *frame_parms, AssertFatal(symbolsymbols_per_tti,"symbol %d >= %d\n", symbol,frame_parms->symbols_per_tti); - AssertFatal(Msc_RSN_RB_UL*12,"Msc_RS %d >= %d\n", + AssertFatal(Msc_RS<=frame_parms->N_RB_UL*12,"Msc_RS %d >= %d\n", Msc_RS,frame_parms->N_RB_UL*12); for (re=0; re<(Msc_RS>>2); re++) { diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c index 18069f9759..9eb34a8905 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c @@ -34,6 +34,9 @@ static int16_t ru_90c[2*128] = {32767, 0,32766, -402,32758, -804,32746, -1206,32 #define SCALE 0x3FFF +//#undef LOG_D +//#define LOG_D(A,B,C...) printf(B,C) + int32_t lte_ul_channel_estimation(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, uint8_t UE_id, @@ -100,7 +103,7 @@ int32_t temp_in_ifft_0[2048*2] __attribute__((aligned(32))); return(-1); } - // LOG_I(PHY,"subframe %d, Ns %d, l %d, Msc_RS = %d, Msc_RS_idx = %d, u %d, v %d, cyclic_shift %d\n",subframe,Ns,l,Msc_RS, Msc_RS_idx,u,v,cyclic_shift); + LOG_D(PHY,"subframe %d, Ns %d, l %d, Msc_RS = %d, Msc_RS_idx = %d, u %d, v %d, cyclic_shift %d\n",subframe,Ns,l,Msc_RS, Msc_RS_idx,u,v,cyclic_shift); #ifdef DEBUG_CH if (Ns==0) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 4adcc130dd..fcdda36265 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -44,10 +44,11 @@ #include "LAYER2/MAC/extern.h" #include "LAYER2/MAC/defs.h" -//#undef LOG_D -//#define LOG_D(A,B,C...) printf(B,C) -//#undef LOG_I -//#define LOG_I(A,B,C...) printf(B,C) +/*#undef LOG_D +#define LOG_D(A,B,C...) printf(B,C) +#undef LOG_I +#define LOG_I(A,B,C...) printf(B,C) +*/ //#define DEBUG_DCI @@ -2665,11 +2666,12 @@ void fill_ulsch(PHY_VARS_eNB *eNB,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame else if(ulsch->harq_processes[harq_pid]->n_DMRS == 7) ulsch->harq_processes[harq_pid]->n_DMRS2 = 9; - LOG_D(PHY,"[eNB %d][PUSCH %d] Frame %d, Subframe %d Programming PUSCH with n_DMRS2 %d (cshift %d) ulsch:ndi:%d ulsch_pdu:ndi:%d new_ulsch:%d status:%d\n", + LOG_D(PHY,"[eNB %d][PUSCH %d] Frame %d, Subframe %d Programming PUSCH with n_DMRS2 %d (cshift %d) ulsch:ndi:%d ulsch_pdu:ndi:%d new_ulsch:%d status:%d ulsch_pdu:rvidx:%d\n", eNB->Mod_id,harq_pid,frame,subframe, ulsch->harq_processes[harq_pid]->n_DMRS2, ulsch->harq_processes[harq_pid]->n_DMRS, - ulsch->harq_processes[harq_pid]->ndi, ulsch_pdu->ulsch_pdu_rel8.new_data_indication, new_ulsch, ulsch->harq_processes[harq_pid]->status); + ulsch->harq_processes[harq_pid]->ndi, ulsch_pdu->ulsch_pdu_rel8.new_data_indication, new_ulsch, ulsch->harq_processes[harq_pid]->status, + ulsch_pdu->ulsch_pdu_rel8.redundancy_version); ulsch->harq_processes[harq_pid]->rvidx = ulsch_pdu->ulsch_pdu_rel8.redundancy_version; ulsch->harq_processes[harq_pid]->Qm = ulsch_pdu->ulsch_pdu_rel8.modulation_type; diff --git a/openair1/PHY/LTE_TRANSPORT/drs_modulation.c b/openair1/PHY/LTE_TRANSPORT/drs_modulation.c index a432cde4e4..101954ca3d 100644 --- a/openair1/PHY/LTE_TRANSPORT/drs_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/drs_modulation.c @@ -94,8 +94,10 @@ int generate_drs_pusch(PHY_VARS_UE *ue, lsymbols_per_tti; l += (7 - frame_parms->Ncp),u=u1,v=v1,cyclic_shift=cyclic_shift1) { - drs_offset = 0; // printf("drs_modulation: Msc_RS = %d, Msc_RS_idx = %d\n",Msc_RS, Msc_RS_idx); - + drs_offset = 0; +#ifdef DEBUG_DRS + printf("drs_modulation: Msc_RS = %d, Msc_RS_idx = %d, u=%d,v=%d\n",Msc_RS, Msc_RS_idx,u,v); +#endif re_offset = frame_parms->first_carrier_offset; diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index c67820d0dd..c1b85a1561 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -1783,7 +1783,7 @@ int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *PHY_vars_eNB, uint8_t use_srs); -void dump_ulsch(PHY_VARS_eNB *phy_vars_eNB,int frame, int subframe, uint8_t UE_id); +void dump_ulsch(PHY_VARS_eNB *phy_vars_eNB,int frame, int subframe, uint8_t UE_id,int round); int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci); diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c index 93c1af8d91..ee038508d1 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c @@ -725,8 +725,8 @@ void ulsch_extract_rbs_single(int32_t **rxdataF, //uint8_t symbol = l+Ns*frame_parms->symbols_per_tti/2; uint8_t symbol = l+((7-frame_parms->Ncp)*(Ns&1)); ///symbol within sub-frame - AssertFatal((frame_parms->nb_antennas_rx>0) && (frame_parms->nb_antennas_rx<3), - "nb_antennas_rx not in (1-2)\n"); + AssertFatal((frame_parms->nb_antennas_rx>0) && (frame_parms->nb_antennas_rx<5), + "nb_antennas_rx not in (1-4)\n"); for (aarx=0; aarxnb_antennas_rx; aarx++) { @@ -1349,35 +1349,54 @@ void rx_ulsch_emul(PHY_VARS_eNB *eNB, } - void dump_ulsch(PHY_VARS_eNB *eNB,int frame,int subframe,uint8_t UE_id) { + void dump_ulsch(PHY_VARS_eNB *eNB,int frame,int subframe,uint8_t UE_id,int round) { uint32_t nsymb = (eNB->frame_parms.Ncp == 0) ? 14 : 12; uint8_t harq_pid; + char fname[100],vname[100]; harq_pid = subframe2harq_pid(&eNB->frame_parms,frame,subframe); - printf("Dumping ULSCH in subframe %d with harq_pid %d, for NB_rb %d, TBS %d, Qm %d, N_symb %d\n", - subframe,harq_pid,eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, + printf("Dumping ULSCH in subframe %d with harq_pid %d, round %d for NB_rb %d, TBS %d, Qm %d, N_symb %d\n", + subframe,harq_pid,round,eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS,eNB->ulsch[UE_id]->harq_processes[harq_pid]->Qm, eNB->ulsch[UE_id]->harq_processes[harq_pid]->Nsymb_pusch); - write_output("/tmp/ulsch_d.m","ulsch_dseq",&eNB->ulsch[UE_id]->harq_processes[harq_pid]->d[0][96], + sprintf(fname,"/tmp/ulsch_r%d_d",round); + sprintf(vname,"/tmp/ulsch_r%d_dseq",round); + write_output(fname,vname,&eNB->ulsch[UE_id]->harq_processes[harq_pid]->d[0][96], eNB->ulsch[UE_id]->harq_processes[harq_pid]->Kplus*3,1,0); - if (eNB->common_vars.rxdata) write_output("/tmp/rxsig0.m","rxs0", &eNB->common_vars.rxdata[0][0],eNB->frame_parms.samples_per_tti*10,1,1); - - if (eNB->frame_parms.nb_antennas_rx>1) - if (eNB->common_vars.rxdata) write_output("/tmp/rxsig1.m","rxs1", &eNB->common_vars.rxdata[1][0],eNB->frame_parms.samples_per_tti*10,1,1); + if (eNB->common_vars.rxdata) { + sprintf(fname,"/tmp/rxsig0_r%d.m",round); + sprintf(vname,"rxs0_r%d",round); + write_output(fname,vname, &eNB->common_vars.rxdata[0][0],eNB->frame_parms.samples_per_tti*10,1,1); + if (eNB->frame_parms.nb_antennas_rx>1) + if (eNB->common_vars.rxdata) { + sprintf(fname,"/tmp/rxsig1_r%d.m",round); + sprintf(vname,"rxs1_r%d",round); + write_output(fname,vname, &eNB->common_vars.rxdata[1][0],eNB->frame_parms.samples_per_tti*10,1,1); + } + } - write_output("/tmp/rxsigF0.m","rxsF0", &eNB->common_vars.rxdataF[0][0],eNB->frame_parms.ofdm_symbol_size*nsymb,1,1); + sprintf(fname,"/tmp/rxsigF0_r%d.m",round); + sprintf(vname,"rxsF0_r%d",round); + write_output(fname,vname, (void*)&eNB->common_vars.rxdataF[0][0],eNB->frame_parms.ofdm_symbol_size*nsymb,1,1); - if (eNB->frame_parms.nb_antennas_rx>1) - write_output("/tmp/rxsigF1.m","rxsF1", &eNB->common_vars.rxdataF[1][0],eNB->frame_parms.ofdm_symbol_size*nsymb,1,1); + if (eNB->frame_parms.nb_antennas_rx>1) { + sprintf(fname,"/tmp/rxsigF1_r%d.m",round); + sprintf(vname,"rxsF1_r%d",round); + write_output(vname,fname, &eNB->common_vars.rxdataF[1][0],eNB->frame_parms.ofdm_symbol_size*nsymb,1,1); + } - write_output("/tmp/rxsigF0_ext.m","rxsF0_ext", &eNB->pusch_vars[UE_id]->rxdataF_ext[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); - - if (eNB->frame_parms.nb_antennas_rx>1) - write_output("/tmp/rxsigF1_ext.m","rxsF1_ext", &eNB->pusch_vars[UE_id]->rxdataF_ext[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + sprintf(fname,"/tmp/rxsigF0_ext_r%d.m",round); + sprintf(vname,"rxsF0_ext_r%d",round); + write_output(fname,vname, &eNB->pusch_vars[UE_id]->rxdataF_ext[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + if (eNB->frame_parms.nb_antennas_rx>1) { + sprintf(fname,"/tmp/rxsigF1_ext_r%d.m",round); + sprintf(vname,"rxsF1_ext_r%d",round); + write_output(fname,vname,&eNB->pusch_vars[UE_id]->rxdataF_ext[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + } /* if (eNB->srs_vars[UE_id].srs_ch_estimates) write_output("/tmp/srs_est0.m","srsest0",eNB->srs_vars[UE_id].srs_ch_estimates[0],eNB->frame_parms.ofdm_symbol_size,1,1); @@ -1385,17 +1404,28 @@ void rx_ulsch_emul(PHY_VARS_eNB *eNB, if (eNB->srs_vars[UE_id].srs_ch_estimates) write_output("/tmp/srs_est1.m","srsest1",eNB->srs_vars[UE_id].srs_ch_estimates[1],eNB->frame_parms.ofdm_symbol_size,1,1); */ - write_output("/tmp/drs_est0.m","drsest0",eNB->pusch_vars[UE_id]->drs_ch_estimates[0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + sprintf(fname,"/tmp/drs_est0_r%d.m",round); + sprintf(vname,"drsest0_r%d",round); + write_output(fname,vname,eNB->pusch_vars[UE_id]->drs_ch_estimates[0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); - if (eNB->frame_parms.nb_antennas_rx>1) - write_output("/tmp/drs_est1.m","drsest1",eNB->pusch_vars[UE_id]->drs_ch_estimates[1],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + if (eNB->frame_parms.nb_antennas_rx>1) { + sprintf(fname,"/tmp/drs_est1_r%d.m",round); + sprintf(vname,"drsest1_r%d",round); + write_output(fname,vname,eNB->pusch_vars[UE_id]->drs_ch_estimates[1],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + } - write_output("/tmp/ulsch_rxF_comp0.m","ulsch0_rxF_comp0",&eNB->pusch_vars[UE_id]->rxdataF_comp[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + sprintf(fname,"/tmp/ulsch0_rxF_comp0_r%d.m",round); + sprintf(vname,"ulsch0_rxF_comp0_r%d",round); + write_output(fname,vname,&eNB->pusch_vars[UE_id]->rxdataF_comp[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); // write_output("ulsch_rxF_comp1.m","ulsch0_rxF_comp1",&eNB->pusch_vars[UE_id]->rxdataF_comp[0][1][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); - write_output("/tmp/ulsch_rxF_llr.m","ulsch_llr",eNB->pusch_vars[UE_id]->llr, + sprintf(fname,"/tmp/ulsch_rxF_llr_r%d.m",round); + sprintf(vname,"ulsch_llr_r%d",round); + write_output(fname,vname,eNB->pusch_vars[UE_id]->llr, eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12*eNB->ulsch[UE_id]->harq_processes[harq_pid]->Qm *eNB->ulsch[UE_id]->harq_processes[harq_pid]->Nsymb_pusch,1,0); - write_output("/tmp/ulsch_ch_mag.m","ulsch_ch_mag",&eNB->pusch_vars[UE_id]->ul_ch_mag[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + sprintf(fname,"/tmp/ulsch_ch_mag_r%d.m",round); + sprintf(vname,"ulsch_ch_mag_r%d",round); + write_output(fname,vname,&eNB->pusch_vars[UE_id]->ul_ch_mag[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); // write_output("ulsch_ch_mag1.m","ulsch_ch_mag1",&eNB->pusch_vars[UE_id]->ul_ch_mag[1][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); //#endif } diff --git a/openair1/PHY/MODULATION/slot_fep_ul.c b/openair1/PHY/MODULATION/slot_fep_ul.c index 1f2963017e..844d15a87e 100644 --- a/openair1/PHY/MODULATION/slot_fep_ul.c +++ b/openair1/PHY/MODULATION/slot_fep_ul.c @@ -24,6 +24,9 @@ #include "defs.h" //#define DEBUG_FEP +//#undef LOG_D +//#define LOG_D(A,B,C...) printf(B,C) + int slot_fep_ul(RU_t *ru, unsigned char l, unsigned char Ns, @@ -134,7 +137,7 @@ int slot_fep_ul(RU_t *ru, } #ifdef DEBUG_FEP - LOG_D(PHY,"slot_fep: done\n"); + // LOG_D(PHY,"slot_fep: done\n"); #endif return(0); } diff --git a/openair1/PHY/MODULATION/ul_7_5_kHz.c b/openair1/PHY/MODULATION/ul_7_5_kHz.c index 80efc70c40..d92dc1c8b3 100644 --- a/openair1/PHY/MODULATION/ul_7_5_kHz.c +++ b/openair1/PHY/MODULATION/ul_7_5_kHz.c @@ -188,7 +188,7 @@ void remove_7_5_kHz(RU_t *ru,uint8_t slot) } - slot_offset = (uint32_t)slot * frame_parms->samples_per_tti/2-ru->N_TA_offset; + slot_offset = ((uint32_t)slot * frame_parms->samples_per_tti/2)-ru->N_TA_offset; slot_offset2 = (uint32_t)(slot&1) * frame_parms->samples_per_tti/2; len = frame_parms->samples_per_tti/2; diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c index 6cb6e66aac..64de288d29 100644 --- a/openair1/SCHED/fapi_l1.c +++ b/openair1/SCHED/fapi_l1.c @@ -37,10 +37,11 @@ #include "nfapi_interface.h" #include "fapi_l1.h" -//#undef LOG_D -//#define LOG_D(A,B,C...) printf(B,C) -//#undef LOG_I -//#define LOG_I(A,B,C...) printf(B,C) +/*#undef LOG_D +#define LOG_D(A,B,C...) printf(B,C) +#undef LOG_I +#define LOG_I(A,B,C...) printf(B,C) +*/ int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req); int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req); @@ -538,11 +539,11 @@ void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, int8_t UE_id; // check if we have received a dci for this ue and ulsch descriptor is configured - + if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) { AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0, "No existing UE ULSCH for rnti %x\n",rel8->rnti); - //LOG_D(PHY,"Applying UL config for UE %d, rnti %x for frame %d, subframe %d\n", UE_id,rel8->rnti,frame,subframe); + LOG_D(PHY,"Applying UL config for UE %d, rnti %x for frame %d, subframe %d, modulation %d, rvidx %d\n", UE_id,rel8->rnti,frame,subframe,rel8->modulation_type,rel8->redundancy_version); fill_ulsch(eNB,&ul_config_pdu->ulsch_pdu,frame,subframe); diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index f771288f35..af845913ba 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -50,8 +50,10 @@ # include "intertask_interface.h" #endif -//#undef LOG_D -//#define LOG_D(A,B,C...) printf(B,C) +/* +#undef LOG_D +#define LOG_D(A,B,C...) printf(B,C) +*/ extern uint8_t nfapi_mode; int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); @@ -1210,7 +1212,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) start_meas(&eNB->ulsch_demodulation_stats); - rx_ulsch(eNB,proc, i); + rx_ulsch(eNB,proc, i); stop_meas(&eNB->ulsch_demodulation_stats); @@ -1263,12 +1265,12 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d Error receiving ULSCH, round %d/%d (ACK %d,%d)\n", eNB->Mod_id,harq_pid, frame,subframe, i, - ulsch_harq->round-1, + ulsch_harq->round, ulsch->Mlimit, ulsch_harq->o_ACK[0], ulsch_harq->o_ACK[1]); - if (ulsch_harq->round >= 3) { + if (ulsch_harq->round >= 4) { ulsch_harq->status = SCH_IDLE; ulsch_harq->handled = 0; ulsch->harq_mask &= ~(1 << harq_pid); diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 0085a31e28..d1097503ea 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -76,6 +76,7 @@ extern double cpuf; //#undef LOG_D //#define LOG_D(A,B,C...) printf(B,C) + void Msg1_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id); void Msg3_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id); @@ -84,7 +85,7 @@ extern uint32_t downlink_frequency[MAX_NUM_CCs][4]; #endif -#define DEBUG_UE_TRACE 1 +#define UE_DEBUG_TRACE 1 void dump_dlsch(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe,uint8_t harq_pid) { @@ -1269,7 +1270,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt } //#endif - if ((frame_tx%100) == 0) +// if ((frame_tx%100) == 0) LOG_D(PHY,"[UE %d] Frame %d, subframe %d: ulsch_start = %d (rxoff %d, HW TA %d, timing advance %d, TA_offset %d\n", ue->Mod_id,frame_tx,subframe_tx, ulsch_start, @@ -1291,16 +1292,25 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt nsymb, frame_parms->nb_prefix_samples, CYCLIC_PREFIX); - else + else { normal_prefix_mod(&ue->common_vars.txdataF[aa][subframe_tx*nsymb*frame_parms->ofdm_symbol_size], #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) - dummy_tx_buffer, + dummy_tx_buffer, #else - &ue->common_vars.txdata[aa][ulsch_start], + &ue->common_vars.txdata[aa][ulsch_start], #endif - nsymb, - &ue->frame_parms); - + nsymb>>1, + &ue->frame_parms); + + normal_prefix_mod(&ue->common_vars.txdataF[aa][((subframe_tx*nsymb)+(nsymb>>1))*frame_parms->ofdm_symbol_size], +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) + dummy_tx_buffer+(frame_parms->samples_per_tti>>1), +#else + &ue->common_vars.txdata[aa][ulsch_start+(frame_parms->samples_per_tti>>1)], +#endif + nsymb>>1, + &ue->frame_parms); + } #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) apply_7_5_kHz(ue,dummy_tx_buffer,0); diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c index dcab55d66f..0aad195d43 100644 --- a/openair1/SCHED/ru_procedures.c +++ b/openair1/SCHED/ru_procedures.c @@ -536,9 +536,10 @@ void fep_full(RU_t *ru) { start_meas(&ru->ofdm_demod_stats); if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 ); - + remove_7_5_kHz(ru,proc->subframe_rx<<1); remove_7_5_kHz(ru,1+(proc->subframe_rx<<1)); + for (l=0; lsymbols_per_tti/2; l++) { slot_fep_ul(ru, l, diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 128fca79e1..57fa787142 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -1409,8 +1409,8 @@ int main(int argc, char **argv) if (input_fd==NULL) { DL_req.dl_config_request_body.number_pdcch_ofdm_symbols = num_pdcch_symbols; - DL_req.sfn_sf = (proc_eNB->frame_tx*10)+subframe; - TX_req.sfn_sf = (proc_eNB->frame_tx*10)+subframe; + DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; // UE specific DCI fill_DCI(eNB, proc_eNB->frame_tx,subframe, diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index cabe966491..4e31016b6b 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -47,9 +47,7 @@ #include "unitary_defs.h" #include "PHY/TOOLS/lte_phy_scope.h" - -PHY_VARS_eNB *eNB; -PHY_VARS_UE *UE; +#include "dummy_functions.c" double cpuf; @@ -78,9 +76,112 @@ double t_tx_min = 1000000000; /*!< \brief initial min process time for tx */ double t_rx_min = 1000000000; /*!< \brief initial min process time for tx */ int n_tx_dropped = 0; /*!< \brief initial max process time for tx */ int n_rx_dropped = 0; /*!< \brief initial max process time for rx */ +int nfapi_mode = 0; +extern void fep_full(RU_t *ru); +extern void ru_fep_full_2thread(RU_t *ru); -void fill_ulsch_dci(PHY_VARS_eNB *eNB,void *UL_dci,int first_rb,int nb_rb,int mcs,int ndi,int cqi_flag) { +nfapi_dl_config_request_t DL_req; +nfapi_ul_config_request_t UL_req; +nfapi_hi_dci0_request_t HI_DCI0_req; +nfapi_ul_config_request_pdu_t ul_config_pdu_list[MAX_NUM_DL_PDU]; +nfapi_tx_request_pdu_t tx_pdu_list[MAX_NUM_TX_REQUEST_PDU]; +nfapi_tx_request_t TX_req; +Sched_Rsp_t sched_resp; + +void +fill_nfapi_ulsch_config_request(nfapi_ul_config_request_pdu_t *ul_config_pdu, + uint8_t cqi_req, + uint8_t p_eNB, + uint8_t cqi_ReportModeAperiodic, + uint8_t betaOffset_CQI_Index, + uint8_t betaOffset_RI_Index, + uint8_t dl_cqi_pmi_size, + uint8_t tmode, + uint32_t handle, + uint16_t rnti, + uint8_t resource_block_start, + uint8_t number_of_resource_blocks, + uint8_t modulation_type, + uint8_t cyclic_shift_2_for_drms, + uint8_t frequency_hopping_enabled_flag, + uint8_t frequency_hopping_bits, + uint8_t new_data_indication, + uint8_t redundancy_version, + uint8_t harq_process_number, + uint8_t ul_tx_mode, + uint8_t current_tx_nb, + uint8_t n_srs, + uint16_t size) +{ + memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); + + // printf("filling ul_config_pdu: modulation type %d, rvidx %d\n",modulation_type,redundancy_version); + + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = handle; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = rnti; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = resource_block_start; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = number_of_resource_blocks; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = modulation_type; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = cyclic_shift_2_for_drms; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = frequency_hopping_enabled_flag; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = frequency_hopping_bits; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = new_data_indication; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = redundancy_version; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = harq_process_number; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = ul_tx_mode; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = current_tx_nb; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = n_srs; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = size; + + if (cqi_req == 1) { + // Add CQI portion + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_cqi_ri_pdu)); + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG; + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.report_type = 1; + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.number_of_cc = 1; + LOG_D(MAC, "report_type %d\n",ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.report_type); + + if (p_eNB <= 2 + && (tmode == 3 || tmode == 4 || tmode == 8 || tmode == 9 || tmode == 10)) + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 1; + else if (p_eNB <= 2) ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 0; + else if (p_eNB == 4) ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 2; + + for (int ri = 0; + ri < (1 << ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size); + ri++) + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[ri] = dl_cqi_pmi_size; + + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_cqi = betaOffset_CQI_Index; + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_ri = betaOffset_RI_Index; + } +} + +void fill_ulsch_dci(PHY_VARS_eNB *eNB, + int frame, + int subframe, + Sched_Rsp_t *sched_resp, + uint16_t rnti, + void *UL_dci, + int first_rb, + int nb_rb, + int mcs, + int modulation_type, + int ndi, + int cqi_flag, + uint8_t beta_CQI, + uint8_t beta_RI, + uint8_t cqi_size) { + + nfapi_ul_config_request_body_t *ul_req=&sched_resp->UL_req->ul_config_request_body; + int harq_pid = ((frame*10)+subframe)&7; + + // printf("ulsch in frame %d, subframe %d => harq_pid %d, mcs %d, ndi %d\n",frame,subframe,harq_pid,mcs,ndi); switch (eNB->frame_parms.N_RB_UL) { case 6: @@ -162,6 +263,36 @@ void fill_ulsch_dci(PHY_VARS_eNB *eNB,void *UL_dci,int first_rb,int nb_rb,int mc break; } + fill_nfapi_ulsch_config_request(&ul_req->ul_config_pdu_list[0], + cqi_flag&1, + 1, // p_eNB + 0, // reportmode Aperiodic + beta_CQI, + beta_RI, + cqi_size, + //cc, + //UE_template->physicalConfigDedicated, + 1, + 0, + 14, // rnti + first_rb, // resource_block_start + nb_rb, // number_of_resource_blocks + modulation_type, + 0, // cyclic_shift_2_for_drms + 0, // frequency_hopping_enabled_flag + 0, // frequency_hopping_bits + ndi, // new_data_indication + mcs>28?(mcs-28):0, // redundancy_version + harq_pid, // harq_process_number + 0, // ul_tx_mode + 0, // current_tx_nb + 0, // n_srs + get_TBS_UL(mcs,nb_rb)); + + sched_resp->UL_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_req->number_of_pdus=1; + ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + } extern void eNB_fep_full(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc); @@ -172,22 +303,26 @@ int main(int argc, char **argv) char c; int i,j,aa,u; - + PHY_VARS_eNB *eNB; + PHY_VARS_UE *UE; + RU_t *ru; int aarx,aatx; double channelx,channely; double sigma2, sigma2_dB=10,SNR,SNR2=0,snr0=-2.0,snr1,SNRmeas,rate,saving_bler=0; double input_snr_step=.2,snr_int=30; double blerr; - + int rvidx[8]={0,2,3,1,0,2,3,1}; int **txdata; LTE_DL_FRAME_PARMS *frame_parms; double s_re0[30720],s_im0[30720],r_re0[30720],r_im0[30720]; double s_re1[30720],s_im1[30720],r_re1[30720],r_im1[30720]; + double r_re2[30720],r_im2[30720]; + double r_re3[30720],r_im3[30720]; double *s_re[2]={s_re0,s_re1}; double *s_im[2]={s_im0,s_im1}; - double *r_re[2]={r_re0,r_re1}; - double *r_im[2]={r_im0,r_im1}; + double *r_re[4]={r_re0,r_re1,r_re2,r_re3}; + double *r_im[4]={r_im0,r_im1,r_im2,r_im3}; double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel double iqim=0.0; uint8_t extended_prefix_flag=0; @@ -254,8 +389,7 @@ int main(int argc, char **argv) uint8_t N_RB_DL=25,osf=1; //uint8_t cyclic_shift = 0; - uint8_t cooperation_flag = 0; //0 no cooperation, 1 delay diversity, 2 Alamouti - uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2; + uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2,cqi_size=11; uint8_t tdd_config=3,frame_type=FDD; uint8_t N0=30; @@ -282,10 +416,24 @@ int main(int argc, char **argv) opp_enabled=1; // to enable the time meas + sched_resp.DL_req = &DL_req; + sched_resp.UL_req = &UL_req; + sched_resp.HI_DCI0_req = &HI_DCI0_req; + sched_resp.TX_req = &TX_req; + memset((void*)&DL_req,0,sizeof(DL_req)); + memset((void*)&UL_req,0,sizeof(UL_req)); + memset((void*)&HI_DCI0_req,0,sizeof(HI_DCI0_req)); + memset((void*)&TX_req,0,sizeof(TX_req)); + + UL_req.ul_config_request_body.ul_config_pdu_list = ul_config_pdu_list; + TX_req.tx_request_body.tx_pdu_list = tx_pdu_list; + cpu_freq_GHz = (double)get_cpu_freq_GHz(); cpuf = cpu_freq_GHz; printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz); + AssertFatal(load_configmodule(argc,argv) != NULL, + "cannot load configuration module, exiting\n"); logInit(); /* @@ -565,9 +713,12 @@ int main(int argc, char **argv) break; } } + RC.nb_L1_inst = 1; + RC.nb_RU = 1; - lte_param_init(1, - 1, + lte_param_init(&eNB,&UE,&ru, + 1, + 1, n_rx, 1, extended_prefix_flag, @@ -575,10 +726,30 @@ int main(int argc, char **argv) 0, tdd_config, N_RB_DL, + 4, threequarter_fs, osf, 0); + RC.eNB = (PHY_VARS_eNB ***)malloc(sizeof(PHY_VARS_eNB **)); + RC.eNB[0] = (PHY_VARS_eNB **)malloc(sizeof(PHY_VARS_eNB *)); + RC.ru = (RU_t **)malloc(sizeof(RC.ru)); + RC.eNB[0][0] = eNB; + RC.ru[0] = ru; + for (int k=0;kRU_list[0]->nb_rx;k++) eNB->common_vars.rxdataF[k] = eNB->RU_list[0]->common.rxdataF[k]; + + memset((void*)&eNB->UL_INFO,0,sizeof(eNB->UL_INFO)); + + printf("Setting indication lists\n"); + eNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = eNB->rx_pdu_list; + eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = eNB->crc_pdu_list; + eNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = eNB->sr_pdu_list; + eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list; + eNB->UL_INFO.cqi_ind.cqi_pdu_list = eNB->cqi_pdu_list; + eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list; + + printf("lte_param_init done\n"); + // for a call to phy_reset_ue later we need PHY_vars_UE_g allocated and pointing to UE PHY_vars_UE_g = (PHY_VARS_UE***)malloc(sizeof(PHY_VARS_UE**)); PHY_vars_UE_g[0] = (PHY_VARS_UE**) malloc(sizeof(PHY_VARS_UE*)); @@ -587,7 +758,7 @@ int main(int argc, char **argv) if (nb_rb_set == 0) nb_rb = eNB->frame_parms.N_RB_UL; - printf("1 . rxdataF_comp[0] %p\n",eNB->pusch_vars[0]->rxdataF_comp[0][0]); + printf("1 . rxdataF_comp[0] %p\n",eNB->pusch_vars[0]->rxdataF_comp[0]); printf("Setting mcs = %d\n",mcs); printf("n_frames = %d\n", n_frames); @@ -670,7 +841,6 @@ int main(int argc, char **argv) eNB->soundingrs_ul_config_dedicated[UE_id].freqDomainPosition = 0; eNB->soundingrs_ul_config_dedicated[UE_id].cyclicShift = 0; - eNB->cooperation_flag = cooperation_flag; eNB->pusch_config_dedicated[UE_id].betaOffset_ACK_Index = beta_ACK; eNB->pusch_config_dedicated[UE_id].betaOffset_RI_Index = beta_RI; @@ -700,7 +870,7 @@ int main(int argc, char **argv) UE2eNB->max_Doppler = maxDoppler; // NN: N_RB_UL has to be defined in ulsim - eNB->ulsch[0] = new_eNB_ulsch(max_turbo_iterations,N_RB_DL,0); + for (int k=0;kulsch[k] = new_eNB_ulsch(max_turbo_iterations,N_RB_DL,0); UE->ulsch[0] = new_ue_ulsch(N_RB_DL,0); if (parallel_flag == 1) { @@ -761,9 +931,9 @@ int main(int argc, char **argv) proc_rxtx->subframe_tx=pdcch_alloc2ul_subframe(&eNB->frame_parms,subframe); proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx; - proc_rxtx_ue->frame_rx = proc_rxtx->frame_tx; + proc_rxtx_ue->frame_rx = (subframe<4)?(proc_rxtx->frame_tx-1):(proc_rxtx->frame_tx); proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx; - proc_rxtx_ue->subframe_rx = proc_rxtx->subframe_tx; + proc_rxtx_ue->subframe_rx = (proc_rxtx->subframe_tx+6)%10; printf("Init UL hopping UE\n"); init_ul_hopping(&UE->frame_parms); @@ -915,7 +1085,6 @@ int main(int argc, char **argv) reset_meas(&UE->ulsch_multiplexing_stats); reset_meas(&eNB->phy_proc_rx); - reset_meas(&eNB->ofdm_demod_stats); reset_meas(&eNB->ulsch_channel_estimation_stats); reset_meas(&eNB->ulsch_freq_offset_estimation_stats); reset_meas(&eNB->rx_dft_stats); @@ -965,19 +1134,38 @@ int main(int argc, char **argv) round=0; while (round < 4) { + proc_rxtx->frame_rx=1; + proc_rxtx->subframe_rx=subframe; + + proc_rxtx->frame_tx=pdcch_alloc2ul_frame(&eNB->frame_parms,1,subframe); + proc_rxtx->subframe_tx=pdcch_alloc2ul_subframe(&eNB->frame_parms,subframe); + + proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx; + proc_rxtx_ue->frame_rx = (subframe<4)?(proc_rxtx->frame_tx-1):(proc_rxtx->frame_tx); + proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx; + proc_rxtx_ue->subframe_rx = (proc_rxtx->subframe_tx+6)%10; + eNB->ulsch[0]->harq_processes[harq_pid]->round=round; UE->ulsch[0]->harq_processes[harq_pid]->round=round; - // printf("Trial %d : Round %d (subframe %d, frame %d)\n",trials,round,proc_rxtx_ue->subframe_rx,proc_rxtx_ue->frame_rx); + if (n_frames==1) printf("filling ulsch: Trial %d : Round %d (subframe %d, frame %d)\n",trials,round,proc_rxtx_ue->subframe_tx,proc_rxtx_ue->frame_tx); round_trials[round]++; + UL_req.sfn_sf = (1<<4)+subframe; + if (n_frames==1) printf("filling ulsch: eNB prog frame %d, subframe %d (%d,%d)\n",proc_rxtx->frame_rx,subframe,sched_resp.frame,sched_resp.subframe); - fill_ulsch_dci(eNB,(void*)&UL_alloc_pdu,first_rb,nb_rb,mcs,ndi,cqi_flag); + int modulation_type; + if (mcs < 11) modulation_type = 2; + else if (mcs < 21) modulation_type = 4; + else if (mcs < 29) modulation_type = 6; + + fill_ulsch_dci(eNB,proc_rxtx->frame_rx,subframe,&sched_resp,14,(void*)&UL_alloc_pdu,first_rb,nb_rb,(round==0)?mcs:(28+rvidx[round]),modulation_type,ndi,cqi_flag,beta_CQI,beta_RI,cqi_size); UE->ulsch_Msg3_active[eNB_id] = 0; UE->ul_power_control_dedicated[eNB_id].accumulationEnabled=1; + if (n_frames==1) printf("filling ulsch: ue prog SFN/SF %d/%d\n",proc_rxtx_ue->frame_rx,proc_rxtx_ue->subframe_rx); generate_ue_ulsch_params_from_dci((void *)&UL_alloc_pdu, 14, - proc_rxtx->subframe_tx, + (subframe+6)%10, format0, UE, proc_rxtx_ue, @@ -988,17 +1176,11 @@ int main(int argc, char **argv) 0, srs_flag); - generate_eNB_ulsch_params_from_dci(eNB,proc_rxtx, - (void *)&UL_alloc_pdu, - 14, - format0, - 0, - SI_RNTI, - 0, - P_RNTI, - CBA_RNTI, - srs_flag); - eNB->ulsch[0]->harq_processes[harq_pid]->subframe_scheduling_flag = 1; + sched_resp.subframe=(subframe+6)%10; + sched_resp.frame=(1024+eNB->proc.frame_rx+((subframe<4)?-1:0))&1023; + + schedule_response(&sched_resp); + ///////////////////// if (abstx) { @@ -1020,6 +1202,9 @@ int main(int argc, char **argv) eNB->proc.frame_rx = 1; eNB->proc.subframe_rx = subframe; + ru->proc.frame_rx = 1; + ru->proc.subframe_rx = subframe; + proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx; proc_rxtx_ue->frame_rx = proc_rxtx->frame_tx; proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx; @@ -1027,70 +1212,6 @@ int main(int argc, char **argv) phy_procedures_UE_TX(UE,proc_rxtx_ue,0,0,normal_txrx,no_relay); - /* - if (srs_flag) - generate_srs_tx(UE,0,AMP,subframe); - - generate_drs_pusch(UE,proc_rxtx_ue,0, - AMP,subframe, - UE->ulsch[0]->harq_processes[harq_pid]->first_rb, - UE->ulsch[0]->harq_processes[harq_pid]->nb_rb, - 0); - - if ((cqi_flag == 1) && (n_frames == 1) ) { - printf("CQI information (O %d) %d %d\n",UE->ulsch[0]->O, - UE->ulsch[0]->o[0],UE->ulsch[0]->o[1]); - print_CQI(UE->ulsch[0]->o,UE->ulsch[0]->uci_format,UE->frame_parms.N_RB_DL,0); - } - - UE->ulsch[0]->o_ACK[0] = taus()&1; - - start_meas(&UE->ulsch_encoding_stats); - - if (ulsch_encoding(input_buffer, - UE, - harq_pid, - eNB_id, - 2, // transmission mode - control_only_flag, - 1// Nbundled - )==-1) { - printf("ulsim.c Problem with ulsch_encoding\n"); - exit(-1); - } - - stop_meas(&UE->ulsch_encoding_stats); - - start_meas(&UE->ulsch_modulation_stats); - ulsch_modulation(UE->common_vars.txdataF,AMP, - proc_rxtx_ue->frame_tx,subframe,&UE->frame_parms, - UE->ulsch[0]); - stop_meas(&UE->ulsch_modulation_stats); - */ - - - - - /* - for (aa=0; aa<1; aa++) { - if (frame_parms->Ncp == EXTENDED) - PHY_ofdm_mod(&UE->common_vars.txdataF[aa][subframe*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX], // input - &txdata[aa][eNB->frame_parms.samples_per_tti*subframe], // output - UE->frame_parms.ofdm_symbol_size, - nsymb, // number of symbols - UE->frame_parms.nb_prefix_samples, // number of prefix samples - CYCLIC_PREFIX); - else - normal_prefix_mod(&UE->common_vars.txdataF[aa][subframe*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX], - &txdata[aa][eNB->frame_parms.samples_per_tti*subframe], - nsymb, - frame_parms); - - - apply_7_5_kHz(UE,UE->common_vars.txdata[aa],subframe<<1); - apply_7_5_kHz(UE,UE->common_vars.txdata[aa],1+(subframe<<1)); - -*/ tx_lev = signal_energy(&UE->common_vars.txdata[0][eNB->frame_parms.samples_per_tti*subframe], eNB->frame_parms.samples_per_tti); @@ -1113,11 +1234,11 @@ int main(int argc, char **argv) //AWGN //Set target wideband RX noise level to N0 - sigma2_dB = N0;//10*log10((double)tx_lev) +10*log10(UE->frame_parms.ofdm_symbol_size/(UE->frame_parms.N_RB_DL*12)) - SNR; + sigma2_dB = N0;//-10*log10(UE->frame_parms.ofdm_symbol_size/(UE->frame_parms.N_RB_DL*12));//10*log10((double)tx_lev) +10*log10(UE->frame_parms.ofdm_symbol_size/(UE->frame_parms.N_RB_DL*12)) - SNR; sigma2 = pow(10,sigma2_dB/10); // compute tx_gain to achieve target SNR (per resource element!) - tx_gain = sqrt(pow(10.0,.1*(N0+SNR))*(nb_rb*12/(double)UE->frame_parms.ofdm_symbol_size)/(double)tx_lev); + tx_gain = sqrt(pow(10.0,.1*(N0+SNR))/(double)tx_lev);//*(nb_rb*12/(double)UE->frame_parms.ofdm_symbol_size)/(double)tx_lev); if (n_frames==1) @@ -1128,8 +1249,8 @@ int main(int argc, char **argv) for (i=0; iframe_parms.nb_antennas_rx; aa++) { - ((short*) &eNB->common_vars.rxdata[0][aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); - ((short*) &eNB->common_vars.rxdata[0][aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i+1] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short*) &ru->common.rxdata[aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short*) &ru->common.rxdata[aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i+1] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); } } @@ -1186,37 +1307,37 @@ int main(int argc, char **argv) for (i=0; iframe_parms.samples_per_tti; i++) { for (aa=0; aaframe_parms.nb_antennas_rx; aa++) { - ((short*) &eNB->common_vars.rxdata[0][aa][eNB->frame_parms.samples_per_tti*subframe])[2*i] = (short) ((tx_gain*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); - ((short*) &eNB->common_vars.rxdata[0][aa][eNB->frame_parms.samples_per_tti*subframe])[2*i+1] = (short) ((tx_gain*r_im[aa][i]) + (iqim*tx_gain*r_re[aa][i]) + sqrt( + ((short*) &ru->common.rxdata[aa][eNB->frame_parms.samples_per_tti*subframe])[2*i] = (short) ((tx_gain*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); + ((short*) &ru->common.rxdata[aa][eNB->frame_parms.samples_per_tti*subframe])[2*i+1] = (short) ((tx_gain*r_im[aa][i]) + (iqim*tx_gain*r_re[aa][i]) + sqrt( sigma2/2)*gaussdouble(0.0,1.0)); } } - if (n_frames==1) { + if (n_frames<=10) { printf("rx_level Null symbol %f\n",10*log10((double)signal_energy((int*) - &eNB->common_vars.rxdata[0][0][(eNB->frame_parms.samples_per_tti<<1) -eNB->frame_parms.ofdm_symbol_size],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); - printf("rx_level data symbol %f\n",10*log10(signal_energy((int*)&eNB->common_vars.rxdata[0][0][160+(eNB->frame_parms.samples_per_tti*subframe)], + &ru->common.rxdata[0][(eNB->frame_parms.samples_per_tti<<1) -eNB->frame_parms.ofdm_symbol_size],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); + printf("rx_level data symbol %f\n",10*log10(signal_energy((int*)&ru->common.rxdata[0][160+(eNB->frame_parms.samples_per_tti*subframe)], OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); } - SNRmeas = 10*log10(((double)signal_energy((int*)&eNB->common_vars.rxdata[0][0][160+(eNB->frame_parms.samples_per_tti*subframe)], + SNRmeas = 10*log10(((double)signal_energy((int*)&ru->common.rxdata[0][160+(eNB->frame_parms.samples_per_tti*subframe)], OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))/((double)signal_energy((int*) - &eNB->common_vars.rxdata[0][0][(eNB->frame_parms.samples_per_tti<<1) -eNB->frame_parms.ofdm_symbol_size], + &ru->common.rxdata[0][(eNB->frame_parms.samples_per_tti<<1) -eNB->frame_parms.ofdm_symbol_size], OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2)) - 1)+10*log10(eNB->frame_parms.N_RB_UL/nb_rb); - if (n_frames==1) { + if (n_frames<=10) { printf("SNRmeas %f\n",SNRmeas); - // write_output("rxsig0UL.m","rxs0", &eNB->common_vars.rxdata[0][0][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1); - //write_output("rxsig1UL.m","rxs1", &eNB->common_vars.rxdata[0][0][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1); + write_output("rxsig0UL.m","rxs0", &ru->common.rxdata[0][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1); + // write_output("rxsig1UL.m","rxs1", &ru->common_vars.rxdata[0][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1); } - eNB->fep = (parallel_flag == 1) ? eNB_fep_full_2thread : eNB_fep_full; + ru->feprx = (parallel_flag == 1) ? ru_fep_full_2thread : fep_full; eNB->td = (parallel_flag == 1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; - eNB->do_prach = NULL; - phy_procedures_eNB_common_RX(eNB,proc_rxtx); + + ru->feprx(ru); phy_procedures_eNB_uespec_RX(eNB,proc_rxtx,no_relay); @@ -1252,7 +1373,7 @@ int main(int argc, char **argv) // if (ret <= eNB->ulsch[0]->max_turbo_iterations) { - if (eNB->ulsch[0]->harq_processes[harq_pid]->round == 0) { + if (eNB->ulsch[0]->harq_processes[harq_pid]->status == SCH_IDLE) { // avg_iter += ret; iter_trials++; @@ -1264,7 +1385,7 @@ int main(int argc, char **argv) print_CQI(eNB->ulsch[0]->harq_processes[harq_pid]->o, eNB->ulsch[0]->harq_processes[harq_pid]->uci_format,0,eNB->frame_parms.N_RB_DL); - dump_ulsch(eNB,proc_rxtx,0); + dump_ulsch(eNB,eNB->proc.frame_rx,subframe,0,round); exit(-1); } @@ -1293,18 +1414,17 @@ int main(int argc, char **argv) eNB->ulsch[0]->harq_processes[harq_pid]->c[s][i]^UE->ulsch[0]->harq_processes[harq_pid]->c[s][i]); } - dump_ulsch(eNB,proc_rxtx,0); - exit(-1); + dump_ulsch(eNB,eNB->proc.frame_rx,subframe,0,round); + if (round == 4) exit(-1); } - // printf("round %d errors %d/%d\n",round,errs[round],trials); + if (n_frames==1) printf("round %d errors %d/%d\n",round,errs[round],trials); round++; if (n_frames==1) { printf("ULSCH in error in round %d\n",round); } - } // ulsch error - + } // ulsch error } // round @@ -1324,7 +1444,7 @@ int main(int argc, char **argv) double t_rx = (double)eNB->phy_proc_rx.p_time/cpu_freq_GHz/1000.0; - double t_rx_fft = (double)eNB->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; + double t_rx_fft = (double)ru->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; double t_rx_demod = (double)eNB->ulsch_demodulation_stats.p_time/cpu_freq_GHz/1000.0; double t_rx_dec = (double)eNB->ulsch_decoding_stats.p_time/cpu_freq_GHz/1000.0; @@ -1449,12 +1569,12 @@ int main(int argc, char **argv) tx_lev_dB, 20*log10(tx_gain), (double)N0, - eNB->measurements[0].n0_power_tot_dB, + eNB->measurements.n0_power_tot_dB, get_hundred_times_delta_IF(UE,eNB_id,harq_pid) , dB_fixed(eNB->pusch_vars[0]->ulsch_power[0]), dB_fixed(eNB->pusch_vars[0]->ulsch_power[1]), - eNB->measurements->n0_power_dB[0], - eNB->measurements->n0_power_dB[1]); + eNB->measurements.n0_power_dB[0], + eNB->measurements.n0_power_dB[1]); effective_rate = ((double)(round_trials[0])/((double)round_trials[0] + round_trials[1] + round_trials[2] + round_trials[3])); @@ -1548,10 +1668,10 @@ int main(int argc, char **argv) printf("Total PHY proc rx :%f us (%d trials)\n",(double)eNB->phy_proc_rx.diff/eNB->phy_proc_rx.trials/cpu_freq_GHz/1000.0,eNB->phy_proc_rx.trials); printf("|__ Statistcs std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median, rx_q1, rx_q3, n_rx_dropped); - std_phy_proc_rx_fft = sqrt((double)eNB->ofdm_demod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/eNB->ofdm_demod_stats.trials - pow((double)eNB->ofdm_demod_stats.diff/eNB->ofdm_demod_stats.trials/cpu_freq_GHz/1000,2)); - printf("OFDM_demod time :%f us (%d trials)\n",(double)eNB->ofdm_demod_stats.diff/eNB->ofdm_demod_stats.trials/cpu_freq_GHz/1000.0, - eNB->ofdm_demod_stats.trials); + std_phy_proc_rx_fft = sqrt((double)ru->ofdm_demod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, + 2)/ru->ofdm_demod_stats.trials - pow((double)ru->ofdm_demod_stats.diff/ru->ofdm_demod_stats.trials/cpu_freq_GHz/1000,2)); + printf("OFDM_demod time :%f us (%d trials)\n",(double)ru->ofdm_demod_stats.diff/ru->ofdm_demod_stats.trials/cpu_freq_GHz/1000.0, + ru->ofdm_demod_stats.trials); printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n", std_phy_proc_rx_fft, rx_fft_median, rx_fft_q1, rx_fft_q3); std_phy_proc_rx_demod = sqrt((double)eNB->ulsch_demodulation_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, 2)/eNB->ulsch_demodulation_stats.trials - pow((double)eNB->ulsch_demodulation_stats.diff/eNB->ulsch_demodulation_stats.trials/cpu_freq_GHz/1000,2)); @@ -1672,7 +1792,7 @@ int main(int argc, char **argv) UE->ulsch_modulation_stats.trials, UE->ulsch_encoding_stats.trials, eNB->phy_proc_rx.trials, - eNB->ofdm_demod_stats.trials, + ru->ofdm_demod_stats.trials, eNB->ulsch_demodulation_stats.trials, eNB->ulsch_decoding_stats.trials ); @@ -1682,7 +1802,7 @@ int main(int argc, char **argv) get_time_meas_us(&UE->ulsch_modulation_stats), get_time_meas_us(&UE->ulsch_encoding_stats), get_time_meas_us(&eNB->phy_proc_rx), - get_time_meas_us(&eNB->ofdm_demod_stats), + get_time_meas_us(&ru->ofdm_demod_stats), get_time_meas_us(&eNB->ulsch_demodulation_stats), get_time_meas_us(&eNB->ulsch_decoding_stats) ); @@ -1733,7 +1853,7 @@ int main(int argc, char **argv) oai_exit=1; - pthread_cond_signal(&eNB->proc.cond_fep); + pthread_cond_signal(&ru->proc.cond_fep); if (abstx) { // ABSTRACTION fprintf(csv_fdUL,"];"); From a1dc99724bdfc7658efd0d41ca3f9d728114f873 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Sat, 17 Feb 2018 11:15:53 -0800 Subject: [PATCH 154/195] missing file --- openair1/SIMULATION/LTE_PHY/dummy_functions.c | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 openair1/SIMULATION/LTE_PHY/dummy_functions.c diff --git a/openair1/SIMULATION/LTE_PHY/dummy_functions.c b/openair1/SIMULATION/LTE_PHY/dummy_functions.c new file mode 100644 index 0000000000..dc86e76113 --- /dev/null +++ b/openair1/SIMULATION/LTE_PHY/dummy_functions.c @@ -0,0 +1,84 @@ + +PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id, + frame_t frameP, uint8_t new_Msg3, + sub_frame_t subframe){ return(NULL);} + +void ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, + sub_frame_t subframe, uint8_t eNB_index, + uint8_t * ulsch_buffer, uint16_t buflen, + uint8_t * access_mode){} + +void Msg1_transmitted(module_id_t module_idP, uint8_t CC_id, + frame_t frameP, uint8_t eNB_id){} + +void Msg3_transmitted(module_id_t module_idP, uint8_t CC_id, + frame_t frameP, uint8_t eNB_id){} + +uint32_t ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, + uint8_t eNB_id, rnti_t rnti, sub_frame_t subframe){ return(0);} + +void rrc_out_of_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index) +{} + +UE_L2_STATE_t ue_scheduler(const module_id_t module_idP, + const frame_t rxFrameP, + const sub_frame_t rxSubframe, + const frame_t txFrameP, + const sub_frame_t txSubframe, + const lte_subframe_t direction, + const uint8_t eNB_index, const int CC_id){ return(0);} + +void ue_decode_p(module_id_t module_idP, int CC_id, frame_t frame, + uint8_t CH_index, void *pdu, uint16_t len){} + +void ue_decode_si(module_id_t module_idP, int CC_id, frame_t frame, + uint8_t CH_index, void *pdu, uint16_t len){} + +void ue_send_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frame, + sub_frame_t subframe, uint8_t * sdu, uint16_t sdu_len, + uint8_t CH_index){} + +uint16_t +ue_process_rar(const module_id_t module_idP, + const int CC_id, + const frame_t frameP, + const rnti_t ra_rnti, + uint8_t * const dlsch_buffer, + rnti_t * const t_crnti, + const uint8_t preamble_index, + uint8_t * selected_rar_buffer){ return(0);} + +void ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, + uint8_t * sdu, uint16_t sdu_len, uint8_t eNB_index, + uint8_t sync_area){} + +int ue_query_mch(uint8_t Mod_id, uint8_t CC_id, uint32_t frame, + sub_frame_t subframe, uint8_t eNB_index, + uint8_t * sync_area, uint8_t * mcch_active){ return(0);} + +void dl_phy_sync_success(module_id_t module_idP, + frame_t frameP, + unsigned char eNB_index, uint8_t first_sync){} + +uint32_t from_earfcn(int eutra_bandP, uint32_t dl_earfcn) { return(0);} + +int32_t get_uldl_offset(int eutra_bandP) { return(0);} + +IF_Module_t *IF_Module_init(int Mod_id) { return(NULL);} + +int8_t get_Po_NOMINAL_PUSCH(module_id_t module_idP, uint8_t CC_id) { return(0);} + +int8_t get_deltaP_rampup(module_id_t module_idP, uint8_t CC_id) { return(0);} + +void thread_top_init(char *thread_name, + int affinity, + uint64_t runtime, + uint64_t deadline, + uint64_t period) {} + +int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { return(0);} +int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); } + +int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); } + +int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); } From b42d83beadfdd07774754d437602417725c70ea7 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Sun, 18 Feb 2018 12:19:31 +0100 Subject: [PATCH 155/195] memory allocation bugs for 2x2 transmission in dlsim --- openair1/PHY/INIT/defs.h | 3 ++- openair1/PHY/INIT/lte_param_init.c | 9 +++++---- openair1/SIMULATION/LTE_PHY/dlsim.c | 6 ++++-- openair1/SIMULATION/LTE_PHY/ulsim.c | 1 + 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/openair1/PHY/INIT/defs.h b/openair1/PHY/INIT/defs.h index bb7fe72114..2c92503133 100644 --- a/openair1/PHY/INIT/defs.h +++ b/openair1/PHY/INIT/defs.h @@ -335,7 +335,8 @@ void lte_param_init(PHY_VARS_eNB **eNBp, RU_t **rup, unsigned char N_tx_port_eNB, unsigned char N_tx_phy, - unsigned char N_rx, + unsigned char N_rx_ru, + unsigned char N_rx_ue, unsigned char transmission_mode, uint8_t extended_prefix_flag, frame_t frame_type, diff --git a/openair1/PHY/INIT/lte_param_init.c b/openair1/PHY/INIT/lte_param_init.c index d9b7b12249..c09652db93 100644 --- a/openair1/PHY/INIT/lte_param_init.c +++ b/openair1/PHY/INIT/lte_param_init.c @@ -39,7 +39,8 @@ void lte_param_init(PHY_VARS_eNB **eNBp, RU_t **rup, unsigned char N_tx_port_eNB, unsigned char N_tx_phy, - unsigned char N_rx, + unsigned char N_rx_ru, + unsigned char N_rx_ue, unsigned char transmission_mode, uint8_t extended_prefix_flag, frame_t frame_type, @@ -90,7 +91,7 @@ void lte_param_init(PHY_VARS_eNB **eNBp, frame_parms->Nid_cell = Nid_cell; frame_parms->nushift = Nid_cell%6; frame_parms->nb_antennas_tx = N_tx_phy; - frame_parms->nb_antennas_rx = N_rx; + frame_parms->nb_antennas_rx = N_rx_ru; frame_parms->nb_antenna_ports_eNB = N_tx_port_eNB; frame_parms->phich_config_common.phich_resource = oneSixth; frame_parms->phich_config_common.phich_duration = normal; @@ -109,11 +110,11 @@ void lte_param_init(PHY_VARS_eNB **eNBp, UE->is_secondary_ue = 0; UE->frame_parms = *frame_parms; - UE->frame_parms.nb_antennas_rx=1; + UE->frame_parms.nb_antennas_rx=N_rx_ue; // eNB->frame_parms = *frame_parms; ru->frame_parms = *frame_parms; ru->nb_tx = N_tx_phy; - ru->nb_rx = N_rx; + ru->nb_rx = N_rx_ru; ru->if_south = LOCAL_RF; eNB->configured=1; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 57fa787142..2de1698450 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -242,7 +242,7 @@ void DL_channel(RU_t *ru,PHY_VARS_UE *UE,uint subframe,int awgn_flag,double SNR, sigma2 = pow(10,sigma2_dB/10); for (i=0; i<2*UE->frame_parms.samples_per_tti; i++) { - for (aa=0; aaframe_parms.nb_antennas_rx; aa++) { + for (aa=0; aaframe_parms.nb_antennas_rx; aa++) { //printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]); ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i] = (short) (r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); @@ -1099,7 +1099,8 @@ int main(int argc, char **argv) lte_param_init(&eNB,&UE,&ru, n_tx_port, n_tx_phy, - n_rx, + 1, + n_rx, transmission_mode, extended_prefix_flag, frame_type, @@ -1304,6 +1305,7 @@ int main(int argc, char **argv) UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti = n_rnti; + printf("Allocating %dx%d eNB->UE channel descriptor\n",eNB->frame_parms.nb_antennas_tx,UE->frame_parms.nb_antennas_rx); eNB2UE[0] = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx, UE->frame_parms.nb_antennas_rx, channel_model, diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 4e31016b6b..8381553bb7 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -720,6 +720,7 @@ int main(int argc, char **argv) 1, 1, n_rx, + 1, 1, extended_prefix_flag, frame_type, From 1c46dd7c694657864c14080c686907755520d999 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Sun, 18 Feb 2018 17:31:40 +0100 Subject: [PATCH 156/195] updates for oaisim --- cmake_targets/CMakeLists.txt | 1 - targets/SIMU/USER/oaisim.c | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index dc445a18bc..89b96bf922 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1300,7 +1300,6 @@ set(L2_SRC ) set(L2_SRC_UE - ${OPENAIR2_DIR}/LAYER2/openair2_proc.c ${PDCP_DIR}/pdcp.c ${PDCP_DIR}/pdcp_fifo.c ${PDCP_DIR}/pdcp_sequence_manager.c diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index 3a282e1d44..b23755c3c1 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -818,13 +818,14 @@ l2l1_task (void *args_p) } */ #ifdef OPENAIR2 - +/* if (eNB_l2_stats) { len = dump_eNB_l2_stats (stats_buffer, 0); rewind (eNB_l2_stats); fwrite (stats_buffer, 1, len, eNB_l2_stats); fflush(eNB_l2_stats); } +*/ #endif #endif From 62787a8893ecfd21748c8fcad93459035819463a Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 19 Feb 2018 14:09:09 +0100 Subject: [PATCH 157/195] fix CentOS compilation The following was not working properly: ./build_oai -I -w USRP After this commit it works. And so does: ./build_oai --eNB -w USRP --- cmake_targets/tools/build_helper | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 1ea97c030f..706cd05fe9 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -249,14 +249,14 @@ install_usrp_uhd_driver_from_source(){ cd /tmp echo "Downloading UHD driver" rm -rf /tmp/uhd - git clone git://github.com/EttusResearch/uhd.git + git clone https://github.com/EttusResearch/uhd.git cd uhd git checkout tags/release_003_010_001_001 mkdir -p host/build cd host/build $CMAKE ../ echo "Compiling UHD" - make + make -j`nproc` make test $SUDO make install $SUDO ldconfig @@ -277,10 +277,11 @@ check_install_usrp_uhd_driver(){ $SUDO apt-get -y --allow-unauthenticated install libuhd-dev libuhd003 uhd-host elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then $SUDO $INSTALLER -y install python boost libusb-devel libusbx-devel boost-devel python-mako python-docutils cmake + $SUDO pip install requests if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then # until EPEL repo hasn't bumped UHD driver to >=3.10 in EPEL, build driver from source $SUDO $INSTALLER -y remove uhd uhd-devel uhd-firmware - install_ursp_uhd_driver_from_source + install_usrp_uhd_driver_from_source else $SUDO $INSTALLER -y install uhd uhd-devel uhd-firmware fi @@ -644,7 +645,8 @@ check_install_oai_software() { lapack \ lapack-devel \ blas \ - blas-devel + blas-devel \ + libyaml-devel fi install_asn1c_from_source From 10e91d4e2f7821ecbb3069aa9eef7c237ade15e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Iardella?= Date: Fri, 16 Feb 2018 16:24:40 +0100 Subject: [PATCH 158/195] Move the accounting phase of the DL pre-processor in a separate procedure --- openair2/LAYER2/MAC/pre_processor.c | 1202 ++++++++++++++------------- openair2/LAYER2/MAC/proto.h | 5 - 2 files changed, 603 insertions(+), 604 deletions(-) diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 759bc591dd..148ea344e5 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -593,588 +593,591 @@ void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t #endif } +void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, + slice_id_t slice_id, + frame_t frameP, + sub_frame_t subframeP, + int N_RBG[MAX_NUM_CCs], + int min_rb_unit[MAX_NUM_CCs], + uint8_t rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], + uint8_t MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX], + uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX]) { + int UE_id, CC_id; + int ii, r1; + + rnti_t rnti; + uint8_t harq_pid, round, transmission_mode; + uint8_t total_rbs_used[MAX_NUM_CCs]; + uint8_t total_ue_count[MAX_NUM_CCs]; + uint16_t average_rbs_per_user[MAX_NUM_CCs]; + uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; + uint16_t nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; + + int N_RB_DL; + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + UE_sched_ctrl *ue_sched_ctl; + COMMON_channels_t *cc; + + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + total_ue_count[CC_id] = 0; + total_rbs_used[CC_id] = 0; + average_rbs_per_user[CC_id] = 0; + for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; ++UE_id) { + nb_rbs_required_remaining[CC_id][UE_id] = 0; + } + } + + // loop over all active UEs + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + rnti = UE_RNTI(Mod_id, UE_id); + + if (rnti == NOT_A_RNTI) + continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) + continue; + if (!ue_slice_membership(UE_id, slice_id)) + continue; + + for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { + CC_id = UE_list->ordered_CCids[ii][UE_id]; + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + cc = &RC.mac[Mod_id]->common_channels[CC_id]; + // TODO Can we use subframe2harqpid() here? + if (cc->tdd_Config) + harq_pid = ((frameP * 10) + subframeP) % 10; + else + harq_pid = ((frameP * 10) + subframeP) & 7; + round = ue_sched_ctl->round[CC_id][harq_pid]; + + average_rbs_per_user[CC_id] = 0; + + if (round != 8) { + nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + total_rbs_used[CC_id] += nb_rbs_required[CC_id][UE_id]; + } + + //nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id]; + if (nb_rbs_required[CC_id][UE_id] > 0) { + total_ue_count[CC_id] = total_ue_count[CC_id] + 1; + } + } + } + + // loop over all active UEs and calculate avg rb per user based on total active UEs + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + rnti = UE_RNTI(Mod_id, UE_id); + + if (rnti == NOT_A_RNTI) + continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) + continue; + if (!ue_slice_membership(UE_id, slice_id)) + continue; + + for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { + CC_id = UE_list->ordered_CCids[ii][UE_id]; + + // hypothetical assignment + /* + * If schedule is enabled and if the priority of the UEs is modified + * The average rbs per logical channel per user will depend on the level of + * priority. Concerning the hypothetical assignement, we should assign more + * rbs to prioritized users. Maybe, we can do a mapping between the + * average rbs per user and the level of priority or multiply the average rbs + * per user by a coefficient which represents the degree of priority. + */ + + N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth) - total_rbs_used[CC_id]; + + // recalculate based on the what is left after retransmission + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] = + flexran_nb_rbs_allowed_slice(slice_percentage[slice_id], N_RB_DL); + + if (total_ue_count[CC_id] == 0) { + average_rbs_per_user[CC_id] = 0; + } else if ((min_rb_unit[CC_id] * total_ue_count[CC_id]) <= + (ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id])) { + average_rbs_per_user[CC_id] = + (uint16_t) floor(ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] / total_ue_count[CC_id]); + } else { + // consider the total number of use that can be scheduled UE + average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; + } + } + } + + // note: nb_rbs_required is assigned according to total_buffer_dl + // extend nb_rbs_required to capture per LCID RB required + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + rnti = UE_RNTI(Mod_id, UE_id); + + if (rnti == NOT_A_RNTI) + continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) + continue; + if (!ue_slice_membership(UE_id, slice_id)) + continue; + + for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { + CC_id = UE_list->ordered_CCids[ii][UE_id]; + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + cc = &RC.mac[Mod_id]->common_channels[CC_id]; + // TODO Can we use subframe2harqpid() here? + if (cc->tdd_Config) + harq_pid = ((frameP * 10) + subframeP) % 10; + else + harq_pid = ((frameP * 10) + subframeP) & 7; + round = ue_sched_ctl->round[CC_id][harq_pid]; + + // 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) { + nb_rbs_required_remaining_1[CC_id][UE_id] = + nb_rbs_required[CC_id][UE_id]; + } else { + nb_rbs_required_remaining_1[CC_id][UE_id] = + cmin(average_rbs_per_user[CC_id], nb_rbs_required[CC_id][UE_id]); + } + } + } + + //Allocation to UEs is done in 2 rounds, + // 1st stage: average number of RBs allocated to each UE + // 2nd stage: remaining RBs are allocated to high priority UEs + for (r1 = 0; r1 < 2; r1++) { + + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { + CC_id = UE_list->ordered_CCids[ii][UE_id]; + + if (r1 == 0) { + nb_rbs_required_remaining[CC_id][UE_id] = + nb_rbs_required_remaining_1[CC_id][UE_id]; + } else { // rb required based only on the buffer - rb allocated in the 1st round + extra reaming rb form the 1st round + nb_rbs_required_remaining[CC_id][UE_id] = + nb_rbs_required[CC_id][UE_id] - + nb_rbs_required_remaining_1[CC_id][UE_id] + + nb_rbs_required_remaining[CC_id][UE_id]; + if (nb_rbs_required_remaining[CC_id][UE_id] < 0) + abort(); + } + + if (nb_rbs_required[CC_id][UE_id] > 0) + LOG_D(MAC, + "round %d : nb_rbs_required_remaining[%d][%d]= %d (remaining_1 %d, required %d, pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n", + r1, CC_id, UE_id, + nb_rbs_required_remaining[CC_id][UE_id], + nb_rbs_required_remaining_1[CC_id][UE_id], + nb_rbs_required[CC_id][UE_id], + UE_list->UE_sched_ctrl[UE_id].pre_nb_available_rbs[CC_id], + N_RBG[CC_id], + min_rb_unit[CC_id]); + + } + } + + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + + for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { + + CC_id = UE_list->ordered_CCids[ii][UE_id]; + // if there are UEs with traffic + if (total_ue_count[CC_id] > 0) { + // ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + // round = ue_sched_ctl->round[CC_id][harq_pid]; + + rnti = UE_RNTI(Mod_id, UE_id); + + // LOG_D(MAC,"UE %d rnti 0x\n", UE_id, rnti ); + if (rnti == NOT_A_RNTI) + continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) + continue; + if (!ue_slice_membership(UE_id, slice_id)) + continue; + + transmission_mode = get_tmode(Mod_id, CC_id, UE_id); + // mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0); + // rrc_status = mac_eNB_get_rrc_status(Mod_id,rnti); + /* 1st allocate for the retx */ + + // retransmission in data channels + // control channel in the 1st transmission + // data channel for all TM + LOG_T(MAC, + "calling dlsch_scheduler_pre_processor_allocate .. \n "); + dlsch_scheduler_pre_processor_allocate(Mod_id, UE_id, + CC_id, + N_RBG[CC_id], + transmission_mode, + min_rb_unit + [CC_id], + to_prb(RC.mac + [Mod_id]->common_channels + [CC_id].mib->message.dl_Bandwidth), + nb_rbs_required, + nb_rbs_required_remaining, + rballoc_sub, + MIMO_mode_indicator); + +#ifdef TM5 + // data chanel TM5: to be revisited + if ((round == 0) && + (transmission_mode == 5) && + (ue_sched_ctl->dl_pow_off[CC_id] != 1)) { + + for (j = 0; j < N_RBG[CC_id]; j += 2) { + + if ((((j == (N_RBG[CC_id] - 1)) + && (rballoc_sub[CC_id][j] == 0) + && (ue_sched_ctl-> + rballoc_sub_UE[CC_id][j] == 0)) + || ((j < (N_RBG[CC_id] - 1)) + && (rballoc_sub[CC_id][j + 1] == 0) + && + (ue_sched_ctl->rballoc_sub_UE + [CC_id][j + 1] == 0))) + && (nb_rbs_required_remaining[CC_id][UE_id] + > 0)) { + + for (ii = UE_list->next[UE_id + 1]; ii >= 0; + ii = UE_list->next[ii]) { + + UE_id2 = ii; + rnti2 = UE_RNTI(Mod_id, UE_id2); + ue_sched_ctl2 = + &UE_list->UE_sched_ctrl[UE_id2]; + round2 = ue_sched_ctl2->round[CC_id]; + if (rnti2 == NOT_A_RNTI) + continue; + if (UE_list-> + UE_sched_ctrl + [UE_id2].ul_out_of_sync == 1) + continue; + + eNB_UE_stats2 = + UE_list-> + eNB_UE_stats[CC_id][UE_id2]; + //mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,frameP,subframeP,&harq_pid2,&round2,0); + + if ((mac_eNB_get_rrc_status + (Mod_id, + rnti2) >= RRC_RECONFIGURED) + && (round2 == 0) + && + (get_tmode(Mod_id, CC_id, UE_id2) + == 5) + && (ue_sched_ctl-> + dl_pow_off[CC_id] != 1)) { + + if ((((j == (N_RBG[CC_id] - 1)) + && + (ue_sched_ctl->rballoc_sub_UE + [CC_id][j] == 0)) + || ((j < (N_RBG[CC_id] - 1)) + && + (ue_sched_ctl-> + rballoc_sub_UE[CC_id][j + + 1] + == 0))) + && + (nb_rbs_required_remaining + [CC_id] + [UE_id2] > 0)) { + + if ((((eNB_UE_stats2-> + DL_pmi_single ^ + eNB_UE_stats1-> + DL_pmi_single) + << (14 - j)) & 0xc000) == 0x4000) { //MU-MIMO only for 25 RBs configuration + + rballoc_sub[CC_id][j] = 1; + ue_sched_ctl-> + rballoc_sub_UE[CC_id] + [j] = 1; + ue_sched_ctl2-> + rballoc_sub_UE[CC_id] + [j] = 1; + MIMO_mode_indicator[CC_id] + [j] = 0; + + if (j < N_RBG[CC_id] - 1) { + rballoc_sub[CC_id][j + + 1] = + 1; + ue_sched_ctl-> + rballoc_sub_UE + [CC_id][j + 1] = 1; + ue_sched_ctl2->rballoc_sub_UE + [CC_id][j + 1] = 1; + MIMO_mode_indicator + [CC_id][j + 1] + = 0; + } + + ue_sched_ctl-> + dl_pow_off[CC_id] + = 0; + ue_sched_ctl2-> + dl_pow_off[CC_id] + = 0; + + + if ((j == N_RBG[CC_id] - 1) + && ((N_RB_DL == 25) + || (N_RB_DL == + 50))) { + + nb_rbs_required_remaining + [CC_id][UE_id] = + nb_rbs_required_remaining + [CC_id][UE_id] - + min_rb_unit[CC_id] + + 1; + ue_sched_ctl->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl->pre_nb_available_rbs + [CC_id] + + min_rb_unit[CC_id] + - 1; + nb_rbs_required_remaining + [CC_id][UE_id2] = + nb_rbs_required_remaining + [CC_id][UE_id2] - + min_rb_unit[CC_id] + + 1; + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] + + min_rb_unit[CC_id] + - 1; + } else { + + nb_rbs_required_remaining + [CC_id][UE_id] = + nb_rbs_required_remaining + [CC_id][UE_id] - 4; + ue_sched_ctl->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl->pre_nb_available_rbs + [CC_id] + 4; + nb_rbs_required_remaining + [CC_id][UE_id2] = + nb_rbs_required_remaining + [CC_id][UE_id2] - + 4; + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] + 4; + } + + break; + } + } + } + } + } + } + } +#endif + } // total_ue_count + } // CC + } // UE + } // end of for for r1 and r2 +} // This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done void dlsch_scheduler_pre_processor(module_id_t Mod_id, - slice_id_t slice_id, - frame_t frameP, - sub_frame_t subframeP, - int N_RBG[MAX_NUM_CCs], int *mbsfn_flag) -{ + slice_id_t slice_id, + frame_t frameP, + sub_frame_t subframeP, + int N_RBG[MAX_NUM_CCs], + int *mbsfn_flag) { - unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], harq_pid = - 0, round = 0, total_ue_count[MAX_NUM_CCs], total_rbs_used[MAX_NUM_CCs]; - unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]; - int UE_id, i; - uint16_t ii, j; - uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - uint16_t nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - uint16_t average_rbs_per_user[MAX_NUM_CCs] = { 0 }; - rnti_t rnti; - int min_rb_unit[MAX_NUM_CCs]; - uint16_t r1 = 0; - uint8_t CC_id; - UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + int UE_id; + uint8_t CC_id; + uint16_t i, j; - int N_RB_DL; - int transmission_mode = 0; - UE_sched_ctrl *ue_sched_ctl; - // int rrc_status = RRC_IDLE; - COMMON_channels_t *cc; + uint8_t rballoc_sub[MAX_NUM_CCs][N_RBG_MAX]; + uint8_t MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]; // If TM5 is revisited, we can move this inside accounting + + int min_rb_unit[MAX_NUM_CCs]; + uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; + + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + UE_sched_ctrl *ue_sched_ctl; +// int rrc_status = RRC_IDLE; #ifdef TM5 - int harq_pid1 = 0; - int round1 = 0, round2 = 0; - int UE_id2; - uint16_t i1, i2, i3; - rnti_t rnti1, rnti2; - LTE_eNB_UE_stats *eNB_UE_stats1 = NULL; - LTE_eNB_UE_stats *eNB_UE_stats2 = NULL; - UE_sched_ctrl *ue_sched_ctl1, *ue_sched_ctl2; + int harq_pid1 = 0; + int round1 = 0, round2 = 0; + int UE_id2; + uint16_t i1, i2, i3; + rnti_t rnti1, rnti2; + LTE_eNB_UE_stats *eNB_UE_stats1 = NULL; + LTE_eNB_UE_stats *eNB_UE_stats2 = NULL; + UE_sched_ctrl *ue_sched_ctl1, *ue_sched_ctl2; #endif - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - if (mbsfn_flag[CC_id] > 0) // If this CC is allocated for MBSFN skip it here - continue; + if (mbsfn_flag[CC_id] > 0) // If this CC is allocated for MBSFN skip it here + continue; + min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id); + for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; ++UE_id) { + if (UE_list->active[UE_id] != TRUE) + continue; - min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id); + if (!ue_slice_membership(UE_id, slice_id)) + continue; - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { - if (UE_list->active[i] != TRUE) - continue; + // Initialize scheduling information for all active UEs + dlsch_scheduler_pre_processor_reset(Mod_id, + UE_id, + CC_id, + frameP, + subframeP, + N_RBG[CC_id], + nb_rbs_required, + rballoc_sub, + MIMO_mode_indicator); - if (!ue_slice_membership(i, slice_id)) - continue; - - UE_id = i; - // Initialize scheduling information for all active UEs - - - - dlsch_scheduler_pre_processor_reset(Mod_id, - UE_id, - CC_id, - frameP, - subframeP, - N_RBG[CC_id], - nb_rbs_required, - nb_rbs_required_remaining, - total_ue_count, - total_rbs_used, - rballoc_sub, - MIMO_mode_indicator); - - } } + } + // Store the DLSCH buffer for each logical channel + store_dlsch_buffer(Mod_id, slice_id, frameP, subframeP); - // Store the DLSCH buffer for each logical channel - store_dlsch_buffer(Mod_id, slice_id,frameP, subframeP); + // Calculate the number of RBs required by each UE on the basis of logical channel's buffer + assign_rbs_required(Mod_id, slice_id, frameP, subframeP, nb_rbs_required, min_rb_unit); + // Sorts the user on the basis of dlsch logical channel buffer and CQI + sort_UEs(Mod_id, slice_id, frameP, subframeP); + // This function does the main allocation of the number of RBs + dlsch_scheduler_pre_processor_accounting(Mod_id, + slice_id, + frameP, + subframeP, + N_RBG, + min_rb_unit, + rballoc_sub, + MIMO_mode_indicator, + nb_rbs_required); - // Calculate the number of RBs required by each UE on the basis of logical channel's buffer - assign_rbs_required(Mod_id, slice_id, frameP, subframeP, nb_rbs_required, - min_rb_unit); - - - - // Sorts the user on the basis of dlsch logical channel buffer and CQI - sort_UEs(Mod_id, slice_id, frameP, subframeP); - - - // loop over all active UEs - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - rnti = UE_RNTI(Mod_id, i); - - if (rnti == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; - UE_id = i; - if (!ue_slice_membership(UE_id, slice_id)) - continue; - - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - cc = &RC.mac[Mod_id]->common_channels[ii]; - if (cc->tdd_Config) - harq_pid = ((frameP * 10) + subframeP) % 10; - else - harq_pid = ((frameP * 10) + subframeP) & 7; - round = ue_sched_ctl->round[CC_id][harq_pid]; - - average_rbs_per_user[CC_id] = 0; - - - if (round != 8) { - nb_rbs_required[CC_id][UE_id] = - UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - total_rbs_used[CC_id]+=nb_rbs_required[CC_id][UE_id]; - } - - //nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id]; - if (nb_rbs_required[CC_id][UE_id] > 0) { - total_ue_count[CC_id] = total_ue_count[CC_id] + 1; - } - - } - } - - // loop over all active UEs and calculate avg rb per user based on total active UEs - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - rnti = UE_RNTI(Mod_id, i); - - if (rnti == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; - UE_id = i; - if (!ue_slice_membership(UE_id, slice_id)) - continue; - - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; - - // hypothetical assignment - /* - * If schedule is enabled and if the priority of the UEs is modified - * The average rbs per logical channel per user will depend on the level of - * priority. Concerning the hypothetical assignement, we should assign more - * rbs to prioritized users. Maybe, we can do a mapping between the - * average rbs per user and the level of priority or multiply the average rbs - * per user by a coefficient which represents the degree of priority. - */ - - - N_RB_DL = - to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib-> - message.dl_Bandwidth) - total_rbs_used[CC_id]; - - //recalcualte based on the what is left after retransmission - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id]= flexran_nb_rbs_allowed_slice(slice_percentage[slice_id],N_RB_DL); - - if (total_ue_count[CC_id] == 0) { - average_rbs_per_user[CC_id] = 0; - } else if ((min_rb_unit[CC_id] * total_ue_count[CC_id]) <= (ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id])) { - average_rbs_per_user[CC_id] = - (uint16_t) floor(ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] / total_ue_count[CC_id]); - } else { - average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; // consider the total number of use that can be scheduled UE - } - } - } - - // note: nb_rbs_required is assigned according to total_buffer_dl - // extend nb_rbs_required to capture per LCID RB required - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - rnti = UE_RNTI(Mod_id, i); - - if (rnti == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; - if (!ue_slice_membership(i, slice_id)) - continue; - - for (ii = 0; ii < UE_num_active_CC(UE_list, i); ii++) { - CC_id = UE_list->ordered_CCids[ii][i]; - ue_sched_ctl = &UE_list->UE_sched_ctrl[i]; - round = ue_sched_ctl->round[CC_id][harq_pid]; - - // 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) { - nb_rbs_required_remaining_1[CC_id][i] = - nb_rbs_required[CC_id][i]; - } else { - nb_rbs_required_remaining_1[CC_id][i] = - cmin(average_rbs_per_user[CC_id], - nb_rbs_required[CC_id][i]); - - } - } - } - - //Allocation to UEs is done in 2 rounds, - // 1st stage: average number of RBs allocated to each UE - // 2nd stage: remaining RBs are allocated to high priority UEs - for (r1 = 0; r1 < 2; r1++) { - - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - for (ii = 0; ii < UE_num_active_CC(UE_list, i); ii++) { - CC_id = UE_list->ordered_CCids[ii][i]; - - if (r1 == 0) { - nb_rbs_required_remaining[CC_id][i] = - nb_rbs_required_remaining_1[CC_id][i]; - } else { // rb required based only on the buffer - rb allloctaed in the 1st round + extra reaming rb form the 1st round - nb_rbs_required_remaining[CC_id][i] = - nb_rbs_required[CC_id][i] - - nb_rbs_required_remaining_1[CC_id][i] + - nb_rbs_required_remaining[CC_id][i]; - if (nb_rbs_required_remaining[CC_id][i] < 0) - abort(); - } - - if (nb_rbs_required[CC_id][i] > 0) - LOG_D(MAC, - "round %d : nb_rbs_required_remaining[%d][%d]= %d (remaining_1 %d, required %d, pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n", - r1, CC_id, i, - nb_rbs_required_remaining[CC_id][i], - nb_rbs_required_remaining_1[CC_id][i], - nb_rbs_required[CC_id][i], - UE_list->UE_sched_ctrl[i]. - pre_nb_available_rbs[CC_id], N_RBG[CC_id], - min_rb_unit[CC_id]); - - } - } - - - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - UE_id = i; - - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { - - // if there are UEs with traffic - if (total_ue_count [CC_id] > 0) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - round = ue_sched_ctl->round[CC_id][harq_pid]; - - rnti = UE_RNTI(Mod_id, UE_id); - - // LOG_D(MAC,"UE %d rnti 0x\n", UE_id, rnti ); - if (rnti == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) - continue; - if (!ue_slice_membership(i, slice_id)) - continue; - - transmission_mode = get_tmode(Mod_id, CC_id, UE_id); - // mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0); - //rrc_status = mac_eNB_get_rrc_status(Mod_id,rnti); - /* 1st allocate for the retx */ - - // retransmission in data channels - // control channel in the 1st transmission - // data channel for all TM - LOG_T(MAC, - "calling dlsch_scheduler_pre_processor_allocate .. \n "); - dlsch_scheduler_pre_processor_allocate(Mod_id, UE_id, - CC_id, - N_RBG[CC_id], - transmission_mode, - min_rb_unit - [CC_id], - to_prb(RC.mac - [Mod_id]->common_channels - [CC_id].mib->message.dl_Bandwidth), - nb_rbs_required, - nb_rbs_required_remaining, - rballoc_sub, - MIMO_mode_indicator); #ifdef TM5 + // This has to be revisited!!!! + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + i1 = 0; + i2 = 0; + i3 = 0; - // data chanel TM5: to be revisted - if ((round == 0) && - (transmission_mode == 5) && - (ue_sched_ctl->dl_pow_off[CC_id] != 1)) { + for (j = 0; j < N_RBG[CC_id]; j++) { + if (MIMO_mode_indicator[CC_id][j] == 2) { + i1 = i1 + 1; + } else if (MIMO_mode_indicator[CC_id][j] == 1) { + i2 = i2 + 1; + } else if (MIMO_mode_indicator[CC_id][j] == 0) { + i3 = i3 + 1; + } + } - for (j = 0; j < N_RBG[CC_id]; j += 2) { + if ((i1 < N_RBG[CC_id]) && (i2 > 0) && (i3 == 0)) { + PHY_vars_eNB_g[Mod_id][CC_id]->check_for_SUMIMO_transmissions = + PHY_vars_eNB_g[Mod_id][CC_id]-> + check_for_SUMIMO_transmissions + 1; + } - if ((((j == (N_RBG[CC_id] - 1)) - && (rballoc_sub[CC_id][j] == 0) - && (ue_sched_ctl-> - rballoc_sub_UE[CC_id][j] == 0)) - || ((j < (N_RBG[CC_id] - 1)) - && (rballoc_sub[CC_id][j + 1] == 0) - && - (ue_sched_ctl->rballoc_sub_UE - [CC_id][j + 1] == 0))) - && (nb_rbs_required_remaining[CC_id][UE_id] - > 0)) { + if (i3 == N_RBG[CC_id] && i1 == 0 && i2 == 0) { + PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions = + PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions + + 1; + } - for (ii = UE_list->next[i + 1]; ii >= 0; - ii = UE_list->next[ii]) { + if ((i1 < N_RBG[CC_id]) && (i3 > 0)) { + PHY_vars_eNB_g[Mod_id][CC_id]->check_for_MUMIMO_transmissions = + PHY_vars_eNB_g[Mod_id][CC_id]-> + check_for_MUMIMO_transmissions + 1; + } - UE_id2 = ii; - rnti2 = UE_RNTI(Mod_id, UE_id2); - ue_sched_ctl2 = - &UE_list->UE_sched_ctrl[UE_id2]; - round2 = ue_sched_ctl2->round[CC_id]; - if (rnti2 == NOT_A_RNTI) - continue; - if (UE_list-> - UE_sched_ctrl - [UE_id2].ul_out_of_sync == 1) - continue; - - eNB_UE_stats2 = - UE_list-> - eNB_UE_stats[CC_id][UE_id2]; - //mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,frameP,subframeP,&harq_pid2,&round2,0); - - if ((mac_eNB_get_rrc_status - (Mod_id, - rnti2) >= RRC_RECONFIGURED) - && (round2 == 0) - && - (get_tmode(Mod_id, CC_id, UE_id2) - == 5) - && (ue_sched_ctl-> - dl_pow_off[CC_id] != 1)) { - - if ((((j == (N_RBG[CC_id] - 1)) - && - (ue_sched_ctl->rballoc_sub_UE - [CC_id][j] == 0)) - || ((j < (N_RBG[CC_id] - 1)) - && - (ue_sched_ctl-> - rballoc_sub_UE[CC_id][j + - 1] - == 0))) - && - (nb_rbs_required_remaining - [CC_id] - [UE_id2] > 0)) { - - if ((((eNB_UE_stats2-> - DL_pmi_single ^ - eNB_UE_stats1-> - DL_pmi_single) - << (14 - j)) & 0xc000) == 0x4000) { //MU-MIMO only for 25 RBs configuration - - rballoc_sub[CC_id][j] = 1; - ue_sched_ctl-> - rballoc_sub_UE[CC_id] - [j] = 1; - ue_sched_ctl2-> - rballoc_sub_UE[CC_id] - [j] = 1; - MIMO_mode_indicator[CC_id] - [j] = 0; - - if (j < N_RBG[CC_id] - 1) { - rballoc_sub[CC_id][j + - 1] = - 1; - ue_sched_ctl-> - rballoc_sub_UE - [CC_id][j + 1] = 1; - ue_sched_ctl2->rballoc_sub_UE - [CC_id][j + 1] = 1; - MIMO_mode_indicator - [CC_id][j + 1] - = 0; - } - - ue_sched_ctl-> - dl_pow_off[CC_id] - = 0; - ue_sched_ctl2-> - dl_pow_off[CC_id] - = 0; - - - if ((j == N_RBG[CC_id] - 1) - && ((N_RB_DL == 25) - || (N_RB_DL == - 50))) { - - nb_rbs_required_remaining - [CC_id][UE_id] = - nb_rbs_required_remaining - [CC_id][UE_id] - - min_rb_unit[CC_id] - + 1; - ue_sched_ctl->pre_nb_available_rbs - [CC_id] = - ue_sched_ctl->pre_nb_available_rbs - [CC_id] + - min_rb_unit[CC_id] - - 1; - nb_rbs_required_remaining - [CC_id][UE_id2] = - nb_rbs_required_remaining - [CC_id][UE_id2] - - min_rb_unit[CC_id] - + 1; - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] = - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] + - min_rb_unit[CC_id] - - 1; - } else { - - nb_rbs_required_remaining - [CC_id][UE_id] = - nb_rbs_required_remaining - [CC_id][UE_id] - 4; - ue_sched_ctl->pre_nb_available_rbs - [CC_id] = - ue_sched_ctl->pre_nb_available_rbs - [CC_id] + 4; - nb_rbs_required_remaining - [CC_id][UE_id2] = - nb_rbs_required_remaining - [CC_id][UE_id2] - - 4; - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] = - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] + 4; - } - - break; - } - } - } - } - } - } - } -#endif - } // total_ue_count - } - } - } // end of for for r1 and r2 - -#ifdef TM5 - - // This has to be revisited!!!! - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - i1 = 0; - i2 = 0; - i3 = 0; - - for (j = 0; j < N_RBG[CC_id]; j++) { - if (MIMO_mode_indicator[CC_id][j] == 2) { - i1 = i1 + 1; - } else if (MIMO_mode_indicator[CC_id][j] == 1) { - i2 = i2 + 1; - } else if (MIMO_mode_indicator[CC_id][j] == 0) { - i3 = i3 + 1; - } - } - - if ((i1 < N_RBG[CC_id]) && (i2 > 0) && (i3 == 0)) { - PHY_vars_eNB_g[Mod_id][CC_id]->check_for_SUMIMO_transmissions = - PHY_vars_eNB_g[Mod_id][CC_id]-> - check_for_SUMIMO_transmissions + 1; - } - - if (i3 == N_RBG[CC_id] && i1 == 0 && i2 == 0) { - PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions = - PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions + - 1; - } - - if ((i1 < N_RBG[CC_id]) && (i3 > 0)) { - PHY_vars_eNB_g[Mod_id][CC_id]->check_for_MUMIMO_transmissions = - PHY_vars_eNB_g[Mod_id][CC_id]-> - check_for_MUMIMO_transmissions + 1; - } - - PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions = - PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions + - 1; - - } + PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions = + PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions + + 1; + } #endif - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - UE_id = i; - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; - //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id]; + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { + CC_id = UE_list->ordered_CCids[i][UE_id]; + //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id]; - if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0) { - LOG_D(MAC, - "******************DL Scheduling Information for UE%d ************************\n", - UE_id); - LOG_D(MAC, "dl power offset UE%d = %d \n", UE_id, - ue_sched_ctl->dl_pow_off[CC_id]); - LOG_D(MAC, - "***********RB Alloc for every subband for UE%d ***********\n", - UE_id); + if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0) { + LOG_D(MAC, "******************DL Scheduling Information for UE%d ************************\n", UE_id); + LOG_D(MAC, "dl power offset UE%d = %d \n", UE_id, ue_sched_ctl->dl_pow_off[CC_id]); + LOG_D(MAC, "***********RB Alloc for every subband for UE%d ***********\n", UE_id); - for (j = 0; j < N_RBG[CC_id]; j++) { - //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[i] = rballoc_sub_UE[CC_id][UE_id][i]; - LOG_D(MAC, "RB Alloc for UE%d and Subband%d = %d\n", - UE_id, j, - ue_sched_ctl->rballoc_sub_UE[CC_id][j]); - } + for (j = 0; j < N_RBG[CC_id]; j++) { + //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[UE_id] = rballoc_sub_UE[CC_id][UE_id][UE_id]; + LOG_D(MAC, "RB Alloc for UE%d and Subband%d = %d\n", UE_id, j, ue_sched_ctl->rballoc_sub_UE[CC_id][j]); + } - //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id]; - LOG_D(MAC, "[eNB %d][SLICE %d]Total RBs allocated for UE%d = %d\n", Mod_id, slice_id, UE_id, - ue_sched_ctl->pre_nb_available_rbs[CC_id]); - } - } + //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id]; + LOG_D(MAC, "[eNB %d][SLICE %d]Total RBs allocated for UE%d = %d\n", + Mod_id, slice_id, UE_id, ue_sched_ctl->pre_nb_available_rbs[CC_id]); + } } + } } #define SF0_LIMIT 1 void dlsch_scheduler_pre_processor_reset(int module_idP, - int UE_id, - uint8_t CC_id, - int frameP, - int subframeP, - int N_RBG, - uint16_t nb_rbs_required[MAX_NUM_CCs] - [NUMBER_OF_UE_MAX], - uint16_t - nb_rbs_required_remaining - [MAX_NUM_CCs][NUMBER_OF_UE_MAX], - unsigned char total_ue_count[MAX_NUM_CCs], - unsigned char total_rbs_used[MAX_NUM_CCs], - unsigned char - rballoc_sub[MAX_NUM_CCs] - [N_RBG_MAX], - unsigned char - MIMO_mode_indicator[MAX_NUM_CCs] - [N_RBG_MAX]) + int UE_id, + uint8_t CC_id, + int frameP, + int subframeP, + int N_RBG, + uint16_t nb_rbs_required[MAX_NUM_CCs] + [NUMBER_OF_UE_MAX], + unsigned char + rballoc_sub[MAX_NUM_CCs] + [N_RBG_MAX], + unsigned char + MIMO_mode_indicator[MAX_NUM_CCs] + [N_RBG_MAX]) { - int i, j; - UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; - UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - rnti_t rnti = UE_RNTI(module_idP, UE_id); + int i, j; + UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; + UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + rnti_t rnti = UE_RNTI(module_idP, UE_id); - uint8_t *vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map; - int N_RB_DL = - to_prb(RC.mac[module_idP]->common_channels[CC_id].mib-> - message.dl_Bandwidth); - int RBGsize = N_RB_DL / N_RBG, RBGsize_last; + uint8_t *vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map; + int N_RB_DL = + to_prb(RC.mac[module_idP]->common_channels[CC_id].mib->message.dl_Bandwidth); + int RBGsize = N_RB_DL / N_RBG, RBGsize_last; #ifdef SF0_LIMIT - int sf0_upper = -1, sf0_lower = -1; + int sf0_upper = -1, sf0_lower = -1; #endif - LOG_D(MAC, "Running preprocessor for UE %d (%x)\n", UE_id, rnti); - // initialize harq_pid and round + LOG_D(MAC, "Running preprocessor for UE %d (%x)\n", UE_id, rnti); + // initialize harq_pid and round - if (ue_sched_ctl->ta_timer) - ue_sched_ctl->ta_timer--; + if (ue_sched_ctl->ta_timer) + ue_sched_ctl->ta_timer--; /* eNB_UE_stats *eNB_UE_stats; @@ -1234,95 +1237,96 @@ dlsch_scheduler_pre_processor_reset(int module_idP, } */ - nb_rbs_required[CC_id][UE_id] = 0; - ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0; - ue_sched_ctl->dl_pow_off[CC_id] = 2; - nb_rbs_required_remaining[CC_id][UE_id] = 0; - total_ue_count[CC_id]=0; - total_rbs_used[CC_id]=0; - switch (N_RB_DL) { + nb_rbs_required[CC_id][UE_id] = 0; + ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0; + ue_sched_ctl->dl_pow_off[CC_id] = 2; + + switch (N_RB_DL) { case 6: - RBGsize = 1; - RBGsize_last = 1; - break; + RBGsize = 1; + RBGsize_last = 1; + break; case 15: - RBGsize = 2; - RBGsize_last = 1; - break; + RBGsize = 2; + RBGsize_last = 1; + break; case 25: - RBGsize = 2; - RBGsize_last = 1; - break; + RBGsize = 2; + RBGsize_last = 1; + break; case 50: - RBGsize = 3; - RBGsize_last = 2; - break; + RBGsize = 3; + RBGsize_last = 2; + break; case 75: - RBGsize = 4; - RBGsize_last = 3; - break; + RBGsize = 4; + RBGsize_last = 3; + break; case 100: - RBGsize = 4; - RBGsize_last = 4; - break; + RBGsize = 4; + RBGsize_last = 4; + break; default: - AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); - } + AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); + } #ifdef SF0_LIMIT - switch (N_RBG) { + switch (N_RBG) { case 6: - sf0_lower = 0; - sf0_upper = 5; - break; + sf0_lower = 0; + sf0_upper = 5; + break; case 8: - sf0_lower = 2; - sf0_upper = 5; - break; + sf0_lower = 2; + sf0_upper = 5; + break; case 13: - sf0_lower = 4; - sf0_upper = 7; - break; + sf0_lower = 4; + sf0_upper = 7; + break; case 17: - sf0_lower = 7; - sf0_upper = 9; - break; + sf0_lower = 7; + sf0_upper = 9; + break; case 25: - sf0_lower = 11; - sf0_upper = 13; - break; + sf0_lower = 11; + sf0_upper = 13; + break; default: - AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); - } + AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); + } #endif - // Initialize Subbands according to VRB map - for (i = 0; i < N_RBG; i++) { - int rb_size = i == N_RBG - 1 ? RBGsize_last : RBGsize; - ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0; - rballoc_sub[CC_id][i] = 0; + // Initialize Subbands according to VRB map + for (i = 0; i < N_RBG; i++) { + int rb_size = i == N_RBG - 1 ? RBGsize_last : RBGsize; + + ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0; + rballoc_sub[CC_id][i] = 0; + #ifdef SF0_LIMIT - // for avoiding 6+ PRBs around DC in subframe 0 (avoid excessive errors) - /* TODO: make it proper - allocate those RBs, do not "protect" them, but - * compute number of available REs and limit MCS according to the - * TBS table 36.213 7.1.7.2.1-1 (can be done after pre-processor) - */ - if (subframeP == 0 && i >= sf0_lower && i <= sf0_upper) - rballoc_sub[CC_id][i] = 1; + // for avoiding 6+ PRBs around DC in subframe 0 (avoid excessive errors) + /* TODO: make it proper - allocate those RBs, do not "protect" them, but + * compute number of available REs and limit MCS according to the + * TBS table 36.213 7.1.7.2.1-1 (can be done after pre-processor) + */ + if (subframeP == 0 && i >= sf0_lower && i <= sf0_upper) + rballoc_sub[CC_id][i] = 1; #endif - // for SI-RNTI,RA-RNTI and P-RNTI allocations - for (j = 0; j < rb_size; j++) { - if (vrb_map[j + (i * RBGsize)] != 0) { - rballoc_sub[CC_id][i] = 1; - LOG_D(MAC, "Frame %d, subframe %d : vrb %d allocated\n", - frameP, subframeP, j + (i * RBGsize)); - break; - } - } - LOG_D(MAC, "Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n", - frameP, subframeP, CC_id, i, rballoc_sub[CC_id][i]); - MIMO_mode_indicator[CC_id][i] = 2; + + // for SI-RNTI,RA-RNTI and P-RNTI allocations + for (j = 0; j < rb_size; j++) { + if (vrb_map[j + (i * RBGsize)] != 0) { + rballoc_sub[CC_id][i] = 1; + LOG_D(MAC, "Frame %d, subframe %d : vrb %d allocated\n", + frameP, subframeP, j + (i * RBGsize)); + break; + } } + LOG_D(MAC, "Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n", + frameP, subframeP, CC_id, i, rballoc_sub[CC_id][i]); + MIMO_mode_indicator[CC_id][i] = 2; + } } diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/proto.h index 348b080d1e..07159f9c24 100644 --- a/openair2/LAYER2/MAC/proto.h +++ b/openair2/LAYER2/MAC/proto.h @@ -209,11 +209,6 @@ void dlsch_scheduler_pre_processor_reset(int module_idP, int UE_id, uint16_t nb_rbs_required[MAX_NUM_CCs] [NUMBER_OF_UE_MAX], - uint16_t - nb_rbs_required_remaining - [MAX_NUM_CCs][NUMBER_OF_UE_MAX], - unsigned char total_ue_count[MAX_NUM_CCs], - unsigned char total_rbs_used[MAX_NUM_CCs], unsigned char rballoc_sub[MAX_NUM_CCs] [N_RBG_MAX], From 9a9c867a7563e9c1089706de7cc59917ba19bbfd Mon Sep 17 00:00:00 2001 From: shahab SHARIAT BAGHERI Date: Tue, 20 Feb 2018 15:09:24 +0100 Subject: [PATCH 159/195] additional Mac stats and Improvements --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 97 ++++++++++- .../ENB_APP/MESSAGES/V2/stats_common.proto | 36 +++++ .../ENB_APP/MESSAGES/V2/stats_messages.proto | 7 +- openair2/ENB_APP/flexran_agent_ran_api.c | 150 +++++++++++++++++- openair2/ENB_APP/flexran_agent_ran_api.h | 72 +++++++++ openair2/LAYER2/MAC/defs.h | 13 ++ openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 7 + openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 1 + 8 files changed, 379 insertions(+), 4 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 230917f673..921ea50bc0 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -62,7 +62,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, // Protocol__FlexHeader *header; int i, j, k; - // int cc_id = 0; + int cc_id = 0; int enb_id = mod_id; /* Allocate memory for list of UE reports */ @@ -490,6 +490,101 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, } + if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_STATS) { + + Protocol__FlexMacStats *macstats; + macstats = malloc(sizeof(Protocol__FlexMacStats)); + if (macstats == NULL) + goto error; + protocol__flex_mac_stats__init(macstats); + + + macstats->total_bytes_sdus_dl = flexran_get_total_size_dl_mac_sdus(mod_id, i, cc_id); + macstats->has_total_bytes_sdus_dl = 1; + + macstats->total_bytes_sdus_ul = flexran_get_total_size_ul_mac_sdus(mod_id, i, cc_id); + macstats->has_total_bytes_sdus_ul = 1; + + macstats->tbs_dl = flexran_get_TBS_dl(mod_id, i, cc_id); + macstats->has_tbs_dl = 1; + + macstats->tbs_ul = flexran_get_TBS_ul(mod_id, i, cc_id); + macstats->has_tbs_ul = 1; + + macstats->prb_retx_dl = flexran_get_num_prb_retx_dl_per_ue(mod_id, i, cc_id); + macstats->has_prb_retx_dl = 1; + + macstats->prb_retx_ul = flexran_get_num_prb_retx_ul_per_ue(mod_id, i, cc_id); + macstats->has_prb_retx_ul = 1; + + macstats->prb_dl = flexran_get_num_prb_dl_tx_per_ue(mod_id, i, cc_id); + macstats->has_prb_dl = 1; + + macstats->prb_ul = flexran_get_num_prb_ul_rx_per_ue(mod_id, i, cc_id); + macstats->has_prb_ul = 1; + + macstats->mcs1_dl = flexran_get_mcs1_dl(mod_id, i, cc_id); + macstats->has_mcs1_dl = 1; + + macstats->mcs2_dl = flexran_get_mcs2_dl(mod_id, i, cc_id); + macstats->has_mcs2_dl = 1; + + macstats->mcs1_ul = flexran_get_mcs1_ul(mod_id, i, cc_id); + macstats->has_mcs1_ul = 1; + + macstats->mcs2_ul = flexran_get_mcs2_ul(mod_id, i, cc_id); + macstats->has_mcs2_ul = 1; + + macstats->total_prb_dl = flexran_get_total_prb_dl_tx_per_ue(mod_id, i, cc_id); + macstats->has_total_prb_dl = 1; + + macstats->total_prb_ul = flexran_get_total_prb_ul_rx_per_ue(mod_id, i, cc_id); + macstats->has_total_prb_ul = 1; + + macstats->total_pdu_dl = flexran_get_total_num_pdu_dl(mod_id, i, cc_id); + macstats->has_total_pdu_dl = 1; + + macstats->total_pdu_ul = flexran_get_total_num_pdu_ul(mod_id, i, cc_id); + macstats->has_total_pdu_ul = 1; + + macstats->total_tbs_dl = flexran_get_total_TBS_dl(mod_id, i, cc_id); + macstats->has_total_tbs_dl = 1; + + macstats->total_tbs_ul = flexran_get_total_TBS_ul(mod_id, i, cc_id); + macstats->has_total_tbs_ul = 1; + + macstats->harq_round = flexran_get_harq_round(mod_id, cc_id, i); + macstats->has_harq_round = 1; + + Protocol__FlexMacSdusDl ** mac_sdus; + mac_sdus = malloc(sizeof(Protocol__FlexMacSdusDl) * flexran_get_num_mac_sdu_tx(mod_id, i, cc_id)); + if (mac_sdus == NULL) + goto error; + + macstats->n_mac_sdus_dl = flexran_get_num_mac_sdu_tx(mod_id, i, cc_id); + + for (j = 0; j < macstats->n_mac_sdus_dl; j++){ + + + mac_sdus[j] = malloc(sizeof(Protocol__FlexMacSdusDl)); + protocol__flex_mac_sdus_dl__init(mac_sdus[j]); + + mac_sdus[j]->lcid = flexran_get_mac_sdu_lcid_index(mod_id, i, cc_id, j); + mac_sdus[j]->has_lcid = 1; + + mac_sdus[j]->sdu_length = flexran_get_mac_sdu_size(mod_id, i, cc_id, mac_sdus[j]->lcid); + mac_sdus[j]->has_sdu_length = 1; + + + } + + + macstats->mac_sdus_dl = mac_sdus; + + + ue_report[i]->mac_stats = macstats; + + } diff --git a/openair2/ENB_APP/MESSAGES/V2/stats_common.proto b/openair2/ENB_APP/MESSAGES/V2/stats_common.proto index f651195ab1..ee286981f5 100644 --- a/openair2/ENB_APP/MESSAGES/V2/stats_common.proto +++ b/openair2/ENB_APP/MESSAGES/V2/stats_common.proto @@ -269,3 +269,39 @@ message flex_pdcp_stats { optional uint64 sfn=17; } + +// +// MAC Stats +// + +message flex_mac_stats { + + optional uint32 tbs_dl = 1; + optional uint32 tbs_ul = 2; + optional uint32 prb_retx_dl = 3; + optional uint32 prb_retx_ul = 4; + optional uint32 prb_dl = 5; + optional uint32 prb_ul = 6; + optional uint32 mcs1_dl = 7; + optional uint32 mcs2_dl = 8; + optional uint32 mcs1_ul = 9; + optional uint32 mcs2_ul = 10; + optional uint32 total_bytes_sdus_ul = 11; + optional uint32 total_bytes_sdus_dl = 12; + optional uint32 total_prb_retx_dl = 13; + optional uint32 total_prb_retx_ul = 14; + optional uint32 total_prb_dl = 15; + optional uint32 total_prb_ul = 16; + optional uint32 total_pdu_dl = 17; + optional uint32 total_pdu_ul = 18; + optional uint32 total_tbs_dl = 19; + optional uint32 total_tbs_ul = 20; + repeated flex_mac_sdus_dl mac_sdus_dl = 21; + optional uint32 harq_round = 22; +} + +message flex_mac_sdus_dl { + + optional uint32 sdu_length = 1; + optional uint32 lcid = 2; +} diff --git a/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto b/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto index b8126c55f2..8eb6510de3 100644 --- a/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto +++ b/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto @@ -48,7 +48,8 @@ message flex_ue_stats_report { optional flex_paging_buffer_report pbr = 8; optional flex_ul_cqi_report ul_cqi_report = 9; optional flex_rrc_measurements rrc_measurements = 10; - optional flex_pdcp_stats pdcp_stats = 11; + optional flex_pdcp_stats pdcp_stats = 11; + optional flex_mac_stats mac_stats = 12; } // @@ -85,9 +86,11 @@ enum flex_ue_stats_type { FLUST_DL_CQI = 16; FLUST_PBS = 32; FLUST_UL_CQI = 64; + FLUST_MAC_STATS = 128; FLUST_PDCP_STATS = 1024; FLUST_RRC_MEASUREMENTS = 65536; // To be extended with more types of stats - + + } diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index c1743bf744..23b564d25e 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -132,7 +132,7 @@ int8_t flexran_get_ue_phr(mid_t mod_id, mid_t ue_id) uint8_t flexran_get_ue_wcqi(mid_t mod_id, mid_t ue_id) { if (!phy_is_present(mod_id, 0)) return 0; - return RC.eNB[mod_id][0]->UE_stats[ue_id].DL_cqi[0]; + return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].dl_cqi[0]; } rlc_buffer_occupancy_t flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) @@ -188,12 +188,160 @@ int32_t flexran_get_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id) } } +uint32_t flexran_get_total_size_dl_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id){ + + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_sdu_bytes; + +} + +uint32_t flexran_get_total_size_ul_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id){ + + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->eNB_stats[cc_id].total_ulsch_bytes_rx; + +} + + +uint32_t flexran_get_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id){ + + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].TBS; +} + +uint32_t flexran_get_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id){ + + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].ulsch_TBS; + +} + +uint16_t flexran_get_num_prb_retx_dl_per_ue(mid_t mod_id, mid_t ue_id, uint32_t cc_id) { + +if (!mac_is_present(mod_id)) return 0; +return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used_retx; + +} + +uint32_t flexran_get_num_prb_retx_ul_per_ue(mid_t mod_id, mid_t ue_id, uint32_t cc_id){ + + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used_retx_rx; + +} + +uint16_t flexran_get_num_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, uint32_t cc_id){ + +if (!mac_is_present(mod_id)) return 0; +return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used; + +} + +uint16_t flexran_get_num_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, uint32_t cc_id){ + +if (!mac_is_present(mod_id)) return 0; +return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used_rx; + +} + + uint8_t flexran_get_ue_wpmi(mid_t mod_id, mid_t ue_id, uint8_t cc_id) { if (!mac_is_present(mod_id)) return 0; return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].periodic_wideband_pmi[cc_id]; } +uint8_t flexran_get_mcs1_dl(mid_t mod_id, mid_t ue_id, int cc_id){ + + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].dlsch_mcs1; +} + +uint8_t flexran_get_mcs2_dl(mid_t mod_id, mid_t ue_id, int cc_id){ + + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].dlsch_mcs2; +} + +uint8_t flexran_get_mcs1_ul(mid_t mod_id, mid_t ue_id, int cc_id){ + + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].ulsch_mcs1; + +} + +uint8_t flexran_get_mcs2_ul(mid_t mod_id, mid_t ue_id, int cc_id){ + + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].ulsch_mcs2; + +} + +uint32_t flexran_get_total_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id){ + + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_rbs_used; + +} + +uint32_t flexran_get_total_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id){ + + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_rbs_used_rx; +} + +uint32_t flexran_get_total_num_pdu_dl(mid_t mod_id, mid_t ue_id, int cc_id){ + + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_num_pdus; +} + +uint32_t flexran_get_total_num_pdu_ul(mid_t mod_id, mid_t ue_id, int cc_id){ + + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_num_pdus_rx; +} + +uint64_t flexran_get_total_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id){ + + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_pdu_bytes; +} + +uint64_t flexran_get_total_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id){ + + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_ulsch_TBS; +} + +int flexran_get_harq_round(mid_t mod_id, uint8_t cc_id, mid_t ue_id){ + + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].harq_round; + +} + +uint32_t flexran_get_num_mac_sdu_tx(mid_t mod_id, mid_t ue_id, int cc_id){ + + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].num_mac_sdu_tx; + +} + +unsigned char flexran_get_mac_sdu_lcid_index(mid_t mod_id, mid_t ue_id, int cc_id, int index){ + + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].lcid_sdu[index]; +} + +uint32_t flexran_get_mac_sdu_size(mid_t mod_id, mid_t ue_id, int cc_id, int lcid){ + + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].sdu_length_tx[lcid]; + +} + + /* TODO needs to be revised */ void flexran_update_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id) { diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index aafb82077e..498da257b1 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -107,6 +107,78 @@ void flexran_update_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id); */ /* this function is broken */ int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id); +/*Get number of mac SDU DL*/ +uint32_t flexran_get_num_mac_sdu_tx(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Return the MAC sdu size got from logical channel lcid */ +uint32_t flexran_get_mac_sdu_size(mid_t mod_id, mid_t ue_id, int cc_id, int lcid); + +/*Return number of MAC SDUs obtained in MAC layer*/ +uint32_t flexran_get_num_mac_sdu_tx(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get mac sdu lcid index*/ +unsigned char flexran_get_mac_sdu_lcid_index(mid_t mod_id, mid_t ue_id, int cc_id, int index); + +/*Get MAC size sdus length dl*/ +uint32_t flexran_get_size_dl_mac_sdus(mid_t mod_id, uint32_t cc_id); + +/*Get MAC size sdus length ul */ +uint32_t flexran_get_size_ul_mac_sdus(mid_t mod_id, uint32_t cc_id); + +/*Get total size DL MAC SDUS*/ +uint32_t flexran_get_total_size_dl_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get total size of UL mac SDUS*/ +uint32_t flexran_get_total_size_ul_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get total number of PDU DL*/ +uint32_t flexran_get_total_num_pdu_dl(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get total number of PDU UL*/ +uint32_t flexran_get_total_num_pdu_ul(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get total PRB dl TODO Should be changed*/ +uint32_t flexran_get_total_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get total PRB ul TODO Should be changed*/ +uint32_t flexran_get_total_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get number of prb for tx per UE DL*/ +uint16_t flexran_get_num_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, uint32_t cc_id); + +/*Get number of prb for rx per UE UL*/ +uint16_t flexran_get_num_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, uint32_t cc_id); + +/*Get number of prb for retx per UE UL*/ +uint32_t flexran_get_num_prb_retx_ul_per_ue(mid_t mod_id, mid_t ue_id, uint32_t cc_id); + +/*Get number of prb for retx per UE*/ +uint16_t flexran_get_num_prb_retx_dl_per_ue(mid_t mod_id, mid_t ue_id, uint32_t cc_id); + +/*MCS before rate adaptation DL*/ +uint8_t flexran_get_mcs1_dl(mid_t mod_id, mid_t ue_id, int cc_id); + +/*MCS after rate adaptation DL*/ +uint8_t flexran_get_mcs2_dl(mid_t mod_id, mid_t ue_id, int cc_id); + +/*MCS before rate adaptation UL*/ +uint8_t flexran_get_mcs1_ul(mid_t mod_id, mid_t ue_id, int cc_id); + +/*MCS after rate adaptation UL*/ +uint8_t flexran_get_mcs2_ul(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get downlink TBS*/ +uint32_t flexran_get_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get uplink TBS */ +uint32_t flexran_get_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get total TBS DL*/ +uint64_t flexran_get_total_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get total TBS DL*/ +uint64_t flexran_get_total_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id); + /* Get the number of active component carriers for a specific UE */ int flexran_get_active_CC(mid_t mod_id, mid_t ue_id); diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index ef1d710138..640cb67294 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -562,6 +562,13 @@ typedef struct { uint32_t num_retransmission; /// instantaneous tx throughput for each TTI // uint32_t tti_throughput[NB_RB_MAX]; + // Number of received MAC SDU + uint32_t num_mac_sdu_tx; + // LCID related to SDU + unsigned char lcid_sdu[NB_RB_MAX]; + // Length of SDU Got from LC DL + uint32_t sdu_length_tx[NB_RB_MAX]; + /// overall // @@ -607,6 +614,8 @@ typedef struct { /// uplink transport block size uint32_t ulsch_TBS; + + uint32_t total_ulsch_TBS; /// total rb used for a new uplink transmission uint32_t num_retransmission_rx; @@ -648,6 +657,10 @@ typedef struct { uint32_t total_num_pdus_rx; /// num of error pdus uint32_t total_num_errors_rx; + // Number of error PDUS + uint32_t num_mac_sdu_rx; + // Length of SDU Got from LC UL - Size array can be refined + uint32_t sdu_length_rx[NB_RB_MAX]; } eNB_UE_STATS; /*! \brief eNB template for UE context information */ diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 48b19b0919..7e6eee0f87 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -1036,6 +1036,8 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, module_idP, CC_id, sdu_lengths[0]); sdu_length_total = sdu_lengths[0]; sdu_lcids[0] = DCCH; + UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[0] = DCCH; + UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[DCCH] = sdu_lengths[0]; UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH] += 1; UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH] += sdu_lengths[0]; num_sdus = 1; @@ -1079,6 +1081,8 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, sdu_lcids[num_sdus] = DCCH1; sdu_length_total += sdu_lengths[num_sdus]; header_len_dcch += 2; + UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = DCCH1; + UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[DCCH1] = sdu_lengths[num_sdus]; UE_list->eNB_UE_stats[CC_id][UE_id]. num_pdu_tx[DCCH1] += 1; UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1] += sdu_lengths[num_sdus]; @@ -1153,6 +1157,8 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, UE_list-> eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid] += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = lcid; + UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[lcid] = sdu_lengths[num_sdus]; UE_list-> eNB_UE_stats[CC_id][UE_id].num_bytes_tx [lcid] += sdu_lengths[num_sdus]; @@ -1355,6 +1361,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, eNB->eNB_stats[CC_id].dlsch_pdus_tx += 1; UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].num_mac_sdu_tx = num_sdus; UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used += nb_rb; UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = mcs; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index ac87498560..b4fb025ea4 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -1315,6 +1315,7 @@ schedule_ulsch_rnti(module_id_t module_idP, rb_table[rb_table_index]); UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += rb_table[rb_table_index]; UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = UE_template->TBS_UL[harq_pid]; + UE_list->eNB_UE_stats[CC_id][UE_id].total_ulsch_TBS += UE_template->TBS_UL[harq_pid]; // buffer_occupancy -= TBS; T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP), From 1e2a7156e0b03de8e89814581db38ffb588456c2 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 22 Feb 2018 11:54:16 +0100 Subject: [PATCH 160/195] test setup v2: minor bugfix --- cmake_targets/autotests/v2/connection.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake_targets/autotests/v2/connection.py b/cmake_targets/autotests/v2/connection.py index 1952b8b72f..3a254f89b8 100644 --- a/cmake_targets/autotests/v2/connection.py +++ b/cmake_targets/autotests/v2/connection.py @@ -13,7 +13,7 @@ class connection: try: (pid, fd) = os.forkpty() except BaseException, e: - log("ERROR: forkpty for '" + description + "': " + e) + log("ERROR: forkpty for '" + description + "': " + str(e)) (pid, fd) = (-1, -1) if pid == -1: @@ -26,7 +26,7 @@ class connection: os.execvp('sshpass', ['sshpass', '-p', password, 'ssh', user + '@' + host]) except BaseException, e: - log("ERROR: execvp for '" + description + "': " + e) + log("ERROR: execvp for '" + description + "': " + str(e)) log("ERROR: execvp failed for '" + description + "'") os._exit(1) From e66bd0e2b1e1c65730477b40a09f73f371870608 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 22 Feb 2018 12:03:10 +0100 Subject: [PATCH 161/195] RAN API: unify style, declare missing function in header --- openair2/ENB_APP/flexran_agent_ran_api.c | 121 ++++++++++------------- openair2/ENB_APP/flexran_agent_ran_api.h | 15 +-- 2 files changed, 62 insertions(+), 74 deletions(-) diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 23b564d25e..61757d0703 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -188,157 +188,142 @@ int32_t flexran_get_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id) } } -uint32_t flexran_get_total_size_dl_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id){ - +uint32_t flexran_get_total_size_dl_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id) +{ if (!mac_is_present(mod_id)) return 0; return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_sdu_bytes; - } -uint32_t flexran_get_total_size_ul_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id){ - - if (!mac_is_present(mod_id)) return 0; +uint32_t flexran_get_total_size_ul_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; return RC.mac[mod_id]->eNB_stats[cc_id].total_ulsch_bytes_rx; - } - -uint32_t flexran_get_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id){ - +uint32_t flexran_get_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id) +{ if (!mac_is_present(mod_id)) return 0; return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].TBS; } -uint32_t flexran_get_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id){ - +uint32_t flexran_get_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id) +{ if (!mac_is_present(mod_id)) return 0; return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].ulsch_TBS; - } -uint16_t flexran_get_num_prb_retx_dl_per_ue(mid_t mod_id, mid_t ue_id, uint32_t cc_id) { - -if (!mac_is_present(mod_id)) return 0; -return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used_retx; - +uint16_t flexran_get_num_prb_retx_dl_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used_retx; } -uint32_t flexran_get_num_prb_retx_ul_per_ue(mid_t mod_id, mid_t ue_id, uint32_t cc_id){ - +uint32_t flexran_get_num_prb_retx_ul_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) +{ if (!mac_is_present(mod_id)) return 0; return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used_retx_rx; - } -uint16_t flexran_get_num_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, uint32_t cc_id){ - -if (!mac_is_present(mod_id)) return 0; -return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used; - +uint16_t flexran_get_num_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used; } -uint16_t flexran_get_num_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, uint32_t cc_id){ - -if (!mac_is_present(mod_id)) return 0; -return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used_rx; - +uint16_t flexran_get_num_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used_rx; } - uint8_t flexran_get_ue_wpmi(mid_t mod_id, mid_t ue_id, uint8_t cc_id) { if (!mac_is_present(mod_id)) return 0; return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].periodic_wideband_pmi[cc_id]; } -uint8_t flexran_get_mcs1_dl(mid_t mod_id, mid_t ue_id, int cc_id){ - +uint8_t flexran_get_mcs1_dl(mid_t mod_id, mid_t ue_id, int cc_id) +{ if (!mac_is_present(mod_id)) return 0; return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].dlsch_mcs1; } -uint8_t flexran_get_mcs2_dl(mid_t mod_id, mid_t ue_id, int cc_id){ - +uint8_t flexran_get_mcs2_dl(mid_t mod_id, mid_t ue_id, int cc_id) +{ if (!mac_is_present(mod_id)) return 0; return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].dlsch_mcs2; } -uint8_t flexran_get_mcs1_ul(mid_t mod_id, mid_t ue_id, int cc_id){ - +uint8_t flexran_get_mcs1_ul(mid_t mod_id, mid_t ue_id, int cc_id) +{ if (!mac_is_present(mod_id)) return 0; return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].ulsch_mcs1; - } -uint8_t flexran_get_mcs2_ul(mid_t mod_id, mid_t ue_id, int cc_id){ - +uint8_t flexran_get_mcs2_ul(mid_t mod_id, mid_t ue_id, int cc_id) +{ if (!mac_is_present(mod_id)) return 0; return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].ulsch_mcs2; - } -uint32_t flexran_get_total_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id){ - +uint32_t flexran_get_total_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) +{ if (!mac_is_present(mod_id)) return 0; return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_rbs_used; - } -uint32_t flexran_get_total_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id){ - +uint32_t flexran_get_total_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) +{ if (!mac_is_present(mod_id)) return 0; return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_rbs_used_rx; } -uint32_t flexran_get_total_num_pdu_dl(mid_t mod_id, mid_t ue_id, int cc_id){ - +uint32_t flexran_get_total_num_pdu_dl(mid_t mod_id, mid_t ue_id, int cc_id) +{ if (!mac_is_present(mod_id)) return 0; return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_num_pdus; } -uint32_t flexran_get_total_num_pdu_ul(mid_t mod_id, mid_t ue_id, int cc_id){ - +uint32_t flexran_get_total_num_pdu_ul(mid_t mod_id, mid_t ue_id, int cc_id) +{ if (!mac_is_present(mod_id)) return 0; return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_num_pdus_rx; } -uint64_t flexran_get_total_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id){ - +uint64_t flexran_get_total_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id) +{ if (!mac_is_present(mod_id)) return 0; return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_pdu_bytes; } -uint64_t flexran_get_total_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id){ - +uint64_t flexran_get_total_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id) +{ if (!mac_is_present(mod_id)) return 0; return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_ulsch_TBS; } -int flexran_get_harq_round(mid_t mod_id, uint8_t cc_id, mid_t ue_id){ - +int flexran_get_harq_round(mid_t mod_id, uint8_t cc_id, mid_t ue_id) +{ if (!mac_is_present(mod_id)) return 0; return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].harq_round; - } -uint32_t flexran_get_num_mac_sdu_tx(mid_t mod_id, mid_t ue_id, int cc_id){ - - if (!mac_is_present(mod_id)) return 0; - return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].num_mac_sdu_tx; - +uint32_t flexran_get_num_mac_sdu_tx(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].num_mac_sdu_tx; } -unsigned char flexran_get_mac_sdu_lcid_index(mid_t mod_id, mid_t ue_id, int cc_id, int index){ - +unsigned char flexran_get_mac_sdu_lcid_index(mid_t mod_id, mid_t ue_id, int cc_id, int index) +{ if (!mac_is_present(mod_id)) return 0; return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].lcid_sdu[index]; } -uint32_t flexran_get_mac_sdu_size(mid_t mod_id, mid_t ue_id, int cc_id, int lcid){ - +uint32_t flexran_get_mac_sdu_size(mid_t mod_id, mid_t ue_id, int cc_id, int lcid) +{ if (!mac_is_present(mod_id)) return 0; return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].sdu_length_tx[lcid]; - } diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 498da257b1..0550722394 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -120,10 +120,10 @@ uint32_t flexran_get_num_mac_sdu_tx(mid_t mod_id, mid_t ue_id, int cc_id); unsigned char flexran_get_mac_sdu_lcid_index(mid_t mod_id, mid_t ue_id, int cc_id, int index); /*Get MAC size sdus length dl*/ -uint32_t flexran_get_size_dl_mac_sdus(mid_t mod_id, uint32_t cc_id); +uint32_t flexran_get_size_dl_mac_sdus(mid_t mod_id, int cc_id); /*Get MAC size sdus length ul */ -uint32_t flexran_get_size_ul_mac_sdus(mid_t mod_id, uint32_t cc_id); +uint32_t flexran_get_size_ul_mac_sdus(mid_t mod_id, int cc_id); /*Get total size DL MAC SDUS*/ uint32_t flexran_get_total_size_dl_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id); @@ -144,16 +144,16 @@ uint32_t flexran_get_total_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id uint32_t flexran_get_total_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id); /*Get number of prb for tx per UE DL*/ -uint16_t flexran_get_num_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, uint32_t cc_id); +uint16_t flexran_get_num_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id); /*Get number of prb for rx per UE UL*/ -uint16_t flexran_get_num_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, uint32_t cc_id); +uint16_t flexran_get_num_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id); /*Get number of prb for retx per UE UL*/ -uint32_t flexran_get_num_prb_retx_ul_per_ue(mid_t mod_id, mid_t ue_id, uint32_t cc_id); +uint32_t flexran_get_num_prb_retx_ul_per_ue(mid_t mod_id, mid_t ue_id, int cc_id); /*Get number of prb for retx per UE*/ -uint16_t flexran_get_num_prb_retx_dl_per_ue(mid_t mod_id, mid_t ue_id, uint32_t cc_id); +uint16_t flexran_get_num_prb_retx_dl_per_ue(mid_t mod_id, mid_t ue_id, int cc_id); /*MCS before rate adaptation DL*/ uint8_t flexran_get_mcs1_dl(mid_t mod_id, mid_t ue_id, int cc_id); @@ -179,6 +179,9 @@ uint64_t flexran_get_total_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id); /*Get total TBS DL*/ uint64_t flexran_get_total_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id); +/* Get the current HARQ round for UE ue_id */ +int flexran_get_harq_round(mid_t mod_id, uint8_t cc_id, mid_t ue_id); + /* Get the number of active component carriers for a specific UE */ int flexran_get_active_CC(mid_t mod_id, mid_t ue_id); From 58eab7515f8b5c3461c5a04aac43cc1b87732c6b Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 21 Feb 2018 11:21:56 +0100 Subject: [PATCH 162/195] integration fix: fix crash With value 4 when connecting one UE and doing some downlink iperf TCP there is a crash. Probably due to the multiple wrong RA detected leading to uplink failure of fake UE that never sends Msg3 (because, well, there is no other UE). This is another problem that will be fixed at some point. Anyway, this value 4 fails. Let's put back 3. --- openair1/SCHED/phy_procedures_lte_eNb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index f70cd85725..496767ca4d 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -1272,7 +1272,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) ulsch_harq->o_ACK[0], ulsch_harq->o_ACK[1]); - if (ulsch_harq->round >= 4) { + if (ulsch_harq->round >= 3) { ulsch_harq->status = SCH_IDLE; ulsch_harq->handled = 0; ulsch->harq_mask &= ~(1 << harq_pid); From 8ca5fb4ef280090ecdca4f151816b5950d075d50 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 21 Feb 2018 11:53:13 +0100 Subject: [PATCH 163/195] integration: cleanup - remove spaces at the end of lines - remove useless dead code use: git show -p -w to see it clearly --- openair1/PHY/CODING/lte_rate_matching.c | 8 +- openair1/PHY/INIT/defs.h | 4 +- openair1/PHY/INIT/lte_init_ru.c | 5 - openair1/PHY/INIT/lte_param_init.c | 8 +- .../lte_ul_channel_estimation.c | 3 - openair1/PHY/LTE_TRANSPORT/dci.c | 54 +++-- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 6 - openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c | 5 - .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 9 +- openair1/PHY/LTE_TRANSPORT/drs_modulation.c | 2 +- openair1/PHY/MODULATION/slot_fep_ul.c | 3 - openair1/SCHED/fapi_l1.c | 8 +- openair1/SCHED/phy_procedures_lte_eNb.c | 5 - openair1/SCHED/phy_procedures_lte_ue.c | 6 +- openair1/SCHED/ru_procedures.c | 2 +- openair1/SIMULATION/LTE_PHY/dlsim.c | 62 +++--- openair1/SIMULATION/LTE_PHY/ulsim.c | 56 +++--- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 184 +++++++++--------- openair2/LAYER2/MAC/defs.h | 76 ++++---- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 22 +-- 20 files changed, 240 insertions(+), 288 deletions(-) diff --git a/openair1/PHY/CODING/lte_rate_matching.c b/openair1/PHY/CODING/lte_rate_matching.c index f96e5dbb17..41c3c5e5a9 100644 --- a/openair1/PHY/CODING/lte_rate_matching.c +++ b/openair1/PHY/CODING/lte_rate_matching.c @@ -463,7 +463,7 @@ uint32_t lte_rate_matching_turbo(uint32_t RTC, uint8_t Qm, uint8_t Nl, uint8_t r, - uint8_t nb_rb) + uint8_t nb_rb) // uint8_t m) { @@ -513,7 +513,7 @@ uint32_t lte_rate_matching_turbo(uint32_t RTC, // counter_buffer[rvidx][cnt]=0; if (Ncb>(3*(RTC<<5))) AssertFatal(1==0,"Exiting, RM condition (Ncb %d, RTC %d, Nir/C %d, Nsoft %d, Kw %d)\n",Ncb,RTC,Nir/C,Nsoft,3*(RTC<<5)); - + AssertFatal(Nl>0,"Nl is 0\n"); AssertFatal(Qm>0,"Qm is 0\n"); Gp = G/Nl/Qm; @@ -750,8 +750,8 @@ int lte_rate_matching_turbo_rx(uint32_t RTC, for (; (ind0 && soft_input2[k]<0) || - (w[ind]<0 && soft_input2[k]>0)) + if ((w[ind]>0 && soft_input2[k]<0) || + (w[ind]<0 && soft_input2[k]>0)) printf("ind %d: w %d => soft_in %d\n",ind,w[ind],soft_input2[k]);*/ w[ind] += soft_input2[k++]; #ifdef RM_DEBUG diff --git a/openair1/PHY/INIT/defs.h b/openair1/PHY/INIT/defs.h index 2c92503133..be3e5c160b 100644 --- a/openair1/PHY/INIT/defs.h +++ b/openair1/PHY/INIT/defs.h @@ -333,13 +333,13 @@ void init_lte_top(LTE_DL_FRAME_PARMS *lte_frame_parms); void lte_param_init(PHY_VARS_eNB **eNBp, PHY_VARS_UE **UEp, RU_t **rup, - unsigned char N_tx_port_eNB, + unsigned char N_tx_port_eNB, unsigned char N_tx_phy, unsigned char N_rx_ru, unsigned char N_rx_ue, unsigned char transmission_mode, uint8_t extended_prefix_flag, - frame_t frame_type, + frame_t frame_type, uint16_t Nid_cell, uint8_t tdd_config, uint8_t N_RB_DL, diff --git a/openair1/PHY/INIT/lte_init_ru.c b/openair1/PHY/INIT/lte_init_ru.c index f6c4d0709a..9168193074 100644 --- a/openair1/PHY/INIT/lte_init_ru.c +++ b/openair1/PHY/INIT/lte_init_ru.c @@ -32,11 +32,6 @@ #include "assertions.h" #include -#undef LOG_I -#define LOG_I(A,B,C...) printf(B,C) -#undef LOG_D -#define LOG_D(A,B,C...) printf(B,C) - int phy_init_RU(RU_t *ru) { LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; diff --git a/openair1/PHY/INIT/lte_param_init.c b/openair1/PHY/INIT/lte_param_init.c index c09652db93..1743a8d90c 100644 --- a/openair1/PHY/INIT/lte_param_init.c +++ b/openair1/PHY/INIT/lte_param_init.c @@ -37,13 +37,13 @@ extern RU_t *ru; void lte_param_init(PHY_VARS_eNB **eNBp, PHY_VARS_UE **UEp, RU_t **rup, - unsigned char N_tx_port_eNB, + unsigned char N_tx_port_eNB, unsigned char N_tx_phy, unsigned char N_rx_ru, unsigned char N_rx_ue, unsigned char transmission_mode, uint8_t extended_prefix_flag, - frame_t frame_type, + frame_t frame_type, uint16_t Nid_cell, uint8_t tdd_config, uint8_t N_RB_DL, @@ -142,7 +142,7 @@ void lte_param_init(PHY_VARS_eNB **eNBp, // DL power control init //if (transmission_mode == 1) { - UE->pdsch_config_dedicated->p_a = pa; + UE->pdsch_config_dedicated->p_a = pa; if (transmission_mode == 1 || transmission_mode ==7) { ((eNB->frame_parms).pdsch_config_common).p_b = 0; @@ -161,7 +161,7 @@ void lte_param_init(PHY_VARS_eNB **eNBp, if (eNB->frame_parms.N_RB_DL == 100) ru->N_TA_offset = 624; else if (eNB->frame_parms.N_RB_DL == 50) ru->N_TA_offset = 624/2; else if (eNB->frame_parms.N_RB_DL == 25) ru->N_TA_offset = 624/4; - } + } else ru->N_TA_offset=0; printf("Done lte_param_init\n"); diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c index 9eb34a8905..9c91d28ade 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c @@ -34,9 +34,6 @@ static int16_t ru_90c[2*128] = {32767, 0,32766, -402,32758, -804,32746, -1206,32 #define SCALE 0x3FFF -//#undef LOG_D -//#define LOG_D(A,B,C...) printf(B,C) - int32_t lte_ul_channel_estimation(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, uint8_t UE_id, diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c index f75ae326e9..94d6cd9c3f 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci.c +++ b/openair1/PHY/LTE_TRANSPORT/dci.c @@ -35,10 +35,10 @@ #include "PHY/defs.h" #include "PHY/extern.h" #include "SCHED/defs.h" -#include "SIMULATION/TOOLS/defs.h" // for taus +#include "SIMULATION/TOOLS/defs.h" // for taus #include "PHY/sse_intrin.h" -#include "assertions.h" +#include "assertions.h" #include "T.h" #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" @@ -52,9 +52,6 @@ //extern uint16_t phich_reg[MAX_NUM_PHICH_GROUPS][3]; //extern uint16_t pcfich_reg[4]; -//#undef LOG_D -//#define LOG_D(A,B,C...) printf(B,C) - uint32_t check_phich_reg(LTE_DL_FRAME_PARMS *frame_parms,uint32_t kprime,uint8_t lprime,uint8_t mi) { @@ -155,7 +152,7 @@ uint16_t extract_crc(uint8_t *dci,uint8_t dci_len) // dci[(dci_len>>3)+1] = 0; // dci[(dci_len>>3)+2] = 0; return((uint16_t)crc16); - + } @@ -218,10 +215,10 @@ uint8_t *generate_dci0(uint8_t *dci, uint16_t coded_bits; uint8_t dci_flip[8]; - AssertFatal((aggregation_level==1) || - (aggregation_level==2) || - (aggregation_level==4) || - (aggregation_level==8) + AssertFatal((aggregation_level==1) || + (aggregation_level==2) || + (aggregation_level==4) || + (aggregation_level==8) #ifdef Rel14 // Added for EPDCCH/MPDCCH || (aggregation_level==16) || @@ -230,17 +227,17 @@ uint8_t *generate_dci0(uint8_t *dci, #endif , "generate_dci FATAL, illegal aggregation_level %d\n",aggregation_level); - + coded_bits = 72 * aggregation_level; - + #ifdef DEBUG_DCI_ENCODING for (int i=0;i<1+((DCI_LENGTH+16)/8);i++) printf("i %d : %x\n",i,dci[i]); #endif - + if (DCI_LENGTH<=32) { dci_flip[0] = dci[3]; dci_flip[1] = dci[2]; @@ -480,7 +477,7 @@ void pdcch_deinterleaving(LTE_DL_FRAME_PARMS *frame_parms,uint16_t *z, uint16_t wptr[1] = wptr2[1]; wptr[2] = wptr2[2]; wptr[3] = wptr2[3]; - /* + /* printf("pdcch_deinterleaving (%p,%p): quad %d (%d) -> (%d,%d %d,%d %d,%d %d,%d)\n",wptr,wptr2,i,(i+frame_parms->Nid_cell)%Mquad, ((char*)wptr2)[0], ((char*)wptr2)[1], @@ -519,7 +516,7 @@ void pdcch_deinterleaving(LTE_DL_FRAME_PARMS *frame_parms,uint16_t *z, uint16_t zptr[2] = wptr[2]; zptr[3] = wptr[3]; - /* + /* printf("deinterleaving ; k %d, index-Nd %d => (%d,%d,%d,%d,%d,%d,%d,%d)\n",k,(index-ND), ((int8_t *)wptr)[0], ((int8_t *)wptr)[1], @@ -540,7 +537,7 @@ void pdcch_deinterleaving(LTE_DL_FRAME_PARMS *frame_parms,uint16_t *z, uint16_t for (i=0; i (%d,%d,%d,%d,%d,%d,%d,%d)\n",i, ((int8_t *)zptr)[0], ((int8_t *)zptr)[1], @@ -550,7 +547,7 @@ void pdcch_deinterleaving(LTE_DL_FRAME_PARMS *frame_parms,uint16_t *z, uint16_t ((int8_t *)zptr)[5], ((int8_t *)zptr)[6], ((int8_t *)zptr)[7]); - */ + */ } } @@ -1513,7 +1510,7 @@ void pdcch_channel_compensation(int32_t **rxdataF_ext, dl_ch128_2 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; #elif defined(__arm__) - + #endif for (rb=0; rbN_RB_DL; rb++) { #if defined(__x86_64__) || defined(__i386__) @@ -2114,7 +2111,7 @@ void pdcch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms, reset = 0; } - + // printf("unscrambling %d : e %d, c %d => ",i,llr[i],((s>>(i&0x1f))&1)); if (((s>>(i%32))&1)==0) llr[i] = -llr[i]; @@ -2348,7 +2345,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, for (i=0; iframe_parms, - get_mi(&RC.eNB[Mod_id][CC_id]->frame_parms,subframe))); + get_mi(&RC.eNB[Mod_id][CC_id]->frame_parms,subframe))); } int get_nCCE_offset_l1(int *CCE_table, - const unsigned char L, - const int nCCE, - const int common_dci, - const unsigned short rnti, + const unsigned char L, + const int nCCE, + const int common_dci, + const unsigned short rnti, const unsigned char subframe) { @@ -2700,7 +2697,7 @@ int get_nCCE_offset_l1(int *CCE_table, break; } } - + if (search_space_free == 1) { // printf("returning %d\n",m*L); @@ -3023,7 +3020,7 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars, return; } // rnti match } // CCEmap_cand == 0 -/* +/* if ( agregationLevel != 0xFF && (format_c == format0 && m==0 && si_rnti != SI_RNTI)) { @@ -4246,6 +4243,3 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, return(dci_cnt); } - - - diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index dd4228a9f9..4b73de6fcc 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -44,12 +44,6 @@ #include "LAYER2/MAC/extern.h" #include "LAYER2/MAC/defs.h" -/*#undef LOG_D -#define LOG_D(A,B,C...) printf(B,C) -#undef LOG_I -#define LOG_I(A,B,C...) printf(B,C) -*/ - //#define DEBUG_DCI uint32_t localRIV2alloc_LUT6[32]; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c index 71399c2652..697164110b 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c @@ -39,11 +39,6 @@ //#define DEBUG_DLSCH_DECODING //#define UE_DEBUG_TRACE 1 -//#undef LOG_D -//#define LOG_D(A,B,C...) printf(B,C) -//#undef LOG_I -//#define LOG_I(A,B,C...) printf(B,C) - extern double cpuf; void free_ue_dlsch(LTE_UE_DLSCH_t *dlsch) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 062cb8d299..1becc98752 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -48,11 +48,6 @@ int16_t interf_unaw_shift = 13; //#define DEBUG_HARQ -//#undef LOG_D -//#define LOG_D(A,B,C...) printf(B,C) -//#undef LOG_I -//#define LOG_I(A,B,C...) printf(B,C) - #define DEBUG_PHY 1 //#define DEBUG_DLSCH_DEMOD 1 @@ -847,7 +842,7 @@ int rx_pdsch(PHY_VARS_UE *ue, pllr_symbol_cw1 = (int8_t*)pdsch_vars[eNB_id]->llr[1]; pllr_symbol_cw0 += llr_offset_symbol; pllr_symbol_cw1 += llr_offset_symbol; - + LOG_I(PHY,"compute LLRs [AbsSubframe %d.%d-%d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %x @LLR Buff(symb) %x\n", frame, subframe,symbol, nb_rb,dlsch0_harq->Qm, @@ -855,7 +850,7 @@ int rx_pdsch(PHY_VARS_UE *ue, pdsch_vars[eNB_id]->llr_offset[symbol], (int16_t*)pdsch_vars[eNB_id]->llr[0], pllr_symbol_cw0); - + switch (dlsch0_harq->Qm) { case 2 : if ((rx_type==rx_standard) || (codeword_TB1 == -1)) { diff --git a/openair1/PHY/LTE_TRANSPORT/drs_modulation.c b/openair1/PHY/LTE_TRANSPORT/drs_modulation.c index 101954ca3d..a0bde219b5 100644 --- a/openair1/PHY/LTE_TRANSPORT/drs_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/drs_modulation.c @@ -94,7 +94,7 @@ int generate_drs_pusch(PHY_VARS_UE *ue, lsymbols_per_tti; l += (7 - frame_parms->Ncp),u=u1,v=v1,cyclic_shift=cyclic_shift1) { - drs_offset = 0; + drs_offset = 0; #ifdef DEBUG_DRS printf("drs_modulation: Msc_RS = %d, Msc_RS_idx = %d, u=%d,v=%d\n",Msc_RS, Msc_RS_idx,u,v); #endif diff --git a/openair1/PHY/MODULATION/slot_fep_ul.c b/openair1/PHY/MODULATION/slot_fep_ul.c index 844d15a87e..f41fc98791 100644 --- a/openair1/PHY/MODULATION/slot_fep_ul.c +++ b/openair1/PHY/MODULATION/slot_fep_ul.c @@ -24,9 +24,6 @@ #include "defs.h" //#define DEBUG_FEP -//#undef LOG_D -//#define LOG_D(A,B,C...) printf(B,C) - int slot_fep_ul(RU_t *ru, unsigned char l, unsigned char Ns, diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c index 6d7132c091..dbefe62747 100644 --- a/openair1/SCHED/fapi_l1.c +++ b/openair1/SCHED/fapi_l1.c @@ -37,12 +37,6 @@ #include "nfapi_interface.h" #include "fapi_l1.h" -/*#undef LOG_D -#define LOG_D(A,B,C...) printf(B,C) -#undef LOG_I -#define LOG_I(A,B,C...) printf(B,C) -*/ - int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req); int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req); int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req); @@ -539,7 +533,7 @@ void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, int8_t UE_id; // check if we have received a dci for this ue and ulsch descriptor is configured - + if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) { AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0, "No existing UE ULSCH for rnti %x\n",rel8->rnti); diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 496767ca4d..105dac0808 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -50,11 +50,6 @@ # include "intertask_interface.h" #endif -/* -#undef LOG_D -#define LOG_D(A,B,C...) printf(B,C) -*/ - extern uint8_t nfapi_mode; int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index d1097503ea..2635649589 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -73,10 +73,6 @@ extern double cpuf; -//#undef LOG_D -//#define LOG_D(A,B,C...) printf(B,C) - - void Msg1_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id); void Msg3_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id); @@ -1301,7 +1297,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt #endif nsymb>>1, &ue->frame_parms); - + normal_prefix_mod(&ue->common_vars.txdataF[aa][((subframe_tx*nsymb)+(nsymb>>1))*frame_parms->ofdm_symbol_size], #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) dummy_tx_buffer+(frame_parms->samples_per_tti>>1), diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c index 0aad195d43..b00a9e2039 100644 --- a/openair1/SCHED/ru_procedures.c +++ b/openair1/SCHED/ru_procedures.c @@ -536,7 +536,7 @@ void fep_full(RU_t *ru) { start_meas(&ru->ofdm_demod_stats); if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 ); - + remove_7_5_kHz(ru,proc->subframe_rx<<1); remove_7_5_kHz(ru,1+(proc->subframe_rx<<1)); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 2de1698450..885d29cc4e 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -254,9 +254,9 @@ void DL_channel(RU_t *ru,PHY_VARS_UE *UE,uint subframe,int awgn_flag,double SNR, uint16_t fill_tx_req(nfapi_tx_request_body_t *tx_req_body, - uint16_t absSF, + uint16_t absSF, uint16_t pdu_length, - uint16_t pdu_index, + uint16_t pdu_index, uint8_t *pdu) { nfapi_tx_request_pdu_t *TX_req = &tx_req_body->tx_pdu_list[tx_req_body->number_of_pdus]; @@ -384,7 +384,7 @@ void fill_DCI(PHY_VARS_eNB *eNB, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = n_rnti+k; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = TPC; // dont adjust power when retransmitting dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = ndi; @@ -403,14 +403,14 @@ void fill_DCI(PHY_VARS_eNB *eNB, dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - fill_dlsch_config(dl_req, - get_TBS_DL(mcs1,NB_RB), + fill_dlsch_config(dl_req, + get_TBS_DL(mcs1,NB_RB), (retrans > 0) ? -1 : 0, /* retransmission, no pdu_index */ - n_rnti, + n_rnti, 0, // type 0 allocation from 7.1.6 in 36.213 0, // virtual_resource_block_assignment_flag, unused here - DLSCH_RB_ALLOC, // resource_block_coding, - get_Qm(mcs1), + DLSCH_RB_ALLOC, // resource_block_coding, + get_Qm(mcs1), rv, // redundancy version 1, // transport blocks 0, // transport block to codeword swap flag @@ -419,7 +419,7 @@ void fill_DCI(PHY_VARS_eNB *eNB, 1, // number of subbands // uint8_t codebook_index, 4, // UE category capacity - pa, // pa + pa, // pa 0, // delta_power_offset for TM5 0, // ngap 0, // nprb @@ -429,7 +429,7 @@ void fill_DCI(PHY_VARS_eNB *eNB, ); fill_tx_req(TX_req, (frame * 10) + subframe, - get_TBS_DL(mcs1,NB_RB), + get_TBS_DL(mcs1,NB_RB), 0, input_buffer[k]); } @@ -441,26 +441,26 @@ void fill_DCI(PHY_VARS_eNB *eNB, case 3: if (common_flag == 0) { - + if (eNB->frame_parms.nb_antennas_tx == 2) { - + if (eNB->frame_parms.frame_type == TDD) { - + } else { - + } } } break; - + case 4: if (common_flag == 0) { - + if (eNB->frame_parms.nb_antennas_tx == 2) { - + if (eNB->frame_parms.frame_type == TDD) { - + } @@ -564,7 +564,7 @@ int main(int argc, char **argv) // char input_val_str[50],input_val_str2[50]; char input_trch_val[16]; - + // unsigned char pbch_pdu[6]; @@ -651,7 +651,7 @@ int main(int argc, char **argv) nfapi_dl_config_request_t DL_req; nfapi_ul_config_request_t UL_req; nfapi_hi_dci0_request_t HI_DCI0_req; - nfapi_dl_config_request_pdu_t dl_config_pdu_list[MAX_NUM_DL_PDU]; + nfapi_dl_config_request_pdu_t dl_config_pdu_list[MAX_NUM_DL_PDU]; nfapi_tx_request_pdu_t tx_pdu_list[MAX_NUM_TX_REQUEST_PDU]; nfapi_tx_request_t TX_req; Sched_Rsp_t sched_resp; @@ -1155,7 +1155,7 @@ int main(int argc, char **argv) uint8_t input_buffer[NUMBER_OF_UE_MAX][20000]; - for (i=0;iframe_parms; @@ -1585,7 +1585,7 @@ int main(int argc, char **argv) (TB0_active==1)?mcs1:0,mcs2,!(trials&1),(TB0_active==1)?round&3:0,pa,&num_common_dci,&num_ue_spec_dci,&num_dci); } } - + proc_eNB->subframe_tx = subframe; sched_resp.subframe=subframe; sched_resp.frame=proc_eNB->frame_tx; @@ -1610,7 +1610,7 @@ int main(int argc, char **argv) 0, subframe, transmission_mode>=7?transmission_mode:0); - + uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword); printf("uncoded_ber_bit=%p\n",uncoded_ber_bit); } @@ -1736,13 +1736,13 @@ int main(int argc, char **argv) write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[0][eNB_id]->rxdataF_comp[0],4*300,1,1); write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[0][eNB_id]->llr,2400,1,4); - + write_output("rxsig0.m","rxs0", &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1); write_output("rxsigF0.m","rxsF0", &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1); - + exit(-1); - + } int bit_errors=0; @@ -1755,9 +1755,9 @@ int main(int argc, char **argv) UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0], 0, subframe<<1); - for (i=0;idlsch[0][0]->harq_processes[0]->e[i]==1 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] > 0)|| - (eNB->dlsch[0][0]->harq_processes[0]->e[i]==0 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] < 0)) { + (eNB->dlsch[0][0]->harq_processes[0]->e[i]==0 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] < 0)) { uncoded_ber_bit[bit_errors++] = 1; printf("error in pos %d : %d => %d\n",i, eNB->dlsch[0][0]->harq_processes[0]->e[i], @@ -1770,10 +1770,10 @@ int main(int argc, char **argv) UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i]); */ } - + write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); write_output("ch0.m","ch0",eNB2UE[0]->ch[0],eNB2UE[0]->channel_length,1,8); - + if (eNB->frame_parms.nb_antennas_tx>1) write_output("ch1.m","ch1",eNB2UE[0]->ch[eNB->frame_parms.nb_antennas_rx],eNB2UE[0]->channel_length,1,8); @@ -2488,7 +2488,7 @@ int main(int argc, char **argv) if (test_perf && !test_passed) return(-1); - else + else return(0); } diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 8381553bb7..d6009bc793 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -84,20 +84,20 @@ extern void ru_fep_full_2thread(RU_t *ru); nfapi_dl_config_request_t DL_req; nfapi_ul_config_request_t UL_req; nfapi_hi_dci0_request_t HI_DCI0_req; -nfapi_ul_config_request_pdu_t ul_config_pdu_list[MAX_NUM_DL_PDU]; +nfapi_ul_config_request_pdu_t ul_config_pdu_list[MAX_NUM_DL_PDU]; nfapi_tx_request_pdu_t tx_pdu_list[MAX_NUM_TX_REQUEST_PDU]; nfapi_tx_request_t TX_req; Sched_Rsp_t sched_resp; void -fill_nfapi_ulsch_config_request(nfapi_ul_config_request_pdu_t *ul_config_pdu, +fill_nfapi_ulsch_config_request(nfapi_ul_config_request_pdu_t *ul_config_pdu, uint8_t cqi_req, uint8_t p_eNB, uint8_t cqi_ReportModeAperiodic, uint8_t betaOffset_CQI_Index, uint8_t betaOffset_RI_Index, uint8_t dl_cqi_pmi_size, - uint8_t tmode, + uint8_t tmode, uint32_t handle, uint16_t rnti, uint8_t resource_block_start, @@ -111,7 +111,7 @@ fill_nfapi_ulsch_config_request(nfapi_ul_config_request_pdu_t *ul_config_pdu, uint8_t harq_process_number, uint8_t ul_tx_mode, uint8_t current_tx_nb, - uint8_t n_srs, + uint8_t n_srs, uint16_t size) { memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); @@ -152,11 +152,11 @@ fill_nfapi_ulsch_config_request(nfapi_ul_config_request_pdu_t *ul_config_pdu, else if (p_eNB <= 2) ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 0; else if (p_eNB == 4) ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 2; - for (int ri = 0; - ri < (1 << ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size); + for (int ri = 0; + ri < (1 << ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size); ri++) ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[ri] = dl_cqi_pmi_size; - + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_cqi = betaOffset_CQI_Index; ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_ri = betaOffset_RI_Index; } @@ -263,17 +263,17 @@ void fill_ulsch_dci(PHY_VARS_eNB *eNB, break; } - fill_nfapi_ulsch_config_request(&ul_req->ul_config_pdu_list[0], - cqi_flag&1, + fill_nfapi_ulsch_config_request(&ul_req->ul_config_pdu_list[0], + cqi_flag&1, 1, // p_eNB 0, // reportmode Aperiodic beta_CQI, beta_RI, cqi_size, - //cc, - //UE_template->physicalConfigDedicated, + //cc, + //UE_template->physicalConfigDedicated, 1, - 0, + 0, 14, // rnti first_rb, // resource_block_start nb_rb, // number_of_resource_blocks @@ -292,7 +292,7 @@ void fill_ulsch_dci(PHY_VARS_eNB *eNB, sched_resp->UL_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; ul_req->number_of_pdus=1; ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - + } extern void eNB_fep_full(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc); @@ -740,7 +740,7 @@ int main(int argc, char **argv) for (int k=0;kRU_list[0]->nb_rx;k++) eNB->common_vars.rxdataF[k] = eNB->RU_list[0]->common.rxdataF[k]; memset((void*)&eNB->UL_INFO,0,sizeof(eNB->UL_INFO)); - + printf("Setting indication lists\n"); eNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = eNB->rx_pdu_list; eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = eNB->crc_pdu_list; @@ -922,7 +922,7 @@ int main(int argc, char **argv) UE->mac_enabled=0; - + eNB_rxtx_proc_t *proc_rxtx = &eNB->proc.proc_rxtx[subframe&1]; UE_rxtx_proc_t *proc_rxtx_ue = &UE->proc.proc_rxtx[subframe&1]; proc_rxtx->frame_rx=1; @@ -1102,7 +1102,7 @@ int main(int argc, char **argv) reset_meas(&eNB->ulsch_tc_intl1_stats); reset_meas(&eNB->ulsch_tc_intl2_stats); - // initialization + // initialization struct list time_vector_tx; initialize(&time_vector_tx); struct list time_vector_tx_ifft; @@ -1137,10 +1137,10 @@ int main(int argc, char **argv) while (round < 4) { proc_rxtx->frame_rx=1; proc_rxtx->subframe_rx=subframe; - + proc_rxtx->frame_tx=pdcch_alloc2ul_frame(&eNB->frame_parms,1,subframe); proc_rxtx->subframe_tx=pdcch_alloc2ul_subframe(&eNB->frame_parms,subframe); - + proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx; proc_rxtx_ue->frame_rx = (subframe<4)?(proc_rxtx->frame_tx-1):(proc_rxtx->frame_tx); proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx; @@ -1158,7 +1158,7 @@ int main(int argc, char **argv) if (mcs < 11) modulation_type = 2; else if (mcs < 21) modulation_type = 4; else if (mcs < 29) modulation_type = 6; - + fill_ulsch_dci(eNB,proc_rxtx->frame_rx,subframe,&sched_resp,14,(void*)&UL_alloc_pdu,first_rb,nb_rb,(round==0)?mcs:(28+rvidx[round]),modulation_type,ndi,cqi_flag,beta_CQI,beta_RI,cqi_size); UE->ulsch_Msg3_active[eNB_id] = 0; @@ -1216,16 +1216,16 @@ int main(int argc, char **argv) tx_lev = signal_energy(&UE->common_vars.txdata[0][eNB->frame_parms.samples_per_tti*subframe], eNB->frame_parms.samples_per_tti); - - + + if (n_frames==1) { write_output("txsigF0UL.m","txsF0", &UE->common_vars.txdataF[0][eNB->frame_parms.ofdm_symbol_size*nsymb*subframe],eNB->frame_parms.ofdm_symbol_size*nsymb,1, 1); //write_output("txsigF1.m","txsF1", UE->common_vars.txdataF[0],FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX,1,1); } - + } // input_fd == NULL - + tx_lev_dB = (unsigned int) dB_fixed_times10(tx_lev); if (n_frames==1) { @@ -1337,7 +1337,7 @@ int main(int argc, char **argv) ru->feprx = (parallel_flag == 1) ? ru_fep_full_2thread : fep_full; eNB->td = (parallel_flag == 1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; - + ru->feprx(ru); phy_procedures_eNB_uespec_RX(eNB,proc_rxtx,no_relay); @@ -1371,10 +1371,10 @@ int main(int argc, char **argv) // printf("ulsch_coding: O[%d] %d\n",i,o_flip[i]); - + // if (ret <= eNB->ulsch[0]->max_turbo_iterations) { - - if (eNB->ulsch[0]->harq_processes[harq_pid]->status == SCH_IDLE) { + + if (eNB->ulsch[0]->harq_processes[harq_pid]->status == SCH_IDLE) { // avg_iter += ret; iter_trials++; @@ -1425,7 +1425,7 @@ int main(int argc, char **argv) if (n_frames==1) { printf("ULSCH in error in round %d\n",round); } - } // ulsch error + } // ulsch error } // round diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 921ea50bc0..31b0f2fe75 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -17,7 +17,7 @@ *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org - */ + */ /*! \file flexran_agent_mac.c * \brief FlexRAN agent message handler for MAC layer @@ -54,7 +54,7 @@ struct lfds700_ringbuffer_element *dl_mac_config_array[NUM_MAX_ENB]; struct lfds700_ringbuffer_state ringbuffer_state[NUM_MAX_ENB]; -int flexran_agent_mac_stats_reply(mid_t mod_id, +int flexran_agent_mac_stats_reply(mid_t mod_id, const report_config_t *report_config, Protocol__FlexUeStatsReport **ue_report, Protocol__FlexCellStatsReport **cell_report) { @@ -68,7 +68,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, /* Allocate memory for list of UE reports */ if (report_config->nr_ue > 0) { - + for (i = 0; i < report_config->nr_ue; i++) { @@ -76,24 +76,24 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, /* Check flag for creation of buffer status report */ if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_BSR) { //TODO should be automated - ue_report[i]->n_bsr = 4; + ue_report[i]->n_bsr = 4; uint32_t *elem; elem = (uint32_t *) malloc(sizeof(uint32_t)*ue_report[i]->n_bsr); if (elem == NULL) goto error; for (j = 0; j < ue_report[i]->n_bsr; j++) { - // NN: we need to know the cc_id here, consider the first one + // NN: we need to know the cc_id here, consider the first one elem[j] = flexran_get_ue_bsr_ul_buffer_info (enb_id, i, j); } - + ue_report[i]->bsr = elem; } - + /* Check flag for creation of PHR report */ if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PHR) { ue_report[i]->phr = flexran_get_ue_phr (enb_id, i); // eNB_UE_list->UE_template[UE_PCCID(enb_id,i)][i].phr_info; ue_report[i]->has_phr = 1; - + } /* Check flag for creation of RLC buffer status report */ @@ -134,19 +134,19 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, if (ue_report[i]->n_rlc_report > 0) ue_report[i]->rlc_report = rlc_reports; - + } /* Check flag for creation of MAC CE buffer status report */ if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_CE_BS) { // TODO: Fill in the actual MAC CE buffer status report - ue_report[i]->pending_mac_ces = (flexran_get_MAC_CE_bitmap_TA(enb_id,i,0) | (0 << 1) | (0 << 2) | (0 << 3)) & 15; + ue_report[i]->pending_mac_ces = (flexran_get_MAC_CE_bitmap_TA(enb_id,i,0) | (0 << 1) | (0 << 2) | (0 << 3)) & 15; // Use as bitmap. Set one or more of the; /* Use as bitmap. Set one or more of the // PROTOCOL__FLEX_CE_TYPE__FLPCET_ values // found in stats_common.pb-c.h. See - // flex_ce_type in FlexRAN specification + // flex_ce_type in FlexRAN specification ue_report[i]->has_pending_mac_ces = 1; - + } /* Check flag for creation of DL CQI report */ @@ -167,7 +167,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, Protocol__FlexDlCsi **csi_reports; csi_reports = malloc(sizeof(Protocol__FlexDlCsi *)*dl_report->n_csi_report); if (csi_reports == NULL) - goto error; + goto error; for (j = 0; j < dl_report->n_csi_report; j++) { csi_reports[j] = malloc(sizeof(Protocol__FlexDlCsi)); @@ -211,18 +211,18 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, if (csi11 == NULL) goto error; protocol__flex_csi_p11__init(csi11); - - csi11->wb_cqi = malloc(sizeof(csi11->wb_cqi)); + + csi11->wb_cqi = malloc(sizeof(csi11->wb_cqi)); csi11->n_wb_cqi = 1; - csi11->wb_cqi[0] = flexran_get_ue_wcqi (enb_id, i); - // According To spec 36.213 - + csi11->wb_cqi[0] = flexran_get_ue_wcqi (enb_id, i); + // According To spec 36.213 + if (flexran_get_antenna_ports(enb_id, j) == 2 && csi_reports[j]->ri == 1) { // TODO PMI csi11->wb_pmi = flexran_get_ue_wpmi(enb_id, i, 0); csi11->has_wb_pmi = 1; - } + } else if (flexran_get_antenna_ports(enb_id, j) == 2 && csi_reports[j]->ri == 2){ // TODO PMI @@ -239,14 +239,14 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, } - csi11->has_wb_pmi = 0; + csi11->has_wb_pmi = 0; csi_reports[j]->p11csi = csi11; } - - + + else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P20CSI){ @@ -256,16 +256,16 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, if (csi20 == NULL) goto error; protocol__flex_csi_p20__init(csi20); - - csi20->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + + csi20->wb_cqi = flexran_get_ue_wcqi (enb_id, i); csi20->has_wb_cqi = 1; - + csi20->bandwidth_part_index = 1 ;//TODO csi20->has_bandwidth_part_index = 1; csi20->sb_index = 1 ;//TODO - csi20->has_sb_index = 1 ; + csi20->has_sb_index = 1 ; csi_reports[j]->p20csi = csi20; @@ -280,20 +280,20 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, // if (csi21 == NULL) // goto error; // protocol__flex_csi_p21__init(csi21); - - // csi21->wb_cqi = flexran_get_ue_wcqi (enb_id, i); - - + + // csi21->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + + // csi21->wb_pmi = flexran_get_ue_pmi(enb_id); //TDO inside // csi21->has_wb_pmi = 1; - // csi21->sb_cqi = 1; // TODO - + // csi21->sb_cqi = 1; // TODO + // csi21->bandwidth_part_index = 1 ; //TDO inside - // csi21->has_bandwidth_part_index = 1 ; + // csi21->has_bandwidth_part_index = 1 ; // csi21->sb_index = 1 ;//TODO - // csi21->has_sb_index = 1 ; + // csi21->has_sb_index = 1 ; // csi_reports[j]->p20csi = csi21; @@ -308,10 +308,10 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, // if (csi12 == NULL) // goto error; // protocol__flex_csi_a12__init(csi12); - - // csi12->wb_cqi = flexran_get_ue_wcqi (enb_id, i); - - // csi12->sb_pmi = 1 ; //TODO inside + + // csi12->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + + // csi12->sb_pmi = 1 ; //TODO inside // TODO continou } @@ -323,18 +323,18 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, // if (csi22 == NULL) // goto error; // protocol__flex_csi_a22__init(csi22); - - // csi22->wb_cqi = flexran_get_ue_wcqi (enb_id, i); - - // csi22->sb_cqi = 1 ; //TODO inside - // csi22->wb_pmi = flexran_get_ue_wcqi (enb_id, i); - // csi22->has_wb_pmi = 1; - - // csi22->sb_pmi = 1 ; //TODO inside + // csi22->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + + // csi22->sb_cqi = 1 ; //TODO inside + + // csi22->wb_pmi = flexran_get_ue_wcqi (enb_id, i); // csi22->has_wb_pmi = 1; - // csi22->sb_list = flexran_get_ue_wcqi (enb_id, i); + // csi22->sb_pmi = 1 ; //TODO inside + // csi22->has_wb_pmi = 1; + + // csi22->sb_list = flexran_get_ue_wcqi (enb_id, i); } @@ -347,10 +347,10 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, // goto error; // protocol__flex_csi_a20__init(csi20); - // csi20->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + // csi20->wb_cqi = flexran_get_ue_wcqi (enb_id, i); // csi20->has_wb_cqi = 1; - // csi20>sb_cqi = 1 ; //TODO inside + // csi20>sb_cqi = 1 ; //TODO inside // csi20>has_sb_cqi = 1 ; // csi20->sb_list = 1; // TODO inside @@ -371,7 +371,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, dl_report->csi_report = csi_reports; //Add the DL CQI report to the stats report ue_report[i]->dl_cqi_report = dl_report; - + } /* Check flag for creation of paging buffer status report */ @@ -463,7 +463,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, //TODO: Set the servCellIndex for this report ul_report[j]->serv_cell_index = 0; ul_report[j]->has_serv_cell_index = 1; - + //Set the list of UL reports of this UE to the full UL report full_ul_report->cqi_meas = ul_report; @@ -487,9 +487,9 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, } // Add full UL CQI report to the UE report ue_report[i]->ul_cqi_report = full_ul_report; - - } + + } if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_STATS) { Protocol__FlexMacStats *macstats; @@ -497,7 +497,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, if (macstats == NULL) goto error; protocol__flex_mac_stats__init(macstats); - + macstats->total_bytes_sdus_dl = flexran_get_total_size_dl_mac_sdus(mod_id, i, cc_id); macstats->has_total_bytes_sdus_dl = 1; @@ -508,7 +508,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, macstats->tbs_dl = flexran_get_TBS_dl(mod_id, i, cc_id); macstats->has_tbs_dl = 1; - macstats->tbs_ul = flexran_get_TBS_ul(mod_id, i, cc_id); + macstats->tbs_ul = flexran_get_TBS_ul(mod_id, i, cc_id); macstats->has_tbs_ul = 1; macstats->prb_retx_dl = flexran_get_num_prb_retx_dl_per_ue(mod_id, i, cc_id); @@ -556,16 +556,16 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, macstats->harq_round = flexran_get_harq_round(mod_id, cc_id, i); macstats->has_harq_round = 1; - Protocol__FlexMacSdusDl ** mac_sdus; + Protocol__FlexMacSdusDl ** mac_sdus; mac_sdus = malloc(sizeof(Protocol__FlexMacSdusDl) * flexran_get_num_mac_sdu_tx(mod_id, i, cc_id)); if (mac_sdus == NULL) goto error; - macstats->n_mac_sdus_dl = flexran_get_num_mac_sdu_tx(mod_id, i, cc_id); - + macstats->n_mac_sdus_dl = flexran_get_num_mac_sdu_tx(mod_id, i, cc_id); + for (j = 0; j < macstats->n_mac_sdus_dl; j++){ - + mac_sdus[j] = malloc(sizeof(Protocol__FlexMacSdusDl)); protocol__flex_mac_sdus_dl__init(mac_sdus[j]); @@ -577,29 +577,29 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, } - - macstats->mac_sdus_dl = mac_sdus; - - ue_report[i]->mac_stats = macstats; + macstats->mac_sdus_dl = mac_sdus; - } - - - - } + ue_report[i]->mac_stats = macstats; - - - - } + } + + + + + } + + + + + } /* Allocate memory for list of cell reports */ if (report_config->nr_cc > 0) { - - + + // Fill in the Cell reports for (i = 0; i < report_config->nr_cc; i++) { @@ -627,10 +627,10 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, cell_report[i]->noise_inter_report = ni_report; } } - - - + + + } return 0; @@ -835,9 +835,9 @@ int flexran_agent_mac_destroy_sr_info(Protocol__FlexranMessage *msg) { int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { Protocol__FlexHeader *header = NULL; int i, j, UE_id; - + int available_harq[NUMBER_OF_UE_MAX]; - + const int xid = *((int *)params); @@ -859,12 +859,12 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle } int ahead_of_time = 0; - + frame = (frame_t) flexran_get_current_system_frame_num(mod_id); subframe = (sub_frame_t) flexran_get_current_subframe(mod_id); subframe = ((subframe + ahead_of_time) % 10); - + if (subframe < flexran_get_current_subframe(mod_id)) { frame = (frame + 1) % 1024; } @@ -887,7 +887,7 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle } } } - + // LOG_I(FLEXRAN_AGENT, "Sending subframe trigger for frame %d and subframe %d\n", flexran_get_current_frame(mod_id), (flexran_get_current_subframe(mod_id) + 1) % 10); @@ -920,8 +920,8 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle // uint8_t harq_id; //uint8_t harq_status; // flexran_get_harq(mod_id, UE_PCCID(mod_id,i), i, frame, subframe, &harq_id, &harq_status); - - + + dl_info[i]->harq_process_id = available_harq[UE_id]; if (RC.mac && RC.mac[mod_id]) RC.mac[mod_id]->UE_list.eNB_UE_stats[UE_PCCID(mod_id,i)][UE_id].harq_pid = 0; @@ -1010,7 +1010,7 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle for (i = 0; i < sf_trigger_msg->n_dl_info; i++) { free(sf_trigger_msg->dl_info[i]->harq_status); } - free(sf_trigger_msg->dl_info); + free(sf_trigger_msg->dl_info); free(sf_trigger_msg->ul_info); free(sf_trigger_msg); } @@ -1184,7 +1184,7 @@ int flexran_agent_mac_destroy_ul_config(Protocol__FlexranMessage *msg) { free(msg->ul_mac_config_msg->header); for (i = 0; i < msg->ul_mac_config_msg->n_ul_ue_data; i++) { // TODO uplink rlc ... - // free(msg->ul_mac_config_msg->dl_ue_data[i]->ce_bitmap); + // free(msg->ul_mac_config_msg->dl_ue_data[i]->ce_bitmap); // for (j = 0; j < msg->ul_mac_config_msg->ul_ue_data[i]->n_rlc_pdu; j++) { // for (k = 0; k < msg->ul_mac_config_msg->ul_ue_data[i]->rlc_pdu[j]->n_rlc_pdu_tb; k++) { // free(msg->ul_mac_config_msg->dl_ue_data[i]->rlc_pdu[j]->rlc_pdu_tb[k]); @@ -1202,7 +1202,7 @@ int flexran_agent_mac_destroy_ul_config(Protocol__FlexranMessage *msg) { // free(msg->ul_mac_config_msg->ul_ue_data[i]); } free(msg->ul_mac_config_msg->ul_ue_data); - + free(msg->ul_mac_config_msg); free(msg); @@ -1216,10 +1216,10 @@ int flexran_agent_mac_destroy_ul_config(Protocol__FlexranMessage *msg) { void flexran_agent_get_pending_dl_mac_config(mid_t mod_id, Protocol__FlexranMessage **msg) { struct lfds700_misc_prng_state ls; - + LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE; lfds700_misc_prng_init(&ls); - + if (lfds700_ringbuffer_read(&ringbuffer_state[mod_id], NULL, (void **) msg, &ls) == 0) { *msg = NULL; } @@ -1230,10 +1230,10 @@ int flexran_agent_mac_handle_dl_mac_config(mid_t mod_id, const void *params, Pro struct lfds700_misc_prng_state ls; enum lfds700_misc_flag overwrite_occurred_flag; Protocol__FlexranMessage *overwritten_dl_config; - + LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE; lfds700_misc_prng_init(&ls); - + lfds700_ringbuffer_write( &ringbuffer_state[mod_id], NULL, (void *) params, @@ -1347,7 +1347,7 @@ int flexran_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { xface->flexran_agent_send_sf_trigger = flexran_agent_send_sf_trigger; //xface->flexran_agent_send_update_mac_stats = flexran_agent_send_update_mac_stats; xface->flexran_agent_get_pending_dl_mac_config = flexran_agent_get_pending_dl_mac_config; - + xface->dl_scheduler_loaded_lib = NULL; xface->ul_scheduler_loaded_lib = NULL; mac_agent_registered[mod_id] = 1; diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index ddb8a6942d..76b2194612 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -157,13 +157,13 @@ #define U_PLANE_INACTIVITY_VALUE 6000 -/* - * eNB part +/* + * eNB part */ -/* - * UE/ENB common part +/* + * UE/ENB common part */ /*!\brief MAC header of Random Access Response for Random access preamble identifier (RAPID) */ typedef struct { @@ -448,20 +448,20 @@ typedef struct { } eNB_DLSCH_INFO; /*! \brief eNB overall statistics */ typedef struct { - /// num BCCH PDU per CC + /// num BCCH PDU per CC uint32_t total_num_bcch_pdu; - /// BCCH buffer size + /// BCCH buffer size uint32_t bcch_buffer; - /// total BCCH buffer size + /// total BCCH buffer size uint32_t total_bcch_buffer; /// BCCH MCS uint32_t bcch_mcs; - /// num CCCH PDU per CC + /// num CCCH PDU per CC uint32_t total_num_ccch_pdu; - /// BCCH buffer size + /// BCCH buffer size uint32_t ccch_buffer; - /// total BCCH buffer size + /// total BCCH buffer size uint32_t total_ccch_buffer; /// BCCH MCS uint32_t ccch_mcs; @@ -562,13 +562,13 @@ typedef struct { uint32_t num_retransmission; /// instantaneous tx throughput for each TTI // uint32_t tti_throughput[NB_RB_MAX]; - // Number of received MAC SDU + // Number of received MAC SDU uint32_t num_mac_sdu_tx; // LCID related to SDU unsigned char lcid_sdu[NB_RB_MAX]; // Length of SDU Got from LC DL uint32_t sdu_length_tx[NB_RB_MAX]; - + /// overall // @@ -614,7 +614,7 @@ typedef struct { /// uplink transport block size uint32_t ulsch_TBS; - + uint32_t total_ulsch_TBS; /// total rb used for a new uplink transmission @@ -625,9 +625,9 @@ typedef struct { uint32_t rbs_used_retx_rx; /// total rb used for a new uplink transmission uint32_t total_rbs_used_rx; - /// normalized rx power + /// normalized rx power int32_t normalized_rx_power; - /// target rx power + /// target rx power int32_t target_rx_power; /// num rx pdu @@ -754,7 +754,7 @@ typedef struct { uint32_t dl_buffer_head_sdu_creation_time[MAX_NUM_LCID]; /// maximum creation time of the downlink buffer head across all LCID uint32_t dl_buffer_head_sdu_creation_time_max; - /// a flag indicating that the downlink head SDU is segmented + /// a flag indicating that the downlink head SDU is segmented uint8_t dl_buffer_head_sdu_is_segmented[MAX_NUM_LCID]; /// size of remaining size to send for the downlink head SDU uint32_t dl_buffer_head_sdu_remaining_size_to_send[MAX_NUM_LCID]; @@ -949,21 +949,21 @@ typedef struct { /// Dedicated information for UEs struct PhysicalConfigDedicated *physicalConfigDedicated[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - /// DLSCH pdu + /// DLSCH pdu DLSCH_PDU DLSCH_pdu[MAX_NUM_CCs][2][NUMBER_OF_UE_MAX]; /// DCI template and MAC connection parameters for UEs UE_TEMPLATE UE_template[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; /// DCI template and MAC connection for RA processes int pCC_id[NUMBER_OF_UE_MAX]; - /// sorted downlink component carrier for the scheduler + /// sorted downlink component carrier for the scheduler int ordered_CCids[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - /// number of downlink active component carrier + /// number of downlink active component carrier int numactiveCCs[NUMBER_OF_UE_MAX]; - /// sorted uplink component carrier for the scheduler + /// sorted uplink component carrier for the scheduler int ordered_ULCCids[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - /// number of uplink active component carrier + /// number of uplink active component carrier int numactiveULCCs[NUMBER_OF_UE_MAX]; - /// number of downlink active component carrier + /// number of downlink active component carrier uint8_t dl_CC_bitmap[NUMBER_OF_UE_MAX]; /// eNB to UE statistics eNB_UE_STATS eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; @@ -1089,7 +1089,7 @@ typedef struct eNB_MAC_INST_s { nfapi_ul_config_request_t UL_req[MAX_NUM_CCs]; /// NFAPI "Temporary" UL Config Request Structure, holds future UL_config requests nfapi_ul_config_request_t UL_req_tmp[MAX_NUM_CCs][10]; - /// Preallocated HI_DCI0 pdu list + /// Preallocated HI_DCI0 pdu list nfapi_hi_dci0_request_pdu_t hi_dci0_pdu_list[MAX_NUM_CCs][MAX_NUM_HI_DCI0_PDU]; /// NFAPI HI/DCI0 Config Request Structure @@ -1112,21 +1112,21 @@ typedef struct eNB_MAC_INST_s { /// eNB stats eNB_STATS eNB_stats[MAX_NUM_CCs]; // MAC function execution peformance profiler - /// processing time of eNB scheduler + /// processing time of eNB scheduler time_stats_t eNB_scheduler; - /// processing time of eNB scheduler for SI + /// processing time of eNB scheduler for SI time_stats_t schedule_si; /// processing time of eNB scheduler for Random access time_stats_t schedule_ra; - /// processing time of eNB ULSCH scheduler + /// processing time of eNB ULSCH scheduler time_stats_t schedule_ulsch; /// processing time of eNB DCI generation time_stats_t fill_DLSCH_dci; /// processing time of eNB MAC preprocessor time_stats_t schedule_dlsch_preprocessor; - /// processing time of eNB DLSCH scheduler + /// processing time of eNB DLSCH scheduler time_stats_t schedule_dlsch; // include rlc_data_req + MAC header + preprocessor - /// processing time of eNB MCH scheduler + /// processing time of eNB MCH scheduler time_stats_t schedule_mch; /// processing time of eNB ULSCH reception time_stats_t rx_ulsch_sdu; // include rlc_data_ind @@ -1134,8 +1134,8 @@ typedef struct eNB_MAC_INST_s { time_stats_t schedule_pch; } eNB_MAC_INST; -/* - * UE part +/* + * UE part */ typedef enum { @@ -1329,24 +1329,24 @@ typedef struct { uint8_t msi_status; // could be an array if there are >1 MCH in one MBSFN area #endif //#ifdef CBA - /// CBA RNTI for each group + /// CBA RNTI for each group uint16_t cba_rnti[NUM_MAX_CBA_GROUP]; - /// last SFN for CBA channel access + /// last SFN for CBA channel access uint8_t cba_last_access[NUM_MAX_CBA_GROUP]; //#endif - /// total UE scheduler processing time + /// total UE scheduler processing time time_stats_t ue_scheduler; // total - /// UE ULSCH tx processing time inlcuding RLC interface (rlc_data_req) and mac header generation + /// UE ULSCH tx processing time inlcuding RLC interface (rlc_data_req) and mac header generation time_stats_t tx_ulsch_sdu; /// UE DLSCH rx processing time inlcuding RLC interface (mac_rrc_data_ind or mac_rlc_status_ind+mac_rlc_data_ind) and mac header parser time_stats_t rx_dlsch_sdu; - /// UE query for MCH subframe processing time + /// UE query for MCH subframe processing time time_stats_t ue_query_mch; - /// UE MCH rx processing time + /// UE MCH rx processing time time_stats_t rx_mch_sdu; - /// UE BCCH rx processing time including RLC interface (mac_rrc_data_ind) + /// UE BCCH rx processing time including RLC interface (mac_rrc_data_ind) time_stats_t rx_si; - /// UE PCCH rx processing time including RLC interface (mac_rrc_data_ind) + /// UE PCCH rx processing time including RLC interface (mac_rrc_data_ind) time_stats_t rx_p; } UE_MAC_INST; /*! \brief ID of the neighboring cells used for HO*/ diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 7e6eee0f87..aeaa55a79a 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -744,7 +744,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, } } /* if (continue_flag != 1 */ - if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated + if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, aggregation, rnti)) { LOG_D(MAC, @@ -929,7 +929,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, dl_req->number_dci++; dl_req->number_pdu++; dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - + eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; @@ -1116,7 +1116,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch); - if (TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch > 0) { // NN: > 2 ? + if (TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch > 0) { // NN: > 2 ? rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, @@ -1158,7 +1158,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid] += 1; UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = lcid; - UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[lcid] = sdu_lengths[num_sdus]; + UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[lcid] = sdu_lengths[num_sdus]; UE_list-> eNB_UE_stats[CC_id][UE_id].num_bytes_tx [lcid] += sdu_lengths[num_sdus]; @@ -1180,7 +1180,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, } if (header_len_dtch == 0) header_len_dtch_last = 0; - // there is at least one SDU + // there is at least one SDU // if (num_sdus > 0 ){ if ((sdu_length_total + header_len_dcch + header_len_dtch) > 0) { @@ -1193,7 +1193,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, if (header_len_dtch == 0) { header_len_dcch = (header_len_dcch > 0) ? 1 : 0; //header_len_dcch; // remove length field } else { - header_len_dtch_last -= 1; // now use it to find how many bytes has to be removed for the last MAC SDU + header_len_dtch_last -= 1; // now use it to find how many bytes has to be removed for the last MAC SDU header_len_dtch = (header_len_dtch > 0) ? header_len_dtch - header_len_dtch_last : header_len_dtch; // remove length field for the last SDU } @@ -1413,10 +1413,10 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, tpc, tpc_accumulated, normalized_rx_power, target_rx_power); - } // Po_PUCCH has been updated + } // Po_PUCCH has been updated else { tpc = 1; //0 - } // time to do TPC update + } // time to do TPC update else { tpc = 1; //0 } @@ -1515,7 +1515,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, UE_list.DLSCH_pdu[CC_id][0][(unsigned char) UE_id].payload [0]); - + LOG_D(MAC, "Filled NFAPI configuration for DCI/DLSCH/TXREQ %d, new SDU\n", eNB->pdu_index[CC_id]); @@ -1695,9 +1695,9 @@ update_ul_dci(module_id_t module_idP, int i; - if (cc->tdd_Config != NULL) { // TDD + if (cc->tdd_Config != NULL) { // TDD for (i = 0; - i hi_dci0_request_body.number_of_dci + HI_DCI0_req->hi_dci0_request_body.number_of_dci; + i hi_dci0_request_body.number_of_dci + HI_DCI0_req->hi_dci0_request_body.number_of_dci; i++) { if ((hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) && From 365ca71a4ab9d06f56c47e22d2a9450dba715572 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 21 Feb 2018 16:16:34 +0100 Subject: [PATCH 164/195] remove compilation warnings --- openair1/PHY/INIT/lte_param_init.c | 1 + openair1/PHY/LTE_TRANSPORT/dci.c | 12 +++---- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 2 +- openair1/PHY/TOOLS/lte_dfts.c | 4 +++ openair1/PHY/TOOLS/lte_phy_scope.c | 2 +- openair1/SCHED/phy_procedures_lte_eNb.c | 4 +-- openair1/SCHED/prach_procedures.c | 2 ++ .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 1 + openair2/ENB_APP/enb_paramdef.h | 4 --- openair2/LAYER2/MAC/pre_processor.c | 5 +++ openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 10 +++--- openair2/RRC/LITE/L2_interface_ue.c | 14 +------- openair2/RRC/LITE/proto.h | 11 ++++++ openair2/RRC/LITE/rrc_UE.c | 4 --- openair2/RRC/LITE/rrc_eNB.c | 3 +- targets/RT/USER/lte-ru.c | 6 +++- targets/SIMU/USER/channel_sim.c | 1 + targets/SIMU/USER/event_handler.c | 8 ++--- targets/SIMU/USER/oaisim.c | 35 ++++++++++--------- targets/SIMU/USER/oaisim_functions.c | 23 ++++++------ 20 files changed, 82 insertions(+), 70 deletions(-) diff --git a/openair1/PHY/INIT/lte_param_init.c b/openair1/PHY/INIT/lte_param_init.c index 1743a8d90c..6cf05769e5 100644 --- a/openair1/PHY/INIT/lte_param_init.c +++ b/openair1/PHY/INIT/lte_param_init.c @@ -33,6 +33,7 @@ extern PHY_VARS_eNB *eNB; extern PHY_VARS_UE *UE; extern RU_t *ru; +extern void phy_init_RU(RU_t*); void lte_param_init(PHY_VARS_eNB **eNBp, PHY_VARS_UE **UEp, diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c index 94d6cd9c3f..ded49d1c73 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci.c +++ b/openair1/PHY/LTE_TRANSPORT/dci.c @@ -1874,12 +1874,6 @@ int32_t rx_pdcch(PHY_VARS_UE *ue, #endif //MU_RECEIVER -#if T_TRACER - T(T_UE_PHY_PDCCH_IQ, T_INT(frame_parms->N_RB_DL), T_INT(frame_parms->N_RB_DL), - T_INT(n_pdcch_symbols), - T_BUFFER(pdcch_vars[eNB_id]->rxdataF_comp, frame_parms->N_RB_DL*12*n_pdcch_symbols* 4)); -#endif - // decode pcfich here and find out pdcch ofdm symbol number n_pdcch_symbols = rx_pcfich(frame_parms, subframe, @@ -1890,6 +1884,12 @@ int32_t rx_pdcch(PHY_VARS_UE *ue, if (n_pdcch_symbols>3) n_pdcch_symbols=1; +#if T_TRACER + T(T_UE_PHY_PDCCH_IQ, T_INT(frame_parms->N_RB_DL), T_INT(frame_parms->N_RB_DL), + T_INT(n_pdcch_symbols), + T_BUFFER(pdcch_vars[eNB_id]->rxdataF_comp, frame_parms->N_RB_DL*12*n_pdcch_symbols* 4)); +#endif + #ifdef DEBUG_DCI_DECODING diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 1becc98752..6284f279d8 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -843,7 +843,7 @@ int rx_pdsch(PHY_VARS_UE *ue, pllr_symbol_cw0 += llr_offset_symbol; pllr_symbol_cw1 += llr_offset_symbol; - LOG_I(PHY,"compute LLRs [AbsSubframe %d.%d-%d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %x @LLR Buff(symb) %x\n", + LOG_I(PHY,"compute LLRs [AbsSubframe %d.%d-%d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %p @LLR Buff(symb) %p\n", frame, subframe,symbol, nb_rb,dlsch0_harq->Qm, pdsch_vars[eNB_id]->llr_length[symbol], diff --git a/openair1/PHY/TOOLS/lte_dfts.c b/openair1/PHY/TOOLS/lte_dfts.c index e0e171f6bf..47b39ea7d2 100644 --- a/openair1/PHY/TOOLS/lte_dfts.c +++ b/openair1/PHY/TOOLS/lte_dfts.c @@ -2047,6 +2047,8 @@ const static int16_t tw16c[24] __attribute__((aligned(32))) = { 0,32767,12540,30 0,32767,30273,12539,23170,-23170,-12539,-30273 }; +#ifdef __AVX2__ + const static int16_t tw16rep[48] __attribute__((aligned(32))) = { 32767,0,30272,-12540,23169 ,-23170,12539 ,-30273,32767,0,30272,-12540,23169 ,-23170,12539 ,-30273, 32767,0,23169,-23170,0 ,-32767,-23170,-23170,32767,0,23169,-23170,0 ,-32767,-23170,-23170, 32767,0,12539,-30273,-23170,-23170,-30273,12539,32767,0,12539,-30273,-23170,-23170,-30273,12539 @@ -2067,6 +2069,8 @@ const static int16_t tw16crep[48] __attribute__((aligned(32))) = { 0,32767,12540 0,32767,30273,12539,23170,-23170,-12539,-30273,0,32767,30273,12539,23170,-23170,-12539,-30273 }; +#endif /* __AVX2__ */ + static inline void dft16(int16_t *x,int16_t *y) __attribute__((always_inline)); diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index 30e57c1c62..1b6c1c9153 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -200,7 +200,7 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, chest_t = (int16_t**) phy_vars_enb->srs_vars[UE_id].srs_ch_estimates[eNB_id]; chest_f = (int16_t**) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates[eNB_id]; pusch_llr = (int16_t*) phy_vars_enb->pusch_vars[UE_id]->llr; - pusch_comp = (int16_t*) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[eNB_id][0]; + pusch_comp = (int16_t*) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[0]; pucch1_comp = (int32_t*) phy_vars_enb->pucch1_stats[UE_id]; pucch1_thres = (int32_t*) phy_vars_enb->pucch1_stats_thres[UE_id]; pucch1ab_comp = (int32_t*) phy_vars_enb->pucch1ab_stats[UE_id]; diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 105dac0808..912e756f76 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -897,7 +897,7 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) harq_ack[0] = 4; // DTX harq_ack[1] = 6; // NACK/DTX harq_ack[2] = 6; // NACK/DTX - + max_metric = 0; } else { @@ -980,7 +980,7 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) harq_ack[1] = 6; // NACK/DTX harq_ack[2] = 6; // NACK/DTX harq_ack[3] = 6; // NACK/DTX - + max_metric = 0; } else { max_metric = max(metric[0],max(metric[1],max(metric[2],metric[3]))); diff --git a/openair1/SCHED/prach_procedures.c b/openair1/SCHED/prach_procedures.c index f3b5644b92..79af3c128e 100644 --- a/openair1/SCHED/prach_procedures.c +++ b/openair1/SCHED/prach_procedures.c @@ -52,6 +52,8 @@ extern uint32_t nfapi_mode; +extern int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); + void prach_procedures(PHY_VARS_eNB *eNB #ifdef Rel14 , diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 31b0f2fe75..7486594d4d 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -40,6 +40,7 @@ #include "log.h" +extern int flexran_get_harq_round(mid_t mod_id, uint8_t cc_id, mid_t ue_id); /*Flags showing if a mac agent has already been registered*/ unsigned int mac_agent_registered[NUM_MAX_ENB]; diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index 2d65e09b58..1a9019b794 100755 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -175,10 +175,6 @@ typedef enum { -static int DEFBANDS[] = {7}; -static int DEFENBS[] = {0}; - - /*-----------------------------------------------------------------------------------------------------------------------------------------*/ /* RU configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 148ea344e5..e7458c347f 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -1609,6 +1609,10 @@ ulsch_scheduler_pre_processor(module_id_t module_idP, } } +#if 0 + /* this logging is wrong, ue_sched_ctl may not be valid here + * TODO: fix + */ for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { if (total_allocated_rbs[CC_id] > 0) { @@ -1617,6 +1621,7 @@ ulsch_scheduler_pre_processor(module_id_t module_idP, ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id]); } } +#endif } diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index e9d2188bfb..05855a14bd 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -769,15 +769,15 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t* const ctxt_pP) { - unsigned char *otg_pkt=NULL; + //unsigned char *otg_pkt=NULL; module_id_t dst_id; // dst for otg - rb_id_t rb_id; - unsigned int pkt_size=0; + //rb_id_t rb_id; + //unsigned int pkt_size=0; protocol_ctxt_t ctxt; // we need to add conditions to avoid transmitting data when the UE is not RRC connected. if ((otg_enabled==1) && (ctxt_pP->enb_flag == ENB_FLAG_YES)) { // generate DL traffic - unsigned int ctime=0; - ctime = ctxt_pP->frame * 100; + //unsigned int ctime=0; + //ctime = ctxt_pP->frame * 100; /*if ((mac_get_rrc_status(eNB_index, ctxt_pP->enb_flag, 0 ) > 2) && (mac_get_rrc_status(eNB_index, ctxt_pP->enb_flag, 1 ) > 2)) { */ diff --git a/openair2/RRC/LITE/L2_interface_ue.c b/openair2/RRC/LITE/L2_interface_ue.c index 7bdbe2523e..3a2aeea451 100644 --- a/openair2/RRC/LITE/L2_interface_ue.c +++ b/openair2/RRC/LITE/L2_interface_ue.c @@ -65,26 +65,14 @@ mac_rrc_data_req_ue( ) //-------------------------------------------------------------------------- { - asn_enc_rval_t enc_rval; - SRB_INFO *Srb_info; - uint8_t Sdu_size = 0; - uint8_t sfn = (uint8_t)((frameP>>2)&0xff); - - #ifdef DEBUG_RRC int i; LOG_I(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id); #endif - eNB_RRC_INST *rrc; - rrc_eNB_carrier_data_t *carrier; - BCCH_BCH_Message_t *mib; - - LOG_D(RRC,"[UE %d] Frame %d Filling CCCH SRB_ID %d\n",Mod_idP,frameP,Srb_id); LOG_D(RRC,"[UE %d] Frame %d buffer_pP status %d,\n",Mod_idP,frameP, UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size); - if( (UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size > 0) ) { #if defined(ENABLE_ITTI) @@ -139,7 +127,6 @@ mac_rrc_data_ind_ue( ) //-------------------------------------------------------------------------- { - SRB_INFO *Srb_info; protocol_ctxt_t ctxt; sdu_size_t sdu_size = 0; @@ -214,6 +201,7 @@ mac_rrc_data_ind_ue( itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p); } #else + SRB_INFO *Srb_info; Srb_info = &UE_rrc_inst[module_idP].Srb0[eNB_indexP]; memcpy(Srb_info->Rx_buffer.Payload,sduP,sdu_lenP); Srb_info->Rx_buffer.payload_size = sdu_lenP; diff --git a/openair2/RRC/LITE/proto.h b/openair2/RRC/LITE/proto.h index 9ece5bcfdd..49cf9f2eba 100644 --- a/openair2/RRC/LITE/proto.h +++ b/openair2/RRC/LITE/proto.h @@ -409,6 +409,17 @@ rrc_data_req( const pdcp_transmission_mode_t modeP ); +uint8_t +rrc_data_req_ue( + const protocol_ctxt_t* const ctxt_pP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_sizeP, + uint8_t* const buffer_pP, + const pdcp_transmission_mode_t modeP +); + void rrc_data_ind( const protocol_ctxt_t* const ctxt_pP, diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c index 8d1f47daf5..121d115398 100644 --- a/openair2/RRC/LITE/rrc_UE.c +++ b/openair2/RRC/LITE/rrc_UE.c @@ -241,7 +241,6 @@ openair_rrc_on_ue( //----------------------------------------------------------------------------- { unsigned short i; - int CC_id; LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" UE?:OPENAIR RRC IN....\n", PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); @@ -4843,9 +4842,6 @@ rrc_rx_tx_ue( //----------------------------------------------------------------------------- { //uint8_t UE_id; - int32_t current_timestamp_ms, ref_timestamp_ms; - struct timeval ts; - struct rrc_eNB_ue_context_s *ue_context_p = NULL,*ue_to_be_removed = NULL; #ifdef LOCALIZATION double estimated_distance; diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index 2a8967a531..9faa686ef6 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -118,7 +118,6 @@ openair_rrc_on( ) //----------------------------------------------------------------------------- { - unsigned short i; int CC_id; LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" ENB:OPENAIR RRC IN....\n", @@ -1232,7 +1231,7 @@ rrc_eNB_generate_RRCConnectionReestablishment( void rrc_eNB_process_RRCConnectionReestablishmentComplete( const protocol_ctxt_t* const ctxt_pP, - const rnti_t const reestablish_rnti, + const rnti_t reestablish_rnti, rrc_eNB_ue_context_t* ue_context_pP, const uint8_t xid, RRCConnectionReestablishmentComplete_r8_IEs_t * rrcConnectionReestablishmentComplete diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 06aad94d30..d909da627f 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -95,6 +95,10 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "enb_config.h" //#include "PHY/TOOLS/time_meas.h" +/* these variables have to be defined before including ENB_APP/enb_paramdef.h */ +static int DEFBANDS[] = {7}; +static int DEFENBS[] = {0}; + #include "ENB_APP/enb_paramdef.h" #include "common/config/config_userapi.h" @@ -1883,7 +1887,6 @@ void configure_ru(int idx, RRU_config_t *config = (RRU_config_t *)arg; RRU_capabilities_t *capabilities = (RRU_capabilities_t*)arg; int ret; - int i; LOG_I(PHY, "Received capabilities from RRU %d\n",idx); @@ -1918,6 +1921,7 @@ void configure_ru(int idx, config->prach_FreqOffset[0],config->prach_ConfigIndex[0]); #ifdef Rel14 + int i; for (i=0;i<4;i++) { config->emtc_prach_CElevel_enable[0][i] = ru->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[i]; config->emtc_prach_FreqOffset[0][i] = ru->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[i]; diff --git a/targets/SIMU/USER/channel_sim.c b/targets/SIMU/USER/channel_sim.c index e2420a1c77..94bd1bbe43 100644 --- a/targets/SIMU/USER/channel_sim.c +++ b/targets/SIMU/USER/channel_sim.c @@ -140,6 +140,7 @@ void do_DL_sig(channel_desc_t *RU2UE[NUMBER_OF_RU_MAX][NUMBER_OF_UE_MAX][MAX_NUM if (!hold_channel) { // calculate the random channel from each RU for (ru_id=0; ru_idframe_parms; random_channel(RU2UE[ru_id][UE_id][CC_id],abstraction_flag); /* diff --git a/targets/SIMU/USER/event_handler.c b/targets/SIMU/USER/event_handler.c index dbdce23df2..e840bde57b 100644 --- a/targets/SIMU/USER/event_handler.c +++ b/targets/SIMU/USER/event_handler.c @@ -685,8 +685,8 @@ void update_mac(Event_t event) LOG_I(EMU,"%" PRIu8 "\n",UE_list->UE_sched_ctrl[event.ue].priority[event.lcid]); } } else if(!strcmp((char *) event.key, "DCI_aggregation_min") && event.value!=NULL && validate_mac(event)) { - Mac_config* mac_config;// = malloc(sizeof(Mac_config)*16); - mac_config = (Mac_config *) event.value; + //Mac_config* mac_config;// = malloc(sizeof(Mac_config)*16); + //mac_config = (Mac_config *) event.value; LOG_I(EMU,"DCI_aggregation_min update \n"); @@ -706,8 +706,8 @@ void update_mac(Event_t event) LOG_I(EMU,"%" PRIu8 "\n",UE_list->UE_template[0][event.ue].DCI_aggregation_min);*/ } } else if(!strcmp((char *) event.key, "DLSCH_dci_size_bits") && event.value!=NULL && validate_mac(event)) { - Mac_config* mac_config;// = malloc(sizeof(Mac_config)*16); - mac_config = (Mac_config *) event.value; + //Mac_config* mac_config;// = malloc(sizeof(Mac_config)*16); + //mac_config = (Mac_config *) event.value; LOG_I(EMU,"DLSCH_dci_size_bits update \n"); diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index b23755c3c1..0008ba3bbd 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -216,7 +216,8 @@ oai_shutdown (void); void reset_opp_meas_oaisim (void); -void wait_eNBs() { +void wait_eNBs(void) +{ return; } @@ -364,7 +365,7 @@ static void set_cli_start(module_id_t module_idP, uint8_t start) #ifdef OPENAIR2 int omv_write(int pfd, node_list* enb_node_list, node_list* ue_node_list, Data_Flow_Unit omv_data) { - module_id_t i, j; + module_id_t i; omv_data.end = 0; //omv_data.total_num_nodes = NB_UE_INST + NB_eNB_INST; @@ -495,7 +496,7 @@ l2l1_task (void *args_p) #undef PRINT_STATS /* this undef is to avoid gcc warnings */ #define PRINT_STATS #ifdef PRINT_STATS - int len; + //int len; FILE *UE_stats[NUMBER_OF_UE_MAX]; FILE *UE_stats_th[NUMBER_OF_UE_MAX]; FILE *eNB_stats[NUMBER_OF_eNB_MAX]; @@ -621,7 +622,6 @@ l2l1_task (void *args_p) } #endif - module_id_t enb_id; module_id_t UE_id; if (abstraction_flag == 1) { @@ -769,11 +769,11 @@ l2l1_task (void *args_p) */ for (ru_id=0;ru_idframe_parms.samples_per_tti; - LOG_D(EMU,"RU %d/%d: TS %llu\n",ru_id,CC_id,current_ru_rx_timestamp[ru_id][CC_id]); + LOG_D(EMU,"RU %d/%d: TS %"PRIi64"\n",ru_id,CC_id,current_ru_rx_timestamp[ru_id][CC_id]); } for (UE_inst = 0; UE_instframe_parms.samples_per_tti; - LOG_D(EMU,"UE %d/%d: TS %llu\n",UE_id,CC_id,current_UE_rx_timestamp[UE_inst][CC_id]); + LOG_D(EMU,"UE %d/%d: TS %"PRIi64"\n",UE_inst,CC_id,current_UE_rx_timestamp[UE_inst][CC_id]); } for (eNB_inst = oai_emulation.info.first_enb_local; @@ -1013,8 +1013,8 @@ int T_dont_fork = 0; /* default is to fork, see 'T_init' to understand */ #endif -void wait_RUs() { - +void wait_RUs(void) +{ int i; // wait for all RUs to be configured over fronthaul @@ -1084,9 +1084,9 @@ static void print_current_directory(void) printf("working directory: %s\n", dir); } -/*------------------------------------------------------------------------------*/ -int -main (int argc, char **argv) +void init_devices(void); + +int main (int argc, char **argv) { clock_t t; @@ -1104,7 +1104,6 @@ main (int argc, char **argv) int node_id; int port,Process_Flag=0,wgt,Channel_Flag=0,temp; #endif - int i; //default parameters oai_emulation.info.n_frames = MAX_FRAME_NUMBER; //1024; //10; @@ -1472,8 +1471,10 @@ print_opp_meas_oaisim (void) &oaisim_stats, &oaisim_stats_f); - print_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_rx, - "[UE][total_phy_proc_rx]", &oaisim_stats, &oaisim_stats_f); + print_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_rx[0], + "[UE][total_phy_proc_rx[0]]", &oaisim_stats, &oaisim_stats_f); + print_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_rx[1], + "[UE][total_phy_proc_rx[1]]", &oaisim_stats, &oaisim_stats_f); // print_meas (&PHY_vars_UE_g[UE_id][0]->ofdm_demod_stats, // "[UE][ofdm_demod]", &oaisim_stats, &oaisim_stats_f); print_meas (&PHY_vars_UE_g[UE_id][0]->rx_dft_stats, "[UE][rx_dft]", @@ -1844,8 +1845,8 @@ get_OAI_emulation () // dummy function declarations -void *rrc_enb_task(void *args_p) { - - +void *rrc_enb_task(void *args_p) +{ + return NULL; } diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c index be8f66fb93..ceaae1958b 100644 --- a/targets/SIMU/USER/oaisim_functions.c +++ b/targets/SIMU/USER/oaisim_functions.c @@ -868,7 +868,7 @@ void check_and_adjust_params(void) { int32_t ret; - int i,j; + //int i,j; if (oai_emulation.info.nb_ue_local + oai_emulation.info.nb_rn_local > NUMBER_OF_UE_MAX) { LOG_E(EMU,"Enter fewer than %d UEs/RNs for the moment or change the NUMBER_OF_UE_MAX\n", NUMBER_OF_UE_MAX); @@ -1081,7 +1081,7 @@ int ru_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void ** while (sample_countframe_parms, UE_id, CC_id); - LOG_D(EMU,"UE %d: DL simulation 6: UE_trx_read @ TS %llu (%llu)=> frame %d, subframe %d\n", - UE_id,(unsigned long long)current_UE_rx_timestamp[UE_id][CC_id], - (unsigned long long)last_UE_rx_timestamp[UE_id][CC_id], - ((unsigned long long)last_UE_rx_timestamp[UE_id][CC_id]/(sptti*10))&1023, + LOG_D(EMU,"UE %d: DL simulation 6: UE_trx_read @ TS %"PRIi64" (%"PRIi64")=> frame %d, subframe %d\n", + UE_id, current_UE_rx_timestamp[UE_id][CC_id], + last_UE_rx_timestamp[UE_id][CC_id], + (int)((last_UE_rx_timestamp[UE_id][CC_id]/(sptti*10))&1023), subframe); last_UE_rx_timestamp[UE_id][CC_id] += read_size; @@ -1367,9 +1367,11 @@ void init_ocm(void) /* Added for PHY abstraction */ - char* frame_type = "unknown"; + /* TODO: frame_type is unused, is it intended? */ + //char* frame_type = "unknown"; LTE_DL_FRAME_PARMS *fp = &RC.ru[0]->frame_parms; +#if 0 switch (fp->frame_type) { case FDD: frame_type = "FDD"; @@ -1379,6 +1381,7 @@ void init_ocm(void) frame_type = "TDD"; break; } +#endif if (abstraction_flag) { From b23a8ad0fe44e4de56373e2af104a68dc41c8aed Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 22 Feb 2018 12:47:23 +0100 Subject: [PATCH 165/195] integation fix: minor typo --- openair2/LAYER2/MAC/defs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index 76b2194612..e3f5d954f1 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -1097,7 +1097,7 @@ typedef struct eNB_MAC_INST_s { /// Prealocated TX pdu list nfapi_tx_request_pdu_t tx_request_pdu[MAX_NUM_CCs][MAX_NUM_TX_REQUEST_PDU]; - /// NFAPI DL PDU structuree + /// NFAPI DL PDU structure nfapi_tx_request_t TX_req[MAX_NUM_CCs]; /// UL handle uint32_t ul_handle; From 37425ee9673675d3c617f5b4126d8a21032e2985 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 22 Feb 2018 11:54:16 +0100 Subject: [PATCH 166/195] bugfix: revert bad change Without this revert, the following does not compile: ./build_oai --oaisim --- openair2/LAYER2/openair2_proc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/openair2/LAYER2/openair2_proc.c b/openair2/LAYER2/openair2_proc.c index 7cb6ce0d2c..f66d1142ab 100644 --- a/openair2/LAYER2/openair2_proc.c +++ b/openair2/LAYER2/openair2_proc.c @@ -228,9 +228,7 @@ int dump_eNB_l2_stats(char *buffer, int length) PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, eNB_id, ENB_FLAG_YES, - /* the following is suspicious, let's put back what was there before */ - /*UE_list->eNB_UE_stats[0][UE_id].crnti,//UE_PCCID(eNB_id,UE_id)][UE_id].crnti, */ - UE_list->eNB_UE_stats[UE_PCCID(eNB_id,UE_id)][UE_id].crnti, + UE_list->eNB_UE_stats[0][UE_id].crnti,//UE_PCCID(eNB_id,UE_id)][UE_id].crnti, eNB->frame, eNB->subframe, eNB_id); From dc0638d7f626fbfae1f9b1f40b89c0007ecc1a20 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Thu, 22 Feb 2018 16:45:18 +0100 Subject: [PATCH 167/195] added compilation directives for nasmesh and ue_ip kernel modules to allow for building on RHEL systems. --- openair2/NETWORK_DRIVER/MESH/device.c | 4 ++-- openair2/NETWORK_DRIVER/UE_IP/device.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openair2/NETWORK_DRIVER/MESH/device.c b/openair2/NETWORK_DRIVER/MESH/device.c index 086ec3909c..f8a420697a 100644 --- a/openair2/NETWORK_DRIVER/MESH/device.c +++ b/openair2/NETWORK_DRIVER/MESH/device.c @@ -241,7 +241,7 @@ int nas_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) // End debug information netif_stop_queue(dev); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) || RHEL_RELEASE_CODE>=1796 netif_trans_update(dev); #else dev->trans_start = jiffies; @@ -306,7 +306,7 @@ void nas_tx_timeout(struct net_device *dev) printk("TX_TIMEOUT: begin\n"); // (struct nas_priv *)(dev->priv)->stats.tx_errors++; (priv->stats).tx_errors++; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) || RHEL_RELEASE_CODE>=1796 netif_trans_update(dev); #else dev->trans_start = jiffies; diff --git a/openair2/NETWORK_DRIVER/UE_IP/device.c b/openair2/NETWORK_DRIVER/UE_IP/device.c index 29db4ae07a..36c6afe914 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/device.c +++ b/openair2/NETWORK_DRIVER/UE_IP/device.c @@ -236,7 +236,7 @@ int ue_ip_hard_start_xmit(struct sk_buff *skb_pP, struct net_device *dev_pP) // End debug information netif_stop_queue(dev_pP); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) || RHEL_RELEASE_CODE >= 1796 netif_trans_update(dev_pP); #else dev_pP->trans_start = jiffies; @@ -312,7 +312,7 @@ void ue_ip_tx_timeout(struct net_device *dev_pP) printk("[UE_IP_DRV][%s] begin\n", __FUNCTION__); // (ue_ip_priv_t *)(dev_pP->priv_p)->stats.tx_errors++; (priv_p->stats).tx_errors++; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) || RHEL_RELEASE_CODE >= 1796 netif_trans_update(dev_pP); #else dev_pP->trans_start = jiffies; From 7d8d1588c31e12410ac08cd420dd23b8c4035203 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 1 Mar 2018 09:04:41 +0100 Subject: [PATCH 168/195] remove unnecessary function declaration has been introduced in commit 365ca71a4ab9d06f56c47e22d2a9450dba715572 --- openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 7486594d4d..0997f2b435 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -40,8 +40,6 @@ #include "log.h" -extern int flexran_get_harq_round(mid_t mod_id, uint8_t cc_id, mid_t ue_id); - /*Flags showing if a mac agent has already been registered*/ unsigned int mac_agent_registered[NUM_MAX_ENB]; From 26d68e9c5e624c3719f9d86f1ba8a9f5739c832f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 2 Mar 2018 12:02:06 +0100 Subject: [PATCH 169/195] hotfix: fix bad RLC UM packet creation Running TCP DL traffic with one connected UE showed a lot of fluctuations in throughput. After analysis it was found that sometimes the RLC UM PDU was not correct. It contained one byte more than it should. On the receiver side, the TCP packet contained in the RLC packet seems to be rejected by the TCP stack of the UE (it has one byte more than it should), leading to a brutal reduction of the throughput, probably due to some congestion detection in the TCP implementation. Or something. This hotfix seems to solve the problem. Using iperf in downlink with a 5MHz eNB, we see no more fluctuations, the traffic is very steady at 16.8Mb/s, as reported by the iperf server running on the phone. (17.5 in the PHY plot of the T tracer.) A rewrite of both the MAC and RLC UM packet generation is needed. The code is way too complex for what it does and may contain several similar problems that only trigger in specific rare conditions. --- openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_segment.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_segment.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_segment.c index f9af7c1cc2..98a44ceeeb 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_segment.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_segment.c @@ -172,7 +172,7 @@ rlc_um_segment_10 (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t *rlc_pP test_pdu_remaining_size = 0; test_remaining_size_to_substract = 0; test_remaining_num_li_to_substract = 0; - pdu_remaining_size = pdu_remaining_size - (test_li_length_in_bytes ^ 3); + //pdu_remaining_size = pdu_remaining_size - (test_li_length_in_bytes ^ 3); } else if ((sdu_mngt_p->sdu_remaining_size + (test_li_length_in_bytes ^ 3)) < test_pdu_remaining_size ) { test_num_li += 1; num_fill_sdu += 1; @@ -365,9 +365,9 @@ rlc_um_segment_10 (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t *rlc_pP sdu_mngt_p->sdu_remaining_size, pdu_remaining_size - sdu_mngt_p->sdu_remaining_size); #endif -#if !EXMIMO - assert(1!=1); -#endif +//#if !EXMIMO +// assert(1!=1); +//#endif memcpy(data, data_sdu_p, sdu_mngt_p->sdu_remaining_size); // reduce the size of the PDU continue_fill_pdu_with_sdu = 0; From 8cace6537e6c66a6608c970fd3117b43ead2da7b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 2 Mar 2018 14:51:37 +0100 Subject: [PATCH 170/195] correctly check for MAC presence in FlexRAN RAN API --- openair2/ENB_APP/flexran_agent_ran_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 61757d0703..a65d352392 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -131,7 +131,7 @@ int8_t flexran_get_ue_phr(mid_t mod_id, mid_t ue_id) uint8_t flexran_get_ue_wcqi(mid_t mod_id, mid_t ue_id) { - if (!phy_is_present(mod_id, 0)) return 0; + if (!mac_is_present(mod_id)) return 0; return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].dl_cqi[0]; } From 4924b18ebd2e76aa09f1a9f6f2d6692df2dfec56 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 2 Mar 2018 14:52:12 +0100 Subject: [PATCH 171/195] FlexRAN: send RNTI in protobuf mac_stats_reply message --- openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 0997f2b435..6cb79efb11 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -70,7 +70,8 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, for (i = 0; i < report_config->nr_ue; i++) { - + ue_report[i]->rnti = report_config->ue_report_type[i].ue_rnti; + ue_report[i]->has_rnti = 1; /* Check flag for creation of buffer status report */ if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_BSR) { From bcaabe513f68a720b6692abd7566b9dbbf91aa34 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Tue, 6 Mar 2018 23:32:51 +0100 Subject: [PATCH 172/195] bugfix on access of avgU array --- openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c index ee038508d1..4b2e81c499 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c @@ -1127,7 +1127,7 @@ void rx_ulsch(PHY_VARS_eNB *eNB, uint32_t l,i; int32_t avgs; uint8_t log2_maxh=0,aarx; - int32_t avgU[2]; + int32_t avgU[eNB->frame_parms.nb_antennas_rx]; // uint8_t harq_pid = ( ulsch->RRCConnRequest_flag== 0) ? subframe2harq_pid_tdd(frame_parms->tdd_config,subframe) : 0; @@ -1212,7 +1212,7 @@ void rx_ulsch(PHY_VARS_eNB *eNB, avgs = 0; for (aarx=0; aarxnb_antennas_rx; aarx++) - avgs = cmax(avgs,avgU[(aarx<<1)]); + avgs = cmax(avgs,avgU[aarx]); // log2_maxh = 4+(log2_approx(avgs)/2); From 957cdbab480eb8126eaa2a1c410e5575c25964b4 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Wed, 7 Mar 2018 01:26:04 +0100 Subject: [PATCH 173/195] fixes bug in ulsim for 2 antenna RX. --- openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c | 2 +- openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c | 2 +- openair1/PHY/MODULATION/slot_fep_ul.c | 2 ++ openair1/SIMULATION/LTE_PHY/ulsim.c | 6 +++--- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c index 9c91d28ade..9ef23f23d0 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c @@ -291,7 +291,7 @@ int32_t temp_in_ifft_0[2048*2] __attribute__((aligned(32))); #ifdef DEBUG_CH - if (aa==0) { + if (aa==1) { if (Ns == 0) { write_output("rxdataF_ext.m","rxF_ext",&rxdataF_ext[aa][symbol_offset],512*2,2,1); write_output("tmpin_ifft.m","drs_in",temp_in_ifft_0,512,1,1); diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c index 4b2e81c499..920d8ff3fd 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c @@ -1395,7 +1395,7 @@ void rx_ulsch_emul(PHY_VARS_eNB *eNB, if (eNB->frame_parms.nb_antennas_rx>1) { sprintf(fname,"/tmp/rxsigF1_ext_r%d.m",round); sprintf(vname,"rxsF1_ext_r%d",round); - write_output(fname,vname,&eNB->pusch_vars[UE_id]->rxdataF_ext[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + write_output(fname,vname,&eNB->pusch_vars[UE_id]->rxdataF_ext[1][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); } /* if (eNB->srs_vars[UE_id].srs_ch_estimates) write_output("/tmp/srs_est0.m","srsest0",eNB->srs_vars[UE_id].srs_ch_estimates[0],eNB->frame_parms.ofdm_symbol_size,1,1); diff --git a/openair1/PHY/MODULATION/slot_fep_ul.c b/openair1/PHY/MODULATION/slot_fep_ul.c index f41fc98791..5beb7eccfd 100644 --- a/openair1/PHY/MODULATION/slot_fep_ul.c +++ b/openair1/PHY/MODULATION/slot_fep_ul.c @@ -24,6 +24,8 @@ #include "defs.h" //#define DEBUG_FEP + + int slot_fep_ul(RU_t *ru, unsigned char l, unsigned char Ns, diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index d6009bc793..fc782be07a 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -859,8 +859,8 @@ int main(int argc, char **argv) printf("PUSCH Beta : ACK %f, RI %f, CQI %f\n",(double)beta_ack[beta_ACK]/8,(double)beta_ri[beta_RI]/8,(double)beta_cqi[beta_CQI]/8); - UE2eNB = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx, - UE->frame_parms.nb_antennas_rx, + UE2eNB = new_channel_desc_scm(1, + n_rx, channel_model, N_RB2sampling_rate(eNB->frame_parms.N_RB_UL), N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL), @@ -1330,7 +1330,7 @@ int main(int argc, char **argv) printf("SNRmeas %f\n",SNRmeas); write_output("rxsig0UL.m","rxs0", &ru->common.rxdata[0][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1); - // write_output("rxsig1UL.m","rxs1", &ru->common_vars.rxdata[0][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1); + if (eNB->frame_parms.nb_antennas_rx>1) write_output("rxsig1UL.m","rxs1", &ru->common.rxdata[1][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1); } From 1a8d81ba57e04532094330d32eddace546068ec4 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 7 Mar 2018 16:11:36 +0100 Subject: [PATCH 174/195] cleanup MAC PDU generation (plus some general cleanup) The code was very unclear and potentially buggy. This new version is more robust. We can waste up to 2 bytes because the last header in the MAC PDU does not contain a length field and when we request data from RLC we suppose a 3-bytes MAC header. This might be optimized at some point, but the benefit would be low. This commit also contains some general cleanup: - formatting - variables' types: let's use 'int' instead of trying to be clever by using small types that may generate bugs if the value is too big - remove 'tpc_accumulated' which was globally used for all UEs and has no purpose other than logging. We may want to rework a bit the TPC machinery at some point. As the code is today we may repeatedly send TPC over and over without caring about the 3GPP limits, in which case no one knows how the UE is supposed to behave: does it clamp the current max value or does it accumulate over and over and take the clamped value to compute its actual power? If we send a reverse TPC (reduce power instead of increase) does it do it immediately or does it have to decrease n+1 times if we previously ordered it to increase n times?) We do not address the problem of prioritizing LCIDs. As of today there is only one dedicated traffic channel (DTCH), so it's not a problem at this point. What has been tested: - monolithic eNB 5/10/20MHz with one cots UE, TCP/UDP UL/DL. At 20MHz the machine used was not capable of keeping up, generating lots of Us and Ls when the throughput reaches 60Mb/s. USRP B210 was used. --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 273 +++++++++------------- openair2/LAYER2/MAC/proto.h | 18 +- 2 files changed, 125 insertions(+), 166 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index aeaa55a79a..0729073eba 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -154,7 +154,7 @@ schedule_next_dlue(module_id_t module_idP, int CC_id, } //------------------------------------------------------------------------------ -unsigned char +int generate_dlsch_header(unsigned char *mac_header, unsigned char num_sdus, unsigned short *sdu_lengths, @@ -344,7 +344,6 @@ generate_dlsch_header(unsigned char *mac_header, //msg("After CEs %d\n",(uint8_t*)mac_header_ptr - mac_header); return ((unsigned char *) mac_header_ptr - mac_header); - } //------------------------------------------------------------------------------ @@ -563,33 +562,28 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) //------------------------------------------------------------------------------ { - - - uint8_t CC_id; + int CC_id; int UE_id; - unsigned char aggregation; + int aggregation; mac_rlc_status_resp_t rlc_status; - unsigned char header_len_dcch = 0, header_len_dcch_tmp = 0; - unsigned char header_len_dtch = 0, header_len_dtch_tmp = - 0, header_len_dtch_last = 0; - unsigned char ta_len = 0; - unsigned char sdu_lcids[NB_RB_MAX], lcid, offset, num_sdus = 0; - uint16_t nb_rb, nb_rb_temp, nb_available_rb; - uint16_t TBS, j, sdu_lengths[NB_RB_MAX], rnti, padding = - 0, post_padding = 0; + int ta_len = 0; + unsigned char sdu_lcids[NB_RB_MAX]; + int lcid, offset, num_sdus = 0; + int nb_rb, nb_rb_temp, nb_available_rb; + uint16_t sdu_lengths[NB_RB_MAX]; + int TBS, j, rnti, padding = 0, post_padding = 0; unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; - unsigned char round = 0; - unsigned char harq_pid = 0; + int round = 0; + int harq_pid = 0; eNB_UE_STATS *eNB_UE_stats = NULL; - uint16_t sdu_length_total = 0; + int sdu_length_total = 0; eNB_MAC_INST *eNB = RC.mac[module_idP]; COMMON_channels_t *cc = eNB->common_channels; UE_list_t *UE_list = &eNB->UE_list; int continue_flag = 0; int32_t normalized_rx_power, target_rx_power; - int32_t tpc = 1; - static int32_t tpc_accumulated = 0; + int tpc = 1; UE_sched_ctrl *ue_sched_ctl; int mcs; int i; @@ -601,6 +595,8 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, nfapi_dl_config_request_pdu_t *dl_config_pdu; int tdd_sfa; int ta_update; + int header_length_last; + int header_length_total; #if 0 if (UE_list->head == -1) { @@ -792,6 +788,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < RRC_CONNECTED) continue; + header_length_total = 0; sdu_length_total = 0; num_sdus = 0; @@ -838,8 +835,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, if (cc[CC_id].tdd_Config != NULL) { UE_list->UE_template[CC_id][UE_id].DAI++; update_ul_dci(module_idP, CC_id, rnti, - UE_list->UE_template[CC_id][UE_id]. - DAI); + UE_list->UE_template[CC_id][UE_id].DAI); LOG_D(MAC, "DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n", CC_id, subframeP, UE_id, @@ -988,13 +984,12 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, module_idP, frameP, CC_id, UE_id); } } else { /* This is a potentially new SDU opportunity */ - rlc_status.bytes_in_buffer = 0; + // Now check RLC information to compute number of required RBs // get maximum TBS size for RLC request - TBS = - get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb); - // check first for RLC data on DCCH + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb); + // add the length for all the control elements (timing adv, drx, etc) : header + payload if (ue_sched_ctl->ta_timer == 0) { @@ -1009,38 +1004,42 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, ta_len = (ta_update != 31) ? 2 : 0; - header_len_dcch = 2; // 2 bytes DCCH SDU subheader - - if (TBS - ta_len - header_len_dcch > 0) { - rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, (TBS - ta_len - header_len_dcch)); // transport block set size + // RLC data on DCCH + if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { + rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, + TBS - ta_len - header_length_total - sdu_length_total - 3); sdu_lengths[0] = 0; - if (rlc_status.bytes_in_buffer > 0) { // There is DCCH to transmit - LOG_D(MAC, - "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", + if (rlc_status.bytes_in_buffer > 0) { + LOG_D(MAC, "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", module_idP, frameP, subframeP, CC_id, - TBS - header_len_dcch); - sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, TBS, //not used - (char *) - &dlsch_buffer - [0]); + TBS - ta_len - header_length_total - sdu_length_total - 3); + + sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, + TBS, //not used + (char *)&dlsch_buffer[0]); T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), T_INT(DCCH), T_INT(sdu_lengths[0])); - LOG_D(MAC, - "[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n", + LOG_D(MAC, "[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n", module_idP, CC_id, sdu_lengths[0]); + sdu_length_total = sdu_lengths[0]; sdu_lcids[0] = DCCH; UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[0] = DCCH; UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[DCCH] = sdu_lengths[0]; UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH] += 1; UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH] += sdu_lengths[0]; + + header_length_last = 1 + 1 + (sdu_lengths[0] >= 128); + header_length_total += header_length_last; + num_sdus = 1; + #ifdef DEBUG_eNB_SCHEDULER LOG_T(MAC, "[eNB %d][DCCH] CC_id %d Got %d bytes :", @@ -1052,26 +1051,25 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, LOG_T(MAC, "\n"); #endif - } else { - header_len_dcch = 0; - sdu_length_total = 0; } } - // check for DCCH1 and update header information (assume 2 byte sub-header) - if (TBS - ta_len - header_len_dcch - sdu_length_total > 0) { - rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, (TBS - ta_len - header_len_dcch - sdu_length_total)); // transport block set size less allocations for timing advance and + + // RLC data on DCCH1 + if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { + rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, + TBS - ta_len - header_length_total - sdu_length_total - 3); + // DCCH SDU sdu_lengths[num_sdus] = 0; if (rlc_status.bytes_in_buffer > 0) { - LOG_D(MAC, - "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n", + LOG_D(MAC, "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n", module_idP, frameP, CC_id, - TBS - header_len_dcch - sdu_length_total); - sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, TBS, //not used - (char *) - &dlsch_buffer - [sdu_length_total]); + TBS - ta_len - header_length_total - sdu_length_total - 3); + + sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, + TBS, //not used + (char *)&dlsch_buffer[sdu_length_total]); T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), @@ -1080,13 +1078,16 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, sdu_lcids[num_sdus] = DCCH1; sdu_length_total += sdu_lengths[num_sdus]; - header_len_dcch += 2; UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = DCCH1; UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[DCCH1] = sdu_lengths[num_sdus]; - UE_list->eNB_UE_stats[CC_id][UE_id]. - num_pdu_tx[DCCH1] += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH1] += 1; UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1] += sdu_lengths[num_sdus]; + + header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); + header_length_total += header_length_last; + num_sdus++; + #ifdef DEBUG_eNB_SCHEDULER LOG_T(MAC, "[eNB %d][DCCH1] CC_id %d Got %d bytes :", @@ -1098,25 +1099,18 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, LOG_T(MAC, "\n"); #endif - } } - // assume the max dtch header size, and adjust it later - header_len_dtch = 0; - header_len_dtch_last = 0; // the header length of the last mac sdu - // lcid has to be sorted before the actual allocation (similar struct as ue_list). + + // TODO: lcid has to be sorted before the actual allocation (similar struct as ue_list). for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { - // TBD: check if the lcid is active + // TODO: check if the lcid is active - header_len_dtch += 3; - header_len_dtch_last = 3; - LOG_D(MAC, - "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", + LOG_D(MAC, "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", module_idP, frameP, lcid, TBS, - TBS - ta_len - header_len_dcch - - sdu_length_total - header_len_dtch); + TBS - ta_len - header_length_total - sdu_length_total - 3); - if (TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch > 0) { // NN: > 2 ? + if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, @@ -1125,25 +1119,22 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, - TBS - ta_len - - header_len_dcch - - sdu_length_total - - header_len_dtch); + TBS - ta_len - header_length_total - sdu_length_total - 3); + if (rlc_status.bytes_in_buffer > 0) { - LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n", module_idP, frameP, - TBS - header_len_dcch - - sdu_length_total - header_len_dtch, lcid, - header_len_dtch); - sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, TBS, //not used - (char - *) - &dlsch_buffer - [sdu_length_total]); + TBS - ta_len - header_length_total - sdu_length_total - 3, + lcid, + header_length_total); + + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, + TBS, //not used + (char *)&dlsch_buffer[sdu_length_total]); + T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), @@ -1152,50 +1143,39 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", module_idP, sdu_lengths[num_sdus], lcid); + sdu_lcids[num_sdus] = lcid; sdu_length_total += sdu_lengths[num_sdus]; - UE_list-> - eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid] - += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid]++; UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = lcid; UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[lcid] = sdu_lengths[num_sdus]; - UE_list-> - eNB_UE_stats[CC_id][UE_id].num_bytes_tx - [lcid] += sdu_lengths[num_sdus]; - if (sdu_lengths[num_sdus] < 128) { - header_len_dtch--; - header_len_dtch_last--; - } + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[num_sdus]; + + header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); + header_length_total += header_length_last; + num_sdus++; + UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; - } // no data for this LCID - else { - header_len_dtch -= 3; } - } // no TBS left - else { - header_len_dtch -= 3; + } else { + // no TBS left break; } } - if (header_len_dtch == 0) - header_len_dtch_last = 0; - // there is at least one SDU + + /* last header does not have length field */ + if (header_length_total) { + header_length_total -= header_length_last; + header_length_total++; + } + + // there is at least one SDU or TA command // if (num_sdus > 0 ){ - if ((sdu_length_total + header_len_dcch + - header_len_dtch) > 0) { + if (ta_len + sdu_length_total + header_length_total > 0) { // Now compute number of required RBs for total sdu length // Assume RAH format 2 - // adjust header lengths - header_len_dcch_tmp = header_len_dcch; - header_len_dtch_tmp = header_len_dtch; - if (header_len_dtch == 0) { - header_len_dcch = (header_len_dcch > 0) ? 1 : 0; //header_len_dcch; // remove length field - } else { - header_len_dtch_last -= 1; // now use it to find how many bytes has to be removed for the last MAC SDU - header_len_dtch = (header_len_dtch > 0) ? header_len_dtch - header_len_dtch_last : header_len_dtch; // remove length field for the last SDU - } mcs = eNB_UE_stats->dlsch_mcs1; @@ -1207,16 +1187,12 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, TBS = get_TBS_DL(mcs, nb_rb); - while (TBS < - (sdu_length_total + header_len_dcch + - header_len_dtch + ta_len)) { + while (TBS < sdu_length_total + header_length_total + ta_len) { nb_rb += min_rb_unit[CC_id]; // if (nb_rb > nb_available_rb) { // if we've gone beyond the maximum number of RBs // (can happen if N_RB_DL is odd) - TBS = - get_TBS_DL(eNB_UE_stats->dlsch_mcs1, - nb_available_rb); + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb); nb_rb = nb_available_rb; break; } @@ -1250,13 +1226,13 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, } // decrease mcs until TBS falls below required length - while ((TBS > (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && (mcs > 0)) { + while ((TBS > sdu_length_total + header_length_total + ta_len) && (mcs > 0)) { mcs--; TBS = get_TBS_DL(mcs, nb_rb); } // if we have decreased too much or we don't have enough RBs, increase MCS - while ((TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) + while ((TBS < sdu_length_total + header_length_total + ta_len) && (((ue_sched_ctl->dl_pow_off[CC_id] > 0) && (mcs < 28)) || ((ue_sched_ctl->dl_pow_off[CC_id] == 0) @@ -1277,23 +1253,14 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, // TBS, sdu_length_total, offset, TBS-sdu_length_total-offset); #endif - if ((TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len) <= 2) { - padding = (TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len); + if (TBS - header_length_total - sdu_length_total - ta_len <= 2) { + padding = TBS - header_length_total - sdu_length_total - ta_len; post_padding = 0; } else { padding = 0; - - // adjust the header len - if (header_len_dtch == 0) { - header_len_dcch = header_len_dcch_tmp; - } else { //if (( header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2))) - header_len_dtch = header_len_dtch_tmp; - } - - post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len; // 1 is for the postpadding header + post_padding = 1; } - offset = generate_dlsch_header((unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], num_sdus, //num_sdus sdu_lengths, // sdu_lcids, 255, // no drx @@ -1304,12 +1271,12 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, //#ifdef DEBUG_eNB_SCHEDULER if (ta_update != 31) { LOG_D(MAC, - "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_dcch %d, header_dtch %d\n", + "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_length %d\n", module_idP, frameP, UE_id, CC_id, sdu_length_total, num_sdus, sdu_lengths[0], sdu_lcids[0], offset, ta_update, padding, post_padding, mcs, TBS, nb_rb, - header_len_dcch, header_len_dtch); + header_length_total); } //#endif #ifdef DEBUG_eNB_SCHEDULER @@ -1327,11 +1294,16 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, dlsch_buffer, sdu_length_total); // memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); +#if 0 // fill remainder of DLSCH with random data for (j = 0; j < (TBS - sdu_length_total - offset); j++) { UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + sdu_length_total + j] = (char) (taus() & 0xff); } - +#endif + // fill remainder of DLSCH with 0 + for (j = 0; j < (TBS - sdu_length_total - offset); j++) { + UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + sdu_length_total + j] = 0; + } if (opt_enabled == 1) { trace_pdu(1, (uint8_t *) @@ -1348,8 +1320,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), - T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id]. - payload[0], TBS)); + T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS)); UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb; @@ -1378,6 +1349,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, UE_list->UE_template[CC_id][UE_id]. DAI); } + // do PUCCH power control // this is the normalized RX power eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; @@ -1399,18 +1371,15 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, if (normalized_rx_power > (target_rx_power + 4)) { tpc = 0; //-1 - tpc_accumulated--; } else if (normalized_rx_power < (target_rx_power - 4)) { tpc = 2; //+1 - tpc_accumulated++; } else { tpc = 1; //0 } LOG_D(MAC, - "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", - module_idP, frameP, subframeP, harq_pid, - tpc, tpc_accumulated, + "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, normalized/target rx power %d/%d\n", + module_idP, frameP, subframeP, harq_pid, tpc, normalized_rx_power, target_rx_power); } // Po_PUCCH has been updated @@ -1456,13 +1425,13 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, module_idP, CC_id, harq_pid, mcs); } + LOG_D(MAC, "Checking feasibility pdu %d (new sdu)\n", dl_req->number_pdu); + if (!CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, dl_config_pdu->dci_dl_pdu. dci_dl_pdu_rel8.aggregation_level, rnti)) { - - ue_sched_ctl->round[CC_id][harq_pid] = 0; dl_req->number_dci++; dl_req->number_pdu++; @@ -1482,8 +1451,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid] = 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs; UE_list->UE_template[CC_id][UE_id].oldmcs2[harq_pid] = 0; - AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != - NULL, + AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is NULL\n"); AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated != NULL, "physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n"); @@ -1506,15 +1474,10 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, 0, //number of PRBs treated as one subband, not used here 0 // number of beamforming vectors, not used here ); - eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB-> - TX_req - [CC_id].tx_request_body, + eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_id].tx_request_body, (frameP * 10) + subframeP, TBS, eNB->pdu_index[CC_id], - eNB-> - UE_list.DLSCH_pdu[CC_id][0][(unsigned char) - UE_id].payload - [0]); + eNB->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0]); LOG_D(MAC, "Filled NFAPI configuration for DCI/DLSCH/TXREQ %d, new SDU\n", @@ -1523,10 +1486,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, eNB->pdu_index[CC_id]++; program_dlsch_acknak(module_idP, CC_id, UE_id, frameP, subframeP, - dl_config_pdu-> - dci_dl_pdu.dci_dl_pdu_rel8. - cce_idx); - + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); } else { LOG_W(MAC, "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d/%x, infeasible CCE allocations\n", @@ -1550,7 +1510,6 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, stop_meas(&eNB->schedule_dlsch); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT); - } //------------------------------------------------------------------------------ diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/proto.h index 07159f9c24..2586c94f43 100644 --- a/openair2/LAYER2/MAC/proto.h +++ b/openair2/LAYER2/MAC/proto.h @@ -855,15 +855,15 @@ in the DLSCH buffer. @param post_padding number of bytes for padding at the end of MAC PDU @returns Number of bytes used for header */ -unsigned char generate_dlsch_header(unsigned char *mac_header, - unsigned char num_sdus, - unsigned short *sdu_lengths, - unsigned char *sdu_lcids, - unsigned char drx_cmd, - unsigned short timing_advance_cmd, - unsigned char *ue_cont_res_id, - unsigned char short_padding, - unsigned short post_padding); +int generate_dlsch_header(unsigned char *mac_header, + unsigned char num_sdus, + unsigned short *sdu_lengths, + unsigned char *sdu_lcids, + unsigned char drx_cmd, + unsigned short timing_advance_cmd, + unsigned char *ue_cont_res_id, + unsigned char short_padding, + unsigned short post_padding); /** \brief RRC eNB Configuration primitive for PHY/MAC. Allows configuration of PHY/MAC resources based on System Information (SI), RRCConnectionSetup and RRCConnectionReconfiguration messages. @param Mod_id Instance ID of eNB From 5a61f9944c93bc33157361330dbdc5165427330c Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 8 Mar 2018 09:58:13 +0100 Subject: [PATCH 175/195] cleanup - remove unnecessary calls to get_cpu_freq_GHz The one in lte-enb.c disrupts the realtime. Using a B200mini with 20MHz bandwidth leads to the UE unable to connect for it seesms like the UL and DL are not properly time synched because of this sleep of one second that happens after the USRP streaming has started. We see some random access attempts but the decoded preamble is wrong. This may be dependant on the setup. I had sporadic errors with a B210, where sometimes the UE could connect and sometimes not. --- targets/RT/USER/lte-enb.c | 7 ------- targets/RT/USER/lte-softmodem.c | 6 ++---- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 01a2c68bf3..e1c5d10de5 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -163,13 +163,6 @@ extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset); static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_name) { - - static double cpu_freq_GHz = 0.0; - - if (cpu_freq_GHz == 0.0) - cpu_freq_GHz = get_cpu_freq_GHz(); - - start_meas(&softmodem_stats_rxtx_sf); // ******************************************************************* diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index f6789086b4..0564049c70 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1249,10 +1249,8 @@ int main( int argc, char **argv ) printf("Runtime table\n"); fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx); - cpuf=get_cpu_freq_GHz(); - - - + + #ifndef DEADLINE_SCHEDULER printf("NO deadline scheduler\n"); From 963805820c9a0b0deff845d44fe116cda5013cc3 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 8 Mar 2018 10:17:16 +0100 Subject: [PATCH 176/195] add a stop_rf function in the RU When the program exits it has to stop the streaming of the USRP. The function exit_fun is supposed to do that. When quitting with control+c (very common case) this function is not called. The code is very unclear there, so let's add a stop_rf in the RU, as there is already a start_rf. If we don't call trx_end_func, then at the next run the USRP device may be in an unstable state and behave improperly. If the program crashes then the USRP device may be in an unstable state. The only solution to this problem is to reset the USRP device. Maybe there is a way to clean the state of the device when we open it, before we start using it. Sort of a cleanup before use. That could be a better solution to "bad state after program crash". What has been tested: - monolithic eNB only --- openair1/PHY/defs.h | 2 ++ targets/RT/USER/lte-ru.c | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index 46f37e9431..a0f37dd885 100644 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -738,6 +738,8 @@ typedef struct RU_t_s{ void (*fh_south_asynch_in)(struct RU_t_s *ru,int *frame, int *subframe); /// function pointer to initialization function for radio interface int (*start_rf)(struct RU_t_s *ru); + /// function pointer to release function for radio interface + int (*stop_rf)(struct RU_t_s *ru); /// function pointer to initialization function for radio interface int (*start_if)(struct RU_t_s *ru,struct PHY_VARS_eNB_s *eNB); /// function pointer to RX front-end processing routine (DFTs/prefix removal or NULL) diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index d909da627f..d9bda6a037 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -1523,7 +1523,13 @@ static void* ru_thread( void* param ) { printf( "Exiting ru_thread \n"); - + + if (ru->stop_rf != NULL) { + if (ru->stop_rf(ru) != 0) + LOG_E(HW,"Could not stop the RF device\n"); + else LOG_I(PHY,"RU %d rf device stopped\n",ru->idx); + } + ru_thread_status = 0; return &ru_thread_status; @@ -1617,6 +1623,12 @@ int start_rf(RU_t *ru) { return(ru->rfdevice.trx_start_func(&ru->rfdevice)); } +int stop_rf(RU_t *ru) +{ + ru->rfdevice.trx_end_func(&ru->rfdevice); + return 0; +} + extern void fep_full(RU_t *ru); extern void ru_fep_full_2thread(RU_t *ru); extern void feptx_ofdm(RU_t *ru); @@ -2082,6 +2094,7 @@ void set_function_spec_param(RU_t *ru) ru->fh_south_in = rx_rf; // local synchronous RF RX ru->fh_south_out = tx_rf; // local synchronous RF TX ru->start_rf = start_rf; // need to start the local RF interface + ru->stop_rf = stop_rf; printf("configuring ru_id %d (start_rf %p)\n", ru->idx, start_rf); /* if (ru->function == eNodeB_3GPP) { // configure RF parameters only for 3GPP eNodeB, we need to get them from RAU otherwise @@ -2113,6 +2126,7 @@ void set_function_spec_param(RU_t *ru) ru->fh_south_asynch_in = NULL; // no asynchronous UL } ru->start_rf = NULL; // no local RF + ru->stop_rf = NULL; ru->start_if = start_if; // need to start if interface for IF5 ru->ifdevice.host_type = RAU_HOST; ru->ifdevice.eth_params = &ru->eth_params; @@ -2137,6 +2151,7 @@ void set_function_spec_param(RU_t *ru) ru->fh_north_out = NULL; ru->fh_north_asynch_in = NULL; ru->start_rf = NULL; // no local RF + ru->stop_rf = NULL; ru->start_if = start_if; // need to start if interface for IF4p5 ru->ifdevice.host_type = RAU_HOST; ru->ifdevice.eth_params = &ru->eth_params; From 45302792ee875a905cd6ec82c8af812fe9ba316a Mon Sep 17 00:00:00 2001 From: oai Date: Fri, 23 Feb 2018 15:37:24 +0100 Subject: [PATCH 177/195] config module fix and extensions for Nb-IoT, shared lib loader and telnet server implementation --- cmake_targets/CMakeLists.txt | 24 +- cmake_targets/build_oai | 18 +- common/config/config_load_configmodule.c | 31 +- common/config/config_load_configmodule.h | 21 +- common/config/config_paramdesc.h | 74 ++- common/config/config_userapi.c | 135 +++- common/config/config_userapi.h | 28 +- common/config/libconfig/config_libconfig.c | 51 +- common/ran_context.h | 14 +- common/utils/load_module_shlib.c | 127 +++- common/utils/load_module_shlib.h | 39 +- common/utils/telnetsrv/CMakeLists.txt | 59 -- common/utils/telnetsrv/telnetsrv.c | 228 +++++-- common/utils/telnetsrv/telnetsrv.h | 11 +- .../utils/telnetsrv/telnetsrv_CMakeLists.txt | 28 + common/utils/telnetsrv/telnetsrv_loader.c | 84 +++ common/utils/telnetsrv/telnetsrv_loader.h | 55 ++ common/utils/telnetsrv/telnetsrv_phycmd.c | 4 +- common/utils/telnetsrv/telnetsrv_phycmd.h | 4 +- common/utils/telnetsrv/telnetsrv_proccmd.c | 189 +++++- common/utils/telnetsrv/telnetsrv_proccmd.h | 29 +- openair1/PHY/CODING/3gpplte.c | 10 +- openair1/PHY/CODING/3gpplte_sse.c | 33 +- openair1/PHY/CODING/3gpplte_turbo_decoder.c | 4 +- .../CODING/3gpplte_turbo_decoder_avx2_16bit.c | 38 +- .../CODING/3gpplte_turbo_decoder_sse_16bit.c | 2 +- .../CODING/3gpplte_turbo_decoder_sse_8bit.c | 2 +- openair1/PHY/CODING/coding_load.c | 134 ++++ openair1/PHY/CODING/defs.h | 32 +- openair1/PHY/CODING/extern.h | 8 +- openair1/PHY/INIT/init_top.c | 15 +- openair1/PHY/LTE_TRANSPORT/dlsch_coding.c | 56 +- openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c | 23 +- openair1/PHY/LTE_TRANSPORT/ulsch_coding.c | 14 +- openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c | 69 +- openair1/PHY/defs.h | 47 ++ openair1/SCHED/phy_procedures_lte_eNb.c | 2 +- openair2/ENB_APP/L1_paramdef.h | 73 ++ openair2/ENB_APP/MACRLC_paramdef.h | 98 +++ openair2/ENB_APP/RRC_config_tools.c | 123 ++++ openair2/ENB_APP/RRC_config_tools.h | 50 ++ openair2/ENB_APP/RRC_paramsvalues.h | 94 +++ openair2/ENB_APP/enb_config.c | 624 ++---------------- openair2/ENB_APP/enb_paramdef.h | 320 +++++---- openair2/ENB_APP/nbiot_config.c | 295 +++++++++ openair2/ENB_APP/nbiot_config.h | 37 ++ openair2/ENB_APP/nbiot_paramdef.h | 400 +++++++++++ openair2/UTIL/LOG/log.c | 7 +- openair2/UTIL/LOG/log.h | 16 +- targets/ARCH/COMMON/common_lib.c | 53 +- targets/ARCH/COMMON/common_lib.h | 4 +- targets/RT/USER/lte-softmodem.c | 69 +- targets/RT/USER/lte-softmodem.h | 7 +- 53 files changed, 2729 insertions(+), 1283 deletions(-) delete mode 100644 common/utils/telnetsrv/CMakeLists.txt create mode 100644 common/utils/telnetsrv/telnetsrv_CMakeLists.txt create mode 100644 common/utils/telnetsrv/telnetsrv_loader.c create mode 100644 common/utils/telnetsrv/telnetsrv_loader.h create mode 100644 openair1/PHY/CODING/coding_load.c create mode 100644 openair2/ENB_APP/L1_paramdef.h create mode 100644 openair2/ENB_APP/MACRLC_paramdef.h create mode 100644 openair2/ENB_APP/RRC_config_tools.c create mode 100644 openair2/ENB_APP/RRC_config_tools.h create mode 100644 openair2/ENB_APP/RRC_paramsvalues.h create mode 100644 openair2/ENB_APP/nbiot_config.c create mode 100644 openair2/ENB_APP/nbiot_config.h create mode 100644 openair2/ENB_APP/nbiot_paramdef.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 89b96bf922..4f264044df 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1042,6 +1042,19 @@ include_directories(${NFAPI_USER_DIR}) # Layer 1 ############################# +set(PHY_TURBOSRC + ${OPENAIR1_DIR}/PHY/CODING/3gpplte_sse.c + ${OPENAIR1_DIR}/PHY/CODING/3gpplte.c + ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c + ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c + ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c + ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder.c +) +set(PHY_TURBOIF + ${OPENAIR1_DIR}/PHY/CODING/coding_load.c +) + +add_library(coding MODULE ${PHY_TURBOSRC} ) set(PHY_SRC # depend on code generation from asn1c ${RRC_FULL_DIR}/asn1_constants.h @@ -1109,11 +1122,8 @@ set(PHY_SRC ${OPENAIR1_DIR}/PHY/CODING/lte_segmentation.c ${OPENAIR1_DIR}/PHY/CODING/ccoding_byte.c ${OPENAIR1_DIR}/PHY/CODING/ccoding_byte_lte.c - ${OPENAIR1_DIR}/PHY/CODING/3gpplte_sse.c ${OPENAIR1_DIR}/PHY/CODING/crc_byte.c - ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c - ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c - ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c + ${PHY_TURBOIF} ${OPENAIR1_DIR}/PHY/CODING/lte_rate_matching.c ${OPENAIR1_DIR}/PHY/CODING/viterbi.c ${OPENAIR1_DIR}/PHY/CODING/viterbi_lte.c @@ -1373,6 +1383,7 @@ set (MAC_SRC_UE set (ENB_APP_SRC ${OPENAIR2_DIR}/ENB_APP/enb_app.c ${OPENAIR2_DIR}/ENB_APP/enb_config.c + ${OPENAIR2_DIR}/ENB_APP/RRC_config_tools.c ) add_library(L2 @@ -2398,3 +2409,8 @@ ADD_CUSTOM_TARGET(oarf DEPENDS ${OCT_FILES} ) +include (${OPENAIR_DIR}/common/utils/telnetsrv/telnetsrv_CMakeLists.txt) + + + + diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 7e0c0ca169..b19e3208a5 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -544,6 +544,9 @@ function main() { compilations \ $lte_build_dir $config_libconfig_shlib \ lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so + compilations \ + $lte_build_dir coding \ + libcoding.so $dbin/libcoding.so if [ "$NOS1" = "1" ] ; then compilations \ @@ -766,17 +769,10 @@ function main() { # Telnet server compilation ##################### if [ "$BUILD_TELNETSRV" = "1" ] ; then - - telnetsrv_build_dir=telnetsrv - mkdir -p $DIR/$telnetsrv_build_dir/build - cd $DIR/$telnetsrv_build_dir/build - echo_info "Compiling telnet server library ..." - - [ "$CLEAN" = "1" ] && rm -rf $DIR/$telnetsrv_build_dir - cmake_file=$OPENAIR_DIR/common/utils/$telnetsrv_build_dir/CMakeLists.txt - cd $DIR/$telnetsrv_build_dir/build - eval "$CMAKE_CMD $OPENAIR_DIR/common/utils/$telnetsrv_build_dir/" - make + build_dir=$lte_build_dir + compilations \ + $build_dir telnetsrv \ + libtelnetsrv.so $dbin/libtelnetsrv.so fi # build RF device and transport protocol libraries diff --git a/common/config/config_load_configmodule.c b/common/config/config_load_configmodule.c index ff66d22a1c..c31a2da4d7 100644 --- a/common/config/config_load_configmodule.c +++ b/common/config/config_load_configmodule.c @@ -197,25 +197,40 @@ int i; return cfgptr; } -void end_configmodule() + +/* free memory allocated when reading parameters */ +/* config module could be initialized again after this call */ +void end_configmodule(void) { if (cfgptr != NULL) { if (cfgptr->end != NULL) { printf ("[CONFIG] calling config module end function...\n"); cfgptr->end(); } + + printf ("[CONFIG] free %u config value pointers\n",cfgptr->numptrs); + for(int i=0; inumptrs ; i++) { + if (cfgptr->ptrs[i] != NULL) { + free(cfgptr->ptrs[i]); + cfgptr->ptrs[i]=NULL; + } + } + cfgptr->numptrs=0; + } +} + +/* free all memory used by config module */ +/* should be called only at program exit */ +void free_configmodule(void) +{ + if (cfgptr != NULL) { + end_configmodule(); if( cfgptr->cfgmode != NULL) free(cfgptr->cfgmode); printf ("[CONFIG] free %u config parameter pointers\n",cfgptr->num_cfgP); for (int i=0; inum_cfgP; i++) { if ( cfgptr->cfgP[i] != NULL) free(cfgptr->cfgP[i]); } - printf ("[CONFIG] free %u config value pointers\n",cfgptr->numptrs); - for(int i=0; inumptrs ; i++) { - if (cfgptr->ptrs[i] != NULL) { - free(cfgptr->ptrs[i]); - } - cfgptr->ptrs[i]=NULL; - } + free(cfgptr); cfgptr=NULL; diff --git a/common/config/config_load_configmodule.h b/common/config/config_load_configmodule.h index 76f074cd6c..724cd1dbf5 100644 --- a/common/config/config_load_configmodule.h +++ b/common/config/config_load_configmodule.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -40,15 +40,18 @@ #define CONFIG_MAX_OOPT_PARAMS 10 // maximum number of parameters in the -O option (-O :P1:P2... #define CONFIG_MAX_ALLOCATEDPTRS 1024 // maximum number of parameters that can be dynamicaly allocated in the config module +/* default values for configuration module parameters */ +#define DEFAULT_CFGMODE "libconfig" // use libconfig file +#define DEFAULT_CFGFILENAME "oai.conf" // default config file + /* rtflags bit position definitions */ -#define CONFIG_PRINTPARAMS 1 // print parameters values while processing -#define CONFIG_DEBUGPTR 2 // print memory allocation/free debug messages -#define CONFIG_DEBUGCMDLINE 4 // print command line processing messages -#define CONFIG_HELP 8 // print help message -#define CONFIG_ABORT 16 // config failed,abort execution -#define CONFIG_NOOOPT 32 // no -O option found when parsing command line - - +#define CONFIG_PRINTPARAMS 1 // print parameters values while processing +#define CONFIG_DEBUGPTR 1<<1 // print memory allocation/free debug messages +#define CONFIG_DEBUGCMDLINE 1<<2 // print command line processing messages +#define CONFIG_NOABORTONCHKF 1<<3 // disable abort execution when parameter checking function fails +#define CONFIG_HELP 1<<20 // print help message +#define CONFIG_ABORT 1<<21 // config failed,abort execution +#define CONFIG_NOOOPT 1<<22 // no -O option found when parsing command line typedef int(*configmodule_initfunc_t)(char *cfgP[],int numP); typedef int(*configmodule_getfunc_t)(paramdef_t *,int numparams, char *prefix); typedef int(*configmodule_getlistfunc_t)(paramlist_def_t *, paramdef_t *,int numparams, char *prefix); diff --git a/common/config/config_paramdesc.h b/common/config/config_paramdesc.h index a7de5e3098..6f153535fb 100644 --- a/common/config/config_paramdesc.h +++ b/common/config/config_paramdesc.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -55,16 +55,61 @@ #define PARAMFLAG_PARAMSET (1 << 16) // parameter has been explicitely set in get functions #define PARAMFLAG_PARAMSETDEF (1 << 17) // parameter has been set to default value in get functions + +/* checkedparam_t is possibly used in paramdef_t for specific parameter value validation */ +#define CONFIG_MAX_NUMCHECKVAL 20 +typedef struct paramdef paramdef_t; +typedef union checkedparam { + struct { + int (*f1)(paramdef_t *param); /* check an integer against a list of authorized values */ + int okintval[CONFIG_MAX_NUMCHECKVAL]; /* integer array, store possible values */ + int num_okintval; /* number of valid values in the checkingval array */ + } s1; + struct { + int (*f1a)(paramdef_t *param); /* check an integer against a list of authorized values and set param value */ + /* to the corresponding item in setintval array (mainly for RRC params) */ + int okintval[CONFIG_MAX_NUMCHECKVAL]; /* integer array, store possible values in config file */ + int setintval[CONFIG_MAX_NUMCHECKVAL]; /* integer array, values set in the paramdef structure */ + int num_okintval; /* number of valid values in the checkingval array */ + } s1a; + struct { + int (*f2)(paramdef_t *param); /* check an integer against an authorized range, defined by its min and max value */ + int okintrange[CONFIG_MAX_NUMCHECKVAL]; /* integer array, store min and max values */ + + } s2; + struct { + int (*f3)(paramdef_t *param); /* check a string against a list of authorized values */ + char *okstrval[CONFIG_MAX_NUMCHECKVAL]; /* string array, store possible values */ + int num_okstrval; /* number of valid values in the checkingval array */ + } s3; + struct { + int (*f3a)(paramdef_t *param); /* check a string against a list of authorized values and set param value */ + /* to the corresponding item in setintval array (mainly for RRC params) */ + char *okstrval[CONFIG_MAX_NUMCHECKVAL]; /* string array, store possible values */ + int setintval[CONFIG_MAX_NUMCHECKVAL]; /* integer array, values set in the paramdef structure */ + int num_okstrval; /* number of valid values in the checkingval array */ + } s3a; + struct { + int (*f4)(paramdef_t *param); /* generic check function, no arguments but the param description */ + + } s4; + struct { + void (*checkfunc)(void) ; + } s5; +} checkedparam_t; + +/* paramdef is used to describe a parameter, array of paramdef_t strustures is used as the main parameter in */ +/* config apis used to retrieve parameters values */ typedef struct paramdef { - char optname[MAX_OPTNAME_SIZE]; /* parameter name, can be used as long command line option */ - char *helpstr; /* help string */ - unsigned int paramflags; /* value is a "ored" combination of above PARAMFLAG_XXXX values */ - union { /* pointer to the parameter value, completed by the config module */ + char optname[MAX_OPTNAME_SIZE]; /* parameter name, can be used as long command line option */ + char *helpstr; /* help string */ + unsigned int paramflags; /* value is a "ored" combination of above PARAMFLAG_XXXX values */ + union { /* pointer to the parameter value, completed by the config module */ char **strptr; char **strlistptr; uint8_t *u8ptr; - char *i8ptr; + int8_t *i8ptr; uint16_t *u16ptr; int16_t *i16ptr; uint32_t *uptr; @@ -72,18 +117,21 @@ typedef struct paramdef uint64_t *u64ptr; int64_t *i64ptr; double *dblptr; + void *voidptr; } ; union { /* default parameter value, to be used when PARAMFLAG_MANDATORY is not specified */ - char *defstrval; - char **defstrlistval; - uint32_t defuintval; - int defintval; - uint64_t defint64val; - int *defintarrayval; - double defdblval; + char *defstrval; + char **defstrlistval; + uint32_t defuintval; + int defintval; + uint64_t defint64val; + int *defintarrayval; + double defdblval; } ; char type; /* parameter value type, as listed below as TYPE_XXXX macro */ int numelt; /* number of elements in a list or array parameters or max size of string value */ + checkedparam_t *chkPptr; /* possible pointer to the structure containing the info used to check parameter values */ + int *processedvalue; /* used to store integer values computed from string original value */ } paramdef_t; #define TYPE_INT TYPE_INT32 diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c index acee5646cd..c1acc84384 100644 --- a/common/config/config_userapi.c +++ b/common/config/config_userapi.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -36,6 +36,7 @@ #include #include #include "config_userapi.h" +extern void exit_fun(const char* s); // lte-softmodem clean exit function configmodule_interface_t *config_get_if(void) @@ -59,7 +60,7 @@ char * config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) *ptr = malloc(length); if ( *ptr != NULL) { memset(*ptr,0,length); - if ( (cfgoptions->paramflags & PARAMFLAG_NOFREE) != 0) { + if ( (cfgoptions->paramflags & PARAMFLAG_NOFREE) == 0) { config_get_if()->ptrs[config_get_if()->numptrs] = *ptr; config_get_if()->numptrs++; } @@ -111,7 +112,29 @@ int tmpval=val; break; } } +void config_assign_processedint(paramdef_t *cfgoption, int val) { + cfgoption->processedvalue = malloc(sizeof(int)); + if ( cfgoption->processedvalue != NULL) { + *(cfgoption->processedvalue) = val; + } else { + fprintf (stderr,"[CONFIG] %s %d malloc error\n",__FILE__, __LINE__); + exit(-1); + } +} +int config_get_processedint(paramdef_t *cfgoption) { + int ret; + if ( cfgoption->processedvalue != NULL) { + ret=*(cfgoption->processedvalue); + free( cfgoption->processedvalue); + cfgoption->processedvalue=NULL; + printf_params("[CONFIG] %s: set from %s to %i\n",cfgoption->optname, *(cfgoption->strptr), ret); + } else { + fprintf (stderr,"[CONFIG] %s %d %s has no processed integer availablle\n",__FILE__, __LINE__, cfgoption->optname); + ret=0; + } +return ret; +} void config_printhelp(paramdef_t *params,int numparams) { for (int i=0 ; is4.f4 != NULL) { + st += params[i].chkPptr->s4.f4(&(params[i])); + } + } + if (st != 0) { + fprintf(stderr,"[CONFIG] config_execcheck: %i parameters with wrong value\n", -st); + if ( CONFIG_ISFLAGSET(CONFIG_NOABORTONCHKF) == 0) { + exit_fun("exit because configuration failed\n"); + } + } +return st; +} + int config_get(paramdef_t *params,int numparams, char *prefix) { int ret= -1; -printf("numparams:%d prefix:%s\n", numparams, prefix); if (CONFIG_ISFLAGSET(CONFIG_ABORT)) { fprintf(stderr,"[CONFIG] config_get skipped, config module not properly initialized\n"); return ret; @@ -138,6 +181,7 @@ configmodule_interface_t *cfgif = config_get_if(); ret = config_get_if()->get(params, numparams,prefix); if (ret >= 0) { config_process_cmdline(params,numparams,prefix); + config_execcheck(params,numparams,prefix); } return ret; } @@ -153,6 +197,89 @@ int config_isparamset(paramdef_t *params,int paramidx) } } -int config_getparamval_fromparamdefidx(paramdef_t *cfgoptions,int paramidx) { +void print_intvalueerror(paramdef_t *param, char *fname, int *okval, int numokval) { + fprintf(stderr,"[CONFIG] %s: %s: %i invalid value, authorized values:\n ", + fname,param->optname, (int)*(param->uptr)); + for ( int i=0; ichkPptr->s1.num_okintval ; i++) { + if( *(param->uptr) == param->chkPptr->s1.okintval[i] ) { + return 0; + } + } + print_intvalueerror(param,"config_check_intval", param->chkPptr->s1.okintval,param->chkPptr->s1.num_okintval); + return -1; +} + +int config_check_modify_integer(paramdef_t *param) +{ + + for (int i=0; i < param->chkPptr->s1a.num_okintval ; i++) { + if (*(param->uptr) == param->chkPptr->s1a.okintval[i] ) { + printf_params("[CONFIG] %s: read value %i, set to %i\n",param->optname,*(param->uptr),param->chkPptr->s1a.setintval [i]); + *(param->uptr) = param->chkPptr->s1a.setintval [i]; + return 0; + } + } + print_intvalueerror(param,"config_check_modify_integer", param->chkPptr->s1a.okintval,param->chkPptr->s1a.num_okintval); + return -1; +} + +int config_check_intrange(paramdef_t *param) +{ + if( *(param->iptr) >= param->chkPptr->s2.okintrange[0] && *(param->iptr) <= param->chkPptr->s2.okintrange[1] ) { + return 0; + } + fprintf(stderr,"[CONFIG] config_check_intrange: %s: %i invalid value, authorized range: %i %i\n", + param->optname, (int)*(param->uptr), param->chkPptr->s2.okintrange[0], param->chkPptr->s2.okintrange[1]); + return -1; +} + +void print_strvalueerror(paramdef_t *param, char *fname, char **okval, int numokval) { + fprintf(stderr,"[CONFIG] %s: %s: %s invalid value, authorized values:\n ", + fname,param->optname, *(param->strptr)); + for ( int i=0; ichkPptr->s3.num_okstrval ; i++) { + if( strcasecmp(*(param->strptr),param->chkPptr->s3.okstrval[i] ) == 0) { + return 0; + } + } + print_strvalueerror(param, "config_check_strval", param->chkPptr->s3.okstrval, param->chkPptr->s3.num_okstrval); + return -1; +} + +int config_checkstr_assign_integer(paramdef_t *param) +{ + + + for (int i=0; i < param->chkPptr->s3a.num_okstrval ; i++) { + if (strcasecmp(*(param->strptr),param->chkPptr->s3a.okstrval[i] ) == 0) { + config_assign_processedint(param, param->chkPptr->s3a.setintval[i]); + return 0; + } + } + print_strvalueerror(param, "config_check_strval", param->chkPptr->s3a.okstrval, param->chkPptr->s3a.num_okstrval); + return -1; } diff --git a/common/config/config_userapi.h b/common/config/config_userapi.h index 5bbc20a950..923a690f51 100644 --- a/common/config/config_userapi.h +++ b/common/config/config_userapi.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -38,24 +38,34 @@ extern "C" { #endif -#define DEFAULT_CFGFILENAME "oaisoftmodem.conf" -#define DEFAULT_CFGMODE "libconfig" - #define CONFIG_GETSOURCE ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgmode ) #define CONFIG_GETNUMP ( (config_get_if()==NULL) ? 0 : config_get_if()->num_cfgP ) #define CONFIG_GETP(P) ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgP[P] ) #define CONFIG_ISFLAGSET(P) ( (config_get_if()==NULL) ? 0 : !!(config_get_if()->rtflags & P)) - +#define CONFIG_ISPARAMFLAGSET(P,F) ( !!(P.paramflags & F)) +/* utility functions, to be used by configuration module and/or configuration libraries */ extern configmodule_interface_t *config_get_if(void); extern char * config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) ; extern void config_printhelp(paramdef_t *,int numparams); extern int config_process_cmdline(paramdef_t *params,int numparams, char *prefix); -extern int config_get(paramdef_t *params,int numparams, char *prefix); -extern int config_isparamset(paramdef_t *params,int paramidx); +extern void config_assign_processedint(paramdef_t *cfgoption, int val); extern void config_assign_int(paramdef_t *cfgoptions, char *fullname, int val); -extern int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix); -extern int config_getparamval_fromparamdefidx(paramdef_t *cfgoptions,int paramidx); + +/* apis to get parameters, to be used by oai modules, at configuration time */ +extern int config_get(paramdef_t *params,int numparams, char *prefix); #define config_getlist config_get_if()->getlist + +/* apis to retrieve parameters info after calling get or getlist functions */ +extern int config_isparamset(paramdef_t *params,int paramidx); +extern int config_get_processedint(paramdef_t *cfgoption); + +/* functions to be used in parameters definition, to check parameters values */ +extern int config_check_intval(paramdef_t *param); +extern int config_check_modify_integer(paramdef_t *param); +extern int config_check_intrange(paramdef_t *param); +extern int config_check_strval(paramdef_t *param); +extern int config_checkstr_assign_integer(paramdef_t *param); + #define CONFIG_GETCONFFILE (config_get_if()->cfgP[0]) #ifdef __cplusplus diff --git a/common/config/libconfig/config_libconfig.c b/common/config/libconfig/config_libconfig.c index 00f5f38b8f..a73a0737f2 100644 --- a/common/config/libconfig/config_libconfig.c +++ b/common/config/libconfig/config_libconfig.c @@ -1,3 +1,33 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ +/*! \file common/config/libconfig/config_libconfig.c + * \brief: implementation libconfig configuration library + * \author Francois TABURET + * \date 2017 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ #define _GNU_SOURCE #include @@ -21,21 +51,23 @@ int read_strlist(paramdef_t *cfgoptions,config_setting_t *setting, char *cfgpath { const char *str; int st; +int numelt; - cfgoptions->numelt=config_setting_length(setting); - cfgoptions->strlistptr=malloc(sizeof(char *) * (cfgoptions->numelt)); + numelt=config_setting_length(setting); + config_check_valptr(cfgoptions,(char **)&(cfgoptions->strlistptr), sizeof(char *) * numelt); st=0; - for (int i=0; i< cfgoptions->numelt && cfgoptions->strlistptr != NULL; i++) { + for (int i=0; i< numelt ; i++) { str=config_setting_get_string_elem(setting,i); if (str==NULL) { printf("[LIBCONFIG] %s%i not found in config file\n", cfgoptions->optname,i); } else { - cfgoptions->strlistptr[i]=malloc(strlen(str)+1); + config_check_valptr(cfgoptions,&(cfgoptions->strlistptr[i]),strlen(str)+1); sprintf(cfgoptions->strlistptr[i],"%s",str); st++; printf_params("[LIBCONFIG] %s%i: %s\n", cfgpath,i,cfgoptions->strlistptr[i]); } } + cfgoptions->numelt=numelt; return st; } @@ -108,10 +140,10 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *)); config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(str)+1); sprintf( *(cfgoptions[i].strptr) , "%s", str); - printf_params("[LIBCONFIG] %s: %s\n", cfgpath,*(cfgoptions[i].strptr) ); + printf_params("[LIBCONFIG] %s: \"%s\"\n", cfgpath,*(cfgoptions[i].strptr) ); } else { sprintf( (char *)(cfgoptions[i].strptr) , "%s", str); - printf_params("[LIBCONFIG] %s: %s\n", cfgpath,(char *)cfgoptions[i].strptr ); + printf_params("[LIBCONFIG] %s: \"%s\"\n", cfgpath,(char *)cfgoptions[i].strptr ); } } else { if( cfgoptions[i].defstrval != NULL) { @@ -121,10 +153,10 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *)); config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(cfgoptions[i].defstrval)+1); sprintf(*(cfgoptions[i].strptr), "%s",cfgoptions[i].defstrval); - printf_params("[LIBCONFIG] %s set to default value %s\n", cfgpath, *(cfgoptions[i].strptr)); + printf_params("[LIBCONFIG] %s set to default value \"%s\"\n", cfgpath, *(cfgoptions[i].strptr)); } else { - sprintf((char *)(cfgoptions[i].strptr), "%s",cfgoptions[i].defstrval); - printf_params("[LIBCONFIG] %s set to default value %s\n", cfgpath, (char *)cfgoptions[i].strptr); + sprintf((char *)*(cfgoptions[i].strptr), "%s",cfgoptions[i].defstrval); + printf_params("[LIBCONFIG] %s set to default value \"%s\"\n", cfgpath, (char *)*(cfgoptions[i].strptr)); } } else { notfound=1; @@ -374,6 +406,7 @@ void config_libconfig_end(void ) config_destroy(&(libconfig_privdata.cfg)); if ( libconfig_privdata.configfile != NULL ) { free(libconfig_privdata.configfile); + libconfig_privdata.configfile=NULL; } } diff --git a/common/ran_context.h b/common/ran_context.h index f59fd8a79c..c521c4f376 100644 --- a/common/ran_context.h +++ b/common/ran_context.h @@ -55,12 +55,18 @@ typedef struct { int nb_inst; /// Number of Component Carriers per instance in this node int *nb_CC; + /// Number of NB_IoT instances in this node + int nb_nb_iot_rrc_inst; /// Number of MACRLC instances in this node int nb_macrlc_inst; + /// Number of NB_IoT MACRLC instances in this node + int nb_nb_iot_macrlc_inst; /// Number of component carriers per instance in this node int *nb_mac_CC; /// Number of L1 instances in this node int nb_L1_inst; + /// Number of NB_IoT L1 instances in this node + int nb_nb_iot_L1_inst; /// Number of Component Carriers per instance in this node int *nb_L1_CC; /// Number of RU instances in this node @@ -69,10 +75,16 @@ typedef struct { flexran_agent_info_t **flexran; /// eNB context variables struct PHY_VARS_eNB_s ***eNB; + /// NB_IoT L1 context variables + //struct PHY_VARS_eNB_NB_IoT_s **L1_NB_IoT; /// RRC context variables struct eNB_RRC_INST_s **rrc; - /// RRC context variables + /// NB_IoT RRC context variables + //struct eNB_RRC_INST_NB_IoT_s **nb_iot_rrc; + /// MAC context variables struct eNB_MAC_INST_s **mac; + /// NB_IoT MAC context variables + //struct eNB_MAC_INST_NB_IoT_s **nb_iot_mac; /// GTPu descriptor gtpv1u_data_t *gtpv1u_data_g; /// RU descriptors. These describe what each radio unit is supposed to do and contain the necessary functions for fronthaul interfaces diff --git a/common/utils/load_module_shlib.c b/common/utils/load_module_shlib.c index b21f39e69d..32d3cfee9b 100644 --- a/common/utils/load_module_shlib.c +++ b/common/utils/load_module_shlib.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include "openair1/PHY/defs.h" @@ -44,55 +45,114 @@ void loader_init(void) { paramdef_t LoaderParams[] = LOADER_PARAMS_DESC; - + loader_data.mainexec_buildversion = PACKAGE_VERSION; int ret = config_get( LoaderParams,sizeof(LoaderParams)/sizeof(paramdef_t),LOADER_CONFIG_PREFIX); if (ret <0) { - fprintf(stderr,"[LOADER] configuration couldn't be performed"); + fprintf(stderr,"[LOADER] %s %d configuration couldn't be performed",__FILE__, __LINE__); if (loader_data.shlibpath == NULL) { loader_data.shlibpath=DEFAULT_PATH; } return; - } + } + loader_data.shlibs = malloc(loader_data.maxshlibs * sizeof(loader_shlibdesc_t)); + if(loader_data.shlibs == NULL) { + fprintf(stderr,"[LOADER] %s %d memory allocation error %s\n",__FILE__, __LINE__,strerror(errno)); + exit_fun("[LOADER] unrecoverable error"); + } + memset(loader_data.shlibs,0,loader_data.maxshlibs * sizeof(loader_shlibdesc_t)); +} + +/* build the full shared lib name from the module name */ +char *loader_format_shlibpath(char *modname) +{ + +char *tmpstr; +char *shlibpath =NULL; +char *shlibversion=NULL; +char *cfgprefix; +paramdef_t LoaderParams[] ={{"shlibpath", NULL, 0, strptr:&shlibpath, defstrval:NULL, TYPE_STRING, 0}, + {"shlibversion", NULL, 0, strptr:&shlibversion, defstrval:"", TYPE_STRING, 0}}; + +int ret; + + + + +/* looks for specific path for this module in the config file */ +/* specific value for a module path and version is located in a modname subsection of the loader section */ +/* shared lib name is formatted as lib.so */ + cfgprefix = malloc(sizeof(LOADER_CONFIG_PREFIX)+strlen(modname)+16); + if (cfgprefix == NULL) { + fprintf(stderr,"[LOADER] %s %d malloc error loading module %s, %s\n",__FILE__, __LINE__, modname, strerror(errno)); + exit_fun("[LOADER] unrecoverable error"); + } else { + sprintf(cfgprefix,LOADER_CONFIG_PREFIX ".%s",modname); + int ret = config_get( LoaderParams,sizeof(LoaderParams)/sizeof(paramdef_t),cfgprefix); + if (ret <0) { + fprintf(stderr,"[LOADER] %s %d couldn't retrieve config from section %s\n",__FILE__, __LINE__,cfgprefix); + } + } +/* no specific path, use loader default shared lib path */ + if (shlibpath == NULL) { + shlibpath = loader_data.shlibpath ; + } + +/* alloc memory for full module shared lib file name */ + tmpstr = malloc(strlen(shlibpath)+strlen(modname)+strlen(shlibversion)+16); + if (tmpstr == NULL) { + fprintf(stderr,"[LOADER] %s %d malloc error loading module %s, %s\n",__FILE__, __LINE__, modname, strerror(errno)); + exit_fun("[LOADER] unrecoverable error"); + } + if(shlibpath[0] != 0) { + ret=sprintf(tmpstr,"%s/",shlibpath); + } else { + ret = 0; + } + + sprintf(tmpstr+ret,"lib%s%s.so",modname,shlibversion); + + + return tmpstr; } int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf) { void *lib_handle; initfunc_t fpi; - char *tmpstr; + checkverfunc_t fpc; + char *shlib_path; + char *afname=NULL; int ret=0; if (loader_data.shlibpath == NULL) { loader_init(); } - tmpstr = malloc(strlen(loader_data.shlibpath)+strlen(modname)+16); - if (tmpstr == NULL) { - fprintf(stderr,"[LOADER] %s %d malloc error loading module %s, %s\n",__FILE__, __LINE__, modname, strerror(errno)); - return -1; - } - if(loader_data.shlibpath[0] != 0) { - ret=sprintf(tmpstr,"%s/",loader_data.shlibpath); - } - if(strstr(modname,".so") == NULL) { - sprintf(tmpstr+ret,"lib%s.so",modname); - } else { - sprintf(tmpstr+ret,"%s",modname); - } + shlib_path = loader_format_shlibpath(modname); + ret = 0; - lib_handle = dlopen(tmpstr, RTLD_LAZY|RTLD_NODELETE|RTLD_GLOBAL); + lib_handle = dlopen(shlib_path, RTLD_LAZY|RTLD_NODELETE|RTLD_GLOBAL); if (!lib_handle) { - fprintf(stderr,"[LOADER] library %s is not loaded: %s\n", tmpstr,dlerror()); + fprintf(stderr,"[LOADER] library %s is not loaded: %s\n", shlib_path,dlerror()); ret = -1; } else { - printf("[LOADER] library %s uccessfully loaded loaded\n", tmpstr); - sprintf(tmpstr,"%s_autoinit",modname); - fpi = dlsym(lib_handle,tmpstr); + printf("[LOADER] library %s successfully loaded\n", shlib_path); + afname=malloc(strlen(modname)+15); + sprintf(afname,"%s_checkbuildver",modname); + fpc = dlsym(lib_handle,afname); + if (fpc != NULL ){ + int chkver_ret = fpc(loader_data.mainexec_buildversion, &(loader_data.shlibs[loader_data.numshlibs].shlib_buildversion)); + if (chkver_ret < 0) { + fprintf(stderr,"[LOADER] %s %d lib %s, version mismatch",__FILE__, __LINE__, modname); + exit_fun("[LOADER] unrecoverable error"); + } + } + sprintf(afname,"%s_autoinit",modname); + fpi = dlsym(lib_handle,afname); - if (fpi != NULL ) - { + if (fpi != NULL ) { fpi(); - } + } if (farray != NULL) { for (int i=0; i #include #include -#include +#include "telnetsrv.h" #include #include #include @@ -53,18 +53,25 @@ #include #include "common/config/config_userapi.h" +#include #include "telnetsrv_phycmd.h" #include "telnetsrv_proccmd.h" -static char* telnet_defstatmod[] = {"softmodem","phy"}; +static char* telnet_defstatmod[] = {"softmodem","phy","loader"}; static telnetsrv_params_t telnetparams; #define TELNETSRV_LISTENADDR 0 #define TELNETSRV_LISTENPORT 1 #define TELNETSRV_PRIORITY 2 #define TELNETSRV_DEBUG 3 -#define TELNETSRV_STATICMOD 7 -#define TELNETSRV_SHRMOD 8 +#define TELNETSRV_LOOPC 4 +#define TELNETSRV_LOOPD 5 +#define TELNETSRV_HISFILE 6 +#define TELNETSRV_HISSIZE 7 +#define TELNETSRV_PHYBSIZE 8 +#define TELNETSRV_STATICMOD 9 +#define TELNETSRV_SHRMOD 10 + paramdef_t telnetoptions[] = { /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* configuration parameters for telnet utility */ @@ -72,19 +79,22 @@ paramdef_t telnetoptions[] = { /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ {"listenaddr", "", 0, uptr:&telnetparams.listenaddr, defstrval:"0.0.0.0", TYPE_IPV4ADDR, 0 }, {"listenport", "", 0, uptr:&(telnetparams.listenport), defuintval:9090, TYPE_UINT, 0 }, - {"priority", "", 0, uptr:NULL, defuintval:0, TYPE_UINT, 0 }, {"loopcount", "", 0, uptr:&(telnetparams.loopcount), defuintval:10, TYPE_UINT, 0 }, {"loopdelay", "", 0, uptr:&(telnetparams.loopdelay), defuintval:5000, TYPE_UINT, 0 }, + {"histfile", "", PARAMFLAG_NOFREE, strptr:&(telnetparams.histfile), defstrval:"oaitelnet.history", TYPE_STRING, 0 }, + {"histsize", "", 0, iptr:&(telnetparams.histsize), defuintval:50, TYPE_INT, 0 }, {"phypbsize", "",0, uptr:&(telnetparams.phyprntbuff_size),defuintval:65000, TYPE_UINT, 0 }, - {"staticmod", "", 0, NULL, defstrlistval:telnet_defstatmod,TYPE_STRINGLIST,1}, - {"shrmod", "", 0, NULL, NULL,TYPE_STRINGLIST,0 }, + {"staticmod", "", 0, strlistptr:NULL, defstrlistval:telnet_defstatmod,TYPE_STRINGLIST,(sizeof(telnet_defstatmod)/sizeof(char *))}, + {"shrmod", "", 0, strlistptr:NULL, defstrlistval:NULL,TYPE_STRINGLIST,0 } }; -int get_phybsize() {return telnetparams.phyprntbuff_size; }; +int get_phybsize(void) {return telnetparams.phyprntbuff_size; }; int add_telnetcmd(char *modulename,telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd ); int setoutput(char *buff, int debug, telnet_printfunc_t prnt); int setparam(char *buff, int debug, telnet_printfunc_t prnt); +int history_cmd(char *buff, int debug, telnet_printfunc_t prnt); telnetshell_vardef_t telnet_vardef[] = { {"debug",TELNET_VARTYPE_INT32,&telnetparams.telnetdbg}, @@ -92,12 +102,15 @@ telnetshell_vardef_t telnet_vardef[] = { {"loopc",TELNET_VARTYPE_INT32,&telnetparams.loopcount}, {"loopd",TELNET_VARTYPE_INT32,&telnetparams.loopdelay}, {"phypb",TELNET_VARTYPE_INT32,&telnetparams.phyprntbuff_size}, +{"hsize",TELNET_VARTYPE_INT32,&telnetparams.histsize}, +{"hfile",TELNET_VARTYPE_STRING,&telnetparams.histfile}, {"",0,NULL} }; telnetshell_cmddef_t telnet_cmdarray[] = { {"redirlog","[here,file,off]",setoutput}, {"param","[prio]",setparam}, + {"history","[list,reset]",history_cmd}, {"","",NULL}, }; @@ -131,41 +144,54 @@ char strpolicy[10]; //sched_get_priority_max(SCHED_FIFO) -if (priority < NICE_MIN) - { +if (priority < NICE_MIN) { policy=SCHED_FIFO; sprintf(strpolicy,"%s","fifo"); - schedp.sched_priority= NICE_MIN - priority ; + schedp.sched_priority= NICE_MIN - priority ; + if ( (schedp.sched_priority < sched_get_priority_min(SCHED_FIFO)) || + (schedp.sched_priority > sched_get_priority_max(SCHED_FIFO)) ) { + client_printf("Error: %i invalid prio, should be %i to %i, \n", + priority, NICE_MIN -sched_get_priority_min(SCHED_FIFO), + NICE_MIN - sched_get_priority_max(SCHED_FIFO) ); } -else if (priority > NICE_MAX) - { +} else if (priority > NICE_MAX) { policy=SCHED_IDLE; sprintf(strpolicy,"%s","idle"); schedp.sched_priority=0; - } -else - { +} else { policy=SCHED_OTHER; sprintf(strpolicy,"%s","other"); schedp.sched_priority=0; - } -if( tid != 0) - { +} + +if( tid != 0) { rt = pthread_setschedparam(tid, policy, &schedp); - } -else if(pid > 0) - { +} else if(pid > 0) { rt = sched_setscheduler( pid, policy,&schedp); - } -if (rt != 0) - { +} else { + rt= -1; + client_printf("Error: no pid or tid specified\n"); +} + +if (rt != 0) { client_printf("Error %i: %s modifying sched param to %s:%i, \n", errno,strerror(errno),strpolicy,schedp.sched_priority); - } -else - { +} else { client_printf("policy set to %s, priority %i\n",strpolicy,schedp.sched_priority); + if ( policy==SCHED_OTHER) { + rt = getpriority(PRIO_PROCESS,tid); + if (rt != -1) { + rt = setpriority(PRIO_PROCESS,tid,priority); + if (rt < 0) { + client_printf("Error %i: %s trying to set nice value of thread %u to %i\n", + errno,strerror(errno),tid,priority); + } + } else { + client_printf("Error %i: %s trying to get nice value of thread %u \n", + errno,strerror(errno),tid); + } } +} @@ -198,14 +224,13 @@ int rt; CPU_ZERO(&cpuset); CPU_SET(coreid, &cpuset); - if (tid > 0) - { + if (tid > 0) { rt = pthread_setaffinity_np((pthread_t)tid, sizeof(cpu_set_t), &cpuset); - } - else if (pid > 0) - { + } else if (pid > 0){ rt = sched_setaffinity((pid_t)pid, sizeof(cpu_set_t), &cpuset); - } + } else { + rt= -1; + } if (rt != 0) { client_printf("Error %i: %s calling , xxx_setaffinity...\n",errno,strerror(errno)); @@ -284,7 +309,6 @@ memset(cmds,0,sizeof(cmds)); sscanf(buff,"%9s %9s %9s %9s %9s", cmds[0],cmds[1],cmds[2],cmds[3],cmds[4] ); if (strncasecmp(cmds[0],"prio",4) == 0) { - pthread_attr_t attr; int prio; prio=(int)strtol(cmds[1],NULL,0); if (errno == ERANGE) @@ -305,6 +329,35 @@ if (strncasecmp(cmds[0],"aff",3) == 0) return CMDSTATUS_NOTFOUND; } /* setparam */ + +int history_cmd(char *buff, int debug, telnet_printfunc_t prnt) +{ +char cmds[TELNET_MAX_MSGLENGTH/TELNET_CMD_MAXSIZE][TELNET_CMD_MAXSIZE]; + + +memset(cmds,0,sizeof(cmds)); +sscanf(buff,"%9s %9s %9s %9s %9s", cmds[0],cmds[1],cmds[2],cmds[3],cmds[4] ); +if (cmds[0] == NULL) + return CMDSTATUS_VARNOTFOUND; +if (strncasecmp(cmds[0],"list",4) == 0) + { + HIST_ENTRY **hist = history_list(); + if (hist) { + for (int i = 0; hist[i]; i++) { + prnt ("%d: %s\n", i + history_base, hist[i]->line); + } + } + return CMDSTATUS_FOUND; + } +if (strncasecmp(cmds[0],"reset",5) == 0) + { + clear_history(); + write_history(telnetparams.histfile); + return CMDSTATUS_FOUND; + } + +return CMDSTATUS_NOTFOUND; +} /* history_cmd */ /*-------------------------------------------------------------------------------------------------------*/ /* generic commands available for all modules loaded by the server @@ -314,11 +367,11 @@ int setgetvar(int moduleindex,char getorset,char *params) { int n,i; char varname[TELNET_CMD_MAXSIZE]; -char varval[TELNET_CMD_MAXSIZE]; +char *varval=NULL; memset(varname,0,sizeof(varname)); - memset(varval,0,sizeof(varval)); - n = sscanf(params,"%s %s",varname,varval); + + n = sscanf(params,"%s %ms",varname,&varval); for ( i=0 ; telnetparams.CmdParsers[moduleindex].var[i].varvalptr != NULL ; i++) { if ( strncasecmp(telnetparams.CmdParsers[moduleindex].var[i].varname,varname,strlen(telnetparams.CmdParsers[moduleindex].var[i].varname)) == 0) @@ -330,7 +383,10 @@ char varval[TELNET_CMD_MAXSIZE]; switch(telnetparams.CmdParsers[moduleindex].var[i].vartype) { case TELNET_VARTYPE_INT32: - client_printf("%i\n",*(int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); + client_printf("%i\n",*(int32_t *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); + break; + case TELNET_VARTYPE_INT64: + client_printf("%lli\n",*(int64_t *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); break; case TELNET_VARTYPE_INT16: client_printf("%hi\n",*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); @@ -338,8 +394,8 @@ char varval[TELNET_CMD_MAXSIZE]; case TELNET_VARTYPE_DOUBLE: client_printf("%g\n",*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); break; - case TELNET_VARTYPE_PTR: - client_printf("0x%08x\n",*((unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr))); + case TELNET_VARTYPE_STRING: + client_printf("\"%s\"\n",*(char **)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); break; default: client_printf("unknown type\n"); @@ -364,6 +420,10 @@ char varval[TELNET_CMD_MAXSIZE]; case TELNET_VARTYPE_DOUBLE: *(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = strtod(varval,NULL); client_printf("%g\n",*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); + break; + case TELNET_VARTYPE_STRING: + sprintf(*(char **)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr),"%s", varval); + client_printf("\"%s\"\n",*(char **)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); break; default: client_printf("unknown type\n"); @@ -372,6 +432,9 @@ char varval[TELNET_CMD_MAXSIZE]; } } } +if (n>1 && varval != NULL) { + free(varval); +} return CMDSTATUS_VARNOTFOUND; } /*----------------------------------------------------------------------------------------------------*/ @@ -515,13 +578,14 @@ if(listen(sock, 1) == -1) fprintf(stderr,"[TELNETSRV] Error %s on listen call\n",strerror(errno)); +using_history(); printf("\nInitializing telnet server...\n"); while( (telnetparams.new_socket = accept(sock, &cli_addr, &cli_len)) ) { printf("[TELNETSRV] Telnet client connected....\n"); - - + read_history(telnetparams.histfile); + stifle_history(telnetparams.histsize); if(telnetparams.new_socket < 0) fprintf(stderr,"[TELNETSRV] Error %s on accept call\n",strerror(errno)); @@ -548,31 +612,43 @@ while( (telnetparams.new_socket = accept(sock, &cli_addr, &cli_len)) ) break; } if (telnetparams.telnetdbg > 0) - printf("[TELNETSRV] Command received: readc %i filled %i %s\n", readc, filled ,buf); - if (strlen(buf) >= 2 ) + printf("[TELNETSRV] Command received: readc %i filled %i \"%s\"\n", readc, filled ,buf); + if (buf[0] == '!') { + if (buf[1] == '!') { + sprintf(buf,"%s","telnet history list"); + } else { + HIST_ENTRY *hisentry = history_get(strtol(buf+1,NULL,0)); + if (hisentry) { + char msg[TELNET_MAX_MSGLENGTH + sizeof(TELNET_PROMPT) +10]; + sprintf(buf,"%s",hisentry->line); + sprintf(msg,"%s %s\n",TELNET_PROMPT, hisentry->line); + send(telnetparams.new_socket, msg, strlen(msg), MSG_NOSIGNAL); + } + } + } + if (strlen(buf) > 2 ) { status=process_command(buf); } else status=CMDSTATUS_NOCMD; - if (status != CMDSTATUS_EXIT) - { - if (status == CMDSTATUS_NOTFOUND) - { + if (status != CMDSTATUS_EXIT) { + if (status == CMDSTATUS_NOTFOUND) { char msg[TELNET_MAX_MSGLENGTH + 50]; sprintf(msg,"Error: \n %s\n is not a softmodem command\n",buf); send(telnetparams.new_socket, msg, strlen(msg), MSG_NOSIGNAL); - } + } else if (status == CMDSTATUS_FOUND) { + add_history(buf); + } send(telnetparams.new_socket, TELNET_PROMPT, sizeof(TELNET_PROMPT), MSG_NOSIGNAL); - } - else - { + } else { printf ("[TELNETSRV] Closing telnet connection...\n"); break; - } + } } - + write_history(telnetparams.histfile); + clear_history(); close(telnetparams.new_socket); printf ("[TELNETSRV] Telnet server waitting for connection...\n"); } @@ -588,7 +664,7 @@ return; */ void exec_moduleinit(char *modname) { -void (*fptr)(); +void (*fptr)(void); char initfunc[TELNET_CMD_MAXSIZE+9]; if (strlen(modname) > TELNET_CMD_MAXSIZE) @@ -609,23 +685,26 @@ char initfunc[TELNET_CMD_MAXSIZE+9]; } } -int add_embeddedmodules() +int add_embeddedmodules(void) { - +int ret=0; for(int i=0; i " #define TELNET_MAXCMD 20 -#define TELNET_CMD_MAXSIZE 10 +#define TELNET_CMD_MAXSIZE 20 #define TELNET_HELPSTR_SIZE 80 /* status return by the command parser after it analysed user input */ @@ -70,7 +69,7 @@ typedef struct cmddef { #define TELNET_VARTYPE_INT64 3 #define TELNET_VARTYPE_STRING 4 #define TELNET_VARTYPE_DOUBLE 5 -#define TELNET_VARTYPE_PTR 6 +//#define TELNET_VARTYPE_PTR 6 typedef struct variabledef { char varname[TELNET_CMD_MAXSIZE]; char vartype; @@ -96,6 +95,8 @@ typedef struct { pthread_t telnet_pthread; // thread id of the telnet server int telnetdbg; // debug level of the server int priority; // server running priority + char *histfile; // command history + int histsize; // command history length int new_socket; // socket of the client connection int logfilefd; // file id of the log file when log output is redirected to a file int saved_stdout; // file id of the previous stdout, used to be able to restore original stdout @@ -134,6 +135,6 @@ VT escape sequence definition, for smarter display.... int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd); void set_sched(pthread_t tid, int pid,int priority); void set_affinity(pthread_t tid, int pid, int coreid); -extern int get_phybsize(); +extern int get_phybsize(void); #endif #endif diff --git a/common/utils/telnetsrv/telnetsrv_CMakeLists.txt b/common/utils/telnetsrv/telnetsrv_CMakeLists.txt new file mode 100644 index 0000000000..5dee7db4c4 --- /dev/null +++ b/common/utils/telnetsrv/telnetsrv_CMakeLists.txt @@ -0,0 +1,28 @@ + + +set(TELNETROOT ${OPENAIR_DIR}/common/utils/telnetsrv ) + + + +set(TELNETSRV_SOURCE + ${TELNETROOT}/telnetsrv.c + ${TELNETROOT}/telnetsrv_phycmd.c + ${TELNETROOT}/telnetsrv_proccmd.c + ${TELNETROOT}/telnetsrv_loader.c + ) + +#set(TELNETSRV_ETHDEVCMD_SOURCE +# ${APPROOT}/telnetsrv/telnetsrv_ethdevcmd.c +# ) + + + +add_library(telnetsrv MODULE ${TELNETSRV_SOURCE} ) +#add_library(telnetsrv_ethdevcmd MODULE ${TELNETSRV_ETHDEVCMD_SOURCE} ) +target_link_libraries(telnetsrv PRIVATE history) + +install(TARGETS telnetsrv DESTINATION bin) + +if (EXISTS "${OPENAIR_BUILD_DIR}/lte_build_oai/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/lte_build_oai/build") + install(TARGETS telnetsrv DESTINATION ${OPENAIR_BUILD_DIR}/lte_build_oai/build) +endif (EXISTS "${OPENAIR_BUILD_DIR}/lte_build_oai/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/lte_build_oai/build") diff --git a/common/utils/telnetsrv/telnetsrv_loader.c b/common/utils/telnetsrv/telnetsrv_loader.c new file mode 100644 index 0000000000..a23e25eb83 --- /dev/null +++ b/common/utils/telnetsrv/telnetsrv_loader.c @@ -0,0 +1,84 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file common/utils/telnetsrv/telnetsrv_loader.c + * \brief: implementation of telnet commands related to softmodem linux process + * \author Francois TABURET + * \date 2018 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ +#define _GNU_SOURCE +#include +#include + + +#define TELNETSERVERCODE +#include "telnetsrv.h" +#define TELNETSRV_LOADER_MAIN +#include "telnetsrv_loader.h" + + +int loader_show_cmd(char *buff, int debug, telnet_printfunc_t prnt); +telnetshell_cmddef_t loader_cmdarray[] = { + {"show","[params,modules]",loader_show_cmd}, + {"","",NULL}, +}; + + +/*-------------------------------------------------------------------------------------*/ +int loader_show_cmd(char *buff, int debug, telnet_printfunc_t prnt) +{ + if (debug > 0) + prnt( "loader_show_cmd received %s\n",buff); + + if (strcasestr(buff,"params") != NULL) { + prnt( "loader parameters:\n"); + prnt( " Main executable build version: \"%s\"\n", loader_data.mainexec_buildversion); + prnt( " Default shared lib path: \"%s\"\n", loader_data.shlibpath); + prnt( " Max number of shared lib : %i\n", loader_data.maxshlibs); + } + else if (strcasestr(buff,"modules") != NULL) { + prnt( "%i shared lib have been dynamicaly loaded by the oai loader\n", loader_data.numshlibs); + for (int i=0 ; i 0) prnt(" proccmd_show received %s\n",buf); - if (strcasestr(buf,"thread") != NULL) - { + if (strcasestr(buf,"thread") != NULL) { print_threads(buf,debug,prnt); - } + } if (strcasestr(buf,"loglvl") != NULL) { - for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++){ - prnt("\t%s:\t%s\t%s\n",g_log->log_component[i].name, map_int_to_str(log_verbosity_names,g_log->log_component[i].flag), - map_int_to_str(log_level_names,g_log->log_component[i].level)); + prnt("component verbosity level enabled\n"); + for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) { + prnt("%02i %17.17s:%10.10s%10.10s %s\n",i ,g_log->log_component[i].name, + map_int_to_str(log_verbosity_names,g_log->log_component[i].flag), + map_int_to_str(log_level_names,g_log->log_component[i].level), + ((g_log->log_component[i].interval>0)?"Y":"N") ); + } + } + if (strcasestr(buf,"config") != NULL) { + prnt("Command line arguments:\n"); + for (int i=0; i < config_get_if()->argc; i++) { + prnt(" %02i %s\n",i ,config_get_if()->argv[i]); + } + prnt("Config module flags ( -O ::dbgl): 0x%08x\n", config_get_if()->rtflags); + + prnt(" Print config debug msg, params values (flag %u): %s\n",CONFIG_PRINTPARAMS, + ((config_get_if()->rtflags & CONFIG_PRINTPARAMS) ? "Y" : "N") ); + prnt(" Print config debug msg, memory management(flag %u): %s\n",CONFIG_DEBUGPTR, + ((config_get_if()->rtflags & CONFIG_DEBUGPTR) ? "Y" : "N") ); + prnt(" Print config debug msg, command line processing (flag %u): %s\n",CONFIG_DEBUGCMDLINE, + ((config_get_if()->rtflags & CONFIG_DEBUGCMDLINE) ? "Y" : "N") ); + prnt(" Don't exit if param check fails (flag %u): %s\n",CONFIG_NOABORTONCHKF, + ((config_get_if()->rtflags & CONFIG_NOABORTONCHKF) ? "Y" : "N") ); + prnt("Config source: %s, parameters:\n",CONFIG_GETSOURCE ); + for (int i=0; i < config_get_if()->num_cfgP; i++) { + prnt(" %02i %s\n",i ,config_get_if()->cfgP[i]); + } + prnt("Softmodem components:\n"); + prnt(" %02i Ru(s)\n", RC.nb_RU); + prnt(" %02i lte RRc(s), %02i NbIoT RRC(s)\n", RC.nb_inst, RC.nb_nb_iot_rrc_inst); + prnt(" %02i lte MACRLC(s), %02i NbIoT MACRLC(s)\n", RC.nb_macrlc_inst, RC.nb_nb_iot_macrlc_inst); + prnt(" %02i lte L1, %02i NbIoT L1\n", RC.nb_L1_inst, RC.nb_nb_iot_L1_inst); + + for(int i=0; i 0) prnt("proccmd_thread received %s\n",buf); + if (strcasestr(buf,"help") != NULL) { + prnt(PROCCMD_THREAD_HELP_STRING); + return 0; + } res=sscanf(buf,"%i %9s %i",&bv1,sv1,&bv2); if (debug > 0) prnt(" proccmd_thread: %i params = %i,%s,%i\n",res,bv1,sv1,bv2); @@ -231,32 +297,95 @@ extern void exit_fun(const char* s); return 0; } + int proccmd_log(char *buf, int debug, telnet_printfunc_t prnt) { int idx1=0; int idx2=NUM_LOG_LEVEL-1; -int s = sscanf(buf,"%*s %i-%i",&idx1,&idx2); +char *logsubcmd=NULL; + +int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2); if (debug > 0) - prnt("process module received %s\n",buf); + prnt( "proccmd_log received %s\n s=%i sub command %s\n",buf,s,((logsubcmd==NULL)?"":logsubcmd)); + + if (s == 1 && logsubcmd != NULL) { + if (strcasestr(logsubcmd,"online") != NULL) { + if (strcasestr(buf,"noonline") != NULL) { + set_glog_onlinelog(0); + prnt("online logging disabled\n",buf); + } else { + set_glog_onlinelog(1); + prnt("online logging enabled\n",buf); + } + } + else if (strcasestr(logsubcmd,"show") != NULL) { + prnt("Available log levels: \n "); + for (int i=0; log_level_names[i].name != NULL; i++) + prnt("%s ",log_level_names[i].name); + prnt("\nAvailable verbosity: \n "); + for (int i=0; log_verbosity_names[i].name != NULL; i++) + prnt("%s ",log_verbosity_names[i].name); + prnt("\n"); + proccmd_show("loglvl",debug,prnt); + } + else if (strcasestr(logsubcmd,"help") != NULL) { + prnt(PROCCMD_LOG_HELP_STRING); + } else { + prnt("%s: wrong log command...\n",logsubcmd); + } + } else if ( s == 3 && logsubcmd != NULL) { + int level, verbosity, interval; + char *tmpstr=NULL; + char *logparam=NULL; + int l; + + level = verbosity = interval = -1; + l=sscanf(logsubcmd,"%m[^'_']_%m[^'_']",&logparam,&tmpstr); + if (debug > 0) + prnt("l=%i, %s %s\n",l,((logparam==NULL)?"\"\"":logparam), ((tmpstr==NULL)?"\"\"":tmpstr)); + if (l ==2 ) { + if (strcmp(logparam,"level") == 0) { + level=map_str_to_int(log_level_names,tmpstr); + if (level < 0) prnt("level %s unknown\n",tmpstr); + } else if (strcmp(logparam,"verbos") == 0) { + verbosity=map_str_to_int(log_verbosity_names,tmpstr); + if (verbosity < 0) prnt("verbosity %s unknown\n",tmpstr); + } else { + prnt("%s%s unknown log sub command \n",logparam, tmpstr); + } + } else if (l ==1 ) { + if (strcmp(logparam,"enable") == 0) { + interval = 1; + } else if (strcmp(logparam,"disable") == 0) { + interval = 0; + } else { + prnt("%s%s unknown log sub command \n",logparam, tmpstr); + } + } else { + prnt("%s unknown log sub command \n",logsubcmd); + } + if (logparam != NULL) free(logparam); + if (tmpstr != NULL) free(tmpstr); + for (int i=idx1; i<=idx2 ; i++) { + set_comp_log(i, level, verbosity, interval); + prnt("log level/verbosity comp %i %s set to %s / %s (%s)\n", + i,((g_log->log_component[i].name==NULL)?"":g_log->log_component[i].name), + map_int_to_str(log_level_names,g_log->log_component[i].level), + map_int_to_str(log_verbosity_names,g_log->log_component[i].flag), + ((g_log->log_component[i].interval>0)?"enabled":"disabled")); + + + } + } else { + prnt("%s: wrong log command...\n",buf); + } - if (strcasestr(buf,"enable") != NULL) - { - set_glog_onlinelog(1); - } - if (strcasestr(buf,"disable") != NULL) - { - set_glog_onlinelog(0); - } - if (strcasestr(buf,"show") != NULL) - { - proccmd_show("loglvl",debug,prnt); - } return 0; } /*-------------------------------------------------------------------------------------*/ -void add_softmodem_cmds() +void add_softmodem_cmds(void) { add_telnetcmd("softmodem",proc_vardef,proc_cmdarray); } diff --git a/common/utils/telnetsrv/telnetsrv_proccmd.h b/common/utils/telnetsrv/telnetsrv_proccmd.h index d7fd0a6e24..b2c05315d8 100644 --- a/common/utils/telnetsrv/telnetsrv_proccmd.h +++ b/common/utils/telnetsrv/telnetsrv_proccmd.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -19,6 +19,7 @@ * contact@openairinterface.org */ + /*! \file common/utils/telnetsrv/telnetsrv_proccmd.h * \brief: Include file defining telnet commands related to this linux process * \author Francois TABURET @@ -43,15 +44,33 @@ extern int proccmd_log(char *buf, int debug, telnet_printfunc_t prnt); telnetshell_vardef_t proc_vardef[] = { {"",0,NULL} }; +#define PROCCMD_LOG_HELP_STRING " log sub commands: \n\ + show: display current log configuration \n\ + online, noonline: enable or disable console logs \n\ + enable, disable id1-id2: enable or disable logs for components index id1 to id2 \n\ + level_ id1-id2: set log level to for components index id1 to id2 \n\ + level_ id1-id2: set log verbosity to for components index id1 to id2 \n\ +use the show command to get the values for , and the list of component indexes \ +that can be used for id1 and id2 \n" + +#define PROCCMD_THREAD_HELP_STRING " thread sub commands: \n\ + aff : set affinity of thread to core \n\ + prio : set scheduling parameters for thread \n\ + if prio < -20: linux scheduling policy set to FIFO, \n\ + with priority = -20 - prio \n\ + if prio > 19: linux scheduling policy set to OTHER, \n\ + with priority (nice value) = prio \n\ + use \"softmodem show thread\" to get \n" + telnetshell_cmddef_t proc_cmdarray[] = { - {"show","loglvl|thread", proccmd_show}, - {"log","[enable,disable]", proccmd_log}, - {"thread"," aff|prio ", proccmd_thread}, + {"show","loglvl|thread|config", proccmd_show}, + {"log","(enter help for details)", proccmd_log}, + {"thread","(enter help for details)", proccmd_thread}, {"exit","", proccmd_exit}, {"","",NULL}, }; #else -extern void add_proccmd_cmds(); +extern void add_proccmd_cmds(void); #endif /* TELNETSRV_PROCCMD_MAIN */ diff --git a/openair1/PHY/CODING/3gpplte.c b/openair1/PHY/CODING/3gpplte.c index ca63857d72..61acdb2ad9 100644 --- a/openair1/PHY/CODING/3gpplte.c +++ b/openair1/PHY/CODING/3gpplte.c @@ -27,7 +27,9 @@ #ifndef TC_MAIN //#include "defs.h" #endif - +#include +#include +#include "PHY/CODING/defs.h" #include "extern_3GPPinterleaver.h" //#define DEBUG_TURBO_ENCODER 1 @@ -35,7 +37,7 @@ uint32_t threegpplte_interleaver_output; uint32_t threegpplte_interleaver_tmp; -inline void threegpplte_interleaver_reset() +inline void threegpplte_interleaver_reset(void) { threegpplte_interleaver_output = 0; threegpplte_interleaver_tmp = 0; @@ -82,7 +84,7 @@ uint8_t output_lut[16],state_lut[16]; inline uint8_t threegpplte_rsc_lut(uint8_t input,uint8_t *state) { - uint8_t output; + uint8_t off; off = (*state<<1)|input; @@ -146,7 +148,7 @@ void threegpplte_turbo_encoder(uint8_t *input, for (i=0; f1f2mat[i].nb_bits!= input_length_bits && i <188; i++); if ( i == 188 ) { - msg("Illegal frame length!\n"); + printf("Illegal frame length!\n"); return; } else { base_interleaver=il_tb+f1f2mat[i].beg_index; diff --git a/openair1/PHY/CODING/3gpplte_sse.c b/openair1/PHY/CODING/3gpplte_sse.c index 5d87a60477..313d63f7a7 100644 --- a/openair1/PHY/CODING/3gpplte_sse.c +++ b/openair1/PHY/CODING/3gpplte_sse.c @@ -96,7 +96,7 @@ static inline void threegpplte_rsc_termination(unsigned char *x,unsigned char *z *state = (*state)>>1; } -void treillis_table_init(void) +static void treillis_table_init(void) { //struct treillis t[][]=all_treillis; //t=memalign(16,sizeof(struct treillis)*8*256); @@ -536,12 +536,12 @@ char interleave_compact_byte(short * base_interleaver,unsigned char * input, uns } */ -void threegpplte_turbo_encoder(unsigned char *input, - unsigned short input_length_bytes, - unsigned char *output, - unsigned char F, - unsigned short interleaver_f1, - unsigned short interleaver_f2) +void threegpplte_turbo_encoder_sse(unsigned char *input, + unsigned short input_length_bytes, + unsigned char *output, + unsigned char F, + unsigned short interleaver_f1, + unsigned short interleaver_f2) { int i; @@ -641,7 +641,24 @@ void threegpplte_turbo_encoder(unsigned char *input, #endif } - +void init_encoder_sse (void) { + treillis_table_init(); +} +/* function which will be called by the shared lib loader, to check shared lib version + against main exec version. version mismatch no considered as fatal (interfaces not supposed to change) +*/ +int coding_checkbuildver(char * mainexec_buildversion, char ** shlib_buildversion) +{ +#ifndef PACKAGE_VERSION +#define PACKAGE_VERSION "standalone built: " __DATE__ __TIME__ +#endif + *shlib_buildversion = PACKAGE_VERSION; + if (strcmp(mainexec_buildversion, *shlib_buildversion) != 0) { + fprintf(stderr,"[CODING] shared lib version %s, doesn't match main version %s, compatibility should be checked\n", + mainexec_buildversion,*shlib_buildversion); + } + return 0; +} #ifdef TC_MAIN #define INPUT_LENGTH 20 diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder.c b/openair1/PHY/CODING/3gpplte_turbo_decoder.c index 4470ecca05..6c50e03806 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder.c @@ -550,7 +550,7 @@ void compute_alpha_s(llr_t* alpha,llr_t* m_11,llr_t* m_10,unsigned short frame_l void compute_beta_s(llr_t* beta,llr_t *m_11,llr_t* m_10,llr_t* alpha,unsigned short frame_length,unsigned char F) { - int k,i; + int k; llr_t old0, old1, old2, old3, old4, old5, old6, old7; llr_t new0, new1, new2, new3, new4, new5, new6, new7; llr_t m_b0, m_b1, m_b2, m_b3, m_b4,m_b5, m_b6, m_b7; @@ -897,7 +897,7 @@ unsigned char phy_threegpplte_turbo_decoder_scalar(llr_t *y, unsigned char crc_len,temp; if (crc_type > 3) { - msg("Illegal crc length!\n"); + fprintf(stderr,"Illegal crc length!\n"); return 255; } diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c index 83a50f214b..ef0ca48df4 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c @@ -37,9 +37,9 @@ /// /// -#ifdef __AVX2__ -#include "PHY/sse_intrin.h" + + #ifndef TEST_DEBUG #include "PHY/defs.h" @@ -58,6 +58,8 @@ #include "mex.h" #endif +#ifdef __AVX2__ +#include "PHY/sse_intrin.h" //#define DEBUG_LOGMAP @@ -837,7 +839,7 @@ void free_td16avx2(void) } } -void init_td16avx2() +void init_td16avx2(void) { int ind,i,i2,i3,j,n,pi,pi2_i,pi2_pi; @@ -1408,6 +1410,36 @@ unsigned char phy_threegpplte_turbo_decoder16avx2(int16_t *y, #endif return(iteration_cnt); } +#else //__AVX2__ +unsigned char phy_threegpplte_turbo_decoder16avx2(int16_t *y, + int16_t *y2, + uint8_t *decoded_bytes, + uint8_t *decoded_bytes2, + uint16_t n, + uint16_t f1, + uint16_t f2, + uint8_t max_iterations, + uint8_t crc_type, + uint8_t F, + time_stats_t *init_stats, + time_stats_t *alpha_stats, + time_stats_t *beta_stats, + time_stats_t *gamma_stats, + time_stats_t *ext_stats, + time_stats_t *intl1_stats, + time_stats_t *intl2_stats) +{ + return 0; +} +void free_td16avx2(void) +{ + +} + +void init_td16avx2(void) +{ + +} #endif //__AVX2__ diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c index a32edd711d..63896924dd 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c @@ -1124,7 +1124,7 @@ void free_td16(void) } } -void init_td16() +void init_td16(void) { int ind,i,i2,i3,j,n,pi,pi3; diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c index 4754e26f38..f7b64b767d 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c @@ -849,7 +849,7 @@ void free_td8(void) extern RAN_CONTEXT_t RC; -void init_td8() +void init_td8(void) { int ind,i,j,n,n2,pi,pi3; diff --git a/openair1/PHY/CODING/coding_load.c b/openair1/PHY/CODING/coding_load.c new file mode 100644 index 0000000000..c8aed8cf30 --- /dev/null +++ b/openair1/PHY/CODING/coding_load.c @@ -0,0 +1,134 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file openair1/PHY/CODING + * \brief: load library implementing coding/decoding algorithms + * \author Francois TABURET + * \date 2017 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ +#include +#include "PHY/defs.h" +#include "common/utils/load_module_shlib.h" + + +loader_shlibfunc_t shlib_fdesc[DECODE_NUM_FPTR]; + +decoder_if_t decoder16; +decoder_if_t decoder8; +encoder_if_t encoder; + +extern int _may_i_use_cpu_feature(unsigned __int64); +uint8_t nodecod(short *y, + short *y2, + unsigned char *decoded_bytes, + unsigned char *decoded_bytes2, + unsigned short n, + unsigned short f1, + unsigned short f2, + unsigned char max_iterations, + unsigned char crc_type, + unsigned char F, + time_stats_t *init_stats, + time_stats_t *alpha_stats, + time_stats_t *beta_stats, + time_stats_t *gamma_stats, + time_stats_t *ext_stats, + time_stats_t *intl1_stats, + time_stats_t *intl2_stats) +{ + printf("."); + return max_iterations+1; +}; + +void decoding_setmode (int mode) { + switch (mode) { + case MODE_DECODE_NONE: + decoder8=nodecod; + decoder16=nodecod; + encoder=(encoder_if_t)shlib_fdesc[ENCODE_C_FPTRIDX].fptr; + break; + case MODE_DECODE_SSE: + decoder8=(decoder_if_t)shlib_fdesc[DECODE_TD8_SSE_FPTRIDX].fptr; + decoder16=(decoder_if_t)shlib_fdesc[DECODE_TD16_SSE_FPTRIDX].fptr; + encoder=(encoder_if_t)shlib_fdesc[ENCODE_SSE_FPTRIDX].fptr; + break; + case MODE_DECODE_C: + decoder16=(decoder_if_t)shlib_fdesc[DECODE_TD_C_FPTRIDX].fptr; + decoder8=(decoder_if_t)shlib_fdesc[DECODE_TD_C_FPTRIDX].fptr; + encoder=(encoder_if_t)shlib_fdesc[ENCODE_C_FPTRIDX].fptr; + break; + case MODE_DECODE_AVX2: + decoder16=(decoder_if_t)shlib_fdesc[DECODE_TD16_AVX2_FPTRIDX].fptr; + decoder8=(decoder_if_t)shlib_fdesc[DECODE_TD8_SSE_FPTRIDX].fptr; + encoder=(encoder_if_t)shlib_fdesc[ENCODE_SSE_FPTRIDX].fptr; + break; + } + +} + + +int load_codinglib(void) { + int ret; + + + shlib_fdesc[DECODE_INITTD8_SSE_FPTRIDX].fname = "init_td8"; + shlib_fdesc[DECODE_INITTD16_SSE_FPTRIDX].fname= "init_td16"; + shlib_fdesc[DECODE_INITTD_AVX2_FPTRIDX].fname="init_td16avx2"; + + shlib_fdesc[DECODE_TD8_SSE_FPTRIDX].fname= "phy_threegpplte_turbo_decoder8"; + shlib_fdesc[DECODE_TD16_SSE_FPTRIDX].fname= "phy_threegpplte_turbo_decoder16"; + shlib_fdesc[DECODE_TD_C_FPTRIDX].fname= "phy_threegpplte_turbo_decoder_scalar"; + shlib_fdesc[DECODE_TD16_AVX2_FPTRIDX].fname= "phy_threegpplte_turbo_decoder16avx2"; + + + shlib_fdesc[DECODE_FREETD8_FPTRIDX].fname = "free_td8"; + shlib_fdesc[DECODE_FREETD16_FPTRIDX].fname= "free_td16"; + shlib_fdesc[DECODE_FREETD_AVX2_FPTRIDX].fname= "free_td16avx2"; + + shlib_fdesc[ENCODE_SSE_FPTRIDX].fname= "threegpplte_turbo_encoder_sse"; + shlib_fdesc[ENCODE_C_FPTRIDX].fname= "threegpplte_turbo_encoder"; + shlib_fdesc[ENCODE_INIT_SSE_FPTRIDX].fname= "init_encoder_sse"; + ret=load_module_shlib("coding",shlib_fdesc,DECODE_NUM_FPTR); + if (ret < 0) exit_fun("Error loading coding library"); + +/* execute encoder/decoder init functions */ + shlib_fdesc[DECODE_INITTD8_SSE_FPTRIDX].fptr(); + shlib_fdesc[DECODE_INITTD16_SSE_FPTRIDX].fptr(); + shlib_fdesc[DECODE_INITTD_AVX2_FPTRIDX].fptr(); + shlib_fdesc[ENCODE_INIT_SSE_FPTRIDX].fptr(); + decoding_setmode(MODE_DECODE_SSE); + +return 0; +} + +void free_codinglib(void) { + + shlib_fdesc[DECODE_FREETD8_FPTRIDX].fptr(); + shlib_fdesc[DECODE_FREETD16_FPTRIDX].fptr(); + shlib_fdesc[DECODE_FREETD_AVX2_FPTRIDX].fptr(); + + +} diff --git a/openair1/PHY/CODING/defs.h b/openair1/PHY/CODING/defs.h index 22339953c3..ce13e045f3 100644 --- a/openair1/PHY/CODING/defs.h +++ b/openair1/PHY/CODING/defs.h @@ -292,9 +292,7 @@ void ccodedot11_init(void); \brief This function initializes the trellis structure for decoding an 802.11 convolutional code.*/ void ccodedot11_init_inv(void); -/*!\fn void teillis_table_init(void) -\brief This function initializes the trellis structure for 3GPP LTE Turbo code.*/ -void treillis_table_init(void); + /*\fn void threegpplte_turbo_encoder(uint8_t *input,uint16_t input_length_bytes,uint8_t *output,uint8_t F,uint16_t interleaver_f1,uint16_t interleaver_f2) \brief This function implements a rate 1/3 8-state parralel concatenated turbo code (3GPP-LTE). @@ -352,35 +350,7 @@ void ccodedab_init_inv(void); \brief This function initializes the different crc tables.*/ void crcTableInit (void); -/*!\fn void free_td8(void) -\brief This function frees the tables for 8-bit LLR Turbo decoder.*/ -void free_td8(void); -/*!\fn void init_td8(void) -\brief This function initializes the tables for 8-bit LLR Turbo decoder.*/ -void init_td8 (void); - -/*!\fn void free_td16(void) -\brief This function frees the tables for 16-bit LLR Turbo decoder.*/ -void free_td16(void); - -/*!\fn void init_td16(void) -\brief This function initializes the tables for 16-bit LLR Turbo decoder.*/ -void init_td16 (void); - -#ifdef __AVX2__ -/*!\fn void init_td8(void) -\brief This function initializes the tables for 8-bit LLR Turbo decoder (AVX2).*/ -void init_td8avx2 (void); - -/*!\fn void free_td16avx2(void) -\brief This function frees the tables for 16-bit LLR Turbo decoder (AVX2).*/ -void free_td16avx2(void); - -/*!\fn void init_td16(void) -\brief This function initializes the tables for 16-bit LLR Turbo decoder (AVX2).*/ -void init_td16avx2 (void); -#endif /*!\fn uint32_t crc24a(uint8_t *inPtr, int32_t bitlen) \brief This computes a 24-bit crc ('a' variant for overall transport block) diff --git a/openair1/PHY/CODING/extern.h b/openair1/PHY/CODING/extern.h index 9c58920a10..0d3e2ccb02 100644 --- a/openair1/PHY/CODING/extern.h +++ b/openair1/PHY/CODING/extern.h @@ -20,5 +20,9 @@ */ extern unsigned short f1f2mat_old[2*188]; - - +extern double cpuf; +extern decoder_if_t decoder16; +extern decoder_if_t decoder8; +extern encoder_if_t encoder; +extern int load_codinglib(void); +extern int free_codinglib(void); diff --git a/openair1/PHY/INIT/init_top.c b/openair1/PHY/INIT/init_top.c index a1edd9d1ea..34e82771b4 100644 --- a/openair1/PHY/INIT/init_top.c +++ b/openair1/PHY/INIT/init_top.c @@ -34,15 +34,12 @@ void init_lte_top(LTE_DL_FRAME_PARMS *frame_parms) ccodelte_init(); ccodelte_init_inv(); - treillis_table_init(); + phy_generate_viterbi_tables(); phy_generate_viterbi_tables_lte(); - init_td8(); - init_td16(); -#ifdef __AVX2__ - init_td16avx2(); -#endif + + load_codinglib(); lte_sync_time_init(frame_parms); generate_ul_ref_sigs(); @@ -61,11 +58,7 @@ void init_lte_top(LTE_DL_FRAME_PARMS *frame_parms) void free_lte_top(void) { - free_td8(); - free_td16(); -#ifdef __AVX2__ - free_td16avx2(); -#endif + free_codinglib(); lte_sync_time_free(); /* free_ul_ref_sigs() is called in phy_free_lte_eNB() */ diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index 7f8c0058ea..e91665e04e 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -286,13 +286,13 @@ int dlsch_encoding_2threads0(te_params *tep) { - threegpplte_turbo_encoder(dlsch->harq_processes[harq_pid]->c[r], - Kr>>3, - &dlsch->harq_processes[harq_pid]->d[r][96], - (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, - f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) - f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) - ); + encoder(dlsch->harq_processes[harq_pid]->c[r], + Kr>>3, + &dlsch->harq_processes[harq_pid]->d[r][96], + (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, + f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) + f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) + ); dlsch->harq_processes[harq_pid]->RTC[r] = sub_block_interleaving_turbo(4+(Kr_bytes*8), &dlsch->harq_processes[harq_pid]->d[r][96], @@ -458,13 +458,13 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, start_meas(te_stats); - threegpplte_turbo_encoder(dlsch->harq_processes[harq_pid]->c[r], - Kr>>3, - &dlsch->harq_processes[harq_pid]->d[r][96], - (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, - f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) - f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) - ); + encoder(dlsch->harq_processes[harq_pid]->c[r], + Kr>>3, + &dlsch->harq_processes[harq_pid]->d[r][96], + (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, + f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) + f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) + ); stop_meas(te_stats); start_meas(i_stats); @@ -651,13 +651,13 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, printf("Encoding ... iind %d f1 %d, f2 %d\n",iind,f1f2mat_old[iind*2],f1f2mat_old[(iind*2)+1]); #endif start_meas(te_stats); - threegpplte_turbo_encoder(dlsch->harq_processes[harq_pid]->c[r], - Kr>>3, - &dlsch->harq_processes[harq_pid]->d[r][96], - (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, - f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) - f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) - ); + encoder(dlsch->harq_processes[harq_pid]->c[r], + Kr>>3, + &dlsch->harq_processes[harq_pid]->d[r][96], + (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, + f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) + f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) + ); stop_meas(te_stats); #ifdef DEBUG_DLSCH_CODING @@ -833,13 +833,13 @@ int dlsch_encoding_SIC(PHY_VARS_UE *ue, printf("Encoding ... iind %d f1 %d, f2 %d\n",iind,f1f2mat_old[iind*2],f1f2mat_old[(iind*2)+1]); #endif start_meas(te_stats); - threegpplte_turbo_encoder(dlsch->harq_processes[harq_pid]->c[r], - Kr>>3, - &dlsch->harq_processes[harq_pid]->d[r][96], - (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, - f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) - f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) - ); + encoder(dlsch->harq_processes[harq_pid]->c[r], + Kr>>3, + &dlsch->harq_processes[harq_pid]->d[r][96], + (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, + f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) + f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) + ); stop_meas(te_stats); #ifdef DEBUG_DLSCH_CODING diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c index 697164110b..4020056e6f 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c @@ -39,7 +39,6 @@ //#define DEBUG_DLSCH_DECODING //#define UE_DEBUG_TRACE 1 -extern double cpuf; void free_ue_dlsch(LTE_UE_DLSCH_t *dlsch) { @@ -206,21 +205,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, time_stats_t *); #endif - uint8_t (*tc)(int16_t *y, - uint8_t *, - uint16_t, - uint16_t, - uint16_t, - uint8_t, - uint8_t, - uint8_t, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *); +decoder_if_t tc; @@ -255,13 +240,13 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, #if 0 tc_2cw = phy_threegpplte_turbo_decoder16avx2; #endif - tc = phy_threegpplte_turbo_decoder16; + tc = decoder16; } else { AssertFatal (harq_process->TBS >= 256 , "Mismatch flag nbRB=%d TBS=%d mcs=%d Qm=%d RIV=%d round=%d \n", harq_process->nb_rb, harq_process->TBS,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round); - tc = phy_threegpplte_turbo_decoder8; + tc = decoder8; } @@ -490,7 +475,9 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, LOG_D(PHY,"AbsSubframe %d.%d Start turbo segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1); ret = tc (&harq_process->d[r][96], + NULL, harq_process->c[r], + NULL, Kr, f1f2mat_old[iind*2], f1f2mat_old[(iind*2)+1], diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c index 9b761f3cc3..09420f48ab 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c @@ -371,13 +371,13 @@ uint32_t ulsch_encoding(uint8_t *a, printf("Encoding ... iind %d f1 %d, f2 %d\n",iind,f1f2mat_old[iind*2],f1f2mat_old[(iind*2)+1]); #endif start_meas(te_stats); - threegpplte_turbo_encoder(ulsch->harq_processes[harq_pid]->c[r], - Kr>>3, - &ulsch->harq_processes[harq_pid]->d[r][96], - (r==0) ? ulsch->harq_processes[harq_pid]->F : 0, - f1f2mat_old[iind*2], // f1 (see 36212-820, page 14) - f1f2mat_old[(iind*2)+1] // f2 (see 36212-820, page 14) - ); + encoder(ulsch->harq_processes[harq_pid]->c[r], + Kr>>3, + &ulsch->harq_processes[harq_pid]->d[r][96], + (r==0) ? ulsch->harq_processes[harq_pid]->F : 0, + f1f2mat_old[iind*2], // f1 (see 36212-820, page 14) + f1f2mat_old[(iind*2)+1] // f2 (see 36212-820, page 14) + ); stop_meas(te_stats); #ifdef DEBUG_ULSCH_CODING diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index 57087051d3..0d9bf8fd76 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -242,27 +242,12 @@ int ulsch_decoding_data_2thread0(td_params* tdp) { uint32_t E=0; uint32_t Gp,GpmodC,Nl=1; uint32_t C = ulsch_harq->C; - - uint8_t (*tc)(int16_t *y, - uint8_t *, - uint16_t, - uint16_t, - uint16_t, - uint8_t, - uint8_t, - uint8_t, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *); + decoder_if_t tc; if (llr8_flag == 0) - tc = phy_threegpplte_turbo_decoder16; + tc = decoder16; else - tc = phy_threegpplte_turbo_decoder8; + tc = decoder8; @@ -385,7 +370,9 @@ int ulsch_decoding_data_2thread0(td_params* tdp) { ret = tc(&ulsch_harq->d[r][96], + NULL, ulsch_harq->c[r], + NULL, Kr, f1f2mat_old[iind*2], f1f2mat_old[(iind*2)+1], @@ -463,22 +450,7 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr int G = ulsch_harq->G; unsigned int E; int Cby2; - - uint8_t (*tc)(int16_t *y, - uint8_t *, - uint16_t, - uint16_t, - uint16_t, - uint8_t, - uint8_t, - uint8_t, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *); + decoder_if_t tc; struct timespec wait; @@ -487,9 +459,9 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr if (llr8_flag == 0) - tc = phy_threegpplte_turbo_decoder16; + tc = decoder16; else - tc = phy_threegpplte_turbo_decoder8; + tc = decoder8; if (ulsch_harq->C>1) { // wakeup worker if more than 1 segment if (pthread_mutex_timedlock(&proc->mutex_td,&wait) != 0) { @@ -608,7 +580,9 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr start_meas(&eNB->ulsch_turbo_decoding_stats); ret = tc(&ulsch_harq->d[r][96], + NULL, ulsch_harq->c[r], + NULL, Kr, f1f2mat_old[iind*2], f1f2mat_old[(iind*2)+1], @@ -670,27 +644,12 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) int G = ulsch_harq->G; unsigned int E; - - uint8_t (*tc)(int16_t *y, - uint8_t *, - uint16_t, - uint16_t, - uint16_t, - uint8_t, - uint8_t, - uint8_t, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *); + decoder_if_t tc; if (llr8_flag == 0) - tc = phy_threegpplte_turbo_decoder16; + tc = *decoder16; else - tc = phy_threegpplte_turbo_decoder8; + tc = *decoder8; for (r=0; rC; r++) { @@ -773,7 +732,9 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) start_meas(&eNB->ulsch_turbo_decoding_stats); ret = tc(&ulsch_harq->d[r][96], + NULL, ulsch_harq->c[r], + NULL, Kr, f1f2mat_old[iind*2], f1f2mat_old[(iind*2)+1], diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index 46f37e9431..a12a0fd210 100644 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -1461,6 +1461,53 @@ extern pthread_cond_t sync_cond; extern pthread_mutex_t sync_mutex; extern int sync_var; + +#define MODE_DECODE_NONE 0 +#define MODE_DECODE_SSE 1 +#define MODE_DECODE_C 2 +#define MODE_DECODE_AVX2 3 + +#define DECODE_INITTD8_SSE_FPTRIDX 0 +#define DECODE_INITTD16_SSE_FPTRIDX 1 +#define DECODE_INITTD_AVX2_FPTRIDX 2 +#define DECODE_TD8_SSE_FPTRIDX 3 +#define DECODE_TD16_SSE_FPTRIDX 4 +#define DECODE_TD_C_FPTRIDX 5 +#define DECODE_TD16_AVX2_FPTRIDX 6 +#define DECODE_FREETD8_FPTRIDX 7 +#define DECODE_FREETD16_FPTRIDX 8 +#define DECODE_FREETD_AVX2_FPTRIDX 9 +#define ENCODE_SSE_FPTRIDX 10 +#define ENCODE_C_FPTRIDX 11 +#define ENCODE_INIT_SSE_FPTRIDX 12 +#define DECODE_NUM_FPTR 13 + + +typedef uint8_t(*decoder_if_t)(int16_t *y, + int16_t *y2, + uint8_t *decoded_bytes, + uint8_t *decoded_bytes2, + uint16_t n, + uint16_t f1, + uint16_t f2, + uint8_t max_iterations, + uint8_t crc_type, + uint8_t F, + time_stats_t *init_stats, + time_stats_t *alpha_stats, + time_stats_t *beta_stats, + time_stats_t *gamma_stats, + time_stats_t *ext_stats, + time_stats_t *intl1_stats, + time_stats_t *intl2_stats); + +typedef uint8_t(*encoder_if_t)(uint8_t *input, + uint16_t input_length_bytes, + uint8_t *output, + uint8_t F, + uint16_t interleaver_f1, + uint16_t interleaver_f2); + #define MAX_RRU_CONFIG_SIZE 1024 typedef enum { RAU_tick=0, diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 912e756f76..6c2e580947 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -650,7 +650,7 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; uint8_t SR_payload = 0,pucch_b0b1[4][2]= {{0,0},{0,0},{0,0},{0,0}},harq_ack[4]={0,0,0,0}; - int32_t metric[4]={0,0,0,0},metric_SR=0,max_metric; + int32_t metric[4]={0,0,0,0},metric_SR=0,max_metric=0; const int subframe = proc->subframe_rx; const int frame = proc->frame_rx; int i; diff --git a/openair2/ENB_APP/L1_paramdef.h b/openair2/ENB_APP/L1_paramdef.h new file mode 100644 index 0000000000..8eef55b718 --- /dev/null +++ b/openair2/ENB_APP/L1_paramdef.h @@ -0,0 +1,73 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file openair2/ENB_APP/L1_paramdef.f + * \brief definition of configuration parameters for all eNodeB modules + * \author Francois TABURET + * \date 2017 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ + + +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + + +/* L1 configuration parameters names */ +#define CONFIG_STRING_L1_CC "num_cc" +#define CONFIG_STRING_L1_LOCAL_N_IF_NAME "local_n_if_name" +#define CONFIG_STRING_L1_LOCAL_N_ADDRESS "local_n_address" +#define CONFIG_STRING_L1_REMOTE_N_ADDRESS "remote_n_address" +#define CONFIG_STRING_L1_LOCAL_N_PORTC "local_n_portc" +#define CONFIG_STRING_L1_REMOTE_N_PORTC "remote_n_portc" +#define CONFIG_STRING_L1_LOCAL_N_PORTD "local_n_portd" +#define CONFIG_STRING_L1_REMOTE_N_PORTD "remote_n_portd" +#define CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE "tr_n_preference" + +/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* L1 configuration parameters */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define L1PARAMS_DESC { \ +{CONFIG_STRING_L1_CC, NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \ +{CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"local_mac", TYPE_STRING, 0}, \ +{CONFIG_STRING_L1_LOCAL_N_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ +{CONFIG_STRING_L1_LOCAL_N_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ +{CONFIG_STRING_L1_REMOTE_N_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.2", TYPE_STRING, 0}, \ +{CONFIG_STRING_L1_LOCAL_N_PORTC, NULL, 0, uptr:NULL, defintval:50030, TYPE_UINT, 0}, \ +{CONFIG_STRING_L1_REMOTE_N_PORTC, NULL, 0, uptr:NULL, defintval:50030, TYPE_UINT, 0}, \ +{CONFIG_STRING_L1_LOCAL_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \ +{CONFIG_STRING_L1_REMOTE_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \ +} +#define L1_CC_IDX 0 +#define L1_TRANSPORT_N_PREFERENCE_IDX 1 +#define L1_LOCAL_N_IF_NAME_IDX 2 +#define L1_LOCAL_N_ADDRESS_IDX 3 +#define L1_REMOTE_N_ADDRESS_IDX 4 +#define L1_LOCAL_N_PORTC_IDX 5 +#define L1_REMOTE_N_PORTC_IDX 6 +#define L1_LOCAL_N_PORTD_IDX 7 +#define L1_REMOTE_N_PORTD_IDX 8 + +/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/ENB_APP/MACRLC_paramdef.h b/openair2/ENB_APP/MACRLC_paramdef.h new file mode 100644 index 0000000000..868917a0ab --- /dev/null +++ b/openair2/ENB_APP/MACRLC_paramdef.h @@ -0,0 +1,98 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file openair2/ENB_APP/MACRLC_paramdef.f + * \brief definition of configuration parameters for all eNodeB modules + * \author Francois TABURET + * \date 2017 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ + + + +/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ + + +/* MACRLC configuration parameters names */ +#define CONFIG_STRING_MACRLC_CC "num_cc" +#define CONFIG_STRING_MACRLC_TRANSPORT_N_PREFERENCE "tr_n_preference" +#define CONFIG_STRING_MACRLC_LOCAL_N_IF_NAME "local_n_if_name" +#define CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS "local_n_address" +#define CONFIG_STRING_MACRLC_REMOTE_N_ADDRESS "remote_n_address" +#define CONFIG_STRING_MACRLC_LOCAL_N_PORTC "local_n_portc" +#define CONFIG_STRING_MACRLC_REMOTE_N_PORTC "remote_n_portc" +#define CONFIG_STRING_MACRLC_LOCAL_N_PORTD "local_n_portd" +#define CONFIG_STRING_MACRLC_REMOTE_N_PORTD "remote_n_portd" +#define CONFIG_STRING_MACRLC_TRANSPORT_S_PREFERENCE "tr_s_preference" +#define CONFIG_STRING_MACRLC_LOCAL_S_IF_NAME "local_s_if_name" +#define CONFIG_STRING_MACRLC_LOCAL_S_ADDRESS "local_s_address" +#define CONFIG_STRING_MACRLC_REMOTE_S_ADDRESS "remote_s_address" +#define CONFIG_STRING_MACRLC_LOCAL_S_PORTC "local_s_portc" +#define CONFIG_STRING_MACRLC_REMOTE_S_PORTC "remote_s_portc" +#define CONFIG_STRING_MACRLC_LOCAL_S_PORTD "local_s_portd" +#define CONFIG_STRING_MACRLC_REMOTE_S_PORTD "remote_s_portd" + + +/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* MacRLC configuration parameters */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define MACRLCPARAMS_DESC { \ +{CONFIG_STRING_MACRLC_CC, NULL, 0, uptr:NULL, defintval:50011, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_TRANSPORT_N_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"local_L1", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_LOCAL_N_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_REMOTE_N_ADDRESS, NULL, 0, uptr:NULL, defstrval:"127.0.0.2", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_LOCAL_N_PORTC, NULL, 0, uptr:NULL, defintval:50010, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_REMOTE_N_PORTC, NULL, 0, uptr:NULL, defintval:50010, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_LOCAL_N_PORTD, NULL, 0, uptr:NULL, defintval:50011, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_REMOTE_N_PORTD, NULL, 0, uptr:NULL, defintval:50011, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_TRANSPORT_S_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"local_RRC", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_LOCAL_S_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_LOCAL_S_ADDRESS, NULL, 0, uptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_REMOTE_S_ADDRESS, NULL, 0, uptr:NULL, defstrval:"127.0.0.2", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_LOCAL_S_PORTC, NULL, 0, uptr:NULL, defintval:50020, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_REMOTE_S_PORTC, NULL, 0, uptr:NULL, defintval:50020, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_LOCAL_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_REMOTE_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \ +} +#define MACRLC_CC_IDX 0 +#define MACRLC_TRANSPORT_N_PREFERENCE_IDX 1 +#define MACRLC_LOCAL_N_IF_NAME_IDX 2 +#define MACRLC_LOCAL_N_ADDRESS_IDX 3 +#define MACRLC_REMOTE_N_ADDRESS_IDX 4 +#define MACRLC_LOCAL_N_PORTC_IDX 5 +#define MACRLC_REMOTE_N_PORTC_IDX 6 +#define MACRLC_LOCAL_N_PORTD_IDX 7 +#define MACRLC_REMOTE_N_PORTD_IDX 8 +#define MACRLC_TRANSPORT_S_PREFERENCE_IDX 9 +#define MACRLC_LOCAL_S_IF_NAME_IDX 10 +#define MACRLC_LOCAL_S_ADDRESS_IDX 11 +#define MACRLC_REMOTE_S_ADDRESS_IDX 12 +#define MACRLC_LOCAL_S_PORTC_IDX 13 +#define MACRLC_REMOTE_S_PORTC_IDX 14 +#define MACRLC_LOCAL_S_PORTD_IDX 15 +#define MACRLC_REMOTE_S_PORTD_IDX 16 +/*---------------------------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/ENB_APP/RRC_config_tools.c b/openair2/ENB_APP/RRC_config_tools.c new file mode 100644 index 0000000000..17fbad1e18 --- /dev/null +++ b/openair2/ENB_APP/RRC_config_tools.c @@ -0,0 +1,123 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* + RRC_config_tools.c + ------------------- + AUTHOR : Francois TABURET + COMPANY : NOKIA BellLabs France + EMAIL : francois.taburet@nokia-bell-labs.com + +*/ + +#include +#include + +#include "log.h" +#include "log_extern.h" +#include "assertions.h" +#if defined(ENABLE_ITTI) +# include "intertask_interface.h" +# if defined(ENABLE_USE_MME) +# include "s1ap_eNB.h" +# include "sctp_eNB_task.h" +# endif +#endif +#include "SystemInformationBlockType2.h" +#include "common/config/config_userapi.h" +#include "RRC_config_tools.h" +#include "DL-GapConfig-NB-r13.h" +#include "NPRACH-Parameters-NB-r13.h" + +static const eutra_band_t eutra_bands[] = { + { 1, 1920 * MHz, 1980 * MHz, 2110 * MHz, 2170 * MHz, FDD}, + { 2, 1850 * MHz, 1910 * MHz, 1930 * MHz, 1990 * MHz, FDD}, + { 3, 1710 * MHz, 1785 * MHz, 1805 * MHz, 1880 * MHz, FDD}, + { 4, 1710 * MHz, 1755 * MHz, 2110 * MHz, 2155 * MHz, FDD}, + { 5, 824 * MHz, 849 * MHz, 869 * MHz, 894 * MHz, FDD}, + { 6, 830 * MHz, 840 * MHz, 875 * MHz, 885 * MHz, FDD}, + { 7, 2500 * MHz, 2570 * MHz, 2620 * MHz, 2690 * MHz, FDD}, + { 8, 880 * MHz, 915 * MHz, 925 * MHz, 960 * MHz, FDD}, + { 9, 1749900 * KHz, 1784900 * KHz, 1844900 * KHz, 1879900 * KHz, FDD}, + {10, 1710 * MHz, 1770 * MHz, 2110 * MHz, 2170 * MHz, FDD}, + {11, 1427900 * KHz, 1452900 * KHz, 1475900 * KHz, 1500900 * KHz, FDD}, + {12, 698 * MHz, 716 * MHz, 728 * MHz, 746 * MHz, FDD}, + {13, 777 * MHz, 787 * MHz, 746 * MHz, 756 * MHz, FDD}, + {14, 788 * MHz, 798 * MHz, 758 * MHz, 768 * MHz, FDD}, + + {17, 704 * MHz, 716 * MHz, 734 * MHz, 746 * MHz, FDD}, + {20, 832 * MHz, 862 * MHz, 791 * MHz, 821 * MHz, FDD}, + {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, + {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, + {34, 2010 * MHz, 2025 * MHz, 2010 * MHz, 2025 * MHz, TDD}, + {35, 1850 * MHz, 1910 * MHz, 1850 * MHz, 1910 * MHz, TDD}, + {36, 1930 * MHz, 1990 * MHz, 1930 * MHz, 1990 * MHz, TDD}, + {37, 1910 * MHz, 1930 * MHz, 1910 * MHz, 1930 * MHz, TDD}, + {38, 2570 * MHz, 2620 * MHz, 2570 * MHz, 2630 * MHz, TDD}, + {39, 1880 * MHz, 1920 * MHz, 1880 * MHz, 1920 * MHz, TDD}, + {40, 2300 * MHz, 2400 * MHz, 2300 * MHz, 2400 * MHz, TDD}, + {41, 2496 * MHz, 2690 * MHz, 2496 * MHz, 2690 * MHz, TDD}, + {42, 3400 * MHz, 3600 * MHz, 3400 * MHz, 3600 * MHz, TDD}, + {43, 3600 * MHz, 3800 * MHz, 3600 * MHz, 3800 * MHz, TDD}, + {44, 703 * MHz, 803 * MHz, 703 * MHz, 803 * MHz, TDD}, +}; + + +int config_check_band_frequencies( int ind, + int16_t band, + uint32_t downlink_frequency, + int32_t uplink_frequency_offset, + uint32_t frame_type) +{ + int errors = 0; + + if (band > 0) { + int band_index; + + for (band_index = 0; band_index < sizeof (eutra_bands) / sizeof (eutra_bands[0]); band_index++) { + if (band == eutra_bands[band_index].band) { + uint32_t uplink_frequency = downlink_frequency + uplink_frequency_offset; + + AssertError (eutra_bands[band_index].dl_min < downlink_frequency, errors ++, + "enb %d downlink frequency %u too low (%u) for band %d!", + ind, downlink_frequency, eutra_bands[band_index].dl_min, band); + AssertError (downlink_frequency < eutra_bands[band_index].dl_max, errors ++, + "enb %d downlink frequency %u too high (%u) for band %d!", + ind, downlink_frequency, eutra_bands[band_index].dl_max, band); + + AssertError (eutra_bands[band_index].ul_min < uplink_frequency, errors ++, + "enb %d uplink frequency %u too low (%u) for band %d!", + ind, uplink_frequency, eutra_bands[band_index].ul_min, band); + AssertError (uplink_frequency < eutra_bands[band_index].ul_max, errors ++, + "enb %d uplink frequency %u too high (%u) for band %d!", + ind, uplink_frequency, eutra_bands[band_index].ul_max, band); + + AssertError (eutra_bands[band_index].frame_type == frame_type, errors ++, + "enb %d invalid frame type (%d/%d) for band %d!", + ind, eutra_bands[band_index].frame_type, frame_type, band); + } + } + } + + + return errors; +} + diff --git a/openair2/ENB_APP/RRC_config_tools.h b/openair2/ENB_APP/RRC_config_tools.h new file mode 100644 index 0000000000..a44da1f90c --- /dev/null +++ b/openair2/ENB_APP/RRC_config_tools.h @@ -0,0 +1,50 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* + RRC_config_tools.h + ------------------- + AUTHOR : Francois TABURET + COMPANY : NOKIA BellLabs France + EMAIL : francois.taburet@nokia-bell-labs.com +*/ +#ifndef RRC_CONFIG_TOOLS_H_ +#define RRC_CONFIG_TOOLS_H_ + +#define KHz (1000UL) +#define MHz (1000 * KHz) + +typedef struct eutra_band_s { + int16_t band; + uint32_t ul_min; + uint32_t ul_max; + uint32_t dl_min; + uint32_t dl_max; + lte_frame_type_t frame_type; +} eutra_band_t; + + +extern int config_check_band_frequencies(int ind, int16_t band, uint32_t downlink_frequency, + int32_t uplink_frequency_offset, uint32_t frame_type); + +extern int config_check_assign_DLGap_NB(paramdef_t *param); +extern int config_check_assign_rach_NB(paramdef_t *param); +#endif diff --git a/openair2/ENB_APP/RRC_paramsvalues.h b/openair2/ENB_APP/RRC_paramsvalues.h new file mode 100644 index 0000000000..fb375e1a09 --- /dev/null +++ b/openair2/ENB_APP/RRC_paramsvalues.h @@ -0,0 +1,94 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file openair2/ENB_APP/RRC_paramsvalues.h + * \brief macro definitions for RRC authorized and asn1 parameters values, to be used in paramdef_t/chechedparam_t structure initializations + * \author Francois TABURET + * \date 2017 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ +#ifndef __RRC_PARAMSVALUES__H__ +#define __RRC_PARAMSVALUES__H__ +/* cell configuration section name */ +#define ENB_CONFIG_STRING_ENB_LIST "eNBs" +/* component carriers configuration section name */ +#define ENB_CONFIG_STRING_COMPONENT_CARRIERS "component_carriers" + +#define ENB_CONFIG_STRING_FRAME_TYPE "frame_type" +#define ENB_CONFIG_STRING_PBCH_REPETITION "pbch_repetition" +#define ENB_CONFIG_STRING_TDD_CONFIG "tdd_config" +#define ENB_CONFIG_STRING_TDD_CONFIG_S "tdd_config_s" +#define ENB_CONFIG_STRING_PREFIX_TYPE "prefix_type" +#define ENB_CONFIG_STRING_PREFIX_TYPE_UL "prefix_type_UL" +#define ENB_CONFIG_STRING_EUTRA_BAND "eutra_band" +#define ENB_CONFIG_STRING_DOWNLINK_FREQUENCY "downlink_frequency" +#define ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET "uplink_frequency_offset" +#define ENB_CONFIG_STRING_NID_CELL "Nid_cell" +#define ENB_CONFIG_STRING_N_RB_DL "N_RB_DL" +#define ENB_CONFIG_STRING_CELL_MBSFN "Nid_cell_mbsfn" + + +#define FRAMETYPE_OKVALUES {"FDD","TDD"} +#define FRAMETYPE_MODVALUES { FDD, TDD} + +#define TDDCFG(A) TDD_Config__subframeAssignment_ ## A +#define TDDCONFIG_OKRANGE { TDDCFG(sa0), TDDCFG(sa6)} + +#define TDDCFGS(A) TDD_Config__specialSubframePatterns_ ## A +#define TDDCONFIGS_OKRANGE { TDDCFGS(ssp0), TDDCFGS(ssp8)} + +#define PREFIX_OKVALUES {"NORMAL","EXTENDED"} +#define PREFIX_MODVALUES { NORMAL, EXTENDED} + +#define PREFIXUL_OKVALUES {"NORMAL","EXTENDED"} +#define PREFIXUL_MODVALUES { NORMAL, EXTENDED} + +#define NRBDL_OKVALUES {6,15,25,50,75,100} + +#define UETIMER_T300_OKVALUES {100,200,300,400,600,1000,1500,2000} +#define UETT300(A) UE_TimersAndConstants__t300_ ## A +#define UETIMER_T300_MODVALUES { UETT300(ms100), UETT300(ms200),UETT300(ms300),UETT300(ms400),UETT300(ms600),UETT300(ms1000),UETT300(ms1500),UETT300(ms2000)} + +#define UETIMER_T301_OKVALUES {100,200,300,400,600,1000,1500,2000} +#define UETT301(A) UE_TimersAndConstants__t301_ ## A +#define UETIMER_T301_MODVALUES { UETT301(ms100), UETT301(ms200),UETT301(ms300),UETT301(ms400),UETT301(ms600),UETT301(ms1000),UETT301(ms1500),UETT301(ms2000)} + +#define UETIMER_T310_OKVALUES {0,50,100,200,500,1000,2000} +#define UETT310(A) UE_TimersAndConstants__t310_ ## A +#define UETIMER_T310_MODVALUES { UETT310(ms0), UETT310(ms50),UETT310(ms100),UETT310(ms200),UETT310(ms500),UETT310(ms1000),UETT310(ms2000)} + +#define UETIMER_T311_OKVALUES {1000,3110,5000,10000,15000,20000,31100} +#define UETT311(A) UE_TimersAndConstants__t311_ ## A +#define UETIMER_T311_MODVALUES { UETT311(ms1000), UETT311(ms3000),UETT311(ms5000),UETT311(ms10000),UETT311(ms15000),UETT311(ms20000),UETT311(ms30000)} + +#define UETIMER_N310_OKVALUES {1,2,3,4,6,8,10,20} +#define UETN310(A) UE_TimersAndConstants__n310_ ## A +#define UETIMER_N310_MODVALUES { UETN310(n1), UETN310(n2),UETN310(n3),UETN310(n4),UETN310(n6),UETN310(n8),UETN310(n10),UETN310(n20)} + +#define UETIMER_N311_OKVALUES {1,2,3,4,5,6,8,10} +#define UETN311(A) UE_TimersAndConstants__n311_ ## A +#define UETIMER_N311_MODVALUES { UETN311(n1), UETN311(n2),UETN311(n3),UETN311(n4),UETN311(n5),UETN311(n6),UETN311(n8),UETN311(n10)} + +#endif diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index a30dc28c94..5e9c320f57 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -52,51 +52,14 @@ #include "nfapi_vnf.h" #include "nfapi_pnf.h" -#include "enb_paramdef.h" +#include "L1_paramdef.h" +#include "MACRLC_paramdef.h" #include "common/config/config_userapi.h" +#include "RRC_config_tools.h" +#include "enb_paramdef.h" extern uint16_t sf_ahead; -static int enb_check_band_frequencies(char* lib_config_file_name_pP, - int ind, - int16_t band, - uint32_t downlink_frequency, - int32_t uplink_frequency_offset, - lte_frame_type_t frame_type) -{ - int errors = 0; - - if (band > 0) { - int band_index; - - for (band_index = 0; band_index < sizeof (eutra_bands) / sizeof (eutra_bands[0]); band_index++) { - if (band == eutra_bands[band_index].band) { - uint32_t uplink_frequency = downlink_frequency + uplink_frequency_offset; - - AssertError (eutra_bands[band_index].dl_min < downlink_frequency, errors ++, - "Failed to parse eNB configuration file %s, enb %d downlink frequency %u too low (%u) for band %d!", - lib_config_file_name_pP, ind, downlink_frequency, eutra_bands[band_index].dl_min, band); - AssertError (downlink_frequency < eutra_bands[band_index].dl_max, errors ++, - "Failed to parse eNB configuration file %s, enb %d downlink frequency %u too high (%u) for band %d!", - lib_config_file_name_pP, ind, downlink_frequency, eutra_bands[band_index].dl_max, band); - - AssertError (eutra_bands[band_index].ul_min < uplink_frequency, errors ++, - "Failed to parse eNB configuration file %s, enb %d uplink frequency %u too low (%u) for band %d!", - lib_config_file_name_pP, ind, uplink_frequency, eutra_bands[band_index].ul_min, band); - AssertError (uplink_frequency < eutra_bands[band_index].ul_max, errors ++, - "Failed to parse eNB configuration file %s, enb %d uplink frequency %u too high (%u) for band %d!", - lib_config_file_name_pP, ind, uplink_frequency, eutra_bands[band_index].ul_max, band); - - AssertError (eutra_bands[band_index].frame_type == frame_type, errors ++, - "Failed to parse eNB configuration file %s, enb %d invalid frame type (%d/%d) for band %d!", - lib_config_file_name_pP, ind, eutra_bands[band_index].frame_type, frame_type, band); - } - } - } - - - return errors; -} void RCconfig_flexran() { @@ -420,14 +383,16 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { paramdef_t ENBParams[] = ENBPARAMS_DESC; paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST,NULL,0}; + checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK; paramdef_t CCsParams[] = CCPARAMS_DESC; paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS,NULL,0}; paramdef_t SRB1Params[] = SRB1PARAMS_DESC; - - - +/* 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]); + } /* get global parameters, defined outside any section in the config file */ config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL); @@ -562,43 +527,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { nb_cc++; - /* - if (strcmp(cc_node_function, "eNodeB_3GPP") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_function[j] = eNodeB_3GPP; - } else if (strcmp(cc_node_function, "eNodeB_3GPP_BBU") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_function[j] = eNodeB_3GPP_BBU; - } else if (strcmp(cc_node_function, "NGFI_RCC_IF4p5") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_function[j] = NGFI_RCC_IF4p5; - } else if (strcmp(cc_node_function, "NGFI_RAU_IF4p5") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_function[j] = NGFI_RAU_IF4p5; - } else if (strcmp(cc_node_function, "NGFI_RRU_IF4p5") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_function[j] = NGFI_RRU_IF4p5; - } else if (strcmp(cc_node_function, "NGFI_RRU_IF5") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_function[j] = NGFI_RRU_IF5; - } else { - AssertError (0, parse_errors ++, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for node_function choice: eNodeB_3GPP or eNodeB_3GPP_BBU or NGFI_IF4_RCC or NGFI_IF4_RRU or NGFI_IF5_RRU !\n", - lib_config_file_name_pP, i, cc_node_function); - } - - if (strcmp(cc_node_timing, "synch_to_ext_device") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_timing[j] = synch_to_ext_device; - } else if (strcmp(cc_node_timing, "synch_to_other") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_timing[j] = synch_to_other; - } else { - AssertError (0, parse_errors ++, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for node_function choice: SYNCH_TO_DEVICE or SYNCH_TO_OTHER !\n", - lib_config_file_name_pP, i, cc_node_timing); - } - - if ((cc_node_synch_ref >= -1) && (cc_node_synch_ref < num_component_carriers)) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_synch_ref[j] = (int16_t) cc_node_synch_ref; - } else { - AssertError (0, parse_errors ++, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for node_synch_ref choice: valid CC_id or -1 !\n", - lib_config_file_name_pP, i, cc_node_synch_ref); - } - */ + RRC_CONFIGURATION_REQ (msg_p).tdd_config[j] = tdd_config; @@ -710,8 +639,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j] = (unsigned int) uplink_frequency_offset; - if (enb_check_band_frequencies(RC.config_file_name, - j, + if (config_check_band_frequencies(j, RRC_CONFIGURATION_REQ (msg_p).eutra_band[j], RRC_CONFIGURATION_REQ (msg_p).downlink_frequency[j], RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j], @@ -1385,244 +1313,13 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { break; } - - switch (ue_TimersAndConstants_t300) { - case 100: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = UE_TimersAndConstants__t300_ms100; - break; - - case 200: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = UE_TimersAndConstants__t300_ms200; - break; - - case 300: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = UE_TimersAndConstants__t300_ms300; - break; - - case 400: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = UE_TimersAndConstants__t300_ms400; - break; - - case 600: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = UE_TimersAndConstants__t300_ms600; - break; - - case 1000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = UE_TimersAndConstants__t300_ms1000; - break; - - case 1500: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = UE_TimersAndConstants__t300_ms1500; - break; - - case 2000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = UE_TimersAndConstants__t300_ms2000; - break; - - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TimersAndConstants_t300 choice: 100,200,300,400,600,1000,1500,2000 ", - RC.config_file_name, i, ue_TimersAndConstants_t300); - break; - - } - - switch (ue_TimersAndConstants_t301) { - case 100: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = UE_TimersAndConstants__t301_ms100; - break; - - case 200: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = UE_TimersAndConstants__t301_ms200; - break; - - case 300: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = UE_TimersAndConstants__t301_ms300; - break; - - case 400: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = UE_TimersAndConstants__t301_ms400; - break; - - case 600: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = UE_TimersAndConstants__t301_ms600; - break; - - case 1000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = UE_TimersAndConstants__t301_ms1000; - break; - - case 1500: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = UE_TimersAndConstants__t301_ms1500; - break; - - case 2000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = UE_TimersAndConstants__t301_ms2000; - break; - - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TimersAndConstants_t301 choice: 100,200,300,400,600,1000,1500,2000 ", - RC.config_file_name, i, ue_TimersAndConstants_t301); - break; - - } - - switch (ue_TimersAndConstants_t310) { - case 0: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = UE_TimersAndConstants__t310_ms0; - break; - - case 50: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = UE_TimersAndConstants__t310_ms50; - break; - - case 100: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = UE_TimersAndConstants__t310_ms100; - break; - - case 200: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = UE_TimersAndConstants__t310_ms200; - break; - - case 500: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = UE_TimersAndConstants__t310_ms500; - break; - - case 1000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = UE_TimersAndConstants__t310_ms1000; - break; - - case 2000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = UE_TimersAndConstants__t310_ms2000; - break; - - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TimersAndConstants_t310 choice: 0,50,100,200,500,1000,1500,2000 ", - RC.config_file_name, i, ue_TimersAndConstants_t310); - break; - - } - - switch (ue_TimersAndConstants_t311) { - case 1000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = UE_TimersAndConstants__t311_ms1000; - break; - - case 3110: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = UE_TimersAndConstants__t311_ms3000; - break; - - case 5000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = UE_TimersAndConstants__t311_ms5000; - break; - - case 10000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = UE_TimersAndConstants__t311_ms10000; - break; - - case 15000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = UE_TimersAndConstants__t311_ms15000; - break; - - case 20000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = UE_TimersAndConstants__t311_ms20000; - break; - - case 31100: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = UE_TimersAndConstants__t311_ms30000; - break; - - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TimersAndConstants_t311 choice: 1000,3000,5000,10000,150000,20000,30000", - RC.config_file_name, i, ue_TimersAndConstants_t311); - break; - - } - - switch (ue_TimersAndConstants_n310) { - case 1: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = UE_TimersAndConstants__n310_n1; - break; - - case 2: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = UE_TimersAndConstants__n310_n2; - break; - - case 3: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = UE_TimersAndConstants__n310_n3; - break; - - case 4: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = UE_TimersAndConstants__n310_n4; - break; - - case 6: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = UE_TimersAndConstants__n310_n6; - break; - - case 8: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = UE_TimersAndConstants__n310_n8; - break; - - case 10: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = UE_TimersAndConstants__n310_n10; - break; - - case 20: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = UE_TimersAndConstants__n310_n20; - break; - - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TimersAndConstants_n310 choice: 1,2,3,4,6,6,8,10,20", - RC.config_file_name, i, ue_TimersAndConstants_n311); - break; - - } - - switch (ue_TimersAndConstants_n311) { - case 1: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = UE_TimersAndConstants__n311_n1; - break; - - case 2: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = UE_TimersAndConstants__n311_n2; - break; - - case 3: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = UE_TimersAndConstants__n311_n3; - break; - - case 4: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = UE_TimersAndConstants__n311_n4; - break; - - case 5: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = UE_TimersAndConstants__n311_n5; - break; - - case 6: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = UE_TimersAndConstants__n311_n6; - break; - - case 8: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = UE_TimersAndConstants__n311_n8; - break; - - case 10: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = UE_TimersAndConstants__n311_n10; - break; - - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TimersAndConstants_t311 choice: 1,2,3,4,5,6,8,10", - RC.config_file_name, i, ue_TimersAndConstants_t311); - break; - - } + + RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = ue_TimersAndConstants_t300; + RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = ue_TimersAndConstants_t301; + RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = ue_TimersAndConstants_t310; + RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = ue_TimersAndConstants_t311; + RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = ue_TimersAndConstants_n310; + RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = ue_TimersAndConstants_n311; switch (ue_TransmissionMode) { case 1: @@ -1965,275 +1662,32 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { } /* - // OTG _CONFIG - setting_otg = config_setting_get_member (setting_enb, ENB_CONF_STRING_OTG_CONFIG); - - if (setting_otg != NULL) { - num_otg_elements = config_setting_length(setting_otg); - printf("num otg elements %d \n", num_otg_elements); - enb_properties_loc.properties[enb_properties_loc_index]->num_otg_elements = 0; - - for (j = 0; j < num_otg_elements; j++) { - subsetting_otg=config_setting_get_elem(setting_otg, j); - - if (config_setting_lookup_int(subsetting_otg, ENB_CONF_STRING_OTG_UE_ID, &otg_ue_id)) { - enb_properties_loc.properties[enb_properties_loc_index]->otg_ue_id[j] = otg_ue_id; - } else { - enb_properties_loc.properties[enb_properties_loc_index]->otg_ue_id[j] = 1; - } - - if (config_setting_lookup_string(subsetting_otg, ENB_CONF_STRING_OTG_APP_TYPE, (const char **)&otg_app_type)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->otg_app_type[j] = map_str_to_int(otg_app_type_names,otg_app_type))== -1) { - enb_properties_loc.properties[enb_properties_loc_index]->otg_app_type[j] = BCBR; - } - } else { - enb_properties_loc.properties[enb_properties_loc_index]->otg_app_type[j] = NO_PREDEFINED_TRAFFIC; // 0 - } - - if (config_setting_lookup_string(subsetting_otg, ENB_CONF_STRING_OTG_BG_TRAFFIC, (const char **)&otg_bg_traffic)) { - - if ((enb_properties_loc.properties[enb_properties_loc_index]->otg_bg_traffic[j] = map_str_to_int(switch_names,otg_bg_traffic)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->otg_bg_traffic[j]=0; - } - } else { - enb_properties_loc.properties[enb_properties_loc_index]->otg_bg_traffic[j] = 0; - printf("otg bg %s\n", otg_bg_traffic); - } - - enb_properties_loc.properties[enb_properties_loc_index]->num_otg_elements+=1; - - } - } - - // log_config - subsetting = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_LOG_CONFIG); + // Network Controller + subsetting = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_NETWORK_CONTROLLER_CONFIG); if (subsetting != NULL) { - // global - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_GLOBAL_LOG_LEVEL, (const char **) &glog_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->glog_level = map_str_to_int(log_level_names, glog_level)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->glog_level = LOG_INFO; + if ( ( + config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_INTERFACE_NAME, + (const char **)&flexran_agent_interface_name) + && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_IPV4_ADDRESS, + (const char **)&flexran_agent_ipv4_address) + && config_setting_lookup_int(subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_PORT, + &flexran_agent_port) + && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_CACHE, + (const char **)&flexran_agent_cache) + ) + ) { + enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_interface_name = strdup(flexran_agent_interface_name); + cidr = flexran_agent_ipv4_address; + address = strtok(cidr, "/"); + //enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_ipv4_address = strdup(address); + if (address) { + IPV4_STR_ADDR_TO_INT_NWBO (address, enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_ipv4_address, "BAD IP ADDRESS FORMAT FOR eNB Agent !\n" ); } - //printf( "\tGlobal log level :\t%s->%d\n",glog_level, enb_properties_loc.properties[enb_properties_loc_index]->glog_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->glog_level = LOG_INFO; + enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_port = flexran_agent_port; + enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_cache = strdup(flexran_agent_cache); } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_GLOBAL_LOG_VERBOSITY,(const char **) &glog_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->glog_verbosity = map_str_to_int(log_verbosity_names, glog_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->glog_verbosity = LOG_MED; - } - - //printf( "\tGlobal log verbosity:\t%s->%d\n",glog_verbosity, enb_properties_loc.properties[enb_properties_loc_index]->glog_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->glog_verbosity = LOG_MED; - } - - // HW - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_HW_LOG_LEVEL, (const char **) &hw_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->hw_log_level = map_str_to_int(log_level_names,hw_log_level)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->hw_log_level = LOG_INFO; - } - - //printf( "\tHW log level :\t%s->%d\n",hw_log_level,enb_properties_loc.properties[enb_properties_loc_index]->hw_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->hw_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_HW_LOG_VERBOSITY, (const char **) &hw_log_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->hw_log_verbosity = map_str_to_int(log_verbosity_names,hw_log_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->hw_log_verbosity = LOG_MED; - } - - //printf( "\tHW log verbosity:\t%s->%d\n",hw_log_verbosity, enb_properties_loc.properties[enb_properties_loc_index]->hw_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->hw_log_verbosity = LOG_MED; - } - - // phy - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_PHY_LOG_LEVEL,(const char **) &phy_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->phy_log_level = map_str_to_int(log_level_names,phy_log_level)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->phy_log_level = LOG_INFO; - } - - //printf( "\tPHY log level :\t%s->%d\n",phy_log_level,enb_properties_loc.properties[enb_properties_loc_index]->phy_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->phy_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_PHY_LOG_VERBOSITY, (const char **)&phy_log_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->phy_log_verbosity = map_str_to_int(log_verbosity_names,phy_log_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->phy_log_verbosity = LOG_MED; - } - - //printf( "\tPHY log verbosity:\t%s->%d\n",phy_log_level,enb_properties_loc.properties[enb_properties_loc_index]->phy_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->phy_log_verbosity = LOG_MED; - } - - //mac - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_MAC_LOG_LEVEL, (const char **)&mac_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->mac_log_level = map_str_to_int(log_level_names,mac_log_level)) == -1 ) { - enb_properties_loc.properties[enb_properties_loc_index]->mac_log_level = LOG_INFO; - } - - //printf( "\tMAC log level :\t%s->%d\n",mac_log_level,enb_properties_loc.properties[enb_properties_loc_index]->mac_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->mac_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_MAC_LOG_VERBOSITY, (const char **)&mac_log_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->mac_log_verbosity = map_str_to_int(log_verbosity_names,mac_log_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->mac_log_verbosity = LOG_MED; - } - - //printf( "\tMAC log verbosity:\t%s->%d\n",mac_log_verbosity,enb_properties_loc.properties[enb_properties_loc_index]->mac_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->mac_log_verbosity = LOG_MED; - } - - //rlc - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_RLC_LOG_LEVEL, (const char **)&rlc_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_level = map_str_to_int(log_level_names,rlc_log_level)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_level = LOG_INFO; - } - - //printf( "\tRLC log level :\t%s->%d\n",rlc_log_level, enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_RLC_LOG_VERBOSITY, (const char **)&rlc_log_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_verbosity = map_str_to_int(log_verbosity_names,rlc_log_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_verbosity = LOG_MED; - } - - //printf( "\tRLC log verbosity:\t%s->%d\n",rlc_log_verbosity, enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_verbosity = LOG_MED; - } - - //pdcp - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_PDCP_LOG_LEVEL, (const char **)&pdcp_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_level = map_str_to_int(log_level_names,pdcp_log_level)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_level = LOG_INFO; - } - - //printf( "\tPDCP log level :\t%s->%d\n",pdcp_log_level, enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_PDCP_LOG_VERBOSITY, (const char **)&pdcp_log_verbosity)) { - enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_verbosity = map_str_to_int(log_verbosity_names,pdcp_log_verbosity); - //printf( "\tPDCP log verbosity:\t%s->%d\n",pdcp_log_verbosity, enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_verbosity = LOG_MED; - } - - //rrc - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_RRC_LOG_LEVEL, (const char **)&rrc_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_level = map_str_to_int(log_level_names,rrc_log_level)) == -1 ) { - enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_level = LOG_INFO; - } - - //printf( "\tRRC log level :\t%s->%d\n",rrc_log_level,enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_RRC_LOG_VERBOSITY, (const char **)&rrc_log_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_verbosity = map_str_to_int(log_verbosity_names,rrc_log_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_verbosity = LOG_MED; - } - - //printf( "\tRRC log verbosity:\t%s->%d\n",rrc_log_verbosity,enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_verbosity = LOG_MED; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_GTPU_LOG_LEVEL, (const char **)>pu_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_level = map_str_to_int(log_level_names,gtpu_log_level)) == -1 ) { - enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_level = LOG_INFO; - } - - //printf( "\tGTPU log level :\t%s->%d\n",gtpu_log_level,enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_GTPU_LOG_VERBOSITY, (const char **)>pu_log_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_verbosity = map_str_to_int(log_verbosity_names,gtpu_log_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_verbosity = LOG_MED; - } - - //printf( "\tGTPU log verbosity:\t%s->%d\n",gtpu_log_verbosity,enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_verbosity = LOG_MED; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_UDP_LOG_LEVEL, (const char **)&udp_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->udp_log_level = map_str_to_int(log_level_names,udp_log_level)) == -1 ) { - enb_properties_loc.properties[enb_properties_loc_index]->udp_log_level = LOG_INFO; - } - - //printf( "\tUDP log level :\t%s->%d\n",udp_log_level,enb_properties_loc.properties[enb_properties_loc_index]->udp_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->udp_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_UDP_LOG_VERBOSITY, (const char **)&udp_log_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->udp_log_verbosity = map_str_to_int(log_verbosity_names,udp_log_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->udp_log_verbosity = LOG_MED; - } - - //printf( "\tUDP log verbosity:\t%s->%d\n",udp_log_verbosity,enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->udp_log_verbosity = LOG_MED; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_OSA_LOG_LEVEL, (const char **)&osa_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->osa_log_level = map_str_to_int(log_level_names,osa_log_level)) == -1 ) { - enb_properties_loc.properties[enb_properties_loc_index]->osa_log_level = LOG_INFO; - } - - //printf( "\tOSA log level :\t%s->%d\n",osa_log_level,enb_properties_loc.properties[enb_properties_loc_index]->osa_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->osa_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_OSA_LOG_VERBOSITY, (const char **)&osa_log_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->osa_log_verbosity = map_str_to_int(log_verbosity_names,osa_log_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->osa_log_verbosity = LOG_MED; - } - - //printf( "\tOSA log verbosity:\t%s->%d\n",osa_log_verbosity,enb_properties_loc.properties[enb_properties_loc_index]->gosa_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->osa_log_verbosity = LOG_MED; - } - - } else { // not configuration is given - enb_properties_loc.properties[enb_properties_loc_index]->glog_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->glog_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->hw_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->hw_log_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->phy_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->phy_log_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->mac_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->mac_log_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->udp_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->udp_log_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->osa_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->osa_log_verbosity = LOG_MED; } */ break; diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index 1a9019b794..d2634b3947 100755 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -31,7 +31,7 @@ */ #include "common/config/config_paramdesc.h" - +#include "RRC_paramsvalues.h" @@ -56,52 +56,6 @@ -#define KHz (1000UL) -#define MHz (1000 * KHz) - -typedef struct eutra_band_s { - int16_t band; - uint32_t ul_min; - uint32_t ul_max; - uint32_t dl_min; - uint32_t dl_max; - lte_frame_type_t frame_type; -} eutra_band_t; - -static const eutra_band_t eutra_bands[] = { - { 1, 1920 * MHz, 1980 * MHz, 2110 * MHz, 2170 * MHz, FDD}, - { 2, 1850 * MHz, 1910 * MHz, 1930 * MHz, 1990 * MHz, FDD}, - { 3, 1710 * MHz, 1785 * MHz, 1805 * MHz, 1880 * MHz, FDD}, - { 4, 1710 * MHz, 1755 * MHz, 2110 * MHz, 2155 * MHz, FDD}, - { 5, 824 * MHz, 849 * MHz, 869 * MHz, 894 * MHz, FDD}, - { 6, 830 * MHz, 840 * MHz, 875 * MHz, 885 * MHz, FDD}, - { 7, 2500 * MHz, 2570 * MHz, 2620 * MHz, 2690 * MHz, FDD}, - { 8, 880 * MHz, 915 * MHz, 925 * MHz, 960 * MHz, FDD}, - { 9, 1749900 * KHz, 1784900 * KHz, 1844900 * KHz, 1879900 * KHz, FDD}, - {10, 1710 * MHz, 1770 * MHz, 2110 * MHz, 2170 * MHz, FDD}, - {11, 1427900 * KHz, 1452900 * KHz, 1475900 * KHz, 1500900 * KHz, FDD}, - {12, 698 * MHz, 716 * MHz, 728 * MHz, 746 * MHz, FDD}, - {13, 777 * MHz, 787 * MHz, 746 * MHz, 756 * MHz, FDD}, - {14, 788 * MHz, 798 * MHz, 758 * MHz, 768 * MHz, FDD}, - - {17, 704 * MHz, 716 * MHz, 734 * MHz, 746 * MHz, FDD}, - {20, 832 * MHz, 862 * MHz, 791 * MHz, 821 * MHz, FDD}, - {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, - {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, - {34, 2010 * MHz, 2025 * MHz, 2010 * MHz, 2025 * MHz, TDD}, - {35, 1850 * MHz, 1910 * MHz, 1850 * MHz, 1910 * MHz, TDD}, - {36, 1930 * MHz, 1990 * MHz, 1930 * MHz, 1990 * MHz, TDD}, - {37, 1910 * MHz, 1930 * MHz, 1910 * MHz, 1930 * MHz, TDD}, - {38, 2570 * MHz, 2620 * MHz, 2570 * MHz, 2630 * MHz, TDD}, - {39, 1880 * MHz, 1920 * MHz, 1880 * MHz, 1920 * MHz, TDD}, - {40, 2300 * MHz, 2400 * MHz, 2300 * MHz, 2400 * MHz, TDD}, - {41, 2496 * MHz, 2690 * MHz, 2496 * MHz, 2690 * MHz, TDD}, - {42, 3400 * MHz, 3600 * MHz, 3400 * MHz, 3600 * MHz, TDD}, - {43, 3600 * MHz, 3800 * MHz, 3600 * MHz, 3800 * MHz, TDD}, - {44, 703 * MHz, 803 * MHz, 703 * MHz, 803 * MHz, TDD}, -}; - - @@ -152,7 +106,7 @@ typedef enum { #define CONFIG_STRING_RU_MAX_RS_EPRE "max_pdschReferenceSignalPower" #define CONFIG_STRING_RU_MAX_RXGAIN "max_rxgain" #define CONFIG_STRING_RU_IF_COMPRESSION "if_compression" - +#define CONFIG_STRING_RU_NBIOTRRC_LIST "NbIoT_RRC_instances" #define RU_LOCAL_IF_NAME_IDX 0 #define RU_LOCAL_ADDRESS_IDX 1 @@ -171,7 +125,7 @@ typedef enum { #define RU_ENB_LIST_IDX 14 #define RU_ATT_TX_IDX 15 #define RU_ATT_RX_IDX 16 - +#define RU_NBIOTRRC_LIST_IDX 17 @@ -196,7 +150,8 @@ typedef enum { {CONFIG_STRING_RU_BAND_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFBANDS, TYPE_INTARRAY, 1}, \ {CONFIG_STRING_RU_ENB_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFENBS, TYPE_INTARRAY, 1}, \ {CONFIG_STRING_RU_ATT_TX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ -{CONFIG_STRING_RU_ATT_RX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0} \ +{CONFIG_STRING_RU_ATT_RX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{CONFIG_STRING_RU_NBIOTRRC_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFENBS, TYPE_INTARRAY, 1}, \ } /*---------------------------------------------------------------------------------------------------------------------------------------*/ @@ -233,8 +188,7 @@ typedef enum { /*------------------------------------------------------------------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------------------------------------------------------------------*/ -/* cell configuration section name */ -#define ENB_CONFIG_STRING_ENB_LIST "eNBs" + /* cell configuration parameters names */ #define ENB_CONFIG_STRING_ENB_ID "eNB_ID" @@ -289,21 +243,9 @@ typedef enum { /*-------------------------------------------------------------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* component carriers configuration section name */ -#define ENB_CONFIG_STRING_COMPONENT_CARRIERS "component_carriers" /* component carries configuration parameters name */ -#define ENB_CONFIG_STRING_FRAME_TYPE "frame_type" -#define ENB_CONFIG_STRING_PBCH_REPETITION "pbch_repetition" -#define ENB_CONFIG_STRING_TDD_CONFIG "tdd_config" -#define ENB_CONFIG_STRING_TDD_CONFIG_S "tdd_config_s" -#define ENB_CONFIG_STRING_PREFIX_TYPE "prefix_type" -#define ENB_CONFIG_STRING_EUTRA_BAND "eutra_band" -#define ENB_CONFIG_STRING_DOWNLINK_FREQUENCY "downlink_frequency" -#define ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET "uplink_frequency_offset" -#define ENB_CONFIG_STRING_NID_CELL "Nid_cell" -#define ENB_CONFIG_STRING_N_RB_DL "N_RB_DL" -#define ENB_CONFIG_STRING_CELL_MBSFN "Nid_cell_mbsfn" + #define ENB_CONFIG_STRING_NB_ANT_PORTS "nb_antenna_ports" #define ENB_CONFIG_STRING_NB_ANT_TX "nb_antennas_tx" #define ENB_CONFIG_STRING_NB_ANT_RX "nb_antennas_rx" @@ -367,11 +309,83 @@ typedef enum { #define ENB_CONFIG_STRING_UETIMERS_N310 "ue_TimersAndConstants_n310" #define ENB_CONFIG_STRING_UETIMERS_N311 "ue_TimersAndConstants_n311" #define ENB_CONFIG_STRING_UE_TRANSMISSION_MODE "ue_TransmissionMode" - -/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* component carriers configuration parameters */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +/* init for checkedparam_t structure */ + +#define CCPARAMS_CHECK { \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s1a= { config_check_modify_integer, UETIMER_T300_OKVALUES, UETIMER_T300_MODVALUES,8}} , \ + { .s1a= { config_check_modify_integer, UETIMER_T301_OKVALUES, UETIMER_T301_MODVALUES,8}} , \ + { .s1a= { config_check_modify_integer, UETIMER_T310_OKVALUES, UETIMER_T310_MODVALUES,7}} , \ + { .s1a= { config_check_modify_integer, UETIMER_T311_OKVALUES, UETIMER_T311_MODVALUES,7}} , \ + { .s1a= { config_check_modify_integer, UETIMER_N310_OKVALUES, UETIMER_N310_MODVALUES,8}} , \ + { .s1a= { config_check_modify_integer, UETIMER_N311_OKVALUES, UETIMER_N311_MODVALUES,8}} , \ + { .s5= {NULL }} , \ +} +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* component carriers configuration parameters */ +/* optname helpstr paramflags XXXptr defXXXval type numelt checked_param */ +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ #define CCPARAMS_DESC { \ {ENB_CONFIG_STRING_FRAME_TYPE, NULL, 0, strptr:&frame_type, defstrval:"FDD", TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_TDD_CONFIG, NULL, 0, iptr:&tdd_config, defintval:3, TYPE_UINT, 0}, \ @@ -443,6 +457,75 @@ typedef enum { {ENB_CONFIG_STRING_UE_TRANSMISSION_MODE, NULL, 0, iptr:&ue_TransmissionMode, defintval:1, TYPE_UINT, 0} \ } +#define ENB_CONFIG_FRAME_TYPE_IDX 0 +#define ENB_CONFIG_TDD_CONFIG_IDX 1 +#define ENB_CONFIG_TDD_CONFIG_S_IDX 2 +#define ENB_CONFIG_PREFIX_TYPE_IDX 3 +#define ENB_CONFIG_PBCH_REPETITION_IDX 4 +#define ENB_CONFIG_EUTRA_BAND_IDX 5 +#define ENB_CONFIG_DOWNLINK_FREQUENCY_IDX 6 +#define ENB_CONFIG_UPLINK_FREQUENCY_OFFSET_IDX 7 +#define ENB_CONFIG_NID_CELL_IDX 8 +#define ENB_CONFIG_N_RB_DL_IDX 9 +#define ENB_CONFIG_CELL_MBSFN_IDX 10 +#define ENB_CONFIG_NB_ANT_PORTS_IDX 11 +#define ENB_CONFIG_PRACH_ROOT_IDX 12 +#define ENB_CONFIG_PRACH_CONFIG_INDEX_IDX 13 +#define ENB_CONFIG_PRACH_HIGH_SPEED_IDX 14 +#define ENB_CONFIG_PRACH_ZERO_CORRELATION_IDX 15 +#define ENB_CONFIG_PRACH_FREQ_OFFSET_IDX 16 +#define ENB_CONFIG_PUCCH_DELTA_SHIFT_IDX 17 +#define ENB_CONFIG_PUCCH_NRB_CQI_IDX 18 +#define ENB_CONFIG_PUCCH_NCS_AN_IDX 19 +#define ENB_CONFIG_PUCCH_N1_AN_IDX 20 +#define ENB_CONFIG_PDSCH_RS_EPRE_IDX 21 +#define ENB_CONFIG_PDSCH_PB_IDX 22 +#define ENB_CONFIG_PUSCH_N_SB_IDX 23 +#define ENB_CONFIG_PUSCH_HOPPINGMODE_IDX 24 +#define ENB_CONFIG_PUSCH_HOPPINGOFFSET_IDX 25 +#define ENB_CONFIG_PUSCH_ENABLE64QAM_IDX 26 +#define ENB_CONFIG_PUSCH_GROUP_HOPPING_EN_IDX 27 +#define ENB_CONFIG_PUSCH_GROUP_ASSIGNMENT_IDX 28 +#define ENB_CONFIG_PUSCH_SEQUENCE_HOPPING_EN_IDX 29 +#define ENB_CONFIG_PUSCH_NDMRS1_IDX 30 +#define ENB_CONFIG_PHICH_DURATION_IDX 31 +#define ENB_CONFIG_PHICH_RESOURCE_IDX 32 +#define ENB_CONFIG_SRS_ENABLE_IDX 33 +#define ENB_CONFIG_SRS_BANDWIDTH_CONFIG_IDX 34 +#define ENB_CONFIG_SRS_SUBFRAME_CONFIG_IDX 35 +#define ENB_CONFIG_SRS_ACKNACKST_CONFIG_IDX 36 +#define ENB_CONFIG_SRS_MAXUPPTS_IDX 37 +#define ENB_CONFIG_PUSCH_PO_NOMINAL_IDX 38 +#define ENB_CONFIG_PUSCH_ALPHA_IDX 39 +#define ENB_CONFIG_PUCCH_PO_NOMINAL_IDX 40 +#define ENB_CONFIG_MSG3_DELTA_PREAMBLE_IDX 41 +#define ENB_CONFIG_PUCCH_DELTAF_FORMAT1_IDX 42 +#define ENB_CONFIG_PUCCH_DELTAF_FORMAT1b_IDX 43 +#define ENB_CONFIG_PUCCH_DELTAF_FORMAT2_IDX 44 +#define ENB_CONFIG_PUCCH_DELTAF_FORMAT2A_IDX 45 +#define ENB_CONFIG_PUCCH_DELTAF_FORMAT2B_IDX 46 +#define ENB_CONFIG_RACH_NUM_RA_PREAMBLES_IDX 47 +#define ENB_CONFIG_RACH_PREAMBLESGROUPACONFIG_IDX 48 +#define ENB_CONFIG_RACH_SIZEOFRA_PREAMBLESGROUPA_IDX 49 +#define ENB_CONFIG_RACH_MESSAGESIZEGROUPA_IDX 50 +#define ENB_CONFIG_RACH_MESSAGEPOWEROFFSETGROUPB_IDX 51 +#define ENB_CONFIG_RACH_POWERRAMPINGSTEP_IDX 52 +#define ENB_CONFIG_RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER_IDX 53 +#define ENB_CONFIG_RACH_PREAMBLETRANSMAX_IDX 54 +#define ENB_CONFIG_RACH_RARESPONSEWINDOWSIZE_IDX 55 +#define ENB_CONFIG_RACH_MACCONTENTIONRESOLUTIONTIMER_IDX 56 +#define ENB_CONFIG_RACH_MAXHARQMSG3TX_IDX 57 +#define ENB_CONFIG_PCCH_DEFAULT_PAGING_CYCLE_IDX 58 +#define ENB_CONFIG_PCCH_NB_IDX 59 +#define ENB_CONFIG_BCCH_MODIFICATIONPERIODCOEFF_IDX 60 +#define ENB_CONFIG_UETIMERS_T300_IDX 61 +#define ENB_CONFIG_UETIMERS_T301_IDX 62 +#define ENB_CONFIG_UETIMERS_T310_IDX 63 +#define ENB_CONFIG_UETIMERS_T311_IDX 64 +#define ENB_CONFIG_UETIMERS_N310_IDX 65 +#define ENB_CONFIG_UETIMERS_N311_IDX 66 +#define ENB_CONFIG_UE_TRANSMISSION_MODE_IDX 67 + /*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* SRB1 configuration parameters section name */ @@ -569,43 +652,8 @@ typedef enum { -/* L1 configuration parameters names */ -#define CONFIG_STRING_L1_CC "num_cc" -#define CONFIG_STRING_L1_LOCAL_N_IF_NAME "local_n_if_name" -#define CONFIG_STRING_L1_LOCAL_N_ADDRESS "local_n_address" -#define CONFIG_STRING_L1_REMOTE_N_ADDRESS "remote_n_address" -#define CONFIG_STRING_L1_LOCAL_N_PORTC "local_n_portc" -#define CONFIG_STRING_L1_REMOTE_N_PORTC "remote_n_portc" -#define CONFIG_STRING_L1_LOCAL_N_PORTD "local_n_portd" -#define CONFIG_STRING_L1_REMOTE_N_PORTD "remote_n_portd" -#define CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE "tr_n_preference" +/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* L1 configuration parameters */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ -#define L1PARAMS_DESC { \ -{CONFIG_STRING_L1_CC, NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \ -{CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"local_mac", TYPE_STRING, 0}, \ -{CONFIG_STRING_L1_LOCAL_N_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ -{CONFIG_STRING_L1_LOCAL_N_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ -{CONFIG_STRING_L1_REMOTE_N_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.2", TYPE_STRING, 0}, \ -{CONFIG_STRING_L1_LOCAL_N_PORTC, NULL, 0, uptr:NULL, defintval:50030, TYPE_UINT, 0}, \ -{CONFIG_STRING_L1_REMOTE_N_PORTC, NULL, 0, uptr:NULL, defintval:50030, TYPE_UINT, 0}, \ -{CONFIG_STRING_L1_LOCAL_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \ -{CONFIG_STRING_L1_REMOTE_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \ -} -#define L1_CC_IDX 0 -#define L1_TRANSPORT_N_PREFERENCE_IDX 1 -#define L1_LOCAL_N_IF_NAME_IDX 2 -#define L1_LOCAL_N_ADDRESS_IDX 3 -#define L1_REMOTE_N_ADDRESS_IDX 4 -#define L1_LOCAL_N_PORTC_IDX 5 -#define L1_REMOTE_N_PORTC_IDX 6 -#define L1_LOCAL_N_PORTD_IDX 7 -#define L1_REMOTE_N_PORTD_IDX 8 - -/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ #define CONFIG_STRING_NETWORK_CONTROLLER_CONFIG "NETWORK_CONTROLLER" @@ -639,64 +687,4 @@ typedef enum { #define CONFIG_STRING_MACRLC_CONFIG "macrlc_config" -/* MACRLC configuration parameters names */ -#define CONFIG_STRING_MACRLC_CC "num_cc" -#define CONFIG_STRING_MACRLC_TRANSPORT_N_PREFERENCE "tr_n_preference" -#define CONFIG_STRING_MACRLC_LOCAL_N_IF_NAME "local_n_if_name" -#define CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS "local_n_address" -#define CONFIG_STRING_MACRLC_REMOTE_N_ADDRESS "remote_n_address" -#define CONFIG_STRING_MACRLC_LOCAL_N_PORTC "local_n_portc" -#define CONFIG_STRING_MACRLC_REMOTE_N_PORTC "remote_n_portc" -#define CONFIG_STRING_MACRLC_LOCAL_N_PORTD "local_n_portd" -#define CONFIG_STRING_MACRLC_REMOTE_N_PORTD "remote_n_portd" -#define CONFIG_STRING_MACRLC_TRANSPORT_S_PREFERENCE "tr_s_preference" -#define CONFIG_STRING_MACRLC_LOCAL_S_IF_NAME "local_s_if_name" -#define CONFIG_STRING_MACRLC_LOCAL_S_ADDRESS "local_s_address" -#define CONFIG_STRING_MACRLC_REMOTE_S_ADDRESS "remote_s_address" -#define CONFIG_STRING_MACRLC_LOCAL_S_PORTC "local_s_portc" -#define CONFIG_STRING_MACRLC_REMOTE_S_PORTC "remote_s_portc" -#define CONFIG_STRING_MACRLC_LOCAL_S_PORTD "local_s_portd" -#define CONFIG_STRING_MACRLC_REMOTE_S_PORTD "remote_s_portd" - -/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* MacRLC configuration parameters */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/ -#define MACRLCPARAMS_DESC { \ -{CONFIG_STRING_MACRLC_CC, NULL, 0, uptr:NULL, defintval:50011, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_TRANSPORT_N_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"local_L1", TYPE_STRING, 0}, \ -{CONFIG_STRING_MACRLC_LOCAL_N_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ -{CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ -{CONFIG_STRING_MACRLC_REMOTE_N_ADDRESS, NULL, 0, uptr:NULL, defstrval:"127.0.0.2", TYPE_STRING, 0}, \ -{CONFIG_STRING_MACRLC_LOCAL_N_PORTC, NULL, 0, uptr:NULL, defintval:50010, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_REMOTE_N_PORTC, NULL, 0, uptr:NULL, defintval:50010, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_LOCAL_N_PORTD, NULL, 0, uptr:NULL, defintval:50011, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_REMOTE_N_PORTD, NULL, 0, uptr:NULL, defintval:50011, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_TRANSPORT_S_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"local_RRC", TYPE_STRING, 0}, \ -{CONFIG_STRING_MACRLC_LOCAL_S_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ -{CONFIG_STRING_MACRLC_LOCAL_S_ADDRESS, NULL, 0, uptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ -{CONFIG_STRING_MACRLC_REMOTE_S_ADDRESS, NULL, 0, uptr:NULL, defstrval:"127.0.0.2", TYPE_STRING, 0}, \ -{CONFIG_STRING_MACRLC_LOCAL_S_PORTC, NULL, 0, uptr:NULL, defintval:50020, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_REMOTE_S_PORTC, NULL, 0, uptr:NULL, defintval:50020, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_LOCAL_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_REMOTE_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \ -} -#define MACRLC_CC_IDX 0 -#define MACRLC_TRANSPORT_N_PREFERENCE_IDX 1 -#define MACRLC_LOCAL_N_IF_NAME_IDX 2 -#define MACRLC_LOCAL_N_ADDRESS_IDX 3 -#define MACRLC_REMOTE_N_ADDRESS_IDX 4 -#define MACRLC_LOCAL_N_PORTC_IDX 5 -#define MACRLC_REMOTE_N_PORTC_IDX 6 -#define MACRLC_LOCAL_N_PORTD_IDX 7 -#define MACRLC_REMOTE_N_PORTD_IDX 8 -#define MACRLC_TRANSPORT_S_PREFERENCE_IDX 9 -#define MACRLC_LOCAL_S_IF_NAME_IDX 10 -#define MACRLC_LOCAL_S_ADDRESS_IDX 11 -#define MACRLC_REMOTE_S_ADDRESS_IDX 12 -#define MACRLC_LOCAL_S_PORTC_IDX 13 -#define MACRLC_REMOTE_S_PORTC_IDX 14 -#define MACRLC_LOCAL_S_PORTD_IDX 15 -#define MACRLC_REMOTE_S_PORTD_IDX 16 -/*---------------------------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/ENB_APP/nbiot_config.c b/openair2/ENB_APP/nbiot_config.c new file mode 100644 index 0000000000..3862a01403 --- /dev/null +++ b/openair2/ENB_APP/nbiot_config.c @@ -0,0 +1,295 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* + nbiot_config.c + ------------------- + AUTHOR : Francois Taburet + COMPANY : NOKIA + EMAIL : francois.taburet@nokia-bell-labs.com +*/ + +#include +#include + +#include "log.h" +#include "log_extern.h" +#include "assertions.h" +#include "enb_config.h" +#include "UTIL/OTG/otg.h" +#include "UTIL/OTG/otg_externs.h" +#if defined(OAI_EMU) +# include "OCG.h" +# include "OCG_extern.h" +#endif +#if defined(ENABLE_ITTI) +# include "intertask_interface.h" +# if defined(ENABLE_USE_MME) +# include "s1ap_eNB.h" +# include "sctp_eNB_task.h" +# endif +#endif +#include "sctp_default_values.h" +#include "SystemInformationBlockType2.h" +#include "LAYER2/MAC/extern.h" +#include "PHY/extern.h" +#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" + +#include "common/config/config_userapi.h" +#include "RRC_config_tools.h" +#include "RRC_paramsvalues.h" +#include "nbiot_paramdef.h" +#include "L1_paramdef.h" +#include "MACRLC_paramdef.h" +#include "LAYER2/MAC/proto_NB_IoT.h" + + +void RCconfig_NbIoTL1(void) { + paramdef_t NbIoT_L1_Params[] = L1PARAMS_DESC; + paramlist_def_t NbIoT_L1_ParamList = {NBIOT_L1LIST_CONFIG_STRING,NULL,0}; + +/* No component carrier for NbIoT, ignore number of CC */ +// NbIoT_L1_Params[L1_CC_IDX ].paramflags = PARAMFLAG_DONOTREAD; + + config_getlist( &NbIoT_L1_ParamList,NbIoT_L1_Params,sizeof(NbIoT_L1_Params)/sizeof(paramdef_t), NULL); + if (NbIoT_L1_ParamList.numelt > 0) { + if (RC.L1_NB_IoT == NULL) { + RC.L1_NB_IoT = (PHY_VARS_eNB_NB_IoT **)malloc(RC.nb_nb_iot_L1_inst*sizeof(PHY_VARS_eNB_NB_IoT *)); + LOG_I(PHY,"RC.L1_NB_IoT = %p\n",RC.L1_NB_IoT); + memset(RC.L1_NB_IoT,0,RC.nb_nb_iot_L1_inst*sizeof(PHY_VARS_eNB_NB_IoT *)); + } + + + for(int j = 0; j eth_params_n.local_if_name = strdup(*(NbIoT_L1_ParamList.paramarray[j][L1_LOCAL_N_IF_NAME_IDX].strptr)); + RC.L1_NB_IoT[j]->eth_params_n.my_addr = strdup(*(NbIoT_L1_ParamList.paramarray[j][L1_LOCAL_N_ADDRESS_IDX].strptr)); + RC.L1_NB_IoT[j]->eth_params_n.remote_addr = strdup(*(NbIoT_L1_ParamList.paramarray[j][L1_REMOTE_N_ADDRESS_IDX].strptr)); + RC.L1_NB_IoT[j]->eth_params_n.my_portc = *(NbIoT_L1_ParamList.paramarray[j][L1_LOCAL_N_PORTC_IDX].iptr); + RC.L1_NB_IoT[j]->eth_params_n.remote_portc = *(NbIoT_L1_ParamList.paramarray[j][L1_REMOTE_N_PORTC_IDX].iptr); + RC.L1_NB_IoT[j]->eth_params_n.my_portd = *(NbIoT_L1_ParamList.paramarray[j][L1_LOCAL_N_PORTD_IDX].iptr); + RC.L1_NB_IoT[j]->eth_params_n.remote_portd = *(NbIoT_L1_ParamList.paramarray[j][L1_REMOTE_N_PORTD_IDX].iptr); + RC.L1_NB_IoT[j]->eth_params_n.transp_preference = ETH_UDP_MODE; + } + + else { // other midhaul + } + }// j=0..num_inst + printf("Initializing northbound interface for NB-IoT L1\n"); + l1_north_init_NB_IoT(); + } else { + LOG_I(PHY,"No " NBIOT_L1LIST_CONFIG_STRING " configuration found"); + } +} + +void RCconfig_NbIoTmacrlc(void) { + + + + paramdef_t NbIoT_MacRLC_Params[] = MACRLCPARAMS_DESC; + paramlist_def_t NbIoT_MacRLC_ParamList = {NBIOT_MACRLCLIST_CONFIG_STRING,NULL,0}; + + +/* No component carrier for NbIoT, ignore number of CC */ +// NbIoT_MacRLC_Params[MACRLC_CC_IDX ].paramflags = PARAMFLAG_DONOTREAD; + + config_getlist( &NbIoT_MacRLC_ParamList,NbIoT_MacRLC_Params,sizeof(NbIoT_MacRLC_Params)/sizeof(paramdef_t), NULL); + + + if ( NbIoT_MacRLC_ParamList.numelt > 0) { + mac_top_init_eNB_NB_IoT(); + for (int j=0;jeth_params_n.local_if_name = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_IF_NAME_IDX].strptr)); + RC.nb_iot_mac[j]->eth_params_n.my_addr = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_ADDRESS_IDX].strptr)); + RC.nb_iot_mac[j]->eth_params_n.remote_addr = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_ADDRESS_IDX].strptr)); + RC.nb_iot_mac[j]->eth_params_n.my_portc = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTC_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_n.remote_portc = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTC_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_n.my_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTD_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_n.remote_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTD_IDX].iptr);; + RC.nb_iot_mac[j]->eth_params_n.transp_preference = ETH_UDP_MODE; + } else { // other midhaul + AssertFatal(1==0,"MACRLC %d: %s unknown northbound midhaul\n",j, *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr)); + } + + if (strcmp(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr), "local_L1") == 0) { + + + } else if (strcmp(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr), "nfapi") == 0) { + RC.nb_iot_mac[j]->eth_params_s.local_if_name = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_IF_NAME_IDX].strptr)); + RC.nb_iot_mac[j]->eth_params_s.my_addr = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_ADDRESS_IDX].strptr)); + RC.nb_iot_mac[j]->eth_params_s.remote_addr = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_ADDRESS_IDX].strptr)); + RC.nb_iot_mac[j]->eth_params_s.my_portc = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_PORTC_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_s.remote_portc = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTC_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_s.my_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_PORTD_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_s.remote_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTD_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_s.transp_preference = ETH_UDP_MODE; + } else { // other midhaul + AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr)); + } + }// j=0..num_inst */ + } else {// MacRLC_ParamList.numelt > 0 + AssertFatal (0, + "No " NBIOT_MACRLCLIST_CONFIG_STRING " configuration found"); + } +} + + + + +int RCconfig_NbIoTRRC(MessageDef *msg_p, int nbiotrrc_id,eNB_RRC_INST_NB_IoT *nbiotrrc) { + + + char instprefix[MAX_OPTNAME_SIZE*3 + 32]; + + + checkedparam_t NBIoTCheckParams[] = NBIOT_RRCPARAMS_CHECK_DESC; + paramdef_t NBIoTParams[] = NBIOTRRCPARAMS_DESC; + + paramdef_t NBIoTPrachParams[] = NBIOTRRC_NPRACH_PARAMS_DESC; + checkedparam_t NBIoTPrachCheckParams[] = NBIOT_RRCLIST_NPRACHPARAMSCHECK_DESC; + + paramdef_t NBIoTRRCRefParams[] = NBIOTRRCPARAMS_RRCREF_DESC; + + paramdef_t NBIoTLteCCParams[] = NBIOT_LTECCPARAMS_DESC; + checkedparam_t NBIoTLteCCCheckParams[] = NBIOT_LTECCPARAMS_CHECK_DESC; +/* map parameter checking array instances to parameter definition array instances */ + for (int i=0; (inb_nb_iot_rrc_inst = NbIoT_ParamList.numelt; + + + + + config_getlist( &NbIoT_MACRLCParamList,NULL,0, NULL); + RC->nb_nb_iot_macrlc_inst = NbIoT_MACRLCParamList.numelt; + // Get num L1 instances + config_getlist( &NbIoT_L1ParamList,NULL,0, NULL); + RC->nb_nb_iot_L1_inst = NbIoT_L1ParamList.numelt; + +} diff --git a/openair2/ENB_APP/nbiot_config.h b/openair2/ENB_APP/nbiot_config.h new file mode 100644 index 0000000000..314fca8180 --- /dev/null +++ b/openair2/ENB_APP/nbiot_config.h @@ -0,0 +1,37 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* + nbiot_config.h + ------------------- + AUTHOR : Francois Taburet + COMPANY : NOKIA + EMAIL : francois.taburet@nokia-bell-labs.com +*/ +#ifndef INCLUDE_NBIOT_CONFIG_H +#define INCLUDE_NBIOT_CONFIG_H + + +extern void RCconfig_NbIoTL1(void) ; +extern void RCconfig_NbIoTmacrlc(void); +extern int RCconfig_NbIoTRRC(MessageDef *msg_p, int nbiotrrc_id,eNB_RRC_INST_NB_IoT *nbiotrrc); +extern void RCConfig_NbIoT(RAN_CONTEXT_t *RC); +#endif diff --git a/openair2/ENB_APP/nbiot_paramdef.h b/openair2/ENB_APP/nbiot_paramdef.h new file mode 100644 index 0000000000..615c96a7b6 --- /dev/null +++ b/openair2/ENB_APP/nbiot_paramdef.h @@ -0,0 +1,400 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file openair2/ENB_APP/enb_paramdef.f + * \brief definition of configuration parameters for all eNodeB modules + * \author Francois TABURET + * \date 2017 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ + +#include "common/config/config_paramdesc.h" +#include "SystemInformationBlockType2.h" +#include "DL-GapConfig-NB-r13.h" +#include "NPRACH-Parameters-NB-r13.h" +#include "PowerRampingParameters.h" +#include "BCCH-Config-NB-r13.h" +#include "PCCH-Config-NB-r13.h" +#include "ACK-NACK-NumRepetitions-NB-r13.h" +#include "TDD-Config.h" + + + + + +/* + int16_t eutra_band; + uint32_t downlink_frequency; + int32_t uplink_frequency_offset; + int16_t Nid_cell;// for testing, change later + int16_t N_RB_DL;// for testing, change later +*/ +/*-------------------------------------------------------------------------------------------------------------------*/ +/* SIB1 parameters possibly coming from LTE RRC (in band deployment) */ +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* component carriers configuration parameters */ +/* optname helpstr paramflags XXXptr defXXXval type numelt checked_param */ +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define NBIOT_LTECCPARAMS_CHECK_DESC { \ + { .s3a= { config_checkstr_assign_integer, FRAMETYPE_OKVALUES, FRAMETYPE_MODVALUES,2}} , \ + { .s2= { config_check_intrange, TDDCONFIG_OKRANGE}}, \ + { .s2= { config_check_intrange, TDDCONFIGS_OKRANGE}}, \ + { .s3a= { config_checkstr_assign_integer, PREFIX_OKVALUES, PREFIX_MODVALUES,2}} , \ + { .s3a= { config_checkstr_assign_integer, PREFIXUL_OKVALUES, PREFIXUL_MODVALUES,2}} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s1= { config_check_intval, NRBDL_OKVALUES,6}} , \ +} + + +#define NBIOT_LTECCPARAMS_DESC { \ +{ENB_CONFIG_STRING_FRAME_TYPE, NULL, 0, strptr:NULL, defstrval:"FDD", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_TDD_CONFIG, NULL, 0, iptr:NULL, defintval:3, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_TDD_CONFIG_S, NULL, 0, iptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_PREFIX_TYPE, NULL, 0, strptr:NULL, defstrval:"NORMAL", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_PREFIX_TYPE_UL, NULL, 0, strptr:NULL, defstrval:"NORMAL", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_EUTRA_BAND, NULL, 0, iptr:NULL, defintval:7, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_DOWNLINK_FREQUENCY, NULL, 0, i64ptr:NULL, defint64val:2680000000, TYPE_UINT64, 0}, \ +{ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET, NULL, 0, iptr:NULL, defintval:-120000000, TYPE_INT, 0}, \ +{ENB_CONFIG_STRING_NID_CELL, NULL, 0, iptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_N_RB_DL, NULL, 0, iptr:NULL, defintval:25, TYPE_UINT, 0}, \ +} +#define LTECCPARAMS_FRAME_TYPE_IDX 0 +#define LTECCPARAMS_TDD_CONFIG_IDX 1 +#define LTECCPARAMS_TDD_CONFIG_S_IDX 2 +#define LTECCPARAMS_PREFIX_TYPE_IDX 3 +#define LTECCPARAMS_PREFIX_TYPE_UL_IDX 4 +#define LTECCPARAMS_EUTRA_BAND_IDX 5 +#define LTECCPARAMS_DOWNLINK_FREQUENCY_IDX 6 +#define LTECCPARAMS_UPLINK_FREQUENCY_OFFSET_IDX 7 +#define LTECCPARAMS_NID_CELL_IDX 8 +#define LTECCPARAMS_N_RB_DL_IDX 9 + + +/*-------------------------------------------------------------------------------------------------------------------*/ + +/* NB-Iot RRC list section name */ +#define NBIOT_RRCLIST_CONFIG_STRING "NB-IoT_RRCs" + + +#define RACH_RARESPONSEWINDOWSIZE_NB_OKVALUES {20,50,80,120,180,240,320,400} +#define PREF1(A) RACH_CE_LevelInfo_r13__ra_ResponseWindowSize_r13_ ## A +#define RACH_RARESPONSEWINDOWSIZE_NB_MODVALUES { PREF1(sf20),PREF1(sf50),PREF1(sf80),PREF1(sf120), \ + PREF1(sf180),PREF1(sf240),PREF1(sf320),PREF1(sf400) } + + +#define RACH_MACCONTENTIONRESOLUTIONTIMER_NB_OKVALUES {80,100,120,160,200,240,480,960} +#define PREF2(A) RACH_CE_LevelInfo_r13__mac_ContentionResolutionTimer_r13_ ## A +#define RACH_MACCONTENTIONRESOLUTIONTIMER_NB_MODVALUES { PREF2(sf80),PREF2(sf100),PREF2(sf120),PREF2(sf160), \ + PREF2(sf200),PREF2(sf240),PREF2(sf480),PREF2(sf960) } + + +#define RACH_POWERRAMPINGSTEP_NB_OKVALUES {0,2,4,6} +#define PREF3(A) PowerRampingParameters__powerRampingStep_ ## A +#define RACH_POWERRAMPINGSTEP_NB_MODVALUES { PREF3(dB0),PREF3(dB2),PREF3(dB4),PREF3(dB6) } + + +#define RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER_NB_OKRANGE {-120, -90} + +#define RACH_PREAMBLETRANSMAX_CE_NB_OKVALUES {3,4,5,6,7,8,10,20,50,100,200} +#define PREF4(A) PreambleTransMax_ ## A +#define RACH_PREAMBLETRANSMAX_CE_NB_MODVALUES { PREF4(n3), PREF4(n4), PREF4(n5), PREF4(n6), PREF4(n7), PREF4(n8), \ + PREF4(n10),PREF4(n20),PREF4(n50),PREF4(n100),PREF4(n200) } + +#define BCCH_MODIFICATIONPERIODCOEFF_NB_OKVALUES {16,32,64,128} +#define PREF5(A) BCCH_Config_NB_r13__modificationPeriodCoeff_r13_ ## A +#define BCCH_MODIFICATIONPERIODCOEFF_NB_MODVALUES { PREF5(n16), PREF5(n32), PREF5(n64),PREF5(n128) } + +#define PCCH_DEFAULTPAGINGCYCLE_NB_OKVALUES {128,256,512,1024} +#define PREF6(A) PCCH_Config_NB_r13__defaultPagingCycle_r13_ ## A +#define PCCH_DEFAULTPAGINGCYCLE_NB_MODVALUES { PREF6(rf128), PREF6(rf256), PREF6(rf512), PREF6(rf1024) } + +#define NPRACH_CP_LENGTH_OKVALUES {0,1} +#define NPRACH_RSRP_RANGE_OKVALUES {0,96} + +#define MSG3RANGESTART_OKVALUES {"zero","oneThird","twoThird","one"} +#define MSG3RANGESTART_MODVALUES {NPRACH_Parameters_NB_r13__nprach_SubcarrierMSG3_RangeStart_r13_zero, NPRACH_Parameters_NB_r13__nprach_SubcarrierMSG3_RangeStart_r13_oneThird, \ + NPRACH_Parameters_NB_r13__nprach_SubcarrierMSG3_RangeStart_r13_twoThird, NPRACH_Parameters_NB_r13__nprach_SubcarrierMSG3_RangeStart_r13_one} + + +#define MAXNUMPREAMBLEATTEMPTCE_OKVALUES {3,4,5,6,7,8,10} +#define MAXNUMPREAMBLEATTEMPTCE_MODVALUES { NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n3, NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n4, \ + NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n5, NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n6, \ + NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n7, NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n8, \ + NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n10 } + +#define NPDSCH_NRS_POWER_OKRANGE {-60,50} + +#define NPUSCH_ACK_NACK_NUMREPETITIONS_NB_OKVALUES {1,2,4,8,16,32,64,128} +#define PREF9(A) ACK_NACK_NumRepetitions_NB_r13_ ## A +#define NPUSCH_ACK_NACK_NUMREPETITIONS_NB_MODVALUES { PREF9(r1), PREF9(r2), PREF9(r4), PREF9(r8), \ + PREF9(r16), PREF9(r32), PREF9(r64), PREF9(r128) } + +#define NPUSCH_SRS_SUBFRAMECONFIG_NB_OKRANGE {0,15} +#define NPUSCH_THREETONE_CYCLICSHIFT_R13_OKRANGE {0,2} +#define NPUSCH_SIXTONE_CYCLICSHIFT_R13_OKRANGE {0,3} + +#define NPUSCH_GROUPHOPPINGENABLED_OKVALUES {"enable","disable"} +#define NPUSCH_GROUPHOPPINGENABLED_MODVALUES {1,0} + +#define NPUSCH_GROUPASSIGNMENTNPUSCH_R13_OKRANGE {0,29} + +#define DLGAPTHRESHOLD_OKVALUES {32,64,128,256} +#define DLGAPTHRESHOLD_MODVALUES { DL_GapConfig_NB_r13__dl_GapThreshold_r13_n32, DL_GapConfig_NB_r13__dl_GapThreshold_r13_n64, \ + DL_GapConfig_NB_r13__dl_GapThreshold_r13_n128, DL_GapConfig_NB_r13__dl_GapThreshold_r13_n256} \ + +#define DLGAPPERIODICITY_OKVALUES {64,128,256,512} +#define DLGAPPERIODICITY_MODVALUES { DL_GapConfig_NB_r13__dl_GapPeriodicity_r13_sf64, DL_GapConfig_NB_r13__dl_GapPeriodicity_r13_sf128, \ + DL_GapConfig_NB_r13__dl_GapPeriodicity_r13_sf256,DL_GapConfig_NB_r13__dl_GapPeriodicity_r13_sf512} + +#define DLGAPDURATION_OKVALUES {"oneEighth","oneFourth","threeEighth","oneHalf"} +#define DLGAPDURATION_MODVALUES {DL_GapConfig_NB_r13__dl_GapDurationCoeff_r13_oneEighth, DL_GapConfig_NB_r13__dl_GapDurationCoeff_r13_oneFourth, \ + DL_GapConfig_NB_r13__dl_GapDurationCoeff_r13_threeEighth, DL_GapConfig_NB_r13__dl_GapDurationCoeff_r13_oneHalf} + +#define NPUSCH_P0_NOMINALNPUSCH_OKRANGE {-126,24} + +#define NPUSCH_ALPHA_OKVALUES {"AL0","AL04","AL05","AL06","AL07","AL08","AL09","AL1"} +#define NPUSCH_ALPHA_MODVALUES { Alpha_r12_al0, Alpha_r12_al04, Alpha_r12_al05, Alpha_r12_al06, \ + Alpha_r12_al07, Alpha_r12_al08, Alpha_r12_al09, Alpha_r12_al1} + +#define DELTAPREAMBLEMSG3_OKRANGE {-1,6} + + + + + +#define NBIOT_RRCPARAMS_CHECK_DESC { \ + { .s1a= { config_check_modify_integer, RACH_RARESPONSEWINDOWSIZE_NB_OKVALUES, RACH_RARESPONSEWINDOWSIZE_NB_MODVALUES, 8}}, \ + { .s1a= { config_check_modify_integer, RACH_MACCONTENTIONRESOLUTIONTIMER_NB_OKVALUES, RACH_MACCONTENTIONRESOLUTIONTIMER_NB_MODVALUES, 8}}, \ + { .s1a= { config_check_modify_integer, RACH_POWERRAMPINGSTEP_NB_OKVALUES, RACH_POWERRAMPINGSTEP_NB_MODVALUES, 4}} , \ + { .s2= { config_check_intrange, RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER_NB_OKRANGE}}, \ + { .s1a= { config_check_modify_integer, RACH_PREAMBLETRANSMAX_CE_NB_OKVALUES, RACH_PREAMBLETRANSMAX_CE_NB_MODVALUES, 11}} , \ + { .s1a= { config_check_modify_integer, BCCH_MODIFICATIONPERIODCOEFF_NB_OKVALUES, BCCH_MODIFICATIONPERIODCOEFF_NB_MODVALUES, 4}} , \ + { .s1a= { config_check_modify_integer, PCCH_DEFAULTPAGINGCYCLE_NB_OKVALUES, PCCH_DEFAULTPAGINGCYCLE_NB_MODVALUES, 4}} , \ + { .s1= { NULL, NPRACH_CP_LENGTH_OKVALUES ,4}} , \ + { .s2= { config_check_intrange, NPRACH_RSRP_RANGE_OKVALUES}} , \ + { .s3a= { config_checkstr_assign_integer, MSG3RANGESTART_OKVALUES, MSG3RANGESTART_MODVALUES, 4}} , \ + { .s1a= { config_check_modify_integer, MAXNUMPREAMBLEATTEMPTCE_OKVALUES, MAXNUMPREAMBLEATTEMPTCE_MODVALUES, 7}} , \ + { .s1= { config_check_intval, NPDSCH_NRS_POWER_OKRANGE,4}} , \ + { .s1a= { config_check_modify_integer, NPUSCH_ACK_NACK_NUMREPETITIONS_NB_OKVALUES, NPUSCH_ACK_NACK_NUMREPETITIONS_NB_MODVALUES, 8}} , \ + { .s2= { config_check_intrange, NPUSCH_SRS_SUBFRAMECONFIG_NB_OKRANGE}} , \ + { .s2= { config_check_intrange, NPUSCH_THREETONE_CYCLICSHIFT_R13_OKRANGE}} , \ + { .s2= { config_check_intrange, NPUSCH_SIXTONE_CYCLICSHIFT_R13_OKRANGE}} , \ + { .s3a= { config_checkstr_assign_integer, NPUSCH_GROUPHOPPINGENABLED_OKVALUES, NPUSCH_GROUPHOPPINGENABLED_MODVALUES, 2}} , \ + { .s2= { config_check_intrange, NPUSCH_GROUPASSIGNMENTNPUSCH_R13_OKRANGE}} , \ + { .s1a= { config_check_modify_integer, DLGAPTHRESHOLD_OKVALUES, DLGAPTHRESHOLD_MODVALUES, 4}} , \ + { .s1a= { config_check_modify_integer, DLGAPPERIODICITY_OKVALUES, DLGAPPERIODICITY_MODVALUES, 4}} , \ + { .s3a= { config_checkstr_assign_integer, DLGAPDURATION_OKVALUES, DLGAPDURATION_MODVALUES , 4}} , \ + { .s2= { config_check_intrange, NPUSCH_P0_NOMINALNPUSCH_OKRANGE}} , \ + { .s3a= { config_checkstr_assign_integer, NPUSCH_ALPHA_OKVALUES, NPUSCH_ALPHA_MODVALUES, 8}} , \ + { .s2= { config_check_intrange, DELTAPREAMBLEMSG3_OKRANGE}} , \ + { .s1a= { config_check_modify_integer, UETIMER_T300_OKVALUES, UETIMER_T300_MODVALUES,8}} , \ + { .s1a= { config_check_modify_integer, UETIMER_T301_OKVALUES, UETIMER_T301_MODVALUES,8}} , \ + { .s1a= { config_check_modify_integer, UETIMER_T310_OKVALUES, UETIMER_T310_MODVALUES,7}} , \ + { .s1a= { config_check_modify_integer, UETIMER_T311_OKVALUES, UETIMER_T311_MODVALUES,7}} , \ + { .s1a= { config_check_modify_integer, UETIMER_N310_OKVALUES, UETIMER_N310_MODVALUES,8}} , \ + { .s1a= { config_check_modify_integer, UETIMER_N311_OKVALUES, UETIMER_N311_MODVALUES,8}} , \ +} +/*-----------------------------------------------------------------------------------------------------------------------------------------*/ +/* NB-IoT RRC configuration parameters */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*-----------------------------------------------------------------------------------------------------------------------------------------*/ +#define NBIOTRRCPARAMS_DESC { \ +{"rach_raResponseWindowSize_NB", NULL, 0, uptr:NULL, defintval:20, TYPE_UINT, 0}, \ +{"rach_macContentionResolutionTimer_NB", NULL, 0, uptr:NULL, defintval:80, TYPE_UINT, 0}, \ +{"rach_powerRampingStep_NB", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"rach_preambleInitialReceivedTargetPower_NB", NULL, 0, iptr:NULL, defintval:-112, TYPE_INT32, 0}, \ +{"rach_preambleTransMax_CE_NB", NULL, 0, uptr:NULL, defintval:3, TYPE_UINT, 0}, \ +{"bcch_modificationPeriodCoeff_NB", NULL, 0, uptr:NULL, defintval:16, TYPE_UINT, 0}, \ +{"pcch_defaultPagingCycle_NB", NULL, 0, uptr:NULL, defintval:256, TYPE_UINT, 0}, \ +{"nprach_CP_Length", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"nprach_rsrp_range", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"nprach_SubcarrierMSG3_RangeStart", NULL, 0, strptr:NULL, defstrval:"one", TYPE_STRING, 0}, \ +{"maxNumPreambleAttemptCE_NB", NULL, 0, uptr:NULL, defintval:10, TYPE_UINT, 0}, \ +{"npdsch_nrs_Power", NULL, 0, iptr:NULL, defintval:0, TYPE_INT, 0}, \ +{"npusch_ack_nack_numRepetitions_NB", NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \ +{"npusch_srs_SubframeConfig_NB", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"npusch_threeTone_CyclicShift_r13", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"npusch_sixTone_CyclicShift_r13", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"npusch_groupHoppingEnabled", NULL, 0, strptr:NULL, defstrval:"disable", TYPE_STRING, 0}, \ +{"npusch_groupAssignmentNPUSCH_r13", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"dl_GapThreshold_NB", NULL, 0, uptr:NULL, defintval:32, TYPE_UINT, 0}, \ +{"dl_GapPeriodicity_NB", NULL, 0, uptr:NULL, defintval:64, TYPE_UINT, 0}, \ +{"dl_GapDurationCoeff_NB", NULL, 0, strptr:NULL, defstrval:"oneEighth", TYPE_STRING, 0}, \ +{"npusch_p0_NominalNPUSCH", NULL, 0, iptr:NULL, defintval:0, TYPE_INT32, 0}, \ +{"npusch_alpha", NULL, 0, strptr:NULL, defstrval:"AL0", TYPE_STRING, 0}, \ +{"deltaPreambleMsg3", NULL, 0, iptr:NULL, defintval:0, TYPE_INT32, 0}, \ +{"ue_TimersAndConstants_t300_NB", NULL, 0, uptr:NULL, defintval:1000, TYPE_UINT, 0}, \ +{"ue_TimersAndConstants_t301_NB", NULL, 0, uptr:NULL, defintval:1000, TYPE_UINT, 0}, \ +{"ue_TimersAndConstants_t310_NB", NULL, 0, uptr:NULL, defintval:1000, TYPE_UINT, 0}, \ +{"ue_TimersAndConstants_t311_NB", NULL, 0, uptr:NULL, defintval:10000, TYPE_UINT, 0}, \ +{"ue_TimersAndConstants_n310_NB", NULL, 0, uptr:NULL, defintval:20, TYPE_UINT, 0}, \ +{"ue_TimersAndConstants_n311_NB", NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \ +} + +#define NBIOT_RACH_RARESPONSEWINDOWSIZE_NB_IDX 0 +#define NBIOT_RACH_MACCONTENTIONRESOLUTIONTIMER_NB_IDX 1 +#define NBIOT_RACH_POWERRAMPINGSTEP_NB_IDX 2 +#define NBIOT_RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER_NB_IDX 3 +#define NBIOT_RACH_PREAMBLETRANSMAX_CE_NB_IDX 4 +#define NBIOT_BCCH_MODIFICATIONPERIODCOEFF_NB_IDX 5 +#define NBIOT_PCCH_DEFAULTPAGINGCYCLE_NB_IDX 6 +#define NBIOT_NPRACH_CP_LENGTH_IDX 7 +#define NBIOT_NPRACH_RSRP_RANGE_IDX 8 +#define NBIOT_NPRACH_SUBCARRIERMSG3_RANGESTART_IDX 9 +#define NBIOT_MAXNUMPREAMBLEATTEMPTCE_NB_IDX 10 +#define NBIOT_NPDSCH_NRS_POWER_IDX 11 +#define NBIOT_NPUSCH_ACK_NACK_NUMREPETITIONS_NB_IDX 12 +#define NBIOT_NPUSCH_SRS_SUBFRAMECONFIG_NB_IDX 13 +#define NBIOT_NPUSCH_THREETONE_CYCLICSHIFT_R13_IDX 14 +#define NBIOT_NPUSCH_SIXTONE_CYCLICSHIFT_R13_IDX 15 +#define NBIOT_NPUSCH_GROUPHOPPINGENABLED_IDX 16 +#define NBIOT_NPUSCH_GROUPASSIGNMENTNPUSCH_R13_IDX 17 +#define NBIOT_DL_GAPTHRESHOLD_NB_IDX 18 +#define NBIOT_DL_GAPPERIODICITY_NB_IDX 19 +#define NBIOT_DL_GAPDURATIONCOEFF_NB_IDX 20 +#define NBIOT_NPUSCH_P0_NOMINALNPUSCH_IDX 21 +#define NBIOT_NPUSCH_ALPHA_IDX 22 +#define NBIOT_DELTAPREAMBLEMSG3_IDX 23 +#define NBIOT_UE_TIMERSANDCONSTANTS_T300_NB_IDX 24 +#define NBIOT_UE_TIMERSANDCONSTANTS_T301_NB_IDX 25 +#define NBIOT_UE_TIMERSANDCONSTANTS_T310_NB_IDX 26 +#define NBIOT_UE_TIMERSANDCONSTANTS_T311_NB_IDX 27 +#define NBIOT_UE_TIMERSANDCONSTANTS_N310_NB_IDX 28 +#define NBIOT_UE_TIMERSANDCONSTANTS_N311_NB_IDX 29 + +/* NB-Iot RRC: link to LTE RRC section name */ +#define NBIOT_LTERRCREF_CONFIG_STRING "LTERRC_Ref" +/*---------------------------------------------------------------------------------------------------------------*/ +/* NB-IoT RRC configuration parameters to link to a LTE RRC instance (in-guard, in-band) */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*---------------------------------------------------------------------------------------------------------------*/ +#define NBIOTRRCPARAMS_RRCREF_DESC { \ +{"RRC_inst", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"CC_inst", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +} +/*--------------------------------------------------------------------------------------------------------------*/ +#define NBIOT_RRCINST_IDX 0 +#define NBIOT_CCINST_IDX 1 + +#define NBIOT_RRCLIST_NPRACHPARAMS_CONFIG_STRING "NPRACH-NB-r13" + + +#define NPRACH_PERIODICITY_OKVALUES {40,80,160,240,320,640,1280,2560} +#define NPRACH_PERIODICITY_MODVALUES { NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms40, NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms80, \ + NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms160, NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms240, \ + NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms320, NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms640, \ + NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms1280, NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms2560 } + +#define NPRACH_STARTTIME_OKVALUES {8,16,32,64,128,256,512,1024} +#define NPRACH_STARTTIME_MODVALUES { NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms8, NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms16, \ + NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms32, NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms64, \ + NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms128, NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms256, \ + NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms512, NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms1024 } + +#define NPRACH_SUBCARRIEROFFSET_OKVALUES {0,12,24,36,2,18,34} +#define NPRACH_SUBCARRIEROFFSET_MODVALUES { NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n0, NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n12, \ + NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n24, NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n36, \ + NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n2, NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n18, \ + NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n34 } + +#define NPRACH_NUMSUBCARRIERS_OKVALUES {12,24,36,48} +#define NPRACH_NUMSUBCARRIERS_MODVALUES { NPRACH_Parameters_NB_r13__nprach_NumSubcarriers_r13_n12, NPRACH_Parameters_NB_r13__nprach_NumSubcarriers_r13_n24, \ + NPRACH_Parameters_NB_r13__nprach_NumSubcarriers_r13_n36, NPRACH_Parameters_NB_r13__nprach_NumSubcarriers_r13_n48 } + + +#define NUMREPETITIONSPERPREAMBLEATTEMPT_OKVALUES {1,2,4,8,16,32,64,128} +#define NUMREPETITIONSPERPREAMBLEATTEMPT_MODVALUES { NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n1, NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n2, \ + NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n4, NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n8, \ + NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n16, NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n32, \ + NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n64, NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n128} + +#define NPDCCHNUMREPETITIONSRA_OKVALUES {1,2,4,8,16,32,64,128,256,512,1024,2048} +#define NPDCCHNUMREPETITIONSRA_MODVALUES { NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r1, NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r2, \ + NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r4, NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r8, \ + NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r16, NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r32, \ + NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r64, NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r128, \ + NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r256, NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r512, \ + NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r1024,NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r2048} + +#define NPDCCHSTARTSFCSSRA_OKVALUES {1,2,4,8,16,32,48,64} +#define NPDCCHSTARTSFCSSRA_MODVALUES { NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v1dot5, NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v2, \ + NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v4, NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v8, \ + NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v16, NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v32, \ + NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v48, NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v64} + +#define NPDCCHOFFSETRA_OKVALUES {"zero","oneEighth","oneFourth","threeEighth"} +#define NPDCCHOFFSETRA_MODVALUES { NPRACH_Parameters_NB_r13__npdcch_Offset_RA_r13_zero, NPRACH_Parameters_NB_r13__npdcch_Offset_RA_r13_oneEighth, \ + NPRACH_Parameters_NB_r13__npdcch_Offset_RA_r13_oneFourth, NPRACH_Parameters_NB_r13__npdcch_Offset_RA_r13_threeEighth} + + + +#define NBIOT_RRCLIST_NPRACHPARAMSCHECK_DESC { \ + { .s1a= { config_check_modify_integer, NPRACH_PERIODICITY_OKVALUES, NPRACH_PERIODICITY_MODVALUES, 8 }}, \ + { .s1a= { config_check_modify_integer, NPRACH_STARTTIME_OKVALUES, NPRACH_STARTTIME_MODVALUES, 8 }}, \ + { .s1a= { config_check_modify_integer, NPRACH_SUBCARRIEROFFSET_OKVALUES, NPRACH_SUBCARRIEROFFSET_MODVALUES, 7 }}, \ + { .s1a= { config_check_modify_integer, NPRACH_NUMSUBCARRIERS_OKVALUES, NPRACH_NUMSUBCARRIERS_MODVALUES, 4 }}, \ + { .s1a= { config_check_modify_integer, NUMREPETITIONSPERPREAMBLEATTEMPT_OKVALUES, NUMREPETITIONSPERPREAMBLEATTEMPT_MODVALUES,8 }}, \ + { .s1a= { config_check_modify_integer, NPDCCHNUMREPETITIONSRA_OKVALUES, NPDCCHNUMREPETITIONSRA_MODVALUES, 12}}, \ + { .s1a= { config_check_modify_integer, NPDCCHSTARTSFCSSRA_OKVALUES, NPDCCHSTARTSFCSSRA_MODVALUES, 8 }}, \ + { .s3a= { config_checkstr_assign_integer, NPDCCHOFFSETRA_OKVALUES, NPDCCHOFFSETRA_MODVALUES, 4 }}, \ +} + + + +/*------------------------------------------------------------------------------------------------------------------------------*/ +/* NB-IoT NPrach parameters, there will be three ocuurences of these parameters in each RRC instance */ + /* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*------------------------------------------------------------------------------------------------------------------------------*/ +#define NBIOTRRC_NPRACH_PARAMS_DESC { \ +{"nprach_Periodicity", NULL, 0, uptr:NULL, defintval:320, TYPE_UINT, 0}, \ +{"nprach_StartTime", NULL, 0, uptr:NULL, defintval:8, TYPE_UINT, 0}, \ +{"nprach_SubcarrierOffset", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"nprach_NumSubcarriers", NULL, 0, uptr:NULL, defintval:12, TYPE_UINT, 0}, \ +{"numRepetitionsPerPreambleAttempt", NULL, 0, uptr:NULL, defintval:2, TYPE_UINT, 0}, \ +{"npdcch_NumRepetitions_RA", NULL, 0, uptr:NULL, defintval:16, TYPE_UINT, 0}, \ +{"npdcch_StartSF_CSS_RA", NULL, 0, uptr:NULL, defintval:2, TYPE_UINT, 0}, \ +{"npdcch_Offset_RA", NULL, 0, strptr:NULL, defstrval:"zero", TYPE_STRING, 0}, \ +} + +#define NBIOT_NPRACH_PERIODICITY_IDX 0 +#define NBIOT_NPRACH_STARTTIME_IDX 1 +#define NBIOT_NPRACH_SUBCARRIEROFFSET_IDX 2 +#define NBIOT_NPRACH_NUMSUBCARRIERS_IDX 3 +#define NBIOT_NUMREPETITIONSPERPREAMBLEATTEMPT_NB_IDX 4 +#define NBIOT_NPDCCH_NUMREPETITIONS_RA_IDX 5 +#define NBIOT_NPDCCH_STARTSF_CSS_RA_IDX 6 +#define NBIOT_NPDCCH_OFFSET_RA_IDX 7 + +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* NB IoT MACRLC configuration list section name */ +#define NBIOT_MACRLCLIST_CONFIG_STRING "NB-IoT_MACRLCs" + + +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* NB IoT L1 configuration list section name */ +#define NBIOT_L1LIST_CONFIG_STRING "NB-IoT_L1s" diff --git a/openair2/UTIL/LOG/log.c b/openair2/UTIL/LOG/log.c index 948425e8da..ff6a5cd573 100644 --- a/openair2/UTIL/LOG/log.c +++ b/openair2/UTIL/LOG/log.c @@ -34,6 +34,7 @@ #define COMPONENT_LOG #define COMPONENT_LOG_IF #include +#define LOG_MAIN #include "log.h" #include "vcd_signal_dumper.h" #include "assertions.h" @@ -46,7 +47,7 @@ # include #include "common/config/config_userapi.h" // main log variables -log_t *g_log; + mapping log_level_names[] = { {"emerg", LOG_EMERG}, @@ -1562,7 +1563,7 @@ int set_log(int component, int level, int interval) component, MIN_LOG_COMPONENTS, MAX_LOG_COMPONENTS); DevCheck((level <= LOG_TRACE) && (level >= LOG_EMERG), level, LOG_TRACE, LOG_EMERG); - DevCheck((interval > 0) && (interval <= 0xFF), interval, 0, 0xFF); + DevCheck((interval >= 0) && (interval <= 0xFF), interval, 0, 0xFF); g_log->log_component[component].level = level; @@ -1596,7 +1597,7 @@ int set_comp_log(int component, int level, int verbosity, int interval) component, MIN_LOG_COMPONENTS, MAX_LOG_COMPONENTS); DevCheck((level <= LOG_TRACE) && (level >= LOG_EMERG), level, LOG_TRACE, LOG_EMERG); - DevCheck((interval > 0) && (interval <= 0xFF), interval, 0, 0xFF); + DevCheck((interval >= 0) && (interval <= 0xFF), interval, 0, 0xFF); #if 0 if ((verbosity == LOG_NONE) || (verbosity == LOG_LOW) || diff --git a/openair2/UTIL/LOG/log.h b/openair2/UTIL/LOG/log.h index c21407f6eb..00bc334de5 100644 --- a/openair2/UTIL/LOG/log.h +++ b/openair2/UTIL/LOG/log.h @@ -253,7 +253,17 @@ typedef enum log_instance_type_e { void log_set_instance_type (log_instance_type_t instance); #endif - +#ifdef LOG_MAIN +log_t *g_log; +#else +#ifdef __cplusplus + extern "C" { +#endif +extern log_t *g_log; +#ifdef __cplusplus +} +#endif +#endif /*--- INCLUDES ---------------------------------------------------------------*/ # include "log_if.h" /*----------------------------------------------------------------------------*/ @@ -279,9 +289,9 @@ void *log_thread_function(void * list); * @brief Macro used to call tr_log_full_ex with file, function and line information * @{*/ #ifdef LOG_NO_THREAD -#define logIt(component, level, format, args...) logRecord_mt(__FILE__, __FUNCTION__, __LINE__, component, level, format, ##args) +#define logIt(component, level, format, args...) (g_log->log_component[component].interval?logRecord_mt(__FILE__, __FUNCTION__, __LINE__, component, level, format, ##args):(void)0) #else //default -#define logIt(component, level, format, args...) logRecord(__FILE__, __FUNCTION__, __LINE__, component, level, format, ##args) +#define logIt(component, level, format, args...) (g_log->log_component[component].interval?logRecord(__FILE__, __FUNCTION__, __LINE__, component, level, format, ##args):(void)0) #endif /* @}*/ diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c index eb9f80872e..d74b1c6d4f 100644 --- a/targets/ARCH/COMMON/common_lib.c +++ b/targets/ARCH/COMMON/common_lib.c @@ -36,6 +36,7 @@ #include #include "common_lib.h" +#include "common/utils/load_module_shlib.h" int set_device(openair0_device *device) { @@ -85,52 +86,26 @@ int set_transport(openair0_device *device) { } } - +typedef int(*devfunc_t)(openair0_device *, openair0_config_t *, eth_params_t *); /* look for the interface library and load it */ int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * cfg, uint8_t flag) { - void *lib_handle; - oai_device_initfunc_t dp ; - oai_transport_initfunc_t tp ; + loader_shlibfunc_t shlib_fdesc[1]; int ret=0; - + char *libname; if (flag == RAU_LOCAL_RADIO_HEAD) { - lib_handle = dlopen(OAI_RF_LIBNAME, RTLD_LAZY); - if (!lib_handle) { - fprintf(stderr,"Unable to locate %s: HW device set to NONE_DEV.\n", OAI_RF_LIBNAME); - fprintf(stderr,"%s\n",dlerror()); - return -1; - } - - dp = dlsym(lib_handle,"device_init"); - - if (dp != NULL ) { - ret = dp(device,openair0_cfg); - if (ret<0) { - fprintf(stderr, "%s %d:oai device intialization failed %s\n", __FILE__, __LINE__, dlerror()); - } - } else { - fprintf(stderr, "%s %d:oai device intializing function not found %s\n", __FILE__, __LINE__, dlerror()); - return -1; - } + libname=OAI_RF_LIBNAME; + shlib_fdesc[0].fname="device_init"; } else { - lib_handle = dlopen(OAI_TP_LIBNAME, RTLD_LAZY); - if (!lib_handle) { - printf( "Unable to locate %s: transport protocol set to NONE_TP.\n", OAI_TP_LIBNAME); - printf( "%s\n",dlerror()); - return -1; - } - - tp = dlsym(lib_handle,"transport_init"); - - if (tp != NULL ) { - tp(device,openair0_cfg,cfg); - } else { - fprintf(stderr, "%s %d:oai device intializing function not found %s\n", __FILE__, __LINE__, dlerror()); - return -1; - } + libname=OAI_TP_LIBNAME; + shlib_fdesc[0].fname="transport_init"; } - + ret=load_module_shlib(libname,shlib_fdesc,1); + if (ret < 0) { + fprintf(stderr,"Library %s couldn't be loaded\n",libname); + } else { + ret=((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg); + } return ret; } diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 2dc1650bfd..433e29e97d 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -36,9 +36,9 @@ #include /* name of shared library implementing the radio front end */ -#define OAI_RF_LIBNAME "liboai_device.so" +#define OAI_RF_LIBNAME "oai_device" /* name of shared library implementing the transport */ -#define OAI_TP_LIBNAME "liboai_transpro.so" +#define OAI_TP_LIBNAME "oai_transpro" /* flags for BBU to determine whether the attached radio head is local or remote */ #define RAU_LOCAL_RADIO_HEAD 0 diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index f6789086b4..bbf35cffa0 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -135,11 +135,11 @@ volatile int oai_exit = 0; static clock_source_t clock_source = internal; static int wait_for_sync = 0; -static char UE_flag=0; +static int8_t UE_flag=0; unsigned int mmapped_dma=0; int single_thread_flag=1; -static char threequarter_fs=0; +static int8_t threequarter_fs=0; uint32_t downlink_frequency[MAX_NUM_CCs][4]; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; @@ -570,7 +570,7 @@ void *l2l1_task(void *arg) { static void get_options(void) { int CC_id; - int tddflag; + int tddflag, nonbiotflag; char *loopfile=NULL; int dumpframe; uint32_t online_log_messages; @@ -627,10 +627,10 @@ static void get_options(void) { if ( (cmdline_uemodeparams[CMDLINE_CALIBUERX_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue; if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXMED_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_med; if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXBYP_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_byp; - if ( (cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = debug_prach; - if ( (cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = no_L2_connect; - if ( (cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = calib_prach_tx; - if ( (cmdline_uemodeparams[CMDLINE_DUMPMEMORY_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_dump_frame; + if ( *(cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].uptr) > 0) mode = debug_prach; + if ( *(cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr) > 0) mode = no_L2_connect; + if ( *(cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr) > 0) mode = calib_prach_tx; + if (dumpframe > 0) mode = rx_dump_frame; if ( downlink_frequency[0][0] > 0) { printf("Downlink frequency set to %u\n", downlink_frequency[0][0]); @@ -645,35 +645,36 @@ static void get_options(void) { frame_parms[CC_id]->frame_type = TDD; } - if (n_rb_dl !=0) { - printf("NB_RB set to %d\n",n_rb_dl); - if ( n_rb_dl < 6 ) { - n_rb_dl = 6; - printf ( "%i: Invalid number of ressource blocks, adjusted to 6\n",n_rb_dl); - } - if ( n_rb_dl > 100 ) { - n_rb_dl = 100; - printf ( "%i: Invalid number of ressource blocks, adjusted to 100\n",n_rb_dl); - } - if ( n_rb_dl > 50 && n_rb_dl < 100 ) { - n_rb_dl = 50; - printf ( "%i: Invalid number of ressource blocks, adjusted to 50\n",n_rb_dl); - } - if ( n_rb_dl > 25 && n_rb_dl < 50 ) { - n_rb_dl = 25; - printf ( "%i: Invalid number of ressource blocks, adjusted to 25\n",n_rb_dl); - } - UE_scan = 0; - for (CC_id=0; CC_idN_RB_DL=n_rb_dl; - frame_parms[CC_id]->N_RB_UL=n_rb_dl; - } + if (frame_parms[0]->N_RB_DL !=0) { + if ( frame_parms[0]->N_RB_DL < 6 ) { + frame_parms[0]->N_RB_DL = 6; + printf ( "%i: Invalid number of ressource blocks, adjusted to 6\n",frame_parms[0]->N_RB_DL); + } + if ( frame_parms[0]->N_RB_DL > 100 ) { + frame_parms[0]->N_RB_DL = 100; + printf ( "%i: Invalid number of ressource blocks, adjusted to 100\n",frame_parms[0]->N_RB_DL); + } + if ( frame_parms[0]->N_RB_DL > 50 && frame_parms[0]->N_RB_DL < 100 ) { + frame_parms[0]->N_RB_DL = 50; + printf ( "%i: Invalid number of ressource blocks, adjusted to 50\n",frame_parms[0]->N_RB_DL); + } + if ( frame_parms[0]->N_RB_DL > 25 && frame_parms[0]->N_RB_DL < 50 ) { + frame_parms[0]->N_RB_DL = 25; + printf ( "%i: Invalid number of ressource blocks, adjusted to 25\n",frame_parms[0]->N_RB_DL); + } + UE_scan = 0; + frame_parms[0]->N_RB_UL=frame_parms[0]->N_RB_DL; + for (CC_id=1; CC_idN_RB_DL=frame_parms[0]->N_RB_DL; + frame_parms[CC_id]->N_RB_UL=frame_parms[0]->N_RB_UL; + } } - for (CC_id=0;CC_id 0 */ diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index 5cc4d5fea2..1d594caadc 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -85,7 +85,7 @@ #define CONFIG_HLP_TPORT "tracer port\n" #define CONFIG_HLP_NOTWAIT "don't wait for tracer, start immediately\n" #define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n" - +#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" /***************************************************************************************************************************************/ /* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument @@ -129,7 +129,7 @@ {"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, u8ptr:&nb_antenna_tx, defuintval:1, TYPE_UINT8, 0}, \ {"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, iptr:&UE_scan_carrier, defintval:0, TYPE_INT, 0}, \ {"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:90, TYPE_INT, 0}, \ -{"r" , CONFIG_HLP_PRB, 0, u8ptr:&n_rb_dl, defintval:0, TYPE_UINT8, 0}, \ +{"r" , CONFIG_HLP_PRB, 0, u8ptr:&(frame_parms[0]->N_RB_DL), defintval:0, TYPE_UINT8, 0}, \ } @@ -168,7 +168,8 @@ extern int16_t dlsch_demod_shift; {"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&ouput_vcd, defintval:0, TYPE_INT, 0}, \ {"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \ {"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \ -{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0} \ +{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \ +{"nbiot-disable", CONFIG_HLP_DISABLNBIOT,PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0} \ } #define CONFIG_HLP_FLOG "Enable online log \n" From b04f3b54a41b08c20e24795338de4bf5865a6649 Mon Sep 17 00:00:00 2001 From: oai Date: Thu, 1 Mar 2018 18:56:04 +0100 Subject: [PATCH 178/195] introduce distinct executables for ue and eNodeB (lte-uesoftmodem, lte-softmodem) --- cmake_targets/CMakeLists.txt | 90 +- cmake_targets/build_oai | 20 +- common/utils/load_module_shlib.c | 52 +- common/utils/load_module_shlib.h | 28 +- common/utils/telnetsrv/telnetsrv.c | 10 +- common/utils/telnetsrv/telnetsrv.h | 2 + openair1/PHY/CODING/3gpplte_sse.c | 2 +- openair1/PHY/CODING/3gpplte_turbo_decoder.c | 10 +- .../CODING/3gpplte_turbo_decoder_sse_16bit.c | 2 + .../CODING/3gpplte_turbo_decoder_sse_8bit.c | 2 + openair1/PHY/CODING/coding_load.c | 73 +- openair1/PHY/CODING/defs.h | 106 +- openair1/PHY/INIT/init_top.c | 2 +- .../PHY/LTE_ESTIMATION/lte_ue_measurements.c | 6 +- openair1/PHY/extern.h | 2 +- openair1/PHY/vars.h | 2 +- openair2/RRC/LITE/L2_interface_ue.c | 1 + openair2/RRC/LITE/rrc_UE.c | 2 +- targets/RT/USER/lte-softmodem.c | 409 +----- targets/RT/USER/lte-softmodem.h | 7 +- targets/RT/USER/lte-uesoftmodem.c | 1139 +++++++++++++++++ 21 files changed, 1419 insertions(+), 548 deletions(-) create mode 100644 targets/RT/USER/lte-uesoftmodem.c diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 4f264044df..a0ee33dc78 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1216,9 +1216,7 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/CODING/ccoding_byte_lte.c ${OPENAIR1_DIR}/PHY/CODING/3gpplte_sse.c ${OPENAIR1_DIR}/PHY/CODING/crc_byte.c - ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c - ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c - ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c + ${PHY_TURBOIF} ${OPENAIR1_DIR}/PHY/CODING/lte_rate_matching.c ${OPENAIR1_DIR}/PHY/CODING/viterbi.c ${OPENAIR1_DIR}/PHY/CODING/viterbi_lte.c @@ -1946,14 +1944,12 @@ add_executable(lte-softmodem ${s1ap_h} ${OPENAIR_BIN_DIR}/messages_xml.h ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c - ${OPENAIR_TARGETS}/RT/USER/lte-ue.c ${OPENAIR_TARGETS}/RT/USER/lte-enb.c ${OPENAIR_TARGETS}/RT/USER/lte-ru.c ${OPENAIR_TARGETS}/RT/USER/lte-softmodem.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c ${OPENAIR_TARGETS}/COMMON/create_tasks.c - ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c @@ -1969,9 +1965,9 @@ add_executable(lte-softmodem target_link_libraries (lte-softmodem -Wl,--start-group - RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS L2 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 - NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB - NFAPI_USER_LIB + RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS L2 + ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 + NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -Wl,--end-group z dl) target_link_libraries (lte-softmodem ${LIBXML2_LIBRARIES}) @@ -1986,14 +1982,12 @@ add_executable(lte-softmodem-nos1 ${s1ap_h} ${OPENAIR_BIN_DIR}/messages_xml.h ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c - ${OPENAIR_TARGETS}/RT/USER/lte-ue.c ${OPENAIR_TARGETS}/RT/USER/lte-enb.c ${OPENAIR_TARGETS}/RT/USER/lte-ru.c ${OPENAIR_TARGETS}/RT/USER/lte-softmodem.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c ${OPENAIR_TARGETS}/COMMON/create_tasks.c - ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/rb_config.c @@ -2007,9 +2001,9 @@ add_executable(lte-softmodem-nos1 ) target_link_libraries (lte-softmodem-nos1 -Wl,--start-group - RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCHED_LIB PHY LFDS L2 ${MSC_LIB} ${RAL_LIB} ${ITTI_LIB} ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 - NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB - NFAPI_USER_LIB + RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCHED_LIB PHY LFDS L2 ${MSC_LIB} ${RAL_LIB} ${ITTI_LIB} + ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 + NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -Wl,--end-group z dl ) target_link_libraries (lte-softmodem-nos1 ${LIBXML2_LIBRARIES}) @@ -2017,6 +2011,76 @@ target_link_libraries (lte-softmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt target_link_libraries (lte-softmodem-nos1 ${LIB_LMS_LIBRARIES}) target_link_libraries (lte-softmodem-nos1 ${T_LIB}) +# lte-uesoftmodem is UE implementation +####################################### + +add_executable(lte-uesoftmodem + ${rrc_h} + ${s1ap_h} + ${OPENAIR_BIN_DIR}/messages_xml.h + ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c + ${OPENAIR_TARGETS}/RT/USER/lte-ue.c + ${OPENAIR_TARGETS}/RT/USER/lte-uesoftmodem.c + ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c + ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c + ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c + ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c + ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c + ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c + ${OPENAIR_DIR}/common/utils/utils.c + ${OPENAIR_DIR}/common/utils/system.c + ${XFORMS_SOURCE} + ${XFORMS_SOURCE_SOFTMODEM} + ${T_SOURCE} + ${CONFIG_SOURCES} + ${SHLIB_LOADER_SOURCES} + ) + +target_link_libraries (lte-uesoftmodem + -Wl,--start-group + RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_UE_LIB PHY_UE LFDS L2_UE + ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 + -Wl,--end-group z dl) + +target_link_libraries (lte-uesoftmodem ${LIBXML2_LIBRARIES}) +target_link_libraries (lte-uesoftmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) +target_link_libraries (lte-uesoftmodem ${LIB_LMS_LIBRARIES}) +target_link_libraries (lte-uesoftmodem ${T_LIB}) + +# lte-softmodem-nos1 is both eNB and UE implementation +################################################### +add_executable(lte-uesoftmodem-nos1 + ${rrc_h} + ${s1ap_h} + ${OPENAIR_BIN_DIR}/messages_xml.h + ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c + ${OPENAIR_TARGETS}/RT/USER/lte-ue.c + ${OPENAIR_TARGETS}/RT/USER/lte-uesoftmodem.c + ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c + ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c + ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c + ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c + ${OPENAIR2_DIR}/RRC/NAS/nas_config.c + ${OPENAIR2_DIR}/RRC/NAS/rb_config.c + ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c + ${OPENAIR_DIR}/common/utils/system.c + ${XFORMS_SOURCE} + ${XFORMS_SOURCE_SOFTMODEM} + ${T_SOURCE} + ${CONFIG_SOURCES} + ${SHLIB_LOADER_SOURCES} + ) +target_link_libraries (lte-uesoftmodem-nos1 + -Wl,--start-group + RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCHED_UE_LIB PHY_UE LFDS L2_UE ${MSC_LIB} ${RAL_LIB} ${ITTI_LIB} + ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 + -Wl,--end-group z dl ) + +target_link_libraries (lte-uesoftmodem-nos1 ${LIBXML2_LIBRARIES}) +target_link_libraries (lte-uesoftmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) +target_link_libraries (lte-uesoftmodem-nos1 ${LIB_LMS_LIBRARIES}) +target_link_libraries (lte-uesoftmodem-nos1 ${T_LIB}) + # USIM process ################# #add_executable(usim diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index b19e3208a5..f5be69d3fa 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -359,7 +359,11 @@ function main() { CMAKE_CMD="$CMAKE_CMD .." echo_info "CMAKE_CMD=$CMAKE_CMD" - + if [ "$eNB" = "1" ] && [ "$UE" = "1" ]; then + echo_error "Cannot build UE and eNB on one build_oai execution" + echo_error "use 2 build_oai invocations" + exit + fi ######################################################### # check validity of HW and TP parameters for eNB ######################################################### @@ -488,10 +492,20 @@ function main() { DIR=$OPENAIR_DIR/cmake_targets if [ "$NOS1" = "1" ] ; then lte_build_dir=lte_noS1_build_oai - lte_exec=lte-softmodem-nos1 + if [ "$eNB" = "1" ] ; then + lte_exec=lte-softmodem-nos1 + fi + if [ "$UE" = "1" ] ; then + lte_exec=lte-uesoftmodem-nos1 + fi else lte_build_dir=lte_build_oai - lte_exec=lte-softmodem + if [ "$eNB" = "1" ] ; then + lte_exec=lte-softmodem + fi + if [ "$UE" = "1" ] ; then + lte_exec=lte-uesoftmodem + fi fi # configuration module libraries, one currently available, using libconfig diff --git a/common/utils/load_module_shlib.c b/common/utils/load_module_shlib.c index 32d3cfee9b..c07b54f54a 100644 --- a/common/utils/load_module_shlib.c +++ b/common/utils/load_module_shlib.c @@ -48,11 +48,11 @@ void loader_init(void) { loader_data.mainexec_buildversion = PACKAGE_VERSION; int ret = config_get( LoaderParams,sizeof(LoaderParams)/sizeof(paramdef_t),LOADER_CONFIG_PREFIX); if (ret <0) { - fprintf(stderr,"[LOADER] %s %d configuration couldn't be performed",__FILE__, __LINE__); + printf("[LOADER] configuration couldn't be performed via config module, parameters set to default values\n"); if (loader_data.shlibpath == NULL) { loader_data.shlibpath=DEFAULT_PATH; } - return; + loader_data.maxshlibs = DEFAULT_MAXSHLIBS; } loader_data.shlibs = malloc(loader_data.maxshlibs * sizeof(loader_shlibdesc_t)); if(loader_data.shlibs == NULL) { @@ -96,7 +96,10 @@ int ret; if (shlibpath == NULL) { shlibpath = loader_data.shlibpath ; } - +/* no specific shared lib version */ + if (shlibversion == NULL) { + shlibversion = "" ; + } /* alloc memory for full module shared lib file name */ tmpstr = malloc(strlen(shlibpath)+strlen(modname)+strlen(shlibversion)+16); if (tmpstr == NULL) { @@ -120,6 +123,7 @@ int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf) void *lib_handle; initfunc_t fpi; checkverfunc_t fpc; + getfarrayfunc_t fpg; char *shlib_path; char *afname=NULL; int ret=0; @@ -155,25 +159,29 @@ int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf) } if (farray != NULL) { + loader_data.shlibs[loader_data.numshlibs].funcarray=malloc(numf*sizeof(loader_shlibfunc_t)); + loader_data.shlibs[loader_data.numshlibs].numfunc=0; for (int i=0; i #include #include - +#include "common/utils/load_module_shlib.h" #include "common/config/config_userapi.h" #include @@ -787,4 +787,10 @@ int telnetsrv_checkbuildver(char * mainexec_buildversion, char ** shlib_buildve return 0; } - +int telnetsrv_getfarray(loader_shlibfunc_t **farray) + { + *farray=malloc(sizeof(loader_shlibfunc_t)); + (*farray)[0].fname=TELNET_ADDCMD_FNAME; + (*farray)[0].fptr=(int (*)(void) )add_telnetcmd; + return 1; + } diff --git a/common/utils/telnetsrv/telnetsrv.h b/common/utils/telnetsrv/telnetsrv.h index 3cf561eda2..2d3ef531ae 100644 --- a/common/utils/telnetsrv/telnetsrv.h +++ b/common/utils/telnetsrv/telnetsrv.h @@ -131,6 +131,8 @@ VT escape sequence definition, for smarter display.... #define STDFMT "\x1b[0m" /*---------------------------------------------------------------------------------------------*/ +#define TELNET_ADDCMD_FNAME "add_telnetcmd" +typedef int(*add_telnetcmd_func_t)(char *, telnetshell_vardef_t *, telnetshell_cmddef_t *); #ifdef TELNETSERVERCODE int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd); void set_sched(pthread_t tid, int pid,int priority); diff --git a/openair1/PHY/CODING/3gpplte_sse.c b/openair1/PHY/CODING/3gpplte_sse.c index 313d63f7a7..8150f02da8 100644 --- a/openair1/PHY/CODING/3gpplte_sse.c +++ b/openair1/PHY/CODING/3gpplte_sse.c @@ -696,7 +696,7 @@ int main(int argc,char **argv) printf("Input %d : %d\n",i,input[i]); } - threegpplte_turbo_encoder(&input[0], + threegpplte_turbo_encoder_sse(&input[0], INPUT_LENGTH, &output[0], 0, diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder.c b/openair1/PHY/CODING/3gpplte_turbo_decoder.c index 6c50e03806..c0e4ca12db 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder.c @@ -874,14 +874,22 @@ void compute_ext_s(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,llr_t* ext, unsigned char phy_threegpplte_turbo_decoder_scalar(llr_t *y, + llr_t *y2, unsigned char *decoded_bytes, + unsigned char *decoded_bytes2, unsigned short n, unsigned short f1, unsigned short f2, unsigned char max_iterations, unsigned char crc_type, unsigned char F, - unsigned char inst) + time_stats_t *init_stats, + time_stats_t *alpha_stats, + time_stats_t *beta_stats, + time_stats_t *gamma_stats, + time_stats_t *ext_stats, + time_stats_t *intl1_stats, + time_stats_t *intl2_stats) { /* y is a pointer to the input diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c index 63896924dd..ae3ce531d0 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c @@ -1172,7 +1172,9 @@ void init_td16(void) } unsigned char phy_threegpplte_turbo_decoder16(short *y, + short *y2, unsigned char *decoded_bytes, + unsigned char *decoded_bytes2, unsigned short n, unsigned short f1, unsigned short f2, diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c index f7b64b767d..5b7174e989 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c @@ -898,7 +898,9 @@ void init_td8(void) } unsigned char phy_threegpplte_turbo_decoder8(short *y, + short y2, unsigned char *decoded_bytes, + unsigned char *decoded_bytes2, unsigned short n, unsigned short f1, unsigned short f2, diff --git a/openair1/PHY/CODING/coding_load.c b/openair1/PHY/CODING/coding_load.c index c8aed8cf30..6e4670dd8e 100644 --- a/openair1/PHY/CODING/coding_load.c +++ b/openair1/PHY/CODING/coding_load.c @@ -29,13 +29,32 @@ * \note * \warning */ +#define _GNU_SOURCE #include + + #include "PHY/defs.h" +#include "PHY/extern.h" #include "common/utils/load_module_shlib.h" +#include "common/utils/telnetsrv/telnetsrv.h" - +static int coding_setmod_cmd(char *buff, int debug, telnet_printfunc_t prnt); +static telnetshell_cmddef_t coding_cmdarray[] = { + {"mode","[sse,avx2,stdc,none]",coding_setmod_cmd}, + {"","",NULL}, +}; +telnetshell_vardef_t coding_vardef[] = { +{"maxiter",TELNET_VARTYPE_INT32,&max_turbo_iterations}, +{"",0,NULL} +}; +/* PHY/defs.h contains MODE_DECODE_XXX macros, following table must match */ +static char *modedesc[] = {"none","sse","C","avx2"}; +static int curmode; +/* function description array, to be used when loading the encoding/decoding shared lib */ loader_shlibfunc_t shlib_fdesc[DECODE_NUM_FPTR]; +/* encoding decoding functions pointers, filled here and used when encoding/decoding */ +/*defined as extern in PHY?CODING/extern.h */ decoder_if_t decoder16; decoder_if_t decoder8; encoder_if_t encoder; @@ -59,7 +78,6 @@ uint8_t nodecod(short *y, time_stats_t *intl1_stats, time_stats_t *intl2_stats) { - printf("."); return max_iterations+1; }; @@ -70,11 +88,6 @@ void decoding_setmode (int mode) { decoder16=nodecod; encoder=(encoder_if_t)shlib_fdesc[ENCODE_C_FPTRIDX].fptr; break; - case MODE_DECODE_SSE: - decoder8=(decoder_if_t)shlib_fdesc[DECODE_TD8_SSE_FPTRIDX].fptr; - decoder16=(decoder_if_t)shlib_fdesc[DECODE_TD16_SSE_FPTRIDX].fptr; - encoder=(encoder_if_t)shlib_fdesc[ENCODE_SSE_FPTRIDX].fptr; - break; case MODE_DECODE_C: decoder16=(decoder_if_t)shlib_fdesc[DECODE_TD_C_FPTRIDX].fptr; decoder8=(decoder_if_t)shlib_fdesc[DECODE_TD_C_FPTRIDX].fptr; @@ -85,15 +98,22 @@ void decoding_setmode (int mode) { decoder8=(decoder_if_t)shlib_fdesc[DECODE_TD8_SSE_FPTRIDX].fptr; encoder=(encoder_if_t)shlib_fdesc[ENCODE_SSE_FPTRIDX].fptr; break; + default: + mode=MODE_DECODE_SSE; + case MODE_DECODE_SSE: + decoder8=(decoder_if_t)shlib_fdesc[DECODE_TD8_SSE_FPTRIDX].fptr; + decoder16=(decoder_if_t)shlib_fdesc[DECODE_TD16_SSE_FPTRIDX].fptr; + encoder=(encoder_if_t)shlib_fdesc[ENCODE_SSE_FPTRIDX].fptr; + break; } - + curmode=mode; } int load_codinglib(void) { int ret; - + memset(shlib_fdesc,0,sizeof(shlib_fdesc)); shlib_fdesc[DECODE_INITTD8_SSE_FPTRIDX].fname = "init_td8"; shlib_fdesc[DECODE_INITTD16_SSE_FPTRIDX].fname= "init_td16"; shlib_fdesc[DECODE_INITTD_AVX2_FPTRIDX].fname="init_td16avx2"; @@ -117,10 +137,18 @@ int load_codinglib(void) { /* execute encoder/decoder init functions */ shlib_fdesc[DECODE_INITTD8_SSE_FPTRIDX].fptr(); shlib_fdesc[DECODE_INITTD16_SSE_FPTRIDX].fptr(); - shlib_fdesc[DECODE_INITTD_AVX2_FPTRIDX].fptr(); - shlib_fdesc[ENCODE_INIT_SSE_FPTRIDX].fptr(); + if(shlib_fdesc[DECODE_INITTD_AVX2_FPTRIDX].fptr != NULL) { + shlib_fdesc[DECODE_INITTD_AVX2_FPTRIDX].fptr(); + } + if(shlib_fdesc[ENCODE_INIT_SSE_FPTRIDX].fptr != NULL) { + shlib_fdesc[ENCODE_INIT_SSE_FPTRIDX].fptr(); + } decoding_setmode(MODE_DECODE_SSE); - +/* look for telnet server, if it is loaded, add the coding commands to it */ + add_telnetcmd_func_t addcmd = (add_telnetcmd_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_ADDCMD_FNAME); + if (addcmd != NULL) { + addcmd("coding",coding_vardef,coding_cmdarray); + } return 0; } @@ -132,3 +160,24 @@ void free_codinglib(void) { } + +/* functions for telnet support, when telnet server is loaded */ +int coding_setmod_cmd(char *buff, int debug, telnet_printfunc_t prnt) +{ + if (debug > 0) + prnt( "coding_setmod_cmd received %s\n",buff); + + if (strcasestr(buff,"sse") != NULL) { + decoding_setmode(MODE_DECODE_SSE); + } else if (strcasestr(buff,"avx2") != NULL) { + decoding_setmode(MODE_DECODE_AVX2); + } else if (strcasestr(buff,"stdc") != NULL) { + decoding_setmode(MODE_DECODE_C); + } else if (strcasestr(buff,"none") != NULL) { + decoding_setmode(MODE_DECODE_NONE); + } else { + prnt("%s: wrong setmod parameter...\n",buff); + } + prnt("Coding and decoding current mode: %s\n",modedesc[curmode]); + return 0; +} diff --git a/openair1/PHY/CODING/defs.h b/openair1/PHY/CODING/defs.h index ce13e045f3..40e19964df 100644 --- a/openair1/PHY/CODING/defs.h +++ b/openair1/PHY/CODING/defs.h @@ -37,7 +37,7 @@ #define CRC8 3 #define MAX_TURBO_ITERATIONS_MBSFN 8 -#define MAX_TURBO_ITERATIONS 4 +#define MAX_TURBO_ITERATIONS max_turbo_iterations #define LTE_NULL 2 @@ -294,21 +294,7 @@ void ccodedot11_init_inv(void); -/*\fn void threegpplte_turbo_encoder(uint8_t *input,uint16_t input_length_bytes,uint8_t *output,uint8_t F,uint16_t interleaver_f1,uint16_t interleaver_f2) -\brief This function implements a rate 1/3 8-state parralel concatenated turbo code (3GPP-LTE). -@param input Pointer to input buffer -@param input_length_bytes Number of bytes to encode -@param output Pointer to output buffer -@param F Number of filler bits at input -@param interleaver_f1 F1 generator -@param interleaver_f2 F2 generator -*/ -void threegpplte_turbo_encoder(uint8_t *input, - uint16_t input_length_bytes, - uint8_t *output, - uint8_t F, - uint16_t interleaver_f1, - uint16_t interleaver_f2); + /** \fn void ccodelte_encode(int32_t numbits,uint8_t add_crc, uint8_t *inPtr,uint8_t *outPtr,uint16_t rnti) @@ -440,95 +426,7 @@ int32_t rate_matching_lte(uint32_t N_coded, uint32_t off); -/*! -\brief This routine performs max-logmap detection for the 3GPP turbo code (with termination). It is optimized for SIMD processing and 16-bit -LLR arithmetic, and requires SSE2,SSSE3 and SSE4.1 (gcc >=4.3 and appropriate CPU) -@param y LLR input (16-bit precision) -@param decoded_bytes Pointer to decoded output -@param n number of coded bits (including tail bits) -@param max_iterations The maximum number of iterations to perform -@param interleaver_f1 F1 generator -@param interleaver_f2 F2 generator -@param crc_type Length of 3GPPLTE crc (CRC24a,CRC24b,CRC16,CRC8) -@param F Number of filler bits at start of packet -@returns number of iterations used (this is 1+max if incorrect crc or if crc_len=0) -*/ -uint8_t phy_threegpplte_turbo_decoder16(int16_t *y, - uint8_t *decoded_bytes, - uint16_t n, - uint16_t interleaver_f1, - uint16_t interleaver_f2, - uint8_t max_iterations, - uint8_t crc_type, - uint8_t F, - time_stats_t *init_stats, - time_stats_t *alpha_stats, - time_stats_t *beta_stats, - time_stats_t *gamma_stats, - time_stats_t *ext_stats, - time_stats_t *intl1_stats, - time_stats_t *intl2_stats); -uint8_t phy_threegpplte_turbo_decoder16avx2(int16_t *y, - int16_t *y2, - uint8_t *decoded_bytes, - uint8_t *decoded_bytes2, - uint16_t n, - uint16_t interleaver_f1, - uint16_t interleaver_f2, - uint8_t max_iterations, - uint8_t crc_type, - uint8_t F, - time_stats_t *init_stats, - time_stats_t *alpha_stats, - time_stats_t *beta_stats, - time_stats_t *gamma_stats, - time_stats_t *ext_stats, - time_stats_t *intl1_stats, - time_stats_t *intl2_stats); - -/*! -\brief This routine performs max-logmap detection for the 3GPP turbo code (with termination). It is optimized for SIMD processing and 8-bit -LLR arithmetic, and requires SSE2,SSSE3 and SSE4.1 (gcc >=4.3 and appropriate CPU) -@param y LLR input (16-bit precision) -@param decoded_bytes Pointer to decoded output -@param n number of coded bits (including tail bits) -@param max_iterations The maximum number of iterations to perform -@param interleaver_f1 F1 generator -@param interleaver_f2 F2 generator -@param crc_type Length of 3GPPLTE crc (CRC24a,CRC24b,CRC16,CRC8) -@param F Number of filler bits at start of packet -@returns number of iterations used (this is 1+max if incorrect crc or if crc_len=0) -*/ -uint8_t phy_threegpplte_turbo_decoder8(int16_t *y, - uint8_t *decoded_bytes, - uint16_t n, - uint16_t interleaver_f1, - uint16_t interleaver_f2, - uint8_t max_iterations, - uint8_t crc_type, - uint8_t F, - time_stats_t *init_stats, - time_stats_t *alpha_stats, - time_stats_t *beta_stats, - time_stats_t *gamma_stats, - time_stats_t *ext_stats, - time_stats_t *intl1_stats, - time_stats_t *intl2_stats); - -uint8_t phy_threegpplte_turbo_decoder_scalar(int16_t *y, - uint8_t *decoded_bytes, - uint16_t n, - uint16_t interleaver_f1, - uint16_t interleaver_f2, - uint8_t max_iterations, - uint8_t crc_type, - uint8_t F, - uint8_t inst); - - - -/** @} */ uint32_t crcbit (uint8_t * , int32_t, diff --git a/openair1/PHY/INIT/init_top.c b/openair1/PHY/INIT/init_top.c index 34e82771b4..6213520b8c 100644 --- a/openair1/PHY/INIT/init_top.c +++ b/openair1/PHY/INIT/init_top.c @@ -22,7 +22,7 @@ /*!\brief Initilization and reconfiguration routines for LTE PHY */ #include "defs.h" #include "PHY/extern.h" - +#include "PHY/CODING/extern.h" void init_lte_top(LTE_DL_FRAME_PARMS *frame_parms) { diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c index c4df34638b..ce6cd86959 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c @@ -207,10 +207,8 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, ((ue->frame_parms.frame_type == TDD) && ((subframe == 1) || (subframe == 6))) ) { // FDD PSS/SSS, compute noise in DTX REs - - if (ue->frame_parms.Ncp==NORMAL) { + if (ue->frame_parms.Ncp == NORMAL) { for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { - if(ue->frame_parms.frame_type == FDD) { rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(5*ue->frame_parms.ofdm_symbol_size)]; @@ -266,7 +264,7 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(12*aarx)); ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size); } else { - LOG_E(PHY, "Not yet implemented: noise power calculation when prefix length = EXTENDED\n"); + LOG_E(PHY, "Not yet implemented: noise power calculation when prefix length == EXTENDED\n"); } } else if ((ue->frame_parms.frame_type == TDD) && diff --git a/openair1/PHY/extern.h b/openair1/PHY/extern.h index 3ff2d64da0..5868c1c022 100644 --- a/openair1/PHY/extern.h +++ b/openair1/PHY/extern.h @@ -126,6 +126,6 @@ extern unsigned short Nb_81_110[8][4]; extern uint16_t hundred_times_log10_NPRB[100]; extern uint8_t alpha_lut[8]; - +extern uint8_t max_turbo_iterations; #endif /*__PHY_EXTERN_H__ */ diff --git a/openair1/PHY/vars.h b/openair1/PHY/vars.h index 45af058308..e8f4e27de1 100644 --- a/openair1/PHY/vars.h +++ b/openair1/PHY/vars.h @@ -149,5 +149,5 @@ int16_t unscrambling_lut[65536*16] __attribute__((aligned(32))); /// lookup table for scrambling in TX uint8_t scrambling_lut[65536*16] __attribute__((aligned(32))); - +uint8_t max_turbo_iterations=4; #endif /*__PHY_VARS_H__ */ diff --git a/openair2/RRC/LITE/L2_interface_ue.c b/openair2/RRC/LITE/L2_interface_ue.c index 3a2aeea451..244f0d2253 100644 --- a/openair2/RRC/LITE/L2_interface_ue.c +++ b/openair2/RRC/LITE/L2_interface_ue.c @@ -65,6 +65,7 @@ mac_rrc_data_req_ue( ) //-------------------------------------------------------------------------- { + #ifdef DEBUG_RRC int i; LOG_I(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id); diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c index 121d115398..3edf230ac2 100644 --- a/openair2/RRC/LITE/rrc_UE.c +++ b/openair2/RRC/LITE/rrc_UE.c @@ -242,6 +242,7 @@ openair_rrc_on_ue( { unsigned short i; + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" UE?:OPENAIR RRC IN....\n", PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); @@ -4841,7 +4842,6 @@ rrc_rx_tx_ue( ) //----------------------------------------------------------------------------- { - //uint8_t UE_id; #ifdef LOCALIZATION double estimated_distance; diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index bbf35cffa0..71ee86ecf1 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -135,7 +135,6 @@ volatile int oai_exit = 0; static clock_source_t clock_source = internal; static int wait_for_sync = 0; -static int8_t UE_flag=0; unsigned int mmapped_dma=0; int single_thread_flag=1; @@ -322,7 +321,7 @@ void signal_handler(int sig) { void exit_fun(const char* s) { - int CC_id; + int ru_id; if (s != NULL) { @@ -331,33 +330,22 @@ void exit_fun(const char* s) oai_exit = 1; - if (UE_flag==0) { + + if (RC.ru == NULL) + exit(-1); // likely init not completed, prevent crash or hang, exit now... for (ru_id=0; ru_idrfdevice.trx_end_func) + if (RC.ru[ru_id] && RC.ru[ru_id]->rfdevice.trx_end_func) RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice); - if (RC.ru[ru_id]->ifdevice.trx_end_func) + if (RC.ru[ru_id] && RC.ru[ru_id]->ifdevice.trx_end_func) RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice); } - } - for(CC_id=0; CC_idrfdevice.trx_end_func) - PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][CC_id]->rfdevice); - } - } #if defined(ENABLE_ITTI) sleep(1); //allow lte-softmodem threads to exit first itti_terminate_tasks (TASK_UNKNOWN); #endif - } } @@ -390,9 +378,9 @@ void reset_stats(FL_OBJECT *button, long arg) } static void *scope_thread(void *arg) { - char stats_buffer[16384]; + # ifdef ENABLE_XFORMS_WRITE_STATS - FILE *UE_stats, *eNB_stats; + FILE *eNB_stats; # endif struct sched_param sched_param; int UE_id, CC_id; @@ -405,47 +393,15 @@ static void *scope_thread(void *arg) { # ifdef ENABLE_XFORMS_WRITE_STATS - if (UE_flag==1) - UE_stats = fopen("UE_stats.txt", "w"); - else - eNB_stats = fopen("eNB_stats.txt", "w"); + eNB_stats = fopen("eNB_stats.txt", "w"); #endif while (!oai_exit) { - if (UE_flag==1) { - dump_ue_stats (PHY_vars_UE_g[0][0], &PHY_vars_UE_g[0][0]->proc.proc_rxtx[0],stats_buffer, 0, mode,rx_input_level_dBm); - //fl_set_object_label(form_stats->stats_text, stats_buffer); - fl_clear_browser(form_stats->stats_text); - fl_add_browser_line(form_stats->stats_text, stats_buffer); - phy_scope_UE(form_ue[0], - PHY_vars_UE_g[0][0], - 0, - 0,7); - - - } else { - /* - if (RC.eNB[0][0]->mac_enabled==1) { - len = dump_eNB_l2_stats (stats_buffer, 0); - //fl_set_object_label(form_stats_l2->stats_text, stats_buffer); - fl_clear_browser(form_stats_l2->stats_text); - fl_add_browser_line(form_stats_l2->stats_text, stats_buffer); - } - len = dump_eNB_stats (RC.eNB[0][0], stats_buffer, 0); - - if (MAX_NUM_CCs>1) - len += dump_eNB_stats (RC.eNB[0][1], &stats_buffer[len], 0); - - //fl_set_object_label(form_stats->stats_text, stats_buffer); - fl_clear_browser(form_stats->stats_text); - fl_add_browser_line(form_stats->stats_text, stats_buffer); - */ ue_cnt=0; for(UE_id=0; UE_iddlsch[UE_id][0]->rnti>0) && (ue_cnt 0) { - uint8_t n_rb_dl; - paramdef_t cmdline_uemodeparams[] =CMDLINE_UEMODEPARAMS_DESC; - paramdef_t cmdline_ueparams[] =CMDLINE_UEPARAMS_DESC; - - set_default_frame_parms(frame_parms); - - config_process_cmdline( cmdline_uemodeparams,sizeof(cmdline_uemodeparams)/sizeof(paramdef_t),NULL); - config_process_cmdline( cmdline_ueparams,sizeof(cmdline_ueparams)/sizeof(paramdef_t),NULL); - if (loopfile != NULL) { - printf("Input file for hardware emulation: %s",loopfile); - mode=loop_through_memory; - input_fd = fopen(loopfile,"r"); - AssertFatal(input_fd != NULL,"Please provide a valid input file\n"); - } - - if ( (cmdline_uemodeparams[CMDLINE_CALIBUERX_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue; - if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXMED_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_med; - if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXBYP_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_byp; - if ( *(cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].uptr) > 0) mode = debug_prach; - if ( *(cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr) > 0) mode = no_L2_connect; - if ( *(cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr) > 0) mode = calib_prach_tx; - if (dumpframe > 0) mode = rx_dump_frame; - - if ( downlink_frequency[0][0] > 0) { - printf("Downlink frequency set to %u\n", downlink_frequency[0][0]); - for (CC_id=0; CC_iddl_CarrierFreq = downlink_frequency[0][0]; - } - UE_scan=0; - } - - if (tddflag > 0) { - for (CC_id=0; CC_idframe_type = TDD; - } - - if (frame_parms[0]->N_RB_DL !=0) { - if ( frame_parms[0]->N_RB_DL < 6 ) { - frame_parms[0]->N_RB_DL = 6; - printf ( "%i: Invalid number of ressource blocks, adjusted to 6\n",frame_parms[0]->N_RB_DL); - } - if ( frame_parms[0]->N_RB_DL > 100 ) { - frame_parms[0]->N_RB_DL = 100; - printf ( "%i: Invalid number of ressource blocks, adjusted to 100\n",frame_parms[0]->N_RB_DL); - } - if ( frame_parms[0]->N_RB_DL > 50 && frame_parms[0]->N_RB_DL < 100 ) { - frame_parms[0]->N_RB_DL = 50; - printf ( "%i: Invalid number of ressource blocks, adjusted to 50\n",frame_parms[0]->N_RB_DL); - } - if ( frame_parms[0]->N_RB_DL > 25 && frame_parms[0]->N_RB_DL < 50 ) { - frame_parms[0]->N_RB_DL = 25; - printf ( "%i: Invalid number of ressource blocks, adjusted to 25\n",frame_parms[0]->N_RB_DL); - } - UE_scan = 0; - frame_parms[0]->N_RB_UL=frame_parms[0]->N_RB_DL; - for (CC_id=1; CC_idN_RB_DL=frame_parms[0]->N_RB_DL; - frame_parms[CC_id]->N_RB_UL=frame_parms[0]->N_RB_UL; - } - } - - - for (CC_id=1;CC_id 0 */ - #if T_TRACER paramdef_t cmdline_ttraceparams[] =CMDLINE_TTRACEPARAMS_DESC ; config_process_cmdline( cmdline_ttraceparams,sizeof(cmdline_ttraceparams)/sizeof(paramdef_t),NULL); #endif if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) ) { - if (UE_flag == 0) { memset((void*)&RC,0,sizeof(RC)); /* Read RC configuration file */ RCConfig(); NB_eNB_INST = RC.nb_inst; NB_RU = RC.nb_RU; printf("Configuration: nb_rrc_inst %d, nb_L1_inst %d, nb_ru %d\n",NB_eNB_INST,RC.nb_L1_inst,NB_RU); - } - } else if (UE_flag == 1 && (!(CONFIG_ISFLAGSET(CONFIG_NOOOPT))) ) { - // Here the configuration file is the XER encoded UE capabilities - // Read it in and store in asn1c data structures - sprintf(uecap_xer,"%stargets/PROJECTS/GENERIC-LTE-EPC/CONF/UE_config.xml",getenv("OPENAIR_HOME")); - printf("%s\n",uecap_xer); - uecap_xer_in=1; - } /* UE with config file */ + } } @@ -757,9 +619,8 @@ void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) { } -void init_openair0(void); -void init_openair0() { +void init_openair0(void) { int card; int i; @@ -799,16 +660,14 @@ void init_openair0() { } - - if (frame_parms[0]->frame_type==TDD) openair0_cfg[card].duplex_mode = duplex_mode_TDD; else //FDD openair0_cfg[card].duplex_mode = duplex_mode_FDD; printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card, - ((UE_flag==0) ? RC.eNB[0][0]->frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx), - ((UE_flag==0) ? RC.eNB[0][0]->frame_parms.nb_antennas_rx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx)); + RC.eNB[0][0]->frame_parms.nb_antennas_tx , + RC.eNB[0][0]->frame_parms.nb_antennas_rx ); openair0_cfg[card].Mod_id = 0; openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL; @@ -816,29 +675,25 @@ void init_openair0() { openair0_cfg[card].clock_source = clock_source; - openair0_cfg[card].tx_num_channels=min(2,((UE_flag==0) ? RC.eNB[0][0]->frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx)); - openair0_cfg[card].rx_num_channels=min(2,((UE_flag==0) ? RC.eNB[0][0]->frame_parms.nb_antennas_rx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx)); + openair0_cfg[card].tx_num_channels=min(2,RC.eNB[0][0]->frame_parms.nb_antennas_tx ); + openair0_cfg[card].rx_num_channels=min(2,RC.eNB[0][0]->frame_parms.nb_antennas_rx ); for (i=0; i<4; i++) { if (irx_total_gain_dB; - } - else { - openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB - rx_gain_off; - } + openair0_cfg[card].rx_gain[i] = RC.eNB[0][0]->rx_total_gain_dB; + openair0_cfg[card].configFilename = rf_config_file; printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n", @@ -847,7 +702,7 @@ void init_openair0() { openair0_cfg[card].tx_freq[i], openair0_cfg[card].rx_freq[i]); } - } + } /* for loop on cards */ } @@ -995,7 +850,6 @@ int restart_L1L2(module_id_t enb_id) msg_p = itti_alloc_new_message(TASK_ENB_APP, RRC_CONFIGURATION_REQ); RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[enb_id]->configuration; itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); - /* TODO XForms might need to be restarted, but it is currently (09/02/18) * broken, so we cannot test it */ @@ -1016,7 +870,7 @@ int restart_L1L2(module_id_t enb_id) } #endif -static inline void wait_nfapi_init(char *thread_name) { +static void wait_nfapi_init(char *thread_name) { printf( "waiting for NFAPI PNF connection and population of global structure (%s)\n",thread_name); pthread_mutex_lock( &nfapi_sync_mutex ); @@ -1038,9 +892,6 @@ int main( int argc, char **argv ) int CC_id; int ru_id; - uint8_t abstraction_flag=0; - uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2; - #if defined (XFORMS) int ret; #endif @@ -1055,8 +906,6 @@ int main( int argc, char **argv ) setvbuf(stderr, NULL, _IONBF, 0); #endif - PHY_VARS_UE *UE[MAX_NUM_CCs]; - mode = normal_txrx; memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS); @@ -1064,16 +913,12 @@ int main( int argc, char **argv ) set_latency_target(); - - // set default parameters - //if (UE_flag == 1) set_default_frame_parms(frame_parms); - logInit(); printf("Reading in command-line options\n"); get_options (); - if (CONFIG_ISFLAGSET(CONFIG_ABORT) && UE_flag == 0) { + if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) { fprintf(stderr,"Getting configuration failed\n"); exit(-1); } @@ -1088,32 +933,10 @@ int main( int argc, char **argv ) //randominit (0); set_taus_seed (0); - if (UE_flag==1) { - printf("configuring for UE\n"); + printf("configuring for RAU/RRU\n"); - set_comp_log(HW, LOG_DEBUG, LOG_HIGH, 1); - set_comp_log(PHY, LOG_INFO, LOG_HIGH, 1); - set_comp_log(MAC, LOG_INFO, LOG_HIGH, 1); - set_comp_log(RLC, LOG_INFO, LOG_HIGH | FLAG_THREAD, 1); - set_comp_log(PDCP, LOG_INFO, LOG_HIGH, 1); - set_comp_log(OTG, LOG_INFO, LOG_HIGH, 1); - set_comp_log(RRC, LOG_INFO, LOG_HIGH, 1); -#if defined(ENABLE_ITTI) - set_comp_log(EMU, LOG_INFO, LOG_MED, 1); -# if defined(ENABLE_USE_MME) - set_comp_log(NAS, LOG_INFO, LOG_HIGH, 1); -# endif -#endif - - } else { - printf("configuring for RAU/RRU\n"); - - } if (ouput_vcd) { - if (UE_flag==1) - VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_UE.vcd"); - else VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_eNB.vcd"); } @@ -1123,12 +946,7 @@ int main( int argc, char **argv ) cpuf=get_cpu_freq_GHz(); #if defined(ENABLE_ITTI) - - if (UE_flag == 1) { - log_set_instance_type (LOG_INSTANCE_UE); - } else { - log_set_instance_type (LOG_INSTANCE_ENB); - } + log_set_instance_type (LOG_INSTANCE_ENB); printf("ITTI init\n"); itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file); @@ -1172,82 +990,11 @@ int main( int argc, char **argv ) LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); - // init the parameters - for (CC_id=0; CC_idnb_antennas_tx = nb_antenna_tx; - frame_parms[CC_id]->nb_antennas_rx = nb_antenna_rx; - frame_parms[CC_id]->nb_antenna_ports_eNB = 1; //initial value overwritten by initial sync later - } - } printf("Before CC \n"); - for (CC_id=0; CC_idmac_enabled = 0; - else - UE[CC_id]->mac_enabled = 1; - - if (UE[CC_id]->mac_enabled == 0) { //set default UL parameters for testing mode - for (i=0; ipusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK; - UE[CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index = beta_RI; - UE[CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI; - - UE[CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = 0; - UE[CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(0%3); - UE[CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4; - } - } - - UE[CC_id]->UE_scan = UE_scan; - UE[CC_id]->UE_scan_carrier = UE_scan_carrier; - UE[CC_id]->mode = mode; - printf("UE[%d]->mode = %d\n",CC_id,mode); - - if (UE[CC_id]->mac_enabled == 1) { - UE[CC_id]->pdcch_vars[0][0]->crnti = 0x1234; - UE[CC_id]->pdcch_vars[1][0]->crnti = 0x1234; - }else { - UE[CC_id]->pdcch_vars[0][0]->crnti = 0x1235; - UE[CC_id]->pdcch_vars[1][0]->crnti = 0x1235; - } - UE[CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off; - UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id]; - - if (frame_parms[CC_id]->frame_type==FDD) { - UE[CC_id]->N_TA_offset = 0; - } - else { - if (frame_parms[CC_id]->N_RB_DL == 100) - UE[CC_id]->N_TA_offset = 624; - else if (frame_parms[CC_id]->N_RB_DL == 50) - UE[CC_id]->N_TA_offset = 624/2; - else if (frame_parms[CC_id]->N_RB_DL == 25) - UE[CC_id]->N_TA_offset = 624/4; - } - init_openair0(); - } - - } - printf("Runtime table\n"); fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx); cpuf=get_cpu_freq_GHz(); @@ -1296,22 +1043,13 @@ int main( int argc, char **argv ) #if defined(ENABLE_ITTI) - if ((UE_flag == 1)|| - (RC.nb_inst > 0)) { + if (RC.nb_inst > 0) { // don't create if node doesn't connect to RRC/S1/GTP - if (UE_flag == 0) { if (create_tasks(1) < 0) { printf("cannot create ITTI tasks\n"); exit(-1); // need a softer mode } - } - else { - if (create_tasks_ue(1) < 0) { - printf("cannot create ITTI tasks\n"); - exit(-1); // need a softer mode - } - } printf("ITTI tasks created\n"); } else { @@ -1343,7 +1081,6 @@ int main( int argc, char **argv ) if (do_forms==1) { fl_initialize (&argc, argv, NULL, 0, 0); - if (UE_flag==0) { form_stats_l2 = create_form_stats_form(); fl_show_form (form_stats_l2->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "l2 stats"); form_stats = create_form_stats_form(); @@ -1364,25 +1101,6 @@ int main( int argc, char **argv ) } } // CC_id } // UE_id - } else { - form_stats = create_form_stats_form(); - fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats"); - UE_id = 0; - form_ue[UE_id] = create_lte_phy_scope_ue(); - sprintf (title, "LTE DL SCOPE UE"); - fl_show_form (form_ue[UE_id]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); - - /* - if (openair_daq_vars.use_ia_receiver) { - fl_set_button(form_ue[UE_id]->button_0,1); - fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver ON"); - } else { - fl_set_button(form_ue[UE_id]->button_0,0); - fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF"); - }*/ - fl_set_button(form_ue[UE_id]->button_0,0); - fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF"); - } ret = pthread_create(&forms_thread, NULL, scope_thread, NULL); @@ -1427,23 +1145,7 @@ int main( int argc, char **argv ) printf("START MAIN THREADS\n"); // start the main threads - if (UE_flag == 1) { - int eMBMS_active = 0; - init_UE(1,eMBMS_active,uecap_xer_in,0); - if (phy_test==0) { - printf("Filling UE band info\n"); - fill_ue_band_info(); - dl_phy_sync_success (0, 0, 0, 1); - } - - number_of_cards = 1; - for(CC_id=0; CC_idrf_map.card=0; - PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+chain_offset; - } - } - else { number_of_cards = 1; printf("RC.nb_L1_inst:%d\n", RC.nb_L1_inst); if (RC.nb_L1_inst > 0) { @@ -1490,42 +1192,10 @@ int main( int argc, char **argv ) } printf("ALL RUs ready - ALL eNBs ready\n"); - } // connect the TX/RX buffers - if (UE_flag==1) { - - for (CC_id=0; CC_idhw_timing_advance = timing_advance; -#else - UE[CC_id]->hw_timing_advance = 160; -#endif - } - if (setup_ue_buffers(UE,&openair0_cfg[0])!=0) { - printf("Error setting up eNB buffer\n"); - exit(-1); - } - - - - if (input_fd) { - printf("Reading in from file to antenna buffer %d\n",0); - if (fread(UE[0]->common_vars.rxdata[0], - sizeof(int32_t), - frame_parms[0]->samples_per_tti*10, - input_fd) != frame_parms[0]->samples_per_tti*10) - printf("error reading from file\n"); - } - //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX; - } else { - - printf("eNB mode\n"); - - } + printf("Sending sync to all threads\n"); @@ -1564,10 +1234,6 @@ int main( int argc, char **argv ) fl_hide_form(form_stats->stats_form); fl_free_form(form_stats->stats_form); - if (UE_flag==1) { - fl_hide_form(form_ue[0]->lte_phy_scope_ue); - fl_free_form(form_ue[0]->lte_phy_scope_ue); - } else { fl_hide_form(form_stats_l2->stats_form); fl_free_form(form_stats_l2->stats_form); @@ -1577,7 +1243,6 @@ int main( int argc, char **argv ) fl_free_form(form_enb[CC_id][UE_id]->lte_phy_scope_enb); } } - } } #endif @@ -1585,8 +1250,6 @@ int main( int argc, char **argv ) printf("stopping MODEM threads\n"); // cleanup - if (UE_flag == 1) { - } else { stop_eNB(NB_eNB_INST); stop_RU(NB_RU); /* release memory used by the RU/eNB threads (incomplete), after all @@ -1601,7 +1264,6 @@ int main( int argc, char **argv ) phy_free_RU(RC.ru[inst]); } free_lte_top(); - } pthread_cond_destroy(&sync_cond); @@ -1613,11 +1275,7 @@ int main( int argc, char **argv ) pthread_mutex_destroy(&ue_pf_po_mutex); // *** Handle per CC_id openair0 - if (UE_flag==1) { - if (PHY_vars_UE_g[0][0]->rfdevice.trx_end_func) - PHY_vars_UE_g[0][0]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][0]->rfdevice); - } - else { + for(ru_id=0; ru_idrfdevice.trx_end_func) RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice); @@ -1625,7 +1283,6 @@ int main( int argc, char **argv ) RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice); } - } if (ouput_vcd) VCD_SIGNAL_DUMPER_CLOSE(); diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index 1d594caadc..e8b9d92490 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -129,10 +129,10 @@ {"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, u8ptr:&nb_antenna_tx, defuintval:1, TYPE_UINT8, 0}, \ {"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, iptr:&UE_scan_carrier, defintval:0, TYPE_INT, 0}, \ {"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:90, TYPE_INT, 0}, \ -{"r" , CONFIG_HLP_PRB, 0, u8ptr:&(frame_parms[0]->N_RB_DL), defintval:0, TYPE_UINT8, 0}, \ +{"r" , CONFIG_HLP_PRB, 0, u8ptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT8, 0}, \ } - +#define DEFAULT_DLF 2680000000 extern int16_t dlsch_demod_shift; /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* command line parameters common to eNodeB and UE */ @@ -155,12 +155,11 @@ extern int16_t dlsch_demod_shift; {"threadSlot1ProcTwo", NULL, 0, iptr:&(threads.slot1_proc_two), defintval:1, TYPE_INT, 0}, \ {"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ {"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ -{"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:2680000000, TYPE_UINT, 0}, \ +{"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:DEFAULT_DLF, TYPE_UINT, 0}, \ {"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \ {"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \ {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \ {"K" , CONFIG_HLP_ITTIL, PARAMFLAG_NOFREE, strptr:&itti_dump_file, defstrval:"/tmp/itti.dump", TYPE_STRING, 0}, \ -{"U" , CONFIG_HLP_UE, PARAMFLAG_BOOL, i8ptr:&UE_flag, defintval:0, TYPE_INT8, 0}, \ {"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ {"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ {"W" , CONFIG_HLP_L2MONW, 0, strptr:(char **)&in_ip, defstrval:"127.0.0.1", TYPE_STRING, sizeof(in_ip)}, \ diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c new file mode 100644 index 0000000000..ae4798f399 --- /dev/null +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -0,0 +1,1139 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file lte-enb.c + * \brief Top-level threads for eNodeB + * \author R. Knopp, F. Kaltenberger, Navid Nikaein + * \date 2012 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr + * \note + * \warning + */ + + +#define _GNU_SOURCE /* See feature_test_macros(7) */ +#include + + +#include "T.h" + +#include "rt_wrapper.h" + + +#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all + +#include "assertions.h" +#include "msc.h" + +#include "PHY/types.h" + +#include "PHY/defs.h" +#include "common/ran_context.h" +#include "common/config/config_userapi.h" +#include "common/utils/load_module_shlib.h" +#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all +//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all + +#include "../../ARCH/COMMON/common_lib.h" +#include "../../ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" + +//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all + +#include "PHY/vars.h" +#include "SCHED/vars.h" +#include "LAYER2/MAC/vars.h" + +#include "../../SIMU/USER/init_lte.h" + +#include "LAYER2/MAC/defs.h" +#include "LAYER2/MAC/vars.h" +#include "LAYER2/MAC/proto.h" +#include "RRC/LITE/vars.h" +#include "PHY_INTERFACE/vars.h" + +#ifdef SMBV +#include "PHY/TOOLS/smbv.h" +unsigned short config_frames[4] = {2,9,11,13}; +#endif +#include "UTIL/LOG/log_extern.h" +#include "UTIL/OTG/otg_tx.h" +#include "UTIL/OTG/otg_externs.h" +#include "UTIL/MATH/oml.h" +#include "UTIL/LOG/vcd_signal_dumper.h" +#include "UTIL/OPT/opt.h" +#include "enb_config.h" +//#include "PHY/TOOLS/time_meas.h" + +#ifndef OPENAIR2 +#include "UTIL/OTG/otg_vars.h" +#endif + +#if defined(ENABLE_ITTI) +#include "intertask_interface_init.h" +#include "create_tasks.h" +#endif + +#include "system.h" + +#ifdef XFORMS +#include "PHY/TOOLS/lte_phy_scope.h" +#include "stats.h" +#endif +#include "lte-softmodem.h" + +/* temporary compilation wokaround (UE/eNB split */ +uint16_t sf_ahead; +#ifdef XFORMS +// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0) +// at eNB 0, an UL scope for every UE +FD_lte_phy_scope_ue *form_ue[NUMBER_OF_UE_MAX]; +FD_lte_phy_scope_enb *form_enb[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; +FD_stats_form *form_stats=NULL,*form_stats_l2=NULL; +char title[255]; +unsigned char scope_enb_num_ue = 2; +static pthread_t forms_thread; //xforms +#endif //XFORMS + +pthread_cond_t sync_cond; +pthread_mutex_t sync_mutex; +int sync_var=-1; //!< protected by mutex \ref sync_mutex. +int config_sync_var=-1; + +uint16_t runtime_phy_rx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100] +uint16_t runtime_phy_tx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100] + +#if defined(ENABLE_ITTI) +volatile int start_eNB = 0; +volatile int start_UE = 0; +#endif +volatile int oai_exit = 0; + +static clock_source_t clock_source = internal; +static int wait_for_sync = 0; + +unsigned int mmapped_dma=0; +int single_thread_flag=1; + +static int8_t threequarter_fs=0; + +uint32_t downlink_frequency[MAX_NUM_CCs][4]; +int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; + + + +#if defined(ENABLE_ITTI) +static char *itti_dump_file = NULL; +#endif + +int UE_scan = 1; +int UE_scan_carrier = 0; +runmode_t mode = normal_txrx; + +FILE *input_fd=NULL; + + +#if MAX_NUM_CCs == 1 +rx_gain_t rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain}}; +double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0}}; +double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0}}; +#else +rx_gain_t rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain},{max_gain,max_gain,max_gain,max_gain}}; +double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0},{20,0,0,0}}; +double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0},{20,0,0,0}}; +#endif + +double rx_gain_off = 0.0; + +double sample_rate=30.72e6; +double bw = 10.0e6; + +static int tx_max_power[MAX_NUM_CCs]; /* = {0,0}*/; + +char rf_config_file[1024]; + +int chain_offset=0; +int phy_test = 0; +uint8_t usim_test = 0; + +uint8_t dci_Format = 0; +uint8_t agregation_Level =0xFF; + +uint8_t nb_antenna_tx = 1; +uint8_t nb_antenna_rx = 1; + +char ref[128] = "internal"; +char channels[128] = "0"; + +int rx_input_level_dBm; + +#ifdef XFORMS +extern int otg_enabled; +static char do_forms=0; +#else +int otg_enabled; +#endif +//int number_of_cards = 1; + + +static LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; +uint32_t target_dl_mcs = 28; //maximum allowed mcs +uint32_t target_ul_mcs = 20; +uint32_t timing_advance = 0; +uint8_t exit_missed_slots=1; +uint64_t num_missed_slots=0; // counter for the number of missed slots + + +extern void reset_opp_meas(void); +extern void print_opp_meas(void); + +extern PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, + uint8_t UE_id, + uint8_t abstraction_flag); + + +int transmission_mode=1; + + + +/* struct for ethernet specific parameters given in eNB conf file */ +eth_params_t *eth_params; + +openair0_config_t openair0_cfg[MAX_CARDS]; + +double cpuf; + +extern char uecap_xer[1024]; +char uecap_xer_in=0; + +int oaisim_flag=0; +threads_t threads= {-1,-1,-1,-1,-1,-1,-1}; + +/* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed + * this is very hackish - find a proper solution + */ +uint8_t abstraction_flag=0; + +/* forward declarations */ +void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]); + +/*---------------------BMC: timespec helpers -----------------------------*/ + +struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; +struct timespec max_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; + +struct timespec clock_difftime(struct timespec start, struct timespec end) { + struct timespec temp; + if ((end.tv_nsec-start.tv_nsec)<0) { + temp.tv_sec = end.tv_sec-start.tv_sec-1; + temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec; + } else { + temp.tv_sec = end.tv_sec-start.tv_sec; + temp.tv_nsec = end.tv_nsec-start.tv_nsec; + } + return temp; +} + +void print_difftimes(void) { +#ifdef DEBUG + printf("difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec); +#else + LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec); +#endif +} + +void update_difftimes(struct timespec start, struct timespec end) { + struct timespec diff_time = { .tv_sec = 0, .tv_nsec = 0 }; + int changed = 0; + diff_time = clock_difftime(start, end); + if ((min_diff_time.tv_nsec == 0) || (diff_time.tv_nsec < min_diff_time.tv_nsec)) { + min_diff_time.tv_nsec = diff_time.tv_nsec; + changed = 1; + } + if ((max_diff_time.tv_nsec == 0) || (diff_time.tv_nsec > max_diff_time.tv_nsec)) { + max_diff_time.tv_nsec = diff_time.tv_nsec; + changed = 1; + } +#if 1 + if (changed) print_difftimes(); +#endif +} + +/*------------------------------------------------------------------------*/ + +unsigned int build_rflocal(int txi, int txq, int rxi, int rxq) { + return (txi + (txq<<6) + (rxi<<12) + (rxq<<18)); +} +unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe) { + return (dcoff_i_rxfe + (dcoff_q_rxfe<<8)); +} + +#if !defined(ENABLE_ITTI) +void signal_handler(int sig) { + void *array[10]; + size_t size; + + if (sig==SIGSEGV) { + // get void*'s for all entries on the stack + size = backtrace(array, 10); + + // print out all the frames to stderr + fprintf(stderr, "Error: signal %d:\n", sig); + backtrace_symbols_fd(array, size, 2); + exit(-1); + } else { + printf("trying to exit gracefully...\n"); + oai_exit = 1; + } +} +#endif +#define KNRM "\x1B[0m" +#define KRED "\x1B[31m" +#define KGRN "\x1B[32m" +#define KBLU "\x1B[34m" +#define RESET "\033[0m" + + + +void exit_fun(const char* s) +{ + int CC_id; + + if (s != NULL) { + printf("%s %s() Exiting OAI softmodem: %s\n",__FILE__, __FUNCTION__, s); + } + + oai_exit = 1; + + for(CC_id=0; CC_idrfdevice.trx_end_func) + PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][CC_id]->rfdevice); + } + +#if defined(ENABLE_ITTI) + sleep(1); //allow lte-softmodem threads to exit first + itti_terminate_tasks (TASK_UNKNOWN); +#endif +} + +#ifdef XFORMS + + +void reset_stats(FL_OBJECT *button, long arg) +{ + int i,j,k; + PHY_VARS_eNB *phy_vars_eNB = RC.eNB[0][0]; + + for (i=0; idlsch[i][0]->Mlimit; j++) { + phy_vars_eNB->UE_stats[i].dlsch_NAK[k][j]=0; + phy_vars_eNB->UE_stats[i].dlsch_ACK[k][j]=0; + phy_vars_eNB->UE_stats[i].dlsch_trials[k][j]=0; + } + + phy_vars_eNB->UE_stats[i].dlsch_l2_errors[k]=0; + phy_vars_eNB->UE_stats[i].ulsch_errors[k]=0; + phy_vars_eNB->UE_stats[i].ulsch_consecutive_errors=0; + + + phy_vars_eNB->UE_stats[i].dlsch_sliding_cnt=0; + phy_vars_eNB->UE_stats[i].dlsch_NAK_round0=0; + phy_vars_eNB->UE_stats[i].dlsch_mcs_offset=0; + } + } +} + +static void *scope_thread(void *arg) { + char stats_buffer[16384]; +# ifdef ENABLE_XFORMS_WRITE_STATS + FILE *UE_stats, *eNB_stats; +# endif + struct sched_param sched_param; + + + sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1; + sched_setscheduler(0, SCHED_FIFO,&sched_param); + + printf("Scope thread has priority %d\n",sched_param.sched_priority); + +# ifdef ENABLE_XFORMS_WRITE_STATS + + UE_stats = fopen("UE_stats.txt", "w"); + +#endif + + while (!oai_exit) { + dump_ue_stats (PHY_vars_UE_g[0][0], &PHY_vars_UE_g[0][0]->proc.proc_rxtx[0],stats_buffer, 0, mode,rx_input_level_dBm); + //fl_set_object_label(form_stats->stats_text, stats_buffer); + fl_clear_browser(form_stats->stats_text); + fl_add_browser_line(form_stats->stats_text, stats_buffer); + + phy_scope_UE(form_ue[0], + PHY_vars_UE_g[0][0], + 0, + 0,7); + + // printf("%s",stats_buffer); + } +# ifdef ENABLE_XFORMS_WRITE_STATS + + if (UE_stats) { + rewind (UE_stats); + fwrite (stats_buffer, 1, len, UE_stats); + fclose (UE_stats); + } + +# endif + + pthread_exit((void*)arg); +} +#endif + + + +#if defined(ENABLE_ITTI) +void *l2l1_task(void *arg) { + MessageDef *message_p = NULL; + int result; + + itti_set_task_real_time(TASK_L2L1); + itti_mark_task_ready(TASK_L2L1); + + + do { + // Wait for a message + itti_receive_msg (TASK_L2L1, &message_p); + + switch (ITTI_MSG_ID(message_p)) { + case TERMINATE_MESSAGE: + oai_exit=1; + itti_exit_task (); + break; + + case ACTIVATE_MESSAGE: + start_UE = 1; + break; + + case DEACTIVATE_MESSAGE: + start_UE = 0; + break; + + case MESSAGE_TEST: + LOG_I(EMU, "Received %s\n", ITTI_MSG_NAME(message_p)); + break; + + default: + LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p)); + break; + } + + result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + } while(!oai_exit); + + return NULL; +} +#endif + + +static void get_options(void) { + int CC_id; + int tddflag, nonbiotflag; + char *loopfile=NULL; + int dumpframe; + uint32_t online_log_messages; + uint32_t glog_level, glog_verbosity; + uint32_t start_telnetsrv; + + paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ; + paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ; + + set_default_frame_parms(frame_parms); + config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); + + if (strlen(in_path) > 0) { + opt_type = OPT_PCAP; + opt_enabled=1; + printf("Enabling OPT for PCAP with the following file %s \n",in_path); + } + if (strlen(in_ip) > 0) { + opt_enabled=1; + opt_type = OPT_WIRESHARK; + printf("Enabling OPT for wireshark for local interface"); + } + + config_process_cmdline( cmdline_logparams,sizeof(cmdline_logparams)/sizeof(paramdef_t),NULL); + if(config_isparamset(cmdline_logparams,CMDLINE_ONLINELOG_IDX)) { + set_glog_onlinelog(online_log_messages); + } + if(config_isparamset(cmdline_logparams,CMDLINE_GLOGLEVEL_IDX)) { + set_glog(glog_level, -1); + } + if(config_isparamset(cmdline_logparams,CMDLINE_GLOGVERBO_IDX)) { + set_glog(-1, glog_verbosity); + } + if (start_telnetsrv) { + load_module_shlib("telnetsrv",NULL,0); + } + + paramdef_t cmdline_uemodeparams[] =CMDLINE_UEMODEPARAMS_DESC; + paramdef_t cmdline_ueparams[] =CMDLINE_UEPARAMS_DESC; + + + config_process_cmdline( cmdline_uemodeparams,sizeof(cmdline_uemodeparams)/sizeof(paramdef_t),NULL); + config_process_cmdline( cmdline_ueparams,sizeof(cmdline_ueparams)/sizeof(paramdef_t),NULL); + if (loopfile != NULL) { + printf("Input file for hardware emulation: %s",loopfile); + mode=loop_through_memory; + input_fd = fopen(loopfile,"r"); + AssertFatal(input_fd != NULL,"Please provide a valid input file\n"); + } + + if ( (cmdline_uemodeparams[CMDLINE_CALIBUERX_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue; + if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXMED_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_med; + if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXBYP_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_byp; + if (cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].uptr) + if ( *(cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].uptr) > 0) mode = debug_prach; + if (cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr) + if ( *(cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr) > 0) mode = no_L2_connect; + if (cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr) + if ( *(cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr) > 0) mode = calib_prach_tx; + if (dumpframe > 0) mode = rx_dump_frame; + + for (CC_id=0; CC_iddl_CarrierFreq = downlink_frequency[0][0]; + } + UE_scan=0; + + + if (tddflag > 0) { + for (CC_id=0; CC_idframe_type = TDD; + } + + if (frame_parms[0]->N_RB_DL !=0) { + if ( frame_parms[0]->N_RB_DL < 6 ) { + frame_parms[0]->N_RB_DL = 6; + printf ( "%i: Invalid number of ressource blocks, adjusted to 6\n",frame_parms[0]->N_RB_DL); + } + if ( frame_parms[0]->N_RB_DL > 100 ) { + frame_parms[0]->N_RB_DL = 100; + printf ( "%i: Invalid number of ressource blocks, adjusted to 100\n",frame_parms[0]->N_RB_DL); + } + if ( frame_parms[0]->N_RB_DL > 50 && frame_parms[0]->N_RB_DL < 100 ) { + frame_parms[0]->N_RB_DL = 50; + printf ( "%i: Invalid number of ressource blocks, adjusted to 50\n",frame_parms[0]->N_RB_DL); + } + if ( frame_parms[0]->N_RB_DL > 25 && frame_parms[0]->N_RB_DL < 50 ) { + frame_parms[0]->N_RB_DL = 25; + printf ( "%i: Invalid number of ressource blocks, adjusted to 25\n",frame_parms[0]->N_RB_DL); + } + UE_scan = 0; + frame_parms[0]->N_RB_UL=frame_parms[0]->N_RB_DL; + for (CC_id=1; CC_idN_RB_DL=frame_parms[0]->N_RB_DL; + frame_parms[CC_id]->N_RB_UL=frame_parms[0]->N_RB_UL; + } + } + + + for (CC_id=1;CC_idframe_type = FDD; + frame_parms[CC_id]->tdd_config = 3; + frame_parms[CC_id]->tdd_config_S = 0; + frame_parms[CC_id]->N_RB_DL = 100; + frame_parms[CC_id]->N_RB_UL = 100; + frame_parms[CC_id]->Ncp = NORMAL; + frame_parms[CC_id]->Ncp_UL = NORMAL; + frame_parms[CC_id]->Nid_cell = 0; + frame_parms[CC_id]->num_MBSFN_config = 0; + frame_parms[CC_id]->nb_antenna_ports_eNB = 1; + frame_parms[CC_id]->nb_antennas_tx = 1; + frame_parms[CC_id]->nb_antennas_rx = 1; + + frame_parms[CC_id]->nushift = 0; + + frame_parms[CC_id]->phich_config_common.phich_resource = oneSixth; + frame_parms[CC_id]->phich_config_common.phich_duration = normal; + // UL RS Config + frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = 0;//n_DMRS1 set to 0 + frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 0; + frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0; + frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0; + + frame_parms[CC_id]->prach_config_common.rootSequenceIndex=22; + frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=1; + frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0; + frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.highSpeedFlag=0; + frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset=0; + + downlink_frequency[CC_id][0] = DEFAULT_DLF; // Use float to avoid issue with frequency over 2^31. + downlink_frequency[CC_id][1] = downlink_frequency[CC_id][0]; + downlink_frequency[CC_id][2] = downlink_frequency[CC_id][0]; + downlink_frequency[CC_id][3] = downlink_frequency[CC_id][0]; + + frame_parms[CC_id]->dl_CarrierFreq=downlink_frequency[CC_id][0]; + + } + +} + +void init_openair0(void) { + + int card; + int i; + + for (card=0; cardN_RB_DL == 100) { + if (frame_parms[0]->threequarter_fs) { + openair0_cfg[card].sample_rate=23.04e6; + openair0_cfg[card].samples_per_frame = 230400; + openair0_cfg[card].tx_bw = 10e6; + openair0_cfg[card].rx_bw = 10e6; + } else { + openair0_cfg[card].sample_rate=30.72e6; + openair0_cfg[card].samples_per_frame = 307200; + openair0_cfg[card].tx_bw = 10e6; + openair0_cfg[card].rx_bw = 10e6; + } + } else if(frame_parms[0]->N_RB_DL == 50) { + openair0_cfg[card].sample_rate=15.36e6; + openair0_cfg[card].samples_per_frame = 153600; + openair0_cfg[card].tx_bw = 5e6; + openair0_cfg[card].rx_bw = 5e6; + } else if (frame_parms[0]->N_RB_DL == 25) { + openair0_cfg[card].sample_rate=7.68e6; + openair0_cfg[card].samples_per_frame = 76800; + openair0_cfg[card].tx_bw = 2.5e6; + openair0_cfg[card].rx_bw = 2.5e6; + } else if (frame_parms[0]->N_RB_DL == 6) { + openair0_cfg[card].sample_rate=1.92e6; + openair0_cfg[card].samples_per_frame = 19200; + openair0_cfg[card].tx_bw = 1.5e6; + openair0_cfg[card].rx_bw = 1.5e6; + } + + + + + if (frame_parms[0]->frame_type==TDD) + openair0_cfg[card].duplex_mode = duplex_mode_TDD; + else //FDD + openair0_cfg[card].duplex_mode = duplex_mode_FDD; + + printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card, + PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx, + PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx); + openair0_cfg[card].Mod_id = 0; + + openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL; + + openair0_cfg[card].clock_source = clock_source; + + + openair0_cfg[card].tx_num_channels=min(2,PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx); + openair0_cfg[card].rx_num_channels=min(2,PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx); + + for (i=0; i<4; i++) { + + if (irx_total_gain_dB - rx_gain_off; + + + openair0_cfg[card].configFilename = rf_config_file; + printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n", + card,i, openair0_cfg[card].tx_gain[i], + openair0_cfg[card].rx_gain[i], + openair0_cfg[card].tx_freq[i], + openair0_cfg[card].rx_freq[i]); + } + } +} + + + + +#if defined(ENABLE_ITTI) +/* + * helper function to terminate a certain ITTI task + */ +void terminate_task(task_id_t task_id, module_id_t mod_id) +{ + LOG_I(ENB_APP, "sending TERMINATE_MESSAGE to task %s (%d)\n", itti_get_task_name(task_id), task_id); + MessageDef *msg; + msg = itti_alloc_new_message (ENB_APP, TERMINATE_MESSAGE); + itti_send_msg_to_task (task_id, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); +} + + + +#endif + +int main( int argc, char **argv ) +{ + int i; +#if defined (XFORMS) + void *status; +#endif + + int CC_id; + uint8_t abstraction_flag=0; + uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2; + +#if defined (XFORMS) + int ret; +#endif + + start_background_system(); + if ( load_configmodule(argc,argv) == NULL) { + exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); + } + +#ifdef DEBUG_CONSOLE + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); +#endif + + PHY_VARS_UE *UE[MAX_NUM_CCs]; + + mode = normal_txrx; + memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS); + + memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs); + + set_latency_target(); + + logInit(); + + printf("Reading in command-line options\n"); + + get_options (); + + +#if T_TRACER + T_init(T_port, 1-T_nowait, T_dont_fork); +#endif + + + + //randominit (0); + set_taus_seed (0); + + + set_comp_log(HW, LOG_DEBUG, LOG_HIGH, 1); + set_comp_log(PHY, LOG_INFO, LOG_HIGH, 1); + set_comp_log(MAC, LOG_INFO, LOG_HIGH, 1); + set_comp_log(RLC, LOG_INFO, LOG_HIGH | FLAG_THREAD, 1); + set_comp_log(PDCP, LOG_INFO, LOG_HIGH, 1); + set_comp_log(OTG, LOG_INFO, LOG_HIGH, 1); + set_comp_log(RRC, LOG_INFO, LOG_HIGH, 1); +#if defined(ENABLE_ITTI) + set_comp_log(EMU, LOG_INFO, LOG_MED, 1); +# if defined(ENABLE_USE_MME) + set_comp_log(NAS, LOG_INFO, LOG_HIGH, 1); +# endif +#endif + + + if (ouput_vcd) { + VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_UE.vcd"); + } + + cpuf=get_cpu_freq_GHz(); + +#if defined(ENABLE_ITTI) + + log_set_instance_type (LOG_INSTANCE_UE); + + + printf("ITTI init\n"); + itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file); + + // initialize mscgen log after ITTI + MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX); +#endif + + if (opt_type != OPT_NONE) { + radio_type_t radio_type; + + if (frame_parms[0]->frame_type == FDD) + radio_type = RADIO_TYPE_FDD; + else + radio_type = RADIO_TYPE_TDD; + + if (init_opt(in_path, in_ip, NULL, radio_type) == -1) + LOG_E(OPT,"failed to run OPT \n"); + } + +#ifdef PDCP_USE_NETLINK + printf("PDCP netlink\n"); + netlink_init(); +#if defined(PDCP_USE_NETLINK_QUEUES) + pdcp_netlink_init(); +#endif +#endif + +#if !defined(ENABLE_ITTI) + // to make a graceful exit when ctrl-c is pressed + signal(SIGSEGV, signal_handler); + signal(SIGINT, signal_handler); +#endif + + + check_clock(); + +#ifndef PACKAGE_VERSION +# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" +#endif + + LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); + + // init the parameters + for (CC_id=0; CC_idnb_antennas_tx = nb_antenna_tx; + frame_parms[CC_id]->nb_antennas_rx = nb_antenna_rx; + frame_parms[CC_id]->nb_antenna_ports_eNB = 1; //initial value overwritten by initial sync later + } + + + + printf("Before CC \n"); + + for (CC_id=0; CC_idmac_enabled = 0; + else + UE[CC_id]->mac_enabled = 1; + + if (UE[CC_id]->mac_enabled == 0) { //set default UL parameters for testing mode + for (i=0; ipusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK; + UE[CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index = beta_RI; + UE[CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI; + + UE[CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = 0; + UE[CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(0%3); + UE[CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4; + } + } + + UE[CC_id]->UE_scan = UE_scan; + UE[CC_id]->UE_scan_carrier = UE_scan_carrier; + UE[CC_id]->mode = mode; + printf("UE[%d]->mode = %d\n",CC_id,mode); + + if (UE[CC_id]->mac_enabled == 1) { + UE[CC_id]->pdcch_vars[0][0]->crnti = 0x1234; + UE[CC_id]->pdcch_vars[1][0]->crnti = 0x1234; + }else { + UE[CC_id]->pdcch_vars[0][0]->crnti = 0x1235; + UE[CC_id]->pdcch_vars[1][0]->crnti = 0x1235; + } + UE[CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off; + UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id]; + + if (frame_parms[CC_id]->frame_type==FDD) { + UE[CC_id]->N_TA_offset = 0; + } + else { + if (frame_parms[CC_id]->N_RB_DL == 100) + UE[CC_id]->N_TA_offset = 624; + else if (frame_parms[CC_id]->N_RB_DL == 50) + UE[CC_id]->N_TA_offset = 624/2; + else if (frame_parms[CC_id]->N_RB_DL == 25) + UE[CC_id]->N_TA_offset = 624/4; + + } + init_openair0(); + } + + printf("Runtime table\n"); + fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx); + cpuf=get_cpu_freq_GHz(); + + + +#ifndef DEADLINE_SCHEDULER + + printf("NO deadline scheduler\n"); + /* Currently we set affinity for UHD to CPU 0 for eNB/UE and only if number of CPUS >2 */ + + cpu_set_t cpuset; + int s; + char cpu_affinity[1024]; + CPU_ZERO(&cpuset); +#ifdef CPU_AFFINITY + if (get_nprocs() > 2) { + CPU_SET(0, &cpuset); + s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + if (s != 0) { + perror( "pthread_setaffinity_np"); + exit_fun("Error setting processor affinity"); + } + LOG_I(HW, "Setting the affinity of main function to CPU 0, for device library to use CPU 0 only!\n"); + } +#endif + + /* Check the actual affinity mask assigned to the thread */ + s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + if (s != 0) { + perror( "pthread_getaffinity_np"); + exit_fun("Error getting processor affinity "); + } + memset(cpu_affinity, 0 , sizeof(cpu_affinity)); + for (int j = 0; j < CPU_SETSIZE; j++) { + if (CPU_ISSET(j, &cpuset)) { + char temp[1024]; + sprintf(temp, " CPU_%d ", j); + strcat(cpu_affinity, temp); + } + } + LOG_I(HW, "CPU Affinity of main() function is... %s\n", cpu_affinity); +#endif + + + + +#if defined(ENABLE_ITTI) + if (create_tasks_ue(1) < 0) { + printf("cannot create ITTI tasks\n"); + exit(-1); // need a softer mode + } + printf("ITTI tasks created\n"); +#endif + + // init UE_PF_PO and mutex lock + pthread_mutex_init(&ue_pf_po_mutex, NULL); + memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs); + + mlockall(MCL_CURRENT | MCL_FUTURE); + + pthread_cond_init(&sync_cond,NULL); + pthread_mutex_init(&sync_mutex, NULL); + +#ifdef XFORMS + int UE_id; + + printf("XFORMS\n"); + + if (do_forms==1) { + fl_initialize (&argc, argv, NULL, 0, 0); + + form_stats = create_form_stats_form(); + fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats"); + UE_id = 0; + form_ue[UE_id] = create_lte_phy_scope_ue(); + sprintf (title, "LTE DL SCOPE UE"); + fl_show_form (form_ue[UE_id]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); + + /* + if (openair_daq_vars.use_ia_receiver) { + fl_set_button(form_ue[UE_id]->button_0,1); + fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver ON"); + } else { + fl_set_button(form_ue[UE_id]->button_0,0); + fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF"); + }*/ + fl_set_button(form_ue[UE_id]->button_0,0); + fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF"); + ret = pthread_create(&forms_thread, NULL, scope_thread, NULL); + + if (ret == 0) + pthread_setname_np( forms_thread, "xforms" ); + + printf("Scope thread created, ret=%d\n",ret); + } + +#endif + + rt_sleep_ns(10*100000000ULL); + + // start the main threads + int eMBMS_active = 0; + init_UE(1,eMBMS_active,uecap_xer_in,0); + + if (phy_test==0) { + printf("Filling UE band info\n"); + fill_ue_band_info(); + dl_phy_sync_success (0, 0, 0, 1); + } + + number_of_cards = 1; + for(CC_id=0; CC_idrf_map.card=0; + PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+chain_offset; + } + + + + // connect the TX/RX buffers + + for (CC_id=0; CC_idhw_timing_advance = timing_advance; +#else + UE[CC_id]->hw_timing_advance = 160; +#endif + } + if (setup_ue_buffers(UE,&openair0_cfg[0])!=0) { + printf("Error setting up eNB buffer\n"); + exit(-1); + } + + + + if (input_fd) { + printf("Reading in from file to antenna buffer %d\n",0); + if (fread(UE[0]->common_vars.rxdata[0], + sizeof(int32_t), + frame_parms[0]->samples_per_tti*10, + input_fd) != frame_parms[0]->samples_per_tti*10) + printf("error reading from file\n"); + } + //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX; + + printf("Sending sync to all threads\n"); + + pthread_mutex_lock(&sync_mutex); + 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 TO TERMINATE\n"); + //getchar(); + +#if defined(ENABLE_ITTI) + printf("Entering ITTI signals handler\n"); + itti_wait_tasks_end(); + printf("Returned from ITTI signal handler\n"); + oai_exit=1; + printf("oai_exit=%d\n",oai_exit); +#else + + while (oai_exit==0) + rt_sleep_ns(100000000ULL); + printf("Terminating application - oai_exit=%d\n",oai_exit); + +#endif + + // stop threads +#ifdef XFORMS + printf("waiting for XFORMS thread\n"); + + if (do_forms==1) { + pthread_join(forms_thread,&status); + fl_hide_form(form_stats->stats_form); + fl_free_form(form_stats->stats_form); + fl_hide_form(form_ue[0]->lte_phy_scope_ue); + fl_free_form(form_ue[0]->lte_phy_scope_ue); + } + +#endif + + printf("stopping MODEM threads\n"); + + pthread_cond_destroy(&sync_cond); + pthread_mutex_destroy(&sync_mutex); + + pthread_mutex_destroy(&ue_pf_po_mutex); + + // *** Handle per CC_id openair0 + if (PHY_vars_UE_g[0][0]->rfdevice.trx_end_func) + PHY_vars_UE_g[0][0]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][0]->rfdevice); + + if (ouput_vcd) + VCD_SIGNAL_DUMPER_CLOSE(); + + if (opt_enabled == 1) + terminate_opt(); + + logClean(); + + printf("Bye.\n"); + + return 0; +} From da50d68b060d16401d8ce604f2c09335dc063db1 Mon Sep 17 00:00:00 2001 From: oai Date: Thu, 8 Mar 2018 15:56:51 +0100 Subject: [PATCH 179/195] more NB-IoT integration --- cmake_targets/CMakeLists.txt | 17 +- cmake_targets/tools/fix_asn1 | 1 + .../SystemInformation-NB-r13-IEs.h.diff | 47 + common/ran_context.h | 6 +- nfapi/oai_integration/nfapi_pnf.h | 2 +- openair1/PHY/CODING/defs_NB_IoT.h | 275 ++++ openair1/PHY/INIT/defs_NB_IoT.h | 77 + openair1/PHY/LTE_REFSIG/defs_NB_IoT.h | 60 + openair1/PHY/LTE_TRANSPORT/dci_NB_IoT.h | 292 ++++ openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h | 787 +++++++++ .../PHY/LTE_TRANSPORT/dlsch_llr_computation.c | 2 +- openair1/PHY/LTE_TRANSPORT/proto_NB_IoT.h | 362 +++++ openair1/PHY/LTE_TRANSPORT/uci_NB_IoT.h | 324 ++++ openair1/PHY/TOOLS/lte_phy_scope.c | 4 +- openair1/PHY/defs_L1_NB_IoT.h | 1031 ++++++++++++ openair1/PHY/impl_defs_lte_NB_IoT.h | 813 ++++++++++ openair1/PHY/impl_defs_top_NB_IoT.h | 541 +++++++ openair1/PHY/types_NB_IoT.h | 32 + openair1/SCHED/prach_procedures.c | 1 + openair2/COMMON/platform_constants.h | 4 + openair2/COMMON/rrc_messages_def.h | 1 + openair2/COMMON/rrc_messages_types.h | 73 + openair2/COMMON/tasks_def.h | 4 + .../{nbiot_config.c => NB_IoT_config.c} | 13 +- .../{nbiot_config.h => NB_IoT_config.h} | 0 openair2/ENB_APP/NB_IoT_interface.c | 58 + openair2/ENB_APP/NB_IoT_interface.h | 50 + .../{nbiot_paramdef.h => NB_IoT_paramdef.h} | 0 openair2/LAYER2/MAC/config_NB_IoT.h | 301 ++++ openair2/LAYER2/MAC/defs_NB_IoT.h | 543 +++++++ openair2/LAYER2/MAC/proto_NB_IoT.h | 198 +++ openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 40 +- openair2/PHY_INTERFACE/IF_Module_NB_IoT.h | 215 +++ openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.c | 1417 +++++++++++++++++ openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.h | 293 ++++ openair2/RRC/LITE/defs_NB_IoT.h | 570 +++++++ openair2/RRC/LITE/extern_NB_IoT.h | 63 + openair2/RRC/LITE/proto.h | 2 + openair2/RRC/LITE/proto_NB_IoT.h | 260 +++ openair2/RRC/LITE/rrc_types_NB_IoT.h | 64 + openair3/GTPV1-U/gtpv1u_eNB.c | 3 +- targets/COMMON/openairinterface5g_limits.h | 1 - targets/RT/USER/lte-softmodem.c | 10 +- 43 files changed, 8800 insertions(+), 57 deletions(-) create mode 100644 cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-NB-r13-IEs.h.diff create mode 100644 openair1/PHY/CODING/defs_NB_IoT.h create mode 100644 openair1/PHY/INIT/defs_NB_IoT.h create mode 100644 openair1/PHY/LTE_REFSIG/defs_NB_IoT.h create mode 100644 openair1/PHY/LTE_TRANSPORT/dci_NB_IoT.h create mode 100644 openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h create mode 100644 openair1/PHY/LTE_TRANSPORT/proto_NB_IoT.h create mode 100644 openair1/PHY/LTE_TRANSPORT/uci_NB_IoT.h create mode 100644 openair1/PHY/defs_L1_NB_IoT.h create mode 100644 openair1/PHY/impl_defs_lte_NB_IoT.h create mode 100644 openair1/PHY/impl_defs_top_NB_IoT.h create mode 100644 openair1/PHY/types_NB_IoT.h rename openair2/ENB_APP/{nbiot_config.c => NB_IoT_config.c} (98%) rename openair2/ENB_APP/{nbiot_config.h => NB_IoT_config.h} (100%) create mode 100644 openair2/ENB_APP/NB_IoT_interface.c create mode 100644 openair2/ENB_APP/NB_IoT_interface.h rename openair2/ENB_APP/{nbiot_paramdef.h => NB_IoT_paramdef.h} (100%) create mode 100644 openair2/LAYER2/MAC/config_NB_IoT.h create mode 100644 openair2/LAYER2/MAC/defs_NB_IoT.h create mode 100644 openair2/LAYER2/MAC/proto_NB_IoT.h create mode 100644 openair2/PHY_INTERFACE/IF_Module_NB_IoT.h create mode 100644 openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.c create mode 100644 openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.h create mode 100644 openair2/RRC/LITE/defs_NB_IoT.h create mode 100644 openair2/RRC/LITE/extern_NB_IoT.h create mode 100644 openair2/RRC/LITE/proto_NB_IoT.h create mode 100644 openair2/RRC/LITE/rrc_types_NB_IoT.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index a0ee33dc78..a22babc33f 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -314,7 +314,8 @@ file(GLOB rrc_h ${RRC_FULL_DIR}/*.h) set(rrc_h ${rrc_h} ${RRC_FULL_DIR}/asn1_constants.h) set_source_files_properties(${rrc_source} PROPERTIES COMPILE_FLAGS -w) # suppress warnings from generated code add_library(RRC_LIB ${rrc_h} ${rrc_source} - ${OPENAIR2_DIR}/RRC/LITE/MESSAGES/asn1_msg.c) + ${OPENAIR2_DIR}/RRC/LITE/MESSAGES/asn1_msg.c + ${OPENAIR2_DIR}/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.c) include_directories ("${RRC_FULL_DIR}") # add the command to generate the source code @@ -1717,6 +1718,17 @@ if(NAS_UE) endif() +# nbiot +add_definitions("-DNUMBER_OF_UE_MAX_NB_IoT=16") +set (NBIOT_SOURCES + ${OPENAIR2_DIR}/ENB_APP/NB_IoT_config.c +) +add_library(NB_IoT MODULE ${NBIOT_SOURCES} ) + +# shared library loader +set (SHLIB_LOADER_SOURCES + ${OPENAIR_DIR}/common/utils/load_module_shlib.c +) # Make lfds as a own source code (even if it is a outside library) # For better intergration with compilation flags & structure of cmake @@ -1789,6 +1801,7 @@ include_directories("${NFAPI_DIR}/nfapi/inc") include_directories("${NFAPI_DIR}/sim_common/inc") include_directories("${NFAPI_DIR}/pnf_sim/inc") + # System packages that are required # We use either the cmake buildin, in ubuntu are in: /usr/share/cmake*/Modules/ # or cmake provide a generic interface to pkg-config that widely used @@ -1947,6 +1960,7 @@ add_executable(lte-softmodem ${OPENAIR_TARGETS}/RT/USER/lte-enb.c ${OPENAIR_TARGETS}/RT/USER/lte-ru.c ${OPENAIR_TARGETS}/RT/USER/lte-softmodem.c + ${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c ${OPENAIR_TARGETS}/COMMON/create_tasks.c @@ -1985,6 +1999,7 @@ add_executable(lte-softmodem-nos1 ${OPENAIR_TARGETS}/RT/USER/lte-enb.c ${OPENAIR_TARGETS}/RT/USER/lte-ru.c ${OPENAIR_TARGETS}/RT/USER/lte-softmodem.c + ${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c ${OPENAIR_TARGETS}/COMMON/create_tasks.c diff --git a/cmake_targets/tools/fix_asn1 b/cmake_targets/tools/fix_asn1 index 5cdab5ffd8..fe819c2716 100755 --- a/cmake_targets/tools/fix_asn1 +++ b/cmake_targets/tools/fix_asn1 @@ -5,6 +5,7 @@ RRC_Rel14=( "SystemInformation-r8-IEs.h" 4df485c5ddf2540eca271876cdc512caa19b0890 "fix_asn1.data/RRC.rel14/SystemInformation-r8-IEs.h.diff" + "SystemInformation-NB-r13-IEs.h" 6d91332d5c39205819b06e5e36efe62ff8e5b33b "fix_asn1.data/RRC.rel14/SystemInformation-NB-r13-IEs.h.diff" ) RRC_Rel10=( diff --git a/cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-NB-r13-IEs.h.diff b/cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-NB-r13-IEs.h.diff new file mode 100644 index 0000000000..37ac4cd858 --- /dev/null +++ b/cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-NB-r13-IEs.h.diff @@ -0,0 +1,47 @@ +48a49,70 +> struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member { +> SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR present; +> union SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_u { +> SystemInformationBlockType2_NB_r13_t sib2_r13; +> SystemInformationBlockType3_NB_r13_t sib3_r13; +> SystemInformationBlockType4_NB_r13_t sib4_r13; +> SystemInformationBlockType5_NB_r13_t sib5_r13; +> SystemInformationBlockType14_NB_r13_t sib14_r13; +> SystemInformationBlockType16_NB_r13_t sib16_r13; +> /* +> * This type is extensible, +> * possible extensions are below. +> */ +> SystemInformationBlockType15_NB_r14_t sib15_v1430; +> SystemInformationBlockType20_NB_r14_t sib20_v1430; +> SystemInformationBlockType22_NB_r14_t sib22_v1430; +> } choice; +> +> /* Context for parsing across buffer boundaries */ +> asn_struct_ctx_t _asn_ctx; +> }; +> +52,72c74 +< A_SEQUENCE_OF(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member { +< SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR present; +< union SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_u { +< SystemInformationBlockType2_NB_r13_t sib2_r13; +< SystemInformationBlockType3_NB_r13_t sib3_r13; +< SystemInformationBlockType4_NB_r13_t sib4_r13; +< SystemInformationBlockType5_NB_r13_t sib5_r13; +< SystemInformationBlockType14_NB_r13_t sib14_r13; +< SystemInformationBlockType16_NB_r13_t sib16_r13; +< /* +< * This type is extensible, +< * possible extensions are below. +< */ +< SystemInformationBlockType15_NB_r14_t sib15_v1430; +< SystemInformationBlockType20_NB_r14_t sib20_v1430; +< SystemInformationBlockType22_NB_r14_t sib22_v1430; +< } choice; +< +< /* Context for parsing across buffer boundaries */ +< asn_struct_ctx_t _asn_ctx; +< } ) list; +--- +> A_SEQUENCE_OF(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member) list; diff --git a/common/ran_context.h b/common/ran_context.h index c521c4f376..18b309d268 100644 --- a/common/ran_context.h +++ b/common/ran_context.h @@ -48,6 +48,8 @@ #include "NwGtpv1uPrivate.h" #include "gtpv1u_eNB_defs.h" +#include "PHY/defs_L1_NB_IoT.h" +#include "RRC/LITE/defs_NB_IoT.h" typedef struct { /// RAN context config file name char *config_file_name; @@ -76,7 +78,7 @@ typedef struct { /// eNB context variables struct PHY_VARS_eNB_s ***eNB; /// NB_IoT L1 context variables - //struct PHY_VARS_eNB_NB_IoT_s **L1_NB_IoT; + struct PHY_VARS_eNB_NB_IoT_s **L1_NB_IoT; /// RRC context variables struct eNB_RRC_INST_s **rrc; /// NB_IoT RRC context variables @@ -84,7 +86,7 @@ typedef struct { /// MAC context variables struct eNB_MAC_INST_s **mac; /// NB_IoT MAC context variables - //struct eNB_MAC_INST_NB_IoT_s **nb_iot_mac; + struct eNB_MAC_INST_NB_IoT_s **nb_iot_mac; /// GTPu descriptor gtpv1u_data_t *gtpv1u_data_g; /// RU descriptors. These describe what each radio unit is supposed to do and contain the necessary functions for fronthaul interfaces diff --git a/nfapi/oai_integration/nfapi_pnf.h b/nfapi/oai_integration/nfapi_pnf.h index 592d4877af..e213d785f1 100644 --- a/nfapi/oai_integration/nfapi_pnf.h +++ b/nfapi/oai_integration/nfapi_pnf.h @@ -21,7 +21,7 @@ #if !defined(NFAPI_PNF_H__) #define NFAPI_PNF_H__ - +int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port); #endif diff --git a/openair1/PHY/CODING/defs_NB_IoT.h b/openair1/PHY/CODING/defs_NB_IoT.h new file mode 100644 index 0000000000..17670ec8bc --- /dev/null +++ b/openair1/PHY/CODING/defs_NB_IoT.h @@ -0,0 +1,275 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* file: PHY/CODING/defs_NB_IoT.h + purpose: Top-level definitions, data types and function prototypes for openairinterface coding blocks for NB-IoT + author: matthieu.kanj@b-com.com, raymond.knopp@eurecom.fr, michele.paffetti@studio.unibo.it + date: 29.06.2017 +*/ + +#ifndef OPENAIR1_PHY_CODING_DEFS_NB_IOT_H_ +#define OPENAIR1_PHY_CODING_DEFS_NB_IOT_H_ + +#include // for uint8/16/32_t + +/* check if this ifndef is required for NB-IoT ?! +//#ifndef NO_OPENAIR1 +//#include "PHY/defs_NB_IoT.h" +//#else +//#include "PHY/TOOLS/time_meas.h" +//#endif +*/ + +#define CRC24_A_NB_IoT 0 +#define CRC24_B_NB_IoT 1 +#define CRC16_NB_IoT 2 +#define CRC8_NB_IoT 3 + +//#define MAX_TURBO_ITERATIONS_MBSFN 8 // no MBSFN +#define MAX_TURBO_ITERATIONS_NB_IoT 4 + +#define LTE_NULL_NB_IoT 2 // defined also in PHY/LTE_TRANSPORT/defs_NB_IoT.h + +/** \fn uint32_t sub_block_interleaving_cc(uint32_t D, uint8_t *d,uint8_t *w) +\brief This is the subblock interleaving algorithm for convolutionally coded blocks from 36-212 (Release 13.4, 2017). +This function takes the d-sequence and generates the w-sequence. The nu-sequence from 36-212 is implicit. +\param D Number of input bits +\param d Pointer to input (d-sequence, convolutional code output) +\param w Pointer to output (w-sequence, interleaver output) +\returns Interleaving matrix cardinality (\f$K_{\pi}\f$ from 36-212) +*/ +uint32_t sub_block_interleaving_cc_NB_IoT(uint32_t D, uint8_t *d,uint8_t *w); + +/** +\brief This is the NB-IoT rate matching algorithm for Convolutionally-coded channels (e.g. BCH,DCI,UCI). It is taken directly from 36-212 (Rel 8 8.6, 2009-03), pages 16-18 ) +\param RCC R^CC_subblock from subblock interleaver (number of rows in interleaving matrix) for up to 8 segments +\param E Number of coded channel bits +\param w This is a pointer to the w-sequence (second interleaver output) +\param e This is a pointer to the e-sequence (rate matching output, channel input/output bits) +\returns \f$E\f$, the number of coded bits per segment */ + +uint32_t lte_rate_matching_cc_NB_IoT(uint32_t RCC, // RRC = 2 + uint16_t E, // E = 1600 + uint8_t *w, // length + uint8_t *e); // length 1600 + +/** \fn void ccodelte_encode(int32_t numbits,uint8_t add_crc, uint8_t *inPtr,uint8_t *outPtr,uint16_t rnti) +\brief This function implements the LTE convolutional code of rate 1/3 + with a constraint length of 7 bits. The inputs are bit packed in octets +(from MSB to LSB). Trellis tail-biting is included here. +@param numbits Number of bits to encode +@param add_crc crc to be appended (8 bits) if add_crc = 1 +@param inPtr Pointer to input buffer +@param outPtr Pointer to output buffer +@param rnti RNTI for CRC scrambling +*/ + +void ccode_encode_NB_IoT (int32_t numbits, + uint8_t add_crc, + uint8_t *inPtr, + uint8_t *outPtr, + uint16_t rnti); + +/*!\fn void ccodelte_init(void) +\brief This function initializes the generator polynomials for an LTE convolutional code.*/ +void ccodelte_init_NB_IoT(void); + +/*!\fn void crcTableInit(void) +\brief This function initializes the different crc tables.*/ +void crcTableInit_NB_IoT (void); + + +/*!\fn uint32_t crc24a(uint8_t *inPtr, int32_t bitlen) +\brief This computes a 24-bit crc ('a' variant for overall transport block) +based on 3GPP UMTS/LTE specifications. +@param inPtr Pointer to input byte stream +@param bitlen length of inputs in bits +*/ +uint32_t crc24a_NB_IoT (uint8_t *inPtr, int32_t bitlen); + +/*!\fn uint32_t crc24b(uint8_t *inPtr, int32_t bitlen) +\brief This computes a 24-bit crc ('b' variant for transport-block segments) +based on 3GPP UMTS/LTE specifications. +@param inPtr Pointer to input byte stream +@param bitlen length of inputs in bits +*/ +uint32_t crc24b_NB_IoT (uint8_t *inPtr, int32_t bitlen); + +/*!\fn uint32_t crc16(uint8_t *inPtr, int32_t bitlen) +\brief This computes a 16-bit crc based on 3GPP UMTS specifications. +@param inPtr Pointer to input byte stream +@param bitlen length of inputs in bits*/ +uint32_t crc16_NB_IoT (uint8_t *inPtr, int32_t bitlen); + +/*!\fn uint32_t crc8(uint8_t *inPtr, int32_t bitlen) +\brief This computes a 8-bit crc based on 3GPP UMTS specifications. +@param inPtr Pointer to input byte stream +@param bitlen length of inputs in bits*/ +uint32_t crc8_NB_IoT (uint8_t *inPtr, int32_t bitlen); + + + + + + +uint32_t crcbit_NB_IoT (uint8_t * , + int32_t, + uint32_t); + + +/*!\fn void phy_viterbi_lte_sse2(int8_t *y, uint8_t *decoded_bytes, uint16_t n) +\brief This routine performs a SIMD optmized Viterbi decoder for the LTE 64-state tail-biting convolutional code. +@param y Pointer to soft input (coded on 8-bits but should be limited to 4-bit precision to avoid overflow) +@param decoded_bytes Pointer to decoded output +@param n Length of input/trellis depth in bits*/ +//void phy_viterbi_lte_sse2(int8_t *y,uint8_t *decoded_bytes,uint16_t n); +void phy_viterbi_lte_sse2_NB_IoT(int8_t *y,uint8_t *decoded_bytes,uint16_t n); + +/** \fn void sub_block_deinterleaving_cc(uint32_t D, int8_t *d,int8_t *w) +\brief This is the subblock deinterleaving algorithm for convolutionally-coded data from 36-212 (Release 8, 8.6 2009-03), pages 15-16. +This function takes the w-sequence and generates the d-sequence. The nu-sequence from 36-212 is implicit. +\param D Number of input bits +\param d Pointer to output (d-sequence, turbo code output) +\param w Pointer to input (w-sequence, interleaver output) +*/ +void sub_block_deinterleaving_cc_NB_IoT(uint32_t D,int8_t *d,int8_t *w); + + +/* +\brief This is the LTE rate matching algorithm for Convolutionally-coded channels (e.g. BCH,DCI,UCI). It is taken directly from 36-212 (Rel 8 8.6, 2009-03), pages 16-18 ) +\param RCC R^CC_subblock from subblock interleaver (number of rows in interleaving matrix) +\param E This the number of coded bits allocated for channel +\param w This is a pointer to the soft w-sequence (second interleaver output) with soft-combined outputs from successive HARQ rounds +\param dummy_w This is the first row of the interleaver matrix for identifying/discarding the "LTE-NULL" positions +\param soft_input This is a pointer to the soft channel output +\returns \f$E\f$, the number of coded bits per segment +*/ +void lte_rate_matching_cc_rx_NB_IoT(uint32_t RCC, + uint16_t E, + int8_t *w, + uint8_t *dummy_w, + int8_t *soft_input); + +/** \fn generate_dummy_w_cc(uint32_t D, uint8_t *w) +\brief This function generates a dummy interleaved sequence (first row) for receiver (convolutionally-coded data), in order to identify the NULL positions used to make the matrix complete. +\param D Number of systematic bits plus 4 (plus 4 for termination) +\param w This is the dummy sequence (first row), it will contain zeros and at most 31 "LTE_NULL" values +\returns Interleaving matrix cardinality (\f$K_{\pi}\f$ from 36-212) +*/ +uint32_t generate_dummy_w_cc_NB_IoT(uint32_t D, uint8_t *w); + +/** \fn lte_segmentation(uint8_t *input_buffer, + uint8_t **output_buffers, + uint32_t B, + uint32_t *C, + uint32_t *Cplus, + uint32_t *Cminus, + uint32_t *Kplus, + uint32_t *Kminus, + uint32_t *F) +\brief This function implements the LTE transport block segmentation algorithm from 36-212, V8.6 2009-03. +@param input_buffer +@param output_buffers +@param B +@param C +@param Cplus +@param Cminus +@param Kplus +@param Kminus +@param F +*/ +int32_t lte_segmentation_NB_IoT(uint8_t *input_buffer, + uint8_t **output_buffers, + uint32_t B, + uint32_t *C, + uint32_t *Cplus, + uint32_t *Cminus, + uint32_t *Kplus, + uint32_t *Kminus, + uint32_t *F); + +/** \fn void sub_block_deinterleaving_turbo(uint32_t D, int16_t *d,int16_t *w) +\brief This is the subblock deinterleaving algorithm from 36-212 (Release 8, 8.6 2009-03), pages 15-16. +This function takes the w-sequence and generates the d-sequence. The nu-sequence from 36-212 is implicit. +\param D Number of systematic bits plus 4 (plus 4 for termination) +\param d Pointer to output (d-sequence, turbo code output) +\param w Pointer to input (w-sequence, interleaver output) +*/ +//*****************void sub_block_deinterleaving_turbo(uint32_t D, int16_t *d,int16_t *w); + +/** +\brief This is the LTE rate matching algorithm for Turbo-coded channels (e.g. DLSCH,ULSCH). It is taken directly from 36-212 (Rel 8 8.6, 2009-03), pages 16-18 ) +\param RTC R^TC_subblock from subblock interleaver (number of rows in interleaving matrix) +\param G This the number of coded transport bits allocated in sub-frame +\param w This is a pointer to the soft w-sequence (second interleaver output) with soft-combined outputs from successive HARQ rounds +\param dummy_w This is the first row of the interleaver matrix for identifying/discarding the "LTE-NULL" positions +\param soft_input This is a pointer to the soft channel output +\param C Number of segments (codewords) in the sub-frame +\param Nsoft Total number of soft bits (from UE capabilities in 36-306) +\param Mdlharq Number of HARQ rounds +\param Kmimo MIMO capability for this DLSCH (0 = no MIMO) +\param rvidx round index (0-3) +\param clear 1 means clear soft buffer (start of HARQ round) +\param Qm modulation order (2,4,6) +\param Nl number of layers (1,2) +\param r segment number +\param E_out the number of coded bits per segment +\returns 0 on success, -1 on failure +*/ + +// int lte_rate_matching_turbo_rx(uint32_t RTC, +// uint32_t G, +// int16_t *w, +// uint8_t *dummy_w, +// int16_t *soft_input, +// uint8_t C, +// uint32_t Nsoft, +// uint8_t Mdlharq, +// uint8_t Kmimo, +// uint8_t rvidx, +// uint8_t clear, +// uint8_t Qm, +// uint8_t Nl, +// uint8_t r, +// uint32_t *E_out); + +// uint32_t lte_rate_matching_turbo_rx_abs(uint32_t RTC, +// uint32_t G, +// double *w, +// uint8_t *dummy_w, +// double *soft_input, +// uint8_t C, +// uint32_t Nsoft, +// uint8_t Mdlharq, +// uint8_t Kmimo, +// uint8_t rvidx, +// uint8_t clear, +// uint8_t Qm, +// uint8_t Nl, +// uint8_t r, +// uint32_t *E_out); + +void ccode_encode_npdsch_NB_IoT (int32_t numbits, + uint8_t *inPtr, + uint8_t *outPtr, + uint32_t crc); + +#endif /* OPENAIR1_PHY_CODING_DEFS_NB_IOT_H_ */ diff --git a/openair1/PHY/INIT/defs_NB_IoT.h b/openair1/PHY/INIT/defs_NB_IoT.h new file mode 100644 index 0000000000..e8ead21780 --- /dev/null +++ b/openair1/PHY/INIT/defs_NB_IoT.h @@ -0,0 +1,77 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + + +#ifndef __INIT_DEFS_NB_IOT__H__ +#define __INIT_DEFS_NB_IOT__H__ + +//#include "PHY/defs_NB_IoT.h" +#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h" +#include "nfapi_interface.h" + +//#include "SystemInformationBlockType2.h" +//#include "RadioResourceConfigCommonSIB.h" +//#include "RadioResourceConfigDedicated.h" +//#include "TDD-Config.h" +//#include "MBSFN-SubframeConfigList.h" +//#include "MobilityControlInfo.h" +//#if defined(Rel10) || defined(Rel14) +//#include "SCellToAddMod-r10.h" +//#endif + +/*brief Configure LTE_DL_FRAME_PARMS with components derived after initial synchronization (MIB-NB decoding + primary/secondary synch).*/ +void phy_config_mib_eNB_NB_IoT(int Mod_id, + int eutra_band, + int Nid_cell, + int Ncp, + int Ncp_UL, + int p_eNB, + uint16_t EARFCN, + uint16_t prb_index, // NB_IoT_RB_ID, + uint16_t operating_mode, + uint16_t control_region_size, + uint16_t eutra_NumCRS_ports); + +/*NB_phy_config_sib1_eNB is not needed since NB-IoT use only FDD mode*/ + +/*brief Configure LTE_DL_FRAME_PARMS with components of SIB2-NB (at eNB).*/ + +//void NB_phy_config_sib2_eNB(module_id_t Mod_id, +// int CC_id, +// RadioResourceConfigCommonSIB_NB_r13_t *radioResourceConfigCommon +// ); + +void phy_config_sib2_eNB_NB_IoT(uint8_t Mod_id, + nfapi_nb_iot_config_t *config, + nfapi_rf_config_t *rf_config, + nfapi_uplink_reference_signal_config_t* ul_nrs_config, + extra_phyConfig_t* extra_phy_parms); + +void phy_config_dedicated_eNB_NB_IoT(module_id_t Mod_id, + rnti_t rnti, + extra_phyConfig_t* extra_phy_parms); + +// void phy_init_lte_top_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms); +void phy_init_nb_iot_eNB(PHY_VARS_eNB_NB_IoT *phyvar); +int l1_north_init_NB_IoT(void); + +#endif + diff --git a/openair1/PHY/LTE_REFSIG/defs_NB_IoT.h b/openair1/PHY/LTE_REFSIG/defs_NB_IoT.h new file mode 100644 index 0000000000..8f0b7b8c4c --- /dev/null +++ b/openair1/PHY/LTE_REFSIG/defs_NB_IoT.h @@ -0,0 +1,60 @@ +/******************************************************************************* + + *******************************************************************************/ +/*! \file PHY/LTE_REFSIG/defs_NB_IoT.c +* \function called by lte_dl_cell_spec_NB_IoT.c , TS 36-211, V13.4.0 2017-02 +* \author M. KANJ +* \date 2017 +* \version 0.0 +* \company bcom +* \email: matthieu.kanj@b-com.com +* \note +* \warning +*/ + +/* Definitions for NB_IoT Reference signals */ + +#ifndef __LTE_REFSIG_DEFS_NB_IOT__H__ +#define __LTE_REFSIG_DEFS_NB_IOT__H__ + +#include "PHY/defs_L1_NB_IoT.h" + +/** @ingroup _PHY_REF_SIG + * @{ +*/ +/*!\brief This function generates the LTE Gold sequence (36-211, Sec 7.2), specifically for DL reference signals. +@param frame_parms LTE DL Frame parameters +@param lte_gold_table pointer to table where sequences are stored +@param Nid_cell Cell Id for NB_IoT (to compute sequences for local and adjacent cells) */ + +void lte_gold_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms, + uint32_t lte_gold_table_NB_IoT[20][2][14], + uint16_t Nid_cell); + +/*! \brief This function generates the Narrowband reference signal (NRS) sequence (36-211, Sec 6.10.1.1) +@param phy_vars_eNB Pointer to eNB variables +@param output Output vector for OFDM symbol (Frequency Domain) +@param amp Q15 amplitude +@param Ns Slot number (0..19) +@param l symbol (0,1) - Note 1 means 3! +@param p antenna index +@param RB_IoT_ID the ID of the RB dedicated for NB_IoT +*/ +int lte_dl_cell_spec_NB_IoT(PHY_VARS_eNB_NB_IoT *phy_vars_eNB, + int32_t *output, + short amp, + unsigned char Ns, + unsigned char l, + unsigned char p, + unsigned short RB_IoT_ID); + + +unsigned int lte_gold_generic_NB_IoT(unsigned int *x1, + unsigned int *x2, + unsigned char reset); + +void generate_ul_ref_sigs_rx_NB_IoT(void); + +void free_ul_ref_sigs_NB_IoT(void); + +#endif diff --git a/openair1/PHY/LTE_TRANSPORT/dci_NB_IoT.h b/openair1/PHY/LTE_TRANSPORT/dci_NB_IoT.h new file mode 100644 index 0000000000..ea84f66de4 --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/dci_NB_IoT.h @@ -0,0 +1,292 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file PHY/LTE_TRANSPORT/dci.h +* \brief typedefs for LTE DCI structures from 36-212, V8.6 2009-03. Limited to 5 MHz formats for the moment.Current LTE compliance V8.6 2009-03. +* \author R. Knopp +* \date 2011 +* \version 0.1 +* \company Eurecom +* \email: knopp@eurecom.fr +* \note +* \warning +*/ +#ifndef __DCI_NB_IOT_H__ +#define __DCI_NB_IOT_H__ + +//#ifndef USER_MODE +//#include "PHY/types.h" +//#else +#include +//#endif + +typedef enum +{ + DCIFormatN0 = 0, + DCIFormatN1, + DCIFormatN1_RA,//is for initial RA procedure (semi-static information) so maybe is not needed + DCIFormatN1_RAR, + DCIFormatN2, + DCIFormatN2_Ind, + DCIFormatN2_Pag, +}DCI_format_NB_IoT_t; + +/// DCI Format Type 0 (180 kHz, 23 bits) +struct DCIFormatN0{ + /// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits + uint8_t type; + /// Subcarrier indication, 6 bits + uint8_t scind; + /// Resourse Assignment (RU Assignment), 3 bits + uint8_t ResAssign; + /// Modulation and Coding Scheme, 4 bits + uint8_t mcs; + /// New Data Indicator, 1 bits + uint8_t ndi; + /// Scheduling Delay, 2 bits + uint8_t Scheddly; + /// Repetition Number, 3 bits + uint8_t RepNum; + /// Redundancy version for HARQ (only use 0 and 2), 1 bits + uint8_t rv; + /// DCI subframe repetition Number, 2 bits + uint8_t DCIRep; +}; + +typedef struct DCIFormatN0 DCIFormatN0_t; + +/// DCI Format Type N1 for User data +struct DCIFormatN1{ + /// type = 0 => DCI Format N0, type = 1 => DCI Format N1,1bits + uint8_t type; + //NPDCCH order indicator (set to 0), 1 bits + uint8_t orderIndicator; + // Scheduling Delay,3 bits + uint8_t Scheddly; + // Resourse Assignment (RU Assignment),3 bits + uint8_t ResAssign; + // Modulation and Coding Scheme,4 bits + uint8_t mcs; + // Repetition Number,4 bits + uint8_t RepNum; + // New Data Indicator,1 bits + uint8_t ndi; + // HARQ-ACK resource,4 bits + uint8_t HARQackRes; + // DCI subframe repetition Number,2 bits + uint8_t DCIRep; +}; + + +typedef struct DCIFormatN1 DCIFormatN1_t; + +/// DCI Format Type N1 for initial RA +struct DCIFormatN1_RA{ + /// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits + uint8_t type; + //NPDCCH order indicator (set to 0),1 bits + uint8_t orderIndicator; + // Start number of NPRACH repetiiton, 2 bits + uint8_t Scheddly; + // Subcarrier indication of NPRACH, 6 bits + uint8_t scind; + // All the remainging bits, 13 bits + uint8_t remaingingBits; +}; + +typedef struct DCIFormatN1_RA DCIFormatN1_RA_t; + +/// DCI Format Type N1 for User data +struct DCIFormatN1_RAR{ + /// type = 0 => DCI Format N0, type = 1 => DCI Format N1,1bits + uint8_t type; + //NPDCCH order indicator (set to 0), 1 bits + uint8_t orderIndicator; + // Scheduling Delay,3 bits + uint8_t Scheddly; + // Resourse Assignment (RU Assignment),3 bits + uint8_t ResAssign; + // Modulation and Coding Scheme,4 bits + uint8_t mcs; + // Repetition Number,4 bits + uint8_t RepNum; + // New Data Indicator,1 bits,reserved in the RAR + uint8_t ndi; + // HARQ-ACK resource,4 bits,reserved in the RAR + uint8_t HARQackRes; + // DCI subframe repetition Number,2 bits + uint8_t DCIRep; +}; + +typedef struct DCIFormatN1_RAR DCIFormatN1_RAR_t; + +// DCI Format Type N2 for direct indication, 15 bits +struct DCIFormatN2_Ind{ + //Flag for paging(1)/direct indication(0), set to 0,1 bits + uint8_t type; + //Direct indication information, 8 bits + uint8_t directIndInf; + // Reserved information bits, 6 bits + uint8_t resInfoBits; +}; + +typedef struct DCIFormatN2_Ind DCIFormatN2_Ind_t; + +// DCI Format Type N2 for Paging, 15 bits +struct DCIFormatN2_Pag{ + //Flag for paging(1)/direct indication(0), set to 1,1 bits + uint8_t type; + // Resourse Assignment (RU Assignment), 3 bits + uint8_t ResAssign; + // Modulation and Coding Scheme, 4 bits + uint8_t mcs; + // Repetition Number, 4 bits + uint8_t RepNum; + // Reserved 3 bits + uint8_t DCIRep; +}; + +typedef struct DCIFormatN2_Pag DCIFormatN2_Pag_t; + +typedef union DCI_CONTENT { + // + DCIFormatN0_t DCIN0; + // + DCIFormatN1_t DCIN1; + // + DCIFormatN1_RA_t DCIN1_RA; + // + DCIFormatN1_RAR_t DCIN1_RAR; + // + DCIFormatN2_Ind_t DCIN2_Ind; + // + DCIFormatN2_Pag_t DCIN2_Pag; + + }DCI_CONTENT; + + /*Structure for packing*/ + + struct DCIN0{ + /// DCI subframe repetition Number, 2 bits + uint8_t DCIRep:2; + /// New Data Indicator, 1 bits + uint8_t ndi:1; + /// Repetition Number, 3 bits + uint8_t RepNum:3; + /// Redundancy version for HARQ (only use 0 and 2), 1 bits + uint8_t rv:1; + /// Modulation and Coding Scheme, 4 bits + uint8_t mcs:4; + /// Scheduling Delay, 2 bits + uint8_t Scheddly:2; + /// Resourse Assignment (RU Assignment), 3 bits + uint8_t ResAssign:3; + /// Subcarrier indication, 6 bits + uint8_t scind:6; + /// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits + uint8_t type:1; + } __attribute__ ((__packed__)); + + typedef struct DCIN0 DCIN0_t; +#define sizeof_DCIN0_t 23 + +struct DCIN1_RAR{ + // DCI subframe repetition Number, 2 bits + uint8_t DCIRep:2; + // HARQ-ACK resource,4 bits + uint8_t HARQackRes:4; + // New Data Indicator,1 bits + uint8_t ndi:1; + // Repetition Number, 4 bits + uint8_t RepNum:4; + // Modulation and Coding Scheme, 4 bits + uint8_t mcs:4; + // Resourse Assignment (RU Assignment), 3 bits + uint8_t ResAssign:3; + // Scheduling Delay, 3 bits + uint8_t Scheddly:3; + //NPDCCH order indicator (set to 0),1 bits + uint8_t orderIndicator:1; + /// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits + uint8_t type:1; + } __attribute__ ((__packed__)); + + typedef struct DCIN1_RAR DCIN1_RAR_t; +#define sizeof_DCIN1_RAR_t 23 + +struct DCIN1{ + // DCI subframe repetition Number, 2 bits + uint8_t DCIRep:2; + // HARQ-ACK resource,4 bits + uint8_t HARQackRes:4; + // New Data Indicator,1 bits + uint8_t ndi:1; + // Repetition Number, 4 bits + uint8_t RepNum:4; + // Modulation and Coding Scheme, 4 bits + uint8_t mcs:4; + // Resourse Assignment (RU Assignment), 3 bits + uint8_t ResAssign:3; + // Scheduling Delay, 3 bits + uint8_t Scheddly:3; + //NPDCCH order indicator (set to 0),1 bits + uint8_t orderIndicator:1; + /// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits + uint8_t type:1; + } __attribute__ ((__packed__)); + + typedef struct DCIN1 DCIN1_t; +#define sizeof_DCIN1_t 23 + +// DCI Format Type N2 for direct indication, 15 bits +struct DCIN2_Ind{ + // Reserved information bits, 6 bits + uint8_t resInfoBits:6; + //Direct indication information, 8 bits + uint8_t directIndInf:8; + //Flag for paging(1)/direct indication(0), set to 0,1 bits + uint8_t type:1; +} __attribute__ ((__packed__));; + +typedef struct DCIN2_Ind DCIN2_Ind_t; +#define sizeof_DCIN2_Ind_t 15 + +// DCI Format Type N2 for Paging, 15 bits +struct DCIN2_Pag{ + // Reserved 3 bits + uint8_t DCIRep:3; + // Repetition Number, 4 bits + uint8_t RepNum:4; + // Modulation and Coding Scheme, 4 bits + uint8_t mcs:4; + // Resourse Assignment (RU Assignment), 3 bits + uint8_t ResAssign:3; + //Flag for paging(1)/direct indication(0), set to 1,1 bits + uint8_t type:1; +} __attribute__ ((__packed__));; + +typedef struct DCIN2_Pag DCIN2_Pag_t; + +#define sizeof_DCIN2_Pag_t 15 + +#define MAX_DCI_SIZE_BITS_NB_IoT 23 + +#endif diff --git a/openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h b/openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h new file mode 100644 index 0000000000..3574ba6740 --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h @@ -0,0 +1,787 @@ +/******************************************************************************* + + *******************************************************************************/ +/*! \file PHY/LTE_TRANSPORT/defs_NB_IoT.h +* \brief data structures for NPDSCH/NDLSCH/NPUSCH/NULSCH physical and transport channel descriptors (TX/RX) of NB-IoT +* \author M. KANJ +* \date 2017 +* \version 0.0 +* \company bcom +* \email: matthieu.kanj@b-com.com +* \note +* \warning +*/ +#ifndef __LTE_TRANSPORT_DEFS_NB_IOT__H__ +#define __LTE_TRANSPORT_DEFS_NB_IOT__H__ +////#include "PHY/defs.h" +//#include "PHY/defs_nb_iot.h" +#include "PHY/LTE_TRANSPORT/dci_NB_IoT.h" +#include "PHY/impl_defs_lte_NB_IoT.h" +#include "openair2/COMMON/platform_types.h" +//#include "dci.h" +#include "PHY/LTE_TRANSPORT/uci_NB_IoT.h" +//#include "dci.h" +//#include "uci.h" +//#ifndef STANDALONE_COMPILE +//#include "UTIL/LISTS/list.h" +//#endif + +//#include "dci_nb_iot.h" + +//#define MOD_TABLE_QPSK_OFFSET 1 +//#define MOD_TABLE_16QAM_OFFSET 5 +//#define MOD_TABLE_64QAM_OFFSET 21 +//#define MOD_TABLE_PSS_OFFSET 85 +// +//// structures below implement 36-211 and 36-212 +// +//#define NSOFT 1827072 +#define LTE_NULL_NB_IoT 2 +// +//// maximum of 3 segments before each coding block if data length exceeds 6144 bits. +// +#define MAX_NUM_DLSCH_SEGMENTS_NB_IoT 16 +//#define MAX_NUM_ULSCH_SEGMENTS MAX_NUM_DLSCH_SEGMENTS +//#define MAX_DLSCH_PAYLOAD_BYTES (MAX_NUM_DLSCH_SEGMENTS*768) +//#define MAX_ULSCH_PAYLOAD_BYTES (MAX_NUM_ULSCH_SEGMENTS*768) +// +//#define MAX_NUM_CHANNEL_BITS_NB_IOT (14*1200*6) // 14 symbols, 1200 REs, 12 bits/RE +//#define MAX_NUM_RE (14*1200) +// +//#if !defined(SI_RNTI) +//#define SI_RNTI (rnti_t)0xffff +//#endif +//#if !defined(M_RNTI) +//#define M_RNTI (rnti_t)0xfffd +//#endif +//#if !defined(P_RNTI) +//#define P_RNTI (rnti_t)0xfffe +//#endif +//#if !defined(CBA_RNTI) +//#define CBA_RNTI (rnti_t)0xfff4 +//#endif +//#if !defined(C_RNTI) +//#define C_RNTI (rnti_t)0x1234 +//#endif +// +//#define PMI_2A_11 0 +//#define PMI_2A_1m1 1 +//#define PMI_2A_1j 2 +//#define PMI_2A_1mj 3 +// +//// for NB-IoT +#define MAX_NUM_CHANNEL_BITS_NB_IoT 3360 //14 symbols * 12 sub-carriers * 10 SF * 2bits/RE // to check during real tests +#define MAX_DL_SIZE_BITS_NB_IoT 680 // in release 13 // in release 14 = 2048 // ??? **** not sure +////#define MAX_NUM_CHANNEL_BITS_NB_IOT 3*680 /// ??? ****not sure +// +//// to be created LTE_eNB_DLSCH_t --> is duplicated for each number of UE and then indexed in the table +// +//typedef struct { // LTE_DL_eNB_HARQ_t +// /// Status Flag indicating for this DLSCH (idle,active,disabled) +// SCH_status_t status; +// /// Transport block size +// uint32_t TBS; +// /// The payload + CRC size in bits, "B" from 36-212 +// uint32_t B; // keep this parameter +// /// Pointer to the payload +// uint8_t *b; // keep this parameter +// /// Pointers to transport block segments +// //uint8_t *c[MAX_NUM_DLSCH_SEGMENTS]; +// /// RTC values for each segment (for definition see 36-212 V8.6 2009-03, p.15) +// // uint32_t RTC[MAX_NUM_DLSCH_SEGMENTS]; +// /// Frame where current HARQ round was sent +// uint32_t frame; +// /// Subframe where current HARQ round was sent +// uint32_t subframe; +// /// Index of current HARQ round for this DLSCH +// uint8_t round; +// /// MCS format for this DLSCH +// uint8_t mcs; +// /// Redundancy-version of the current sub-frame +// uint8_t rvidx; +// /// MIMO mode for this DLSCH +// MIMO_mode_t mimo_mode; +// /// Current RB allocation +// uint32_t rb_alloc[4]; +// /// distributed/localized flag +// vrb_t vrb_type; +// /// Current subband PMI allocation +// uint16_t pmi_alloc; +// /// Current subband RI allocation +// uint32_t ri_alloc; +// /// Current subband CQI1 allocation +// uint32_t cqi_alloc1; +// /// Current subband CQI2 allocation +// uint32_t cqi_alloc2; +// /// Current Number of RBs +// uint16_t nb_rb; +// /// downlink power offset field +// uint8_t dl_power_off; +// /// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18) +// uint8_t e[MAX_NUM_CHANNEL_BITS_NB_IOT]; +// /// data after scrambling +// uint8_t s_e[MAX_NUM_CHANNEL_BITS_NB_IOT]; +// /// length of the table e +// uint16_t length_e // new parameter +// /// Tail-biting convolutional coding outputs +// uint8_t d[96+(3*(24+MAX_DL_SIZE_BITS_NB_IOT))]; // new parameter +// /// Sub-block interleaver outputs +// uint8_t w[3*3*(MAX_DL_SIZE_BITS_NB_IOT+24)]; // new parameter +// /// Number of MIMO layers (streams) (for definition see 36-212 V8.6 2009-03, p.17, TM3-4) +// uint8_t Nl; +// /// Number of layers for this PDSCH transmission (TM8-10) +// uint8_t Nlayers; +// /// First layer for this PSCH transmission +// uint8_t first_layer; +//} NB_IoT_DL_eNB_HARQ_t; + +typedef enum { + + SCH_IDLE_NB_IoT, + ACTIVE_NB_IoT, + CBA_ACTIVE_NB_IoT, + DISABLED_NB_IoT + +} SCH_status_NB_IoT_t; + + +typedef struct { + /// NB-IoT + SCH_status_NB_IoT_t status; + /// The scheduling the NPDCCH and the NPDSCH transmission TS 36.213 Table 16.4.1-1 + uint8_t scheduling_delay; + /// The number of the subframe to transmit the NPDSCH Table TS 36.213 Table 16.4.1.3-1 (Nsf) (NB. in this case is not the index Isf) + uint8_t resource_assignment; + /// is the index that determined the repeat number of NPDSCH through table TS 36.213 Table 16.4.1.3-2 / for SIB1-NB Table 16.4.1.3-3 + uint8_t repetition_number; + /// Determined the ACK/NACK delay and the subcarrier allocation TS 36.213 Table 16.4.2 + uint8_t HARQ_ACK_resource; + /// Determined the repetition number value 0-3 (2 biut carried by the FAPI NPDCCH) + uint8_t dci_subframe_repetitions; + /// modulation always QPSK Qm = 2 + uint8_t modulation; + /// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18) + uint8_t e[MAX_NUM_CHANNEL_BITS_NB_IoT]; + /// data after scrambling + uint8_t s_e[MAX_NUM_CHANNEL_BITS_NB_IoT]; + //length of the table e + uint16_t length_e; // new parameter + /// Tail-biting convolutional coding outputs + uint8_t d[96+(3*(24+MAX_DL_SIZE_BITS_NB_IoT))]; // new parameter + /// Sub-block interleaver outputs + uint8_t w[3*3*(MAX_DL_SIZE_BITS_NB_IoT+24)]; // new parameter + + /// Status Flag indicating for this DLSCH (idle,active,disabled) + //SCH_status_t status; + /// Transport block size + uint32_t TBS; + /// The payload + CRC size in bits, "B" from 36-212 + uint32_t B; + /// Pointer to the payload + uint8_t *b; + ///pdu of the ndlsch message + uint8_t *pdu; + /// Frame where current HARQ round was sent + uint32_t frame; + /// Subframe where current HARQ round was sent + uint32_t subframe; + /// Index of current HARQ round for this DLSCH + uint8_t round; + /// MCS format for this NDLSCH , TS 36.213 Table 16.4.1.5 + uint8_t mcs; + // we don't have code block segmentation / crc attachment / concatenation in NB-IoT R13 36.212 6.4.2 + // we don't have beamforming in NB-IoT + //this index will be used mainly for SI message buffer + uint8_t pdu_buffer_index; + +} NB_IoT_DL_eNB_HARQ_t; + + +typedef struct { // LTE_eNB_DLSCH_t + /// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding) + uint32_t *txdataF[8]; + /// Allocated RNTI (0 means DLSCH_t is not currently used) + uint16_t rnti; + /// Active flag for baseband transmitter processing + uint8_t active; + /// Indicator of TX activation per subframe. Used during PUCCH detection for ACK/NAK. + uint8_t subframe_tx[10]; + /// First CCE of last PDSCH scheduling per subframe. Again used during PUCCH detection for ACK/NAK. + uint8_t nCCE[10]; + /// Current HARQ process id + uint8_t current_harq_pid; + /// Process ID's per subframe. Used to associate received ACKs on PUSCH/PUCCH to DLSCH harq process ids + uint8_t harq_ids[10]; + /// Window size (in outgoing transport blocks) for fine-grain rate adaptation + uint8_t ra_window_size; + /// First-round error threshold for fine-grain rate adaptation + uint8_t error_threshold; + /// Pointers to 8 HARQ processes for the DLSCH + NB_IoT_DL_eNB_HARQ_t harq_process; + /// circular list of free harq PIDs (the oldest come first) + /// (10 is arbitrary value, must be > to max number of DL HARQ processes in LTE) + int harq_pid_freelist[10]; + /// the head position of the free list (if list is free then head=tail) + int head_freelist; + /// the tail position of the free list + int tail_freelist; + /// Number of soft channel bits + uint32_t G; + /// Codebook index for this dlsch (0,1,2,3) + uint8_t codebook_index; + /// Maximum number of HARQ processes (for definition see 36-212 V8.6 2009-03, p.17) + uint8_t Mdlharq; + /// Maximum number of HARQ rounds + uint8_t Mlimit; + /// MIMO transmission mode indicator for this sub-frame (for definition see 36-212 V8.6 2009-03, p.17) + uint8_t Kmimo; + /// Nsoft parameter related to UE Category + uint32_t Nsoft; + /// amplitude of PDSCH (compared to RS) in symbols without pilots + int16_t sqrt_rho_a; + /// amplitude of PDSCH (compared to RS) in symbols containing pilots + int16_t sqrt_rho_b; + +} NB_IoT_eNB_DLSCH_t; + + +typedef struct { + /// HARQ process id + uint8_t harq_id; + /// ACK bits (after decoding) 0:NACK / 1:ACK / 2:DTX + uint8_t ack; + /// send status (for PUCCH) + uint8_t send_harq_status; + /// nCCE (for PUCCH) + uint8_t nCCE; + /// DAI value detected from DCI1/1a/1b/1d/2/2a/2b/2c. 0xff indicates not touched + uint8_t vDAI_DL; + /// DAI value detected from DCI0/4. 0xff indicates not touched + uint8_t vDAI_UL; +} harq_status_NB_IoT_t; + +typedef struct { + /// UL RSSI per receive antenna + int32_t UL_rssi[NB_ANTENNAS_RX]; + /// PUCCH1a/b power (digital linear) + uint32_t Po_PUCCH; + /// PUCCH1a/b power (dBm) + int32_t Po_PUCCH_dBm; + /// PUCCH1 power (digital linear), conditioned on below threshold + uint32_t Po_PUCCH1_below; + /// PUCCH1 power (digital linear), conditioned on above threshold + uint32_t Po_PUCCH1_above; + /// Indicator that Po_PUCCH has been updated by PHY + int32_t Po_PUCCH_update; + /// DL Wideband CQI index (2 TBs) + uint8_t DL_cqi[2]; + /// DL Subband CQI index (from HLC feedback) + uint8_t DL_subband_cqi[2][13]; + /// DL PMI Single Stream + uint16_t DL_pmi_single; + /// DL PMI Dual Stream + uint16_t DL_pmi_dual; + /// Current RI + uint8_t rank; + /// CRNTI of UE + uint16_t crnti; ///user id (rnti) of connected UEs + /// Initial timing offset estimate from PRACH for RAR + int32_t UE_timing_offset; + /// Timing advance estimate from PUSCH for MAC timing advance signalling + int32_t timing_advance_update; + /// Current mode of UE (NOT SYCHED, RAR, PUSCH) + UE_MODE_NB_IoT_t mode; + /// Current sector where UE is attached + uint8_t sector; + + /// dlsch l2 errors + uint32_t dlsch_l2_errors[8]; + /// dlsch trials per harq and round + uint32_t dlsch_trials[8][8]; + /// dlsch ACK/NACK per hard_pid and round + uint32_t dlsch_ACK[8][8]; + uint32_t dlsch_NAK[8][8]; + + /// ulsch l2 errors per harq_pid + uint32_t ulsch_errors[8]; + /// ulsch l2 consecutive errors per harq_pid + uint32_t ulsch_consecutive_errors; //[8]; + /// ulsch trials/errors/fer per harq and round + uint32_t nulsch_decoding_attempts[8][8]; + uint32_t ulsch_round_errors[8][8]; + uint32_t ulsch_decoding_attempts_last[8][8]; + uint32_t ulsch_round_errors_last[8][8]; + uint32_t ulsch_round_fer[8][8]; + uint32_t sr_received; + uint32_t sr_total; + + /// dlsch sliding count and total errors in round 0 are used to compute the dlsch_mcs_offset + uint32_t dlsch_sliding_cnt; + uint32_t dlsch_NAK_round0; + int8_t dlsch_mcs_offset; + + /// Target mcs1 after rate-adaptation (used by MAC layer scheduler) + uint8_t dlsch_mcs1; + /// Target mcs2 after rate-adaptation (used by MAC layer scheduler) + uint8_t dlsch_mcs2; + /// Total bits received from MAC on PDSCH + int total_TBS_MAC; + /// Total bits acknowledged on PDSCH + int total_TBS; + /// Total bits acknowledged on PDSCH (last interval) + int total_TBS_last; + /// Bitrate on the PDSCH [bps] + unsigned int dlsch_bitrate; + // unsigned int total_transmitted_bits; + +} NB_IoT_eNB_UE_stats; + +typedef struct { + /// Indicator of first transmission + uint8_t first_tx; + /// Last Ndi received for this process on DCI (used for C-RNTI only) + uint8_t DCINdi; + /// DLSCH status flag indicating + //SCH_status_t status; + /// Transport block size + uint32_t TBS; + /// The payload + CRC size in bits + uint32_t B; + /// Pointer to the payload + uint8_t *b; + /// Pointers to transport block segments + uint8_t *c[MAX_NUM_DLSCH_SEGMENTS_NB_IoT]; + /// RTC values for each segment (for definition see 36-212 V8.6 2009-03, p.15) + uint32_t RTC[MAX_NUM_DLSCH_SEGMENTS_NB_IoT]; + /// Index of current HARQ round for this DLSCH + uint8_t round; + /// MCS format for this DLSCH + uint8_t mcs; + /// Qm (modulation order) for this DLSCH + uint8_t Qm; + /// Redundancy-version of the current sub-frame + uint8_t rvidx; + /// MIMO mode for this DLSCH + // MIMO_mode_t mimo_mode; + /// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) + int16_t w[MAX_NUM_DLSCH_SEGMENTS_NB_IoT][3*(6144+64)]; + /// for abstraction soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) + double w_abs[MAX_NUM_DLSCH_SEGMENTS_NB_IoT][3*(6144+64)]; + /// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) + int16_t *d[MAX_NUM_DLSCH_SEGMENTS_NB_IoT]; + /// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9) + uint32_t C; + /// Number of "small" code segments (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Cminus; + /// Number of "large" code segments (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Cplus; + /// Number of bits in "small" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Kminus; + /// Number of bits in "large" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Kplus; + /// Number of "Filler" bits (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t F; + /// Number of MIMO layers (streams) (for definition see 36-212 V8.6 2009-03, p.17) + uint8_t Nl; + /// current delta_pucch + int8_t delta_PUCCH; + /// Number of soft channel bits + uint32_t G; + /// Current Number of RBs + uint16_t nb_rb; + /// Current subband PMI allocation + uint16_t pmi_alloc; + /// Current RB allocation (even slots) + uint32_t rb_alloc_even[4]; + /// Current RB allocation (odd slots) + uint32_t rb_alloc_odd[4]; + /// distributed/localized flag + //vrb_t vrb_type; + /// downlink power offset field + uint8_t dl_power_off; + /// trials per round statistics + uint32_t trials[8]; + /// error statistics per round + uint32_t errors[8]; + /// codeword this transport block is mapped to + uint8_t codeword; + +} NB_IoT_DL_UE_HARQ_t; + +typedef struct { + /// RNTI + uint16_t rnti; + /// Active flag for DLSCH demodulation + uint8_t active; + /// Transmission mode + uint8_t mode1_flag; + /// amplitude of PDSCH (compared to RS) in symbols without pilots + int16_t sqrt_rho_a; + /// amplitude of PDSCH (compared to RS) in symbols containing pilots + int16_t sqrt_rho_b; + /// Current HARQ process id threadRx Odd and threadRx Even + uint8_t current_harq_pid; + /// Current subband antenna selection + uint32_t antenna_alloc; + /// Current subband RI allocation + uint32_t ri_alloc; + /// Current subband CQI1 allocation + uint32_t cqi_alloc1; + /// Current subband CQI2 allocation + uint32_t cqi_alloc2; + /// saved subband PMI allocation from last PUSCH/PUCCH report + uint16_t pmi_alloc; + /// HARQ-ACKs + harq_status_NB_IoT_t harq_ack; + /// Pointers to up to 8 HARQ processes + NB_IoT_DL_UE_HARQ_t *harq_process; + /// Maximum number of HARQ processes(for definition see 36-212 V8.6 2009-03, p.17 + uint8_t Mdlharq; + /// MIMO transmission mode indicator for this sub-frame (for definition see 36-212 V8.6 2009-03, p.17) + uint8_t Kmimo; + /// Nsoft parameter related to UE Category + uint32_t Nsoft; + /// Maximum number of Turbo iterations + uint8_t max_turbo_iterations; + /// number of iterations used in last turbo decoding + uint8_t last_iteration_cnt; + /// accumulated tx power adjustment for PUCCH + int8_t g_pucch; + +} NB_IoT_UE_DLSCH_t; + +//---------------------------------------------------------------------------------------------------------- +// NB-IoT +//---------------------------------------------------------------------------------------------------- + +//enum for distinguish the different type of ndlsch (may in the future will be not needed) +typedef enum +{ + + SIB1, + SI_Message, + RAR, + UE_Data + +}ndlsch_flag_t; + + + +typedef struct { + rnti_t rnti; + //array containing the pdus of DCI + uint8_t *a[2]; + //Array containing encoded DCI data + uint8_t *e[2]; + + //UE specific parameters + uint16_t npdcch_NumRepetitions; + + uint16_t repetition_number; + //indicate the corresponding subframe within the repetition (set to 0 when a new NPDCCH pdu is received) + uint16_t repetition_idx; + + // uint16_t npdcch_Offset_USS; + // uint16_t npdcch_StartSF_USS; + + +}NB_IoT_eNB_NPDCCH_t; + + +typedef struct{ + + //Number of repetitions (R) for common search space (RAR and PAGING) + uint16_t number_repetition_RA; + uint16_t number_repetition_PAg; + //index of the current subframe among the repetition (set to 0 when we receive the new NPDCCH) + uint16_t repetition_idx_RA; + uint16_t repetition_idx_Pag; + +}NB_IoT_eNB_COMMON_NPDCCH_t; + + +typedef struct { + + /// Length of DCI in bits + uint8_t dci_length; + /// Aggregation level only 1,2 in NB-IoT + uint8_t L; + /// Position of first CCE of the dci + int firstCCE; + /// flag to indicate that this is a RA response + boolean_t ra_flag; + /// rnti + rnti_t rnti; + /// Format + DCI_format_NB_IoT_t format; + /// DCI pdu + uint8_t dci_pdu[8]; + +} DCI_ALLOC_NB_IoT_t; + + +typedef struct { + //delete the count for the DCI numbers,NUM_DCI_MAX should set to 2 + uint32_t num_npdcch_symbols; + ///indicates the starting OFDM symbol in the first slot of a subframe k for the NPDCCH transmission + /// see FAPI/NFAPI specs Table 4-45 + uint8_t npdcch_start_symbol; + uint8_t Num_dci; + DCI_ALLOC_NB_IoT_t dci_alloc[2] ; + +} DCI_PDU_NB_IoT; + + + + +typedef struct { + /// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding) + int32_t *txdataF[8]; + /// dl channel estimates (estimated from ul channel estimates) + int32_t **calib_dl_ch_estimates; + /// Allocated RNTI (0 means DLSCH_t is not currently used) + uint16_t rnti; + /// Active flag for baseband transmitter processing + uint8_t active; + /// Indicator of TX activation per subframe. Used during PUCCH detection for ACK/NAK. + uint8_t subframe_tx[10]; + /// First CCE of last PDSCH scheduling per subframe. Again used during PUCCH detection for ACK/NAK. + uint8_t nCCE[10]; + /*in NB-IoT there is only 1 HARQ process for each UE therefore no pid is required*/ + /// The only HARQ process for the DLSCH + NB_IoT_DL_eNB_HARQ_t *harq_process; + /// Number of soft channel bits + uint32_t G; + /// Maximum number of HARQ rounds + uint8_t Mlimit; + /// Nsoft parameter related to UE Category + uint32_t Nsoft; + /// amplitude of PDSCH (compared to RS) in symbols without pilots + int16_t sqrt_rho_a; + /// amplitude of PDSCH (compared to RS) in symbols containing pilots + int16_t sqrt_rho_b; + ///NB-IoT + /// may use in the npdsch_procedures + uint16_t scrambling_sequence_intialization; + /// number of cell specific TX antenna ports assumed by the UE + uint8_t nrs_antenna_ports; + + //This indicate the current subframe within the subframe interval between the NPDSCH transmission (Nsf*Nrep) + uint16_t sf_index; + ///indicates the starting OFDM symbol in the first slot of a subframe k for the NPDSCH transmission + /// see FAPI/NFAPI specs Table 4-47 + uint8_t npdsch_start_symbol; + /*SIB1-NB related parameters*/ + ///flag for indicate if the current frame is the start of a new SIB1-NB repetition within the SIB1-NB period (0 = FALSE, 1 = TRUE) + uint8_t sib1_rep_start; + ///the number of the frame within the 16 continuous frame in which sib1-NB is transmitted (1-8 = 1st, 2nd ecc..) (0 = not foresees a transmission) + uint8_t relative_sib1_frame; + //Flag used to discern among different NDLSCH structures (SIB1,SI,RA,UE-spec) + //(used inside the ndlsch procedure for distinguish the different type of data to manage also in term of repetitions and transmission over more subframes + ndlsch_flag_t ndlsch_type; + +} NB_IoT_eNB_NDLSCH_t; + +typedef struct { + /// Length of CQI data under RI=1 assumption(bits) + uint8_t Or1; + /// Rank information + uint8_t o_RI[2]; + /// Format of CQI data + UCI_format_NB_IoT_t uci_format; + /// The value of DAI in DCI format 0 + uint8_t V_UL_DAI; + /// Pointer to CQI data + uint8_t o[MAX_CQI_BYTES_NB_IoT]; + /// CQI CRC status + uint8_t cqi_crc_status; + /// PHICH active flag + uint8_t phich_active; + /// PHICH ACK + uint8_t phich_ACK; + /// Length of rank information (bits) + uint8_t O_RI; + /// First Allocated RB + uint16_t first_rb; + /// Current Number of RBs + uint16_t nb_rb; + /// Determined the subcarrier allocation for the NPUSCH.(15, 3.75 KHz) + uint8_t subcarrier_indication; + /// Determined the number of resource unit for the NPUSCH + uint8_t resource_assignment; + /// Determined the scheduling delay for NPUSCH + uint8_t scheduling_delay; + /// The number of the repetition number for NPUSCH Transport block + uint8_t repetition_number; + /// Determined the repetition number value 0-3 + uint8_t dci_subframe_repetitions; + /// Flag indicating that this ULSCH has been allocated by a DCI (otherwise it is a retransmission based on PHICH NAK) + uint8_t dci_alloc; + /// Flag indicating that this ULSCH has been allocated by a RAR (otherwise it is a retransmission based on PHICH NAK or DCI) + uint8_t rar_alloc; + /// Status Flag indicating for this ULSCH (idle,active,disabled) + SCH_status_NB_IoT_t status; + /// Subframe scheduling indicator (i.e. Transmission opportunity indicator) + uint8_t subframe_scheduling_flag; + /// Transport block size + uint32_t TBS; + /// The payload + CRC size in bits + uint32_t B; + /// Number of soft channel bits + uint32_t G; + /// Pointer to ACK + uint8_t o_ACK[4]; + /// Length of ACK information (bits) + uint8_t O_ACK; + /// coded ACK bits + int16_t q_ACK[MAX_ACK_PAYLOAD_NB_IoT]; + /// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9) + /// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18) + int16_t e[MAX_NUM_CHANNEL_BITS_NB_IoT] __attribute__((aligned(32))); + /// coded RI bits + int16_t q_RI[MAX_RI_PAYLOAD_NB_IoT]; + /// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27) + int8_t q[MAX_CQI_PAYLOAD_NB_IoT]; + /// number of coded CQI bits after interleaving + uint8_t o_RCC; + /// coded and interleaved CQI bits + int8_t o_w[(MAX_CQI_BITS_NB_IoT+8)*3]; + /// coded CQI bits + int8_t o_d[96+((MAX_CQI_BITS_NB_IoT+8)*3)]; + /// + uint32_t C; + /// Number of "small" code segments (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Cminus; + /// Number of "large" code segments (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Cplus; + /// Number of bits in "small" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Kminus; + /// Number of bits in "large" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Kplus; + /// Number of "Filler" bits (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t F; + /// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled + //uint8_t h[MAX_NUM_CHANNEL_BITS]; + /// SRS active flag + uint8_t srs_active; + /// Pointer to the payload + uint8_t *b; + /// Current Number of Symbols + uint8_t Nsymb_pusch; + /// Index of current HARQ round for this ULSCH + uint8_t round; + /// MCS format for this ULSCH + uint8_t mcs; + /// Redundancy-version of the current sub-frame (value 0->RV0,value 1 ->RV2) + uint8_t rvidx; + /// Msc_initial, Initial number of subcarriers for ULSCH (36-212, v8.6 2009-03, p.26-27) + uint16_t Msc_initial; + /// Nsymb_initial, Initial number of symbols for ULSCH (36-212, v8.6 2009-03, p.26-27) + uint8_t Nsymb_initial; + /// n_DMRS for cyclic shift of DMRS (36.213 Table 9.1.2-2) + uint8_t n_DMRS; + /// n_DMRS for cyclic shift of DMRS (36.213 Table 9.1.2-2) - previous scheduling + /// This is needed for PHICH generation which + /// is done after a new scheduling + uint8_t previous_n_DMRS; + /// n_DMRS 2 for cyclic shift of DMRS (36.211 Table 5.5.1.1.-1) + uint8_t n_DMRS2; + /// Flag to indicate that this ULSCH is for calibration information sent from UE (i.e. no MAC SDU to pass up) + // int calibration_flag; + /// delta_TF for power control + int32_t delta_TF; + ///////////////////////////////////////////// 4 parameter added by vincent /////////////////////////////////////////////// + // NB_IoT: Nsymb_UL and Nslot_UL are defined in 36.211, Section 10.1.2.3, Table 10.1.2.3-1 + // The number of symbol in a resource unit is given by Nsymb_UL*Nslot_UL + uint8_t Nsymb_UL; + // Number of NPUSCH slots + uint8_t Nslot_UL; + // Number of subcarrier for NPUSH, can be 1, 3, 6, 12 + uint8_t N_sc_RU; + // Index of UL NB_IoT resource block + uint32_t UL_RB_ID_NB_IoT; + // Subcarrier indication fields, obtained through DCI, Section 16.5.1.1 in 36.213 + uint16_t I_sc; + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +} NB_IoT_UL_eNB_HARQ_t; + + +typedef struct { + /// Pointers to the HARQ processes for the NULSCH + NB_IoT_UL_eNB_HARQ_t *harq_process; + /// Maximum number of HARQ rounds + uint8_t Mlimit; + /// Value 0 = npush format 1 (data) value 1 = npusch format 2 (ACK/NAK) + uint8_t npusch_format; + /// Flag to indicate that eNB awaits UE Msg3 + uint8_t Msg3_active; + /// Flag to indicate that eNB should decode UE Msg3 + uint8_t Msg3_flag; + /// Subframe for Msg3 + uint8_t Msg3_subframe; + /// Frame for Msg3 + uint32_t Msg3_frame; + /// RNTI attributed to this ULSCH + uint16_t rnti; + /// cyclic shift for DM RS + uint8_t cyclicShift; + /// cooperation flag + uint8_t cooperation_flag; + /// (only in-band mode), indicate the resource block overlap the SRS configuration of LTE + uint8_t N_srs; + /// + uint8_t scrambling_re_intialization_batch_index; + /// number of cell specific TX antenna ports assumed by the UE + uint8_t nrs_antenna_ports; + /// + uint16_t scrambling_sequence_intialization; + /// + uint16_t sf_index; + /// Determined the ACK/NACK delay and the subcarrier allocation TS 36.213 Table 16.4.2 + uint8_t HARQ_ACK_resource; + + ///////////// kept from LTE /////////////////////////////////////////////////// + + /// Maximum number of iterations used in eNB turbo decoder + uint8_t max_turbo_iterations; + /// ACK/NAK Bundling flag + uint8_t bundling; + /// beta_offset_cqi times 8 + uint16_t beta_offset_cqi_times8; + /// beta_offset_ri times 8 + uint16_t beta_offset_ri_times8; + /// beta_offset_harqack times 8 + uint16_t beta_offset_harqack_times8; + /// num active cba group + uint8_t num_active_cba_groups; + /// allocated CBA RNTI for this ulsch + uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP]; + #ifdef LOCALIZATION + /// epoch timestamp in millisecond + int32_t reference_timestamp_ms; + /// aggregate physical states every n millisecond + int32_t aggregation_period_ms; + /// a set of lists used for localization + struct list loc_rss_list[10], loc_rssi_list[10], loc_subcarrier_rss_list[10], loc_timing_advance_list[10], loc_timing_update_list[10]; + struct list tot_loc_rss_list, tot_loc_rssi_list, tot_loc_subcarrier_rss_list, tot_loc_timing_advance_list, tot_loc_timing_update_list; + #endif + +} NB_IoT_eNB_NULSCH_t; + +#define NPBCH_A 34 + +typedef struct { + //the 2 LSB of the hsfn (the MSB are indicated by the SIB1-NB) + uint16_t h_sfn_lsb; + + uint8_t npbch_d[96+(3*(16+NPBCH_A))]; + uint8_t npbch_w[3*3*(16+NPBCH_A)]; + uint8_t npbch_e[1600]; + ///pdu of the npbch message + uint8_t *pdu; + +} NB_IoT_eNB_NPBCH_t; + + +#endif diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c index 46689a9aaa..7682045ae1 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c @@ -40,7 +40,7 @@ //#define DEBUG_LLR_SIC -int16_t zero[8] __attribute__ ((aligned(16))) = {0,0,0,0,0,0,0,0}; +int16_t zeros[8] __attribute__ ((aligned(16))) = {0,0,0,0,0,0,0,0}; int16_t ones[8] __attribute__ ((aligned(16))) = {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff}; #if defined(__x86_64__) || defined(__i386__) __m128i rho_rpi __attribute__ ((aligned(16))); diff --git a/openair1/PHY/LTE_TRANSPORT/proto_NB_IoT.h b/openair1/PHY/LTE_TRANSPORT/proto_NB_IoT.h new file mode 100644 index 0000000000..9e3a55eacc --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/proto_NB_IoT.h @@ -0,0 +1,362 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file PHY/LTE_TRANSPORT/proto.h + * \brief Function prototypes for PHY physical/transport channel processing and generation V8.6 2009-03 + * \author R. Knopp, F. Kaltenberger + * \date 2011 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr + * \note + * \warning + */ +#ifndef __LTE_TRANSPORT_PROTO_NB_IOT__H__ +#define __LTE_TRANSPORT_PROTO_NB_IOT__H__ +#include "PHY/defs_L1_NB_IoT.h" +//#include + +//NPSS + +int generate_npss_NB_IoT(int32_t **txdataF, + short amp, + NB_IoT_DL_FRAME_PARMS *frame_parms, + unsigned short symbol_offset, // symbol_offset should equal to 3 for NB-IoT + unsigned short slot_offset, + unsigned short RB_IoT_ID); // new attribute (values are between 0.. Max_RB_number-1), it does not exist for LTE + +//NSSS + +int generate_sss_NB_IoT(int32_t **txdataF, + int16_t amp, + NB_IoT_DL_FRAME_PARMS *frame_parms, + uint16_t symbol_offset, // symbol_offset = 3 for NB-IoT + uint16_t slot_offset, + unsigned short frame_number, // new attribute (Get value from higher layer), it does not exist for LTE + unsigned short RB_IoT_ID); // new attribute (values are between 0.. Max_RB_number-1), it does not exist for LTE + +//*****************Vincent part for Cell ID estimation from NSSS ******************// + +int rx_nsss_NB_IoT(PHY_VARS_UE_NB_IoT *ue,int32_t *tot_metric); + +int nsss_extract_NB_IoT(PHY_VARS_UE_NB_IoT *ue, + NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t **nsss_ext, + int l); + +//NRS + +void generate_pilots_NB_IoT(PHY_VARS_eNB_NB_IoT *phy_vars_eNB, + int32_t **txdataF, + int16_t amp, + uint16_t Ntti, // Ntti = 10 + unsigned short RB_IoT_ID, // RB reserved for NB-IoT + unsigned short With_NSSS); // With_NSSS = 1; if the frame include a sub-Frame with NSSS signal + + +//NPBCH + +int allocate_npbch_REs_in_RB(NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t **txdataF, + uint32_t *jj, + uint32_t symbol_offset, + uint8_t *x0, + uint8_t pilots, + int16_t amp, + unsigned short id_offset, + uint32_t *re_allocated); + + +int generate_npbch(NB_IoT_eNB_NPBCH_t *eNB_npbch, + int32_t **txdataF, + int amp, + NB_IoT_DL_FRAME_PARMS *frame_parms, + uint8_t *npbch_pdu, + uint8_t frame_mod64, + unsigned short NB_IoT_RB_ID); + + +void npbch_scrambling(NB_IoT_DL_FRAME_PARMS *frame_parms, + uint8_t *npbch_e, + uint32_t length); + +// Functions below implement 36-211 and 36-212 + +/*Function to pack the DCI*/ +// newly added function for NB-IoT , does not exist for LTE +void add_dci_NB_IoT(DCI_PDU_NB_IoT *DCI_pdu, + void *pdu, + rnti_t rnti, + unsigned char dci_size_bytes, + unsigned char aggregation, + unsigned char dci_size_bits, + unsigned char dci_fmt, + uint8_t npdcch_start_symbol); + + +/*Use the UL DCI Information to configure PHY and also Pack the DCI*/ +int generate_eNB_ulsch_params_from_dci_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, + eNB_rxtx_proc_NB_IoT_t *proc, + DCI_CONTENT *DCI_Content, + uint16_t rnti, + DCI_format_NB_IoT_t dci_format, + uint8_t UE_id, + uint8_t aggregation, + uint8_t npdcch_start_symbol); + + +/*Use the DL DCI Information to configure PHY and also Pack the DCI*/ +int generate_eNB_dlsch_params_from_dci_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, + int frame, + uint8_t subframe, + DCI_CONTENT *DCI_Content, + uint16_t rnti, + DCI_format_NB_IoT_t dci_format, + NB_IoT_eNB_NDLSCH_t *ndlsch, + NB_IoT_DL_FRAME_PARMS *frame_parms, + uint8_t aggregation, + uint8_t npdcch_start_symbol); + + +/*Function for DCI encoding, scrambling, modulation*/ +uint8_t generate_dci_top_NB_IoT(NB_IoT_eNB_NPDCCH_t *npdcch, + uint8_t Num_dci, + DCI_ALLOC_NB_IoT_t *dci_alloc, + int16_t amp, + NB_IoT_DL_FRAME_PARMS *fp, + int32_t **txdataF, + uint32_t subframe, + uint8_t npdcch_start_symbol); + +/*! + \brief Decoding of PUSCH/ACK/RI/ACK from 36-212. + @param phy_vars_eNB Pointer to eNB top-level descriptor + @param proc Pointer to RXTX proc variables + @param UE_id ID of UE transmitting this PUSCH + @param subframe Index of subframe for PUSCH + @param control_only_flag Receive PUSCH with control information only + @param Nbundled Nbundled parameter for ACK/NAK scrambling from 36-212/36-213 + @param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used + @returns 0 on success +*/ +unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *phy_vars_eNB, + eNB_rxtx_proc_NB_IoT_t *proc, + uint8_t UE_id, + uint8_t control_only_flag, + uint8_t Nbundled, + uint8_t llr8_flag); + +//NB-IoT version +NB_IoT_eNB_NDLSCH_t *new_eNB_dlsch_NB_IoT(//unsigned char Kmimo, + //unsigned char Mdlharq, + uint32_t Nsoft, + //unsigned char N_RB_DL, + uint8_t abstraction_flag, + NB_IoT_DL_FRAME_PARMS* frame_parms); + + +NB_IoT_eNB_NULSCH_t *new_eNB_ulsch_NB_IoT(uint8_t abstraction_flag); + + +uint8_t subframe2harq_pid_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t subframe); + + +/** \brief Compute Q (modulation order) based on I_MCS for PUSCH. Implements table 8.6.1-1 from 36.213. + @param I_MCS */ + +//uint8_t get_Qm_ul_NB_IoT(uint8_t I_MCS); +unsigned char get_Qm_ul_NB_IoT(unsigned char I_MCS, uint8_t N_sc_RU); + +/** \fn dlsch_encoding(PHY_VARS_eNB *eNB, + uint8_t *input_buffer, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t num_pdcch_symbols, + LTE_eNB_DLSCH_t *dlsch, + int frame, + uint8_t subframe) + \brief This function performs a subset of the bit-coding functions for LTE as described in 36-212, Release 8.Support is limited to turbo-coded channels (DLSCH/ULSCH). The implemented functions are: + - CRC computation and addition + - Code block segmentation and sub-block CRC addition + - Channel coding (Turbo coding) + - Rate matching (sub-block interleaving, bit collection, selection and transmission + - Code block concatenation + @param eNB Pointer to eNB PHY context + @param input_buffer Pointer to input buffer for sub-frame + @param frame_parms Pointer to frame descriptor structure + @param num_pdcch_symbols Number of PDCCH symbols in this subframe + @param dlsch Pointer to dlsch to be encoded + @param frame Frame number + @param subframe Subframe number + @param rm_stats Time statistics for rate-matching + @param te_stats Time statistics for turbo-encoding + @param i_stats Time statistics for interleaving + @returns status +*/ + +int32_t dlsch_encoding_NB_IoT(unsigned char *a, + NB_IoT_eNB_DLSCH_t *dlsch, + uint8_t Nsf, // number of subframes required for npdsch pdu transmission calculated from Isf (3GPP spec table) + unsigned int G, // G (number of available RE) is implicitly multiplied by 2 (since only QPSK modulation) + time_stats_t *rm_stats, + time_stats_t *te_stats, + time_stats_t *i_stats); + + +void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *phy_vars_eNB, + eNB_rxtx_proc_NB_IoT_t *proc, + uint8_t eNB_id, // this is the effective sector id + uint8_t UE_id, + NB_IoT_eNB_NULSCH_t **ulsch, + uint8_t cooperation_flag); + + + + +void ulsch_extract_rbs_single_NB_IoT(int32_t **rxdataF, + int32_t **rxdataF_ext, + // uint32_t first_rb, + //uint32_t UL_RB_ID_NB_IoT, // index of UL NB_IoT resource block + uint8_t N_sc_RU, // number of subcarriers in UL + uint32_t I_sc, // subcarrier indication field + uint32_t nb_rb, + uint8_t l, + uint8_t Ns, + NB_IoT_DL_FRAME_PARMS *frame_parms); + +void extract_CQI_NB_IoT(void *o,UCI_format_NB_IoT_t uci_format,NB_IoT_eNB_UE_stats *stats,uint8_t N_RB_DL, uint16_t * crnti, uint8_t * access_mode); + +//*****************Vincent part for nprach ******************// +void RX_NPRACH_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, int16_t *Rx_buffer); + +uint32_t TA_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, + int16_t *Rx_sub_sampled_buffer, + uint16_t sub_sampling_rate, + uint16_t FRAME_LENGTH_COMPLEX_SUB_SAMPLES, + uint32_t estimated_TA_coarse, + char coarse); + +uint8_t NPRACH_detection_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, int16_t *Rx_sub_sampled_buffer, uint16_t sub_sampling_rate, uint32_t FRAME_LENGTH_COMPLEX_SUB_SAMPLES); + +int16_t* sub_sampling_NB_IoT(int16_t *input_buffer, uint32_t length_input, uint32_t *length_ouput, uint16_t sub_sampling_rate); +//************************************************************// +//*****************Vincent part for ULSCH demodulation ******************// +uint16_t get_UL_sc_start_NB_IoT(uint16_t I_sc); + +void generate_grouphop_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms); + +void init_ul_hopping_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms); + +void rotate_single_carrier_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, + NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + uint8_t UE_id, + uint8_t symbol, + uint8_t Qm); + +void fill_rbs_zeros_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, + NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + uint8_t UE_id, + uint8_t symbol); + +int32_t ulsch_bpsk_llr_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, + NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + int16_t *ulsch_llr, + uint8_t symbol, + uint8_t uint8_t, + int16_t **llrp); + + +int32_t ulsch_qpsk_llr_NB_IoT( + NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + int16_t *ulsch_llr, + uint8_t symbol, + uint8_t nb_rb, + int16_t **llrp); + +void rotate_bpsk_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, + NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + uint8_t UE_id, + uint8_t symbol); +//************************************************************// + +//************************************************************// +//*****************Vincent part for DLSCH demodulation ******************// + +int rx_npdsch_NB_IoT(PHY_VARS_UE_NB_IoT *ue, + unsigned char eNB_id, + unsigned char eNB_id_i, //if this == ue->n_connected_eNB, we assume MU interference + uint32_t frame, + uint8_t subframe, + unsigned char symbol, + unsigned char first_symbol_flag, + unsigned char i_mod, + unsigned char harq_pid); + +unsigned short dlsch_extract_rbs_single_NB_IoT(int **rxdataF, + int **dl_ch_estimates, + int **rxdataF_ext, + int **dl_ch_estimates_ext, + unsigned short pmi, + unsigned char *pmi_ext, + unsigned int *rb_alloc, + unsigned char symbol, + unsigned char subframe, + uint32_t frame, + uint32_t high_speed_flag, + NB_IoT_DL_FRAME_PARMS *frame_parms); + +void dlsch_channel_level_NB_IoT(int **dl_ch_estimates_ext, + NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t *avg, + uint8_t symbol, + unsigned short nb_rb); + +void dlsch_channel_compensation_NB_IoT(int **rxdataF_ext, + int **dl_ch_estimates_ext, + int **dl_ch_mag, + int **dl_ch_magb, + int **rxdataF_comp, + int **rho, + NB_IoT_DL_FRAME_PARMS *frame_parms, + unsigned char symbol, + uint8_t first_symbol_flag, + unsigned char mod_order, + unsigned short nb_rb, + unsigned char output_shift, + PHY_MEASUREMENTS_NB_IoT *measurements); + +int dlsch_qpsk_llr_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + int16_t *dlsch_llr, + uint8_t symbol, + uint8_t first_symbol_flag, + uint16_t nb_rb, + int16_t **llr32p, + uint8_t beamforming_mode); + +//************************************************************// + + +#endif diff --git a/openair1/PHY/LTE_TRANSPORT/uci_NB_IoT.h b/openair1/PHY/LTE_TRANSPORT/uci_NB_IoT.h new file mode 100644 index 0000000000..b20635360d --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/uci_NB_IoT.h @@ -0,0 +1,324 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef __UCI_NB_IOT__H__ +#define __UCI_NB_IOT__H__ +//#include "PHY/types_NB_IoT.h" + + + +typedef enum { + ue_selected_NB_IoT, + wideband_cqi_rank1_2A_NB_IoT, //wideband_cqi_rank1_2A, + wideband_cqi_rank2_2A_NB_IoT, //wideband_cqi_rank2_2A, + HLC_subband_cqi_nopmi_NB_IoT, //HLC_subband_cqi_nopmi, + HLC_subband_cqi_rank1_2A_NB_IoT, //HLC_subband_cqi_rank1_2A, + HLC_subband_cqi_rank2_2A_NB_IoT, //HLC_subband_cqi_rank2_2A, + HLC_subband_cqi_modes123_NB_IoT, //HLC_subband_cqi_modes123 + HLC_subband_cqi_mcs_CBA_NB_IoT, // MCS and RNTI, for contention-based acces + unknown_cqi_NB_IoT// +} UCI_format_NB_IoT_t; + +// **********************************************1.5 MHz*************************************************************************** +typedef struct __attribute__((packed)) +{ + uint32_t padding:16; + uint32_t pmi:12; + uint32_t cqi1:4; +} +wideband_cqi_rank1_2A_1_5MHz_NB_IoT ; +#define sizeof_wideband_cqi_rank1_2A_1_5MHz_NB_IoT 16 + +typedef struct __attribute__((packed)) +{ + uint16_t padding:2; + uint16_t pmi:6; + uint16_t cqi2:4; + uint16_t cqi1:4; +} +wideband_cqi_rank2_2A_1_5MHz_NB_IoT ; +#define sizeof_wideband_cqi_rank2_2A_1_5MHz_NB_IoT 14 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:16; + uint32_t diffcqi1:12; + uint32_t cqi1:4; +} +HLC_subband_cqi_nopmi_1_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_nopmi_1_5MHz_NB_IoT 16 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:14; + uint32_t pmi:2; + uint32_t diffcqi1:12; + uint32_t cqi1:4; +} +HLC_subband_cqi_rank1_2A_1_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_rank1_2A_1_5MHz_NB_IoT 18 + +typedef struct __attribute__((packed)) +{ + uint64_t padding:31; + uint64_t pmi:1; + uint64_t diffcqi2:12; + uint64_t cqi2:4; + uint64_t diffcqi1:12; + uint64_t cqi1:4; +} +HLC_subband_cqi_rank2_2A_1_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_rank2_2A_1_5MHz_NB_IoT 33 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:16; + uint32_t diffcqi1:12; + uint32_t cqi1:4; +} +HLC_subband_cqi_modes123_1_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_modes123_1_5MHz_NB_IoT 16 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:11; + uint32_t crnti:16; + uint32_t mcs:5; +} +HLC_subband_cqi_mcs_CBA_1_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz_NB_IoT 21 + + +// **********************************************5 MHz*************************************************************************** +typedef struct __attribute__((packed)) +{ + uint32_t padding:14; + uint32_t pmi:14; + uint32_t cqi1:4; +} +wideband_cqi_rank1_2A_5MHz_NB_IoT ; +#define sizeof_wideband_cqi_rank1_2A_5MHz_NB_IoT 18 + +typedef struct __attribute__((packed)) +{ + uint16_t padding:1; + uint16_t pmi:7; + uint16_t cqi2:4; + uint16_t cqi1:4; +} +wideband_cqi_rank2_2A_5MHz_NB_IoT ; +#define sizeof_wideband_cqi_rank2_2A_5MHz_NB_IoT 15 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:14; + uint32_t diffcqi1:14; + uint32_t cqi1:4; +} +HLC_subband_cqi_nopmi_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_nopmi_5MHz_NB_IoT 18 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:12; + uint32_t pmi:2; + uint32_t diffcqi1:14; + uint32_t cqi1:4; +} +HLC_subband_cqi_rank1_2A_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_rank1_2A_5MHz_NB_IoT 20 + +typedef struct __attribute__((packed)) +{ + uint64_t padding:27; + uint64_t pmi:1; + uint64_t diffcqi2:14; + uint64_t cqi2:4; + uint64_t diffcqi1:14; + uint64_t cqi1:4; +} +HLC_subband_cqi_rank2_2A_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_rank2_2A_5MHz_NB_IoT 37 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:14; + uint32_t diffcqi1:14; + uint32_t cqi1:4; +} +HLC_subband_cqi_modes123_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_modes123_5MHz_NB_IoT 18 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:11; + uint32_t crnti:16; + uint32_t mcs:5; +} +HLC_subband_cqi_mcs_CBA_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_mcs_CBA_5MHz_NB_IoT 21 + +// **********************************************10 MHz*************************************************************************** +typedef struct __attribute__((packed)) +{ + uint32_t padding:10; + uint32_t pmi:18; + uint32_t cqi1:4; +} +wideband_cqi_rank1_2A_10MHz_NB_IoT ; +#define sizeof_wideband_cqi_rank1_2A_10MHz_NB_IoT 22 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:15; + uint32_t pmi:9; + uint32_t cqi2:4; + uint32_t cqi1:4; +} +wideband_cqi_rank2_2A_10MHz_NB_IoT ; +#define sizeof_wideband_cqi_rank2_2A_10MHz_NB_IoT 17 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:10; + uint32_t diffcqi1:18; + uint32_t cqi1:4; +} +HLC_subband_cqi_nopmi_10MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_nopmi_10MHz_NB_IoT 22 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:8; + uint32_t pmi:2; + uint32_t diffcqi1:18; + uint32_t cqi1:4; +} +HLC_subband_cqi_rank1_2A_10MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_rank1_2A_10MHz_NB_IoT 24 + +typedef struct __attribute__((packed)) +{ + uint64_t padding:19; + uint64_t pmi:1; + uint64_t diffcqi2:18; + uint64_t cqi2:4; + uint64_t diffcqi1:18; + uint64_t cqi1:4; +} +HLC_subband_cqi_rank2_2A_10MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_rank2_2A_10MHz_NB_IoT 45 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:10; + uint32_t diffcqi1:18; + uint32_t cqi1:4; +} +HLC_subband_cqi_modes123_10MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_modes123_10MHz_NB_IoT 22 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:11; + uint32_t crnti:16; + uint32_t mcs:5; +} +HLC_subband_cqi_mcs_CBA_10MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_mcs_CBA_10MHz_NB_IoT 21 + +// **********************************************20 MHz*************************************************************************** +typedef struct __attribute__((packed)) +{ + uint32_t padding:2; + uint32_t pmi:26; + uint32_t cqi1:4; +} +wideband_cqi_rank1_2A_20MHz_NB_IoT ; +#define sizeof_wideband_cqi_rank1_2A_20MHz_NB_IoT 20 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:11; + uint32_t pmi:13; + uint32_t cqi2:4; + uint32_t cqi1:4; +} +wideband_cqi_rank2_2A_20MHz_NB_IoT ; +#define sizeof_wideband_cqi_rank2_2A_20MHz_NB_IoT 21 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:2; + uint32_t diffcqi1:26; + uint32_t cqi1:4; +} +HLC_subband_cqi_nopmi_20MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_nopmi_20MHz_NB_IoT 30 + +typedef struct __attribute__((packed)) +{ + // uint32_t padding:12; + uint32_t pmi:2; + uint32_t diffcqi1:26; + uint32_t cqi1:4; +} +HLC_subband_cqi_rank1_2A_20MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_rank1_2A_20MHz_NB_IoT 32 + +typedef struct __attribute__((packed)) +{ + uint64_t padding:3; + uint64_t pmi:1; + uint64_t diffcqi2:26; + uint64_t cqi2:4; + uint64_t diffcqi1:26; + uint64_t cqi1:4; +} +HLC_subband_cqi_rank2_2A_20MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_rank2_2A_20MHz_NB_IoT 61 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:2; + uint32_t diffcqi1:26; + uint32_t cqi1:4; +} +HLC_subband_cqi_modes123_20MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_modes123_20MHz_NB_IoT 30 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:11; + uint32_t crnti:16; + uint32_t mcs:5; +} +HLC_subband_cqi_mcs_CBA_20MHz_NB_IoT; + +#define sizeof_HLC_subband_cqi_mcs_CBA_20MHz_NB_IoT 21 + +#define MAX_CQI_PAYLOAD_NB_IoT (sizeof(HLC_subband_cqi_rank2_2A_20MHz_NB_IoT)*8*20) +#define MAX_CQI_BITS_NB_IoT (sizeof(HLC_subband_cqi_rank2_2A_20MHz_NB_IoT)*8) +#define MAX_CQI_BYTES_NB_IoT (sizeof(HLC_subband_cqi_rank2_2A_20MHz_NB_IoT)) +#define MAX_ACK_PAYLOAD_NB_IoT 18 +#define MAX_RI_PAYLOAD_NB_IoT 6 + +#endif \ No newline at end of file diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index 1b6c1c9153..eb86af9165 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -162,7 +162,7 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, int16_t **chest_t; int16_t **chest_f; int16_t *pusch_llr; - int16_t *pusch_comp; + int32_t *pusch_comp; int32_t *pucch1_comp; int32_t *pucch1_thres; int32_t *pucch1ab_comp; @@ -200,7 +200,7 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, chest_t = (int16_t**) phy_vars_enb->srs_vars[UE_id].srs_ch_estimates[eNB_id]; chest_f = (int16_t**) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates[eNB_id]; pusch_llr = (int16_t*) phy_vars_enb->pusch_vars[UE_id]->llr; - pusch_comp = (int16_t*) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[0]; + pusch_comp = (int32_t*) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[0]; pucch1_comp = (int32_t*) phy_vars_enb->pucch1_stats[UE_id]; pucch1_thres = (int32_t*) phy_vars_enb->pucch1_stats_thres[UE_id]; pucch1ab_comp = (int32_t*) phy_vars_enb->pucch1ab_stats[UE_id]; diff --git a/openair1/PHY/defs_L1_NB_IoT.h b/openair1/PHY/defs_L1_NB_IoT.h new file mode 100644 index 0000000000..b9368b76e3 --- /dev/null +++ b/openair1/PHY/defs_L1_NB_IoT.h @@ -0,0 +1,1031 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file PHY/defs.h + \brief Top-level defines and structure definitions + \author R. Knopp, F. Kaltenberger + \date 2011 + \version 0.1 + \company Eurecom + \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr + \note + \warning +*/ +#ifndef __PHY_DEFS_NB_IOT__H__ +#define __PHY_DEFS_NB_IOT__H__ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include "common_lib.h" +#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h" + +//#include +#include "assertions.h" +#ifdef MEX +# define msg mexPrintf +#else +# ifdef OPENAIR2 +# if ENABLE_RAL +# include "collection/hashtable/hashtable.h" +# include "COMMON/ral_messages_types.h" +# include "UTIL/queue.h" +# endif +# include "log.h" +# define msg(aRGS...) LOG_D(PHY, ##aRGS) +# else +# define msg printf +# endif +#endif +//use msg in the real-time thread context +#define msg_nrt printf +//use msg_nrt in the non real-time context (for initialization, ...) +#ifndef malloc16 +# ifdef __AVX2__ +# define malloc16(x) memalign(32,x) +# else +# define malloc16(x) memalign(16,x) +# endif +#endif +#define free16(y,x) free(y) +#define bigmalloc malloc +#define bigmalloc16 malloc16 +#define openair_free(y,x) free((y)) +#define PAGE_SIZE 4096 + +//#ifdef SHRLIBDEV +//extern int rxrescale; +//#define RX_IQRESCALELEN rxrescale +//#else +//#define RX_IQRESCALELEN 15 +//#endif + +//! \brief Allocate \c size bytes of memory on the heap with alignment 16 and zero it afterwards. +//! If no more memory is available, this function will terminate the program with an assertion error. +//****************************************************************************************************** +/* +static inline void* malloc16_clear( size_t size ) +{ +#ifdef __AVX2__ + void* ptr = memalign(32, size); +#else + void* ptr = memalign(16, size); +#endif + DevAssert(ptr); + memset( ptr, 0, size ); + return ptr; +} + +*/ + + +// #define PAGE_MASK 0xfffff000 +// #define virt_to_phys(x) (x) + +// #define openair_sched_exit() exit(-1) + + +// #define max(a,b) ((a)>(b) ? (a) : (b)) +// #define min(a,b) ((a)<(b) ? (a) : (b)) + + +// #define bzero(s,n) (memset((s),0,(n))) + +// #define cmax(a,b) ((a>b) ? (a) : (b)) +// #define cmin(a,b) ((ac) ? (cmax(a,b)) : (c)) + +// /// suppress compiler warning for unused arguments +// #define UNUSED(x) (void)x; + + +#include "PHY/impl_defs_top_NB_IoT.h" +//#include "impl_defs_top.h" +//#include "impl_defs_lte.h" +#include "PHY/impl_defs_lte_NB_IoT.h" + +#include "PHY/TOOLS/time_meas.h" +//#include "PHY/CODING/defs.h" +#include "PHY/CODING/defs_NB_IoT.h" +#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h" +//#include "PHY/TOOLS/defs.h" +//#include "platform_types.h" +///#include "openair1/PHY/LTE_TRANSPORT/defs_nb_iot.h" + +////////////////////////////////////////////////////////////////////#ifdef OPENAIR_LTE (check if this is required) + +//#include "PHY/LTE_TRANSPORT/defs.h" +#include "PHY/LTE_TRANSPORT/defs_NB_IoT.h" +#include + +#include "targets/ARCH/COMMON/common_lib.h" +#include "targets/COMMON/openairinterface5g_limits.h" + +#define NUM_DCI_MAX_NB_IoT 32 + +#define NUMBER_OF_eNB_SECTORS_MAX_NB_IoT 3 + +#define NB_BANDS_MAX_NB_IoT 8 + + +#ifdef OCP_FRAMEWORK +#include +#else +typedef enum {normal_txrx_NB_IoT=0,rx_calib_ue_NB_IoT=1,rx_calib_ue_med_NB_IoT=2,rx_calib_ue_byp_NB_IoT=3,debug_prach_NB_IoT=4,no_L2_connect_NB_IoT=5,calib_prach_tx_NB_IoT=6,rx_dump_frame_NB_IoT=7,loop_through_memory_NB_IoT=8} runmode_NB_IoT_t; +#endif +/* +enum transmission_access_mode { + NO_ACCESS=0, + POSTPONED_ACCESS, + CANCELED_ACCESS, + UNKNOWN_ACCESS, + SCHEDULED_ACCESS, + CBA_ACCESS}; + +typedef enum { + eNodeB_3GPP=0, // classical eNodeB function + eNodeB_3GPP_BBU, // eNodeB with NGFI IF5 + NGFI_RCC_IF4p5, // NGFI_RCC (NGFI radio cloud center) + NGFI_RAU_IF4p5, + NGFI_RRU_IF5, // NGFI_RRU (NGFI remote radio-unit,IF5) + NGFI_RRU_IF4p5 // NGFI_RRU (NGFI remote radio-unit,IF4p5) +} eNB_func_t; + +typedef enum { + synch_to_ext_device=0, // synch to RF or Ethernet device + synch_to_other // synch to another source (timer, other CC_id) +} eNB_timing_t; +#endif +*/ +typedef struct UE_SCAN_INFO_NB_IoT_s { + /// 10 best amplitudes (linear) for each pss signals + int32_t amp[3][10]; + /// 10 frequency offsets (kHz) corresponding to best amplitudes, with respect do minimum DL frequency in the band + int32_t freq_offset_Hz[3][10]; + +} UE_SCAN_INFO_NB_IoT_t; + +/// Top-level PHY Data Structure for RN +typedef struct { + /// Module ID indicator for this instance + uint8_t Mod_id; + uint32_t frame; + // phy_vars_eNB_NB_IoT + // phy_vars ue + // cuurently only used to store and forward the PMCH + uint8_t mch_avtive[10]; + uint8_t sync_area[10]; // num SF + NB_IoT_UE_DLSCH_t *dlsch_rn_MCH[10]; + +} PHY_VARS_RN_NB_IoT; +/* +#ifdef OCP_FRAMEWORK +#include +#else +//typedef enum {normal_txrx=0,rx_calib_ue=1,rx_calib_ue_med=2,rx_calib_ue_byp=3,debug_prach=4,no_L2_connect=5,calib_prach_tx=6,rx_dump_frame=7,loop_through_memory=8} runmode_t; +*/ +// enum transmission_access_mode { +// NO_ACCESS=0, +// POSTPONED_ACCESS, +// CANCELED_ACCESS, +// UNKNOWN_ACCESS, +// SCHEDULED_ACCESS, +// CBA_ACCESS}; + +typedef enum { + eNodeB_3GPP_NB_IoT=0, // classical eNodeB function + eNodeB_3GPP_BBU_NB_IoT, // eNodeB with NGFI IF5 + NGFI_RCC_IF4p5_NB_IoT, // NGFI_RCC (NGFI radio cloud center) + NGFI_RAU_IF4p5_NB_IoT, + NGFI_RRU_IF5_NB_IoT, // NGFI_RRU (NGFI remote radio-unit,IF5) + NGFI_RRU_IF4p5_NB_IoT // NGFI_RRU (NGFI remote radio-unit,IF4p5) +} eNB_func_NB_IoT_t; + +typedef enum { + + synch_to_ext_device_NB_IoT=0, // synch to RF or Ethernet device + synch_to_other_NB_IoT // synch to another source (timer, other CC_id) + +} eNB_timing_NB_IoT_t; +////////////////////////////////////////////////////////////////////#endif + + +typedef struct { + + struct PHY_VARS_eNB_NB_IoT_s *eNB; + NB_IoT_eNB_NDLSCH_t *dlsch; + int G; + +} te_params_NB_IoT; + + +typedef struct { + + struct PHY_VARS_eNB_NB_IoT_s *eNB; + int UE_id; + int harq_pid; + int llr8_flag; + int ret; + +} td_params_NB_IoT; + + +/// Context data structure for RX/TX portion of subframe processing +typedef struct { + /// timestamp transmitted to HW + openair0_timestamp timestamp_tx; + /// subframe to act upon for transmission + int subframe_tx; + /// subframe to act upon for reception + int subframe_rx; + /// frame to act upon for transmission + int frame_tx; + /// frame to act upon for reception + int frame_rx; + /// \brief Instance count for RXn-TXnp4 processing thread. + /// \internal This variable is protected by \ref mutex_rxtx. + int instance_cnt_rxtx; + /// pthread structure for RXn-TXnp4 processing thread + pthread_t pthread_rxtx; + /// pthread attributes for RXn-TXnp4 processing thread + pthread_attr_t attr_rxtx; + /// condition variable for tx processing thread + pthread_cond_t cond_rxtx; + /// mutex for RXn-TXnp4 processing thread + pthread_mutex_t mutex_rxtx; + /// scheduling parameters for RXn-TXnp4 thread + struct sched_param sched_param_rxtx; + /// NB-IoT for IF_Module + pthread_t pthread_l2; + pthread_cond_t cond_l2; + pthread_mutex_t mutex_l2; + int instance_cnt_l2; + pthread_attr_t attr_l2; + +} eNB_rxtx_proc_NB_IoT_t; +/* +typedef struct { + struct PHY_VARS_eNB_NB_IoT_s *eNB; + int UE_id; + int harq_pid; + int llr8_flag; + int ret; +} td_params; + +typedef struct { + struct PHY_VARS_eNB_NB_IoT_s *eNB; + LTE_eNB_DLSCH_t *dlsch; + int G; +} te_params; +*/ + +/// Context data structure for eNB subframe processing +typedef struct eNB_proc_NB_IoT_t_s { + /// thread index + int thread_index; + /// timestamp received from HW + openair0_timestamp timestamp_rx; + /// timestamp to send to "slave rru" + openair0_timestamp timestamp_tx; + /// subframe to act upon for reception + int subframe_rx; + /// symbol mask for IF4p5 reception per subframe + uint32_t symbol_mask[10]; + /// subframe to act upon for PRACH + int subframe_prach; + /// frame to act upon for reception + int frame_rx; + /// frame to act upon for transmission + int frame_tx; + /// frame offset for secondary eNBs (to correct for frame asynchronism at startup) + int frame_offset; + /// frame to act upon for PRACH + int frame_prach; + /// \internal This variable is protected by \ref mutex_fep. + int instance_cnt_fep; + /// \internal This variable is protected by \ref mutex_td. + int instance_cnt_td; + /// \internal This variable is protected by \ref mutex_te. + int instance_cnt_te; + /// \brief Instance count for FH processing thread. + /// \internal This variable is protected by \ref mutex_FH. + int instance_cnt_FH; + /// \brief Instance count for rx processing thread. + /// \internal This variable is protected by \ref mutex_prach. + int instance_cnt_prach; + // instance count for over-the-air eNB synchronization + int instance_cnt_synch; + /// \internal This variable is protected by \ref mutex_asynch_rxtx. + int instance_cnt_asynch_rxtx; + /// pthread structure for FH processing thread + pthread_t pthread_FH; + /// pthread structure for eNB single processing thread + pthread_t pthread_single; + /// pthread structure for asychronous RX/TX processing thread + pthread_t pthread_asynch_rxtx; + /// flag to indicate first RX acquisition + int first_rx; + /// flag to indicate first TX transmission + int first_tx; + /// pthread attributes for parallel fep thread + pthread_attr_t attr_fep; + /// pthread attributes for parallel turbo-decoder thread + pthread_attr_t attr_td; + /// pthread attributes for parallel turbo-encoder thread + pthread_attr_t attr_te; + /// pthread attributes for FH processing thread + pthread_attr_t attr_FH; + /// pthread attributes for single eNB processing thread + pthread_attr_t attr_single; + /// pthread attributes for prach processing thread + pthread_attr_t attr_prach; + /// pthread attributes for over-the-air synch thread + pthread_attr_t attr_synch; + /// pthread attributes for asynchronous RX thread + pthread_attr_t attr_asynch_rxtx; + /// scheduling parameters for parallel fep thread + struct sched_param sched_param_fep; + /// scheduling parameters for parallel turbo-decoder thread + struct sched_param sched_param_td; + /// scheduling parameters for parallel turbo-encoder thread + struct sched_param sched_param_te; + /// scheduling parameters for FH thread + struct sched_param sched_param_FH; + /// scheduling parameters for single eNB thread + struct sched_param sched_param_single; + /// scheduling parameters for prach thread + struct sched_param sched_param_prach; + /// scheduling parameters for over-the-air synchronization thread + struct sched_param sched_param_synch; + /// scheduling parameters for asynch_rxtx thread + struct sched_param sched_param_asynch_rxtx; + /// pthread structure for parallel fep thread + pthread_t pthread_fep; + /// pthread structure for parallel turbo-decoder thread + pthread_t pthread_td; + /// pthread structure for parallel turbo-encoder thread + pthread_t pthread_te; + /// pthread structure for PRACH thread + pthread_t pthread_prach; + /// pthread structure for eNB synch thread + pthread_t pthread_synch; + /// condition variable for parallel fep thread + pthread_cond_t cond_fep; + /// condition variable for parallel turbo-decoder thread + pthread_cond_t cond_td; + /// condition variable for parallel turbo-encoder thread + pthread_cond_t cond_te; + /// condition variable for FH thread + pthread_cond_t cond_FH; + /// condition variable for PRACH processing thread; + pthread_cond_t cond_prach; + // condition variable for over-the-air eNB synchronization + pthread_cond_t cond_synch; + /// condition variable for asynch RX/TX thread + pthread_cond_t cond_asynch_rxtx; + /// mutex for RU access to processing (NPDSCH/PUSCH) + pthread_mutex_t mutex_RU; + /// mutex for parallel fep thread + pthread_mutex_t mutex_fep; + /// mutex for parallel turbo-decoder thread + pthread_mutex_t mutex_td; + /// mutex for parallel turbo-encoder thread + pthread_mutex_t mutex_te; + /// mutex for FH + pthread_mutex_t mutex_FH; + /// mutex for PRACH thread + pthread_mutex_t mutex_prach; + // mutex for over-the-air eNB synchronization + pthread_mutex_t mutex_synch; + /// mutex for RU access to NB-IoT processing (NPRACH) + pthread_mutex_t mutex_RU_PRACH; + /// mutex for asynch RX/TX thread + pthread_mutex_t mutex_asynch_rxtx; + /// mask for RUs serving nbiot (NPDSCH/NPUSCH) + int RU_mask; + /// mask for RUs serving nbiot (PRACH) + int RU_mask_prach; +#ifdef Rel14 + /// mask for RUs serving eNB (PRACH) + int RU_mask_prach_br; +#endif + /// parameters for turbo-decoding worker thread + td_params_NB_IoT tdp; + /// parameters for turbo-encoding worker thread + te_params_NB_IoT tep; + /// number of slave threads + int num_slaves; + /// array of pointers to slaves + struct eNB_proc_NB_IoT_t_s **slave_proc; + /// set of scheduling variables RXn-TXnp4 threads + // newly added for NB_IoT + eNB_rxtx_proc_NB_IoT_t proc_rxtx[2]; + +} eNB_proc_NB_IoT_t; + + +/// Context data structure for RX/TX portion of subframe processing +typedef struct { + /// index of the current UE RX/TX proc + int proc_id; + /// timestamp transmitted to HW + openair0_timestamp timestamp_tx; + /// subframe to act upon for transmission + int subframe_tx; + /// subframe to act upon for reception + int subframe_rx; + /// frame to act upon for transmission + int frame_tx; + /// frame to act upon for reception + int frame_rx; + /// \brief Instance count for RXn-TXnp4 processing thread. + /// \internal This variable is protected by \ref mutex_rxtx. + int instance_cnt_rxtx; + /// pthread structure for RXn-TXnp4 processing thread + pthread_t pthread_rxtx; + /// pthread attributes for RXn-TXnp4 processing thread + pthread_attr_t attr_rxtx; + /// condition variable for tx processing thread + pthread_cond_t cond_rxtx; + /// mutex for RXn-TXnp4 processing thread + pthread_mutex_t mutex_rxtx; + /// scheduling parameters for RXn-TXnp4 thread + struct sched_param sched_param_rxtx; + /// + int sub_frame_start; + /// + int sub_frame_step; + /// + unsigned long long gotIQs; + +} UE_rxtx_proc_NB_IoT_t; + +/// Context data structure for eNB subframe processing +typedef struct { + /// Last RX timestamp + openair0_timestamp timestamp_rx; + /// pthread attributes for main UE thread + pthread_attr_t attr_ue; + /// scheduling parameters for main UE thread + struct sched_param sched_param_ue; + /// pthread descriptor main UE thread + pthread_t pthread_ue; + /// \brief Instance count for synch thread. + /// \internal This variable is protected by \ref mutex_synch. + int instance_cnt_synch; + /// pthread attributes for synch processing thread + pthread_attr_t attr_synch; + /// scheduling parameters for synch thread + struct sched_param sched_param_synch; + /// pthread descriptor synch thread + pthread_t pthread_synch; + /// condition variable for UE synch thread; + pthread_cond_t cond_synch; + /// mutex for UE synch thread + pthread_mutex_t mutex_synch; + /// set of scheduling variables RXn-TXnp4 threads + UE_rxtx_proc_NB_IoT_t proc_rxtx[2]; + +} UE_proc_NB_IoT_t; + + + +/// Top-level PHY Data Structure for eNB +typedef struct PHY_VARS_eNB_NB_IoT_s { + /// Module ID indicator for this instance + module_id_t Mod_id; + uint8_t configured; + eNB_proc_NB_IoT_t proc; + int num_RU; + RU_t *RU_list[MAX_NUM_RU_PER_eNB]; + /// Ethernet parameters for northbound midhaul interface (L1 to Mac) + eth_params_t eth_params_n; + /// Ethernet parameters for fronthaul interface (upper L1 to Radio head) + eth_params_t eth_params; + int single_thread_flag; + openair0_rf_map rf_map; + int abstraction_flag; + openair0_timestamp ts_offset; + // indicator for synchronization state of eNB + int in_synch; + // indicator for master/slave (RRU) + int is_slave; + // indicator for precoding function (eNB,3GPP_eNB_BBU) + int do_precoding; + IF_Module_NB_IoT_t *if_inst_NB_IoT; + UL_IND_NB_IoT_t UL_INFO_NB_IoT; + pthread_mutex_t UL_INFO_mutex; + void (*do_prach)(struct PHY_VARS_eNB_NB_IoT_s *eNB,int frame,int subframe); + void (*fep)(struct PHY_VARS_eNB_NB_IoT_s *eNB,eNB_rxtx_proc_NB_IoT_t *proc); + int (*td)(struct PHY_VARS_eNB_NB_IoT_s *eNB,int UE_id,int harq_pid,int llr8_flag); + int (*te)(struct PHY_VARS_eNB_NB_IoT_s *,uint8_t *,uint8_t,NB_IoT_eNB_DLSCH_t *,int,uint8_t,time_stats_t *,time_stats_t *,time_stats_t *); + void (*proc_uespec_rx)(struct PHY_VARS_eNB_NB_IoT_s *eNB,eNB_rxtx_proc_NB_IoT_t *proc,const relaying_type_t_NB_IoT r_type); + void (*proc_tx)(struct PHY_VARS_eNB_NB_IoT_s *eNB,eNB_rxtx_proc_NB_IoT_t *proc,relaying_type_t_NB_IoT r_type,PHY_VARS_RN_NB_IoT *rn); + void (*tx_fh)(struct PHY_VARS_eNB_NB_IoT_s *eNB,eNB_rxtx_proc_NB_IoT_t *proc); + void (*rx_fh)(struct PHY_VARS_eNB_NB_IoT_s *eNB,int *frame, int *subframe); + int (*start_rf)(struct PHY_VARS_eNB_NB_IoT_s *eNB); + int (*start_if)(struct PHY_VARS_eNB_NB_IoT_s *eNB); + void (*fh_asynch)(struct PHY_VARS_eNB_NB_IoT_s *eNB,int *frame, int *subframe); + uint8_t local_flag; + uint32_t rx_total_gain_dB; + NB_IoT_DL_FRAME_PARMS frame_parms; + PHY_MEASUREMENTS_eNB_NB_IoT measurements[NUMBER_OF_eNB_SECTORS_MAX_NB_IoT]; /// Measurement variables + NB_IoT_eNB_COMMON common_vars; + NB_IoT_eNB_SRS srs_vars[NUMBER_OF_UE_MAX_NB_IoT]; + NB_IoT_eNB_PBCH pbch; + NB_IoT_eNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX_NB_IoT]; + NB_IoT_eNB_PRACH prach_vars; + //LTE_eNB_DLSCH_t *dlsch[NUMBER_OF_UE_MAX_NB_IoT][2]; // Nusers times two spatial streams + NB_IoT_eNB_NULSCH_t *ulsch[NUMBER_OF_UE_MAX_NB_IoT+1]; // Nusers + number of RA (the ulsch[0] contains RAR) + //LTE_eNB_DLSCH_t *dlsch_SI,*dlsch_ra; + //LTE_eNB_DLSCH_t *dlsch_MCH; + NB_IoT_eNB_UE_stats UE_stats[NUMBER_OF_UE_MAX_NB_IoT]; + //LTE_eNB_UE_stats *UE_stats_ptr[NUMBER_OF_UE_MAX_NB_IoT]; + /// cell-specific reference symbols + uint32_t lte_gold_table_NB_IoT[20][2][14]; + /// UE-specific reference symbols (p=5), TM 7 + uint32_t lte_gold_uespec_port5_table[NUMBER_OF_UE_MAX_NB_IoT][20][38]; + /// UE-specific reference symbols (p=7...14), TM 8/9/10 + uint32_t lte_gold_uespec_table[2][20][2][21]; + /// mbsfn reference symbols + uint32_t lte_gold_mbsfn_table[10][3][42]; + /// + uint32_t X_u[64][839]; + /// + uint8_t pbch_pdu[4]; //PBCH_PDU_SIZE + /// + char eNB_generate_rar; + /// Indicator set to 0 after first SR + uint8_t first_sr[NUMBER_OF_UE_MAX_NB_IoT]; + + uint32_t max_peak_val; + /// + int max_eNB_id, max_sync_pos; + /// + int N_TA_offset; ///timing offset used in TDD + /// \brief sinr for all subcarriers of the current link (used only for abstraction). + /// first index: ? [0..N_RB_DL*12[ + double *sinr_dB; + /// N0 (used for abstraction) + double N0; + /// + unsigned char first_run_timing_advance[NUMBER_OF_UE_MAX_NB_IoT]; + unsigned char first_run_I0_measurements; + + unsigned char cooperation_flag; // for cooperative communication + + unsigned char is_secondary_eNB; // primary by default + unsigned char is_init_sync; /// Flag to tell if initial synchronization is performed. This affects how often the secondary eNB will listen to the PSS from the primary system. + unsigned char has_valid_precoder; /// Flag to tell if secondary eNB has channel estimates to create NULL-beams from, and this B/F vector is created. + unsigned char PeNB_id; /// id of Primary eNB + int rx_offset; /// Timing offset (used if is_secondary_eNB) + + /// hold the precoder for NULL beam to the primary user + int **dl_precoder_SeNB[3]; + /// + char log2_maxp; /// holds the maximum channel/precoder coefficient + /// if ==0 enables phy only test mode + int mac_enabled; + /// For emulation only (used by UE abstraction to retrieve DCI) + uint8_t num_common_dci[2]; // num_dci in even/odd subframes + /// + uint8_t num_ue_spec_dci[2]; // num_dci in even/odd subframes + /// + DCI_ALLOC_NB_IoT_t dci_alloc[2][NUM_DCI_MAX_NB_IoT]; // dci_alloc from even/odd subframes + ///////////// + // PDSCH Variables + PDSCH_CONFIG_DEDICATED_NB_IoT pdsch_config_dedicated[NUMBER_OF_UE_MAX_NB_IoT]; + // PUSCH Variables + PUSCH_CONFIG_DEDICATED_NB_IoT pusch_config_dedicated[NUMBER_OF_UE_MAX_NB_IoT]; + // PUCCH variables + PUCCH_CONFIG_DEDICATED_NB_IoT pucch_config_dedicated[NUMBER_OF_UE_MAX_NB_IoT]; + // UL-POWER-Control + UL_POWER_CONTROL_DEDICATED_NB_IoT ul_power_control_dedicated[NUMBER_OF_UE_MAX_NB_IoT]; + // TPC + TPC_PDCCH_CONFIG_NB_IoT tpc_pdcch_config_pucch[NUMBER_OF_UE_MAX_NB_IoT]; + /// + TPC_PDCCH_CONFIG_NB_IoT tpc_pdcch_config_pusch[NUMBER_OF_UE_MAX_NB_IoT]; + // CQI reporting + CQI_REPORT_CONFIG_NB_IoT cqi_report_config[NUMBER_OF_UE_MAX_NB_IoT]; + // SRS Variables + SOUNDINGRS_UL_CONFIG_DEDICATED_NB_IoT soundingrs_ul_config_dedicated[NUMBER_OF_UE_MAX_NB_IoT]; + /// + uint8_t ncs_cell[20][7]; + // Scheduling Request Config + SCHEDULING_REQUEST_CONFIG_NB_IoT scheduling_request_config[NUMBER_OF_UE_MAX_NB_IoT]; + // Transmission mode per UE + uint8_t transmission_mode[NUMBER_OF_UE_MAX_NB_IoT]; + /// cba_last successful reception for each group, used for collision detection + uint8_t cba_last_reception[4]; + // Pointers for active physicalConfigDedicated to be applied in current subframe + struct PhysicalConfigDedicated *physicalConfigDedicated[NUMBER_OF_UE_MAX_NB_IoT]; + //Pointers for actve physicalConfigDedicated for NB-IoT to be applied in current subframe + struct PhysicalConfigDedicated_NB_r13 *phy_config_dedicated_NB_IoT[NUMBER_OF_UE_MAX_NB_IoT]; + /// + uint32_t rb_mask_ul[4]; + /// Information regarding TM5 + MU_MIMO_mode_NB_IoT mu_mimo_mode[NUMBER_OF_UE_MAX_NB_IoT]; + /// target_ue_dl_mcs : only for debug purposes + uint32_t target_ue_dl_mcs; + /// target_ue_ul_mcs : only for debug purposes + uint32_t target_ue_ul_mcs; + /// target_ue_dl_rballoc : only for debug purposes + uint32_t ue_dl_rb_alloc; + /// target ul PRBs : only for debug + uint32_t ue_ul_nb_rb; + ///check for Total Transmissions + uint32_t check_for_total_transmissions; + ///check for MU-MIMO Transmissions + uint32_t check_for_MUMIMO_transmissions; + ///check for SU-MIMO Transmissions + uint32_t check_for_SUMIMO_transmissions; + ///check for FULL MU-MIMO Transmissions + uint32_t FULL_MUMIMO_transmissions; + /// Counter for total bitrate, bits and throughput in downlink + uint32_t total_dlsch_bitrate; + /// + uint32_t total_transmitted_bits; + /// + uint32_t total_system_throughput; + /// + int hw_timing_advance; + /// + time_stats_t phy_proc; + time_stats_t phy_proc_tx; + time_stats_t phy_proc_rx; + time_stats_t rx_prach; + + time_stats_t ofdm_mod_stats; + time_stats_t dlsch_encoding_stats; + time_stats_t dlsch_modulation_stats; + time_stats_t dlsch_scrambling_stats; + time_stats_t dlsch_rate_matching_stats; + time_stats_t dlsch_turbo_encoding_stats; + time_stats_t dlsch_interleaving_stats; + + time_stats_t ofdm_demod_stats; + time_stats_t rx_dft_stats; + time_stats_t ulsch_channel_estimation_stats; + time_stats_t ulsch_freq_offset_estimation_stats; + time_stats_t ulsch_decoding_stats; + time_stats_t ulsch_demodulation_stats; + time_stats_t ulsch_rate_unmatching_stats; + time_stats_t ulsch_turbo_decoding_stats; + time_stats_t ulsch_deinterleaving_stats; + time_stats_t ulsch_demultiplexing_stats; + time_stats_t ulsch_llr_stats; + time_stats_t ulsch_tc_init_stats; + time_stats_t ulsch_tc_alpha_stats; + time_stats_t ulsch_tc_beta_stats; + time_stats_t ulsch_tc_gamma_stats; + time_stats_t ulsch_tc_ext_stats; + time_stats_t ulsch_tc_intl1_stats; + time_stats_t ulsch_tc_intl2_stats; + + #ifdef LOCALIZATION + /// time state for localization + time_stats_t localization_stats; + #endif + + int32_t pucch1_stats_cnt[NUMBER_OF_UE_MAX_NB_IoT][10]; + int32_t pucch1_stats[NUMBER_OF_UE_MAX_NB_IoT][10*1024]; + int32_t pucch1_stats_thres[NUMBER_OF_UE_MAX_NB_IoT][10*1024]; + int32_t pucch1ab_stats_cnt[NUMBER_OF_UE_MAX_NB_IoT][10]; + int32_t pucch1ab_stats[NUMBER_OF_UE_MAX_NB_IoT][2*10*1024]; + int32_t pusch_stats_rb[NUMBER_OF_UE_MAX_NB_IoT][10240]; + int32_t pusch_stats_round[NUMBER_OF_UE_MAX_NB_IoT][10240]; + int32_t pusch_stats_mcs[NUMBER_OF_UE_MAX_NB_IoT][10240]; + int32_t pusch_stats_bsr[NUMBER_OF_UE_MAX_NB_IoT][10240]; + int32_t pusch_stats_BO[NUMBER_OF_UE_MAX_NB_IoT][10240]; + + /// RF and Interface devices per CC + openair0_device rfdevice; + openair0_device ifdevice; + /// Pointer for ifdevice buffer struct + if_buffer_t ifbuffer; + + //------------------------ + // NB-IoT + //------------------------ + + /* + * NUMBER_OF_UE_MAX_NB_IoT maybe in the future should be dynamic because could be very large and the memory may explode + * (is almost the indication of the number of UE context that we are storing at PHY layer) + * + * reasoning: the following data structure (ndlsch, nulsch ecc..) are used to store the context that should be transmitted in at least n+4 subframe later + * (the minimum interval between NPUSCH and the ACK for this) + * the problem is that in NB_IoT the ACK for the UPLINK is contained in the DCI through the NDI field (if this value change from the previous one then it means ACK) + * but may we could schedule this DCI long time later so may lots of contents shuld be stored (there is no concept of phich channel in NB-IoT) + * For the DL transmission the UE send a proper ACK/NACK message + * + * *the HARQ process should be killed when the NDI change + * + * *In the Structure for nulsch we should also store the information related to the subframe (because each time we should read it and understand what should be done + * in that subframe) + * + */ + + + /* + * TIMING + * the entire transmission and scheduling are done for the "subframe" concept but the subframe = proc->subframe_tx (that in reality is the subframe_rx +4) + * (see USER/lte-enb/wakeup_rxtx ) + * + * Related to FAPI: + * DCI and DL_CONFIG.request (also more that 1) and MAC_PDU are transmitted in the same subframe (our assumption) so will be all contained in the schedule_response getting from the scheduler + * DCI0 and UL_CONFIG.request are transmitted in the same subframe (our assumption) so contained in the schedule_response + * + */ + + //TODO: check what should be NUMBER_OF_UE_MAX_NB_IoT value + NB_IoT_eNB_NPBCH_t *npbch; + NB_IoT_eNB_NPDCCH_t *npdcch[NUMBER_OF_UE_MAX_NB_IoT]; + NB_IoT_eNB_NDLSCH_t *ndlsch[NUMBER_OF_UE_MAX_NB_IoT][2]; + NB_IoT_eNB_NULSCH_t *nulsch[NUMBER_OF_UE_MAX_NB_IoT+1]; //nulsch[0] contains the RAR + NB_IoT_eNB_NDLSCH_t *ndlsch_SI,*ndlsch_ra, *ndlsch_SIB1; + + NB_IoT_DL_FRAME_PARMS frame_parms_NB_IoT; + // DCI for at most 2 DCI pdus + DCI_PDU_NB_IoT *DCI_pdu; + + + +} PHY_VARS_eNB_NB_IoT; + +//#define debug_msg if (((mac_xface->frame%100) == 0) || (mac_xface->frame < 50)) msg + +/// Top-level PHY Data Structure for UE +typedef struct { + /// \brief Module ID indicator for this instance + uint8_t Mod_id; + /// \brief Mapping of CC_id antennas to cards + openair0_rf_map rf_map; + //uint8_t local_flag; + /// \brief Indicator of current run mode of UE (normal_txrx, rx_calib_ue, no_L2_connect, debug_prach) + runmode_NB_IoT_t mode; + /// \brief Indicator that UE should perform band scanning + int UE_scan; + /// \brief Indicator that UE should perform coarse scanning around carrier + int UE_scan_carrier; + /// \brief Indicator that UE is synchronized to an eNB + int is_synchronized; + /// Data structure for UE process scheduling + UE_proc_NB_IoT_t proc; + /// Flag to indicate the UE shouldn't do timing correction at all + int no_timing_correction; + /// \brief Total gain of the TX chain (16-bit baseband I/Q to antenna) + uint32_t tx_total_gain_dB; + /// \brief Total gain of the RX chain (antenna to baseband I/Q) This is a function of rx_gain_mode (and the corresponding gain) and the rx_gain of the card. + uint32_t rx_total_gain_dB; + /// \brief Total gains with maximum RF gain stage (ExpressMIMO2/Lime) + uint32_t rx_gain_max[4]; + /// \brief Total gains with medium RF gain stage (ExpressMIMO2/Lime) + uint32_t rx_gain_med[4]; + /// \brief Total gains with bypassed RF gain stage (ExpressMIMO2/Lime) + uint32_t rx_gain_byp[4]; + /// \brief Current transmit power + int16_t tx_power_dBm[10]; + /// \brief Total number of REs in current transmission + int tx_total_RE[10]; + /// \brief Maximum transmit power + int8_t tx_power_max_dBm; + /// \brief Number of eNB seen by UE + uint8_t n_connected_eNB; + /// \brief indicator that Handover procedure has been initiated + uint8_t ho_initiated; + /// \brief indicator that Handover procedure has been triggered + uint8_t ho_triggered; + /// \brief Measurement variables. + PHY_MEASUREMENTS_NB_IoT measurements; + NB_IoT_DL_FRAME_PARMS frame_parms; + /// \brief Frame parame before ho used to recover if ho fails. + NB_IoT_DL_FRAME_PARMS frame_parms_before_ho; + NB_IoT_UE_COMMON common_vars; + + NB_IoT_UE_PDSCH *pdsch_vars[2][NUMBER_OF_CONNECTED_eNB_MAX+1]; // two RxTx Threads + NB_IoT_UE_DLSCH_t *dlsch[2][NUMBER_OF_CONNECTED_eNB_MAX][2]; // two RxTx Threads + //Paging parameters + uint32_t IMSImod1024; + uint32_t PF; + uint32_t PO; + // For abstraction-purposes only + uint8_t sr[10]; + uint8_t pucch_sel[10]; + uint8_t pucch_payload[22]; + //UE_MODE_t UE_mode[NUMBER_OF_CONNECTED_eNB_MAX]; + //cell-specific reference symbols + uint32_t lte_gold_table[7][20][2][14]; + //UE-specific reference symbols (p=5), TM 7 + uint32_t lte_gold_uespec_port5_table[20][38]; + //ue-specific reference symbols + uint32_t lte_gold_uespec_table[2][20][2][21]; + //mbsfn reference symbols + uint32_t lte_gold_mbsfn_table[10][3][42]; + /// + uint32_t X_u[64][839]; + /// + uint32_t high_speed_flag; + uint32_t perfect_ce; + int16_t ch_est_alpha; + int generate_ul_signal[NUMBER_OF_CONNECTED_eNB_MAX]; + /// + UE_SCAN_INFO_NB_IoT_t scan_info[NB_BANDS_MAX_NB_IoT]; + /// + char ulsch_no_allocation_counter[NUMBER_OF_CONNECTED_eNB_MAX]; + +/* + + unsigned char ulsch_Msg3_active[NUMBER_OF_CONNECTED_eNB_MAX]; + uint32_t ulsch_Msg3_frame[NUMBER_OF_CONNECTED_eNB_MAX]; + unsigned char ulsch_Msg3_subframe[NUMBER_OF_CONNECTED_eNB_MAX]; + PRACH_RESOURCES_t *prach_resources[NUMBER_OF_CONNECTED_eNB_MAX]; + int turbo_iterations, turbo_cntl_iterations; + /// \brief ?. + /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded) + uint32_t total_TBS[NUMBER_OF_CONNECTED_eNB_MAX]; + /// \brief ?. + /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded) + uint32_t total_TBS_last[NUMBER_OF_CONNECTED_eNB_MAX]; + /// \brief ?. + /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded) + uint32_t bitrate[NUMBER_OF_CONNECTED_eNB_MAX]; + /// \brief ?. + /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded) + uint32_t total_received_bits[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_errors[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_errors_last[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_received[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_received_last[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_fer[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_SI_received[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_SI_errors[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_ra_received[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_ra_errors[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_p_received[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_p_errors[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mch_received_sf[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mch_received[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mcch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mtch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mcch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mtch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mcch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mtch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int current_dlsch_cqi[NUMBER_OF_CONNECTED_eNB_MAX]; + unsigned char first_run_timing_advance[NUMBER_OF_CONNECTED_eNB_MAX]; + uint8_t generate_prach; + uint8_t prach_cnt; + uint8_t prach_PreambleIndex; + // uint8_t prach_timer; + uint8_t decode_SIB; + uint8_t decode_MIB; + int rx_offset; /// Timing offset + int rx_offset_diff; /// Timing adjustment for ofdm symbol0 on HW USRP + int timing_advance; ///timing advance signalled from eNB + int hw_timing_advance; + int N_TA_offset; ///timing offset used in TDD + /// Flag to tell if UE is secondary user (cognitive mode) + unsigned char is_secondary_ue; + /// Flag to tell if secondary eNB has channel estimates to create NULL-beams from. + unsigned char has_valid_precoder; + /// hold the precoder for NULL beam to the primary eNB + int **ul_precoder_S_UE; + /// holds the maximum channel/precoder coefficient + char log2_maxp; +*/ + /// if ==0 enables phy only test mode + int mac_enabled; + /// Flag to initialize averaging of PHY measurements + int init_averaging; + /// \brief sinr for all subcarriers of the current link (used only for abstraction). + /// - first index: ? [0..12*N_RB_DL[ + double *sinr_dB; + /// \brief sinr for all subcarriers of first symbol for the CQI Calculation. + /// - first index: ? [0..12*N_RB_DL[ + double *sinr_CQI_dB; + /// sinr_effective used for CQI calulcation + double sinr_eff; + /// N0 (used for abstraction) + double N0; +/* + /// PDSCH Varaibles + PDSCH_CONFIG_DEDICATED pdsch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// PUSCH Varaibles + PUSCH_CONFIG_DEDICATED pusch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// PUSCH contention-based access vars + PUSCH_CA_CONFIG_DEDICATED pusch_ca_config_dedicated[NUMBER_OF_eNB_MAX]; // lola + + /// PUCCH variables + + PUCCH_CONFIG_DEDICATED pucch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + + uint8_t ncs_cell[20][7]; + + /// UL-POWER-Control + UL_POWER_CONTROL_DEDICATED ul_power_control_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// TPC + TPC_PDCCH_CONFIG tpc_pdcch_config_pucch[NUMBER_OF_CONNECTED_eNB_MAX]; + TPC_PDCCH_CONFIG tpc_pdcch_config_pusch[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// CQI reporting + CQI_REPORT_CONFIG cqi_report_config[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// SRS Variables + SOUNDINGRS_UL_CONFIG_DEDICATED soundingrs_ul_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// Scheduling Request Config + SCHEDULING_REQUEST_CONFIG scheduling_request_config[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// Transmission mode per eNB + uint8_t transmission_mode[NUMBER_OF_CONNECTED_eNB_MAX]; + + time_stats_t phy_proc; + time_stats_t phy_proc_tx; + time_stats_t phy_proc_rx[2]; + + uint32_t use_ia_receiver; + + time_stats_t ofdm_mod_stats; + time_stats_t ulsch_encoding_stats; + time_stats_t ulsch_modulation_stats; + time_stats_t ulsch_segmentation_stats; + time_stats_t ulsch_rate_matching_stats; + time_stats_t ulsch_turbo_encoding_stats; + time_stats_t ulsch_interleaving_stats; + time_stats_t ulsch_multiplexing_stats; + + time_stats_t generic_stat; + time_stats_t pdsch_procedures_stat; + time_stats_t dlsch_procedures_stat; + + time_stats_t ofdm_demod_stats; + time_stats_t dlsch_rx_pdcch_stats; + time_stats_t rx_dft_stats; + time_stats_t dlsch_channel_estimation_stats; + time_stats_t dlsch_freq_offset_estimation_stats; + time_stats_t dlsch_decoding_stats[2]; + time_stats_t dlsch_demodulation_stats; + time_stats_t dlsch_rate_unmatching_stats; + time_stats_t dlsch_turbo_decoding_stats; + time_stats_t dlsch_deinterleaving_stats; + time_stats_t dlsch_llr_stats; + time_stats_t dlsch_unscrambling_stats; + time_stats_t dlsch_rate_matching_stats; + time_stats_t dlsch_turbo_encoding_stats; + time_stats_t dlsch_interleaving_stats; + time_stats_t dlsch_tc_init_stats; + time_stats_t dlsch_tc_alpha_stats; + time_stats_t dlsch_tc_beta_stats; + time_stats_t dlsch_tc_gamma_stats; + time_stats_t dlsch_tc_ext_stats; + time_stats_t dlsch_tc_intl1_stats; + time_stats_t dlsch_tc_intl2_stats; + time_stats_t tx_prach; + + /// RF and Interface devices per CC + openair0_device rfdevice; + time_stats_t dlsch_encoding_SIC_stats; + time_stats_t dlsch_scrambling_SIC_stats; + time_stats_t dlsch_modulation_SIC_stats; + time_stats_t dlsch_llr_stripping_unit_SIC_stats; + time_stats_t dlsch_unscrambling_SIC_stats; + +#if ENABLE_RAL + hash_table_t *ral_thresholds_timed; + SLIST_HEAD(ral_thresholds_gen_poll_s, ral_threshold_phy_t) ral_thresholds_gen_polled[RAL_LINK_PARAM_GEN_MAX]; + SLIST_HEAD(ral_thresholds_lte_poll_s, ral_threshold_phy_t) ral_thresholds_lte_polled[RAL_LINK_PARAM_LTE_MAX]; +#endif +*/ +} PHY_VARS_UE_NB_IoT; + + + +#include "PHY/INIT/defs_NB_IoT.h" +#include "PHY/LTE_REFSIG/defs_NB_IoT.h" +#include "PHY/LTE_TRANSPORT/proto_NB_IoT.h" +#endif // __PHY_DEFS__H__ diff --git a/openair1/PHY/impl_defs_lte_NB_IoT.h b/openair1/PHY/impl_defs_lte_NB_IoT.h new file mode 100644 index 0000000000..7ae6f59c7e --- /dev/null +++ b/openair1/PHY/impl_defs_lte_NB_IoT.h @@ -0,0 +1,813 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file PHY/impl_defs_lte.h +* \brief LTE Physical channel configuration and variable structure definitions +* \author R. Knopp, F. Kaltenberger +* \date 2011 +* \version 0.1 +* \company Eurecom +* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr +* \note +* \warning +*/ + +#ifndef __PHY_IMPL_DEFS_NB_IOT__H__ +#define __PHY_IMPL_DEFS_NB_IOT__H__ + +#include "types_NB_IoT.h" +//#include "defs.h" + +typedef enum {TDD_NB_IoT=1,FDD_NB_IoT=0} NB_IoT_frame_type_t; +typedef enum {EXTENDED_NB_IoT=1,NORMAL_NB_IoT=0} NB_IoT_prefix_type_t; +typedef enum {SF_DL_NB_IoT, SF_UL_NB_IoT, SF_S_NB_IoT} NB_IoT_subframe_t; + +#define A_SEQUENCE_OF(type) A_SET_OF(type) + +#define A_SET_OF(type) \ + struct { \ + type **array; \ + int count; /* Meaningful size */ \ + int size; /* Allocated size */ \ + void (*free)(type *); \ + } + + +///////////////////////// + /// Union for \ref TPC_PDCCH_CONFIG::tpc_Index. +typedef union { + /// Index of N when DCI format 3 is used. See TS 36.212 (5.3.3.1.6). \vr{[1..15]} + uint8_t indexOfFormat3; + /// Index of M when DCI format 3A is used. See TS 36.212 (5.3.3.1.7). \vr{[1..31]} + uint8_t indexOfFormat3A; +} TPC_INDEX_NB_IoT_t; + +/// TPC-PDCCH-Config Information Element from 36.331 RRC spec +typedef struct { + /// RNTI for power control using DCI format 3/3A, see TS 36.212. \vr{[0..65535]} + uint16_t rnti; + /// Index of N or M, see TS 36.212 (5.3.3.1.6 and 5.3.3.1.7), where N or M is dependent on the used DCI format (i.e. format 3 or 3a). + TPC_INDEX_NB_IoT_t tpc_Index; +} TPC_PDCCH_CONFIG_NB_IoT; + /// Enumeration for parameter \f$N_\text{ANRep}\f$ \ref PUCCH_CONFIG_DEDICATED::repetitionFactor. +typedef enum { + //n2=0, + n4_n, + n6_n +} ACKNAKREP_NB_IoT_t; + +/// Enumeration for \ref PUCCH_CONFIG_DEDICATED::tdd_AckNackFeedbackMode. +typedef enum { + bundling_N=0, + multiplexing_N +} ANFBmode_NB_IoT_t; + +/// PUCCH-ConfigDedicated from 36.331 RRC spec +typedef struct { + /// Flag to indicate ACK NAK repetition activation, see TS 36.213 (10.1). \vr{[0..1]} + uint8_t ackNackRepetition; + /// Parameter: \f$N_\text{ANRep}\f$, see TS 36.213 (10.1). + ACKNAKREP_NB_IoT_t repetitionFactor; + /// Parameter: \f$n^{(1)}_\text{PUCCH,ANRep}\f$, see TS 36.213 (10.1). \vr{[0..2047]} + uint16_t n1PUCCH_AN_Rep; + /// Feedback mode, see TS 36.213 (7.3). \details Applied to both PUCCH and PUSCH feedback. For TDD, should always be set to bundling. + ANFBmode_NB_IoT_t tdd_AckNackFeedbackMode; +} PUCCH_CONFIG_DEDICATED_NB_IoT; + // UE specific PUSCH configuration. +typedef struct { + /// Parameter: \f$I^\text{HARQ-ACK}_\text{offset}\f$, see TS 36.213 (Table 8.6.3-1). \vr{[0..15]} + uint16_t betaOffset_ACK_Index; + /// Parameter: \f$I^{RI}_\text{offset}\f$, see TS 36.213 (Table 8.6.3-2). \vr{[0..15]} + uint16_t betaOffset_RI_Index; + /// Parameter: \f$I^{CQI}_\text{offset}\f$, see TS 36.213 (Table 8.6.3-3). \vr{[0..15]} + uint16_t betaOffset_CQI_Index; +} PUSCH_CONFIG_DEDICATED_NB_IoT; +/// Enumeration for Parameter \f$P_A\f$ \ref PDSCH_CONFIG_DEDICATED::p_a. +typedef enum { + //dBm6=0, ///< (dB-6) corresponds to -6 dB + // dBm477, ///< (dB-4dot77) corresponds to -4.77 dB + // dBm3, ///< (dB-3) corresponds to -3 dB + //dBm177, ///< (dB-1dot77) corresponds to -1.77 dB + //dB0, ///< corresponds to 0 dB + // dB1, ///< corresponds to 1 dB + dB2_NB, ///< corresponds to 2 dB + dB3_NB ///< corresponds to 3 dB +} PA_NB_IoT_t; + +/// PDSCH-ConfigDedicated from 36.331 RRC spec +typedef struct { + /// Parameter: \f$P_A\f$, see TS 36.213 (5.2). + PA_NB_IoT_t p_a; +} PDSCH_CONFIG_DEDICATED_NB_IoT; + +/// UplinkPowerControlDedicated Information Element from 36.331 RRC spec +typedef struct { + /// Parameter: \f$P_\text{0\_UE\_PUSCH}(1)\f$, see TS 36.213 (5.1.1.1), unit dB. \vr{[-8..7]}\n This field is applicable for non-persistent scheduling, only. + int8_t p0_UE_PUSCH; + /// Parameter: Ks, see TS 36.213 (5.1.1.1). \vr{[0..1]}\n en0 corresponds to value 0 corresponding to state “disabled”. en1 corresponds to value 1.25 corresponding to “enabled”. \note the specification sais it is an enumerated value. \warning the enumeration values do not correspond to the given values in the specification (en1 should be 1.25). + uint8_t deltaMCS_Enabled; + /// Parameter: Accumulation-enabled, see TS 36.213 (5.1.1.1). \vr{[0..1]} 1 corresponds to "enabled" whereas 0 corresponds to "disabled". + uint8_t accumulationEnabled; + /// Parameter: \f$P_\text{0\_UE\_PUCCH}(1)\f$, see TS 36.213 (5.1.2.1), unit dB. \vr{[-8..7]} + int8_t p0_UE_PUCCH; + /// Parameter: \f$P_\text{SRS\_OFFSET}\f$, see TS 36.213 (5.1.3.1). \vr{[0..15]}\n For Ks=1.25 (\ref deltaMCS_Enabled), the actual parameter value is pSRS_Offset value - 3. For Ks=0, the actual parameter value is -10.5 + 1.5*pSRS_Offset value. + int8_t pSRS_Offset; + /// Specifies the filtering coefficient for RSRP measurements used to calculate path loss, as specified in TS 36.213 (5.1.1.1).\details The same filtering mechanism applies as for quantityConfig described in 5.5.3.2. \note the specification sais it is an enumerated value. + uint8_t filterCoefficient; +} UL_POWER_CONTROL_DEDICATED_NB_IoT; + +/// Union for \ref TPC_PDCCH_CONFIG::tpc_Index. +//typedef union { + /// Index of N when DCI format 3 is used. See TS 36.212 (5.3.3.1.6). \vr{[1..15]} + // uint8_t indexOfFormat3; + /// Index of M when DCI format 3A is used. See TS 36.212 (5.3.3.1.7). \vr{[1..31]} + // uint8_t indexOfFormat3A; +//} TPC_INDEX_NB_IoT_t; + +/// CQI-ReportPeriodic +typedef struct { + /// Parameter: \f$n^{(2)}_\text{PUCCH}\f$, see TS 36.213 (7.2). \vr{[0..1185]}, -1 indicates inactivity + int16_t cqi_PUCCH_ResourceIndex; + /// Parameter: CQI/PMI Periodicity and Offset Configuration Index \f$I_\text{CQI/PMI}\f$, see TS 36.213 (tables 7.2.2-1A and 7.2.2-1C). \vr{[0..1023]} + int16_t cqi_PMI_ConfigIndex; + /// Parameter: K, see 36.213 (4.2.2). \vr{[1..4]} + uint8_t K; + /// Parameter: RI Config Index \f$I_\text{RI}\f$, see TS 36.213 (7.2.2-1B). \vr{[0..1023]}, -1 indicates inactivity + int16_t ri_ConfigIndex; + /// Parameter: Simultaneous-AN-and-CQI, see TS 36.213 (10.1). \vr{[0..1]} 1 indicates that simultaneous transmission of ACK/NACK and CQI is allowed. + uint8_t simultaneousAckNackAndCQI; + /// parameter computed from Tables 7.2.2-1A and 7.2.2-1C + uint16_t Npd; + /// parameter computed from Tables 7.2.2-1A and 7.2.2-1C + uint16_t N_OFFSET_CQI; +} CQI_REPORTPERIODIC_NB_IoT; + +/// Enumeration for parameter reporting mode \ref CQI_REPORT_CONFIG::cqi_ReportModeAperiodic. +typedef enum { + //rm12=0, + //rm20=1, + //rm22=2, + rm30_N=3, + rm31_N=4 +} CQI_REPORTMODEAPERIODIC_NB_IoT; + +/// CQI-ReportConfig Information Element from 36.331 RRC spec +typedef struct { + /// Parameter: reporting mode. Value rm12 corresponds to Mode 1-2, rm20 corresponds to Mode 2-0, rm22 corresponds to Mode 2-2 etc. PUSCH reporting modes are described in TS 36.213 [23, 7.2.1]. + CQI_REPORTMODEAPERIODIC_NB_IoT cqi_ReportModeAperiodic; + /// Parameter: \f$\Delta_\text{offset}\f$, see TS 36.213 (7.2.3). \vr{[-1..6]}\n Actual value = IE value * 2 [dB]. + int8_t nomPDSCH_RS_EPRE_Offset; + CQI_REPORTPERIODIC_NB_IoT CQI_ReportPeriodic; +} CQI_REPORT_CONFIG_NB_IoT; + +/// SoundingRS-UL-ConfigDedicated Information Element from 36.331 RRC spec +typedef struct { + /// Parameter: \f$B_\text{SRS}\f$, see TS 36.211 (table 5.5.3.2-1, 5.5.3.2-2, 5.5.3.2-3 and 5.5.3.2-4). \vr{[0..3]} \note the specification sais it is an enumerated value. + uint8_t srs_Bandwidth; + /// Parameter: SRS hopping bandwidth \f$b_\text{hop}\in\{0,1,2,3\}\f$, see TS 36.211 (5.5.3.2) \vr{[0..3]} \note the specification sais it is an enumerated value. + uint8_t srs_HoppingBandwidth; + /// Parameter: \f$n_\text{RRC}\f$, see TS 36.211 (5.5.3.2). \vr{[0..23]} + uint8_t freqDomainPosition; + /// Parameter: Duration, see TS 36.213 (8.2). \vr{[0..1]} 0 corresponds to "single" and 1 to "indefinite". + uint8_t duration; + /// Parameter: \f$k_\text{TC}\in\{0,1\}\f$, see TS 36.211 (5.5.3.2). \vr{[0..1]} + uint8_t transmissionComb; + /// Parameter: \f$I_\text{SRS}\f$, see TS 36.213 (table 8.2-1). \vr{[0..1023]} + uint16_t srs_ConfigIndex; + /// Parameter: \f$n^\text{CS}_\text{SRS}\f$. See TS 36.211 (5.5.3.1). \vr{[0..7]} \note the specification sais it is an enumerated value. + uint8_t cyclicShift; + // Parameter: internal implementation: UE SRS configured + uint8_t srsConfigDedicatedSetup; + // Parameter: cell srs subframe for internal implementation + uint8_t srsCellSubframe; + // Parameter: ue srs subframe for internal implementation + uint8_t srsUeSubframe; +} SOUNDINGRS_UL_CONFIG_DEDICATED_NB_IoT; + + +/// Enumeration for parameter SR transmission \ref SCHEDULING_REQUEST_CONFIG::dsr_TransMax. +typedef enum { + //sr_n4=0, + // sr_n8=1, + // sr_n16=2, + sr_n32_N=3, + sr_n64_N=4 +} DSR_TRANSMAX_NB_IoT_t; + +/// SchedulingRequestConfig Information Element from 36.331 RRC spec +typedef struct { + /// Parameter: \f$n^{(1)}_\text{PUCCH,SRI}\f$, see TS 36.213 (10.1). \vr{[0..2047]} + uint16_t sr_PUCCH_ResourceIndex; + /// Parameter: \f$I_\text{SR}\f$, see TS 36.213 (10.1). \vr{[0..155]} + uint8_t sr_ConfigIndex; + /// Parameter for SR transmission in TS 36.321 (5.4.4). \details The value n4 corresponds to 4 transmissions, n8 corresponds to 8 transmissions and so on. + DSR_TRANSMAX_NB_IoT_t dsr_TransMax; +} SCHEDULING_REQUEST_CONFIG_NB_IoT; + +typedef struct { + /// Downlink Power offset field + uint8_t dl_pow_off; + ///Subband resource allocation field + uint8_t rballoc_sub[50]; + ///Total number of PRBs indicator + uint8_t pre_nb_available_rbs; +} MU_MIMO_mode_NB_IoT; +//////////////////////// + +typedef struct { + + /// \brief Holds the received data in the frequency domain. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: symbol [0..28*ofdm_symbol_size[ + int32_t **rxdataF; + + /// \brief Hold the channel estimates in frequency domain. + /// - first index: eNB id [0..6] (hard coded) + /// - second index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - third index: samples? [0..symbols_per_tti*(ofdm_symbol_size+LTE_CE_FILTER_LENGTH)[ + int32_t **dl_ch_estimates[7]; + + /// \brief Hold the channel estimates in time domain (used for tracking). + /// - first index: eNB id [0..6] (hard coded) + /// - second index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - third index: samples? [0..2*ofdm_symbol_size[ + int32_t **dl_ch_estimates_time[7]; +}NB_IoT_UE_COMMON_PER_THREAD; + +typedef struct { + /// \brief Holds the transmit data in time domain. + /// For IFFT_FPGA this points to the same memory as PHY_vars->tx_vars[a].TX_DMA_BUFFER. + /// - first index: tx antenna [0..nb_antennas_tx[ + /// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES[ + int32_t **txdata; + /// \brief Holds the transmit data in the frequency domain. + /// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. + /// - first index: tx antenna [0..nb_antennas_tx[ + /// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX[ + int32_t **txdataF; + + /// \brief Holds the received data in time domain. + /// Should point to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES+2048[ + int32_t **rxdata; + + NB_IoT_UE_COMMON_PER_THREAD common_vars_rx_data_per_thread[2]; + + /// holds output of the sync correlator + int32_t *sync_corr; + /// estimated frequency offset (in radians) for all subcarriers + int32_t freq_offset; + /// eNb_id user is synched to + int32_t eNb_id; +} NB_IoT_UE_COMMON; + +typedef struct { + /// \brief Received frequency-domain signal after extraction. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **rxdataF_ext; + /// \brief Received frequency-domain ue specific pilots. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..12*N_RB_DL[ + int32_t **rxdataF_uespec_pilots; + /// \brief Received frequency-domain signal after extraction and channel compensation. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **rxdataF_comp0; + /// \brief Received frequency-domain signal after extraction and channel compensation for the second stream. For the SIC receiver we need to store the history of this for each harq process and round + /// - first index: ? [0..7] (hard coded) accessed via \c harq_pid + /// - second index: ? [0..7] (hard coded) accessed via \c round + /// - third index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - fourth index: ? [0..168*N_RB_DL[ + int32_t **rxdataF_comp1[8][8]; + /// \brief Downlink channel estimates extracted in PRBS. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_estimates_ext; + /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS. For the SIC receiver we need to store the history of this for each harq process and round + /// - first index: ? [0..7] (hard coded) accessed via \c harq_pid + /// - second index: ? [0..7] (hard coded) accessed via \c round + /// - third index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - fourth index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_rho_ext[8][8]; + /// \brief Downlink beamforming channel estimates in frequency domain. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: samples? [0..symbols_per_tti*(ofdm_symbol_size+LTE_CE_FILTER_LENGTH)[ + int32_t **dl_bf_ch_estimates; + /// \brief Downlink beamforming channel estimates. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_bf_ch_estimates_ext; + /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_rho2_ext; + /// \brief Downlink PMIs extracted in PRBS and grouped in subbands. + /// - first index: ressource block [0..N_RB_DL[ + uint8_t *pmi_ext; + /// \brief Magnitude of Downlink Channel first layer (16QAM level/First 64QAM level). + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_mag0; + /// \brief Magnitude of Downlink Channel second layer (16QAM level/First 64QAM level). + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_mag1[8][8]; + /// \brief Magnitude of Downlink Channel, first layer (2nd 64QAM level). + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_magb0; + /// \brief Magnitude of Downlink Channel second layer (2nd 64QAM level). + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_magb1[8][8]; + /// \brief Cross-correlation of two eNB signals. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: symbol [0..] + int32_t **rho; + /// never used... always send dl_ch_rho_ext instead... + int32_t **rho_i; + /// \brief Pointers to llr vectors (2 TBs). + /// - first index: ? [0..1] (hard coded) + /// - second index: ? [0..1179743] (hard coded) + int16_t *llr[2]; + /// \f$\log_2(\max|H_i|^2)\f$ + int16_t log2_maxh; + /// \f$\log_2(\max|H_i|^2)\f$ //this is for TM3-4 layer1 channel compensation + int16_t log2_maxh0; + /// \f$\log_2(\max|H_i|^2)\f$ //this is for TM3-4 layer2 channel commpensation + int16_t log2_maxh1; + /// \brief LLR shifts for subband scaling. + /// - first index: ? [0..168*N_RB_DL[ + uint8_t *llr_shifts; + /// \brief Pointer to LLR shifts. + /// - first index: ? [0..168*N_RB_DL[ + uint8_t *llr_shifts_p; + /// \brief Pointers to llr vectors (128-bit alignment). + /// - first index: ? [0..0] (hard coded) + /// - second index: ? [0..] + int16_t **llr128; + /// \brief Pointers to llr vectors (128-bit alignment). + /// - first index: ? [0..0] (hard coded) + /// - second index: ? [0..] + int16_t **llr128_2ndstream; + //uint32_t *rb_alloc; + //uint8_t Qm[2]; + //MIMO_mode_t mimo_mode; +} NB_IoT_UE_PDSCH; + +/// NPRACH-ParametersList-NB-r13 from 36.331 RRC spec +typedef struct NPRACH_Parameters_NB_IoT{ + /// the period time for nprach + uint16_t nprach_Periodicity; + /// for the start time for the NPRACH resource from 40ms-2560ms + uint16_t nprach_StartTime; + /// for the subcarrier of set to the NPRACH preamble from n0 - n34 + uint16_t nprach_SubcarrierOffset; + ///number of subcarriers in a NPRACH resource allowed values (n12,n24,n36,n48) + uint16_t nprach_NumSubcarriers; + /// where is the region that in NPRACH resource to indicate if this UE support MSG3 for multi-tone or not. from 0 - 1 + uint16_t nprach_SubcarrierMSG3_RangeStart; + /// The max preamble transmission attempt for the CE level from 1 - 128 + uint16_t maxNumPreambleAttemptCE; + /// Number of NPRACH repetitions per attempt for each NPRACH resource + uint16_t numRepetitionsPerPreambleAttempt; + /// The number of the repetition for DCI use in RAR/MSG3/MSG4 from 1 - 2048 (Rmax) + uint16_t npdcch_NumRepetitions_RA; + /// Starting subframe for NPDCCH Common searching space for (RAR/MSG3/MSG4) + uint16_t npdcch_StartSF_CSS_RA; + /// Fractional period offset of starting subframe for NPDCCH common search space + uint16_t npdcch_Offset_RA; +} nprach_parameters_NB_IoT_t; + +typedef struct{ + nprach_parameters_NB_IoT_t list[3]; +}NPRACH_List_NB_IoT_t; + +typedef long RSRP_Range_t; + +typedef struct { + A_SEQUENCE_OF(RSRP_Range_t) list; +}rsrp_ThresholdsNPrachInfoList; + + +/// NPRACH_ConfigSIB-NB from 36.331 RRC spec +typedef struct { + /// nprach_CP_Length_r13, for the CP length(unit us) only 66.7 and 266.7 is implemented + uint16_t nprach_CP_Length; + /// The criterion for UEs to select a NPRACH resource. Up to 2 RSRP threshold values can be signalled. \vr{[1..2]} + struct rsrp_ThresholdsNPrachInfoList *rsrp_ThresholdsPrachInfoList; + /// NPRACH Parameters List + NPRACH_List_NB_IoT_t nprach_ParametersList; + +} NPRACH_CONFIG_COMMON; + +/// NPDSCH-ConfigCommon from 36.331 RRC spec +typedef struct { + ///see TS 36.213 (16.2). \vr{[-60..50]}\n Provides the downlink reference-signal EPRE. The actual value in dBm. + uint16_t nrs_Power; +} NPDSCH_CONFIG_COMMON; + +typedef struct{ + /// The base sequence of DMRS sequence in a cell for 3 tones transmission; see TS 36.211 [21, 10.1.4.1.2]. If absent, it is given by NB-IoT CellID mod 12. Value 12 is not used. + uint16_t threeTone_BaseSequence; + /// Define 3 cyclic shifts for the 3-tone case, see TS 36.211 [21, 10.1.4.1.2]. + uint16_t threeTone_CyclicShift; + /// The base sequence of DMRS sequence in a cell for 6 tones transmission; see TS 36.211 [21, 10.1.4.1.2]. If absent, it is given by NB-IoT CellID mod 14. Value 14 is not used. + uint16_t sixTone_BaseSequence; + /// Define 4 cyclic shifts for the 6-tone case, see TS 36.211 [21, 10.1.4.1.2]. + uint16_t sixTone_CyclicShift; + /// The base sequence of DMRS sequence in a cell for 12 tones transmission; see TS 36.211 [21, 10.1.4.1.2]. If absent, it is given by NB-IoT CellID mod 30. Value 30 is not used. + uint16_t twelveTone_BaseSequence; + +}DMRS_CONFIG_t; + +/// UL-ReferenceSignalsNPUSCH from 36.331 RRC spec +typedef struct { + /// Parameter: Group-hopping-enabled, see TS 36.211 (5.5.1.3). \vr{[0..1]} + uint8_t groupHoppingEnabled; + /// , see TS 36.211 (5.5.1.3). \vr{[0..29]} + uint8_t groupAssignmentNPUSCH; + /// Parameter: cyclicShift, see TS 36.211 (Table 5.5.2.1.1-2). \vr{[0..7]} + uint8_t cyclicShift; + /// nPRS for cyclic shift of DRS \note not part of offical UL-ReferenceSignalsPUSCH ASN1 specification. + uint8_t nPRS[20]; + /// group hopping sequence for DMRS, 36.211, Section 10.1.4.1.3. Second index corresponds to the four possible subcarrier configurations + uint8_t grouphop[20][4]; + /// sequence hopping sequence for DRS \note not part of offical UL-ReferenceSignalsPUSCH ASN1 specification. + uint8_t seqhop[20]; +} UL_REFERENCE_SIGNALS_NPUSCH_t; + + +/// PUSCH-ConfigCommon from 36.331 RRC spec. +typedef struct { + /// Number of repetitions for ACK/NACK HARQ response to NPDSCH containing Msg4 per NPRACH resource, see TS 36.213 [23, 16.4.2]. + uint8_t ack_NACK_NumRepetitions_Msg4[3]; + /// SRS SubframeConfiguration. See TS 36.211 [21, table 5.5.3.3-1]. Value sc0 corresponds to value 0, sc1 to value 1 and so on. + uint8_t srs_SubframeConfig; + /// Parameter: \f$N^{HO}_{RB}\f$, see TS 36.211 (5.3.4). \vr{[0..98]} + DMRS_CONFIG_t dmrs_Config; + /// Ref signals configuration + UL_REFERENCE_SIGNALS_NPUSCH_t ul_ReferenceSignalsNPUSCH; + +} NPUSCH_CONFIG_COMMON; + + +typedef struct{ + /// See TS 36.213 [23, 16.2.1.1], unit dBm. + uint8_t p0_NominalNPUSCH; + /// See TS 36.213 [23, 16.2.1.1] where al0 corresponds to 0, al04 corresponds to value 0.4, al05 to 0.5, al06 to 0.6, al07 to 0.7, al08 to 0.8, al09 to 0.9 and al1 corresponds to 1. + uint8_t alpha; + /// See TS 36.213 [23, 16.2.1.1]. Actual value = IE value * 2 [dB]. + uint8_t deltaPreambleMsg3; +}UplinkPowerControlCommon_NB_IoT; + + +/* DL-GapConfig-NB-r13 */ +typedef struct { + uint16_t dl_GapThreshold; + uint16_t dl_GapPeriodicity; + uint16_t dl_GapDurationCoeff; +} DL_GapConfig_NB_IoT; + +#define NBIOT_INBAND_LTEPCI 0 +#define NBIOT_INBAND_IOTPCI 1 +#define NBIOT_INGUARD 2 +#define NBIOT_STANDALONE 3 + + +typedef struct { + /// for inband, lte bandwidth + uint8_t LTE_N_RB_DL; + uint8_t LTE_N_RB_UL; + /// Cell ID + uint16_t Nid_cell; + /// shift of pilot position in one RB + uint8_t nushift; + /// indicates if node is a UE (NODE=2) or eNB (PRIMARY_CH=0). + uint8_t node_id; + /// Frequency index of CBMIMO1 card + uint8_t freq_idx; + /// RX Frequency for ExpressMIMO/LIME + uint32_t carrier_freq[4]; + /// TX Frequency for ExpressMIMO/LIME + uint32_t carrier_freqtx[4]; + /// RX gain for ExpressMIMO/LIME + uint32_t rxgain[4]; + /// TX gain for ExpressMIMO/LIME + uint32_t txgain[4]; + /// RF mode for ExpressMIMO/LIME + uint32_t rfmode[4]; + /// RF RX DC Calibration for ExpressMIMO/LIME + uint32_t rxdc[4]; + /// RF TX DC Calibration for ExpressMIMO/LIME + uint32_t rflocal[4]; + /// RF VCO calibration for ExpressMIMO/LIME + uint32_t rfvcolocal[4]; + /// Turns on second TX of CBMIMO1 card + uint8_t dual_tx; + /// flag to indicate SISO transmission + uint8_t mode1_flag; + /// Indicator that 20 MHz channel uses 3/4 sampling frequency + //uint8_t threequarter_fs; + /// Size of FFT + uint16_t ofdm_symbol_size; + /// Number of prefix samples in all but first symbol of slot + uint16_t nb_prefix_samples; + /// Number of prefix samples in first symbol of slot + uint16_t nb_prefix_samples0; + /// Carrier offset in FFT buffer for first RE in PRB0 + uint16_t first_carrier_offset; + /// Number of samples in a subframe + uint32_t samples_per_tti; + /// Number of OFDM/SC-FDMA symbols in one subframe (to be modified to account for potential different in UL/DL) + uint16_t symbols_per_tti; + /// Number of Physical transmit antennas in node + uint8_t nb_antennas_tx; + /// Number of Receive antennas in node + uint8_t nb_antennas_rx; + /// Number of common transmit antenna ports in eNodeB (1 or 2) + uint8_t nb_antenna_ports_eNB; + /// Number of common receiving antenna ports in eNodeB (1 or 2) + uint8_t nb_antenna_ports_rx_eNB; + /// NPRACH Config Common (from 36-331 RRC spec) + NPRACH_CONFIG_COMMON nprach_config_common; + /// NPDSCH Config Common (from 36-331 RRC spec) + NPDSCH_CONFIG_COMMON npdsch_config_common; + /// PUSCH Config Common (from 36-331 RRC spec) + NPUSCH_CONFIG_COMMON npusch_config_common; + /// UL Power Control (from 36-331 RRC spec) + UplinkPowerControlCommon_NB_IoT ul_power_control_config_common; + /// DL Gap + DL_GapConfig_NB_IoT DL_gap_config; + /// Size of SI windows used for repetition of one SI message (in frames) + uint8_t SIwindowsize; + /// Period of SI windows used for repetition of one SI message (in frames) + uint16_t SIPeriod; + int eutra_band; + uint32_t dl_CarrierFreq; + uint32_t ul_CarrierFreq; + // CE level to determine the NPRACH Configuration (one CE for each NPRACH config.) + uint8_t CE; + + /* + * index of the PRB assigned to NB-IoT carrier in in-band/guard-band operating mode + */ + unsigned short NB_IoT_RB_ID; + + + /*Following FAPI approach: + * 0 = in-band with same PCI + * 1 = in-band with diff PCI + * 2 = guard band + * 3 =stand alone + */ + uint16_t operating_mode; + /* + * Only for In-band operating mode with same PCI + * its measured in number of OFDM symbols + * allowed values: + * 1, 2, 3, 4(this value is written in FAPI specs but not exist in TS 36.331 v14.2.1 pag 587) + * -1 (we put this value when is not defined - other operating mode) + */ + uint16_t control_region_size; + + /*Number of EUTRA CRS antenna ports (AP) + * valid only for in-band different PCI mode + * value 0 = indicates the same number of AP as NRS APs + * value 1 = four CRS APs + */ + uint16_t eutra_NumCRS_ports; + + /* Subcarrier bandwidth + 0 -> 3.75 kHz + 1 -> 15 kHz + */ + uint8_t subcarrier_spacing; + +} NB_IoT_DL_FRAME_PARMS; + +typedef struct { + /// \brief Pointers (dynamic) to the received data in the time domain. + /// - first index: rx antenna [0..nb_antennas_rx] + /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti] + int32_t **rxdata; + /// \brief Pointers (dynamic) to the received data in the frequency domain. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti] + int32_t **rxdataF; + /// \brief holds the transmit data in the frequency domain. + /// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. //? + /// - first index: eNB id [0..2] (hard coded) + /// - second index: tx antenna [0..14[ where 14 is the total supported antenna ports. + /// - third index: sample [0..] + int32_t **txdataF; +} NB_IoT_eNB_COMMON; + +typedef struct { + /// \brief Holds the transmit data in the frequency domain. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[ + int32_t **txdata; + /// \brief Holds the receive data in the frequency domain. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[ + int32_t **rxdata[3]; + /// \brief Holds the last subframe of received data in time domain after removal of 7.5kHz frequency offset. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: sample [0..samples_per_tti[ + int32_t **rxdata_7_5kHz[3]; + /// \brief Holds the received data in the frequency domain. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[ + int32_t **rxdataF[3]; + /// \brief Holds output of the sync correlator. + /// - first index: sample [0..samples_per_tti*10[ + uint32_t *sync_corr[3]; +} NB_IoT_RU_COMMON; + +typedef struct { + /// \brief Hold the channel estimates in frequency domain based on SRS. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..ofdm_symbol_size[ + int32_t **srs_ch_estimates[3]; + /// \brief Hold the channel estimates in time domain based on SRS. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..2*ofdm_symbol_size[ + int32_t **srs_ch_estimates_time[3]; + /// \brief Holds the SRS for channel estimation at the RX. + /// - first index: ? [0..ofdm_symbol_size[ + int32_t *srs; +} NB_IoT_eNB_SRS; + +typedef struct { + /// \brief Holds the received data in the frequency domain for the allocated RBs in repeated format. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..2*ofdm_symbol_size[ + /// - third index (definition from phy_init_lte_eNB()): ? [0..24*N_RB_UL*frame_parms->symbols_per_tti[ + /// \warning inconsistent third index definition + int32_t **rxdataF_ext[3]; + /// \brief Holds the received data in the frequency domain for the allocated RBs in normal format. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index (definition from phy_init_lte_eNB()): ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **rxdataF_ext2[3]; + /// \brief Hold the channel estimates in time domain based on DRS. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..4*ofdm_symbol_size[ + int32_t **drs_ch_estimates_time[3]; + /// \brief Hold the channel estimates in frequency domain based on DRS. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **drs_ch_estimates[3]; + /// \brief Hold the channel estimates for UE0 in case of Distributed Alamouti Scheme. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **drs_ch_estimates_0[3]; + /// \brief Hold the channel estimates for UE1 in case of Distributed Almouti Scheme. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **drs_ch_estimates_1[3]; + /// \brief Holds the compensated signal. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **rxdataF_comp[3]; + /// \brief Hold the compensated data (y)*(h0*) in case of Distributed Alamouti Scheme. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **rxdataF_comp_0[3]; + /// \brief Hold the compensated data (y*)*(h1) in case of Distributed Alamouti Scheme. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **rxdataF_comp_1[3]; + /// \brief ?. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_mag[3]; + /// \brief ?. + /// - first index: eNB id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_magb[3]; + /// \brief Hold the channel mag for UE0 in case of Distributed Alamouti Scheme. + /// - first index: eNB id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_mag_0[3]; + /// \brief Hold the channel magb for UE0 in case of Distributed Alamouti Scheme. + /// - first index: eNB id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_magb_0[3]; + /// \brief Hold the channel mag for UE1 in case of Distributed Alamouti Scheme. + /// - first index: eNB id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_mag_1[3]; + /// \brief Hold the channel magb for UE1 in case of Distributed Alamouti Scheme. + /// - first index: eNB id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_magb_1[3]; + /// measured RX power based on DRS + int ulsch_power[2]; + /// measured RX power based on DRS for UE0 in case of Distributed Alamouti Scheme + int ulsch_power_0[2]; + /// measured RX power based on DRS for UE0 in case of Distributed Alamouti Scheme + int ulsch_power_1[2]; + /// \brief llr values. + /// - first index: ? [0..1179743] (hard coded) + int16_t *llr; +#ifdef LOCALIZATION + /// number of active subcarrier for a specific UE + int32_t active_subcarrier; + /// subcarrier power in dBm + int32_t *subcarrier_power; +#endif +} NB_IoT_eNB_PUSCH; + +#define PBCH_A_NB_IoT 24 +typedef struct { + uint8_t pbch_d[96+(3*(16+PBCH_A_NB_IoT))]; + uint8_t pbch_w[3*3*(16+PBCH_A_NB_IoT)]; + uint8_t pbch_e[1920]; +} NB_IoT_eNB_PBCH; + + +typedef enum { + /// TM1 + SISO_NB_IoT=0, + /// TM2 + ALAMOUTI_NB_IoT=1, + /// TM3 + LARGE_CDD_NB_IoT=2, + /// the next 6 entries are for TM5 + UNIFORM_PRECODING11_NB_IoT=3, + UNIFORM_PRECODING1m1_NB_IoT=4, + UNIFORM_PRECODING1j_NB_IoT=5, + UNIFORM_PRECODING1mj_NB_IoT=6, + PUSCH_PRECODING0_NB_IoT=7, + PUSCH_PRECODING1_NB_IoT=8, + /// the next 3 entries are for TM4 + DUALSTREAM_UNIFORM_PRECODING1_NB_IoT=9, + DUALSTREAM_UNIFORM_PRECODINGj_NB_IoT=10, + DUALSTREAM_PUSCH_PRECODING_NB_IoT=11, + TM7_NB_IoT=12, + TM8_NB_IoT=13, + TM9_10_NB_IoT=14 +} MIMO_mode_NB_IoT_t; + +typedef struct { + /// \brief ?. + /// first index: ? [0..1023] (hard coded) + int16_t *prachF; + /// \brief ?. + /// first index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx. + /// second index: ? [0..ofdm_symbol_size*12[ + int16_t *rxsigF[64]; + /// \brief local buffer to compute prach_ifft (necessary in case of multiple CCs) + /// first index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx. + /// second index: ? [0..2047] (hard coded) + int16_t *prach_ifft[64]; +} NB_IoT_eNB_PRACH; + +typedef enum { + NOT_SYNCHED_NB_IoT=0, + PRACH_NB_IoT=1, + RA_RESPONSE_NB_IoT=2, + PUSCH_NB_IoT=3, + RESYNCH_NB_IoT=4 +} UE_MODE_NB_IoT_t; + + +#endif diff --git a/openair1/PHY/impl_defs_top_NB_IoT.h b/openair1/PHY/impl_defs_top_NB_IoT.h new file mode 100644 index 0000000000..e512ec0215 --- /dev/null +++ b/openair1/PHY/impl_defs_top_NB_IoT.h @@ -0,0 +1,541 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file PHY/impl_defs_top.h +* \brief More defines and structure definitions +* \author R. Knopp, F. Kaltenberger +* \date 2011 +* \version 0.1 +* \company Eurecom +* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr +* \note +* \warning +*/ + +#ifndef __PHY_IMPLEMENTATION_DEFS_NB_IOT_H__ +#define __PHY_IMPLEMENTATION_DEFS_NB_IOT_H__ + + +#include "openairinterface5g_limits.h" +/** @defgroup _ref_implementation_ OpenAirInterface LTE Implementation + * @{ + + * @defgroup _PHY_RF_INTERFACE_ PHY - RF Interface + * @ingroup _PHY_RF_INTERFACE_ + * @{ + * @defgroup _GENERIC_PHY_RF_INTERFACE_ Generic PHY - RF Interface + * @defgroup _USRP_PHY_RF_INTERFACE_ PHY - USRP RF Interface + * @defgroup _BLADERF_PHY_RF_INTERFACE_ PHY - BLADERF RF Interface + * @defgroup _LMSSDR_PHY_RF_INTERFACE_ PHY - LMSSDR RF Interface + * @} + * + * @ingroup _ref_implementation_ + * @{ + * This module is responsible for defining the generic interface between PHY and RF Target + * @} + + * @defgroup _openair1_ openair1 Reference Implementation + * @ingroup _ref_implementation_ + * @{ + + + * @defgroup _physical_layer_ref_implementation_ Physical Layer Reference Implementation + * @ingroup _openair1_ + * @{ + + + * @defgroup _PHY_STRUCTURES_ Basic Structures and Memory Initialization + * @ingroup _physical_layer_ref_implementation_ + * @{ + * This module is responsible for defining and initializing the PHY variables during static configuration of OpenAirInterface. + * @} + + * @defgroup _PHY_DSP_TOOLS_ DSP Tools + * @ingroup _physical_layer_ref_implementation_ + * @{ + * This module is responsible for basic signal processing related to inner-MODEM processing. + * @} + + * @defgroup _PHY_MODULATION_ Modulation and Demodulation + * @ingroup _physical_layer_ref_implementation_ + * @{ + * This module is responsible for procedures related to OFDMA modulation and demodulation. + * @} + + * @defgroup _PHY_PARAMETER_ESTIMATION_BLOCKS_ Parameter Estimation + * @ingroup _physical_layer_ref_implementation_ + * @{ + * This module is responsible for procedures related to OFDMA frequency-domain channel estimation for LTE Downlink Channels. + * @} + + * @defgroup _PHY_CODING_BLOCKS_ Channel Coding/Decoding Functions + * @ingroup _physical_layer_ref_implementation_ + * @{ + * This module is responsible for procedures related to channel coding/decoding, rate-matching, segementation and interleaving. + * @} + + * @defgroup _PHY_TRANSPORT_ Transport/Physical Channel Processing + * @ingroup _physical_layer_ref_implementation_ + * @{ + * This module is responsible for defining and processing the PHY procedures (TX/RX) related to transport and physical channels. + * @} + + * @defgroup _PHY_PROCEDURES_ Physical Layer Procedures + * @ingroup _physical_layer_ref_implementation_ + * @{ + * This module is responsible for defining and processing the PHY procedures (TX/RX) related to transport and physical channels. + * @} + + * @} + * @} + * @} + */ + +//#include "types.h" + +/* + + +#define NUMBER_OF_OFDM_CARRIERS (frame_parms->ofdm_symbol_size) +#define NUMBER_OF_SYMBOLS_PER_FRAME (frame_parms->symbols_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME) +#define NUMBER_OF_USEFUL_CARRIERS (12*frame_parms->N_RB_DL) +#define NUMBER_OF_ZERO_CARRIERS (NUMBER_OF_OFDM_CARRIERS-NUMBER_OF_USEFUL_CARRIERS) +#define NUMBER_OF_USEFUL_CARRIERS_BYTES (NUMBER_OF_USEFUL_CARRIERS>>2) +#define HALF_NUMBER_OF_USEFUL_CARRIERS (NUMBER_OF_USEFUL_CARRIERS>>1) +#define HALF_NUMBER_OF_USEFUL_CARRIERS_BYTES (HALF_NUMBER_OF_USEFUL_CARRIERS>>2) +#define FIRST_CARRIER_OFFSET (HALF_NUMBER_OF_USEFUL_CARRIERS+NUMBER_OF_ZERO_CARRIERS) +#define NUMBER_OF_OFDM_SYMBOLS_PER_SLOT (NUMBER_OF_SYMBOLS_PER_FRAME/LTE_SLOTS_PER_FRAME) + +#ifdef EMOS +#define EMOS_SCH_INDEX 1 +#endif //EMOS + +#define EXTENSION_TYPE (PHY_config->PHY_framing.Extension_type) + +#define NUMBER_OF_OFDM_CARRIERS_BYTES NUMBER_OF_OFDM_CARRIERS*4 +//#define NUMBER_OF_USEFUL_CARRIERS_BYTES NUMBER_OF_USEFUL_CARRIERS*4 +#define HALF_NUMBER_OF_USER_CARRIERS_BYTES NUMBER_OF_USEFUL_CARRIERS/2 + +#define CYCLIC_PREFIX_LENGTH (frame_parms->nb_prefix_samples) +#define CYCLIC_PREFIX_LENGTH_SAMPLES (CYCLIC_PREFIX_LENGTH*2) +#define CYCLIC_PREFIX_LENGTH_BYTES (CYCLIC_PREFIX_LENGTH*4) +#define CYCLIC_PREFIX_LENGTH0 (frame_parms->nb_prefix_samples0) +#define CYCLIC_PREFIX_LENGTH_SAMPLES0 (CYCLIC_PREFIX_LENGTH0*2) +#define CYCLIC_PREFIX_LENGTH_BYTES0 (CYCLIC_PREFIX_LENGTH0*4) + +#define OFDM_SYMBOL_SIZE_SAMPLES ((NUMBER_OF_OFDM_CARRIERS + CYCLIC_PREFIX_LENGTH)*2) // 16-bit units (i.e. real samples) +#define OFDM_SYMBOL_SIZE_SAMPLES0 ((NUMBER_OF_OFDM_CARRIERS + CYCLIC_PREFIX_LENGTH0)*2) // 16-bit units (i.e. real samples) +#define OFDM_SYMBOL_SIZE_SAMPLES_MAX 4096 // 16-bit units (i.e. real samples) +#define OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES (OFDM_SYMBOL_SIZE_SAMPLES/2) // 32-bit units (i.e. complex samples) +#define OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0 (OFDM_SYMBOL_SIZE_SAMPLES0/2) // 32-bit units (i.e. complex samples) +#define OFDM_SYMBOL_SIZE_SAMPLES_NO_PREFIX ((NUMBER_OF_OFDM_CARRIERS)*2) +#define OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX (OFDM_SYMBOL_SIZE_SAMPLES_NO_PREFIX/2) +#define OFDM_SYMBOL_SIZE_BYTES (OFDM_SYMBOL_SIZE_SAMPLES*2) +#define OFDM_SYMBOL_SIZE_BYTES0 (OFDM_SYMBOL_SIZE_SAMPLES0*2) +#define OFDM_SYMBOL_SIZE_BYTES_NO_PREFIX (OFDM_SYMBOL_SIZE_SAMPLES_NO_PREFIX*2) + +#define SLOT_LENGTH_BYTES (frame_parms->samples_per_tti<<1) // 4 bytes * samples_per_tti/2 +#define SLOT_LENGTH_BYTES_NO_PREFIX (OFDM_SYMBOL_SIZE_BYTES_NO_PREFIX * NUMBER_OF_OFDM_SYMBOLS_PER_SLOT) + +#define FRAME_LENGTH_COMPLEX_SAMPLES (frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME) +#define FRAME_LENGTH_SAMPLES (FRAME_LENGTH_COMPLEX_SAMPLES*2) +#define FRAME_LENGTH_SAMPLES_NO_PREFIX (NUMBER_OF_SYMBOLS_PER_FRAME*OFDM_SYMBOL_SIZE_SAMPLES_NO_PREFIX) +#define FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX (FRAME_LENGTH_SAMPLES_NO_PREFIX/2) + +#define NUMBER_OF_CARRIERS_PER_GROUP (NUMBER_OF_USEFUL_CARRIERS/NUMBER_OF_FREQUENCY_GROUPS) + +#define RX_PRECISION (16) +#define LOG2_RX_PRECISION (4) +#define RX_OUTPUT_SHIFT (4) + + +#define SAMPLE_SIZE_BYTES 2 // 2 bytes/real sample + +#define FRAME_LENGTH_BYTES (FRAME_LENGTH_SAMPLES * SAMPLE_SIZE_BYTES) // frame size in bytes +#define FRAME_LENGTH_BYTES_NO_PREFIX (FRAME_LENGTH_SAMPLES_NO_PREFIX * SAMPLE_SIZE_BYTES) // frame size in bytes + + +#define FFT_SCALE_FACTOR 8 // Internal Scaling for FFT +#define DMA_BLKS_PER_SLOT (SLOT_LENGTH_BYTES/2048) // Number of DMA blocks per slot +#define SLOT_TIME_NS (SLOT_LENGTH_SAMPLES*(1e3)/7.68) // slot time in ns + +#define NB_ANTENNA_PORTS_ENB 6 // total number of eNB antenna ports + +#ifdef EXMIMO +#define TARGET_RX_POWER 55 // Target digital power for the AGC +#define TARGET_RX_POWER_MAX 55 // Maximum digital power, such that signal does not saturate (value found by simulation) +#define TARGET_RX_POWER_MIN 50 // Minimum digital power, anything below will be discarded (value found by simulation) +#else +#define TARGET_RX_POWER 50 // Target digital power for the AGC +#define TARGET_RX_POWER_MAX 65 // Maximum digital power, such that signal does not saturate (value found by simulation) +#define TARGET_RX_POWER_MIN 35 // Minimum digital power, anything below will be discarded (value found by simulation) +#endif + +//the min and max gains have to match the calibrated gain table +//#define MAX_RF_GAIN 160 +//#define MIN_RF_GAIN 96 +#define MAX_RF_GAIN 200 +#define MIN_RF_GAIN 80 + +#define PHY_SYNCH_OFFSET ((OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)-1) // OFFSET of BEACON SYNCH +#define PHY_SYNCH_MIN_POWER 1000 +#define PHY_SYNCH_THRESHOLD 100 + +*/ + +#define ONE_OVER_SQRT2_Q15_NB_IoT 23170 + +/* +#define ONE_OVER_2_Q15 16384 + +// QAM amplitude definitions + +/// First Amplitude for QAM16 (\f$ 2^{15} \times 2/\sqrt{10}\f$) +#define QAM16_n1 20724 +/// Second Amplitude for QAM16 (\f$ 2^{15} \times 1/\sqrt{10}\f$) +#define QAM16_n2 10362 + +///First Amplitude for QAM64 (\f$ 2^{15} \times 4/\sqrt{42}\f$) +#define QAM64_n1 20225 +///Second Amplitude for QAM64 (\f$ 2^{15} \times 2/\sqrt{42}\f$) +#define QAM64_n2 10112 +///Third Amplitude for QAM64 (\f$ 2^{15} \times 1/\sqrt{42}\f$) +#define QAM64_n3 5056 + +/// First Amplitude for QAM16 for TM5 (\f$ 2^{15} \times 2/sqrt(20)\f$) +#define QAM16_TM5_n1 14654 +/// Second Amplitude for QAM16 for TM5 Receiver (\f$ 2^{15} \times 1/\sqrt{20}\f$) +#define QAM16_TM5_n2 7327 + +///First Amplitude for QAM64 (\f$ 2^{15} \times 4/\sqrt{84}\f$) +#define QAM64_TM5_n1 14301 +///Second Amplitude for QAM64 (\f$ 2^{15} \times 2/\sqrt{84}\f$) +#define QAM64_TM5_n2 7150 +///Third Amplitude for QAM64 for TM5 Receiver (\f$ 2^{15} \times 1/\sqrt{84}\f$) +#define QAM64_TM5_n3 3575 + + +#ifdef BIT8_RXMUX +#define PERROR_SHIFT 0 +#else +#define PERROR_SHIFT 10 +#endif + +#define BIT8_TX_SHIFT 2 +#define BIT8_TX_SHIFT_DB 12 + +//#define CHBCH_RSSI_MIN -75 + +#ifdef BIT8_TX +#define AMP 128 +#else +#define AMP 512//1024 //4096 +#endif + +#define AMP_OVER_SQRT2 ((AMP*ONE_OVER_SQRT2_Q15)>>15) +#define AMP_OVER_2 (AMP>>1) + +/// Threshold for PUCCH Format 1 detection +#define PUCCH1_THRES 0 +/// Threshold for PUCCH Format 1a/1b detection +#define PUCCH1a_THRES 4 + +/// Data structure for transmission. +typedef struct { + /// RAW TX sample buffer + char *TX_DMA_BUFFER[2]; +} TX_VARS ; + +/// Data structure for reception. +typedef struct { + /// RAW TX sample buffer + char *TX_DMA_BUFFER[2]; + /// RAW RX sample buffer + int *RX_DMA_BUFFER[2]; +} TX_RX_VARS; + +//! \brief Extension Type / +typedef enum { + CYCLIC_PREFIX, + CYCLIC_SUFFIX, + ZEROS, + NONE +} Extension_t; + +/// Measurement Variables +*/ +#define NUMBER_OF_SUBBANDS_MAX_NB_IoT 13 +/* +#define NUMBER_OF_HARQ_PID_MAX 8 + +#define MAX_FRAME_NUMBER 0x400 +#include "openairinterface5g_limits.h" + +#define NUMBER_OF_RN_MAX 3 +typedef enum {no_relay=1,unicast_relay_type1,unicast_relay_type2, multicast_relay} relaying_type_t; + +typedef struct { + //unsigned int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (linear) + //unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (dB) + //unsigned short rx_avg_power_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //! estimated avg received signal power (dB) + + // RRC measurements + uint32_t rssi; + int n_adj_cells; + unsigned int adj_cell_id[6]; + uint32_t rsrq[7]; + uint32_t rsrp[7]; + float rsrp_filtered[7]; // after layer 3 filtering + float rsrq_filtered[7]; + // common measurements + //! estimated noise power (linear) + unsigned int n0_power[NB_ANTENNAS_RX]; + //! estimated noise power (dB) + unsigned short n0_power_dB[NB_ANTENNAS_RX]; + //! total estimated noise power (linear) + unsigned int n0_power_tot; + //! total estimated noise power (dB) + unsigned short n0_power_tot_dB; + //! average estimated noise power (linear) + unsigned int n0_power_avg; + //! average estimated noise power (dB) + unsigned short n0_power_avg_dB; + //! total estimated noise power (dBm) + short n0_power_tot_dBm; + + // UE measurements + //! estimated received spatial signal power (linear) + int rx_spatial_power[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; + //! estimated received spatial signal power (dB) + unsigned short rx_spatial_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; + + /// estimated received signal power (sum over all TX antennas) + //int wideband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + /// estimated received signal power (sum over all TX antennas) + //int wideband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + + /// estimated received signal power (sum over all TX/RX antennas) + int rx_power_tot[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW + /// estimated received signal power (sum over all TX/RX antennas) + unsigned short rx_power_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW + + //! estimated received signal power (sum of all TX/RX antennas, time average) + int rx_power_avg[NUMBER_OF_CONNECTED_eNB_MAX]; + //! estimated received signal power (sum of all TX/RX antennas, time average, in dB) + unsigned short rx_power_avg_dB[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// SINR (sum of all TX/RX antennas, in dB) + int wideband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX]; + /// SINR (sum of all TX/RX antennas, time average, in dB) + int wideband_cqi_avg[NUMBER_OF_CONNECTED_eNB_MAX]; + + //! estimated rssi (dBm) + short rx_rssi_dBm[NUMBER_OF_CONNECTED_eNB_MAX]; + //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation) + int rx_correlation[NUMBER_OF_CONNECTED_eNB_MAX][2]; + //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation) + int rx_correlation_dB[NUMBER_OF_CONNECTED_eNB_MAX][2]; + + /// Wideband CQI (sum of all RX antennas, in dB, for precoded transmission modes (3,4,5,6), up to 4 spatial streams) + int precoded_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX+1][4]; + /// Subband CQI per RX antenna (= SINR) + int subband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX]; + /// Total Subband CQI (= SINR) + int subband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX]; + /// Subband CQI in dB (= SINR dB) + int subband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX]; + /// Total Subband CQI + int subband_cqi_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX]; + /// Wideband PMI for each RX antenna + int wideband_pmi_re[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + /// Wideband PMI for each RX antenna + int wideband_pmi_im[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + ///Subband PMI for each RX antenna + int subband_pmi_re[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX][NB_ANTENNAS_RX]; + ///Subband PMI for each RX antenna + int subband_pmi_im[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX][NB_ANTENNAS_RX]; + /// chosen RX antennas (1=Rx antenna 1, 2=Rx antenna 2, 3=both Rx antennas) + unsigned char selected_rx_antennas[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX]; + /// Wideband Rank indication + unsigned char rank[NUMBER_OF_CONNECTED_eNB_MAX]; + /// Number of RX Antennas + unsigned char nb_antennas_rx; + /// DLSCH error counter + // short dlsch_errors; + +} PHY_MEASUREMENTS; +*/ +typedef enum {no_relay_NB_IoT=1,unicast_relay_type1_NB_IoT,unicast_relay_type2_NB_IoT, multicast_relay_NB_IoT} relaying_type_t_NB_IoT; +typedef struct { + //unsigned int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (linear) + //unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (dB) + //unsigned short rx_avg_power_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //! estimated avg received signal power (dB) + + // RRC measurements + uint32_t rssi; + int n_adj_cells; + unsigned int adj_cell_id[6]; + uint32_t rsrq[7]; + uint32_t rsrp[7]; + float rsrp_filtered[7]; // after layer 3 filtering + float rsrq_filtered[7]; + // common measurements + //! estimated noise power (linear) + unsigned int n0_power[NB_ANTENNAS_RX]; + //! estimated noise power (dB) + unsigned short n0_power_dB[NB_ANTENNAS_RX]; + //! total estimated noise power (linear) + unsigned int n0_power_tot; + //! total estimated noise power (dB) + unsigned short n0_power_tot_dB; + //! average estimated noise power (linear) + unsigned int n0_power_avg; + //! average estimated noise power (dB) + unsigned short n0_power_avg_dB; + //! total estimated noise power (dBm) + short n0_power_tot_dBm; + + // UE measurements + //! estimated received spatial signal power (linear) + int rx_spatial_power[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; + //! estimated received spatial signal power (dB) + unsigned short rx_spatial_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; + + /// estimated received signal power (sum over all TX antennas) + //int wideband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + /// estimated received signal power (sum over all TX antennas) + //int wideband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + + /// estimated received signal power (sum over all TX/RX antennas) + int rx_power_tot[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW + /// estimated received signal power (sum over all TX/RX antennas) + unsigned short rx_power_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW + + //! estimated received signal power (sum of all TX/RX antennas, time average) + int rx_power_avg[NUMBER_OF_CONNECTED_eNB_MAX]; + //! estimated received signal power (sum of all TX/RX antennas, time average, in dB) + unsigned short rx_power_avg_dB[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// SINR (sum of all TX/RX antennas, in dB) + int wideband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX]; + /// SINR (sum of all TX/RX antennas, time average, in dB) + int wideband_cqi_avg[NUMBER_OF_CONNECTED_eNB_MAX]; + + //! estimated rssi (dBm) + short rx_rssi_dBm[NUMBER_OF_CONNECTED_eNB_MAX]; + //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation) + int rx_correlation[NUMBER_OF_CONNECTED_eNB_MAX][2]; + //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation) + int rx_correlation_dB[NUMBER_OF_CONNECTED_eNB_MAX][2]; + + /// Wideband CQI (sum of all RX antennas, in dB, for precoded transmission modes (3,4,5,6), up to 4 spatial streams) + int precoded_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX+1][4]; + /// Subband CQI per RX antenna (= SINR) + int subband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX_NB_IoT]; + /// Total Subband CQI (= SINR) + int subband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX_NB_IoT]; + /// Subband CQI in dB (= SINR dB) + int subband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX_NB_IoT]; + /// Total Subband CQI + int subband_cqi_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX_NB_IoT]; + /// Wideband PMI for each RX antenna + int wideband_pmi_re[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + /// Wideband PMI for each RX antenna + int wideband_pmi_im[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + ///Subband PMI for each RX antenna + int subband_pmi_re[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX_NB_IoT][NB_ANTENNAS_RX]; + ///Subband PMI for each RX antenna + int subband_pmi_im[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX_NB_IoT][NB_ANTENNAS_RX]; + /// chosen RX antennas (1=Rx antenna 1, 2=Rx antenna 2, 3=both Rx antennas) + unsigned char selected_rx_antennas[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX_NB_IoT]; + /// Wideband Rank indication + unsigned char rank[NUMBER_OF_CONNECTED_eNB_MAX]; + /// Number of RX Antennas + unsigned char nb_antennas_rx; + /// DLSCH error counter + // short dlsch_errors; + +} PHY_MEASUREMENTS_NB_IoT; + + +typedef struct { + //unsigned int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (linear) + //unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (dB) + //unsigned short rx_avg_power_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //! estimated avg received signal power (dB) + + // common measurements + //! estimated noise power (linear) + unsigned int n0_power[NB_ANTENNAS_RX]; + //! estimated noise power (dB) + unsigned short n0_power_dB[NB_ANTENNAS_RX]; + //! total estimated noise power (linear) + unsigned int n0_power_tot; + //! estimated avg noise power (dB) + unsigned short n0_power_tot_dB; + //! estimated avg noise power (dB) + short n0_power_tot_dBm; + //! estimated avg noise power per RB per RX ant (lin) + unsigned short n0_subband_power[NB_ANTENNAS_RX][100]; + //! estimated avg noise power per RB per RX ant (dB) + unsigned short n0_subband_power_dB[NB_ANTENNAS_RX][100]; + //! estimated avg noise power per RB (dB) + short n0_subband_power_tot_dB[100]; + //! estimated avg noise power per RB (dBm) + short n0_subband_power_tot_dBm[100]; + // eNB measurements (per user) + //! estimated received spatial signal power (linear) + unsigned int rx_spatial_power[NUMBER_OF_UE_MAX_NB_IoT][2][2]; + //! estimated received spatial signal power (dB) + unsigned short rx_spatial_power_dB[NUMBER_OF_UE_MAX_NB_IoT][2][2]; + //! estimated rssi (dBm) + short rx_rssi_dBm[NUMBER_OF_UE_MAX_NB_IoT]; + //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation) + int rx_correlation[NUMBER_OF_UE_MAX_NB_IoT][2]; + //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation) + int rx_correlation_dB[NUMBER_OF_UE_MAX_NB_IoT][2]; + + /// Wideband CQI (= SINR) + int wideband_cqi[NUMBER_OF_UE_MAX_NB_IoT][NB_ANTENNAS_RX]; + /// Wideband CQI in dB (= SINR dB) + int wideband_cqi_dB[NUMBER_OF_UE_MAX_NB_IoT][NB_ANTENNAS_RX]; + /// Wideband CQI (sum of all RX antennas, in dB) + char wideband_cqi_tot[NUMBER_OF_UE_MAX_NB_IoT]; + /// Subband CQI per RX antenna and RB (= SINR) + int subband_cqi[NUMBER_OF_UE_MAX_NB_IoT][NB_ANTENNAS_RX][100]; + /// Total Subband CQI and RB (= SINR) + int subband_cqi_tot[NUMBER_OF_UE_MAX_NB_IoT][100]; + /// Subband CQI in dB and RB (= SINR dB) + int subband_cqi_dB[NUMBER_OF_UE_MAX_NB_IoT][NB_ANTENNAS_RX][100]; + /// Total Subband CQI and RB + int subband_cqi_tot_dB[NUMBER_OF_UE_MAX_NB_IoT][100]; + +} PHY_MEASUREMENTS_eNB_NB_IoT; +/* +#define MCS_COUNT 28 +#define MCS_TABLE_LENGTH_MAX 64 +*/ +#endif //__PHY_IMPLEMENTATION_DEFS_H__ +/**@} +*/ diff --git a/openair1/PHY/types_NB_IoT.h b/openair1/PHY/types_NB_IoT.h new file mode 100644 index 0000000000..e8a6ea501e --- /dev/null +++ b/openair1/PHY/types_NB_IoT.h @@ -0,0 +1,32 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef __openair_TYPES_NB_IOT_H__ +#define __openair_TYPES_NB_IOT_H__ + +#ifdef USER_MODE +#include +#else +#include +#endif + + +#endif /*__openair_TYPES_NB_IOT_H__ */ diff --git a/openair1/SCHED/prach_procedures.c b/openair1/SCHED/prach_procedures.c index 79af3c128e..4730eed613 100644 --- a/openair1/SCHED/prach_procedures.c +++ b/openair1/SCHED/prach_procedures.c @@ -36,6 +36,7 @@ #include "SCHED/extern.h" #include "nfapi_interface.h" #include "fapi_l1.h" +#include "nfapi_pnf.h" #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h index f4004bdbf9..4debccc7b0 100644 --- a/openair2/COMMON/platform_constants.h +++ b/openair2/COMMON/platform_constants.h @@ -77,6 +77,10 @@ #define MAX_MANAGED_ENB_PER_MOBILE 2 +///NB-IOT +#define NB_RB_MAX_NB_IOT (maxDRB_NB_r13 + 3) //MP: NB_IoT --> 2(DRB)+3(SRBs - 2 is not used) = 5 + + #define DEFAULT_RAB_ID 1 #define NB_RB_MAX (maxDRB + 3) /* was 11, now 14, maxDRB comes from asn1_constants.h, + 3 because of 3 SRB, one invisible id 0, then id 1 and 2 */ diff --git a/openair2/COMMON/rrc_messages_def.h b/openair2/COMMON/rrc_messages_def.h index be3d18c996..08ea93f427 100644 --- a/openair2/COMMON/rrc_messages_def.h +++ b/openair2/COMMON/rrc_messages_def.h @@ -54,6 +54,7 @@ MESSAGE_DEF(RRC_STATE_IND, MESSAGE_PRIORITY_MED, RrcStateInd, //-------------------------------------------------------------------------------------------// // eNB: ENB_APP -> RRC messages MESSAGE_DEF(RRC_CONFIGURATION_REQ, MESSAGE_PRIORITY_MED, RrcConfigurationReq, rrc_configuration_req) +MESSAGE_DEF(NBIOTRRC_CONFIGURATION_REQ, MESSAGE_PRIORITY_MED, NbIoTRrcConfigurationReq, nbiotrrc_configuration_req) // UE: NAS -> RRC messages MESSAGE_DEF(NAS_KENB_REFRESH_REQ, MESSAGE_PRIORITY_MED, NasKenbRefreshReq, nas_kenb_refresh_req) diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 6fd0a04113..9bd25d3b3a 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -62,6 +62,8 @@ typedef UL_DCCH_Message_t RrcUlDcchMessage; #define RRC_CONFIGURATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_configuration_req +#define NBIOTRRC_CONFIGURATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nbiotrrc_configuration_req + #define NAS_KENB_REFRESH_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_kenb_refresh_req #define NAS_CELL_SELECTION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_cell_selection_req #define NAS_CONN_ESTABLI_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_conn_establi_req @@ -167,6 +169,77 @@ typedef struct RrcConfigurationReq_s { long ue_TimersAndConstants_n311[MAX_NUM_CCs]; long ue_TransmissionMode[MAX_NUM_CCs]; } RrcConfigurationReq; +#define MAX_NUM_NBIOT_CELEVELS 3 +typedef struct NbIoTRrcConfigurationReq_s { + uint32_t cell_identity; + + uint16_t tac; + + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + lte_frame_type_t frame_type; + uint8_t tdd_config; + uint8_t tdd_config_s; + lte_prefix_type_t prefix_type; + lte_prefix_type_t prefix_type_UL; + int16_t eutra_band; + uint32_t downlink_frequency; + int32_t uplink_frequency_offset; + int16_t Nid_cell;// for testing, change later + int16_t N_RB_DL;// for testing, change later + //RACH + long rach_raResponseWindowSize_NB; + long rach_macContentionResolutionTimer_NB; + long rach_powerRampingStep_NB; + long rach_preambleInitialReceivedTargetPower_NB; + long rach_preambleTransMax_CE_NB; + //BCCH + long bcch_modificationPeriodCoeff_NB; + //PCCH + long pcch_defaultPagingCycle_NB; + long pcch_nB_NB; + long pcch_npdcch_NumRepetitionPaging_NB; + //NPRACH + long nprach_CP_Length; + long nprach_rsrp_range; + long nprach_Periodicity[MAX_NUM_NBIOT_CELEVELS]; + long nprach_StartTime[MAX_NUM_NBIOT_CELEVELS]; + long nprach_SubcarrierOffset[MAX_NUM_NBIOT_CELEVELS]; + long nprach_NumSubcarriers[MAX_NUM_NBIOT_CELEVELS]; + long numRepetitionsPerPreambleAttempt_NB[MAX_NUM_NBIOT_CELEVELS]; + long nprach_SubcarrierMSG3_RangeStart; + long maxNumPreambleAttemptCE_NB; + long npdcch_NumRepetitions_RA[MAX_NUM_NBIOT_CELEVELS]; + long npdcch_StartSF_CSS_RA[MAX_NUM_NBIOT_CELEVELS]; + long npdcch_Offset_RA[MAX_NUM_NBIOT_CELEVELS]; + //NPDSCH + long npdsch_nrs_Power; + //NPUSCH + long npusch_ack_nack_numRepetitions_NB; + long npusch_srs_SubframeConfig_NB; + long npusch_threeTone_CyclicShift_r13; + long npusch_sixTone_CyclicShift_r13; + BOOLEAN_t npusch_groupHoppingEnabled; + long npusch_groupAssignmentNPUSCH_r13; + + //DL_GapConfig + long dl_GapThreshold_NB; + long dl_GapPeriodicity_NB; + long dl_GapDurationCoeff_NB; + //Uplink power control Common + long npusch_p0_NominalNPUSCH; + long npusch_alpha; + long deltaPreambleMsg3; + //UE timers and constants + long ue_TimersAndConstants_t300_NB; + long ue_TimersAndConstants_t301_NB; + long ue_TimersAndConstants_t310_NB; + long ue_TimersAndConstants_t311_NB; + long ue_TimersAndConstants_n310_NB; + long ue_TimersAndConstants_n311_NB; +} NbIoTRrcConfigurationReq; + // UE: NAS -> RRC messages typedef kenb_refresh_req_t NasKenbRefreshReq; diff --git a/openair2/COMMON/tasks_def.h b/openair2/COMMON/tasks_def.h index 530365828d..92d1ff4128 100644 --- a/openair2/COMMON/tasks_def.h +++ b/openair2/COMMON/tasks_def.h @@ -40,6 +40,10 @@ SUB_TASK_DEF(TASK_L2L1, TASK_PDCP_ENB, 200) /// Radio Resource Control task TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200) + +// Define here for now +TASK_DEF(TASK_RRC_ENB_NB_IoT, TASK_PRIORITY_MED, 200) + /// S1ap task /// RAL task for ENB TASK_DEF(TASK_RAL_ENB, TASK_PRIORITY_MED, 200) diff --git a/openair2/ENB_APP/nbiot_config.c b/openair2/ENB_APP/NB_IoT_config.c similarity index 98% rename from openair2/ENB_APP/nbiot_config.c rename to openair2/ENB_APP/NB_IoT_config.c index 3862a01403..09e22ef845 100644 --- a/openair2/ENB_APP/nbiot_config.c +++ b/openair2/ENB_APP/NB_IoT_config.c @@ -33,13 +33,6 @@ #include "log.h" #include "log_extern.h" #include "assertions.h" -#include "enb_config.h" -#include "UTIL/OTG/otg.h" -#include "UTIL/OTG/otg_externs.h" -#if defined(OAI_EMU) -# include "OCG.h" -# include "OCG_extern.h" -#endif #if defined(ENABLE_ITTI) # include "intertask_interface.h" # if defined(ENABLE_USE_MME) @@ -47,16 +40,14 @@ # include "sctp_eNB_task.h" # endif #endif -#include "sctp_default_values.h" #include "SystemInformationBlockType2.h" -#include "LAYER2/MAC/extern.h" + #include "PHY/extern.h" #include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" - #include "common/config/config_userapi.h" #include "RRC_config_tools.h" #include "RRC_paramsvalues.h" -#include "nbiot_paramdef.h" +#include "NB_IoT_paramdef.h" #include "L1_paramdef.h" #include "MACRLC_paramdef.h" #include "LAYER2/MAC/proto_NB_IoT.h" diff --git a/openair2/ENB_APP/nbiot_config.h b/openair2/ENB_APP/NB_IoT_config.h similarity index 100% rename from openair2/ENB_APP/nbiot_config.h rename to openair2/ENB_APP/NB_IoT_config.h diff --git a/openair2/ENB_APP/NB_IoT_interface.c b/openair2/ENB_APP/NB_IoT_interface.c new file mode 100644 index 0000000000..30ffbb3bb5 --- /dev/null +++ b/openair2/ENB_APP/NB_IoT_interface.c @@ -0,0 +1,58 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file openair2/ENB_APP/NB_IoT_interface.c + * \brief: load library implementing coding/decoding algorithms + * \date 2018 + * \version 0.1 + * \note + * \warning + */ +#define _GNU_SOURCE +#include + + +#include "openair1/PHY/extern.h" +#include "common/utils/load_module_shlib.h" +#define NBIOT_INTERFACE_SOURCE +#include "NB_IoT_interface.h" + + + + +int load_NB_IoT(void) { + int ret; + RCConfig_NbIoT_f_t RCConfig; + loader_shlibfunc_t shlib_fdesc[]=NBIOT_INTERFACE_FLIST; + + ret=load_module_shlib(NBIOT_MODULENAME,shlib_fdesc,sizeof(shlib_fdesc)/sizeof(loader_shlibfunc_t)); + if (ret) { + return ret; + } + RCConfig = get_shlibmodule_fptr(NBIOT_MODULENAME,NBIOT_RCCONFIG_FNAME ); + if (RCConfig == NULL) { + return -1; + } + + RCConfig(&RC); +return 0; +} + diff --git a/openair2/ENB_APP/NB_IoT_interface.h b/openair2/ENB_APP/NB_IoT_interface.h new file mode 100644 index 0000000000..b3454b077b --- /dev/null +++ b/openair2/ENB_APP/NB_IoT_interface.h @@ -0,0 +1,50 @@ +/* + *Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file openair2/ENB_APP/NB_IoT_interface.h + * \brief: api interface for nb-iot application + * \date 2018 + * \version 0.1 + * \note + * \warning + */ +#ifndef NBIOT_INTERFACE_H +#define NBIOT_INTERFACE_H + + +#define NBIOT_MODULENAME "NB_IoT" + +typedef void(*RCConfig_NbIoT_f_t)(RAN_CONTEXT_t *RC); +#define NBIOT_RCCONFIG_FNAME "RCConfig_NbIoT" + +#ifdef NBIOT_INTERFACE_SOURCE + +#define NBIOT_INTERFACE_FLIST {\ +{NBIOT_RCCONFIG_FNAME,NULL},\ +} + +#else /* NBIOT_INTERFACE_SOURCE */ + +extern int load_NB_IoT(void); + +#endif + +#endif diff --git a/openair2/ENB_APP/nbiot_paramdef.h b/openair2/ENB_APP/NB_IoT_paramdef.h similarity index 100% rename from openair2/ENB_APP/nbiot_paramdef.h rename to openair2/ENB_APP/NB_IoT_paramdef.h diff --git a/openair2/LAYER2/MAC/config_NB_IoT.h b/openair2/LAYER2/MAC/config_NB_IoT.h new file mode 100644 index 0000000000..0e497e3b0f --- /dev/null +++ b/openair2/LAYER2/MAC/config_NB_IoT.h @@ -0,0 +1,301 @@ + +/*! \file config_NB_IoT.h + * \brief configured structures used by scheduler + * \author NTUST BMW Lab./ + * \date 2017 + * \email: + * \version 1.0 + * + */ + +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +//#include "NB_IoT_Message_definitions.h" + +#define NUMBER_OF_SIBS_MAX_NB_IoT 6 + +///MIB +typedef enum operationModeInf{ + iNB_IoTand_SamePCI_r13 = 1, + iNB_IoTand_DifferentPCI_r13 = 2, + guardband_r13 = 3, + standalone_r13 = 4 +}operationModeInf_t; + +///SIB1_SchedulingInfo_NB_IoT_r13 +typedef enum si_Periodicity{ + si_Periodicity_rf64=640, + si_Periodicity_rf128=1280, + si_Periodicity_rf256=2560, + si_Periodicity_rf512=5120, + si_Periodicity_rf1024=10240, + si_Periodicity_rf2048=20480, + si_Periodicity_rf4096=40960 +}si_Periodicity_NB_IoT; + +typedef enum si_RepetitionPattern{ + si_RepetitionPattern_every2ndRF=0, + si_RepetitionPattern_every4thRF, + si_RepetitionPattern_every8thRF, + si_RepetitionPattern_every16thRF +}si_RepetitionPattern_NB_IoT; + +typedef enum sib_MappingInfo{ + sib2_v=0x1, + sib3_v=0x2, + sib4_v=0x4, + sib5_v=0x8, + sib14_v=0x10, + sib16_v=0x20 +}sib_MappingInfo_NB_IoT; + +typedef enum si_TB{ + si_TB_56=2, + si_TB_120=2, + si_TB_208=8, + si_TB_256=8, + si_TB_328=8, + si_TB_440=8, + si_TB_552=8, + si_TB_680=8 +}si_TB_NB_IoT; + +///RACH_ConfigCommon configuration + +typedef enum ra_ResponseWindowSize{ + ra_ResponseWindowSize_pp2=2, + ra_ResponseWindowSize_pp3=3, + ra_ResponseWindowSize_pp4=4, + ra_ResponseWindowSize_pp5=5, + ra_ResponseWindowSize_pp6=6, + ra_ResponseWindowSize_pp7=7, + ra_ResponseWindowSize_pp8=8, + ra_ResponseWindowSize_pp10=10 +}ra_ResponseWindowSize_NB_IoT; + +typedef enum mac_ContentionResolutionTimer{ + mac_ContentionResolutionTimer_pp1=1, + mac_ContentionResolutionTimer_pp2=2, + mac_ContentionResolutionTimer_pp3=3, + mac_ContentionResolutionTimer_pp4=4, + mac_ContentionResolutionTimer_pp8=8, + mac_ContentionResolutionTimer_pp16=16, + mac_ContentionResolutionTimer_pp32=32, + mac_ContentionResolutionTimer_pp64=64 +}mac_ContentionResolutionTimer_NB_IoT; + +///NPRACH_ConfigSIB configuration + +typedef enum nprach_Periodicity{ + nprach_Periodicity_ms40=40, + nprach_Periodicity_ms80=80, + nprach_Periodicity_ms160=160, + nprach_Periodicity_ms240=240, + nprach_Periodicity_ms320=320, + nprach_Periodicity_ms640=640, + nprach_Periodicity_ms1280=1280, + nprach_Periodicity_ms2560=2560 +}nprach_Periodicity_NB_IoT; + +typedef enum nprach_StartTime{ + nprach_StartTime_ms8=8, + nprach_StartTime_ms16=16, + nprach_StartTime_ms32=32, + nprach_StartTime_ms64=64, + nprach_StartTime_ms128=128, + nprach_StartTime_ms256=256, + nprach_StartTime_ms512=512, + nprach_StartTime_ms1024=1024 +}nprach_StartTime_NB_IoT; + +typedef enum nprach_SubcarrierOffset{ + nprach_SubcarrierOffset_n0=0, + nprach_SubcarrierOffset_n12=12, + nprach_SubcarrierOffset_n24=24, + nprach_SubcarrierOffset_n36=36, + nprach_SubcarrierOffset_n2=2, + nprach_SubcarrierOffset_n18=18, + nprach_SubcarrierOffset_n34=34 +}nprach_SubcarrierOffset_NB_IoT; + +typedef enum nprach_NumSubcarriers{ + nprach_NumSubcarriers_n12=12, + nprach_NumSubcarriers_n24=24, + nprach_NumSubcarriers_n36=36, + nprach_NumSubcarriers_n48=48 +}nprach_NumSubcarriers_NB_IoT; + +typedef enum nprach_SubcarrierMSG3_RangeStart{ + nprach_SubcarrierMSG3_RangeStart_zero=0, + nprach_SubcarrierMSG3_RangeStart_oneThird=1/3, + nprach_SubcarrierMSG3_RangeStart_twoThird=2/3, + nprach_SubcarrierMSG3_RangeStart_one=1 +}nprach_SubcarrierMSG3_RangeStart_NB_IoT; + +typedef enum maxNumPreambleAttemptCE{ + maxNumPreambleAttemptCE_n3=3, + maxNumPreambleAttemptCE_n4=4, + maxNumPreambleAttemptCE_n5=5, + maxNumPreambleAttemptCE_n6=6, + maxNumPreambleAttemptCE_n7=7, + maxNumPreambleAttemptCE_n8=8, + maxNumPreambleAttemptCE_n10=10 +}maxNumPreambleAttemptCE_NB_IoT; + +typedef enum numRepetitionsPerPreambleAttempt{ + numRepetitionsPerPreambleAttempt_n1=1, + numRepetitionsPerPreambleAttempt_n2=2, + numRepetitionsPerPreambleAttempt_n4=4, + numRepetitionsPerPreambleAttempt_n8=8, + numRepetitionsPerPreambleAttempt_n16=16, + numRepetitionsPerPreambleAttempt_n32=32, + numRepetitionsPerPreambleAttempt_n64=64, + numRepetitionsPerPreambleAttempt_n128=128 +}numRepetitionsPerPreambleAttempt_NB_IoT; + +typedef enum npdcch_NumRepetitions_RA{ + npdcch_NumRepetitions_RA_r1=1, + npdcch_NumRepetitions_RA_r2=2, + npdcch_NumRepetitions_RA_r4=4, + npdcch_NumRepetitions_RA_r8=8, + npdcch_NumRepetitions_RA_r16=16, + npdcch_NumRepetitions_RA_r32=32, + npdcch_NumRepetitions_RA_r64=64, + npdcch_NumRepetitions_RA_r128=128, + npdcch_NumRepetitions_RA_r256=256, + npdcch_NumRepetitions_RA_r512=512, + npdcch_NumRepetitions_RA_r1024=1024, + npdcch_NumRepetitions_RA_r2048=2048 +}npdcch_NumRepetitions_RA_NB_IoT; + +typedef enum npdcch_StartSF_CSS_RA{ + npdcch_StartSF_CSS_RA_v1dot5=3/2, + npdcch_StartSF_CSS_RA_v2=2, + npdcch_StartSF_CSS_RA_v4=4, + npdcch_StartSF_CSS_RA_v8=8, + npdcch_StartSF_CSS_RA_v16=16, + npdcch_StartSF_CSS_RA_v32=32, + npdcch_StartSF_CSS_RA_v48=48, + npdcch_StartSF_CSS_RA_v64=64 +}npdcch_StartSF_CSS_RA_NB_IoT; + +typedef enum npdcch_Offset_RA{ + zero=0, + oneEighth=1/8, + oneFourth=1/4, + threeEighth=3/8 +}npdcch_Offset_RA_NB_IoT; + +typedef enum si_window_length_e{ + ms160=160, + ms320=320, + ms480=480, + ms640=640, + ms960=960, + ms1280=1280, + ms1600=1600 +}si_window_length_t; + +typedef enum si_periodicity_e{ + rf64=640, + rf128=1280, + rf256=2560, + rf512=5120, + rf1024=10240, + rf2048=20480, + rf4096=40960 +}si_periodicity_t; + +typedef enum si_repetition_pattern_e{ + every2ndRF=20, + every4thRF=40, + every8thRF=80, + every16thRF=160 +}si_repetition_pattern_t; + +typedef enum si_tb_e{ + b56=2, + b120=2, + b208=8, + b256=8, + b328=8, + b440=8, + b552=8, + b680=8 +}si_tb_t; + + +typedef struct sibs_NB_IoT_sched_s{ + si_periodicity_t si_periodicity; + si_repetition_pattern_t si_repetition_pattern; + sib_MappingInfo_NB_IoT sib_mapping_info; //bit vector + si_tb_t si_tb; + +}sibs_NB_IoT_sched_t; + + +///-------------------------------------------------------MAC--------------------------------------------------------------------/// +typedef struct sib1_NB_IoT_sched_s{ + int repetitions; // 4, 8, 16 + int starting_rf; +}sib1_NB_IoT_sched_t; + +typedef struct { + + uint32_t mac_ra_ResponseWindowSize_NB_IoT; + uint32_t mac_ContentionResolutionTimer_NB_IoT; + +}mac_RACH_ConfigCommon_NB_IoT; + +typedef struct { + + uint32_t mac_nprach_Periodicity_NB_IoT; + uint32_t mac_nprach_StartTime_NB_IoT; + uint32_t mac_nprach_SubcarrierOffset_NB_IoT; + uint32_t mac_nprach_NumSubcarriers_NB_IoT; + uint32_t mac_nprach_SubcarrierMSG3_RangeStart_NB_IoT; + uint32_t mac_maxNumPreambleAttemptCE_NB_IoT; + uint32_t mac_numRepetitionsPerPreambleAttempt_NB_IoT; + // css + uint32_t mac_npdcch_NumRepetitions_RA_NB_IoT; // rmax + uint32_t mac_npdcch_StartSF_CSS_RA_NB_IoT; // G + uint32_t mac_npdcch_Offset_RA_NB_IoT; // alpha offset + +}mac_NPRACH_ConfigSIB_NB_IoT; + +typedef struct{ + //npdcch-NumRepetitions-r13 + uint32_t R_max; + //npdcch-StartSF-USS-r13 + double G; + //npdcch-Offset-USS-r13 + double a_offset; +}npdcch_ConfigDedicated_NB_IoT; + +typedef struct rrc_config_NB_IoT_s{ + + ///MIB + uint16_t schedulingInfoSIB1_NB_IoT; + + ///SIB1 + uint32_t cellIdentity_NB_IoT; + + sib1_NB_IoT_sched_t sib1_NB_IoT_sched_config; + ///SIBS + sibs_NB_IoT_sched_t sibs_NB_IoT_sched[NUMBER_OF_SIBS_MAX_NB_IoT]; + si_window_length_t si_window_length; + uint32_t si_radio_frame_offset; + + ///SIB2 mac_RACH_ConfigCommon_NB_IoT + mac_RACH_ConfigCommon_NB_IoT mac_RACH_ConfigCommon[3]; + + ///SIB2 mac_NPRACH_ConfigSIB_NB_IoT + mac_NPRACH_ConfigSIB_NB_IoT mac_NPRACH_ConfigSIB[3]; + + ///NPDCCH Dedicated config + npdcch_ConfigDedicated_NB_IoT npdcch_ConfigDedicated[3]; + +}rrc_config_NB_IoT_t; + +#endif diff --git a/openair2/LAYER2/MAC/defs_NB_IoT.h b/openair2/LAYER2/MAC/defs_NB_IoT.h new file mode 100644 index 0000000000..a427de5b2c --- /dev/null +++ b/openair2/LAYER2/MAC/defs_NB_IoT.h @@ -0,0 +1,543 @@ + +/*! \file defs_NB_IoT.c + * \brief MAC layer structures + * \author NTUST BMW Lab./ + * \date 2017 + * \email: + * \version 1.0 + * + */ +#ifndef __LAYER2_MAC_DEFS_NB_IOT_H__ +#define __LAYER2_MAC_DEFS_NB_IOT_H__ +#ifdef USER_MODE +#include +#include +#include +#endif +//#include "COMMON/openair_defs.h" +#include "COMMON/platform_constants.h" +#include "COMMON/mac_rrc_primitives.h" +#include "PHY/LTE_TRANSPORT/defs_NB_IoT.h" +//#include "PHY/defs.h" +#include "PHY/defs_L1_NB_IoT.h" +#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h" +#include "config_NB_IoT.h" +// MAC definition +#define MAX_FRAME 0xfffff +#define NUM_FRAME 0x100000 +#define MAX_SUBFRAME 10485760 + +#define MAX(a, b) (((a)>(b))?(a):(b)) + +// RA-RNTI: 1+SFN_id>>2 +#define RA_RNTI_LOW 0x0001 // SFN_id = 0 +#define RA_RNTI_HIGH 0x0100 // SFN_id = 1023 +#define C_RNTI_LOW 0x0101 +#define C_RNTI_HIGH + +// ULSCH LCHAN IDs +/*!\brief LCID of extended power headroom for ULSCH */ +#define EXTENDED_POWER_HEADROOM 25 +/*!\brief LCID of power headroom for ULSCH */ +#define POWER_HEADROOM 26 +/*!\brief LCID of CRNTI for ULSCH */ +#define CRNTI 27 +/*!\brief LCID of truncated BSR for ULSCH */ +#define TRUNCATED_BSR 28 +/*!\brief LCID of short BSR for ULSCH */ +#define SHORT_BSR 29 +/*!\brief LCID of long BSR for ULSCH */ +#define LONG_BSR 30 +/*! \brief Values of CCCH LCID for DLSCH */ +#define CCCH_LCHANID 0 +/*!\brief Values of BCCH logical channel */ +#define BCCH 3 // SI +/*!\brief Values of PCCH logical channel */ +#define PCCH 4 // Paging +/*!\brief Value of CCCH / SRB0 logical channel */ +#define CCCH 0 // srb0 +/*!\brief DCCH / SRB1 logical channel */ +#define DCCH 1 // srb1 +/*!\brief DCCH1 / SRB2 logical channel */ +#define DCCH1 2 // srb2 +/*!\brief DTCH DRB1 logical channel */ +#define DTCH 3 // LCID +/*!\brief MCCH logical channel */ +#define MCCH 4 +/*!\brief MTCH logical channel */ +#define MTCH 1 +// DLSCH LCHAN ID +/*!\brief LCID of UE contention resolution identity for DLSCH*/ +#define UE_CONT_RES 28 +/*!\brief LCID of timing advance for DLSCH */ +#define TIMING_ADV_CMD 29 +/*!\brief LCID of discontinous reception mode for DLSCH */ +#define DRX_CMD 30 +/*!\brief LCID of padding LCID for DLSCH */ +#define SHORT_PADDING 31 + + +typedef enum tone_type_e +{ + sixtone = 0, + threetone, + singletone1, + singletone2, + singletone3 +}tone_type_t; + +typedef enum channel_NB_IoT_e +{ + NPDCCH = 0, + NPUSCH, + NPDSCH +}channel_NB_IoT_t; + +typedef enum{ + UL = 0, + DL +}message_direction_t; + +#define MAX_NUMBER_OF_UE_MAX_NB_IoT 20 +#define SCH_PAYLOAD_SIZE_MAX_NB_IoT 320 +#define MAX_NUMBER_OF_SIBs_NB_IoT 16 + +/*!\brief Values of BCCH0 logical channel for MIB*/ +#define BCCH0_NB_IoT 11 // MIB-NB_IoT +/*!\brief Values of BCCH1 logical channel for SIBs */ +#define BCCH1_NB_IoT 12 // SI-SIB-NB_IoTs +/*!\brief Values of PCCH logical channel */ +#define PCCH_NB_IoT 13 // Paging XXX not used for the moment +#define MCCH_NB_IoT 14 +/*!\brief Value of CCCH / SRB0 logical channel */ +#define CCCH_NB_IoT 0 // srb0 ---> XXX exactly the same as in LTE (commented for compilation purposes) +/*!\brief DCCH0 / SRB1bis logical channel */ +#define DCCH0_NB_IoT 3 // srb1bis +/*!\brief DCCH1 / SRB1 logical channel */ +#define DCCH1_NB_IoT 1 // srb1 //XXX we redefine it for the SRB1 +/*!\brief DTCH0 DRB0 logical channel */ +#define DTCH0_NB_IoT 4 // DRB0 +/*!\brief DTCH1 DRB1 logical channel */ +#define DTCH1_NB_IoT 5 // DRB1 +/*Index of UE contention resoulution logical channel*/ +#define UE_CONTENTION_RESOLUTION 28 +/*Index of TIMING_ADVANCE logical channel*/ +#define TIMING_ADVANCE 29 +/*Index of DRX_COMMAND logical channel*/ +#define DRX_COMMAND 30 +/*Index of PADDING logical channel*/ +#define PADDING 31 + + +/// NPRACH-ParametersList-NB_IoT-r13 from 36.331 RRC spec defined in PHY +/*typedef struct NPRACH_Parameters_NB_IoT{ + + /// the period time for nprach + int nprach_Periodicity; + /// for the start time for the NPRACH resource from 40ms-2560ms + int nprach_StartTime; + /// for the subcarrier of set to the NPRACH preamble from n0 - n34 + int nprach_SubcarrierOffset; + ///number of subcarriers in a NPRACH resource allowed values (n12,n24,n36,n48) + int nprach_NumSubcarriers; + /// where is the region that in NPRACH resource to indicate if this UE support MSG3 for multi-tone or not. from 0 - 1 + int nprach_SubcarrierMSG3_RangeStart; + /// The max preamble transmission attempt for the CE level from 1 - 128 + int maxNumPreambleAttemptCE; + /// Number of NPRACH repetitions per attempt for each NPRACH resource + int numRepetitionsPerPreambleAttempt; + /// The number of the repetition for DCI use in RAR/MSG3/MSG4 from 1 - 2048 (Rmax) + int npdcch_NumRepetitions_RA; + /// Starting subframe for NPDCCH Common searching space for (RAR/MSG3/MSG4) + int npdcch_StartSF_CSS_RA; + /// Fractional period offset of starting subframe for NPDCCH common search space + int npdcch_Offset_RA; + +} nprach_parameters_NB_IoT_t;*/ + +/*! \brief Downlink SCH PDU Structure */ +typedef struct { + uint8_t payload[SCH_PAYLOAD_SIZE_MAX_NB_IoT]; + uint32_t pdu_size; +} __attribute__ ((__packed__)) DLSCH_PDU_NB_IoT; + +/*! \brief eNB template for UE context information */ +typedef struct { + // C-RNTI of UE + rnti_t rnti; + // UE CE level + int CE_level; + // Direction of transmission(DL:0\UL:1\NONE:-1) + int32_t direction; + // DCI Reptition + uint32_t R_dci; + // MAX repetition + uint32_t R_max; + + // HARQ round + uint32_t HARQ_round; + /*Downlink information*/ + + /// DLSCH pdu + DLSCH_PDU_NB_IoT DLSCH_pdu; + // PDU size + uint32_t DLSCH_pdu_size; + // Data Reptition + uint32_t R_dl; + // MCS index + uint32_t I_mcs_dl; + // total downlink buffer DCCH0_NB_IoT + uint32_t dl_buffer_DCCH0_NB_IoT; + // NDI + int oldNDI_DL; + //HARQ ACK/NACK repetition + uint32_t R_harq; + + /*Uplink information*/ + int oldNDI_UL; + // Uplink data repeat, now just follow the rach repeat number + uint32_t R_ul; + // PHR value (0-3) + uint32_t PHR; + // The uplink data size from BSR or DVI + uint32_t ul_total_buffer; + // Determine if this UE support multi-tone transmission or not + int multi_tone; + // Next UE_template ID + int next; + // Previous UE_template ID + int prev; + // MSG4 complete + int RRC_connected; + // UE active flag + int active; + +} UE_TEMPLATE_NB_IoT; + +/*36331 NPDCCH-ConfigDedicated-NB_IoT*/ +typedef struct{ + //npdcch-NumRepetitions-r13 + uint32_t R_max; + //npdcch-StartSF-USS-r13 + double G; + //npdcch-Offset-USS-r13 + double a_offset; + //NPDCCH period + uint32_t T; + //Starting subfrane of Search Space which is mod T + uint32_t ss_start_uss; +}NPDCCH_config_dedicated_NB_IoT_t; + + +/*! \brief UE list used by eNB to order UEs/CC for scheduling*/ +typedef struct { + + /// DCI template and MAC connection parameters for UEs + UE_TEMPLATE_NB_IoT UE_template_NB_IoT[MAX_NUMBER_OF_UE_MAX_NB_IoT]; + + /// NPDCCH Period and searching space info + NPDCCH_config_dedicated_NB_IoT_t NPDCCH_config_dedicated; + //int next[MAX_NUMBER_OF_UE_MAX_NB_IoT]; + // -1:No UE in list + int head; + // -1:No UE in list + int tail; + int num_UEs; + //boolean_t active[MAX_NUMBER_OF_UE_MAX_NB_IoT]; + +} UE_list_NB_IoT_t; + + +typedef struct{ + + // flag to indicate scheduing MIB-NB_IoT + uint8_t flag_MIB; + // flag to indicate scheduling SIB1-NB_IoT + uint8_t flag_SIB1; + // flag to indicate scheduling SIBs-NB_IoT + uint8_t flag_SIBs[MAX_NUMBER_OF_SIBs_NB_IoT]; + // flag to indicate scheduling type2 NPDCCH CSS with different CE level + uint8_t flag_type2_css[3]; + // flag to indicate scheduling type1 NPDCCH CSS with different CE level + uint8_t flag_type1_css[3]; + // flag to indicate scheduling NPDCCH USS with UE list + uint8_t flag_uss[MAX_NUMBER_OF_UE_MAX_NB_IoT]; + // flag to indicate scheduling sib1/MIB + uint8_t flag_fix_scheduling; + // number of the type2 css to schedule in this period + uint8_t num_type2_css_run; + // number of the type1 css to schedule in this period + uint8_t num_type1_css_run; + // number of the uss to schedule in this period + uint8_t num_uss_run; + +}scheduling_flag_t; + +typedef struct available_resource_UL_s{ + + ///Resource start subframe + uint32_t start_subframe; + ///Resource end subframe + uint32_t end_subframe; + // pointer to next node + struct available_resource_UL_s *next, *prev; + +}available_resource_UL_t; + +typedef struct available_resource_DL_s{ + uint32_t start_subframe; + uint32_t end_subframe; + + struct available_resource_DL_s *next, *prev; +}available_resource_DL_t; + +/*Structure used for scheduling*/ +typedef struct{ + //resource position info. + uint32_t sf_end,sf_start; + //resource position info. separate by HyperSF, Frame, Subframe + uint32_t start_h, end_h; + uint32_t start_f, end_f; + uint32_t start_sf, end_sf; + //whcih available resource node is used + available_resource_DL_t *node; +}sched_temp_DL_NB_IoT_t; + +/*!\brief MAC subheader short with 7bit Length field */ +typedef struct { + uint8_t LCID:5; // octet 1 LSB + uint8_t E:1; + uint8_t F2:1; + uint8_t R:1; // octet 1 MSB + uint8_t L:7; // octet 2 LSB + uint8_t F:1; // octet 2 MSB +} __attribute__((__packed__))SCH_SUBHEADER_SHORT_NB_IoT; +typedef struct { + uint8_t LCID:5; // octet 1 LSB + uint8_t E:1; + uint8_t F2:1; + uint8_t R:1; // octet 1 MSB + uint8_t L_MSB:7; + uint8_t F:1; // octet 2 MSB + uint8_t L_LSB:8; +} __attribute__((__packed__))SCH_SUBHEADER_LONG_NB_IoT; +typedef struct { + uint8_t LCID:5; // octet 1 LSB + uint8_t E:1; + uint8_t F2:1; + uint8_t R:1; // octet 1 MSB + uint8_t L_MSB:8; // octet 2 MSB + uint8_t L_LSB:8; +} __attribute__((__packed__))SCH_SUBHEADER_LONG_EXTEND_NB_IoT; +/*!\brief MAC subheader short without length field */ +typedef struct { + uint8_t LCID:5; + uint8_t F2:1; + uint8_t E:1; + uint8_t R:1; +} __attribute__((__packed__))SCH_SUBHEADER_FIXED_NB_IoT; + + +/*! \brief Uplink SCH PDU Structure */ +typedef struct { + int8_t payload[SCH_PAYLOAD_SIZE_MAX_NB_IoT]; /*!< \brief SACH payload */ + uint16_t Pdu_size; +} __attribute__ ((__packed__)) ULSCH_PDU_NB_IoT; + +typedef struct { + uint8_t PH:6; + uint8_t R:2; +} __attribute__((__packed__))POWER_HEADROOM_CMD_NB_IoT; + +typedef struct { + uint8_t RAPID:6; + uint8_t T:1; + uint8_t E:1; +} __attribute__((__packed__))RA_HEADER_RAPID_NB_IoT; + +/*Structure used for UL scheduling*/ +typedef struct{ + //resource position info. + uint32_t sf_end, sf_start; + //resource position info. separate by HyperSF, Frame, Subframe + //uint32_t start_h, end_h; + //uint32_t start_f, end_f; + //uint32_t start_sf, end_sf; + // information for allocating the resource + int tone; + int scheduling_delay; + int subcarrier_indication; + int ACK_NACK_resource_field; + available_resource_UL_t *node; +}sched_temp_UL_NB_IoT_t; + +typedef struct Available_available_resource_DL{ + + ///Available Resoruce for sixtone + available_resource_UL_t *sixtone_Head;//, *sixtone_npusch_frame; + uint32_t sixtone_end_subframe; + ///Available Resoruce for threetone + available_resource_UL_t *threetone_Head;//, *threetone_npusch_frame; + uint32_t threetone_end_subframe; + ///Available Resoruce for singletone1 + available_resource_UL_t *singletone1_Head;//, *singletone1_npusch_frame; + uint32_t singletone1_end_subframe; + ///Available Resoruce for singletone2 + available_resource_UL_t *singletone2_Head;//, *singletone2_npusch_frame; + uint32_t singletone2_end_subframe; + ///Available Resoruce for singletone3 + available_resource_UL_t *singletone3_Head;//, *singletone3_npusch_frame; + uint32_t singletone3_end_subframe; + +}available_resource_tones_UL_t; + +typedef struct schedule_result{ + // The subframe read by output handler + uint32_t output_subframe; + // SDU length + uint32_t sdu_length; + // MAC PDU + uint8_t *DLSCH_pdu; + // The data direction indicated by this DCI + uint8_t direction; + // pointer to DCI + void *DCI_pdu; + // when all the procedure related to this DCI, enable this flag + boolean_t DCI_release; + // Indicate the channel which to transmit + channel_NB_IoT_t channel; + // rnti + rnti_t rnti; + // 0 = TC-RNTI , 1 = RA-RNTI, 2 = P-RNTI, 3 = others + uint8_t rnti_type; + // 0 = data, 1 = ACK/NACK + uint8_t npusch_format; + //HARQ ACK/NACK repetition + uint32_t R_harq; + // pointer to next node + struct schedule_result *next; + + uint32_t end_subframe; + + uint8_t *rar_buffer; + +}schedule_result_t; + +/*Flag structure used for trigger each scheduler*/ +typedef struct{ + scheduling_flag_t scheduling_flag; + //sched_temp_DL_NB_IoT_t sched_result_DL; + //resource grid for Uplink + available_resource_tones_UL_t *UL_resource; + //scheduling result read by output handler + schedule_result_t *schedule_result_list_UL; + schedule_result_t *schedule_result_list_DL; +}SCHEDULE_NB_IoT_t; + +typedef struct{ + uint32_t num_dlsf_per_period; + uint16_t *sf_to_dlsf_table; + uint16_t *dlsf_to_sf_table; +}DLSF_INFO_t; + +typedef enum ce_level_e{ + ce0=0, + ce1, + ce2, + ce_level_total +}ce_level_t; + + + +/*! \brief eNB template for the Random access information */ +typedef struct RA_TEMPLATE_NB_IoT_s{ + + boolean_t active; + uint32_t msg3_retransmit_count; + uint32_t msg4_retransmit_count; + uint16_t ta; + uint8_t preamble_index; + ce_level_t ce_level; + rnti_t ue_rnti; + rnti_t ra_rnti; + struct RA_TEMPLATE_NB_IoT_s *next, *prev; + boolean_t wait_msg4_ack; + boolean_t wait_msg3_ack; + uint8_t rar_buffer[7]; + +} RA_TEMPLATE_NB_IoT; + +typedef struct RA_template_list_s{ + RA_TEMPLATE_NB_IoT *head; + RA_TEMPLATE_NB_IoT *tail; +}RA_template_list_t; + + +/*! \brief top level eNB MAC structure */ +typedef struct eNB_MAC_INST_NB_IoT_s { + /// Ethernet parameters for northbound midhaul interface + eth_params_t eth_params_n; + /// Ethernet parameters for fronthaul interface + eth_params_t eth_params_s; + + uint8_t Mod_id; + // System + uint32_t hyper_system_frame; + uint32_t system_frame; + uint32_t sub_frame; + + uint32_t current_subframe; + /// Pointer to IF module instance for PHY + IF_Module_t *if_inst; + // RA + RA_template_list_t RA_msg2_list; + RA_template_list_t RA_msg3_list; + RA_template_list_t RA_msg4_list; + + RA_TEMPLATE_NB_IoT RA_template[MAX_NUMBER_OF_UE_MAX_NB_IoT]; + + //int32_t last_tx_subframe; + + // for tool + int32_t sib1_flag[64]; + int32_t sib1_count[64]; + int32_t sib1_period; + uint16_t dlsf_table[64]; + int32_t sibs_table[256]; + + // channel config + + //USS list + //Number of USS period is used + int num_uss_list; + UE_list_NB_IoT_t *UE_list_spec; + + scheduling_flag_t scheduling_flag; + + uint32_t schedule_subframe_DL; + uint32_t schedule_subframe_UL; + + rrc_config_NB_IoT_t rrc_config; + + nfapi_config_request_t config; + + IF_Module_NB_IoT_t *if_inst_NB_IoT; +} eNB_MAC_INST_NB_IoT; + +// actually not here, but for now put it here +typedef struct { + uint32_t bytes_in_buffer; /*!< \brief Bytes buffered in RLC protocol instance. */ + uint32_t pdus_in_buffer; /*!< \brief Number of PDUs buffered in RLC protocol instance (OBSOLETE). */ + uint32_t head_sdu_creation_time; /*!< \brief Head SDU creation time. */ + uint32_t head_sdu_remaining_size_to_send; /*!< \brief remaining size of sdu: could be the total size or the remaining size of already segmented sdu */ + boolean_t head_sdu_is_segmented; /*!< \brief 0 if head SDU has not been segmented, 1 if already segmented */ +} mac_rlc_status_resp_NB_IoT_t; + +// global variables + +nprach_parameters_NB_IoT_t nprach_list[3]; + +//DLSF Table +DLSF_INFO_t DLSF_information; + +#endif /*__LAYER2_MAC_DEFS_NB_IoT_H__ */ diff --git a/openair2/LAYER2/MAC/proto_NB_IoT.h b/openair2/LAYER2/MAC/proto_NB_IoT.h new file mode 100644 index 0000000000..e493275987 --- /dev/null +++ b/openair2/LAYER2/MAC/proto_NB_IoT.h @@ -0,0 +1,198 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file LAYER2/MAC/proto_NB_IoT.h + * \brief MAC functions prototypes for eNB and UE + * \author Navid Nikaein and Raymond Knopp + * \date 2010 - 2014 + * \email navid.nikaein@eurecom.fr + * \version 1.0 + */ + +#ifndef __LAYER2_MAC_PROTO_NB_IoT_H__ +#define __LAYER2_MAC_PROTO_NB_IoT_H__ + +#include "openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h" +#include "LAYER2/MAC/defs_NB_IoT.h" +#include "COMMON/platform_types.h" +#include "openair2/RRC/LITE/defs_NB_IoT.h" +/** \addtogroup _mac + * @{ + */ + +int l2_init_eNB_NB_IoT(void); + +///config +void rrc_mac_config_req_NB_IoT( + module_id_t Mod_idP, + int CC_idP, + int rntiP, + rrc_eNB_carrier_data_NB_IoT_t *carrier, + SystemInformationBlockType1_NB_t *sib1_NB_IoT, + RadioResourceConfigCommonSIB_NB_r13_t *radioResourceConfigCommon, + PhysicalConfigDedicated_NB_r13_t *physicalConfigDedicated, + LogicalChannelConfig_NB_r13_t *logicalChannelConfig, //FIXME: decide how to use it + uint8_t ded_flag, + uint8_t ue_list_ded_num); + +///system +void init_mac_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst); +//void init_rrc_NB_IoT(); +void release_mac_inst(uint8_t order); +eNB_MAC_INST_NB_IoT *get_mac_inst(uint8_t order); +uint8_t register_mac_inst(eNB_MAC_INST_NB_IoT *inst, uint8_t order); + +///tool +void init_tool(sib1_NB_IoT_sched_t *config); +void UE_info_setting(UE_TEMPLATE_NB_IoT *UE_info); +UE_TEMPLATE_NB_IoT *get_ue_from_rnti(eNB_MAC_INST_NB_IoT *inst, rnti_t rnti); + +///scheduler +void eNB_dlsch_ulsch_scheduler_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t abs_subframe); +void eNB_scheduler_computing_flag_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t abs_subframe, uint32_t *scheduler_flags, uint32_t *common_flags, uint32_t *max_subframe); + +//Calvin temp define self-tools +int init_debug(eNB_MAC_INST_NB_IoT *inst); +void maintain_available_resource(eNB_MAC_INST_NB_IoT *mac_inst); +void extend_available_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, int max_subframe); +available_resource_DL_t *check_sibs_resource(eNB_MAC_INST_NB_IoT *mac_inst, int check_start_subframe, int check_end_subframe, int num_subframe, int *residual_subframe, int *out_last_subframe, int *out_first_subframe); +uint32_t calculate_DLSF(eNB_MAC_INST_NB_IoT *mac_inst, int abs_start_subframe, int abs_end_subframe); +void init(eNB_MAC_INST_NB_IoT *mac_inst); +void init_dl_list(eNB_MAC_INST_NB_IoT *mac_inst); +int is_dlsf(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe); +void fill_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, available_resource_DL_t *node, int start_subframe, int end_subframe, schedule_result_t *new_node); +available_resource_DL_t *check_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, int check_subframe, int num_subframes, int *out_last_subframe, int *out_first_subframe); +void print_available_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst); +void print_schedule_result_DL(void); +void print_schedule_result_UL(void); +void add_ue(eNB_MAC_INST_NB_IoT *mac_inst, uint16_t rnti, ce_level_t ce, uint32_t PHR, uint32_t ul_total_buffer); +void remove_ue(eNB_MAC_INST_NB_IoT *mac_inst, uint16_t rnti, ce_level_t ce); +// SIBs +void schedule_sibs(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t sibs_order, int start_subframe); + +//RA +void msg3_do_retransmit_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t c_rnti); +void msg4_do_retransmit_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t c_rnti); +void schedule_RA_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst); +void init_RA_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint8_t preamble_index, ce_level_t ce_level, uint32_t sfn_id, uint16_t ta); +void schedule_rar_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe); +void receive_msg3_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t c_rnti, uint32_t phr, uint32_t ul_total_buffer); +void schedule_msg3_retransimission_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe); +void schedule_msg4_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe); +void fill_rar_NB_IoT(eNB_MAC_INST_NB_IoT *inst, RA_TEMPLATE_NB_IoT *ra_template, uint8_t msg3_schedule_delay, uint8_t msg3_rep, sched_temp_UL_NB_IoT_t *schedule_template); +void receive_msg4_ack_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t rnti); + +//USS +void schedule_uss_NB_IoT(module_id_t module_id, eNB_MAC_INST_NB_IoT *mac_inst, uint32_t subframe, uint32_t frame, uint32_t hypersfn, int index_ss); + +//DATA +uint8_t *parse_ulsch_header( uint8_t *mac_header, + uint8_t *num_ce, + uint8_t *num_sdu, + uint8_t *rx_ces, + uint8_t *rx_lcids, + uint16_t *rx_lengths, + uint16_t tb_length ); + +/*******UL Scheduler**********/ +void print_scheduling_result_UL(void); +void print_available_UL_resource(void); +/*set nprach configuration at intial time*/ +void setting_nprach(void); +/*Uplink main scheduler*/ +int schedule_UL_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst,UE_TEMPLATE_NB_IoT *UE_info, uint32_t subframe, uint32_t frame, uint32_t H_SFN); +/*Check available uplink resource list, if there is available uplink resource, return 0, otherwise, return 1*/ +int Check_UL_resource(uint32_t DL_end, int total_ru, sched_temp_UL_NB_IoT_t *NPUSCH_info, int multi_tone, int fmt2_flag); +/*Get I Repetition number in DCI*/ +int get_I_REP(int N_rep); +/*Get N REP from preamble repeat*/ +int get_N_REP(int CE_level); +/*Get TBS from mcs, multi-tone, Iru*/ +int get_TBS_UL_NB_IoT(uint32_t mcs,uint32_t multi_tone,int Iru); +/*get I tbs from mcs and multi-tone*/ +int get_I_TBS_NB_IoT(int x,int y); +/*Get DCI REP from R max and R*/ +int get_DCI_REP(uint32_t R,uint32_t R_max); +/*Check single tone resource list*/ +int single_tone_ru_allocation(uint32_t uplink_time, int total_ru, sched_temp_UL_NB_IoT_t *NPUSCH_info, int fmt2_flag); +/*Check multi tone resource list*/ +int multi_tone_ru_allocation(uint32_t uplink_time, int total_ru, sched_temp_UL_NB_IoT_t *NPUSCH_info); +/*Generate scheduling result of DCI N0 and Uplink config*/ +void generate_scheduling_result_UL(int32_t DCI_subframe, int32_t DCI_end_subframe, uint32_t UL_subframe, uint32_t UL_end_subframe, DCIFormatN0_t *DCI_inst, rnti_t rnti, uint8_t *ul_debug_str, uint8_t *dl_debug_str); +/*Adjust UL resource by removing the used resource*/ +void adjust_UL_resource_list(sched_temp_UL_NB_IoT_t *NPUSCH_info); +/*Initialize resource by nprach configuration*/ +void Initialize_Resource(void); +/*Function to extend uplink resource grid*/ +//void add_UL_Resource(eNB_MAC_INST_NB_IoT *mac_inst); +void add_UL_Resource(void); +/*Get ACK/NAK resource field*/ +int get_resource_field_value(int subcarrier, int k0); +/*Get DL Repetition index*/ +uint8_t get_index_Rep_dl(uint16_t R); + +/*******DL Scheduler********/ +void schedule_DL_NB_IoT(module_id_t module_id, eNB_MAC_INST_NB_IoT *mac_inst, UE_TEMPLATE_NB_IoT *UE_info, uint32_t hyperSF_start, uint32_t frame_start, uint32_t subframe_start); +int check_resource_NPDCCH_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t hyperSF_start, uint32_t frame_start, uint32_t subframe_start, sched_temp_DL_NB_IoT_t *NPDCCH_info, uint32_t cdd_num, uint32_t dci_rep); +int check_resource_NPDSCH_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, sched_temp_DL_NB_IoT_t *NPDSCH_info, uint32_t sf_end, uint32_t I_delay, uint32_t R_max, uint32_t R_dl, uint32_t n_sf); +int check_resource_DL_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t hyperSF_start, uint32_t frame_start, uint32_t subframe_start, uint32_t dlsf_require, sched_temp_DL_NB_IoT_t *schedule_info); +uint32_t get_I_mcs(int CE_level); +uint32_t get_max_tbs(uint32_t I_tbs); +uint32_t get_tbs(uint32_t data_size, uint32_t I_tbs, uint32_t *I_sf); +uint32_t get_num_sf(uint32_t I_sf); +uint32_t get_scheduling_delay(uint32_t I_delay, uint32_t R_max); +uint32_t get_HARQ_delay(int subcarrier_spacing, uint32_t HARQ_delay_index); +//void generate_scheduling_result_DL(uint32_t DCI_subframe, uint32_t NPDSCH_subframe, uint32_t HARQ_subframe, DCIFormatN1_t *DCI, rnti_t rnti, uint32_t TBS, uint8_t *DLSCH_pdu); +void generate_scheduling_result_DL(sched_temp_DL_NB_IoT_t* DCI_info, sched_temp_DL_NB_IoT_t* NPDSCH_info, sched_temp_UL_NB_IoT_t* HARQ_info, DCIFormatN1_t *DCI_inst, rnti_t rnti, uint32_t TBS, uint8_t *DLSCH_pdu); +void fill_DCI_N1(DCIFormatN1_t *DCI_N1, UE_TEMPLATE_NB_IoT *UE_info, uint32_t scheddly, uint32_t I_sf, uint32_t I_harq); +//Transfrom source into hyperSF, Frame, Subframe format +void convert_system_number(uint32_t source_sf,uint32_t *hyperSF, uint32_t *frame, uint32_t *subframe); +//Trnasform hyperSF, Frame, Subframe format into subframe unit +uint32_t convert_system_number_sf(uint32_t hyperSF, uint32_t frame, uint32_t subframe); +/*input start position amd num_dlsf DL subframe, caculate the last subframe number*/ +uint32_t cal_num_dlsf(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t hyperSF, uint32_t frame, uint32_t subframe, uint32_t* hyperSF_result, uint32_t* frame_result, uint32_t* subframe_result, uint32_t num_dlsf_require); +void init_dlsf_info(eNB_MAC_INST_NB_IoT *mac_inst, DLSF_INFO_t *DLSF_info); +uint32_t generate_dlsch_header_NB_IoT(uint8_t *pdu, uint32_t num_sdu, logical_chan_id_t *logical_channel, uint32_t *sdu_length, uint8_t flag_drx, uint8_t flag_ta, uint32_t TBS); +void maintain_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, sched_temp_DL_NB_IoT_t *NPDCCH_info, sched_temp_DL_NB_IoT_t *NPDSCH_info); +void init_tool_sib1(eNB_MAC_INST_NB_IoT *mac_inst); +//int is_dlsf(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe); +/**DL test , delete**/ +available_resource_DL_t* new_dl_node(uint32_t start_subframe, uint32_t end_subframe, uint32_t dlsf); +void initialize_dl_resource(available_resource_DL_t *DL_Resource_node, uint32_t start_subframe, uint32_t end_subframe, uint32_t dlsf); +void insert_dl_resource(available_resource_DL_t *DL_Resource_node); +void insert_schedule_result(schedule_result_t **list, int subframe, schedule_result_t *node); +//interface with IF + +uint8_t *parse_ulsch_header_NB_IoT( uint8_t *mac_header, uint8_t *num_ce, uint8_t *num_sdu, uint8_t *rx_ces, uint8_t *rx_lcids, uint16_t *rx_lengths, uint16_t tb_length); + +void rx_sdu_NB_IoT(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t subframe, uint16_t rnti, uint8_t *sdu, uint16_t length); + +int output_handler(eNB_MAC_INST_NB_IoT *mac_inst, module_id_t module_id, int CC_id, uint32_t hypersfn, uint32_t frame, uint32_t subframe, uint8_t MIB_flag, uint8_t SIB1_flag, uint32_t current_time); +// main + +void mac_top_init_eNB_NB_IoT(void); + +uint32_t to_earfcn_NB_IoT(int eutra_bandP,uint32_t dl_CarrierFreq, float m_dl); + +uint32_t from_earfcn_NB_IoT(int eutra_bandP,uint32_t dl_earfcn, float m_dl); + +int32_t get_uldl_offset_NB_IoT(int eutra_band); +#endif diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 05855a14bd..2de1b3fc74 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -769,18 +769,15 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t* const ctxt_pP) { - //unsigned char *otg_pkt=NULL; + module_id_t dst_id; // dst for otg - //rb_id_t rb_id; - //unsigned int pkt_size=0; protocol_ctxt_t ctxt; // we need to add conditions to avoid transmitting data when the UE is not RRC connected. if ((otg_enabled==1) && (ctxt_pP->enb_flag == ENB_FLAG_YES)) { // generate DL traffic - //unsigned int ctime=0; - //ctime = ctxt_pP->frame * 100; - /*if ((mac_get_rrc_status(eNB_index, ctxt_pP->enb_flag, 0 ) > 2) && - (mac_get_rrc_status(eNB_index, ctxt_pP->enb_flag, 1 ) > 2)) { */ + + + PROTOCOL_CTXT_SET_BY_MODULE_ID( &ctxt, ctxt_pP->module_id, @@ -792,36 +789,7 @@ void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t* const ctxt_pP) for (dst_id = 0; dst_id 2 ) { - unsigned int temp = 0; - otg_pkt=packet_gen( - ENB_MODULE_ID_TO_INSTANCE(ctxt.module_id), - UE_MODULE_ID_TO_INSTANCE(dst_id), - 0, - ctime, - &temp); - pkt_size = temp; - if (otg_pkt != NULL) { - rb_id = dst_id * maxDRB + DTCH; - pdcp_data_req(&ctxt, - SRB_FLAG_NO, - rb_id, - RLC_MUI_UNDEFINED, - RLC_SDU_CONFIRM_NO, - pkt_size, - otg_pkt, - PDCP_TRANSMISSION_MODE_DATA); - LOG_I(OTG, - "send packet from module %d on rab id %d (src %d, dst %d) pkt size %d\n", - ctxt_pP->module_id, rb_id, ctxt_pP->module_id, dst_id, pkt_size); - free(otg_pkt); - } - } - } -*/ } } } diff --git a/openair2/PHY_INTERFACE/IF_Module_NB_IoT.h b/openair2/PHY_INTERFACE/IF_Module_NB_IoT.h new file mode 100644 index 0000000000..479bd47d94 --- /dev/null +++ b/openair2/PHY_INTERFACE/IF_Module_NB_IoT.h @@ -0,0 +1,215 @@ + +/*This is the interface module between PHY +*Provided the FAPI style interface structures for P7. +*Provide the semi-FAPI style interface for P5 (configuration) +* +*/ + +#ifndef __IF_MODULE_NB_IoT__H__ +#define __IF_MODULE_NB_IoT__H__ + +#include "nfapi_interface.h" +//#include "openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h" +#include "PhysicalConfigDedicated-NB-r13.h" +//#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h" +#include "openair2/COMMON/platform_types.h" +//#include "openair1/SCHED/IF_Module_L1_primitives_NB_IoT.h" + +//#define SCH_PAYLOAD_SIZE_MAX 4096 +#define BCCH_PAYLOAD_SIZE_MAX_NB_IoT 128 + + + +// P5 FAPI-like configuration structures------------------------------------------------------------------------------- + +/*MP: MISSED COMMON CONFIG. of SIB2-NB in FAPI SPECS + * some of them may not needed because are used only at UE side + * some of them are not needed because not necessary at PHY level + * other have to be clarified since seems to be needed at PHY layer + * there is no UE_Config. request message carrying NB-IoT parameters??? + * + * */ +typedef struct{ + //nprach_config + uint16_t nprach_config_0_subcarrier_MSG3_range_start; + uint16_t nprach_config_1_subcarrier_MSG3_range_start; + uint16_t nprach_config_2_subcarrier_MSG3_range_start; + uint16_t nprach_config_0_max_num_preamble_attempt_CE; + uint16_t nprach_config_1_max_num_preamble_attempt_CE; + uint16_t nprach_config_2_max_num_preamble_attempt_CE; + uint16_t nprach_config_0_npdcch_num_repetitions_RA; //Rmax (see TS 36.213 ch 16.6) -->only this is managed at PHY layer + uint16_t nprach_config_1_npdcch_num_repetitions_RA; + uint16_t nprach_config_2_npdcch_num_repetitions_RA; + uint16_t nprach_config_0_npdcch_startSF_CSS_RA; //G (see TS 36.213 ch 16.6) + uint16_t nprach_config_1_npdcch_startSF_CSS_RA; + uint16_t nprach_config_2_npdcch_startSF_CSS_RA; + uint16_t nprach_config_0_npdcch_offset_RA; //Alfa_offset (see TS 36.213 ch 16.6) + uint16_t nprach_config_1_npdcch_offset_RA; + uint16_t nprach_config_2_npdcch_offset_RA; + + //configured through the phy_config_dedicated + //Higher layer parameter for NPDCCH UE-spec search space + uint16_t npdcch_NumRepetitions;//Rmax (see TS 36.213 ch 16.6) -->only this is managed at PHY layer + uint16_t npdcch_StartSF_USS; //G (see TS 36.213 ch 16.6) + uint16_t npdcch_Offset_USS; //Alfa_offset (see TS 36.213 ch 16.6) + + + ACK_NACK_NumRepetitions_NB_r13_t *ack_nack_numRepetitions_MSG4; //pointer to the first cell of a list of ack_nack_num_repetitions + + //ulPowerControlCommon (UE side) + uint16_t p0_nominal_npusch; + uint16_t alpha; + uint16_t delta_preamle_MSG3; + + + /*Dedicated configuration -->not supported by FAPI (may not needed) + * In OAI at least are needed when we manage the phy_procedures_eNB_TX in which we call the phy_config_dedicated_eNB_step2 + * that use the physicalConfigDedicated info previously stored in the PHY_VARS_eNB_NB_IoT structure through the phy_config_dedicated procedure + */ + //PhysicalConfigDedicated_NB_r13_t *phy_config_dedicated; + + + + +}extra_phyConfig_t; + +typedef struct{ + + /*OAI config. parameters*/ + module_id_t mod_id; + int CC_id; + uint16_t rnti; + int get_MIB; //should be different from 0 only when the mib!= null (NB_rrc_mac_config_req_eNB_IoT) + int get_COMMON; + int get_DEDICATED; + + //ID of the Resource Block dedicated to NB-IoT + //For Nb-IoT only a restricted values of PRB indexes are allowed (see Rhode&Shwartz pag9) + //unsigned short NB_IoT_RB_ID; (should coincide with PRB index) + + + + + /*FAPI useful config. parameters used in the code + * + * -nfapi_uplink_reference_signal_config_t uplink_reference_signal_config + * -nfapi_subframe_config_t subframe_config; + * -nfapi_rf_config_t rf_config; + * -nfapi_sch_config_t sch_config; + * -nfapi_nb_iot_config_t config_NB_IoT; + * -nfapi_l23_config_t l23_config; + * -nfapi_config --> EARFCN (for the transport of the dl_CarrierFreq + * */ + + //XXX where allocate memory?? + nfapi_config_request_t* cfg; + + /*MP: MISSED COMMON CONFIG. of SIB2-NB in FAPI SPECS (may non needed)*/ + extra_phyConfig_t extra_phy_parms; + +}PHY_Config_NB_IoT_t; + + + +// uplink subframe P7--------------------------------------------------------------------------------- + + +/*UL_IND_t: +* A structure handles all the uplink information. +* Corresponding to the NRACH.indicaiton, UL_Config_indication, RX_ULSCH.indication, CRC.inidcation, NB_HARQ.indication in FAPI +*/ +typedef struct{ + + /*Start at the common part*/ + + int test; + + //Module ID + module_id_t module_id; + //CC ID + int CC_id; + //frame + frame_t frame; + //subframe + sub_frame_t subframe; + //Hyper frame for NB-IoT implementation + uint32_t hypersfn; + + /*preamble part*/ + + nfapi_nrach_indication_body_t NRACH; + + /*Uplink data part*/ + + /*indication of the harq feedback*/ + nfapi_nb_harq_indication_t nb_harq_ind; + /*indication of the uplink data PDU*/ + nfapi_rx_indication_body_t RX_NPUSCH; + /*crc_indication*/ + nfapi_crc_indication_body_t crc_ind; + + }UL_IND_NB_IoT_t; + + // Downlink subframe P7 + + +typedef struct{ + + /*Start at the common part*/ + + //Module ID + module_id_t module_id; + //CC ID + int CC_id; + // hyper subframe + uint32_t hypersfn; + //frame + frame_t frame; + //subframe + sub_frame_t subframe; + + /// nFAPI DL Config Request + nfapi_dl_config_request_t *DL_req; + /// nFAPI UL Config Request + nfapi_ul_config_request_t *UL_req; + /// nFAPI HI_DCI Request + nfapi_hi_dci0_request_t *HI_DCI0_req; + /// nFAPI TX Request + nfapi_tx_request_t *TX_req; + /// Pointers to DL SDUs + //uint8_t **sdu; + +}Sched_Rsp_NB_IoT_t; + + +/*IF_Module_t a group for gathering the Interface +It should be allocated at the main () in lte-softmodem.c*/ +typedef struct IF_Module_NB_IoT_s{ + //define the function pointer + void (*UL_indication)(UL_IND_NB_IoT_t *UL_INFO); + void (*schedule_response)(Sched_Rsp_NB_IoT_t *Sched_INFO); + void (*PHY_config_req)(PHY_Config_NB_IoT_t* config_INFO); +}IF_Module_NB_IoT_t; + +/*Initial */ + +/*Interface for Downlink, transmitting the DLSCH SDU, DCI SDU*/ +void schedule_response_NB_IoT(Sched_Rsp_NB_IoT_t *Sched_INFO); + +/*Interface for PHY Configuration + * Trigger the phy_config_xxx functions using parameters from the shared PHY_Config structure + * */ +void PHY_config_req_NB_IoT(PHY_Config_NB_IoT_t* config_INFO); + +//int IF_Module_init(IF_Module_t *if_inst); + +/*Interface for Downlink, transmitting the DLSCH SDU, DCI SDU*/ +//void Schedule_Response_NB_IoT(Sched_Rsp_NB_IoT_t *Sched_INFO); + +/*Interface for uplink, transmitting the Preamble(list), ULSCH SDU, NAK, Tick (trigger scheduler) +*/ +void UL_indication_NB_IoT(UL_IND_NB_IoT_t *UL_INFO); + +IF_Module_NB_IoT_t *IF_Module_init_NB_IoT(int Mod_id); + +#endif diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.c b/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.c new file mode 100644 index 0000000000..866b2c1e91 --- /dev/null +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.c @@ -0,0 +1,1417 @@ +/* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file asn1_msg.c +* \brief primitives to build the asn1 messages +* \author Raymond Knopp, Navid Nikaein and Michele Paffetti +* \date 2011, 2017 +* \version 1.0 +* \company Eurecom +* \email: raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, michele.paffetti@studio.unibo.it +*/ + +#include +#include +#include /* for atoi(3) */ +#include /* for getopt(3) */ +#include /* for strerror(3) */ +#include /* for EX_* exit codes */ +#include /* for errno */ +#include "UTIL/LOG/log.h" +#include +#include /* for _ASN_DEFAULT_STACK_MAX */ +#include +#include "asn1_msg.h" + + + +//#include for NB-IoT------------------- +#include "RRCConnectionRequest-NB.h" +#include "BCCH-DL-SCH-Message-NB.h" +#include "UL-CCCH-Message-NB.h" +#include "UL-DCCH-Message-NB.h" +#include "DL-CCCH-Message-NB.h" +#include "DL-DCCH-Message-NB.h" +#include "EstablishmentCause-NB-r13.h" +#include "RRCConnectionSetup-NB.h" +#include "SRB-ToAddModList-NB-r13.h" +#include "DRB-ToAddModList-NB-r13.h" +#include "RRC/LITE/defs_NB_IoT.h" +#include "RRCConnectionSetupComplete-NB.h" +#include "RRCConnectionReconfigurationComplete-NB.h" +#include "RRCConnectionReconfiguration-NB.h" +#include "MasterInformationBlock-NB.h" +#include "SystemInformation-NB.h" +#include "SystemInformationBlockType1.h" +#include "SIB-Type-NB-r13.h" +#include "RRCConnectionResume-NB.h" +#include "RRCConnectionReestablishment-NB.h" +#include "../defs_NB_IoT.h" +//---------------------------------------- + +//#include "PHY/defs.h" +#include "enb_config.h" + +#if defined(ENABLE_ITTI) +# include "intertask_interface.h" +#endif + + + + +/*do_MIB_NB_NB_IoT*/ +uint8_t do_MIB_NB_IoT( + rrc_eNB_carrier_data_NB_IoT_t *carrier, + uint16_t N_RB_DL,//may not needed--> for NB_IoT only 1 PRB is used + uint32_t frame, + uint32_t hyper_frame) +{ + asn_enc_rval_t enc_rval; + BCCH_BCH_Message_NB_t *mib_NB_IoT = &(carrier->mib_NB_IoT); + + /* + * systemFrameNumber-MSB: (TS 36.331 pag 576) + * define the 4 MSB of the SFN (10 bits). The last significant 6 bits will be acquired implicitly by decoding the NPBCH + * NOTE: 6 LSB will be used for counting the 64 radio frames in the TTI period (640 ms) that is exactly the MIB period + * + * hyperSFN-LSB: + * indicates the 2 least significant bits of the HSFN. The remaining 8 bits are present in SIB1-NB + * NOTE: with the 2 bits we count the 4 HSFN (is 1 SIB1-Nb modification period) while the other 6 count the number of modification periods + * + * + * NOTE: in OAI never modify the SIB messages!!?? + */ + + //XXX check if correct the bit assignment + uint8_t sfn_MSB = (uint8_t)((frame>>6) & 0x0f); // all the 4 bits are set to 1 + uint8_t hsfn_LSB = (uint8_t)(hyper_frame & 0x03); //2 bits set to 1 (0x3 = 0011) + uint16_t spare=0; //11 bits --> use uint16 + + mib_NB_IoT->message.systemFrameNumber_MSB_r13.buf = &sfn_MSB; + mib_NB_IoT->message.systemFrameNumber_MSB_r13.size = 1; //if expressed in byte + mib_NB_IoT->message.systemFrameNumber_MSB_r13.bits_unused = 4; //is byte based (so how many bits you don't use of the 8 bits of a bite + + mib_NB_IoT->message.hyperSFN_LSB_r13.buf= &hsfn_LSB; + mib_NB_IoT->message.hyperSFN_LSB_r13.size= 1; + mib_NB_IoT->message.hyperSFN_LSB_r13.bits_unused = 6; + + //XXX to be set?? + mib_NB_IoT->message.spare.buf = (uint8_t *)&spare; + mib_NB_IoT->message.spare.size = 2; + mib_NB_IoT->message.spare.bits_unused = 5; + + //decide how to set it + mib_NB_IoT->message.schedulingInfoSIB1_r13 =11; //see TS 36.213-->tables 16.4.1.3-3 ecc... + mib_NB_IoT->message.systemInfoValueTag_r13= 0; + mib_NB_IoT->message.ab_Enabled_r13 = 0; + + //to be decided + mib_NB_IoT->message.operationModeInfo_r13.present = MasterInformationBlock_NB__operationModeInfo_r13_PR_inband_SamePCI_r13; + mib_NB_IoT->message.operationModeInfo_r13.choice.inband_SamePCI_r13.eutra_CRS_SequenceInfo_r13 = 0; + + printf("[MIB] Initialization of frame information,sfn_MSB %x, hsfn_LSB %x\n", + (uint32_t)sfn_MSB, + (uint32_t)hsfn_LSB); + + enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_BCH_Message_NB, + (void*)mib_NB_IoT, + carrier->MIB_NB_IoT, + 100); + if(enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + + if (enc_rval.encoded==-1) { + return(-1); + } + + return((enc_rval.encoded+7)/8); + +} + +/*do_SIB1_NB*/ +uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, int CC_id, + rrc_eNB_carrier_data_NB_IoT_t *carrier, + NbIoTRrcConfigurationReq *configuration, + uint32_t frame + ) +{ + BCCH_DL_SCH_Message_NB_t *bcch_message= &(carrier->siblock1_NB_IoT); + SystemInformationBlockType1_NB_t **sib1_NB_IoT= &(carrier->sib1_NB_IoT); + + + asn_enc_rval_t enc_rval; + + PLMN_IdentityInfo_NB_r13_t PLMN_identity_info_NB_IoT; + MCC_MNC_Digit_t dummy_mcc[3],dummy_mnc[3]; + SchedulingInfo_NB_r13_t *schedulingInfo_NB_IoT; + SIB_Type_NB_r13_t *sib_type_NB_IoT; + + + long* attachWithoutPDN_Connectivity = NULL; + attachWithoutPDN_Connectivity = CALLOC(1,sizeof(long)); + long *nrs_CRS_PowerOffset=NULL; + nrs_CRS_PowerOffset = CALLOC(1, sizeof(long)); + long *eutraControlRegionSize=NULL; //this parameter should be set only if we are considering in-band operating mode (samePCI or differentPCI) + eutraControlRegionSize = CALLOC(1,sizeof(long)); + long systemInfoValueTagSI = 0; + + memset(bcch_message,0,sizeof(BCCH_DL_SCH_Message_NB_t)); + bcch_message->message.present = BCCH_DL_SCH_MessageType_NB_PR_c1; + bcch_message->message.choice.c1.present = BCCH_DL_SCH_MessageType_NB__c1_PR_systemInformationBlockType1_r13; + + //allocation + *sib1_NB_IoT = &bcch_message->message.choice.c1.choice.systemInformationBlockType1_r13; + + + /*TS 36.331 v14.2.0 pag 589 + * hyperSFN-MSB + * Indicates the 8 most significant bits of the hyper-SFN. Together with the hyper-LSB in MIB-NB the complete HSFN is build up + */ + //FIXME see if correct + uint8_t hyperSFN_MSB = (uint8_t) ((frame>>2)& 0xff); + + //XXX to be checked + (*sib1_NB_IoT)->hyperSFN_MSB_r13.buf = &hyperSFN_MSB; + (*sib1_NB_IoT)->hyperSFN_MSB_r13.size = 1; + (*sib1_NB_IoT)->hyperSFN_MSB_r13.bits_unused = 0; + + memset(&PLMN_identity_info_NB_IoT,0,sizeof(PLMN_IdentityInfo_NB_r13_t)); + + PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc = CALLOC(1,sizeof(*PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc)); + memset(PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc,0,sizeof(*PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc)); + + asn_set_empty(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list);//.size=0; + + //left as it is??? +#if defined(ENABLE_ITTI) + dummy_mcc[0] = (configuration->mcc / 100) % 10; + dummy_mcc[1] = (configuration->mcc / 10) % 10; + dummy_mcc[2] = (configuration->mcc / 1) % 10; +#else + dummy_mcc[0] = 0; + dummy_mcc[1] = 0; + dummy_mcc[2] = 1; +#endif + ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list,&dummy_mcc[0]); + ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list,&dummy_mcc[1]); + ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list,&dummy_mcc[2]); + + PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list.size=0; + PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list.count=0; + + +#if defined(ENABLE_ITTI) + + if (configuration->mnc >= 100) { + dummy_mnc[0] = (configuration->mnc / 100) % 10; + dummy_mnc[1] = (configuration->mnc / 10) % 10; + dummy_mnc[2] = (configuration->mnc / 1) % 10; + } else { + if (configuration->mnc_digit_length == 2) { + dummy_mnc[0] = (configuration->mnc / 10) % 10; + dummy_mnc[1] = (configuration->mnc / 1) % 10; + dummy_mnc[2] = 0xf; + } else { + dummy_mnc[0] = (configuration->mnc / 100) % 100; + dummy_mnc[1] = (configuration->mnc / 10) % 10; + dummy_mnc[2] = (configuration->mnc / 1) % 10; + } + } + +#else + dummy_mnc[0] = 0; + dummy_mnc[1] = 1; + dummy_mnc[2] = 0xf; +#endif + ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list,&dummy_mnc[0]); + ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list,&dummy_mnc[1]); + + if (dummy_mnc[2] != 0xf) { + ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list,&dummy_mnc[2]); + } + + //still set to "notReserved" as in the previous case + PLMN_identity_info_NB_IoT.cellReservedForOperatorUse_r13=PLMN_IdentityInfo_NB_r13__cellReservedForOperatorUse_r13_notReserved; + + *attachWithoutPDN_Connectivity = 0; + PLMN_identity_info_NB_IoT.attachWithoutPDN_Connectivity_r13 = attachWithoutPDN_Connectivity; + + ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.plmn_IdentityList_r13.list,&PLMN_identity_info_NB_IoT); + + // 16 bits = 2 byte + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf = MALLOC(2); //MALLOC works in byte + + //lefts as it is? +#if defined(ENABLE_ITTI) + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[0] = (configuration->tac >> 8) & 0xff; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[1] = (configuration->tac >> 0) & 0xff; +#else + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[0] = 0x00; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[1] = 0x01; +#endif + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.size=2; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.bits_unused=0; + + // 28 bits --> i have to use 32 bits = 4 byte + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf = MALLOC(8); // why allocate 8 byte? +#if defined(ENABLE_ITTI) + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[0] = (configuration->cell_identity >> 20) & 0xff; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[1] = (configuration->cell_identity >> 12) & 0xff; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[2] = (configuration->cell_identity >> 4) & 0xff; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[3] = (configuration->cell_identity << 4) & 0xf0; +#else + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[0] = 0x00; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[1] = 0x00; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[2] = 0x00; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[3] = 0x10; +#endif + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.size=4; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.bits_unused=4; + + //Still set to "notBarred" as in the previous case + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellBarred_r13=SystemInformationBlockType1_NB__cellAccessRelatedInfo_r13__cellBarred_r13_notBarred; + + //Still Set to "notAllowed" like in the previous case + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.intraFreqReselection_r13=SystemInformationBlockType1_NB__cellAccessRelatedInfo_r13__intraFreqReselection_r13_notAllowed; + + + (*sib1_NB_IoT)->cellSelectionInfo_r13.q_RxLevMin_r13=-65; //which value?? TS 36.331 V14.2.1 pag. 589 + (*sib1_NB_IoT)->cellSelectionInfo_r13.q_QualMin_r13 = 0; //FIXME new parameter for SIB1-NB, not present in SIB1 (for cell reselection but if not used the UE should apply the default value) + + (*sib1_NB_IoT)->p_Max_r13 = CALLOC(1, sizeof(P_Max_t)); + *((*sib1_NB_IoT)->p_Max_r13) = 23; + + //FIXME + (*sib1_NB_IoT)->freqBandIndicator_r13 = +#if defined(ENABLE_ITTI) + configuration->eutra_band; +#else + 5; //if not configured we use band 5 (UL: 824 MHz - 849MHz / DL: 869 MHz - 894 MHz FDD mode) +#endif + + //OPTIONAL new parameters, to be used? + /* + * freqBandInfo_r13 + * multiBandInfoList_r13 + * nrs_CRS_PowerOffset_r13 + * sib1_NB_IoT->downlinkBitmap_r13.choice.subframePattern10_r13 =(is a BIT_STRING) + */ + + + (*sib1_NB_IoT)->downlinkBitmap_r13 = CALLOC(1, sizeof(struct DL_Bitmap_NB_r13)); + ((*sib1_NB_IoT)->downlinkBitmap_r13)->present= DL_Bitmap_NB_r13_PR_NOTHING; + + *eutraControlRegionSize = 1; + (*sib1_NB_IoT)->eutraControlRegionSize_r13 = eutraControlRegionSize; + + + *nrs_CRS_PowerOffset= 0; + (*sib1_NB_IoT)->nrs_CRS_PowerOffset_r13 = nrs_CRS_PowerOffset; + + schedulingInfo_NB_IoT = (SchedulingInfo_NB_r13_t*) malloc (3*sizeof(SchedulingInfo_NB_r13_t)); + sib_type_NB_IoT = (SIB_Type_NB_r13_t *) malloc (3*sizeof(SIB_Type_NB_r13_t)); + + memset(&schedulingInfo_NB_IoT[0],0,sizeof(SchedulingInfo_NB_r13_t)); + memset(&schedulingInfo_NB_IoT[1],0,sizeof(SchedulingInfo_NB_r13_t)); + memset(&schedulingInfo_NB_IoT[2],0,sizeof(SchedulingInfo_NB_r13_t)); + memset(&sib_type_NB_IoT[0],0,sizeof(SIB_Type_NB_r13_t)); + memset(&sib_type_NB_IoT[1],0,sizeof(SIB_Type_NB_r13_t)); + memset(&sib_type_NB_IoT[2],0,sizeof(SIB_Type_NB_r13_t)); + + + // Now, follow the scheduler SIB configuration + // There is only one sib2+sib3 common setting + schedulingInfo_NB_IoT[0].si_Periodicity_r13=SchedulingInfo_NB_r13__si_Periodicity_r13_rf4096; + schedulingInfo_NB_IoT[0].si_RepetitionPattern_r13=SchedulingInfo_NB_r13__si_RepetitionPattern_r13_every2ndRF; //This Indicates the starting radio frames within the SI window used for SI message transmission. + schedulingInfo_NB_IoT[0].si_TB_r13= SchedulingInfo_NB_r13__si_TB_r13_b680;//208 bits + + + // This is for SIB2/3 + /*SIB3 --> There is no mapping information of SIB2 since it is always present + * in the first SystemInformation message + * listed in the schedulingInfoList list. + * */ + sib_type_NB_IoT[0]=SIB_Type_NB_r13_sibType3_NB_r13; + + ASN_SEQUENCE_ADD(&schedulingInfo_NB_IoT[0].sib_MappingInfo_r13.list,&sib_type_NB_IoT[0]); + ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->schedulingInfoList_r13.list,&schedulingInfo_NB_IoT[0]); + + //printf("[ASN Debug] SI P: %ld\n",(*sib1_NB_IoT)->schedulingInfoList_r13.list.array[0]->si_Periodicity_r13); + +#if defined(ENABLE_ITTI) + + if (configuration->frame_type == TDD) +#endif + { + //FIXME in NB-IoT mandatory to be FDD --> so must give an error + LOG_E(RRC,"[NB-IoT %d] Frame Type is TDD --> not supported by NB-IoT, exiting\n", Mod_id); //correct? + exit(-1); + } + + //FIXME which value chose for the following parameter + (*sib1_NB_IoT)->si_WindowLength_r13=SystemInformationBlockType1_NB__si_WindowLength_r13_ms160; + (*sib1_NB_IoT)->si_RadioFrameOffset_r13= 0; + + /*In Nb-IoT change/update of specific SI message can additionally be indicated by a SI message specific value tag + * systemInfoValueTagSI (there is no SystemInfoValueTag in SIB1-NB but only in MIB-NB) + *contained in systemInfoValueTagList_r13 + **/ + //FIXME correct? + (*sib1_NB_IoT)->systemInfoValueTagList_r13 = CALLOC(1, sizeof(struct SystemInfoValueTagList_NB_r13)); + asn_set_empty(&(*sib1_NB_IoT)->systemInfoValueTagList_r13->list); + ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->systemInfoValueTagList_r13->list,&systemInfoValueTagSI); + + +#ifdef XER_PRINT //generate xml files + xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message_NB, (void*)bcch_message); +#endif + + + enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_DL_SCH_Message_NB, + (void*)bcch_message, + carrier->SIB1_NB_IoT, + 100); + + if (enc_rval.encoded > 0){ + LOG_F(RRC,"ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + + +#ifdef USER_MODE + LOG_D(RRC,"[NB-IoT] SystemInformationBlockType1-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); +#endif + + if (enc_rval.encoded==-1) { + return(-1); + } + + return((enc_rval.encoded+7)/8); +} + +/*SIB23_NB_IoT*/ +//to be clarified is it is possible to carry SIB2 and SIB3 in the same SI message for NB-IoT? +uint8_t do_SIB23_NB_IoT(uint8_t Mod_id, + int CC_id, + rrc_eNB_carrier_data_NB_IoT_t *carrier,//MP: this is already a carrier[CC_id] + NbIoTRrcConfigurationReq *configuration ) //openair2/COMMON/rrc_messages_types.h +{ + struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member *sib2_NB_part; + struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member *sib3_NB_part; + + BCCH_DL_SCH_Message_NB_t *bcch_message = &(carrier->systemInformation_NB_IoT); //is the systeminformation-->BCCH_DL_SCH_Message_NB + SystemInformationBlockType2_NB_r13_t *sib2_NB_IoT; + SystemInformationBlockType3_NB_r13_t *sib3_NB_IoT; + + asn_enc_rval_t enc_rval; + RACH_Info_NB_r13_t rach_Info_NB_IoT; + NPRACH_Parameters_NB_r13_t *nprach_parameters; + + //optional + long *connEstFailOffset = NULL; + connEstFailOffset = CALLOC(1, sizeof(long)); + +// RSRP_ThresholdsNPRACH_InfoList_NB_r13_t *rsrp_ThresholdsPrachInfoList; +// RSRP_Range_t rsrp_range; + + ACK_NACK_NumRepetitions_NB_r13_t ack_nack_repetition; + struct NPUSCH_ConfigCommon_NB_r13__dmrs_Config_r13 *dmrs_config; + struct DL_GapConfig_NB_r13 *dl_Gap; + + long *srs_SubframeConfig; + srs_SubframeConfig= CALLOC(1, sizeof(long)); + + + if (bcch_message) { + memset(bcch_message,0,sizeof(BCCH_DL_SCH_Message_NB_t)); + } else { + LOG_E(RRC,"[NB-IoT %d] BCCH_MESSAGE_NB is null, exiting\n", Mod_id); + exit(-1); + } + + //before schould be allocated memory somewhere? +// if (!carrier->sib2_NB_IoT) { +// LOG_E(RRC,"[NB-IoT %d] sib2_NB_IoT is null, exiting\n", Mod_id); +// exit(-1); +// } +// +// if (!carrier->sib3_NB_IoT) { +// LOG_E(RRC,"[NB-IoT %d] sib3_NB_IoT is null, exiting\n", Mod_id); +// exit(-1); +// } + + + LOG_I(RRC,"[NB-IoT %d] Configuration SIB2/3\n", Mod_id); + + sib2_NB_part = CALLOC(1,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); + sib3_NB_part = CALLOC(1,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); + memset(sib2_NB_part,0,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); + memset(sib3_NB_part,0,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); + + sib2_NB_part->present = SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR_sib2_r13; + sib3_NB_part->present = SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR_sib3_r13; + + //may bug if not correct allocation of memory + carrier->sib2_NB_IoT = &sib2_NB_part->choice.sib2_r13; + carrier->sib3_NB_IoT = &sib3_NB_part->choice.sib3_r13; + sib2_NB_IoT = carrier->sib2_NB_IoT; + sib3_NB_IoT = carrier->sib3_NB_IoT; + + nprach_parameters = (NPRACH_Parameters_NB_r13_t *) malloc (3*sizeof(NPRACH_Parameters_NB_r13_t)); + + memset(&nprach_parameters[0],0,sizeof(NPRACH_Parameters_NB_r13_t)); + memset(&nprach_parameters[1],0,sizeof(NPRACH_Parameters_NB_r13_t)); + memset(&nprach_parameters[2],0,sizeof(NPRACH_Parameters_NB_r13_t)); + +/// SIB2-NB----------------------------------------- + + //Barring is manage by ab-Enabled in MIB-NB (but is not a struct as ac-BarringInfo in LTE legacy) + + //RACH Config. Common-------------------------------------------------------------- + sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.preambleTransMax_CE_r13 = + configuration->rach_preambleTransMax_CE_NB; + sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.powerRampingParameters_r13.powerRampingStep = + configuration->rach_powerRampingStep_NB; + sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.powerRampingParameters_r13.preambleInitialReceivedTargetPower = + configuration->rach_preambleInitialReceivedTargetPower_NB; + + rach_Info_NB_IoT.ra_ResponseWindowSize_r13 = configuration->rach_raResponseWindowSize_NB; + rach_Info_NB_IoT.mac_ContentionResolutionTimer_r13 = configuration-> rach_macContentionResolutionTimer_NB; + //rach_infoList max size = maxNPRACH-Resources-NB-r13 = 3 + ASN_SEQUENCE_ADD(&sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.rach_InfoList_r13.list,&rach_Info_NB_IoT); + + //TS 36.331 pag 614 --> if not present the value to infinity sould be used + *connEstFailOffset = 0; + + sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.connEstFailOffset_r13 = connEstFailOffset; /*OPTIONAL*/ + + + // BCCH-Config-NB-IoT---------------------------------------------------------------- + sib2_NB_IoT->radioResourceConfigCommon_r13.bcch_Config_r13.modificationPeriodCoeff_r13 + = configuration->bcch_modificationPeriodCoeff_NB; + + // PCCH-Config-NB-IoT----------------------------------------------------------------- + sib2_NB_IoT->radioResourceConfigCommon_r13.pcch_Config_r13.defaultPagingCycle_r13 + = configuration->pcch_defaultPagingCycle_NB; + sib2_NB_IoT->radioResourceConfigCommon_r13.pcch_Config_r13.nB_r13 = configuration->pcch_nB_NB; + sib2_NB_IoT->radioResourceConfigCommon_r13.pcch_Config_r13.npdcch_NumRepetitionPaging_r13 = configuration-> pcch_npdcch_NumRepetitionPaging_NB; + + //NPRACH-Config-NB-IoT----------------------------------------------------------------- + + sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.rsrp_ThresholdsPrachInfoList_r13 = NULL; + sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.nprach_CP_Length_r13 = configuration->nprach_CP_Length; + /*OPTIONAL*/ +// =CALLOC(1, sizeof(struct RSRP_ThresholdsNPRACH_InfoList_NB_r13)); //fatto uguale dopo +// rsrp_ThresholdsPrachInfoList = sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.rsrp_ThresholdsPrachInfoList_r13; +// rsrp_range = configuration->nprach_rsrp_range_NB; +// ASN_SEQUENCE_ADD(&rsrp_ThresholdsPrachInfoList->list,rsrp_range); + + // According configuration to set the 3 CE level configuration setting + + nprach_parameters[0].nprach_Periodicity_r13 = configuration->nprach_Periodicity[0]; + nprach_parameters[0].nprach_StartTime_r13 = configuration->nprach_StartTime[0]; + nprach_parameters[0].nprach_SubcarrierOffset_r13 = configuration->nprach_SubcarrierOffset[0]; + nprach_parameters[0].nprach_NumSubcarriers_r13 = configuration->nprach_NumSubcarriers[0]; + nprach_parameters[0].numRepetitionsPerPreambleAttempt_r13 = configuration->numRepetitionsPerPreambleAttempt_NB[0]; + nprach_parameters[0].nprach_SubcarrierMSG3_RangeStart_r13 = configuration->nprach_SubcarrierMSG3_RangeStart; + nprach_parameters[0].maxNumPreambleAttemptCE_r13 = configuration->maxNumPreambleAttemptCE_NB; + nprach_parameters[0].npdcch_NumRepetitions_RA_r13 = configuration->npdcch_NumRepetitions_RA[0]; + nprach_parameters[0].npdcch_StartSF_CSS_RA_r13 = configuration->npdcch_StartSF_CSS_RA[0]; + nprach_parameters[0].npdcch_Offset_RA_r13 = configuration->npdcch_Offset_RA[0]; + + nprach_parameters[1].nprach_Periodicity_r13 = configuration->nprach_Periodicity[1]; + nprach_parameters[1].nprach_StartTime_r13 = configuration->nprach_StartTime[1]; + nprach_parameters[1].nprach_SubcarrierOffset_r13 = configuration->nprach_SubcarrierOffset[1]; + nprach_parameters[1].nprach_NumSubcarriers_r13 = configuration->nprach_NumSubcarriers[1]; + nprach_parameters[1].numRepetitionsPerPreambleAttempt_r13 = configuration->numRepetitionsPerPreambleAttempt_NB[1]; + nprach_parameters[1].nprach_SubcarrierMSG3_RangeStart_r13 = configuration->nprach_SubcarrierMSG3_RangeStart; + nprach_parameters[1].maxNumPreambleAttemptCE_r13 = configuration->maxNumPreambleAttemptCE_NB; + nprach_parameters[1].npdcch_NumRepetitions_RA_r13 = configuration->npdcch_NumRepetitions_RA[1]; + nprach_parameters[1].npdcch_StartSF_CSS_RA_r13 = configuration->npdcch_StartSF_CSS_RA[1]; + nprach_parameters[1].npdcch_Offset_RA_r13 = configuration->npdcch_Offset_RA[1]; + + nprach_parameters[2].nprach_Periodicity_r13 = configuration->nprach_Periodicity[2]; + nprach_parameters[2].nprach_StartTime_r13 = configuration->nprach_StartTime[2]; + nprach_parameters[2].nprach_SubcarrierOffset_r13 = configuration->nprach_SubcarrierOffset[2]; + nprach_parameters[2].nprach_NumSubcarriers_r13 = configuration->nprach_NumSubcarriers[2]; + nprach_parameters[2].numRepetitionsPerPreambleAttempt_r13 = configuration->numRepetitionsPerPreambleAttempt_NB[2]; + nprach_parameters[2].nprach_SubcarrierMSG3_RangeStart_r13 = configuration->nprach_SubcarrierMSG3_RangeStart; + nprach_parameters[2].maxNumPreambleAttemptCE_r13 = configuration->maxNumPreambleAttemptCE_NB; + nprach_parameters[2].npdcch_NumRepetitions_RA_r13 = configuration->npdcch_NumRepetitions_RA[2]; + nprach_parameters[2].npdcch_StartSF_CSS_RA_r13 = configuration->npdcch_StartSF_CSS_RA[2]; + nprach_parameters[2].npdcch_Offset_RA_r13 = configuration->npdcch_Offset_RA[2]; + + + //nprach_parameterList have a max size of 3 possible nprach configuration (see maxNPRACH_Resources_NB_r13) + ASN_SEQUENCE_ADD(&sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.nprach_ParametersList_r13.list,&nprach_parameters[0]); + ASN_SEQUENCE_ADD(&sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.nprach_ParametersList_r13.list,&nprach_parameters[1]); + ASN_SEQUENCE_ADD(&sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.nprach_ParametersList_r13.list,&nprach_parameters[2]); + + // NPDSCH-Config NB-IOT + sib2_NB_IoT->radioResourceConfigCommon_r13.npdsch_ConfigCommon_r13.nrs_Power_r13= configuration->npdsch_nrs_Power; + + + //NPUSCH-Config NB-IoT---------------------------------------------------------------- + //list of size 3 (see maxNPRACH_Resources_NB_r13) + ack_nack_repetition = configuration-> npusch_ack_nack_numRepetitions_NB; //is an enumerative + ASN_SEQUENCE_ADD(&(sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.ack_NACK_NumRepetitions_Msg4_r13.list) ,&ack_nack_repetition); + + *srs_SubframeConfig = configuration->npusch_srs_SubframeConfig_NB; + sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.srs_SubframeConfig_r13= srs_SubframeConfig; /*OPTIONAL*/ + + + /*OPTIONAL*/ + dmrs_config = CALLOC(1,sizeof(struct NPUSCH_ConfigCommon_NB_r13__dmrs_Config_r13)); + dmrs_config->threeTone_CyclicShift_r13 = configuration->npusch_threeTone_CyclicShift_r13; + dmrs_config->sixTone_CyclicShift_r13 = configuration->npusch_sixTone_CyclicShift_r13; + + /*OPTIONAL + * -define the base sequence for a DMRS sequence in a cell with multi tone transmission (3,6,12) see TS 36.331 NPUSCH-Config-NB + * -if not defined will be calculated based on the cellID once we configure the phy layer (rrc_mac_config_req) through the config_sib2 */ + dmrs_config->threeTone_BaseSequence_r13 = NULL; + dmrs_config->sixTone_BaseSequence_r13 = NULL; + dmrs_config->twelveTone_BaseSequence_r13 = NULL; + + sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.dmrs_Config_r13 = dmrs_config; + + //ulReferenceSignalsNPUSCH + /*Reference Signal (RS) for UL in NB-IoT is called DRS (Demodulation Reference Signal) + * sequence-group hopping can be enabled or disabled by means of the cell-specific parameter groupHoppingEnabled_r13 + * sequence-group hopping can be disabled for certain specific UE through the parameter groupHoppingDisabled (physicalConfigDedicated) + * groupAssignmentNPUSCH--> is used for generate the sequence-shift pattern + */ + sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.ul_ReferenceSignalsNPUSCH_r13.groupHoppingEnabled_r13= configuration->npusch_groupHoppingEnabled; + sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.ul_ReferenceSignalsNPUSCH_r13.groupAssignmentNPUSCH_r13 =configuration->npusch_groupAssignmentNPUSCH_r13; + + + //dl_GAP---------------------------------------------------------------------------------/*OPTIONAL*/ + dl_Gap = CALLOC(1,sizeof(struct DL_GapConfig_NB_r13)); + dl_Gap->dl_GapDurationCoeff_r13= configuration-> dl_GapDurationCoeff_NB; + dl_Gap->dl_GapPeriodicity_r13= configuration->dl_GapPeriodicity_NB; + dl_Gap->dl_GapThreshold_r13= configuration->dl_GapThreshold_NB; + sib2_NB_IoT->radioResourceConfigCommon_r13.dl_Gap_r13 = dl_Gap; + + + // uplinkPowerControlCommon - NB-IoT------------------------------------------------------ + sib2_NB_IoT->radioResourceConfigCommon_r13.uplinkPowerControlCommon_r13.p0_NominalNPUSCH_r13 = configuration->npusch_p0_NominalNPUSCH; + sib2_NB_IoT->radioResourceConfigCommon_r13.uplinkPowerControlCommon_r13.deltaPreambleMsg3_r13 = configuration->deltaPreambleMsg3; + sib2_NB_IoT->radioResourceConfigCommon_r13.uplinkPowerControlCommon_r13.alpha_r13 = configuration->npusch_alpha; + //no deltaFlist_PUCCH and no UL cyclic prefix + + // UE Timers and Constants -NB-IoT-------------------------------------------------------- + sib2_NB_IoT->ue_TimersAndConstants_r13.t300_r13 = configuration-> ue_TimersAndConstants_t300_NB; + sib2_NB_IoT->ue_TimersAndConstants_r13.t301_r13 = configuration-> ue_TimersAndConstants_t301_NB; + sib2_NB_IoT->ue_TimersAndConstants_r13.t310_r13 = configuration-> ue_TimersAndConstants_t310_NB; + sib2_NB_IoT->ue_TimersAndConstants_r13.t311_r13 = configuration-> ue_TimersAndConstants_t311_NB; + sib2_NB_IoT->ue_TimersAndConstants_r13.n310_r13 = configuration-> ue_TimersAndConstants_n310_NB; + sib2_NB_IoT->ue_TimersAndConstants_r13.n311_r13 = configuration-> ue_TimersAndConstants_n311_NB; + + //other SIB2-NB Parameters-------------------------------------------------------------------------------- + sib2_NB_IoT->freqInfo_r13.additionalSpectrumEmission_r13 = 1; + sib2_NB_IoT->freqInfo_r13.ul_CarrierFreq_r13 = NULL; /*OPTIONAL*/ + + sib2_NB_IoT->timeAlignmentTimerCommon_r13=TimeAlignmentTimer_infinity;//TimeAlignmentTimer_sf5120; + + /*OPTIONAL*/ + sib2_NB_IoT->multiBandInfoList_r13 = NULL; + +/// SIB3-NB------------------------------------------------------- + + sib3_NB_IoT->cellReselectionInfoCommon_r13.q_Hyst_r13=SystemInformationBlockType3_NB_r13__cellReselectionInfoCommon_r13__q_Hyst_r13_dB4; + sib3_NB_IoT->cellReselectionServingFreqInfo_r13.s_NonIntraSearch_r13=0; //or define in configuration? + + sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_RxLevMin_r13 = -70; + //new + sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_QualMin_r13 = CALLOC(1,sizeof(*sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_QualMin_r13)); + *(sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_QualMin_r13)= 10; //a caso + + sib3_NB_IoT->intraFreqCellReselectionInfo_r13.p_Max_r13 = NULL; + sib3_NB_IoT->intraFreqCellReselectionInfo_r13.s_IntraSearchP_r13 = 31; // s_intraSearch --> s_intraSearchP!!! (they call in a different way) + sib3_NB_IoT->intraFreqCellReselectionInfo_r13.t_Reselection_r13=1; + + //how to manage? + sib3_NB_IoT->freqBandInfo_r13 = NULL; + sib3_NB_IoT->multiBandInfoList_r13 = NULL; + + +///BCCH message (generate the SI message) + bcch_message->message.present = BCCH_DL_SCH_MessageType_NB_PR_c1; + bcch_message->message.choice.c1.present = BCCH_DL_SCH_MessageType_NB__c1_PR_systemInformation_r13; + + bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.present = SystemInformation_NB__criticalExtensions_PR_systemInformation_r13; + bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.choice.systemInformation_r13.sib_TypeAndInfo_r13.list.count=0; + + ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.choice.systemInformation_r13.sib_TypeAndInfo_r13.list, + sib2_NB_part); + ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.choice.systemInformation_r13.sib_TypeAndInfo_r13.list, + sib3_NB_part); + +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message_NB, (void*)bcch_message); +#endif + enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_DL_SCH_Message_NB, + (void*)bcch_message, + carrier->SIB23_NB_IoT, + 900); +// AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", +// enc_rval.failed_type->name, enc_rval.encoded); + +//#if defined(ENABLE_ITTI)..... + + +#ifdef USER_MODE + LOG_D(RRC,"[NB-IoT] SystemInformation-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); +#endif + + if (enc_rval.encoded==-1) { + msg("[RRC] ASN1 : SI-NB encoding failed for SIB23_NB_IoT\n"); + return(-1); + } + + carrier->sib2_NB_IoT = sib2_NB_IoT; + carrier->sib3_NB_IoT = sib3_NB_IoT; + + return((enc_rval.encoded+7)/8); +} + +/*do_RRCConnectionSetup_NB_IoT--> the aim is to establish SRB1 and SRB1bis(implicitly)*/ +uint8_t do_RRCConnectionSetup_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, + int CC_id, + uint8_t* const buffer, //Srb0.Tx_buffer.Payload + const uint8_t Transaction_id, + const NB_IoT_DL_FRAME_PARMS* const frame_parms, // maybe not used + SRB_ToAddModList_NB_r13_t** SRB_configList_NB_IoT, //for both SRB1bis and SRB1 + struct PhysicalConfigDedicated_NB_r13** physicalConfigDedicated_NB_IoT +) + +{ + + asn_enc_rval_t enc_rval; + + + //MP:logical channel group not defined for Nb-IoT + + //MP: logical channel priority pag 605 (is 1 for SRB1 and for SRB1bis should be the same) + //long* prioritySRB1 = NULL; + long* prioritySRB1bis = NULL; + BOOLEAN_t* logicalChannelSR_Prohibit =NULL; //pag 605 + BOOLEAN_t* npusch_AllSymbols= NULL; + +// struct SRB_ToAddMod_NB_r13* SRB1_config_NB = NULL; +// struct SRB_ToAddMod_NB_r13__rlc_Config_r13* SRB1_rlc_config_NB = NULL; +// struct SRB_ToAddMod_NB_r13__logicalChannelConfig_r13* SRB1_lchan_config_NB = NULL; + + struct SRB_ToAddMod_NB_r13* SRB1bis_config_NB_IoT = NULL; + struct SRB_ToAddMod_NB_r13__rlc_Config_r13* SRB1bis_rlc_config_NB_IoT = NULL; + struct SRB_ToAddMod_NB_r13__logicalChannelConfig_r13* SRB1bis_lchan_config_NB_IoT = NULL; + + //No UL_specific parameters for NB-IoT in LogicalChanelConfig-NB + + PhysicalConfigDedicated_NB_r13_t* physicalConfigDedicated2_NB_IoT = NULL; + DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; + RRCConnectionSetup_NB_t* rrcConnectionSetup_NB_IoT = NULL; + + memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(DL_CCCH_Message_NB_t)); + dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1; + dl_ccch_msg_NB_IoT.message.choice.c1.present = DL_CCCH_MessageType_NB__c1_PR_rrcConnectionSetup_r13; + rrcConnectionSetup_NB_IoT = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionSetup_r13; + + + if (*SRB_configList_NB_IoT) { + free(*SRB_configList_NB_IoT); + } + *SRB_configList_NB_IoT = CALLOC(1,sizeof(SRB_ToAddModList_NB_r13_t)); + +/// SRB1-------------------- + { +// SRB1_config_NB = CALLOC(1,sizeof(*SRB1_config_NB)); +// +// //no srb_Identity in SRB_ToAddMod_NB +// +// SRB1_rlc_config_NB = CALLOC(1,sizeof(*SRB1_rlc_config_NB)); +// SRB1_config_NB->rlc_Config_r13 = SRB1_rlc_config_NB; +// +// SRB1_rlc_config_NB->present = SRB_ToAddMod_NB_r13__rlc_Config_r13_PR_explicitValue; +// SRB1_rlc_config_NB->choice.explicitValue.present=RLC_Config_NB_r13_PR_am;//the only possible in NB_IoT +// +//// SRB1_rlc_config_NB->choice.explicitValue.choice.am.ul_AM_RLC_r13.t_PollRetransmit_r13 = enb_properties.properties[ctxt_pP->module_id]->srb1_timer_poll_retransmit_r13; +//// SRB1_rlc_config_NB->choice.explicitValue.choice.am.ul_AM_RLC_r13.maxRetxThreshold_r13 = enb_properties.properties[ctxt_pP->module_id]->srb1_max_retx_threshold_r13; +//// //(musT be disabled--> SRB1 config pag 640 specs ) +//// SRB1_rlc_config_NB->choice.explicitValue.choice.am.dl_AM_RLC_r13.enableStatusReportSN_Gap_r13 =NULL; +// +// +// SRB1_rlc_config_NB->choice.explicitValue.choice.am.ul_AM_RLC_r13.t_PollRetransmit_r13 = T_PollRetransmit_NB_r13_ms25000; +// SRB1_rlc_config_NB->choice.explicitValue.choice.am.ul_AM_RLC_r13.maxRetxThreshold_r13 = UL_AM_RLC_NB_r13__maxRetxThreshold_r13_t8; +// //(musT be disabled--> SRB1 config pag 640 specs ) +// SRB1_rlc_config_NB->choice.explicitValue.choice.am.dl_AM_RLC_r13.enableStatusReportSN_Gap_r13 = NULL; +// +// SRB1_lchan_config_NB = CALLOC(1,sizeof(*SRB1_lchan_config_NB)); +// SRB1_config_NB->logicalChannelConfig_r13 = SRB1_lchan_config_NB; +// +// SRB1_lchan_config_NB->present = SRB_ToAddMod_NB_r13__logicalChannelConfig_r13_PR_explicitValue; +// +// +// prioritySRB1 = CALLOC(1, sizeof(long)); +// *prioritySRB1 = 1; +// SRB1_lchan_config_NB->choice.explicitValue.priority_r13 = prioritySRB1; +// +// logicalChannelSR_Prohibit = CALLOC(1, sizeof(BOOLEAN_t)); +// *logicalChannelSR_Prohibit = 1; +// //schould be set to TRUE (specs pag 641) +// SRB1_lchan_config_NB->choice.explicitValue.logicalChannelSR_Prohibit_r13 = logicalChannelSR_Prohibit; +// +// //ADD SRB1 +// ASN_SEQUENCE_ADD(&(*SRB_configList_NB_IoT)->list,SRB1_config_NB); + } + +///SRB1bis (The configuration for SRB1 and SRB1bis is the same) the only difference is the logical channel identity = 3 but not set here + + SRB1bis_config_NB_IoT = CALLOC(1,sizeof(*SRB1bis_config_NB_IoT)); + + //no srb_Identity in SRB_ToAddMod_NB + SRB1bis_rlc_config_NB_IoT = CALLOC(1,sizeof(*SRB1bis_rlc_config_NB_IoT)); + SRB1bis_config_NB_IoT->rlc_Config_r13 = SRB1bis_rlc_config_NB_IoT; + + SRB1bis_rlc_config_NB_IoT->present = SRB_ToAddMod_NB_r13__rlc_Config_r13_PR_explicitValue; + SRB1bis_rlc_config_NB_IoT->choice.explicitValue.present=RLC_Config_NB_r13_PR_am;//MP: the only possible RLC config in NB_IoT + + SRB1bis_rlc_config_NB_IoT->choice.explicitValue.choice.am.ul_AM_RLC_r13.t_PollRetransmit_r13 = T_PollRetransmit_NB_r13_ms25000; + SRB1bis_rlc_config_NB_IoT->choice.explicitValue.choice.am.ul_AM_RLC_r13.maxRetxThreshold_r13 = UL_AM_RLC_NB_r13__maxRetxThreshold_r13_t8; + //(musT be disabled--> SRB1 config pag 640 specs ) + SRB1bis_rlc_config_NB_IoT->choice.explicitValue.choice.am.dl_AM_RLC_r13.enableStatusReportSN_Gap_r13 =NULL; + + SRB1bis_lchan_config_NB_IoT = CALLOC(1,sizeof(*SRB1bis_lchan_config_NB_IoT)); + SRB1bis_config_NB_IoT->logicalChannelConfig_r13 = SRB1bis_lchan_config_NB_IoT; + + SRB1bis_lchan_config_NB_IoT->present = SRB_ToAddMod_NB_r13__logicalChannelConfig_r13_PR_explicitValue; + + prioritySRB1bis = CALLOC(1, sizeof(long)); + *prioritySRB1bis = 1; //same as SRB1? + SRB1bis_lchan_config_NB_IoT->choice.explicitValue.priority_r13 = prioritySRB1bis; + + logicalChannelSR_Prohibit = CALLOC(1, sizeof(BOOLEAN_t)); + *logicalChannelSR_Prohibit = 1; //schould be set to TRUE (specs pag 641) + SRB1bis_lchan_config_NB_IoT->choice.explicitValue.logicalChannelSR_Prohibit_r13 = logicalChannelSR_Prohibit; + + //ADD SRB1bis + //MP: Actually there is no way to distinguish SRB1 and SRB1bis once put in the list + //MP: SRB_ToAddModList_NB_r13_t size = 1 + ASN_SEQUENCE_ADD(&(*SRB_configList_NB_IoT)->list,SRB1bis_config_NB_IoT); + + + // PhysicalConfigDedicated (NPDCCH, NPUSCH, CarrierConfig, UplinkPowerControl) + + physicalConfigDedicated2_NB_IoT = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT)); + *physicalConfigDedicated_NB_IoT = physicalConfigDedicated2_NB_IoT; + + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13= CALLOC(1, sizeof(*physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13)); + physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13 = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13)); + physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13 = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13)); + physicalConfigDedicated2_NB_IoT->uplinkPowerControlDedicated_r13 = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT->uplinkPowerControlDedicated_r13)); + + //no tpc, no cqi and no pucch, no pdsch, no soundingRS, no AntennaInfo, no scheduling request config + + /* + * NB-IoT supports the operation with either one or two antenna ports, AP0 and AP1. + * For the latter case, Space Frequency Block Coding (SFBC) is applied. + * Once selected, the same transmission scheme applies to NPBCH, NPDCCH, and NPDSCH. + * */ + + //FIXME: MP: CarrierConfigDedicated check the set values ---------------------------------------------- + + //DL + + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.dl_CarrierFreq_r13.carrierFreq_r13=0;//random value set + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.downlinkBitmapNonAnchor_r13= CALLOC(1,sizeof(struct DL_CarrierConfigDedicated_NB_r13__downlinkBitmapNonAnchor_r13)); + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.downlinkBitmapNonAnchor_r13->present= + DL_CarrierConfigDedicated_NB_r13__downlinkBitmapNonAnchor_r13_PR_useNoBitmap_r13; + + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.dl_GapNonAnchor_r13 = CALLOC(1,sizeof(struct DL_CarrierConfigDedicated_NB_r13__dl_GapNonAnchor_r13)); + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.dl_GapNonAnchor_r13->present = + DL_CarrierConfigDedicated_NB_r13__dl_GapNonAnchor_r13_PR_useNoGap_r13; + + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.inbandCarrierInfo_r13= NULL; + + //UL + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->ul_CarrierConfig_r13.ul_CarrierFreq_r13= NULL; + + // NPDCCH + physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13->npdcch_NumRepetitions_r13 =0; + physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13->npdcch_Offset_USS_r13 =0; + physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13->npdcch_StartSF_USS_r13=0; + + // NPUSCH //(specs TS 36.331 v14.2.1 pag 643) /* OPTIONAL */ + physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13->ack_NACK_NumRepetitions_r13= NULL; + npusch_AllSymbols= CALLOC(1, sizeof(BOOLEAN_t)); + *npusch_AllSymbols= 1; //TRUE + physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13->npusch_AllSymbols_r13= npusch_AllSymbols; /* OPTIONAL */ + physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13->groupHoppingDisabled_r13=NULL; /* OPTIONAL */ + + // UplinkPowerControlDedicated + physicalConfigDedicated2_NB_IoT->uplinkPowerControlDedicated_r13->p0_UE_NPUSCH_r13 = 0; // 0 dB (specs TS36.331 v14.2.1 pag 643) + + + //Fill the rrcConnectionSetup-NB message + rrcConnectionSetup_NB_IoT->rrc_TransactionIdentifier = Transaction_id; //input value + rrcConnectionSetup_NB_IoT->criticalExtensions.present = RRCConnectionSetup_NB__criticalExtensions_PR_c1; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.present =RRCConnectionSetup_NB__criticalExtensions__c1_PR_rrcConnectionSetup_r13 ; + //MP: carry only SRB1bis at the moment and phyConfigDedicated + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.srb_ToAddModList_r13 = *SRB_configList_NB_IoT; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.drb_ToAddModList_r13 = NULL; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.drb_ToReleaseList_r13 = NULL; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.rlf_TimersAndConstants_r13 = NULL; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.physicalConfigDedicated_r13 = physicalConfigDedicated2_NB_IoT; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.mac_MainConfig_r13 = NULL; + +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_DL_CCCH_Message, (void*)&dl_ccch_msg); +#endif + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, + (void*)&dl_ccch_msg_NB_IoT, + buffer, + 100); + + if (enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + +#ifdef USER_MODE + LOG_D(RRC,"RRCConnectionSetup-NB Encoded %zd bits (%zd bytes), ecause %d\n", + enc_rval.encoded,(enc_rval.encoded+7)/8,ecause); +#endif + + return((enc_rval.encoded+7)/8); +} + +/*do_SecurityModeCommand - exactly the same as previous implementation*/ +uint8_t do_SecurityModeCommand_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t* const buffer, + const uint8_t Transaction_id, + const uint8_t cipheringAlgorithm, + const uint8_t integrityProtAlgorithm) +{ + DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + asn_enc_rval_t enc_rval; + + memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t)); + + dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_securityModeCommand_r13; + + dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.rrc_TransactionIdentifier = Transaction_id; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.present = SecurityModeCommand__criticalExtensions_PR_c1; + + dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.choice.c1.present = + SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8; + + // the two following information could be based on the mod_id + dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm + = (CipheringAlgorithm_r12_t)cipheringAlgorithm; //bug solved + + dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm + = (e_SecurityAlgorithmConfig__integrityProtAlgorithm)integrityProtAlgorithm; + +//only changed "asn_DEF_DL_DCCH_Message_NB" +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_DL_DCCH_Message_NB, (void*)&dl_dcch_msg_NB_IoT); +#endif + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, + (void*)&dl_dcch_msg_NB_IoT, + buffer, + 100); + if (enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + + +//#if defined(ENABLE_ITTI) +//# if !defined(DISABLE_XER_SPRINT).... + +#ifdef USER_MODE + LOG_D(RRC,"[NB-IoT %d] securityModeCommand-NB for UE %x Encoded %zd bits (%zd bytes)\n", + ctxt_pP->module_id, + ctxt_pP->rnti, + enc_rval.encoded, + (enc_rval.encoded+7)/8); +#endif + + if (enc_rval.encoded==-1) { + LOG_E(RRC,"[NB-IoT %d] ASN1 : securityModeCommand-NB encoding failed for UE %x\n", + ctxt_pP->module_id, + ctxt_pP->rnti); + return(-1); + } + + return((enc_rval.encoded+7)/8); +} + +/*do_UECapabilityEnquiry_NB_IoT - very similar to legacy lte*/ +uint8_t do_UECapabilityEnquiry_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t* const buffer, + const uint8_t Transaction_id +) + +{ + + DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + //no RAT type in NB-IoT + asn_enc_rval_t enc_rval; + + memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t)); + + dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_ueCapabilityEnquiry_r13; + + dl_dcch_msg_NB_IoT.message.choice.c1.choice.ueCapabilityEnquiry_r13.rrc_TransactionIdentifier = Transaction_id; + + dl_dcch_msg_NB_IoT.message.choice.c1.choice.ueCapabilityEnquiry_r13.criticalExtensions.present = UECapabilityEnquiry_NB__criticalExtensions_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.ueCapabilityEnquiry_r13.criticalExtensions.choice.c1.present = + UECapabilityEnquiry_NB__criticalExtensions__c1_PR_ueCapabilityEnquiry_r13; + + //no ue_CapabilityRequest (list of RAT_Type) + +//only changed "asn_DEF_DL_DCCH_Message_NB" +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_DL_DCCH_Message_NB, (void*)&dl_dcch_msg_NB_IoT); +#endif + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, + (void*)&dl_dcch_msg_NB_IoT, + buffer, + 100); + if (enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + +//#if defined(ENABLE_ITTI) +//# if !defined(DISABLE_XER_SPRINT).... + +#ifdef USER_MODE + LOG_D(RRC,"[NB-IoT %d] UECapabilityEnquiry-NB for UE %x Encoded %zd bits (%zd bytes)\n", + ctxt_pP->module_id, + ctxt_pP->rnti, + enc_rval.encoded, + (enc_rval.encoded+7)/8); +#endif + + if (enc_rval.encoded==-1) { + LOG_E(RRC,"[NB-IoT %d] ASN1 : UECapabilityEnquiry-NB encoding failed for UE %x\n", + ctxt_pP->module_id, + ctxt_pP->rnti); + return(-1); + } + + return((enc_rval.encoded+7)/8); +} + +/*do_RRCConnectionReconfiguration_NB_IoT-->may convey information for resource configuration + * (including RBs, MAC main configuration and physical channel configuration) + * including any associated dedicated NAS information.*/ +uint16_t do_RRCConnectionReconfiguration_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t *buffer, + uint8_t Transaction_id, + SRB_ToAddModList_NB_r13_t *SRB1_list_NB, //SRB_ConfigList2 (default)--> only SRB1 + DRB_ToAddModList_NB_r13_t *DRB_list_NB_IoT, //DRB_ConfigList (default) + DRB_ToReleaseList_NB_r13_t *DRB_list2_NB_IoT, //is NULL when passed + struct PhysicalConfigDedicated_NB_r13 *physicalConfigDedicated_NB_IoT, + MAC_MainConfig_NB_r13_t *mac_MainConfig_NB_IoT, + struct RRCConnectionReconfiguration_NB_r13_IEs__dedicatedInfoNASList_r13* dedicatedInfoNASList_NB_IoT) + +{ + + //check on DRB_list if contains more than 2 DRB? + + asn_enc_rval_t enc_rval; + DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + RRCConnectionReconfiguration_NB_t *rrcConnectionReconfiguration_NB; + + + memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t)); + + dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_rrcConnectionReconfiguration_r13; + rrcConnectionReconfiguration_NB = &dl_dcch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReconfiguration_r13; + + // RRCConnectionReconfiguration + rrcConnectionReconfiguration_NB->rrc_TransactionIdentifier = Transaction_id; + rrcConnectionReconfiguration_NB->criticalExtensions.present = RRCConnectionReconfiguration_NB__criticalExtensions_PR_c1; + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.present =RRCConnectionReconfiguration_NB__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r13 ; + + //RAdioResourceconfigDedicated + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13 = + CALLOC(1,sizeof(*rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13)); + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->srb_ToAddModList_r13 = SRB1_list_NB; //only SRB1 + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->drb_ToAddModList_r13 = DRB_list_NB_IoT; + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->drb_ToReleaseList_r13 = DRB_list2_NB_IoT; //NULL + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->physicalConfigDedicated_r13 = physicalConfigDedicated_NB_IoT; + //FIXME may not used now + //rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->rlf_TimersAndConstants_r13 + + if (mac_MainConfig_NB_IoT!=NULL) { + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13 = + CALLOC(1, sizeof(*rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13)); + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13->present + =RadioResourceConfigDedicated_NB_r13__mac_MainConfig_r13_PR_explicitValue_r13; + //why memcopy only this one? + memcpy(&rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13->choice.explicitValue_r13, + mac_MainConfig_NB_IoT, sizeof(*mac_MainConfig_NB_IoT)); + + } else { + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13=NULL; + } + + //no measConfig, measIDlist + //no mobilityControlInfo + + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.dedicatedInfoNASList_r13 = dedicatedInfoNASList_NB_IoT; + //mainly used for cell-reselection/handover purposes?? + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.fullConfig_r13 = NULL; + + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, + (void*)&dl_dcch_msg_NB_IoT, + buffer, + RRC_BUF_SIZE); + if (enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed %s, %li\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + + //changed only asn_DEF_DL_DCCH_Message_NB +#ifdef XER_PRINT + xer_fprint(stdout,&asn_DEF_DL_DCCH_Message_NB,(void*)&dl_dcch_msg_NB_IoT); +#endif + +//#if defined(ENABLE_ITTI) +//# if !defined(DISABLE_XER_SPRINT)... + + + LOG_I(RRC,"RRCConnectionReconfiguration-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + + return((enc_rval.encoded+7)/8); +} + +/*do_RRCConnectionReestablishmentReject - exactly the same as legacy LTE*/ +uint8_t do_RRCConnectionReestablishmentReject_NB_IoT( + uint8_t Mod_id, + uint8_t* const buffer) +{ + + asn_enc_rval_t enc_rval; + + DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; + RRCConnectionReestablishmentReject_t *rrcConnectionReestablishmentReject; + + memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(DL_CCCH_Message_NB_t)); + dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1; + dl_ccch_msg_NB_IoT.message.choice.c1.present = DL_CCCH_MessageType_NB__c1_PR_rrcConnectionReestablishmentReject_r13; + rrcConnectionReestablishmentReject = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReestablishmentReject_r13; + + // RRCConnectionReestablishmentReject //exactly the same as LTE + rrcConnectionReestablishmentReject->criticalExtensions.present = RRCConnectionReestablishmentReject__criticalExtensions_PR_rrcConnectionReestablishmentReject_r8; + + //Only change in "asn_DEF_DL_CCCH_Message_NB" +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_DL_CCCH_Message_NB, (void*)&dl_ccch_msg_NB_IoT); +#endif + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, + (void*)&dl_ccch_msg_NB_IoT, + buffer, + 100); + if (enc_rval.encoded <= 0) { + LOG_F(RRC,"ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + + //Only change in "asn_DEF_DL_CCCH_Message_NB" +#if defined(ENABLE_ITTI) +# if !defined(DISABLE_XER_SPRINT) + { + char message_string[20000]; + size_t message_string_size; + + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) { + MessageDef *msg_p; + + msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); + msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; + memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); + } + } +# endif +#endif + +#ifdef USER_MODE + LOG_D(RRC,"RRCConnectionReestablishmentReject Encoded %zd bits (%zd bytes)\n", + enc_rval.encoded,(enc_rval.encoded+7)/8); +#endif + + return((enc_rval.encoded+7)/8); +} + +/*do_RRCConnectionReject_NB_IoT*/ +uint8_t do_RRCConnectionReject_NB_IoT( + uint8_t Mod_id, + uint8_t* const buffer) + +{ + + asn_enc_rval_t enc_rval; + + DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; + RRCConnectionReject_NB_t *rrcConnectionReject_NB_IoT; + + memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(DL_CCCH_Message_NB_t)); + dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1; + dl_ccch_msg_NB_IoT.message.choice.c1.present = DL_CCCH_MessageType_NB__c1_PR_rrcConnectionReject_r13; + rrcConnectionReject_NB_IoT = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReject_r13; + + // RRCConnectionReject-NB_IoT + rrcConnectionReject_NB_IoT->criticalExtensions.present = RRCConnectionReject_NB__criticalExtensions_PR_c1; + rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.present = RRCConnectionReject_NB__criticalExtensions__c1_PR_rrcConnectionReject_r13; + /* let's put an extended wait time of 1s for the moment */ + rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReject_r13.extendedWaitTime_r13 = 1; + //new-use of suspend indication + //If present, this field indicates that the UE should remain suspended and not release its stored context. + rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReject_r13.rrc_SuspendIndication_r13= + CALLOC(1, sizeof(long)); + *(rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReject_r13.rrc_SuspendIndication_r13)= + RRCConnectionReject_NB_r13_IEs__rrc_SuspendIndication_r13_true; + + //Only Modified "asn_DEF_DL_CCCH_Message_NB" +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_DL_CCCH_Message_NB, (void*)&dl_ccch_msg); +#endif + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, + (void*)&dl_ccch_msg_NB_IoT, + buffer, + 100); + if (enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed (%s, %ld)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + +#if defined(ENABLE_ITTI) +# if !defined(DISABLE_XER_SPRINT) + { + char message_string[20000]; + size_t message_string_size; + + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) { + MessageDef *msg_p; + + msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); + msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; + memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); + } + } +# endif +#endif + +#ifdef USER_MODE + LOG_D(RRC,"RRCConnectionReject-NB Encoded %zd bits (%zd bytes)\n", + enc_rval.encoded,(enc_rval.encoded+7)/8); +#endif + + return((enc_rval.encoded+7)/8); +} + + +//no do_MBSFNAreaConfig(..) in NB-IoT +//no do_MeasurementReport(..) in NB-IoT + +/*do_DLInformationTransfer_NB*/ +uint8_t do_DLInformationTransfer_NB_IoT( + uint8_t Mod_id, + uint8_t **buffer, + uint8_t transaction_id, + uint32_t pdu_length, + uint8_t *pdu_buffer) + +{ + ssize_t encoded; + + DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + + memset(&dl_dcch_msg_NB_IoT, 0, sizeof(DL_DCCH_Message_NB_t)); + + dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_dlInformationTransfer_r13; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.rrc_TransactionIdentifier = transaction_id; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.present = DLInformationTransfer_NB__criticalExtensions_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.choice.c1.present = DLInformationTransfer_NB__criticalExtensions__c1_PR_dlInformationTransfer_r13; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.choice.c1.choice.dlInformationTransfer_r13.dedicatedInfoNAS_r13.size = pdu_length; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.choice.c1.choice.dlInformationTransfer_r13.dedicatedInfoNAS_r13.buf = pdu_buffer; + + encoded = uper_encode_to_new_buffer (&asn_DEF_DL_DCCH_Message_NB, NULL, (void*) &dl_dcch_msg_NB_IoT, (void **) buffer); + + //only change in "asn_DEF_DL_DCCH_Message_NB" +#if defined(ENABLE_ITTI) +# if !defined(DISABLE_XER_SPRINT) + { + char message_string[10000]; + size_t message_string_size; + + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_DCCH_Message_NB, (void *)&dl_dcch_msg_NB_IoT)) > 0) { + MessageDef *msg_p; + + msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, RRC_DL_DCCH, message_string_size + sizeof (IttiMsgText)); + msg_p->ittiMsg.rrc_dl_dcch.size = message_string_size; + memcpy(&msg_p->ittiMsg.rrc_dl_dcch.text, message_string, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); + } + } +# endif +#endif + + return encoded; +} + +/*do_ULInformationTransfer*/ +//for the moment is not needed (UE-SIDE) + +/*OAI_UECapability_t *fill_ue_capability*/ + +/*do_RRCConnectionReestablishment_NB-->used to re-establish SRB1*/ //which parameter to use? +uint8_t do_RRCConnectionReestablishment_NB_IoT( + uint8_t Mod_id, + uint8_t* const buffer, + const uint8_t Transaction_id, + const NB_IoT_DL_FRAME_PARMS* const frame_parms, //to be changed + SRB_ToAddModList_NB_r13_t* SRB_list_NB_IoT) //should contain SRB1 already configured? +{ + + asn_enc_rval_t enc_rval; + DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; + RRCConnectionReestablishment_NB_t* rrcConnectionReestablishment_NB_IoT; + + memset(&dl_ccch_msg_NB_IoT, 0, sizeof(DL_CCCH_Message_NB_t)); + + dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1; + dl_ccch_msg_NB_IoT.message.choice.c1.present = DL_CCCH_MessageType_NB__c1_PR_rrcConnectionReestablishment_r13; + rrcConnectionReestablishment_NB_IoT = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReestablishment_r13; + + //rrcConnectionReestablishment_NB + rrcConnectionReestablishment_NB_IoT->rrc_TransactionIdentifier = Transaction_id; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.present = RRCConnectionReestablishment_NB__criticalExtensions_PR_c1; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.present = RRCConnectionReestablishment_NB__criticalExtensions__c1_PR_rrcConnectionReestablishment_r13; + + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.srb_ToAddModList_r13 = SRB_list_NB_IoT; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.drb_ToAddModList_r13 = NULL; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.drb_ToReleaseList_r13 = NULL; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.rlf_TimersAndConstants_r13= NULL; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.mac_MainConfig_r13= NULL; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.physicalConfigDedicated_r13 = NULL; + + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.nextHopChainingCount_r13=0; + + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, + (void*)&dl_ccch_msg_NB_IoT, + buffer, + RRC_BUF_SIZE); + + if (enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed (%s, %li)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + +#ifdef XER_PRINT + xer_fprint(stdout,&asn_DEF_DL_CCCH_Message_NB,(void*)&dl_ccch_msg_NB_IoT); +#endif + +#if defined(ENABLE_ITTI) +# if !defined(DISABLE_XER_SPRINT) + { + char message_string[30000]; + size_t message_string_size; + + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) { + MessageDef *msg_p; + + msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); + msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; + memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); + } + } +# endif +#endif + + LOG_I(RRC,"RRCConnectionReestablishment-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + return 0; +} + +/*do_RRCConnectionRelease_NB--> is used to command the release of an RRC connection*/ +uint8_t do_RRCConnectionRelease_NB_IoT( + uint8_t Mod_id, + uint8_t *buffer, + const uint8_t Transaction_id) +{ + + asn_enc_rval_t enc_rval; + + DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + RRCConnectionRelease_NB_t *rrcConnectionRelease_NB_IoT; + + + memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t)); + + dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_rrcConnectionRelease_r13; + rrcConnectionRelease_NB_IoT = &dl_dcch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionRelease_r13; + + // RRCConnectionRelease + rrcConnectionRelease_NB_IoT->rrc_TransactionIdentifier = Transaction_id; + rrcConnectionRelease_NB_IoT->criticalExtensions.present = RRCConnectionRelease_NB__criticalExtensions_PR_c1; + rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.present =RRCConnectionRelease_NB__criticalExtensions__c1_PR_rrcConnectionRelease_r13 ; + + rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.releaseCause_r13 = ReleaseCause_NB_r13_other; + rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.redirectedCarrierInfo_r13 = NULL; + rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.extendedWaitTime_r13 = NULL; + + //Why allocate memory for non critical extension? + rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.nonCriticalExtension=CALLOC(1, + sizeof(*rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.nonCriticalExtension)); + + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, + (void*)&dl_dcch_msg_NB_IoT, + buffer, + RRC_BUF_SIZE);//check + + return((enc_rval.encoded+7)/8); +} + + + + diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.h b/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.h new file mode 100644 index 0000000000..67e0919307 --- /dev/null +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.h @@ -0,0 +1,293 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file asn1_msg.h +* \brief primitives to build the asn1 messages +* \author Raymond Knopp, Navid Nikaein and Michele Paffetti +* \date 2011, 2017 +* \version 1.0 +* \company Eurecom +* \email: raymond.knopp@eurecom.fr ,navid.nikaein@eurecom.fr, michele.paffetti@studio.unibo.it +*/ + +#ifdef USER_MODE +#include +#include +#include /* for atoi(3) */ +#include /* for getopt(3) */ +#include /* for strerror(3) */ +#include /* for EX_* exit codes */ +#include /* for errno */ +#else +#include /* Needed by all modules */ +#endif + +#include +#include /* for _ASN_DEFAULT_STACK_MAX */ + + +#include "RRC/LITE/defs_NB_IoT.h" + +/* + * The variant of the above function which dumps the BASIC-XER (XER_F_BASIC) + * output into the chosen string buffer. + * RETURN VALUES: + * 0: The structure is printed. + * -1: Problem printing the structure. + * WARNING: No sensible error value is returned. + */ + + +/** +\brief Generate configuration for SIB1 (eNB). +@param carrier pointer to Carrier information +@param N_RB_DL Number of downlink PRBs +@param frame radio frame number +@return size of encoded bit stream in bytes*/ +uint8_t do_MIB_NB_IoT( + rrc_eNB_carrier_data_NB_IoT_t *carrier, + uint32_t N_RB_DL, + uint32_t frame, + uint32_t hyper_frame); + + +/** +\brief Generate a default configuration for SIB1-NB (eNB). +@param Mod_id Instance of eNB +@param CC_id Component carrier to configure +@param carrier pointer to Carrier information +@param configuration Pointer Configuration Request structure +@return size of encoded bit stream in bytes*/ + +uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, + int CC_id, + rrc_eNB_carrier_data_NB_IoT_t *carrier, + NbIoTRrcConfigurationReq *configuration, + uint32_t frame + ); + +/** +\brief Generate a default configuration for SIB2/SIB3-NB in one System Information PDU (eNB). +@param Mod_id Index of eNB (used to derive some parameters) +@param buffer Pointer to PER-encoded ASN.1 description of SI-NB PDU +@param systemInformation_NB_IoT Pointer to asn1c C representation of SI-NB PDU +@param sib2_NB Pointer (returned) to sib2_NB component withing SI-NB PDU +@param sib3_NB Pointer (returned) to sib3_NB component withing SI-NB PDU +@return size of encoded bit stream in bytes*/ + +uint8_t do_SIB23_NB_IoT(uint8_t Mod_id, + int CC_id, + rrc_eNB_carrier_data_NB_IoT_t *carrier, + NbIoTRrcConfigurationReq *configuration + ); + +/**(UE-SIDE) +\brief Generate an RRCConnectionRequest-NB UL-CCCH-Message (UE) based on random string or S-TMSI. This +routine only generates an mo-data establishment cause. +@param buffer Pointer to PER-encoded ASN.1 description of UL-DCCH-Message PDU +@param rv 5 byte random string or S-TMSI +@param Mod_id +@returns Size of encoded bit stream in bytes*/ + +uint8_t do_RRCConnectionRequest_NB_IoT(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv); + + +/**(UE -SIDE) +\brief Generate an RRCConnectionSetupComplete-NB UL-DCCH-Message (UE) +@param Mod_id +@param Transaction_id +@param dedicatedInfoNASLength +@param dedicatedInfoNAS +@param buffer Pointer to PER-encoded ASN.1 description of UL-DCCH-Message PDU +@returns Size of encoded bit stream in bytes*/ + +uint8_t do_RRCConnectionSetupComplete_NB_IoT(uint8_t Mod_id, uint8_t* buffer, const uint8_t Transaction_id, const int dedicatedInfoNASLength, + const char* dedicatedInfoNAS); + +/** (UE-SIDE) +\brief Generate an RRCConnectionReconfigurationComplete-NB UL-DCCH-Message (UE) +@param buffer Pointer to PER-encoded ASN.1 description of UL-DCCH-Message PDU +@param ctxt_pP +@param Transaction_id +@returns Size of encoded bit stream in bytes*/ + +uint8_t do_RRCConnectionReconfigurationComplete_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t* buffer, + const uint8_t Transaction_id +); + +/** +\brief Generate an RRCConnectionSetup-NB DL-CCCH-Message (eNB). This routine configures SRB_ToAddMod (SRB1/SRB1bis-NB) and +PhysicalConfigDedicated-NB IEs. +@param ctxt_pP Running context +@param ue_context_pP UE context +@param CC_id Component Carrier ID +@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU +@param transmission_mode Transmission mode for UE (1-9) +@param UE_id UE index for this message +@param Transaction_id Transaction_ID for this message +@param SRB_configList Pointer (returned) to SRB1_config/SRB1bis_config(later) IEs for this UE +@param physicalConfigDedicated_NB Pointer (returned) to PhysicalConfigDedicated-NB IE for this UE +@returns Size of encoded bit stream in bytes*/ + +uint8_t do_RRCConnectionSetup_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, + int CC_id, + uint8_t* const buffer, //carrier[CC_id].Srb0.Tx_buffer.Payload + const uint8_t Transaction_id, + const NB_IoT_DL_FRAME_PARMS* const frame_parms, //to be changed but not deleted + SRB_ToAddModList_NB_r13_t** SRB_configList_NB_IoT, //in order to be configured--> stanno puntando alla SRB_configlist dell ue_context + struct PhysicalConfigDedicated_NB_r13** physicalConfigDedicated_NB_IoT //in order to be configured--> stanno puntando alla physicalConfigDedicated dell ue_context +); + + +/** + * For which SRB is used in NB-IoT?? +\brief Generate an RRCConnectionReconfiguration-NB DL-DCCH-Message (eNB). This routine configures SRBToAddMod-NB (SRB1) and one DRBToAddMod-NB +(DRB3). PhysicalConfigDedicated-NB is not updated. +@param ctxt_pP Running context +@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU +@param Transaction_id Transaction_ID for this message +@param SRB_list_NB Pointer to SRB List to be added/modified (NULL if no additions/modifications) +@param DRB_list_NB Pointer to DRB List to be added/modified (NULL if no additions/modifications) +@param DRB_list2_NB Pointer to DRB List to be released (NULL if none to be released) +//sps not supported by NB-IoT +@param physicalConfigDedicated_NB Pointer to PhysicalConfigDedicated-NB to be modified (NULL if no modifications) +//measurement not supported by NB-IoT +@param mac_MainConfig Pointer to Mac_MainConfig(NULL if no modifications) +//no CBA functionalities +@returns Size of encoded bit stream in bytes*/ + +uint16_t +do_RRCConnectionReconfiguration_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t *buffer, + uint8_t Transaction_id, + SRB_ToAddModList_NB_r13_t *SRB_list_NB_IoT, + DRB_ToAddModList_NB_r13_t *DRB_list_NB_IoT, + DRB_ToReleaseList_NB_r13_t *DRB_list2_NB_IoT, + struct PhysicalConfigDedicated_NB_r13 *physicalConfigDedicated, + MAC_MainConfig_t *mac_MainConfig, + struct RRCConnectionReconfiguration_NB_r13_IEs__dedicatedInfoNASList_r13* dedicatedInfoNASList_NB_IoT); + +/** + * E-UTRAN applies the procedure as follows: when only for NB-IoT SRB1 and SRB1bis is established + \brief Generate a SecurityModeCommand + @param ctxt_pP Running context + @param buffer Pointer to PER-encoded ASN.1 description + @param Transaction_id Transaction_ID for this message + @param cipheringAlgorithm + @param integrityProtAlgorithm + */ + +uint8_t do_SecurityModeCommand_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t* const buffer, + const uint8_t Transaction_id, + const uint8_t cipheringAlgorithm, + const uint8_t integrityProtAlgorithm); + +/** + * E-UTRAN applies the procedure as follows: when only for NB-IoT SRB1 and SRB1bis is established + \brief Generate a SecurityModeCommand + @param ctxt_pP Running context + @param buffer Pointer to PER-encoded ASN.1 description + @param Transaction_id Transaction_ID for this message + */ + +uint8_t do_UECapabilityEnquiry_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t* const buffer, + const uint8_t Transaction_id +); + + +/** + * There is nothing new in this type of message for NB-IoT (only change in some nomenclature) +\brief Generate an RRCConnectionReestablishmentReject DL-CCCH-Message (eNB). +@param Mod_id Module ID of eNB +@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU +@returns Size of encoded bit stream in bytes*/ + +uint8_t +do_RRCConnectionReestablishmentReject_NB_IoT( + uint8_t Mod_id, + uint8_t* const buffer); + + +/** +\brief Generate an RRCConnectionReject-NB DL-CCCH-Message (eNB). +@param Mod_id Module ID of eNB +@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU +@returns Size of encoded bit stream in bytes*/ +uint8_t +do_RRCConnectionReject_NB_IoT( + uint8_t Mod_id, + uint8_t* const buffer); + + +/** +\brief Generate an RRCConnectionRelease-NB DL-DCCH-Message +@param Mod_id Module ID of eNB +@param buffer Pointer to PER-encoded ASN.1 description +@param transaction_id Transaction index +@returns Size of encoded bit stream in bytes*/ + +uint8_t do_RRCConnectionRelease_NB_IoT(uint8_t Mod_id, uint8_t *buffer,int Transaction_id); + + +uint8_t do_DLInformationTransfer_NB_IoT( + uint8_t Mod_id, + uint8_t **buffer, + uint8_t transaction_id, + uint32_t pdu_length, + uint8_t *pdu_buffer); + +//for now not implemented since UE side +//uint8_t do_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t *pdu_buffer); + +//for now not implemented since UE side??? +//OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) + +/** +\brief Generate an RRCConnectionReestablishment-NB DL-CCCH Message + *@param + * + */ + +uint8_t do_RRCConnectionReestablishment_NB_IoT( + uint8_t Mod_id, + uint8_t* const buffer, + const uint8_t Transaction_id, + const NB_IoT_DL_FRAME_PARMS* const frame_parms, //to be changed + SRB_ToAddModList_NB_r13_t** SRB_configList_NB_IoT + ); + +/** +\brief Generate an RRCConnectionRelease-NB DL-DCCH-Message (eNB) +@param Mod_id Module ID of eNB +@param buffer Pointer to PER-encoded ASN.1 description of DL-DCCH-Message PDU +@param transaction_id Transaction index +@returns Size of encoded bit stream in bytes*/ + +//uint8_t do_RRCConnectionRelease_NB_IoT(uint8_t Mod_id, uint8_t *buffer,int Transaction_id); diff --git a/openair2/RRC/LITE/defs_NB_IoT.h b/openair2/RRC/LITE/defs_NB_IoT.h new file mode 100644 index 0000000000..98b9148cd2 --- /dev/null +++ b/openair2/RRC/LITE/defs_NB_IoT.h @@ -0,0 +1,570 @@ +/* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file RRC/LITE/defs_NB_IoT.h +* \brief NB-IoT RRC struct definitions and function prototypes +* \author Navid Nikaein, Raymond Knopp and Michele Paffetti +* \date 2010 - 2014, 2017 +* \version 1.0 +* \company Eurecom +* \email: navid.nikaein@eurecom.fr, raymond.knopp@eurecom.fr, michele.paffetti@studio.unibo.it +*/ + +#ifndef __OPENAIR_RRC_DEFS_NB_IOT_H__ +#define __OPENAIR_RRC_DEFS_NB_IOT_H__ + + +#include +#include +#include + +#include "collection/tree.h" +#include "rrc_types_NB_IoT.h" +#include "COMMON/platform_constants.h" +#include "COMMON/platform_types.h" +#include "targets/COMMON/openairinterface5g_limits.h" + +#include "COMMON/mac_rrc_primitives.h" + +//-----NB-IoT #include files------- + +//#include "SystemInformationBlockType1-NB.h" +//#include "SystemInformation-NB.h" +#include "RRCConnectionReconfiguration-NB.h" +#include "RRCConnectionReconfigurationComplete-NB.h" +#include "RRCConnectionSetup-NB.h" +#include "RRCConnectionSetupComplete-NB.h" +#include "RRCConnectionRequest-NB.h" +#include "RRCConnectionReestablishmentRequest-NB.h" +#include "BCCH-DL-SCH-Message-NB.h" +#include "BCCH-BCH-Message-NB.h" +#include "AS-Config-NB.h" +#include "AS-Context-NB.h" +#include "UE-Capability-NB-r13.h" //equivalent of UE-EUTRA-Capability.h +//------------------- + +#if defined(ENABLE_ITTI) +# include "intertask_interface.h" +#endif + +/* TODO: be sure this include is correct. + * It solves a problem of compilation of the RRH GW, + * issue #186. + */ +#if !defined(ENABLE_ITTI) +# include "as_message.h" +#endif + +#if defined(ENABLE_USE_MME) +# include "commonDef.h" +#endif + +#if ENABLE_RAL +# include "collection/hashtable/obj_hashtable.h" +#endif + + + +/*I will change the name of the structure for compile purposes--> hope not to undo this process*/ + +typedef unsigned int uid_NB_IoT_t; +#define UID_LINEAR_ALLOCATOR_BITMAP_SIZE_NB_IoT (((NUMBER_OF_UE_MAX_NB_IoT/8)/sizeof(unsigned int)) + 1) + +typedef struct uid_linear_allocator_NB_IoT_s { + unsigned int bitmap[UID_LINEAR_ALLOCATOR_BITMAP_SIZE_NB_IoT]; +} uid_allocator_NB_IoT_t; + + +#define PROTOCOL_RRC_CTXT_UE_FMT PROTOCOL_CTXT_FMT +#define PROTOCOL_RRC_CTXT_UE_ARGS(CTXT_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp) + +#define PROTOCOL_RRC_CTXT_FMT PROTOCOL_CTXT_FMT +#define PROTOCOL_RRC_CTXT_ARGS(CTXT_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp) + + +//left as they are --> used in LAYER2/epenair2_proc.c and UE side +typedef enum UE_STATE_NB_IoT_e { + RRC_INACTIVE_NB_IoT=0, + RRC_IDLE_NB_IoT, + RRC_SI_RECEIVED_NB_IoT, + RRC_CONNECTED_NB_IoT, + RRC_RECONFIGURED_NB_IoT, + RRC_HO_EXECUTION_NB_IoT //maybe not needed? +} UE_STATE_NB_IoT_t; + + +/** @defgroup _rrc RRC + * @ingroup _oai2 + * @{ + */ +typedef struct UE_RRC_INFO_NB_IoT_s { + UE_STATE_NB_IoT_t State; + uint8_t SIB1systemInfoValueTag; + uint32_t SIStatus; + uint32_t SIcnt; +#if defined(Rel10) || defined(Rel14) + uint8_t MCCHStatus[8]; // MAX_MBSFN_AREA +#endif + uint8_t SIwindowsize; //!< Corresponds to the SIB1 si-WindowLength parameter. The unit is ms. Possible values are (final): 1,2,5,10,15,20,40 + uint8_t handoverTarget; + //HO_STATE_t ho_state; + uint16_t SIperiod; //!< Corresponds to the SIB1 si-Periodicity parameter (multiplied by 10). Possible values are (final): 80,160,320,640,1280,2560,5120 + unsigned short UE_index; + uint32_t T300_active; + uint32_t T300_cnt; + uint32_t T304_active; + uint32_t T304_cnt; + uint32_t T310_active; + uint32_t T310_cnt; + uint32_t N310_cnt; + uint32_t N311_cnt; + rnti_t rnti; +} __attribute__ ((__packed__)) UE_RRC_INFO_NB_IoT; + +//#define NUM_PRECONFIGURED_LCHAN (NB_CH_CX*2) //BCCH, CCCH + +#define UE_MODULE_INVALID ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!! +#define UE_INDEX_INVALID ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!! used to be -1 + + + +// HO_STATE is not supported by NB-IoT + +//#define NUMBER_OF_UE_MAX MAX_MOBILES_PER_RG +#define RRM_FREE(p) if ( (p) != NULL) { free(p) ; p=NULL ; } +#define RRM_MALLOC(t,n) (t *) malloc16( sizeof(t) * n ) +#define RRM_CALLOC(t,n) (t *) malloc16( sizeof(t) * n) +#define RRM_CALLOC2(t,s) (t *) malloc16( s ) + +//Measurement Report not supported in NB-IoT + +#define PAYLOAD_SIZE_MAX 1024 +#define RRC_BUF_SIZE 255 +#define UNDEF_SECURITY_MODE 0xff +#define NO_SECURITY_MODE 0x20 + +/* TS 36.331: RRC-TransactionIdentifier ::= INTEGER (0..3) */ +#define RRC_TRANSACTION_IDENTIFIER_NUMBER 3 + +typedef struct UE_S_TMSI_NB_IoT_s { + boolean_t presence; + mme_code_t mme_code; + m_tmsi_t m_tmsi; +} __attribute__ ((__packed__)) UE_S_TMSI_NB_IoT; + + +typedef enum e_rab_satus_NB_IoT_e { + E_RAB_STATUS_NEW_NB_IoT, + E_RAB_STATUS_DONE_NB_IoT, // from the eNB perspective + E_RAB_STATUS_ESTABLISHED_NB_IoT, // get the reconfigurationcomplete form UE + E_RAB_STATUS_FAILED_NB_IoT, +} e_rab_status_NB_IoT_t; + +typedef struct e_rab_param_NB_IoT_s { + e_rab_t param; + uint8_t status; + uint8_t xid; // transaction_id +} __attribute__ ((__packed__)) e_rab_param_NB_IoT_t; + + +//HANDOVER_INFO not implemented in NB-IoT delete + + +#define RRC_HEADER_SIZE_MAX 64 +#define RRC_BUFFER_SIZE_MAX 1024 + +typedef struct { + char Payload[RRC_BUFFER_SIZE_MAX]; + char Header[RRC_HEADER_SIZE_MAX]; + char payload_size; +} RRC_BUFFER_NB_IoT; + +#define RRC_BUFFER_SIZE_NB_IoT sizeof(RRC_BUFFER_NB_IoT) + + +typedef struct RB_INFO_NB_IoT_s { + uint16_t Rb_id; //=Lchan_id + //LCHAN_DESC Lchan_desc[2]; no more used + //MAC_MEAS_REQ_ENTRY *Meas_entry; //may not needed for NB-IoT +} RB_INFO_NB_IoT; + +typedef struct SRB_INFO_NB_IoT_s { + uint16_t Srb_id; //=Lchan_id---> useful for distinguish between SRB1 and SRB1bis? + RRC_BUFFER_NB_IoT Rx_buffer; + RRC_BUFFER_NB_IoT Tx_buffer; + //LCHAN_DESC Lchan_desc[2]; no more used + unsigned int Trans_id; + uint8_t Active; +} SRB_INFO_NB_IoT; + + +typedef struct RB_INFO_TABLE_ENTRY_NB_IoT_s { + RB_INFO_NB_IoT Rb_info; + uint8_t Active; + uint32_t Next_check_frame; + uint8_t Status; +} RB_INFO_TABLE_ENTRY_NB_IoT; + +typedef struct SRB_INFO_TABLE_ENTRY_NB_IoT_s { + SRB_INFO_NB_IoT Srb_info; + uint8_t Active; + uint8_t Status; + uint32_t Next_check_frame; +} SRB_INFO_TABLE_ENTRY_NB_IoT; + +//MEAS_REPORT_LIST_s not implemented in NB-IoT but is used at UE side +//HANDOVER_INFO_UE not implemented in NB-IoT +typedef struct HANDOVER_INFO_UE_NB_IoT_s { + PhysCellId_t targetCellId; + uint8_t measFlag; +} HANDOVER_INFO_UE_NB_IoT; + +//NB-IoT eNB_RRC_UE_NB_IoT_s--(used as a context in eNB --> ue_context in rrc_eNB_ue_context)------ +typedef struct eNB_RRC_UE_NB_IoT_s { + + EstablishmentCause_t establishment_cause; + uint8_t primaryCC_id; + //in NB-IoT only SRB0, SRB1 and SRB1bis (until AS security activation) exist + + /*MP: Concept behind List and List2 + * + * SRB_configList --> is used for the actual list of SRBs that is managed/that should be send over the RRC message + * SRB_configList2--> refers to all the SRBs configured for that specific transaction identifier + * this because in a single transaction one or more SRBs could be established + * and you want to keep memory on what happen for every transaction + * Transaction ID (xid): is used to associate the proper RRC....Complete message received by the UE to the corresponding + * message previously sent by the eNB (e.g. RRCConnectionSetup -- RRCConnectionSetupComplete) + * this because it could happen that more messages are transmitted at the same time + */ + SRB_ToAddModList_NB_r13_t* SRB_configList;//for SRB1 and SRB1bis + SRB_ToAddModList_NB_r13_t* SRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; + DRB_ToAddModList_NB_r13_t* DRB_configList; //for all the DRBs + DRB_ToAddModList_NB_r13_t* DRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; //for the configured DRBs of a xid + uint8_t DRB_active[2];//in LTE was 8 --> at most 2 for NB-IoT + + struct PhysicalConfigDedicated_NB_r13* physicalConfigDedicated_NB_IoT; + MAC_MainConfig_NB_r13_t* mac_MainConfig_NB_IoT; + + //No SPS(semi-persistent scheduling) in NB-IoT + //No Measurement report in NB-IoT + + SRB_INFO_NB_IoT SI; + SRB_INFO_NB_IoT Srb0; + SRB_INFO_TABLE_ENTRY_NB_IoT Srb1; + SRB_INFO_TABLE_ENTRY_NB_IoT Srb1bis; + +#if defined(ENABLE_SECURITY) + /* KeNB as derived from KASME received from EPC */ + uint8_t kenb[32]; +#endif + + /* Used integrity/ciphering algorithms--> maintained the same for NB-IoT */ + e_CipheringAlgorithm_r12 ciphering_algorithm; //Specs. TS 36.331 V14.1.0 pag 432 Change position of chipering enumerative w.r.t previous version + e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm; + + uint8_t Status; + rnti_t rnti; + uint64_t random_ue_identity; + + + + /* Information from UE RRC ConnectionRequest-NB-r13_IE--> NB-IoT */ + UE_S_TMSI_NB_IoT Initialue_identity_s_TMSI; + EstablishmentCause_NB_r13_t establishment_cause_NB_IoT; //different set for NB-IoT + + /* Information from UE RRC ConnectionReestablishmentRequest-NB--> NB-IoT */ + ReestablishmentCause_NB_r13_t reestablishment_cause_NB_IoT; //different set for NB_IoT + + /* UE id for initial connection to S1AP */ + uint16_t ue_initial_id; + + /* Information from S1AP initial_context_setup_req */ + uint32_t eNB_ue_s1ap_id :24; + + security_capabilities_t security_capabilities; + + /* Total number of e_rab already setup in the list */ //NAS list? + uint8_t setup_e_rabs; + /* Number of e_rab to be setup in the list */ //NAS list? + uint8_t nb_of_e_rabs; + /* list of e_rab to be setup by RRC layers */ + e_rab_param_NB_IoT_t e_rab[NB_RB_MAX_NB_IOT];//[S1AP_MAX_E_RAB]; + + // LG: For GTPV1 TUNNELS + uint32_t enb_gtp_teid[S1AP_MAX_E_RAB]; + transport_layer_addr_t enb_gtp_addrs[S1AP_MAX_E_RAB]; + rb_id_t enb_gtp_ebi[S1AP_MAX_E_RAB]; + + //Which timers are referring to? + uint32_t ul_failure_timer; + uint32_t ue_release_timer; + //threshold of the release timer--> set in RRCConnectionRelease + uint32_t ue_release_timer_thres; +} eNB_RRC_UE_NB_IoT_t; +//-------------------------------------------------------------------------------- + +typedef uid_NB_IoT_t ue_uid_t; + + +//generally variable called: ue_context_pP +typedef struct rrc_eNB_ue_context_NB_IoT_s { + + /* Tree related data */ + RB_ENTRY(rrc_eNB_ue_context_NB_IoT_s) entries; + + /* Uniquely identifies the UE between MME and eNB within the eNB. + * This id is encoded on 24bits. + */ + rnti_t ue_id_rnti; + + // another key for protocol layers but should not be used as a key for RB tree + ue_uid_t local_uid; + + /* UE id for initial connection to S1AP */ + struct eNB_RRC_UE_NB_IoT_s ue_context; //context of ue in the e-nB + +} rrc_eNB_ue_context_NB_IoT_t; + + + +//---NB-IoT (completely changed)------------------------------- +//called "carrier"--> data from PHY layer +typedef struct { + + // buffer that contains the encoded messages + uint8_t *MIB_NB_IoT; + uint8_t sizeof_MIB_NB_IoT; + + uint8_t *SIB1_NB_IoT; + uint8_t sizeof_SIB1_NB_IoT; + uint8_t *SIB23_NB_IoT; + uint8_t sizeof_SIB23_NB_IoT; + + + //not actually implemented in OAI + uint8_t *SIB4_NB_IoT; + uint8_t sizeof_SIB4_NB_IoT; + uint8_t *SIB5_NB_IoT; + uint8_t sizeof_SIB5_NB_IoT; + uint8_t *SIB14_NB_IoT; + uint8_t sizeof_SIB14_NB_IoT; + uint8_t *SIB16_NB_IoT; + uint8_t sizeof_SIB16_NB_IoT; + + //TS 36.331 V14.2.1 +// uint8_t *SIB15_NB; +// uint8_t sizeof_SIB15_NB; +// uint8_t *SIB20_NB; +// uint8_t sizeof_SIB20_NB; +// uint8_t *SIB22_NB; +// uint8_t sizeof_SIB22_NB; + + //implicit parameters needed + int Ncp; //cyclic prefix for DL + int Ncp_UL; //cyclic prefix for UL + int p_eNB; //number of tx antenna port + int p_rx_eNB; //number of receiving antenna ports + uint32_t dl_CarrierFreq; //detected by the UE + uint32_t ul_CarrierFreq; //detected by the UE + uint16_t physCellId; //not stored in the MIB-NB but is getting through NPSS/NSSS + + //are the only static one (memory has been already allocated) + BCCH_BCH_Message_NB_t mib_NB_IoT; + BCCH_DL_SCH_Message_NB_t siblock1_NB_IoT; //SIB1-NB + BCCH_DL_SCH_Message_NB_t systemInformation_NB_IoT; //SI + + SystemInformationBlockType1_NB_t *sib1_NB_IoT; + SystemInformationBlockType2_NB_r13_t *sib2_NB_IoT; + SystemInformationBlockType3_NB_r13_t *sib3_NB_IoT; + //not implemented yet + SystemInformationBlockType4_NB_r13_t *sib4_NB_IoT; + SystemInformationBlockType5_NB_r13_t *sib5_NB_IoT; + SystemInformationBlockType14_NB_r13_t *sib14_NB_IoT; + SystemInformationBlockType16_NB_r13_t *sib16_NB_IoT; + + + SRB_INFO_NB_IoT SI; + SRB_INFO_NB_IoT Srb0; + + uint8_t **MCCH_MESSAGE; // probably not needed , but added to remove errors + uint8_t sizeof_MCCH_MESSAGE[8];// but added to remove errors + SRB_INFO_NB_IoT MCCH_MESS[8];// MAX_MBSFN_AREA + /*future implementation TS 36.331 V14.2.1 + SystemInformationBlockType15_NB_r14_t *sib15; + SystemInformationBlockType20_NB_r14_t *sib20; + SystemInformationBlockType22_NB_r14_t *sib22; + + uint8_t SCPTM_flag; + uint8_t sizeof_SC_MCHH_MESS[]; + SC_MCCH_Message_NB_t scptm;*/ + + +} rrc_eNB_carrier_data_NB_IoT_t; +//--------------------------------------------------- + + + +//---NB-IoT---(completely change)--------------------- +typedef struct eNB_RRC_INST_NB_IoT_s { + + rrc_eNB_carrier_data_NB_IoT_t carrier[MAX_NUM_CCs]; + + uid_allocator_NB_IoT_t uid_allocator; // for rrc_ue_head + RB_HEAD(rrc_ue_tree_NB_IoT_s, rrc_eNB_ue_context_NB_IoT_s) rrc_ue_head; // ue_context tree key search by rnti + + uint8_t Nb_ue; + + hash_table_t *initial_id2_s1ap_ids; // key is content is rrc_ue_s1ap_ids_t + hash_table_t *s1ap_id2_s1ap_ids ; // key is content is rrc_ue_s1ap_ids_t + + //RRC configuration + RrcConfigurationReq configuration; //rrc_messages_types.h + + // other PLMN parameters + /// Mobile country code + int mcc; + /// Mobile network code + int mnc; + /// number of mnc digits + int mnc_digit_length; + + // other RAN parameters //FIXME: to be checked--> depends on APP layer + int srb1_timer_poll_retransmit; + int srb1_max_retx_threshold; + int srb1_timer_reordering; + int srb1_timer_status_prohibit; + int srs_enable[MAX_NUM_CCs]; + + +} eNB_RRC_INST_NB_IoT; + +#define RRC_HEADER_SIZE_MAX_NB_IoT 64 +#define MAX_UE_CAPABILITY_SIZE_NB_IoT 255 + +//not needed for the moment +typedef struct OAI_UECapability_NB_IoT_s { + uint8_t sdu[MAX_UE_CAPABILITY_SIZE_NB_IoT]; + uint8_t sdu_size; +////NB-IoT------ + UE_Capability_NB_r13_t UE_Capability_NB_IoT; //replace the UE_EUTRA_Capability of LTE +} OAI_UECapability_NB_IoT_t; + +#define RRC_BUFFER_SIZE_MAX_NB_IoT 1024 + + + +typedef struct UE_RRC_INST_NB_IoT_s { + Rrc_State_NB_IoT_t RrcState; + Rrc_Sub_State_NB_IoT_t RrcSubState; +# if defined(ENABLE_USE_MME) + plmn_t plmnID; + Byte_t rat; + as_nas_info_t initialNasMsg; +# endif + OAI_UECapability_NB_IoT_t *UECap; + uint8_t *UECapability; + uint8_t UECapability_size; + + UE_RRC_INFO_NB_IoT Info[NB_SIG_CNX_UE]; + + SRB_INFO_NB_IoT Srb0[NB_SIG_CNX_UE]; + SRB_INFO_TABLE_ENTRY_NB_IoT Srb1[NB_CNX_UE]; + SRB_INFO_TABLE_ENTRY_NB_IoT Srb2[NB_CNX_UE]; + HANDOVER_INFO_UE_NB_IoT HandoverInfoUe; + /* + uint8_t *SIB1[NB_CNX_UE]; + uint8_t sizeof_SIB1[NB_CNX_UE]; + uint8_t *SI[NB_CNX_UE]; + uint8_t sizeof_SI[NB_CNX_UE]; + uint8_t SIB1Status[NB_CNX_UE]; + uint8_t SIStatus[NB_CNX_UE]; + SystemInformationBlockType1_t *sib1[NB_CNX_UE]; + SystemInformation_t *si[NB_CNX_UE]; //!< Temporary storage for an SI message. Decoding happens in decode_SI(). + */ + SystemInformationBlockType2_t *sib2[NB_CNX_UE]; + /* + SystemInformationBlockType3_t *sib3[NB_CNX_UE]; + SystemInformationBlockType4_t *sib4[NB_CNX_UE]; + SystemInformationBlockType5_t *sib5[NB_CNX_UE]; + SystemInformationBlockType6_t *sib6[NB_CNX_UE]; + SystemInformationBlockType7_t *sib7[NB_CNX_UE]; + SystemInformationBlockType8_t *sib8[NB_CNX_UE]; + SystemInformationBlockType9_t *sib9[NB_CNX_UE]; + SystemInformationBlockType10_t *sib10[NB_CNX_UE]; + SystemInformationBlockType11_t *sib11[NB_CNX_UE]; + +#if defined(Rel10) || defined(Rel14) + uint8_t MBMS_flag; + uint8_t *MCCH_MESSAGE[NB_CNX_UE]; + uint8_t sizeof_MCCH_MESSAGE[NB_CNX_UE]; + uint8_t MCCH_MESSAGEStatus[NB_CNX_UE]; + MBSFNAreaConfiguration_r9_t *mcch_message[NB_CNX_UE]; + SystemInformationBlockType12_r9_t *sib12[NB_CNX_UE]; + SystemInformationBlockType13_r9_t *sib13[NB_CNX_UE]; +#endif +#ifdef CBA + uint8_t num_active_cba_groups; + uint16_t cba_rnti[NUM_MAX_CBA_GROUP]; +#endif + uint8_t num_srb; + struct SRB_ToAddMod *SRB1_config[NB_CNX_UE]; + struct SRB_ToAddMod *SRB2_config[NB_CNX_UE]; + struct DRB_ToAddMod *DRB_config[NB_CNX_UE][8]; + rb_id_t *defaultDRB; // remember the ID of the default DRB + MeasObjectToAddMod_t *MeasObj[NB_CNX_UE][MAX_MEAS_OBJ]; + struct ReportConfigToAddMod *ReportConfig[NB_CNX_UE][MAX_MEAS_CONFIG]; + */ + struct QuantityConfig *QuantityConfig[NB_CNX_UE]; + /* + struct MeasIdToAddMod *MeasId[NB_CNX_UE][MAX_MEAS_ID]; + MEAS_REPORT_LIST *measReportList[NB_CNX_UE][MAX_MEAS_ID]; + uint32_t measTimer[NB_CNX_UE][MAX_MEAS_ID][6]; // 6 neighboring cells + RSRP_Range_t s_measure; + struct MeasConfig__speedStatePars *speedStatePars; + struct PhysicalConfigDedicated *physicalConfigDedicated[NB_CNX_UE]; + struct SPS_Config *sps_Config[NB_CNX_UE]; + MAC_MainConfig_t *mac_MainConfig[NB_CNX_UE]; + MeasGapConfig_t *measGapConfig[NB_CNX_UE]; + double filter_coeff_rsrp; // [7] ??? + double filter_coeff_rsrq; // [7] ??? + float rsrp_db[7]; + float rsrq_db[7]; + float rsrp_db_filtered[7]; + float rsrq_db_filtered[7]; +#if ENABLE_RAL + obj_hash_table_t *ral_meas_thresholds; + ral_transaction_id_t scan_transaction_id; +#endif +#if defined(ENABLE_SECURITY) + // KeNB as computed from parameters within USIM card // + uint8_t kenb[32]; +#endif + + // Used integrity/ciphering algorithms // + CipheringAlgorithm_r12_t ciphering_algorithm; + e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm; + */ +} UE_RRC_INST_NB_IoT; + + +#include "proto_NB_IoT.h" //should be put here otherwise compilation error + +#endif +/** @} */ diff --git a/openair2/RRC/LITE/extern_NB_IoT.h b/openair2/RRC/LITE/extern_NB_IoT.h new file mode 100644 index 0000000000..23e7329aec --- /dev/null +++ b/openair2/RRC/LITE/extern_NB_IoT.h @@ -0,0 +1,63 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file vars.h +* \brief rrc external vars +* \author Navid Nikaein and Raymond Knopp, Michele Paffetti +* \date 2011-2017 +* \version 1.0 +* \company Eurecom +* \email: navid.nikaein@eurecom.fr, michele.paffetti@studio.unibo.it +*/ + +#ifndef __OPENAIR_RRC_EXTERN_NB_IOT_H__ +#define __OPENAIR_RRC_EXTERN_NB_IOT_H__ +#include "RRC/LITE/defs_NB_IoT.h" +#include "PHY_INTERFACE/IF_Module_NB_IoT.h" +#include "LAYER2/RLC/rlc.h" +#include "LogicalChannelConfig-NB-r13.h" +#include "LAYER2/MAC/defs_NB_IoT.h" + +#include "common/ran_context.h" + + +//MP: NOTE:XXX some of the parameters defined in vars_nb_iot are called by the extern.h file so not replicated here + +extern UE_RRC_INST_NB_IoT *UE_rrc_inst_NB_IoT; + +extern eNB_RRC_INST_NB_IoT *eNB_rrc_inst_NB_IoT; +extern PHY_Config_NB_IoT_t *config_INFO; + +extern rlc_info_t Rlc_info_am_NB_IoT,Rlc_info_am_config_NB_IoT; +extern uint8_t DRB2LCHAN_NB_IoT[2]; +extern LogicalChannelConfig_NB_r13_t SRB1bis_logicalChannelConfig_defaultValue_NB_IoT; +extern LogicalChannelConfig_NB_r13_t SRB1_logicalChannelConfig_defaultValue_NB_IoT; + +extern uint16_t T300_NB_IoT[8]; +extern uint16_t T301_NB_IoT[8]; +extern uint16_t T310_NB_IoT[8]; +extern uint16_t T311_NB_IoT[8]; +extern uint16_t N310_NB_IoT[8]; +extern uint16_t N311_NB_IoT[8]; +extern uint8_t *get_NB_IoT_MIB(struct eNB_RRC_INST_NB_IoT_s *nb_iot_rrc); +#endif + + diff --git a/openair2/RRC/LITE/proto.h b/openair2/RRC/LITE/proto.h index 49cf9f2eba..b920587419 100644 --- a/openair2/RRC/LITE/proto.h +++ b/openair2/RRC/LITE/proto.h @@ -410,6 +410,7 @@ rrc_data_req( ); uint8_t + rrc_data_req_ue( const protocol_ctxt_t* const ctxt_pP, const rb_id_t rb_idP, @@ -420,6 +421,7 @@ rrc_data_req_ue( const pdcp_transmission_mode_t modeP ); + void rrc_data_ind( const protocol_ctxt_t* const ctxt_pP, diff --git a/openair2/RRC/LITE/proto_NB_IoT.h b/openair2/RRC/LITE/proto_NB_IoT.h new file mode 100644 index 0000000000..b2f8e5b5c9 --- /dev/null +++ b/openair2/RRC/LITE/proto_NB_IoT.h @@ -0,0 +1,260 @@ +/* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file proto_NB_IoT.h + * \brief RRC functions prototypes for eNB and UE for NB-IoT + * \author Navid Nikaein, Raymond Knopp and Michele Paffetti + * \date 2010 - 2014 + * \email navid.nikaein@eurecom.fr, michele.paffetti@studio.unibo.it + * \version 1.0 + + */ +/** \addtogroup _rrc + * @{ + */ + +#include "RRC/LITE/defs_NB_IoT.h" +#include "pdcp.h" +#include "rlc.h" +#include "extern_NB_IoT.h" +#include "LAYER2/MAC/defs_NB_IoT.h" +/*NOTE: no static function should be declared in this header file (e.g. init_SI_NB)*/ + +/*------------------------common_nb_iot.c----------------------------------------*/ + +/** \brief configure BCCH & CCCH Logical Channels and associated rrc_buffers, configure associated SRBs + */ +void openair_rrc_on_NB_IoT(const protocol_ctxt_t* const ctxt_pP); + +void rrc_config_buffer_NB_IoT(SRB_INFO_NB_IoT *srb_info, uint8_t Lchan_type, uint8_t Role); + +int L3_xface_init_NB_IoT(void); + +void openair_rrc_top_init_eNB_NB_IoT(void); + +//void rrc_top_cleanup(void); -->seems not to be used + +//rrc_t310_expiration-->seems not to be used + +/** \brief Function to update timers every subframe. For UE it updates T300,T304 and T310. +@param ctxt_pP running context +@param enb_index +@param CC_id +*/ +RRC_status_t rrc_rx_tx_NB_IoT(protocol_ctxt_t* const ctxt_pP, const uint8_t enb_index, const int CC_id); + +//long binary_search_int(int elements[], long numElem, int value);--> seems not to be used +//long binary_search_float(float elements[], long numElem, float value);--> used only at UE side + + + +//--------------------------------------- + + +//defined in L2_interface +//called by rx_sdu only in case of CCCH message (e.g RRCConnectionRequest-NB) +int8_t mac_rrc_data_ind_eNB_NB_IoT( + const module_id_t module_idP, + const int CC_id, + const frame_t frameP, + const sub_frame_t sub_frameP, + const rnti_t rntiP, + const rb_id_t srb_idP,//could be skipped since always go through the CCCH channel + const uint8_t* sduP, + const sdu_size_t sdu_lenP +); +//------------------------------------------- + +//defined in L2_interface +void dump_ue_list_NB_IoT(UE_list_NB_IoT_t *listP, int ul_flag); +//------------------------------------------- + + +//defined in L2_interface +void mac_eNB_rrc_ul_failure_NB_IoT( + const module_id_t mod_idP, + const int CC_idP, + const frame_t frameP, + const sub_frame_t subframeP, + const rnti_t rntiP); +//------------------------------------------ + +//defined in eNB_scheduler_primitives.c +int rrc_mac_remove_ue_NB_IoT( + module_id_t mod_idP, + rnti_t rntiP); +//------------------------------------------ +//defined in L2_interface +void mac_eNB_rrc_ul_in_sync_NB_IoT( + const module_id_t mod_idP, + const int CC_idP, + const frame_t frameP, + const sub_frame_t subframeP, + const rnti_t rntiP); +//------------------------------------------ +//defined in L2_interface +int mac_eNB_get_rrc_status_NB_IoT( + const module_id_t Mod_idP, + const rnti_t rntiP +); +//--------------------------- + + +/*-----------eNB procedures (rrc_eNB_nb_iot.c)---------------*/ + +//---Initialization-------------- +void openair_eNB_rrc_on_NB_IoT( + const protocol_ctxt_t* const ctxt_pP +); + +void rrc_config_buffer_NB_IoT( + SRB_INFO_NB_IoT* Srb_info, + uint8_t Lchan_type, + uint8_t Role +); + +char openair_rrc_eNB_configuration_NB_IoT( + const module_id_t enb_mod_idP, + NbIoTRrcConfigurationReq* configuration +); + +//----------------------------- +/**\brief RRC eNB task. (starting of the RRC state machine) + \param void *args_p Pointer on arguments to start the task. */ +void *rrc_enb_task_NB_IoT(void *args_p); + +/**\brief Entry routine to decode a UL-CCCH-Message-NB. Invokes PER decoder and parses message. + \param ctxt_pP Running context + \param Srb_info Pointer to SRB0 information structure (buffer, etc.)*/ +int rrc_eNB_decode_ccch_NB_IoT( + protocol_ctxt_t* const ctxt_pP, + const SRB_INFO_NB_IoT* const Srb_info, + const int CC_id +); + +/**\brief Entry routine to decode a UL-DCCH-Message-NB. Invokes PER decoder and parses message. + \param ctxt_pP Context + \param Rx_sdu Pointer Received Message + \param sdu_size Size of incoming SDU*/ +int rrc_eNB_decode_dcch_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + const rb_id_t Srb_id, + const uint8_t* const Rx_sdu, + const sdu_size_t sdu_sizeP +); + +/**\brief Generate RRCConnectionReestablishmentReject-NB + \param ctxt_pP Running context + \param ue_context_pP UE context + \param CC_id Component Carrier ID*/ +void rrc_eNB_generate_RRCConnectionReestablishmentReject_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, + const int CC_id +); + +void rrc_eNB_generate_RRCConnectionReject_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, + const int CC_id +); + +void rrc_eNB_generate_RRCConnectionSetup_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, + const int CC_id +); + +void rrc_eNB_process_RRCConnectionReconfigurationComplete_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* ue_context_pP, + const uint8_t xid //transaction identifier +); + + +void //was under ITTI +rrc_eNB_reconfigure_DRBs_NB_IoT(const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* ue_context_pP); + +void //was under ITTI +rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP +// const uint8_t ho_state + ); + +void rrc_eNB_process_RRCConnectionSetupComplete_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* ue_context_pP, + RRCConnectionSetupComplete_NB_r13_IEs_t * rrcConnectionSetupComplete_NB +); + +void rrc_eNB_generate_SecurityModeCommand_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP +); + +void rrc_eNB_generate_UECapabilityEnquiry_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP +); + +void rrc_eNB_generate_defaultRRCConnectionReconfiguration_NB_IoT(const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP + //no HO flag + ); + + +/// Utilities------------------------------------------------ + +void rrc_eNB_free_UE_NB_IoT( + const module_id_t enb_mod_idP, + const struct rrc_eNB_ue_context_NB_IoT_s* const ue_context_pP + ); + +void rrc_eNB_free_mem_UE_context_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + struct rrc_eNB_ue_context_NB_IoT_s* const ue_context_pP +); + + + +/**\brief Function to get the next transaction identifier. + \param module_idP Instance ID for CH/eNB + \return a transaction identifier*/ +uint8_t rrc_eNB_get_next_transaction_identifier_NB_IoT(module_id_t module_idP); + + +int rrc_init_global_param_NB_IoT(void); + +//L2_interface.c +int8_t mac_rrc_data_req_eNB_NB_IoT( + const module_id_t Mod_idP, + const int CC_id, + const frame_t frameP, + const frame_t h_frameP, + const sub_frame_t subframeP, //need for the case in which both SIB1-NB_IoT and SIB23-NB_IoT will be scheduled in the same frame + const rb_id_t Srb_id, + uint8_t* const buffer_pP, + uint8_t flag +); + + + diff --git a/openair2/RRC/LITE/rrc_types_NB_IoT.h b/openair2/RRC/LITE/rrc_types_NB_IoT.h new file mode 100644 index 0000000000..55e98ea5f1 --- /dev/null +++ b/openair2/RRC/LITE/rrc_types_NB_IoT.h @@ -0,0 +1,64 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file rrc_types.h +* \brief rrc types and subtypes +* \author Navid Nikaein and Raymond Knopp +* \date 2011 - 2014 +* \version 1.0 +* \company Eurecom +* \email: navid.nikaein@eurecom.fr, raymond.knopp@eurecom.fr +*/ + +#ifndef RRC_TYPES_NB_IOT_H_ +#define RRC_TYPES_NB_IOT_H_ + +typedef enum Rrc_State_NB_IoT_e { + RRC_STATE_INACTIVE_NB_IoT=0, + RRC_STATE_IDLE_NB_IoT, + RRC_STATE_CONNECTED_NB_IoT, + + RRC_STATE_FIRST_NB_IoT = RRC_STATE_INACTIVE_NB_IoT, + RRC_STATE_LAST_NB_IoT = RRC_STATE_CONNECTED_NB_IoT, +} Rrc_State_NB_IoT_t; + +typedef enum Rrc_Sub_State_NB_IoT_e { + RRC_SUB_STATE_INACTIVE_NB_IoT=0, + + RRC_SUB_STATE_IDLE_SEARCHING_NB_IoT, + RRC_SUB_STATE_IDLE_RECEIVING_SIB_NB_IoT, + RRC_SUB_STATE_IDLE_SIB_COMPLETE_NB_IoT, + RRC_SUB_STATE_IDLE_CONNECTING_NB_IoT, + RRC_SUB_STATE_IDLE_NB_IoT, + + RRC_SUB_STATE_CONNECTED_NB_IoT, + + RRC_SUB_STATE_INACTIVE_FIRST_NB_IoT = RRC_SUB_STATE_INACTIVE_NB_IoT, + RRC_SUB_STATE_INACTIVE_LAST_NB_IoT = RRC_SUB_STATE_INACTIVE_NB_IoT, + + RRC_SUB_STATE_IDLE_FIRST_NB_IoT = RRC_SUB_STATE_IDLE_SEARCHING_NB_IoT, + RRC_SUB_STATE_IDLE_LAST_NB_IoT = RRC_SUB_STATE_IDLE_NB_IoT, + + RRC_SUB_STATE_CONNECTED_FIRST_NB_IoT = RRC_SUB_STATE_CONNECTED_NB_IoT, + RRC_SUB_STATE_CONNECTED_LAST_NB_IoT = RRC_SUB_STATE_CONNECTED_NB_IoT, +} Rrc_Sub_State_NB_IoT_t; + +#endif /* RRC_TYPES_H_ */ diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c index a2517e07b8..7f63e8c1ce 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB.c +++ b/openair3/GTPV1-U/gtpv1u_eNB.c @@ -53,6 +53,7 @@ #undef GTP_DUMP_SOCKET +/* extern boolean_t pdcp_data_req( const protocol_ctxt_t* const ctxt_pP, const srb_flag_t srb_flagP, @@ -62,7 +63,7 @@ extern boolean_t pdcp_data_req( const sdu_size_t sdu_buffer_sizeP, unsigned char *const sdu_buffer_pP, const pdcp_transmission_mode_t modeP); - +*/ extern unsigned char NB_eNB_INST; extern RAN_CONTEXT_t RC; diff --git a/targets/COMMON/openairinterface5g_limits.h b/targets/COMMON/openairinterface5g_limits.h index 63f5b96c33..98de4a024f 100644 --- a/targets/COMMON/openairinterface5g_limits.h +++ b/targets/COMMON/openairinterface5g_limits.h @@ -11,7 +11,6 @@ # define NUMBER_OF_RU_MAX 32 # define NUMBER_OF_UE_MAX 20 # define NUMBER_OF_CONNECTED_eNB_MAX 3 - # if defined(STANDALONE) && STANDALONE==1 # undef NUMBER_OF_eNB_MAX # undef NUMBER_OF_UE_MAX diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 71ee86ecf1..6b52bab64c 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -100,7 +100,7 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "stats.h" #endif #include "lte-softmodem.h" - +#include "NB_IoT_interface.h" #ifdef XFORMS // current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0) // at eNB 0, an UL scope for every UE @@ -560,6 +560,14 @@ static void get_options(void) { NB_eNB_INST = RC.nb_inst; NB_RU = RC.nb_RU; printf("Configuration: nb_rrc_inst %d, nb_L1_inst %d, nb_ru %d\n",NB_eNB_INST,RC.nb_L1_inst,NB_RU); + if (nonbiotflag <= 0) { + load_NB_IoT(); + printf(" nb_nbiot_rrc_inst %d, nb_nbiot_L1_inst %d, nb_nbiot_macrlc_inst %d\n", + RC.nb_nb_iot_rrc_inst, RC.nb_nb_iot_L1_inst, RC.nb_nb_iot_macrlc_inst); + } else { + printf("All Nb-IoT instances disabled\n"); + RC.nb_nb_iot_rrc_inst=RC.nb_nb_iot_L1_inst=RC.nb_nb_iot_macrlc_inst=0; + } } } From 71e7f9713a9d410a249ad3097caa53128e1dc2d3 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 9 Mar 2018 10:11:24 +0100 Subject: [PATCH 180/195] hack: try to avoid "buffer full" problem when pushing DL traffic This is hack-level development. With this commit you can do UDP DL traffic of say 100Mb/s over a 5MHz link with one connected UE and the eNB should not crash because of memory exhaustion. Of course on the receiver side you won't get 100Mb/s and many many lost packets. But the system should not crash. 1Gb/s does not work. So in any case try to remain within some reasonable limits. There is no reason to push more than twice the maximum achievable throughput of the link. This work is based on a patch proposed by Francesco Gringoli. --- common/utils/itti/intertask_interface.c | 97 +++++++++++++++++++++++++ common/utils/itti/intertask_interface.h | 12 +++ openair2/LAYER2/RLC/rlc.c | 9 +++ openair3/UDP/udp_eNB_task.c | 13 +++- 4 files changed, 130 insertions(+), 1 deletion(-) diff --git a/common/utils/itti/intertask_interface.c b/common/utils/itti/intertask_interface.c index 554f50a2a1..85b5fef509 100644 --- a/common/utils/itti/intertask_interface.c +++ b/common/utils/itti/intertask_interface.c @@ -391,6 +391,103 @@ int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, Me return 0; } +/* same as itti_send_msg_to_task but returns -1 in case of failure instead of crashing */ +/* TODO: this is a hack - the whole logic needs a proper rework. */ +/* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */ +int itti_try_send_msg_to_task(task_id_t destination_task_id, instance_t instance, MessageDef *message) +{ + thread_id_t destination_thread_id; + task_id_t origin_task_id; + message_list_t *new; + uint32_t priority; + message_number_t message_number; + uint32_t message_id; + + AssertFatal (message != NULL, "Message is NULL!\n"); + AssertFatal (destination_task_id < itti_desc.task_max, "Destination task id (%d) is out of range (%d)\n", destination_task_id, itti_desc.task_max); + + destination_thread_id = TASK_GET_THREAD_ID(destination_task_id); + message->ittiMsgHeader.destinationTaskId = destination_task_id; + message->ittiMsgHeader.instance = instance; + message->ittiMsgHeader.lte_time.frame = itti_desc.lte_time.frame; + message->ittiMsgHeader.lte_time.slot = itti_desc.lte_time.slot; + message_id = message->ittiMsgHeader.messageId; + AssertFatal (message_id < itti_desc.messages_id_max, "Message id (%d) is out of range (%d)!\n", message_id, itti_desc.messages_id_max); + + origin_task_id = ITTI_MSG_ORIGIN_ID(message); + + priority = itti_get_message_priority (message_id); + + /* Increment the global message number */ + message_number = itti_increment_message_number (); + + itti_dump_queue_message (origin_task_id, message_number, message, itti_desc.messages_info[message_id].name, + sizeof(MessageHeader) + message->ittiMsgHeader.ittiMsgSize); + + if (destination_task_id != TASK_UNKNOWN) { + + if (itti_desc.threads[destination_thread_id].task_state == TASK_STATE_ENDED) { + ITTI_DEBUG(ITTI_DEBUG_ISSUES, " Message %s, number %lu with priority %d can not be sent from %s to queue (%u:%s), ended destination task!\n", + itti_desc.messages_info[message_id].name, + message_number, + priority, + itti_get_task_name(origin_task_id), + destination_task_id, + itti_get_task_name(destination_task_id)); + } else { + /* We cannot send a message if the task is not running */ + AssertFatal (itti_desc.threads[destination_thread_id].task_state == TASK_STATE_READY, + "Task %s Cannot send message %s (%d) to thread %d, it is not in ready state (%d)!\n", + itti_get_task_name(origin_task_id), + itti_desc.messages_info[message_id].name, + message_id, + destination_thread_id, + itti_desc.threads[destination_thread_id].task_state); + + /* Allocate new list element */ + new = (message_list_t *) itti_malloc (origin_task_id, destination_task_id, sizeof(struct message_list_s)); + + /* Fill in members */ + new->msg = message; + new->message_number = message_number; + new->message_priority = priority; + + /* Enqueue message in destination task queue */ + if (lfds611_queue_enqueue(itti_desc.tasks[destination_task_id].message_queue, new) == 0) { + itti_free(origin_task_id, new); + return -1; + } + + { + /* Only use event fd for tasks, subtasks will pool the queue */ + if (TASK_GET_PARENT_TASK_ID(destination_task_id) == TASK_UNKNOWN) { + ssize_t write_ret; + eventfd_t sem_counter = 1; + + /* Call to write for an event fd must be of 8 bytes */ + write_ret = write (itti_desc.threads[destination_thread_id].task_event_fd, &sem_counter, sizeof(sem_counter)); + AssertFatal (write_ret == sizeof(sem_counter), "Write to task message FD (%d) failed (%d/%d)\n", + destination_thread_id, (int) write_ret, (int) sizeof(sem_counter)); + } + } + + ITTI_DEBUG(ITTI_DEBUG_SEND, " Message %s, number %lu with priority %d successfully sent from %s to queue (%u:%s)\n", + itti_desc.messages_info[message_id].name, + message_number, + priority, + itti_get_task_name(origin_task_id), + destination_task_id, + itti_get_task_name(destination_task_id)); + } + } else { + /* This is a debug message to TASK_UNKNOWN, we can release safely release it */ + int result = itti_free(origin_task_id, message); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + } + + return 0; +} + void itti_subscribe_event_fd(task_id_t task_id, int fd) { thread_id_t thread_id; diff --git a/common/utils/itti/intertask_interface.h b/common/utils/itti/intertask_interface.h index 606c851d1d..ada34ce1b7 100644 --- a/common/utils/itti/intertask_interface.h +++ b/common/utils/itti/intertask_interface.h @@ -108,6 +108,18 @@ int itti_send_broadcast_message(MessageDef *message_p); **/ int itti_send_msg_to_task(task_id_t task_id, instance_t instance, MessageDef *message); +/* TODO: this is a hack. Almost no caller of itti_send_msg_to_task checks + * the return value so it has been changed to crash the program in case + * of failure instead of returning -1 as the documentation above says. + * The RLC UM code may receive too much data when doing UDP at a higher + * throughput than the link allows and so for this specific case we need + * a version that actually returns -1 on failure. + * + * This needs to be cleaned at some point. + */ +/* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */ +int itti_try_send_msg_to_task(task_id_t task_id, instance_t instance, MessageDef *message); + /** \brief Add a new fd to monitor. * NOTE: it is up to the user to read data associated with the fd * \param task_id Task ID of the receiving task diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c index d27d46ff42..783441bd58 100644 --- a/openair2/LAYER2/RLC/rlc.c +++ b/openair2/LAYER2/RLC/rlc.c @@ -437,6 +437,15 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, break; case RLC_MODE_UM: + /* TODO: this is a hack, needs better solution. Let's not use too + * much memory and store at maximum 5 millions bytes. + */ + /* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */ + if (rlc_um_get_buffer_occupancy(&rlc_union_p->rlc.um) > 5000000) { + free_mem_block(sdu_pP, __func__); + return RLC_OP_STATUS_OUT_OF_RESSOURCES; + } + new_sdu_p = get_free_mem_block (sdu_sizeP + sizeof (struct rlc_um_data_req_alloc), __func__); if (new_sdu_p != NULL) { diff --git a/openair3/UDP/udp_eNB_task.c b/openair3/UDP/udp_eNB_task.c index 527715eb7a..4d6bd6e033 100644 --- a/openair3/UDP/udp_eNB_task.c +++ b/openair3/UDP/udp_eNB_task.c @@ -270,10 +270,21 @@ void udp_eNB_receiver(struct udp_socket_desc_s *udp_sock_pP) n, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); #endif - if (itti_send_msg_to_task(udp_sock_pP->task_id, INSTANCE_DEFAULT, message_p) < 0) { + /* TODO: this is a hack. Let's accept failures and do nothing when + * it happens. Since itti_send_msg_to_task crashes when the message + * queue is full we wrote itti_try_send_msg_to_task that returns -1 + * if the queue is full. + */ + /* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */ + //if (itti_send_msg_to_task(udp_sock_pP->task_id, INSTANCE_DEFAULT, message_p) < 0) { + if (itti_try_send_msg_to_task(udp_sock_pP->task_id, INSTANCE_DEFAULT, message_p) < 0) { +#if 0 LOG_I(UDP_, "Failed to send message %d to task %d\n", UDP_DATA_IND, udp_sock_pP->task_id); +#endif + itti_free(TASK_UDP, message_p); + itti_free(TASK_UDP, forwarded_buffer); return; } } From 92bb82eb2b25bba91f5df88176ffb2534e38f199 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 9 Mar 2018 16:40:09 +0100 Subject: [PATCH 181/195] integration fix: fix license version to 1.1 --- common/config/config_cmdline.c | 2 +- common/config/config_load_configmodule.c | 2 +- common/config/libconfig/config_libconfig.h | 2 +- common/config/libconfig/config_libconfig_private.h | 2 +- common/ran_context.h | 2 +- common/utils/load_module_shlib.c | 2 +- common/utils/load_module_shlib.h | 2 +- common/utils/telnetsrv/telnetsrv_phycmd.c | 2 +- common/utils/telnetsrv/telnetsrv_phycmd.h | 2 +- openair1/PHY/CODING/coding_load.c | 2 +- openair1/PHY/CODING/defs_NB_IoT.h | 2 +- openair1/PHY/INIT/defs_NB_IoT.h | 2 +- openair1/PHY/LTE_TRANSPORT/dci_NB_IoT.h | 2 +- openair1/PHY/LTE_TRANSPORT/edci.c | 2 +- openair1/PHY/LTE_TRANSPORT/mdci.h | 2 +- openair1/PHY/LTE_TRANSPORT/proto_NB_IoT.h | 2 +- openair1/PHY/LTE_TRANSPORT/uci_NB_IoT.h | 2 +- openair1/PHY/defs_L1_NB_IoT.h | 2 +- openair1/PHY/impl_defs_lte_NB_IoT.h | 2 +- openair1/PHY/impl_defs_top_NB_IoT.h | 2 +- openair1/PHY/types_NB_IoT.h | 2 +- openair1/SCHED/fapi_l1.c | 2 +- openair1/SCHED/fapi_l1.h | 2 +- openair1/SCHED/ru_procedures.c | 2 +- openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c | 2 +- openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h | 2 +- openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp_defs.h | 2 +- openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c | 2 +- openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h | 2 +- openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h | 2 +- openair2/ENB_APP/L1_paramdef.h | 2 +- openair2/ENB_APP/MACRLC_paramdef.h | 2 +- openair2/ENB_APP/NB_IoT_paramdef.h | 2 +- openair2/ENB_APP/RRC_paramsvalues.h | 2 +- openair2/ENB_APP/enb_paramdef.h | 2 +- openair2/ENB_APP/flexran_agent_ran_api.c | 2 +- openair2/ENB_APP/flexran_agent_ran_api.h | 2 +- openair2/ENB_APP/flexran_agent_timer.c | 2 +- openair2/ENB_APP/flexran_agent_timer.h | 2 +- openair2/LAYER2/MAC/proto_NB_IoT.h | 2 +- openair2/PHY_INTERFACE/IF_Module.h | 2 +- openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.c | 2 +- openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.h | 2 +- openair2/RRC/LITE/defs_NB_IoT.h | 2 +- openair2/RRC/LITE/extern_NB_IoT.h | 2 +- openair2/RRC/LITE/proto_NB_IoT.h | 2 +- openair2/RRC/LITE/rrc_types_NB_IoT.h | 2 +- 47 files changed, 47 insertions(+), 47 deletions(-) diff --git a/common/config/config_cmdline.c b/common/config/config_cmdline.c index cb24cc5222..040cd92faf 100644 --- a/common/config/config_cmdline.c +++ b/common/config/config_cmdline.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/common/config/config_load_configmodule.c b/common/config/config_load_configmodule.c index c31a2da4d7..7860742804 100644 --- a/common/config/config_load_configmodule.c +++ b/common/config/config_load_configmodule.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/common/config/libconfig/config_libconfig.h b/common/config/libconfig/config_libconfig.h index 8013d602cf..f541584185 100644 --- a/common/config/libconfig/config_libconfig.h +++ b/common/config/libconfig/config_libconfig.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/common/config/libconfig/config_libconfig_private.h b/common/config/libconfig/config_libconfig_private.h index 022e0e6330..fb126ff7cb 100644 --- a/common/config/libconfig/config_libconfig_private.h +++ b/common/config/libconfig/config_libconfig_private.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/common/ran_context.h b/common/ran_context.h index 18b309d268..4380dc65f1 100644 --- a/common/ran_context.h +++ b/common/ran_context.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/common/utils/load_module_shlib.c b/common/utils/load_module_shlib.c index c07b54f54a..fecdc2a58c 100644 --- a/common/utils/load_module_shlib.c +++ b/common/utils/load_module_shlib.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/common/utils/load_module_shlib.h b/common/utils/load_module_shlib.h index 2653bdeba5..ffbad66570 100644 --- a/common/utils/load_module_shlib.h +++ b/common/utils/load_module_shlib.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/common/utils/telnetsrv/telnetsrv_phycmd.c b/common/utils/telnetsrv/telnetsrv_phycmd.c index a69efa234c..c60126f1c7 100644 --- a/common/utils/telnetsrv/telnetsrv_phycmd.c +++ b/common/utils/telnetsrv/telnetsrv_phycmd.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/common/utils/telnetsrv/telnetsrv_phycmd.h b/common/utils/telnetsrv/telnetsrv_phycmd.h index 50f1e81edc..6e2b0ecacf 100644 --- a/common/utils/telnetsrv/telnetsrv_phycmd.h +++ b/common/utils/telnetsrv/telnetsrv_phycmd.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair1/PHY/CODING/coding_load.c b/openair1/PHY/CODING/coding_load.c index 6e4670dd8e..31f71e6b31 100644 --- a/openair1/PHY/CODING/coding_load.c +++ b/openair1/PHY/CODING/coding_load.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair1/PHY/CODING/defs_NB_IoT.h b/openair1/PHY/CODING/defs_NB_IoT.h index 17670ec8bc..2a6bee7924 100644 --- a/openair1/PHY/CODING/defs_NB_IoT.h +++ b/openair1/PHY/CODING/defs_NB_IoT.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair1/PHY/INIT/defs_NB_IoT.h b/openair1/PHY/INIT/defs_NB_IoT.h index e8ead21780..8a83cbd038 100644 --- a/openair1/PHY/INIT/defs_NB_IoT.h +++ b/openair1/PHY/INIT/defs_NB_IoT.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair1/PHY/LTE_TRANSPORT/dci_NB_IoT.h b/openair1/PHY/LTE_TRANSPORT/dci_NB_IoT.h index ea84f66de4..60720e13b7 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_NB_IoT.h +++ b/openair1/PHY/LTE_TRANSPORT/dci_NB_IoT.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair1/PHY/LTE_TRANSPORT/edci.c b/openair1/PHY/LTE_TRANSPORT/edci.c index 37b1c56349..5caf5bcd71 100755 --- a/openair1/PHY/LTE_TRANSPORT/edci.c +++ b/openair1/PHY/LTE_TRANSPORT/edci.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair1/PHY/LTE_TRANSPORT/mdci.h b/openair1/PHY/LTE_TRANSPORT/mdci.h index 1e278f8011..060227eac0 100644 --- a/openair1/PHY/LTE_TRANSPORT/mdci.h +++ b/openair1/PHY/LTE_TRANSPORT/mdci.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair1/PHY/LTE_TRANSPORT/proto_NB_IoT.h b/openair1/PHY/LTE_TRANSPORT/proto_NB_IoT.h index 9e3a55eacc..d8b17ff263 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto_NB_IoT.h +++ b/openair1/PHY/LTE_TRANSPORT/proto_NB_IoT.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair1/PHY/LTE_TRANSPORT/uci_NB_IoT.h b/openair1/PHY/LTE_TRANSPORT/uci_NB_IoT.h index b20635360d..6f2dd0f989 100644 --- a/openair1/PHY/LTE_TRANSPORT/uci_NB_IoT.h +++ b/openair1/PHY/LTE_TRANSPORT/uci_NB_IoT.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair1/PHY/defs_L1_NB_IoT.h b/openair1/PHY/defs_L1_NB_IoT.h index b9368b76e3..25ee646548 100644 --- a/openair1/PHY/defs_L1_NB_IoT.h +++ b/openair1/PHY/defs_L1_NB_IoT.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair1/PHY/impl_defs_lte_NB_IoT.h b/openair1/PHY/impl_defs_lte_NB_IoT.h index 7ae6f59c7e..1167323174 100644 --- a/openair1/PHY/impl_defs_lte_NB_IoT.h +++ b/openair1/PHY/impl_defs_lte_NB_IoT.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair1/PHY/impl_defs_top_NB_IoT.h b/openair1/PHY/impl_defs_top_NB_IoT.h index e512ec0215..f7e0c7ff7f 100644 --- a/openair1/PHY/impl_defs_top_NB_IoT.h +++ b/openair1/PHY/impl_defs_top_NB_IoT.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair1/PHY/types_NB_IoT.h b/openair1/PHY/types_NB_IoT.h index e8a6ea501e..6735092583 100644 --- a/openair1/PHY/types_NB_IoT.h +++ b/openair1/PHY/types_NB_IoT.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c index dbefe62747..df01fad136 100644 --- a/openair1/SCHED/fapi_l1.c +++ b/openair1/SCHED/fapi_l1.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair1/SCHED/fapi_l1.h b/openair1/SCHED/fapi_l1.h index 725bb31c45..f04e8581db 100644 --- a/openair1/SCHED/fapi_l1.h +++ b/openair1/SCHED/fapi_l1.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c index b00a9e2039..534023632c 100644 --- a/openair1/SCHED/ru_procedures.c +++ b/openair1/SCHED/ru_procedures.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c index 25ec919127..43455fa32a 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c +++ b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h index a962390c00..83aac45406 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h +++ b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp_defs.h b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp_defs.h index 46bdf744de..f2da72545a 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp_defs.h +++ b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp_defs.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c index e88c4eaccf..43951ee95a 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h index ae26b41621..780976893e 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h index cf20c477de..8c336abef1 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/ENB_APP/L1_paramdef.h b/openair2/ENB_APP/L1_paramdef.h index 8eef55b718..b062235ff6 100644 --- a/openair2/ENB_APP/L1_paramdef.h +++ b/openair2/ENB_APP/L1_paramdef.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/ENB_APP/MACRLC_paramdef.h b/openair2/ENB_APP/MACRLC_paramdef.h index 868917a0ab..4e732fe942 100644 --- a/openair2/ENB_APP/MACRLC_paramdef.h +++ b/openair2/ENB_APP/MACRLC_paramdef.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/ENB_APP/NB_IoT_paramdef.h b/openair2/ENB_APP/NB_IoT_paramdef.h index 615c96a7b6..6409fe63ee 100644 --- a/openair2/ENB_APP/NB_IoT_paramdef.h +++ b/openair2/ENB_APP/NB_IoT_paramdef.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/ENB_APP/RRC_paramsvalues.h b/openair2/ENB_APP/RRC_paramsvalues.h index fb375e1a09..06fee0e172 100644 --- a/openair2/ENB_APP/RRC_paramsvalues.h +++ b/openair2/ENB_APP/RRC_paramsvalues.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index d2634b3947..a8379c259f 100755 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index a65d352392..3200f55f16 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 0550722394..4e5f214af0 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/ENB_APP/flexran_agent_timer.c b/openair2/ENB_APP/flexran_agent_timer.c index f5436e4d01..dda3027353 100644 --- a/openair2/ENB_APP/flexran_agent_timer.c +++ b/openair2/ENB_APP/flexran_agent_timer.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/ENB_APP/flexran_agent_timer.h b/openair2/ENB_APP/flexran_agent_timer.h index 86e0d07825..98d83c78a9 100644 --- a/openair2/ENB_APP/flexran_agent_timer.h +++ b/openair2/ENB_APP/flexran_agent_timer.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/LAYER2/MAC/proto_NB_IoT.h b/openair2/LAYER2/MAC/proto_NB_IoT.h index e493275987..6e6d98eba1 100644 --- a/openair2/LAYER2/MAC/proto_NB_IoT.h +++ b/openair2/LAYER2/MAC/proto_NB_IoT.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/PHY_INTERFACE/IF_Module.h b/openair2/PHY_INTERFACE/IF_Module.h index 7baae6c3b6..3b1c88dda0 100644 --- a/openair2/PHY_INTERFACE/IF_Module.h +++ b/openair2/PHY_INTERFACE/IF_Module.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.c b/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.c index 866b2c1e91..80dcfd4053 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.c +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.c @@ -2,7 +2,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.h b/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.h index 67e0919307..e88bdadbd9 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.h +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/RRC/LITE/defs_NB_IoT.h b/openair2/RRC/LITE/defs_NB_IoT.h index 98b9148cd2..a5fdbb702e 100644 --- a/openair2/RRC/LITE/defs_NB_IoT.h +++ b/openair2/RRC/LITE/defs_NB_IoT.h @@ -2,7 +2,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/RRC/LITE/extern_NB_IoT.h b/openair2/RRC/LITE/extern_NB_IoT.h index 23e7329aec..39b49ecc03 100644 --- a/openair2/RRC/LITE/extern_NB_IoT.h +++ b/openair2/RRC/LITE/extern_NB_IoT.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/RRC/LITE/proto_NB_IoT.h b/openair2/RRC/LITE/proto_NB_IoT.h index b2f8e5b5c9..e346204912 100644 --- a/openair2/RRC/LITE/proto_NB_IoT.h +++ b/openair2/RRC/LITE/proto_NB_IoT.h @@ -2,7 +2,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/RRC/LITE/rrc_types_NB_IoT.h b/openair2/RRC/LITE/rrc_types_NB_IoT.h index 55e98ea5f1..0266572cd0 100644 --- a/openair2/RRC/LITE/rrc_types_NB_IoT.h +++ b/openair2/RRC/LITE/rrc_types_NB_IoT.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * From e7cfe377db29ef7cbeda1e8e8ef0a39ba1368035 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 9 Mar 2018 16:43:08 +0100 Subject: [PATCH 182/195] integration fix: fix file format (dos2unix) End of line character has to be unix-style, not dos-style. --- openair2/LAYER2/MAC/defs_NB_IoT.h | 1086 +++---- openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.c | 2834 +++++++++--------- openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.h | 586 ++-- openair2/RRC/LITE/defs_NB_IoT.h | 1140 +++---- openair2/RRC/LITE/extern_NB_IoT.h | 124 +- openair2/RRC/LITE/proto_NB_IoT.h | 520 ++-- 6 files changed, 3145 insertions(+), 3145 deletions(-) diff --git a/openair2/LAYER2/MAC/defs_NB_IoT.h b/openair2/LAYER2/MAC/defs_NB_IoT.h index a427de5b2c..77c0828b28 100644 --- a/openair2/LAYER2/MAC/defs_NB_IoT.h +++ b/openair2/LAYER2/MAC/defs_NB_IoT.h @@ -1,543 +1,543 @@ - -/*! \file defs_NB_IoT.c - * \brief MAC layer structures - * \author NTUST BMW Lab./ - * \date 2017 - * \email: - * \version 1.0 - * - */ -#ifndef __LAYER2_MAC_DEFS_NB_IOT_H__ -#define __LAYER2_MAC_DEFS_NB_IOT_H__ -#ifdef USER_MODE -#include -#include -#include -#endif -//#include "COMMON/openair_defs.h" -#include "COMMON/platform_constants.h" -#include "COMMON/mac_rrc_primitives.h" -#include "PHY/LTE_TRANSPORT/defs_NB_IoT.h" -//#include "PHY/defs.h" -#include "PHY/defs_L1_NB_IoT.h" -#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h" -#include "config_NB_IoT.h" -// MAC definition -#define MAX_FRAME 0xfffff -#define NUM_FRAME 0x100000 -#define MAX_SUBFRAME 10485760 - -#define MAX(a, b) (((a)>(b))?(a):(b)) - -// RA-RNTI: 1+SFN_id>>2 -#define RA_RNTI_LOW 0x0001 // SFN_id = 0 -#define RA_RNTI_HIGH 0x0100 // SFN_id = 1023 -#define C_RNTI_LOW 0x0101 -#define C_RNTI_HIGH - -// ULSCH LCHAN IDs -/*!\brief LCID of extended power headroom for ULSCH */ -#define EXTENDED_POWER_HEADROOM 25 -/*!\brief LCID of power headroom for ULSCH */ -#define POWER_HEADROOM 26 -/*!\brief LCID of CRNTI for ULSCH */ -#define CRNTI 27 -/*!\brief LCID of truncated BSR for ULSCH */ -#define TRUNCATED_BSR 28 -/*!\brief LCID of short BSR for ULSCH */ -#define SHORT_BSR 29 -/*!\brief LCID of long BSR for ULSCH */ -#define LONG_BSR 30 -/*! \brief Values of CCCH LCID for DLSCH */ -#define CCCH_LCHANID 0 -/*!\brief Values of BCCH logical channel */ -#define BCCH 3 // SI -/*!\brief Values of PCCH logical channel */ -#define PCCH 4 // Paging -/*!\brief Value of CCCH / SRB0 logical channel */ -#define CCCH 0 // srb0 -/*!\brief DCCH / SRB1 logical channel */ -#define DCCH 1 // srb1 -/*!\brief DCCH1 / SRB2 logical channel */ -#define DCCH1 2 // srb2 -/*!\brief DTCH DRB1 logical channel */ -#define DTCH 3 // LCID -/*!\brief MCCH logical channel */ -#define MCCH 4 -/*!\brief MTCH logical channel */ -#define MTCH 1 -// DLSCH LCHAN ID -/*!\brief LCID of UE contention resolution identity for DLSCH*/ -#define UE_CONT_RES 28 -/*!\brief LCID of timing advance for DLSCH */ -#define TIMING_ADV_CMD 29 -/*!\brief LCID of discontinous reception mode for DLSCH */ -#define DRX_CMD 30 -/*!\brief LCID of padding LCID for DLSCH */ -#define SHORT_PADDING 31 - - -typedef enum tone_type_e -{ - sixtone = 0, - threetone, - singletone1, - singletone2, - singletone3 -}tone_type_t; - -typedef enum channel_NB_IoT_e -{ - NPDCCH = 0, - NPUSCH, - NPDSCH -}channel_NB_IoT_t; - -typedef enum{ - UL = 0, - DL -}message_direction_t; - -#define MAX_NUMBER_OF_UE_MAX_NB_IoT 20 -#define SCH_PAYLOAD_SIZE_MAX_NB_IoT 320 -#define MAX_NUMBER_OF_SIBs_NB_IoT 16 - -/*!\brief Values of BCCH0 logical channel for MIB*/ -#define BCCH0_NB_IoT 11 // MIB-NB_IoT -/*!\brief Values of BCCH1 logical channel for SIBs */ -#define BCCH1_NB_IoT 12 // SI-SIB-NB_IoTs -/*!\brief Values of PCCH logical channel */ -#define PCCH_NB_IoT 13 // Paging XXX not used for the moment -#define MCCH_NB_IoT 14 -/*!\brief Value of CCCH / SRB0 logical channel */ -#define CCCH_NB_IoT 0 // srb0 ---> XXX exactly the same as in LTE (commented for compilation purposes) -/*!\brief DCCH0 / SRB1bis logical channel */ -#define DCCH0_NB_IoT 3 // srb1bis -/*!\brief DCCH1 / SRB1 logical channel */ -#define DCCH1_NB_IoT 1 // srb1 //XXX we redefine it for the SRB1 -/*!\brief DTCH0 DRB0 logical channel */ -#define DTCH0_NB_IoT 4 // DRB0 -/*!\brief DTCH1 DRB1 logical channel */ -#define DTCH1_NB_IoT 5 // DRB1 -/*Index of UE contention resoulution logical channel*/ -#define UE_CONTENTION_RESOLUTION 28 -/*Index of TIMING_ADVANCE logical channel*/ -#define TIMING_ADVANCE 29 -/*Index of DRX_COMMAND logical channel*/ -#define DRX_COMMAND 30 -/*Index of PADDING logical channel*/ -#define PADDING 31 - - -/// NPRACH-ParametersList-NB_IoT-r13 from 36.331 RRC spec defined in PHY -/*typedef struct NPRACH_Parameters_NB_IoT{ - - /// the period time for nprach - int nprach_Periodicity; - /// for the start time for the NPRACH resource from 40ms-2560ms - int nprach_StartTime; - /// for the subcarrier of set to the NPRACH preamble from n0 - n34 - int nprach_SubcarrierOffset; - ///number of subcarriers in a NPRACH resource allowed values (n12,n24,n36,n48) - int nprach_NumSubcarriers; - /// where is the region that in NPRACH resource to indicate if this UE support MSG3 for multi-tone or not. from 0 - 1 - int nprach_SubcarrierMSG3_RangeStart; - /// The max preamble transmission attempt for the CE level from 1 - 128 - int maxNumPreambleAttemptCE; - /// Number of NPRACH repetitions per attempt for each NPRACH resource - int numRepetitionsPerPreambleAttempt; - /// The number of the repetition for DCI use in RAR/MSG3/MSG4 from 1 - 2048 (Rmax) - int npdcch_NumRepetitions_RA; - /// Starting subframe for NPDCCH Common searching space for (RAR/MSG3/MSG4) - int npdcch_StartSF_CSS_RA; - /// Fractional period offset of starting subframe for NPDCCH common search space - int npdcch_Offset_RA; - -} nprach_parameters_NB_IoT_t;*/ - -/*! \brief Downlink SCH PDU Structure */ -typedef struct { - uint8_t payload[SCH_PAYLOAD_SIZE_MAX_NB_IoT]; - uint32_t pdu_size; -} __attribute__ ((__packed__)) DLSCH_PDU_NB_IoT; - -/*! \brief eNB template for UE context information */ -typedef struct { - // C-RNTI of UE - rnti_t rnti; - // UE CE level - int CE_level; - // Direction of transmission(DL:0\UL:1\NONE:-1) - int32_t direction; - // DCI Reptition - uint32_t R_dci; - // MAX repetition - uint32_t R_max; - - // HARQ round - uint32_t HARQ_round; - /*Downlink information*/ - - /// DLSCH pdu - DLSCH_PDU_NB_IoT DLSCH_pdu; - // PDU size - uint32_t DLSCH_pdu_size; - // Data Reptition - uint32_t R_dl; - // MCS index - uint32_t I_mcs_dl; - // total downlink buffer DCCH0_NB_IoT - uint32_t dl_buffer_DCCH0_NB_IoT; - // NDI - int oldNDI_DL; - //HARQ ACK/NACK repetition - uint32_t R_harq; - - /*Uplink information*/ - int oldNDI_UL; - // Uplink data repeat, now just follow the rach repeat number - uint32_t R_ul; - // PHR value (0-3) - uint32_t PHR; - // The uplink data size from BSR or DVI - uint32_t ul_total_buffer; - // Determine if this UE support multi-tone transmission or not - int multi_tone; - // Next UE_template ID - int next; - // Previous UE_template ID - int prev; - // MSG4 complete - int RRC_connected; - // UE active flag - int active; - -} UE_TEMPLATE_NB_IoT; - -/*36331 NPDCCH-ConfigDedicated-NB_IoT*/ -typedef struct{ - //npdcch-NumRepetitions-r13 - uint32_t R_max; - //npdcch-StartSF-USS-r13 - double G; - //npdcch-Offset-USS-r13 - double a_offset; - //NPDCCH period - uint32_t T; - //Starting subfrane of Search Space which is mod T - uint32_t ss_start_uss; -}NPDCCH_config_dedicated_NB_IoT_t; - - -/*! \brief UE list used by eNB to order UEs/CC for scheduling*/ -typedef struct { - - /// DCI template and MAC connection parameters for UEs - UE_TEMPLATE_NB_IoT UE_template_NB_IoT[MAX_NUMBER_OF_UE_MAX_NB_IoT]; - - /// NPDCCH Period and searching space info - NPDCCH_config_dedicated_NB_IoT_t NPDCCH_config_dedicated; - //int next[MAX_NUMBER_OF_UE_MAX_NB_IoT]; - // -1:No UE in list - int head; - // -1:No UE in list - int tail; - int num_UEs; - //boolean_t active[MAX_NUMBER_OF_UE_MAX_NB_IoT]; - -} UE_list_NB_IoT_t; - - -typedef struct{ - - // flag to indicate scheduing MIB-NB_IoT - uint8_t flag_MIB; - // flag to indicate scheduling SIB1-NB_IoT - uint8_t flag_SIB1; - // flag to indicate scheduling SIBs-NB_IoT - uint8_t flag_SIBs[MAX_NUMBER_OF_SIBs_NB_IoT]; - // flag to indicate scheduling type2 NPDCCH CSS with different CE level - uint8_t flag_type2_css[3]; - // flag to indicate scheduling type1 NPDCCH CSS with different CE level - uint8_t flag_type1_css[3]; - // flag to indicate scheduling NPDCCH USS with UE list - uint8_t flag_uss[MAX_NUMBER_OF_UE_MAX_NB_IoT]; - // flag to indicate scheduling sib1/MIB - uint8_t flag_fix_scheduling; - // number of the type2 css to schedule in this period - uint8_t num_type2_css_run; - // number of the type1 css to schedule in this period - uint8_t num_type1_css_run; - // number of the uss to schedule in this period - uint8_t num_uss_run; - -}scheduling_flag_t; - -typedef struct available_resource_UL_s{ - - ///Resource start subframe - uint32_t start_subframe; - ///Resource end subframe - uint32_t end_subframe; - // pointer to next node - struct available_resource_UL_s *next, *prev; - -}available_resource_UL_t; - -typedef struct available_resource_DL_s{ - uint32_t start_subframe; - uint32_t end_subframe; - - struct available_resource_DL_s *next, *prev; -}available_resource_DL_t; - -/*Structure used for scheduling*/ -typedef struct{ - //resource position info. - uint32_t sf_end,sf_start; - //resource position info. separate by HyperSF, Frame, Subframe - uint32_t start_h, end_h; - uint32_t start_f, end_f; - uint32_t start_sf, end_sf; - //whcih available resource node is used - available_resource_DL_t *node; -}sched_temp_DL_NB_IoT_t; - -/*!\brief MAC subheader short with 7bit Length field */ -typedef struct { - uint8_t LCID:5; // octet 1 LSB - uint8_t E:1; - uint8_t F2:1; - uint8_t R:1; // octet 1 MSB - uint8_t L:7; // octet 2 LSB - uint8_t F:1; // octet 2 MSB -} __attribute__((__packed__))SCH_SUBHEADER_SHORT_NB_IoT; -typedef struct { - uint8_t LCID:5; // octet 1 LSB - uint8_t E:1; - uint8_t F2:1; - uint8_t R:1; // octet 1 MSB - uint8_t L_MSB:7; - uint8_t F:1; // octet 2 MSB - uint8_t L_LSB:8; -} __attribute__((__packed__))SCH_SUBHEADER_LONG_NB_IoT; -typedef struct { - uint8_t LCID:5; // octet 1 LSB - uint8_t E:1; - uint8_t F2:1; - uint8_t R:1; // octet 1 MSB - uint8_t L_MSB:8; // octet 2 MSB - uint8_t L_LSB:8; -} __attribute__((__packed__))SCH_SUBHEADER_LONG_EXTEND_NB_IoT; -/*!\brief MAC subheader short without length field */ -typedef struct { - uint8_t LCID:5; - uint8_t F2:1; - uint8_t E:1; - uint8_t R:1; -} __attribute__((__packed__))SCH_SUBHEADER_FIXED_NB_IoT; - - -/*! \brief Uplink SCH PDU Structure */ -typedef struct { - int8_t payload[SCH_PAYLOAD_SIZE_MAX_NB_IoT]; /*!< \brief SACH payload */ - uint16_t Pdu_size; -} __attribute__ ((__packed__)) ULSCH_PDU_NB_IoT; - -typedef struct { - uint8_t PH:6; - uint8_t R:2; -} __attribute__((__packed__))POWER_HEADROOM_CMD_NB_IoT; - -typedef struct { - uint8_t RAPID:6; - uint8_t T:1; - uint8_t E:1; -} __attribute__((__packed__))RA_HEADER_RAPID_NB_IoT; - -/*Structure used for UL scheduling*/ -typedef struct{ - //resource position info. - uint32_t sf_end, sf_start; - //resource position info. separate by HyperSF, Frame, Subframe - //uint32_t start_h, end_h; - //uint32_t start_f, end_f; - //uint32_t start_sf, end_sf; - // information for allocating the resource - int tone; - int scheduling_delay; - int subcarrier_indication; - int ACK_NACK_resource_field; - available_resource_UL_t *node; -}sched_temp_UL_NB_IoT_t; - -typedef struct Available_available_resource_DL{ - - ///Available Resoruce for sixtone - available_resource_UL_t *sixtone_Head;//, *sixtone_npusch_frame; - uint32_t sixtone_end_subframe; - ///Available Resoruce for threetone - available_resource_UL_t *threetone_Head;//, *threetone_npusch_frame; - uint32_t threetone_end_subframe; - ///Available Resoruce for singletone1 - available_resource_UL_t *singletone1_Head;//, *singletone1_npusch_frame; - uint32_t singletone1_end_subframe; - ///Available Resoruce for singletone2 - available_resource_UL_t *singletone2_Head;//, *singletone2_npusch_frame; - uint32_t singletone2_end_subframe; - ///Available Resoruce for singletone3 - available_resource_UL_t *singletone3_Head;//, *singletone3_npusch_frame; - uint32_t singletone3_end_subframe; - -}available_resource_tones_UL_t; - -typedef struct schedule_result{ - // The subframe read by output handler - uint32_t output_subframe; - // SDU length - uint32_t sdu_length; - // MAC PDU - uint8_t *DLSCH_pdu; - // The data direction indicated by this DCI - uint8_t direction; - // pointer to DCI - void *DCI_pdu; - // when all the procedure related to this DCI, enable this flag - boolean_t DCI_release; - // Indicate the channel which to transmit - channel_NB_IoT_t channel; - // rnti - rnti_t rnti; - // 0 = TC-RNTI , 1 = RA-RNTI, 2 = P-RNTI, 3 = others - uint8_t rnti_type; - // 0 = data, 1 = ACK/NACK - uint8_t npusch_format; - //HARQ ACK/NACK repetition - uint32_t R_harq; - // pointer to next node - struct schedule_result *next; - - uint32_t end_subframe; - - uint8_t *rar_buffer; - -}schedule_result_t; - -/*Flag structure used for trigger each scheduler*/ -typedef struct{ - scheduling_flag_t scheduling_flag; - //sched_temp_DL_NB_IoT_t sched_result_DL; - //resource grid for Uplink - available_resource_tones_UL_t *UL_resource; - //scheduling result read by output handler - schedule_result_t *schedule_result_list_UL; - schedule_result_t *schedule_result_list_DL; -}SCHEDULE_NB_IoT_t; - -typedef struct{ - uint32_t num_dlsf_per_period; - uint16_t *sf_to_dlsf_table; - uint16_t *dlsf_to_sf_table; -}DLSF_INFO_t; - -typedef enum ce_level_e{ - ce0=0, - ce1, - ce2, - ce_level_total -}ce_level_t; - - - -/*! \brief eNB template for the Random access information */ -typedef struct RA_TEMPLATE_NB_IoT_s{ - - boolean_t active; - uint32_t msg3_retransmit_count; - uint32_t msg4_retransmit_count; - uint16_t ta; - uint8_t preamble_index; - ce_level_t ce_level; - rnti_t ue_rnti; - rnti_t ra_rnti; - struct RA_TEMPLATE_NB_IoT_s *next, *prev; - boolean_t wait_msg4_ack; - boolean_t wait_msg3_ack; - uint8_t rar_buffer[7]; - -} RA_TEMPLATE_NB_IoT; - -typedef struct RA_template_list_s{ - RA_TEMPLATE_NB_IoT *head; - RA_TEMPLATE_NB_IoT *tail; -}RA_template_list_t; - - -/*! \brief top level eNB MAC structure */ -typedef struct eNB_MAC_INST_NB_IoT_s { - /// Ethernet parameters for northbound midhaul interface - eth_params_t eth_params_n; - /// Ethernet parameters for fronthaul interface - eth_params_t eth_params_s; - - uint8_t Mod_id; - // System - uint32_t hyper_system_frame; - uint32_t system_frame; - uint32_t sub_frame; - - uint32_t current_subframe; - /// Pointer to IF module instance for PHY - IF_Module_t *if_inst; - // RA - RA_template_list_t RA_msg2_list; - RA_template_list_t RA_msg3_list; - RA_template_list_t RA_msg4_list; - - RA_TEMPLATE_NB_IoT RA_template[MAX_NUMBER_OF_UE_MAX_NB_IoT]; - - //int32_t last_tx_subframe; - - // for tool - int32_t sib1_flag[64]; - int32_t sib1_count[64]; - int32_t sib1_period; - uint16_t dlsf_table[64]; - int32_t sibs_table[256]; - - // channel config - - //USS list - //Number of USS period is used - int num_uss_list; - UE_list_NB_IoT_t *UE_list_spec; - - scheduling_flag_t scheduling_flag; - - uint32_t schedule_subframe_DL; - uint32_t schedule_subframe_UL; - - rrc_config_NB_IoT_t rrc_config; - - nfapi_config_request_t config; - - IF_Module_NB_IoT_t *if_inst_NB_IoT; -} eNB_MAC_INST_NB_IoT; - -// actually not here, but for now put it here -typedef struct { - uint32_t bytes_in_buffer; /*!< \brief Bytes buffered in RLC protocol instance. */ - uint32_t pdus_in_buffer; /*!< \brief Number of PDUs buffered in RLC protocol instance (OBSOLETE). */ - uint32_t head_sdu_creation_time; /*!< \brief Head SDU creation time. */ - uint32_t head_sdu_remaining_size_to_send; /*!< \brief remaining size of sdu: could be the total size or the remaining size of already segmented sdu */ - boolean_t head_sdu_is_segmented; /*!< \brief 0 if head SDU has not been segmented, 1 if already segmented */ -} mac_rlc_status_resp_NB_IoT_t; - -// global variables - -nprach_parameters_NB_IoT_t nprach_list[3]; - -//DLSF Table -DLSF_INFO_t DLSF_information; - -#endif /*__LAYER2_MAC_DEFS_NB_IoT_H__ */ + +/*! \file defs_NB_IoT.c + * \brief MAC layer structures + * \author NTUST BMW Lab./ + * \date 2017 + * \email: + * \version 1.0 + * + */ +#ifndef __LAYER2_MAC_DEFS_NB_IOT_H__ +#define __LAYER2_MAC_DEFS_NB_IOT_H__ +#ifdef USER_MODE +#include +#include +#include +#endif +//#include "COMMON/openair_defs.h" +#include "COMMON/platform_constants.h" +#include "COMMON/mac_rrc_primitives.h" +#include "PHY/LTE_TRANSPORT/defs_NB_IoT.h" +//#include "PHY/defs.h" +#include "PHY/defs_L1_NB_IoT.h" +#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h" +#include "config_NB_IoT.h" +// MAC definition +#define MAX_FRAME 0xfffff +#define NUM_FRAME 0x100000 +#define MAX_SUBFRAME 10485760 + +#define MAX(a, b) (((a)>(b))?(a):(b)) + +// RA-RNTI: 1+SFN_id>>2 +#define RA_RNTI_LOW 0x0001 // SFN_id = 0 +#define RA_RNTI_HIGH 0x0100 // SFN_id = 1023 +#define C_RNTI_LOW 0x0101 +#define C_RNTI_HIGH + +// ULSCH LCHAN IDs +/*!\brief LCID of extended power headroom for ULSCH */ +#define EXTENDED_POWER_HEADROOM 25 +/*!\brief LCID of power headroom for ULSCH */ +#define POWER_HEADROOM 26 +/*!\brief LCID of CRNTI for ULSCH */ +#define CRNTI 27 +/*!\brief LCID of truncated BSR for ULSCH */ +#define TRUNCATED_BSR 28 +/*!\brief LCID of short BSR for ULSCH */ +#define SHORT_BSR 29 +/*!\brief LCID of long BSR for ULSCH */ +#define LONG_BSR 30 +/*! \brief Values of CCCH LCID for DLSCH */ +#define CCCH_LCHANID 0 +/*!\brief Values of BCCH logical channel */ +#define BCCH 3 // SI +/*!\brief Values of PCCH logical channel */ +#define PCCH 4 // Paging +/*!\brief Value of CCCH / SRB0 logical channel */ +#define CCCH 0 // srb0 +/*!\brief DCCH / SRB1 logical channel */ +#define DCCH 1 // srb1 +/*!\brief DCCH1 / SRB2 logical channel */ +#define DCCH1 2 // srb2 +/*!\brief DTCH DRB1 logical channel */ +#define DTCH 3 // LCID +/*!\brief MCCH logical channel */ +#define MCCH 4 +/*!\brief MTCH logical channel */ +#define MTCH 1 +// DLSCH LCHAN ID +/*!\brief LCID of UE contention resolution identity for DLSCH*/ +#define UE_CONT_RES 28 +/*!\brief LCID of timing advance for DLSCH */ +#define TIMING_ADV_CMD 29 +/*!\brief LCID of discontinous reception mode for DLSCH */ +#define DRX_CMD 30 +/*!\brief LCID of padding LCID for DLSCH */ +#define SHORT_PADDING 31 + + +typedef enum tone_type_e +{ + sixtone = 0, + threetone, + singletone1, + singletone2, + singletone3 +}tone_type_t; + +typedef enum channel_NB_IoT_e +{ + NPDCCH = 0, + NPUSCH, + NPDSCH +}channel_NB_IoT_t; + +typedef enum{ + UL = 0, + DL +}message_direction_t; + +#define MAX_NUMBER_OF_UE_MAX_NB_IoT 20 +#define SCH_PAYLOAD_SIZE_MAX_NB_IoT 320 +#define MAX_NUMBER_OF_SIBs_NB_IoT 16 + +/*!\brief Values of BCCH0 logical channel for MIB*/ +#define BCCH0_NB_IoT 11 // MIB-NB_IoT +/*!\brief Values of BCCH1 logical channel for SIBs */ +#define BCCH1_NB_IoT 12 // SI-SIB-NB_IoTs +/*!\brief Values of PCCH logical channel */ +#define PCCH_NB_IoT 13 // Paging XXX not used for the moment +#define MCCH_NB_IoT 14 +/*!\brief Value of CCCH / SRB0 logical channel */ +#define CCCH_NB_IoT 0 // srb0 ---> XXX exactly the same as in LTE (commented for compilation purposes) +/*!\brief DCCH0 / SRB1bis logical channel */ +#define DCCH0_NB_IoT 3 // srb1bis +/*!\brief DCCH1 / SRB1 logical channel */ +#define DCCH1_NB_IoT 1 // srb1 //XXX we redefine it for the SRB1 +/*!\brief DTCH0 DRB0 logical channel */ +#define DTCH0_NB_IoT 4 // DRB0 +/*!\brief DTCH1 DRB1 logical channel */ +#define DTCH1_NB_IoT 5 // DRB1 +/*Index of UE contention resoulution logical channel*/ +#define UE_CONTENTION_RESOLUTION 28 +/*Index of TIMING_ADVANCE logical channel*/ +#define TIMING_ADVANCE 29 +/*Index of DRX_COMMAND logical channel*/ +#define DRX_COMMAND 30 +/*Index of PADDING logical channel*/ +#define PADDING 31 + + +/// NPRACH-ParametersList-NB_IoT-r13 from 36.331 RRC spec defined in PHY +/*typedef struct NPRACH_Parameters_NB_IoT{ + + /// the period time for nprach + int nprach_Periodicity; + /// for the start time for the NPRACH resource from 40ms-2560ms + int nprach_StartTime; + /// for the subcarrier of set to the NPRACH preamble from n0 - n34 + int nprach_SubcarrierOffset; + ///number of subcarriers in a NPRACH resource allowed values (n12,n24,n36,n48) + int nprach_NumSubcarriers; + /// where is the region that in NPRACH resource to indicate if this UE support MSG3 for multi-tone or not. from 0 - 1 + int nprach_SubcarrierMSG3_RangeStart; + /// The max preamble transmission attempt for the CE level from 1 - 128 + int maxNumPreambleAttemptCE; + /// Number of NPRACH repetitions per attempt for each NPRACH resource + int numRepetitionsPerPreambleAttempt; + /// The number of the repetition for DCI use in RAR/MSG3/MSG4 from 1 - 2048 (Rmax) + int npdcch_NumRepetitions_RA; + /// Starting subframe for NPDCCH Common searching space for (RAR/MSG3/MSG4) + int npdcch_StartSF_CSS_RA; + /// Fractional period offset of starting subframe for NPDCCH common search space + int npdcch_Offset_RA; + +} nprach_parameters_NB_IoT_t;*/ + +/*! \brief Downlink SCH PDU Structure */ +typedef struct { + uint8_t payload[SCH_PAYLOAD_SIZE_MAX_NB_IoT]; + uint32_t pdu_size; +} __attribute__ ((__packed__)) DLSCH_PDU_NB_IoT; + +/*! \brief eNB template for UE context information */ +typedef struct { + // C-RNTI of UE + rnti_t rnti; + // UE CE level + int CE_level; + // Direction of transmission(DL:0\UL:1\NONE:-1) + int32_t direction; + // DCI Reptition + uint32_t R_dci; + // MAX repetition + uint32_t R_max; + + // HARQ round + uint32_t HARQ_round; + /*Downlink information*/ + + /// DLSCH pdu + DLSCH_PDU_NB_IoT DLSCH_pdu; + // PDU size + uint32_t DLSCH_pdu_size; + // Data Reptition + uint32_t R_dl; + // MCS index + uint32_t I_mcs_dl; + // total downlink buffer DCCH0_NB_IoT + uint32_t dl_buffer_DCCH0_NB_IoT; + // NDI + int oldNDI_DL; + //HARQ ACK/NACK repetition + uint32_t R_harq; + + /*Uplink information*/ + int oldNDI_UL; + // Uplink data repeat, now just follow the rach repeat number + uint32_t R_ul; + // PHR value (0-3) + uint32_t PHR; + // The uplink data size from BSR or DVI + uint32_t ul_total_buffer; + // Determine if this UE support multi-tone transmission or not + int multi_tone; + // Next UE_template ID + int next; + // Previous UE_template ID + int prev; + // MSG4 complete + int RRC_connected; + // UE active flag + int active; + +} UE_TEMPLATE_NB_IoT; + +/*36331 NPDCCH-ConfigDedicated-NB_IoT*/ +typedef struct{ + //npdcch-NumRepetitions-r13 + uint32_t R_max; + //npdcch-StartSF-USS-r13 + double G; + //npdcch-Offset-USS-r13 + double a_offset; + //NPDCCH period + uint32_t T; + //Starting subfrane of Search Space which is mod T + uint32_t ss_start_uss; +}NPDCCH_config_dedicated_NB_IoT_t; + + +/*! \brief UE list used by eNB to order UEs/CC for scheduling*/ +typedef struct { + + /// DCI template and MAC connection parameters for UEs + UE_TEMPLATE_NB_IoT UE_template_NB_IoT[MAX_NUMBER_OF_UE_MAX_NB_IoT]; + + /// NPDCCH Period and searching space info + NPDCCH_config_dedicated_NB_IoT_t NPDCCH_config_dedicated; + //int next[MAX_NUMBER_OF_UE_MAX_NB_IoT]; + // -1:No UE in list + int head; + // -1:No UE in list + int tail; + int num_UEs; + //boolean_t active[MAX_NUMBER_OF_UE_MAX_NB_IoT]; + +} UE_list_NB_IoT_t; + + +typedef struct{ + + // flag to indicate scheduing MIB-NB_IoT + uint8_t flag_MIB; + // flag to indicate scheduling SIB1-NB_IoT + uint8_t flag_SIB1; + // flag to indicate scheduling SIBs-NB_IoT + uint8_t flag_SIBs[MAX_NUMBER_OF_SIBs_NB_IoT]; + // flag to indicate scheduling type2 NPDCCH CSS with different CE level + uint8_t flag_type2_css[3]; + // flag to indicate scheduling type1 NPDCCH CSS with different CE level + uint8_t flag_type1_css[3]; + // flag to indicate scheduling NPDCCH USS with UE list + uint8_t flag_uss[MAX_NUMBER_OF_UE_MAX_NB_IoT]; + // flag to indicate scheduling sib1/MIB + uint8_t flag_fix_scheduling; + // number of the type2 css to schedule in this period + uint8_t num_type2_css_run; + // number of the type1 css to schedule in this period + uint8_t num_type1_css_run; + // number of the uss to schedule in this period + uint8_t num_uss_run; + +}scheduling_flag_t; + +typedef struct available_resource_UL_s{ + + ///Resource start subframe + uint32_t start_subframe; + ///Resource end subframe + uint32_t end_subframe; + // pointer to next node + struct available_resource_UL_s *next, *prev; + +}available_resource_UL_t; + +typedef struct available_resource_DL_s{ + uint32_t start_subframe; + uint32_t end_subframe; + + struct available_resource_DL_s *next, *prev; +}available_resource_DL_t; + +/*Structure used for scheduling*/ +typedef struct{ + //resource position info. + uint32_t sf_end,sf_start; + //resource position info. separate by HyperSF, Frame, Subframe + uint32_t start_h, end_h; + uint32_t start_f, end_f; + uint32_t start_sf, end_sf; + //whcih available resource node is used + available_resource_DL_t *node; +}sched_temp_DL_NB_IoT_t; + +/*!\brief MAC subheader short with 7bit Length field */ +typedef struct { + uint8_t LCID:5; // octet 1 LSB + uint8_t E:1; + uint8_t F2:1; + uint8_t R:1; // octet 1 MSB + uint8_t L:7; // octet 2 LSB + uint8_t F:1; // octet 2 MSB +} __attribute__((__packed__))SCH_SUBHEADER_SHORT_NB_IoT; +typedef struct { + uint8_t LCID:5; // octet 1 LSB + uint8_t E:1; + uint8_t F2:1; + uint8_t R:1; // octet 1 MSB + uint8_t L_MSB:7; + uint8_t F:1; // octet 2 MSB + uint8_t L_LSB:8; +} __attribute__((__packed__))SCH_SUBHEADER_LONG_NB_IoT; +typedef struct { + uint8_t LCID:5; // octet 1 LSB + uint8_t E:1; + uint8_t F2:1; + uint8_t R:1; // octet 1 MSB + uint8_t L_MSB:8; // octet 2 MSB + uint8_t L_LSB:8; +} __attribute__((__packed__))SCH_SUBHEADER_LONG_EXTEND_NB_IoT; +/*!\brief MAC subheader short without length field */ +typedef struct { + uint8_t LCID:5; + uint8_t F2:1; + uint8_t E:1; + uint8_t R:1; +} __attribute__((__packed__))SCH_SUBHEADER_FIXED_NB_IoT; + + +/*! \brief Uplink SCH PDU Structure */ +typedef struct { + int8_t payload[SCH_PAYLOAD_SIZE_MAX_NB_IoT]; /*!< \brief SACH payload */ + uint16_t Pdu_size; +} __attribute__ ((__packed__)) ULSCH_PDU_NB_IoT; + +typedef struct { + uint8_t PH:6; + uint8_t R:2; +} __attribute__((__packed__))POWER_HEADROOM_CMD_NB_IoT; + +typedef struct { + uint8_t RAPID:6; + uint8_t T:1; + uint8_t E:1; +} __attribute__((__packed__))RA_HEADER_RAPID_NB_IoT; + +/*Structure used for UL scheduling*/ +typedef struct{ + //resource position info. + uint32_t sf_end, sf_start; + //resource position info. separate by HyperSF, Frame, Subframe + //uint32_t start_h, end_h; + //uint32_t start_f, end_f; + //uint32_t start_sf, end_sf; + // information for allocating the resource + int tone; + int scheduling_delay; + int subcarrier_indication; + int ACK_NACK_resource_field; + available_resource_UL_t *node; +}sched_temp_UL_NB_IoT_t; + +typedef struct Available_available_resource_DL{ + + ///Available Resoruce for sixtone + available_resource_UL_t *sixtone_Head;//, *sixtone_npusch_frame; + uint32_t sixtone_end_subframe; + ///Available Resoruce for threetone + available_resource_UL_t *threetone_Head;//, *threetone_npusch_frame; + uint32_t threetone_end_subframe; + ///Available Resoruce for singletone1 + available_resource_UL_t *singletone1_Head;//, *singletone1_npusch_frame; + uint32_t singletone1_end_subframe; + ///Available Resoruce for singletone2 + available_resource_UL_t *singletone2_Head;//, *singletone2_npusch_frame; + uint32_t singletone2_end_subframe; + ///Available Resoruce for singletone3 + available_resource_UL_t *singletone3_Head;//, *singletone3_npusch_frame; + uint32_t singletone3_end_subframe; + +}available_resource_tones_UL_t; + +typedef struct schedule_result{ + // The subframe read by output handler + uint32_t output_subframe; + // SDU length + uint32_t sdu_length; + // MAC PDU + uint8_t *DLSCH_pdu; + // The data direction indicated by this DCI + uint8_t direction; + // pointer to DCI + void *DCI_pdu; + // when all the procedure related to this DCI, enable this flag + boolean_t DCI_release; + // Indicate the channel which to transmit + channel_NB_IoT_t channel; + // rnti + rnti_t rnti; + // 0 = TC-RNTI , 1 = RA-RNTI, 2 = P-RNTI, 3 = others + uint8_t rnti_type; + // 0 = data, 1 = ACK/NACK + uint8_t npusch_format; + //HARQ ACK/NACK repetition + uint32_t R_harq; + // pointer to next node + struct schedule_result *next; + + uint32_t end_subframe; + + uint8_t *rar_buffer; + +}schedule_result_t; + +/*Flag structure used for trigger each scheduler*/ +typedef struct{ + scheduling_flag_t scheduling_flag; + //sched_temp_DL_NB_IoT_t sched_result_DL; + //resource grid for Uplink + available_resource_tones_UL_t *UL_resource; + //scheduling result read by output handler + schedule_result_t *schedule_result_list_UL; + schedule_result_t *schedule_result_list_DL; +}SCHEDULE_NB_IoT_t; + +typedef struct{ + uint32_t num_dlsf_per_period; + uint16_t *sf_to_dlsf_table; + uint16_t *dlsf_to_sf_table; +}DLSF_INFO_t; + +typedef enum ce_level_e{ + ce0=0, + ce1, + ce2, + ce_level_total +}ce_level_t; + + + +/*! \brief eNB template for the Random access information */ +typedef struct RA_TEMPLATE_NB_IoT_s{ + + boolean_t active; + uint32_t msg3_retransmit_count; + uint32_t msg4_retransmit_count; + uint16_t ta; + uint8_t preamble_index; + ce_level_t ce_level; + rnti_t ue_rnti; + rnti_t ra_rnti; + struct RA_TEMPLATE_NB_IoT_s *next, *prev; + boolean_t wait_msg4_ack; + boolean_t wait_msg3_ack; + uint8_t rar_buffer[7]; + +} RA_TEMPLATE_NB_IoT; + +typedef struct RA_template_list_s{ + RA_TEMPLATE_NB_IoT *head; + RA_TEMPLATE_NB_IoT *tail; +}RA_template_list_t; + + +/*! \brief top level eNB MAC structure */ +typedef struct eNB_MAC_INST_NB_IoT_s { + /// Ethernet parameters for northbound midhaul interface + eth_params_t eth_params_n; + /// Ethernet parameters for fronthaul interface + eth_params_t eth_params_s; + + uint8_t Mod_id; + // System + uint32_t hyper_system_frame; + uint32_t system_frame; + uint32_t sub_frame; + + uint32_t current_subframe; + /// Pointer to IF module instance for PHY + IF_Module_t *if_inst; + // RA + RA_template_list_t RA_msg2_list; + RA_template_list_t RA_msg3_list; + RA_template_list_t RA_msg4_list; + + RA_TEMPLATE_NB_IoT RA_template[MAX_NUMBER_OF_UE_MAX_NB_IoT]; + + //int32_t last_tx_subframe; + + // for tool + int32_t sib1_flag[64]; + int32_t sib1_count[64]; + int32_t sib1_period; + uint16_t dlsf_table[64]; + int32_t sibs_table[256]; + + // channel config + + //USS list + //Number of USS period is used + int num_uss_list; + UE_list_NB_IoT_t *UE_list_spec; + + scheduling_flag_t scheduling_flag; + + uint32_t schedule_subframe_DL; + uint32_t schedule_subframe_UL; + + rrc_config_NB_IoT_t rrc_config; + + nfapi_config_request_t config; + + IF_Module_NB_IoT_t *if_inst_NB_IoT; +} eNB_MAC_INST_NB_IoT; + +// actually not here, but for now put it here +typedef struct { + uint32_t bytes_in_buffer; /*!< \brief Bytes buffered in RLC protocol instance. */ + uint32_t pdus_in_buffer; /*!< \brief Number of PDUs buffered in RLC protocol instance (OBSOLETE). */ + uint32_t head_sdu_creation_time; /*!< \brief Head SDU creation time. */ + uint32_t head_sdu_remaining_size_to_send; /*!< \brief remaining size of sdu: could be the total size or the remaining size of already segmented sdu */ + boolean_t head_sdu_is_segmented; /*!< \brief 0 if head SDU has not been segmented, 1 if already segmented */ +} mac_rlc_status_resp_NB_IoT_t; + +// global variables + +nprach_parameters_NB_IoT_t nprach_list[3]; + +//DLSF Table +DLSF_INFO_t DLSF_information; + +#endif /*__LAYER2_MAC_DEFS_NB_IoT_H__ */ diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.c b/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.c index 80dcfd4053..43721bbfd5 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.c +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.c @@ -1,1417 +1,1417 @@ -/* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file asn1_msg.c -* \brief primitives to build the asn1 messages -* \author Raymond Knopp, Navid Nikaein and Michele Paffetti -* \date 2011, 2017 -* \version 1.0 -* \company Eurecom -* \email: raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, michele.paffetti@studio.unibo.it -*/ - -#include -#include -#include /* for atoi(3) */ -#include /* for getopt(3) */ -#include /* for strerror(3) */ -#include /* for EX_* exit codes */ -#include /* for errno */ -#include "UTIL/LOG/log.h" -#include -#include /* for _ASN_DEFAULT_STACK_MAX */ -#include -#include "asn1_msg.h" - - - -//#include for NB-IoT------------------- -#include "RRCConnectionRequest-NB.h" -#include "BCCH-DL-SCH-Message-NB.h" -#include "UL-CCCH-Message-NB.h" -#include "UL-DCCH-Message-NB.h" -#include "DL-CCCH-Message-NB.h" -#include "DL-DCCH-Message-NB.h" -#include "EstablishmentCause-NB-r13.h" -#include "RRCConnectionSetup-NB.h" -#include "SRB-ToAddModList-NB-r13.h" -#include "DRB-ToAddModList-NB-r13.h" -#include "RRC/LITE/defs_NB_IoT.h" -#include "RRCConnectionSetupComplete-NB.h" -#include "RRCConnectionReconfigurationComplete-NB.h" -#include "RRCConnectionReconfiguration-NB.h" -#include "MasterInformationBlock-NB.h" -#include "SystemInformation-NB.h" -#include "SystemInformationBlockType1.h" -#include "SIB-Type-NB-r13.h" -#include "RRCConnectionResume-NB.h" -#include "RRCConnectionReestablishment-NB.h" -#include "../defs_NB_IoT.h" -//---------------------------------------- - -//#include "PHY/defs.h" -#include "enb_config.h" - -#if defined(ENABLE_ITTI) -# include "intertask_interface.h" -#endif - - - - -/*do_MIB_NB_NB_IoT*/ -uint8_t do_MIB_NB_IoT( - rrc_eNB_carrier_data_NB_IoT_t *carrier, - uint16_t N_RB_DL,//may not needed--> for NB_IoT only 1 PRB is used - uint32_t frame, - uint32_t hyper_frame) -{ - asn_enc_rval_t enc_rval; - BCCH_BCH_Message_NB_t *mib_NB_IoT = &(carrier->mib_NB_IoT); - - /* - * systemFrameNumber-MSB: (TS 36.331 pag 576) - * define the 4 MSB of the SFN (10 bits). The last significant 6 bits will be acquired implicitly by decoding the NPBCH - * NOTE: 6 LSB will be used for counting the 64 radio frames in the TTI period (640 ms) that is exactly the MIB period - * - * hyperSFN-LSB: - * indicates the 2 least significant bits of the HSFN. The remaining 8 bits are present in SIB1-NB - * NOTE: with the 2 bits we count the 4 HSFN (is 1 SIB1-Nb modification period) while the other 6 count the number of modification periods - * - * - * NOTE: in OAI never modify the SIB messages!!?? - */ - - //XXX check if correct the bit assignment - uint8_t sfn_MSB = (uint8_t)((frame>>6) & 0x0f); // all the 4 bits are set to 1 - uint8_t hsfn_LSB = (uint8_t)(hyper_frame & 0x03); //2 bits set to 1 (0x3 = 0011) - uint16_t spare=0; //11 bits --> use uint16 - - mib_NB_IoT->message.systemFrameNumber_MSB_r13.buf = &sfn_MSB; - mib_NB_IoT->message.systemFrameNumber_MSB_r13.size = 1; //if expressed in byte - mib_NB_IoT->message.systemFrameNumber_MSB_r13.bits_unused = 4; //is byte based (so how many bits you don't use of the 8 bits of a bite - - mib_NB_IoT->message.hyperSFN_LSB_r13.buf= &hsfn_LSB; - mib_NB_IoT->message.hyperSFN_LSB_r13.size= 1; - mib_NB_IoT->message.hyperSFN_LSB_r13.bits_unused = 6; - - //XXX to be set?? - mib_NB_IoT->message.spare.buf = (uint8_t *)&spare; - mib_NB_IoT->message.spare.size = 2; - mib_NB_IoT->message.spare.bits_unused = 5; - - //decide how to set it - mib_NB_IoT->message.schedulingInfoSIB1_r13 =11; //see TS 36.213-->tables 16.4.1.3-3 ecc... - mib_NB_IoT->message.systemInfoValueTag_r13= 0; - mib_NB_IoT->message.ab_Enabled_r13 = 0; - - //to be decided - mib_NB_IoT->message.operationModeInfo_r13.present = MasterInformationBlock_NB__operationModeInfo_r13_PR_inband_SamePCI_r13; - mib_NB_IoT->message.operationModeInfo_r13.choice.inband_SamePCI_r13.eutra_CRS_SequenceInfo_r13 = 0; - - printf("[MIB] Initialization of frame information,sfn_MSB %x, hsfn_LSB %x\n", - (uint32_t)sfn_MSB, - (uint32_t)hsfn_LSB); - - enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_BCH_Message_NB, - (void*)mib_NB_IoT, - carrier->MIB_NB_IoT, - 100); - if(enc_rval.encoded <= 0) { - LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - } - - if (enc_rval.encoded==-1) { - return(-1); - } - - return((enc_rval.encoded+7)/8); - -} - -/*do_SIB1_NB*/ -uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, int CC_id, - rrc_eNB_carrier_data_NB_IoT_t *carrier, - NbIoTRrcConfigurationReq *configuration, - uint32_t frame - ) -{ - BCCH_DL_SCH_Message_NB_t *bcch_message= &(carrier->siblock1_NB_IoT); - SystemInformationBlockType1_NB_t **sib1_NB_IoT= &(carrier->sib1_NB_IoT); - - - asn_enc_rval_t enc_rval; - - PLMN_IdentityInfo_NB_r13_t PLMN_identity_info_NB_IoT; - MCC_MNC_Digit_t dummy_mcc[3],dummy_mnc[3]; - SchedulingInfo_NB_r13_t *schedulingInfo_NB_IoT; - SIB_Type_NB_r13_t *sib_type_NB_IoT; - - - long* attachWithoutPDN_Connectivity = NULL; - attachWithoutPDN_Connectivity = CALLOC(1,sizeof(long)); - long *nrs_CRS_PowerOffset=NULL; - nrs_CRS_PowerOffset = CALLOC(1, sizeof(long)); - long *eutraControlRegionSize=NULL; //this parameter should be set only if we are considering in-band operating mode (samePCI or differentPCI) - eutraControlRegionSize = CALLOC(1,sizeof(long)); - long systemInfoValueTagSI = 0; - - memset(bcch_message,0,sizeof(BCCH_DL_SCH_Message_NB_t)); - bcch_message->message.present = BCCH_DL_SCH_MessageType_NB_PR_c1; - bcch_message->message.choice.c1.present = BCCH_DL_SCH_MessageType_NB__c1_PR_systemInformationBlockType1_r13; - - //allocation - *sib1_NB_IoT = &bcch_message->message.choice.c1.choice.systemInformationBlockType1_r13; - - - /*TS 36.331 v14.2.0 pag 589 - * hyperSFN-MSB - * Indicates the 8 most significant bits of the hyper-SFN. Together with the hyper-LSB in MIB-NB the complete HSFN is build up - */ - //FIXME see if correct - uint8_t hyperSFN_MSB = (uint8_t) ((frame>>2)& 0xff); - - //XXX to be checked - (*sib1_NB_IoT)->hyperSFN_MSB_r13.buf = &hyperSFN_MSB; - (*sib1_NB_IoT)->hyperSFN_MSB_r13.size = 1; - (*sib1_NB_IoT)->hyperSFN_MSB_r13.bits_unused = 0; - - memset(&PLMN_identity_info_NB_IoT,0,sizeof(PLMN_IdentityInfo_NB_r13_t)); - - PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc = CALLOC(1,sizeof(*PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc)); - memset(PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc,0,sizeof(*PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc)); - - asn_set_empty(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list);//.size=0; - - //left as it is??? -#if defined(ENABLE_ITTI) - dummy_mcc[0] = (configuration->mcc / 100) % 10; - dummy_mcc[1] = (configuration->mcc / 10) % 10; - dummy_mcc[2] = (configuration->mcc / 1) % 10; -#else - dummy_mcc[0] = 0; - dummy_mcc[1] = 0; - dummy_mcc[2] = 1; -#endif - ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list,&dummy_mcc[0]); - ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list,&dummy_mcc[1]); - ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list,&dummy_mcc[2]); - - PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list.size=0; - PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list.count=0; - - -#if defined(ENABLE_ITTI) - - if (configuration->mnc >= 100) { - dummy_mnc[0] = (configuration->mnc / 100) % 10; - dummy_mnc[1] = (configuration->mnc / 10) % 10; - dummy_mnc[2] = (configuration->mnc / 1) % 10; - } else { - if (configuration->mnc_digit_length == 2) { - dummy_mnc[0] = (configuration->mnc / 10) % 10; - dummy_mnc[1] = (configuration->mnc / 1) % 10; - dummy_mnc[2] = 0xf; - } else { - dummy_mnc[0] = (configuration->mnc / 100) % 100; - dummy_mnc[1] = (configuration->mnc / 10) % 10; - dummy_mnc[2] = (configuration->mnc / 1) % 10; - } - } - -#else - dummy_mnc[0] = 0; - dummy_mnc[1] = 1; - dummy_mnc[2] = 0xf; -#endif - ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list,&dummy_mnc[0]); - ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list,&dummy_mnc[1]); - - if (dummy_mnc[2] != 0xf) { - ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list,&dummy_mnc[2]); - } - - //still set to "notReserved" as in the previous case - PLMN_identity_info_NB_IoT.cellReservedForOperatorUse_r13=PLMN_IdentityInfo_NB_r13__cellReservedForOperatorUse_r13_notReserved; - - *attachWithoutPDN_Connectivity = 0; - PLMN_identity_info_NB_IoT.attachWithoutPDN_Connectivity_r13 = attachWithoutPDN_Connectivity; - - ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.plmn_IdentityList_r13.list,&PLMN_identity_info_NB_IoT); - - // 16 bits = 2 byte - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf = MALLOC(2); //MALLOC works in byte - - //lefts as it is? -#if defined(ENABLE_ITTI) - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[0] = (configuration->tac >> 8) & 0xff; - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[1] = (configuration->tac >> 0) & 0xff; -#else - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[0] = 0x00; - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[1] = 0x01; -#endif - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.size=2; - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.bits_unused=0; - - // 28 bits --> i have to use 32 bits = 4 byte - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf = MALLOC(8); // why allocate 8 byte? -#if defined(ENABLE_ITTI) - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[0] = (configuration->cell_identity >> 20) & 0xff; - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[1] = (configuration->cell_identity >> 12) & 0xff; - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[2] = (configuration->cell_identity >> 4) & 0xff; - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[3] = (configuration->cell_identity << 4) & 0xf0; -#else - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[0] = 0x00; - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[1] = 0x00; - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[2] = 0x00; - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[3] = 0x10; -#endif - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.size=4; - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.bits_unused=4; - - //Still set to "notBarred" as in the previous case - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellBarred_r13=SystemInformationBlockType1_NB__cellAccessRelatedInfo_r13__cellBarred_r13_notBarred; - - //Still Set to "notAllowed" like in the previous case - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.intraFreqReselection_r13=SystemInformationBlockType1_NB__cellAccessRelatedInfo_r13__intraFreqReselection_r13_notAllowed; - - - (*sib1_NB_IoT)->cellSelectionInfo_r13.q_RxLevMin_r13=-65; //which value?? TS 36.331 V14.2.1 pag. 589 - (*sib1_NB_IoT)->cellSelectionInfo_r13.q_QualMin_r13 = 0; //FIXME new parameter for SIB1-NB, not present in SIB1 (for cell reselection but if not used the UE should apply the default value) - - (*sib1_NB_IoT)->p_Max_r13 = CALLOC(1, sizeof(P_Max_t)); - *((*sib1_NB_IoT)->p_Max_r13) = 23; - - //FIXME - (*sib1_NB_IoT)->freqBandIndicator_r13 = -#if defined(ENABLE_ITTI) - configuration->eutra_band; -#else - 5; //if not configured we use band 5 (UL: 824 MHz - 849MHz / DL: 869 MHz - 894 MHz FDD mode) -#endif - - //OPTIONAL new parameters, to be used? - /* - * freqBandInfo_r13 - * multiBandInfoList_r13 - * nrs_CRS_PowerOffset_r13 - * sib1_NB_IoT->downlinkBitmap_r13.choice.subframePattern10_r13 =(is a BIT_STRING) - */ - - - (*sib1_NB_IoT)->downlinkBitmap_r13 = CALLOC(1, sizeof(struct DL_Bitmap_NB_r13)); - ((*sib1_NB_IoT)->downlinkBitmap_r13)->present= DL_Bitmap_NB_r13_PR_NOTHING; - - *eutraControlRegionSize = 1; - (*sib1_NB_IoT)->eutraControlRegionSize_r13 = eutraControlRegionSize; - - - *nrs_CRS_PowerOffset= 0; - (*sib1_NB_IoT)->nrs_CRS_PowerOffset_r13 = nrs_CRS_PowerOffset; - - schedulingInfo_NB_IoT = (SchedulingInfo_NB_r13_t*) malloc (3*sizeof(SchedulingInfo_NB_r13_t)); - sib_type_NB_IoT = (SIB_Type_NB_r13_t *) malloc (3*sizeof(SIB_Type_NB_r13_t)); - - memset(&schedulingInfo_NB_IoT[0],0,sizeof(SchedulingInfo_NB_r13_t)); - memset(&schedulingInfo_NB_IoT[1],0,sizeof(SchedulingInfo_NB_r13_t)); - memset(&schedulingInfo_NB_IoT[2],0,sizeof(SchedulingInfo_NB_r13_t)); - memset(&sib_type_NB_IoT[0],0,sizeof(SIB_Type_NB_r13_t)); - memset(&sib_type_NB_IoT[1],0,sizeof(SIB_Type_NB_r13_t)); - memset(&sib_type_NB_IoT[2],0,sizeof(SIB_Type_NB_r13_t)); - - - // Now, follow the scheduler SIB configuration - // There is only one sib2+sib3 common setting - schedulingInfo_NB_IoT[0].si_Periodicity_r13=SchedulingInfo_NB_r13__si_Periodicity_r13_rf4096; - schedulingInfo_NB_IoT[0].si_RepetitionPattern_r13=SchedulingInfo_NB_r13__si_RepetitionPattern_r13_every2ndRF; //This Indicates the starting radio frames within the SI window used for SI message transmission. - schedulingInfo_NB_IoT[0].si_TB_r13= SchedulingInfo_NB_r13__si_TB_r13_b680;//208 bits - - - // This is for SIB2/3 - /*SIB3 --> There is no mapping information of SIB2 since it is always present - * in the first SystemInformation message - * listed in the schedulingInfoList list. - * */ - sib_type_NB_IoT[0]=SIB_Type_NB_r13_sibType3_NB_r13; - - ASN_SEQUENCE_ADD(&schedulingInfo_NB_IoT[0].sib_MappingInfo_r13.list,&sib_type_NB_IoT[0]); - ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->schedulingInfoList_r13.list,&schedulingInfo_NB_IoT[0]); - - //printf("[ASN Debug] SI P: %ld\n",(*sib1_NB_IoT)->schedulingInfoList_r13.list.array[0]->si_Periodicity_r13); - -#if defined(ENABLE_ITTI) - - if (configuration->frame_type == TDD) -#endif - { - //FIXME in NB-IoT mandatory to be FDD --> so must give an error - LOG_E(RRC,"[NB-IoT %d] Frame Type is TDD --> not supported by NB-IoT, exiting\n", Mod_id); //correct? - exit(-1); - } - - //FIXME which value chose for the following parameter - (*sib1_NB_IoT)->si_WindowLength_r13=SystemInformationBlockType1_NB__si_WindowLength_r13_ms160; - (*sib1_NB_IoT)->si_RadioFrameOffset_r13= 0; - - /*In Nb-IoT change/update of specific SI message can additionally be indicated by a SI message specific value tag - * systemInfoValueTagSI (there is no SystemInfoValueTag in SIB1-NB but only in MIB-NB) - *contained in systemInfoValueTagList_r13 - **/ - //FIXME correct? - (*sib1_NB_IoT)->systemInfoValueTagList_r13 = CALLOC(1, sizeof(struct SystemInfoValueTagList_NB_r13)); - asn_set_empty(&(*sib1_NB_IoT)->systemInfoValueTagList_r13->list); - ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->systemInfoValueTagList_r13->list,&systemInfoValueTagSI); - - -#ifdef XER_PRINT //generate xml files - xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message_NB, (void*)bcch_message); -#endif - - - enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_DL_SCH_Message_NB, - (void*)bcch_message, - carrier->SIB1_NB_IoT, - 100); - - if (enc_rval.encoded > 0){ - LOG_F(RRC,"ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - } - - -#ifdef USER_MODE - LOG_D(RRC,"[NB-IoT] SystemInformationBlockType1-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); -#endif - - if (enc_rval.encoded==-1) { - return(-1); - } - - return((enc_rval.encoded+7)/8); -} - -/*SIB23_NB_IoT*/ -//to be clarified is it is possible to carry SIB2 and SIB3 in the same SI message for NB-IoT? -uint8_t do_SIB23_NB_IoT(uint8_t Mod_id, - int CC_id, - rrc_eNB_carrier_data_NB_IoT_t *carrier,//MP: this is already a carrier[CC_id] - NbIoTRrcConfigurationReq *configuration ) //openair2/COMMON/rrc_messages_types.h -{ - struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member *sib2_NB_part; - struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member *sib3_NB_part; - - BCCH_DL_SCH_Message_NB_t *bcch_message = &(carrier->systemInformation_NB_IoT); //is the systeminformation-->BCCH_DL_SCH_Message_NB - SystemInformationBlockType2_NB_r13_t *sib2_NB_IoT; - SystemInformationBlockType3_NB_r13_t *sib3_NB_IoT; - - asn_enc_rval_t enc_rval; - RACH_Info_NB_r13_t rach_Info_NB_IoT; - NPRACH_Parameters_NB_r13_t *nprach_parameters; - - //optional - long *connEstFailOffset = NULL; - connEstFailOffset = CALLOC(1, sizeof(long)); - -// RSRP_ThresholdsNPRACH_InfoList_NB_r13_t *rsrp_ThresholdsPrachInfoList; -// RSRP_Range_t rsrp_range; - - ACK_NACK_NumRepetitions_NB_r13_t ack_nack_repetition; - struct NPUSCH_ConfigCommon_NB_r13__dmrs_Config_r13 *dmrs_config; - struct DL_GapConfig_NB_r13 *dl_Gap; - - long *srs_SubframeConfig; - srs_SubframeConfig= CALLOC(1, sizeof(long)); - - - if (bcch_message) { - memset(bcch_message,0,sizeof(BCCH_DL_SCH_Message_NB_t)); - } else { - LOG_E(RRC,"[NB-IoT %d] BCCH_MESSAGE_NB is null, exiting\n", Mod_id); - exit(-1); - } - - //before schould be allocated memory somewhere? -// if (!carrier->sib2_NB_IoT) { -// LOG_E(RRC,"[NB-IoT %d] sib2_NB_IoT is null, exiting\n", Mod_id); -// exit(-1); -// } -// -// if (!carrier->sib3_NB_IoT) { -// LOG_E(RRC,"[NB-IoT %d] sib3_NB_IoT is null, exiting\n", Mod_id); -// exit(-1); -// } - - - LOG_I(RRC,"[NB-IoT %d] Configuration SIB2/3\n", Mod_id); - - sib2_NB_part = CALLOC(1,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); - sib3_NB_part = CALLOC(1,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); - memset(sib2_NB_part,0,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); - memset(sib3_NB_part,0,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); - - sib2_NB_part->present = SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR_sib2_r13; - sib3_NB_part->present = SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR_sib3_r13; - - //may bug if not correct allocation of memory - carrier->sib2_NB_IoT = &sib2_NB_part->choice.sib2_r13; - carrier->sib3_NB_IoT = &sib3_NB_part->choice.sib3_r13; - sib2_NB_IoT = carrier->sib2_NB_IoT; - sib3_NB_IoT = carrier->sib3_NB_IoT; - - nprach_parameters = (NPRACH_Parameters_NB_r13_t *) malloc (3*sizeof(NPRACH_Parameters_NB_r13_t)); - - memset(&nprach_parameters[0],0,sizeof(NPRACH_Parameters_NB_r13_t)); - memset(&nprach_parameters[1],0,sizeof(NPRACH_Parameters_NB_r13_t)); - memset(&nprach_parameters[2],0,sizeof(NPRACH_Parameters_NB_r13_t)); - -/// SIB2-NB----------------------------------------- - - //Barring is manage by ab-Enabled in MIB-NB (but is not a struct as ac-BarringInfo in LTE legacy) - - //RACH Config. Common-------------------------------------------------------------- - sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.preambleTransMax_CE_r13 = - configuration->rach_preambleTransMax_CE_NB; - sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.powerRampingParameters_r13.powerRampingStep = - configuration->rach_powerRampingStep_NB; - sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.powerRampingParameters_r13.preambleInitialReceivedTargetPower = - configuration->rach_preambleInitialReceivedTargetPower_NB; - - rach_Info_NB_IoT.ra_ResponseWindowSize_r13 = configuration->rach_raResponseWindowSize_NB; - rach_Info_NB_IoT.mac_ContentionResolutionTimer_r13 = configuration-> rach_macContentionResolutionTimer_NB; - //rach_infoList max size = maxNPRACH-Resources-NB-r13 = 3 - ASN_SEQUENCE_ADD(&sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.rach_InfoList_r13.list,&rach_Info_NB_IoT); - - //TS 36.331 pag 614 --> if not present the value to infinity sould be used - *connEstFailOffset = 0; - - sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.connEstFailOffset_r13 = connEstFailOffset; /*OPTIONAL*/ - - - // BCCH-Config-NB-IoT---------------------------------------------------------------- - sib2_NB_IoT->radioResourceConfigCommon_r13.bcch_Config_r13.modificationPeriodCoeff_r13 - = configuration->bcch_modificationPeriodCoeff_NB; - - // PCCH-Config-NB-IoT----------------------------------------------------------------- - sib2_NB_IoT->radioResourceConfigCommon_r13.pcch_Config_r13.defaultPagingCycle_r13 - = configuration->pcch_defaultPagingCycle_NB; - sib2_NB_IoT->radioResourceConfigCommon_r13.pcch_Config_r13.nB_r13 = configuration->pcch_nB_NB; - sib2_NB_IoT->radioResourceConfigCommon_r13.pcch_Config_r13.npdcch_NumRepetitionPaging_r13 = configuration-> pcch_npdcch_NumRepetitionPaging_NB; - - //NPRACH-Config-NB-IoT----------------------------------------------------------------- - - sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.rsrp_ThresholdsPrachInfoList_r13 = NULL; - sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.nprach_CP_Length_r13 = configuration->nprach_CP_Length; - /*OPTIONAL*/ -// =CALLOC(1, sizeof(struct RSRP_ThresholdsNPRACH_InfoList_NB_r13)); //fatto uguale dopo -// rsrp_ThresholdsPrachInfoList = sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.rsrp_ThresholdsPrachInfoList_r13; -// rsrp_range = configuration->nprach_rsrp_range_NB; -// ASN_SEQUENCE_ADD(&rsrp_ThresholdsPrachInfoList->list,rsrp_range); - - // According configuration to set the 3 CE level configuration setting - - nprach_parameters[0].nprach_Periodicity_r13 = configuration->nprach_Periodicity[0]; - nprach_parameters[0].nprach_StartTime_r13 = configuration->nprach_StartTime[0]; - nprach_parameters[0].nprach_SubcarrierOffset_r13 = configuration->nprach_SubcarrierOffset[0]; - nprach_parameters[0].nprach_NumSubcarriers_r13 = configuration->nprach_NumSubcarriers[0]; - nprach_parameters[0].numRepetitionsPerPreambleAttempt_r13 = configuration->numRepetitionsPerPreambleAttempt_NB[0]; - nprach_parameters[0].nprach_SubcarrierMSG3_RangeStart_r13 = configuration->nprach_SubcarrierMSG3_RangeStart; - nprach_parameters[0].maxNumPreambleAttemptCE_r13 = configuration->maxNumPreambleAttemptCE_NB; - nprach_parameters[0].npdcch_NumRepetitions_RA_r13 = configuration->npdcch_NumRepetitions_RA[0]; - nprach_parameters[0].npdcch_StartSF_CSS_RA_r13 = configuration->npdcch_StartSF_CSS_RA[0]; - nprach_parameters[0].npdcch_Offset_RA_r13 = configuration->npdcch_Offset_RA[0]; - - nprach_parameters[1].nprach_Periodicity_r13 = configuration->nprach_Periodicity[1]; - nprach_parameters[1].nprach_StartTime_r13 = configuration->nprach_StartTime[1]; - nprach_parameters[1].nprach_SubcarrierOffset_r13 = configuration->nprach_SubcarrierOffset[1]; - nprach_parameters[1].nprach_NumSubcarriers_r13 = configuration->nprach_NumSubcarriers[1]; - nprach_parameters[1].numRepetitionsPerPreambleAttempt_r13 = configuration->numRepetitionsPerPreambleAttempt_NB[1]; - nprach_parameters[1].nprach_SubcarrierMSG3_RangeStart_r13 = configuration->nprach_SubcarrierMSG3_RangeStart; - nprach_parameters[1].maxNumPreambleAttemptCE_r13 = configuration->maxNumPreambleAttemptCE_NB; - nprach_parameters[1].npdcch_NumRepetitions_RA_r13 = configuration->npdcch_NumRepetitions_RA[1]; - nprach_parameters[1].npdcch_StartSF_CSS_RA_r13 = configuration->npdcch_StartSF_CSS_RA[1]; - nprach_parameters[1].npdcch_Offset_RA_r13 = configuration->npdcch_Offset_RA[1]; - - nprach_parameters[2].nprach_Periodicity_r13 = configuration->nprach_Periodicity[2]; - nprach_parameters[2].nprach_StartTime_r13 = configuration->nprach_StartTime[2]; - nprach_parameters[2].nprach_SubcarrierOffset_r13 = configuration->nprach_SubcarrierOffset[2]; - nprach_parameters[2].nprach_NumSubcarriers_r13 = configuration->nprach_NumSubcarriers[2]; - nprach_parameters[2].numRepetitionsPerPreambleAttempt_r13 = configuration->numRepetitionsPerPreambleAttempt_NB[2]; - nprach_parameters[2].nprach_SubcarrierMSG3_RangeStart_r13 = configuration->nprach_SubcarrierMSG3_RangeStart; - nprach_parameters[2].maxNumPreambleAttemptCE_r13 = configuration->maxNumPreambleAttemptCE_NB; - nprach_parameters[2].npdcch_NumRepetitions_RA_r13 = configuration->npdcch_NumRepetitions_RA[2]; - nprach_parameters[2].npdcch_StartSF_CSS_RA_r13 = configuration->npdcch_StartSF_CSS_RA[2]; - nprach_parameters[2].npdcch_Offset_RA_r13 = configuration->npdcch_Offset_RA[2]; - - - //nprach_parameterList have a max size of 3 possible nprach configuration (see maxNPRACH_Resources_NB_r13) - ASN_SEQUENCE_ADD(&sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.nprach_ParametersList_r13.list,&nprach_parameters[0]); - ASN_SEQUENCE_ADD(&sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.nprach_ParametersList_r13.list,&nprach_parameters[1]); - ASN_SEQUENCE_ADD(&sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.nprach_ParametersList_r13.list,&nprach_parameters[2]); - - // NPDSCH-Config NB-IOT - sib2_NB_IoT->radioResourceConfigCommon_r13.npdsch_ConfigCommon_r13.nrs_Power_r13= configuration->npdsch_nrs_Power; - - - //NPUSCH-Config NB-IoT---------------------------------------------------------------- - //list of size 3 (see maxNPRACH_Resources_NB_r13) - ack_nack_repetition = configuration-> npusch_ack_nack_numRepetitions_NB; //is an enumerative - ASN_SEQUENCE_ADD(&(sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.ack_NACK_NumRepetitions_Msg4_r13.list) ,&ack_nack_repetition); - - *srs_SubframeConfig = configuration->npusch_srs_SubframeConfig_NB; - sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.srs_SubframeConfig_r13= srs_SubframeConfig; /*OPTIONAL*/ - - - /*OPTIONAL*/ - dmrs_config = CALLOC(1,sizeof(struct NPUSCH_ConfigCommon_NB_r13__dmrs_Config_r13)); - dmrs_config->threeTone_CyclicShift_r13 = configuration->npusch_threeTone_CyclicShift_r13; - dmrs_config->sixTone_CyclicShift_r13 = configuration->npusch_sixTone_CyclicShift_r13; - - /*OPTIONAL - * -define the base sequence for a DMRS sequence in a cell with multi tone transmission (3,6,12) see TS 36.331 NPUSCH-Config-NB - * -if not defined will be calculated based on the cellID once we configure the phy layer (rrc_mac_config_req) through the config_sib2 */ - dmrs_config->threeTone_BaseSequence_r13 = NULL; - dmrs_config->sixTone_BaseSequence_r13 = NULL; - dmrs_config->twelveTone_BaseSequence_r13 = NULL; - - sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.dmrs_Config_r13 = dmrs_config; - - //ulReferenceSignalsNPUSCH - /*Reference Signal (RS) for UL in NB-IoT is called DRS (Demodulation Reference Signal) - * sequence-group hopping can be enabled or disabled by means of the cell-specific parameter groupHoppingEnabled_r13 - * sequence-group hopping can be disabled for certain specific UE through the parameter groupHoppingDisabled (physicalConfigDedicated) - * groupAssignmentNPUSCH--> is used for generate the sequence-shift pattern - */ - sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.ul_ReferenceSignalsNPUSCH_r13.groupHoppingEnabled_r13= configuration->npusch_groupHoppingEnabled; - sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.ul_ReferenceSignalsNPUSCH_r13.groupAssignmentNPUSCH_r13 =configuration->npusch_groupAssignmentNPUSCH_r13; - - - //dl_GAP---------------------------------------------------------------------------------/*OPTIONAL*/ - dl_Gap = CALLOC(1,sizeof(struct DL_GapConfig_NB_r13)); - dl_Gap->dl_GapDurationCoeff_r13= configuration-> dl_GapDurationCoeff_NB; - dl_Gap->dl_GapPeriodicity_r13= configuration->dl_GapPeriodicity_NB; - dl_Gap->dl_GapThreshold_r13= configuration->dl_GapThreshold_NB; - sib2_NB_IoT->radioResourceConfigCommon_r13.dl_Gap_r13 = dl_Gap; - - - // uplinkPowerControlCommon - NB-IoT------------------------------------------------------ - sib2_NB_IoT->radioResourceConfigCommon_r13.uplinkPowerControlCommon_r13.p0_NominalNPUSCH_r13 = configuration->npusch_p0_NominalNPUSCH; - sib2_NB_IoT->radioResourceConfigCommon_r13.uplinkPowerControlCommon_r13.deltaPreambleMsg3_r13 = configuration->deltaPreambleMsg3; - sib2_NB_IoT->radioResourceConfigCommon_r13.uplinkPowerControlCommon_r13.alpha_r13 = configuration->npusch_alpha; - //no deltaFlist_PUCCH and no UL cyclic prefix - - // UE Timers and Constants -NB-IoT-------------------------------------------------------- - sib2_NB_IoT->ue_TimersAndConstants_r13.t300_r13 = configuration-> ue_TimersAndConstants_t300_NB; - sib2_NB_IoT->ue_TimersAndConstants_r13.t301_r13 = configuration-> ue_TimersAndConstants_t301_NB; - sib2_NB_IoT->ue_TimersAndConstants_r13.t310_r13 = configuration-> ue_TimersAndConstants_t310_NB; - sib2_NB_IoT->ue_TimersAndConstants_r13.t311_r13 = configuration-> ue_TimersAndConstants_t311_NB; - sib2_NB_IoT->ue_TimersAndConstants_r13.n310_r13 = configuration-> ue_TimersAndConstants_n310_NB; - sib2_NB_IoT->ue_TimersAndConstants_r13.n311_r13 = configuration-> ue_TimersAndConstants_n311_NB; - - //other SIB2-NB Parameters-------------------------------------------------------------------------------- - sib2_NB_IoT->freqInfo_r13.additionalSpectrumEmission_r13 = 1; - sib2_NB_IoT->freqInfo_r13.ul_CarrierFreq_r13 = NULL; /*OPTIONAL*/ - - sib2_NB_IoT->timeAlignmentTimerCommon_r13=TimeAlignmentTimer_infinity;//TimeAlignmentTimer_sf5120; - - /*OPTIONAL*/ - sib2_NB_IoT->multiBandInfoList_r13 = NULL; - -/// SIB3-NB------------------------------------------------------- - - sib3_NB_IoT->cellReselectionInfoCommon_r13.q_Hyst_r13=SystemInformationBlockType3_NB_r13__cellReselectionInfoCommon_r13__q_Hyst_r13_dB4; - sib3_NB_IoT->cellReselectionServingFreqInfo_r13.s_NonIntraSearch_r13=0; //or define in configuration? - - sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_RxLevMin_r13 = -70; - //new - sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_QualMin_r13 = CALLOC(1,sizeof(*sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_QualMin_r13)); - *(sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_QualMin_r13)= 10; //a caso - - sib3_NB_IoT->intraFreqCellReselectionInfo_r13.p_Max_r13 = NULL; - sib3_NB_IoT->intraFreqCellReselectionInfo_r13.s_IntraSearchP_r13 = 31; // s_intraSearch --> s_intraSearchP!!! (they call in a different way) - sib3_NB_IoT->intraFreqCellReselectionInfo_r13.t_Reselection_r13=1; - - //how to manage? - sib3_NB_IoT->freqBandInfo_r13 = NULL; - sib3_NB_IoT->multiBandInfoList_r13 = NULL; - - -///BCCH message (generate the SI message) - bcch_message->message.present = BCCH_DL_SCH_MessageType_NB_PR_c1; - bcch_message->message.choice.c1.present = BCCH_DL_SCH_MessageType_NB__c1_PR_systemInformation_r13; - - bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.present = SystemInformation_NB__criticalExtensions_PR_systemInformation_r13; - bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.choice.systemInformation_r13.sib_TypeAndInfo_r13.list.count=0; - - ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.choice.systemInformation_r13.sib_TypeAndInfo_r13.list, - sib2_NB_part); - ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.choice.systemInformation_r13.sib_TypeAndInfo_r13.list, - sib3_NB_part); - -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message_NB, (void*)bcch_message); -#endif - enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_DL_SCH_Message_NB, - (void*)bcch_message, - carrier->SIB23_NB_IoT, - 900); -// AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", -// enc_rval.failed_type->name, enc_rval.encoded); - -//#if defined(ENABLE_ITTI)..... - - -#ifdef USER_MODE - LOG_D(RRC,"[NB-IoT] SystemInformation-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); -#endif - - if (enc_rval.encoded==-1) { - msg("[RRC] ASN1 : SI-NB encoding failed for SIB23_NB_IoT\n"); - return(-1); - } - - carrier->sib2_NB_IoT = sib2_NB_IoT; - carrier->sib3_NB_IoT = sib3_NB_IoT; - - return((enc_rval.encoded+7)/8); -} - -/*do_RRCConnectionSetup_NB_IoT--> the aim is to establish SRB1 and SRB1bis(implicitly)*/ -uint8_t do_RRCConnectionSetup_NB_IoT( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, - int CC_id, - uint8_t* const buffer, //Srb0.Tx_buffer.Payload - const uint8_t Transaction_id, - const NB_IoT_DL_FRAME_PARMS* const frame_parms, // maybe not used - SRB_ToAddModList_NB_r13_t** SRB_configList_NB_IoT, //for both SRB1bis and SRB1 - struct PhysicalConfigDedicated_NB_r13** physicalConfigDedicated_NB_IoT -) - -{ - - asn_enc_rval_t enc_rval; - - - //MP:logical channel group not defined for Nb-IoT - - //MP: logical channel priority pag 605 (is 1 for SRB1 and for SRB1bis should be the same) - //long* prioritySRB1 = NULL; - long* prioritySRB1bis = NULL; - BOOLEAN_t* logicalChannelSR_Prohibit =NULL; //pag 605 - BOOLEAN_t* npusch_AllSymbols= NULL; - -// struct SRB_ToAddMod_NB_r13* SRB1_config_NB = NULL; -// struct SRB_ToAddMod_NB_r13__rlc_Config_r13* SRB1_rlc_config_NB = NULL; -// struct SRB_ToAddMod_NB_r13__logicalChannelConfig_r13* SRB1_lchan_config_NB = NULL; - - struct SRB_ToAddMod_NB_r13* SRB1bis_config_NB_IoT = NULL; - struct SRB_ToAddMod_NB_r13__rlc_Config_r13* SRB1bis_rlc_config_NB_IoT = NULL; - struct SRB_ToAddMod_NB_r13__logicalChannelConfig_r13* SRB1bis_lchan_config_NB_IoT = NULL; - - //No UL_specific parameters for NB-IoT in LogicalChanelConfig-NB - - PhysicalConfigDedicated_NB_r13_t* physicalConfigDedicated2_NB_IoT = NULL; - DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; - RRCConnectionSetup_NB_t* rrcConnectionSetup_NB_IoT = NULL; - - memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(DL_CCCH_Message_NB_t)); - dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1; - dl_ccch_msg_NB_IoT.message.choice.c1.present = DL_CCCH_MessageType_NB__c1_PR_rrcConnectionSetup_r13; - rrcConnectionSetup_NB_IoT = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionSetup_r13; - - - if (*SRB_configList_NB_IoT) { - free(*SRB_configList_NB_IoT); - } - *SRB_configList_NB_IoT = CALLOC(1,sizeof(SRB_ToAddModList_NB_r13_t)); - -/// SRB1-------------------- - { -// SRB1_config_NB = CALLOC(1,sizeof(*SRB1_config_NB)); -// -// //no srb_Identity in SRB_ToAddMod_NB -// -// SRB1_rlc_config_NB = CALLOC(1,sizeof(*SRB1_rlc_config_NB)); -// SRB1_config_NB->rlc_Config_r13 = SRB1_rlc_config_NB; -// -// SRB1_rlc_config_NB->present = SRB_ToAddMod_NB_r13__rlc_Config_r13_PR_explicitValue; -// SRB1_rlc_config_NB->choice.explicitValue.present=RLC_Config_NB_r13_PR_am;//the only possible in NB_IoT -// -//// SRB1_rlc_config_NB->choice.explicitValue.choice.am.ul_AM_RLC_r13.t_PollRetransmit_r13 = enb_properties.properties[ctxt_pP->module_id]->srb1_timer_poll_retransmit_r13; -//// SRB1_rlc_config_NB->choice.explicitValue.choice.am.ul_AM_RLC_r13.maxRetxThreshold_r13 = enb_properties.properties[ctxt_pP->module_id]->srb1_max_retx_threshold_r13; -//// //(musT be disabled--> SRB1 config pag 640 specs ) -//// SRB1_rlc_config_NB->choice.explicitValue.choice.am.dl_AM_RLC_r13.enableStatusReportSN_Gap_r13 =NULL; -// -// -// SRB1_rlc_config_NB->choice.explicitValue.choice.am.ul_AM_RLC_r13.t_PollRetransmit_r13 = T_PollRetransmit_NB_r13_ms25000; -// SRB1_rlc_config_NB->choice.explicitValue.choice.am.ul_AM_RLC_r13.maxRetxThreshold_r13 = UL_AM_RLC_NB_r13__maxRetxThreshold_r13_t8; -// //(musT be disabled--> SRB1 config pag 640 specs ) -// SRB1_rlc_config_NB->choice.explicitValue.choice.am.dl_AM_RLC_r13.enableStatusReportSN_Gap_r13 = NULL; -// -// SRB1_lchan_config_NB = CALLOC(1,sizeof(*SRB1_lchan_config_NB)); -// SRB1_config_NB->logicalChannelConfig_r13 = SRB1_lchan_config_NB; -// -// SRB1_lchan_config_NB->present = SRB_ToAddMod_NB_r13__logicalChannelConfig_r13_PR_explicitValue; -// -// -// prioritySRB1 = CALLOC(1, sizeof(long)); -// *prioritySRB1 = 1; -// SRB1_lchan_config_NB->choice.explicitValue.priority_r13 = prioritySRB1; -// -// logicalChannelSR_Prohibit = CALLOC(1, sizeof(BOOLEAN_t)); -// *logicalChannelSR_Prohibit = 1; -// //schould be set to TRUE (specs pag 641) -// SRB1_lchan_config_NB->choice.explicitValue.logicalChannelSR_Prohibit_r13 = logicalChannelSR_Prohibit; -// -// //ADD SRB1 -// ASN_SEQUENCE_ADD(&(*SRB_configList_NB_IoT)->list,SRB1_config_NB); - } - -///SRB1bis (The configuration for SRB1 and SRB1bis is the same) the only difference is the logical channel identity = 3 but not set here - - SRB1bis_config_NB_IoT = CALLOC(1,sizeof(*SRB1bis_config_NB_IoT)); - - //no srb_Identity in SRB_ToAddMod_NB - SRB1bis_rlc_config_NB_IoT = CALLOC(1,sizeof(*SRB1bis_rlc_config_NB_IoT)); - SRB1bis_config_NB_IoT->rlc_Config_r13 = SRB1bis_rlc_config_NB_IoT; - - SRB1bis_rlc_config_NB_IoT->present = SRB_ToAddMod_NB_r13__rlc_Config_r13_PR_explicitValue; - SRB1bis_rlc_config_NB_IoT->choice.explicitValue.present=RLC_Config_NB_r13_PR_am;//MP: the only possible RLC config in NB_IoT - - SRB1bis_rlc_config_NB_IoT->choice.explicitValue.choice.am.ul_AM_RLC_r13.t_PollRetransmit_r13 = T_PollRetransmit_NB_r13_ms25000; - SRB1bis_rlc_config_NB_IoT->choice.explicitValue.choice.am.ul_AM_RLC_r13.maxRetxThreshold_r13 = UL_AM_RLC_NB_r13__maxRetxThreshold_r13_t8; - //(musT be disabled--> SRB1 config pag 640 specs ) - SRB1bis_rlc_config_NB_IoT->choice.explicitValue.choice.am.dl_AM_RLC_r13.enableStatusReportSN_Gap_r13 =NULL; - - SRB1bis_lchan_config_NB_IoT = CALLOC(1,sizeof(*SRB1bis_lchan_config_NB_IoT)); - SRB1bis_config_NB_IoT->logicalChannelConfig_r13 = SRB1bis_lchan_config_NB_IoT; - - SRB1bis_lchan_config_NB_IoT->present = SRB_ToAddMod_NB_r13__logicalChannelConfig_r13_PR_explicitValue; - - prioritySRB1bis = CALLOC(1, sizeof(long)); - *prioritySRB1bis = 1; //same as SRB1? - SRB1bis_lchan_config_NB_IoT->choice.explicitValue.priority_r13 = prioritySRB1bis; - - logicalChannelSR_Prohibit = CALLOC(1, sizeof(BOOLEAN_t)); - *logicalChannelSR_Prohibit = 1; //schould be set to TRUE (specs pag 641) - SRB1bis_lchan_config_NB_IoT->choice.explicitValue.logicalChannelSR_Prohibit_r13 = logicalChannelSR_Prohibit; - - //ADD SRB1bis - //MP: Actually there is no way to distinguish SRB1 and SRB1bis once put in the list - //MP: SRB_ToAddModList_NB_r13_t size = 1 - ASN_SEQUENCE_ADD(&(*SRB_configList_NB_IoT)->list,SRB1bis_config_NB_IoT); - - - // PhysicalConfigDedicated (NPDCCH, NPUSCH, CarrierConfig, UplinkPowerControl) - - physicalConfigDedicated2_NB_IoT = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT)); - *physicalConfigDedicated_NB_IoT = physicalConfigDedicated2_NB_IoT; - - physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13= CALLOC(1, sizeof(*physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13)); - physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13 = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13)); - physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13 = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13)); - physicalConfigDedicated2_NB_IoT->uplinkPowerControlDedicated_r13 = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT->uplinkPowerControlDedicated_r13)); - - //no tpc, no cqi and no pucch, no pdsch, no soundingRS, no AntennaInfo, no scheduling request config - - /* - * NB-IoT supports the operation with either one or two antenna ports, AP0 and AP1. - * For the latter case, Space Frequency Block Coding (SFBC) is applied. - * Once selected, the same transmission scheme applies to NPBCH, NPDCCH, and NPDSCH. - * */ - - //FIXME: MP: CarrierConfigDedicated check the set values ---------------------------------------------- - - //DL - - physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.dl_CarrierFreq_r13.carrierFreq_r13=0;//random value set - physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.downlinkBitmapNonAnchor_r13= CALLOC(1,sizeof(struct DL_CarrierConfigDedicated_NB_r13__downlinkBitmapNonAnchor_r13)); - physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.downlinkBitmapNonAnchor_r13->present= - DL_CarrierConfigDedicated_NB_r13__downlinkBitmapNonAnchor_r13_PR_useNoBitmap_r13; - - physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.dl_GapNonAnchor_r13 = CALLOC(1,sizeof(struct DL_CarrierConfigDedicated_NB_r13__dl_GapNonAnchor_r13)); - physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.dl_GapNonAnchor_r13->present = - DL_CarrierConfigDedicated_NB_r13__dl_GapNonAnchor_r13_PR_useNoGap_r13; - - physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.inbandCarrierInfo_r13= NULL; - - //UL - physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->ul_CarrierConfig_r13.ul_CarrierFreq_r13= NULL; - - // NPDCCH - physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13->npdcch_NumRepetitions_r13 =0; - physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13->npdcch_Offset_USS_r13 =0; - physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13->npdcch_StartSF_USS_r13=0; - - // NPUSCH //(specs TS 36.331 v14.2.1 pag 643) /* OPTIONAL */ - physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13->ack_NACK_NumRepetitions_r13= NULL; - npusch_AllSymbols= CALLOC(1, sizeof(BOOLEAN_t)); - *npusch_AllSymbols= 1; //TRUE - physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13->npusch_AllSymbols_r13= npusch_AllSymbols; /* OPTIONAL */ - physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13->groupHoppingDisabled_r13=NULL; /* OPTIONAL */ - - // UplinkPowerControlDedicated - physicalConfigDedicated2_NB_IoT->uplinkPowerControlDedicated_r13->p0_UE_NPUSCH_r13 = 0; // 0 dB (specs TS36.331 v14.2.1 pag 643) - - - //Fill the rrcConnectionSetup-NB message - rrcConnectionSetup_NB_IoT->rrc_TransactionIdentifier = Transaction_id; //input value - rrcConnectionSetup_NB_IoT->criticalExtensions.present = RRCConnectionSetup_NB__criticalExtensions_PR_c1; - rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.present =RRCConnectionSetup_NB__criticalExtensions__c1_PR_rrcConnectionSetup_r13 ; - //MP: carry only SRB1bis at the moment and phyConfigDedicated - rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.srb_ToAddModList_r13 = *SRB_configList_NB_IoT; - rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.drb_ToAddModList_r13 = NULL; - rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.drb_ToReleaseList_r13 = NULL; - rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.rlf_TimersAndConstants_r13 = NULL; - rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.physicalConfigDedicated_r13 = physicalConfigDedicated2_NB_IoT; - rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.mac_MainConfig_r13 = NULL; - -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_DL_CCCH_Message, (void*)&dl_ccch_msg); -#endif - enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, - (void*)&dl_ccch_msg_NB_IoT, - buffer, - 100); - - if (enc_rval.encoded <= 0) { - LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - } - -#ifdef USER_MODE - LOG_D(RRC,"RRCConnectionSetup-NB Encoded %zd bits (%zd bytes), ecause %d\n", - enc_rval.encoded,(enc_rval.encoded+7)/8,ecause); -#endif - - return((enc_rval.encoded+7)/8); -} - -/*do_SecurityModeCommand - exactly the same as previous implementation*/ -uint8_t do_SecurityModeCommand_NB_IoT( - const protocol_ctxt_t* const ctxt_pP, - uint8_t* const buffer, - const uint8_t Transaction_id, - const uint8_t cipheringAlgorithm, - const uint8_t integrityProtAlgorithm) -{ - DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; - asn_enc_rval_t enc_rval; - - memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t)); - - dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; - dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_securityModeCommand_r13; - - dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.rrc_TransactionIdentifier = Transaction_id; - dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.present = SecurityModeCommand__criticalExtensions_PR_c1; - - dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.choice.c1.present = - SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8; - - // the two following information could be based on the mod_id - dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm - = (CipheringAlgorithm_r12_t)cipheringAlgorithm; //bug solved - - dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm - = (e_SecurityAlgorithmConfig__integrityProtAlgorithm)integrityProtAlgorithm; - -//only changed "asn_DEF_DL_DCCH_Message_NB" -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_DL_DCCH_Message_NB, (void*)&dl_dcch_msg_NB_IoT); -#endif - enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, - (void*)&dl_dcch_msg_NB_IoT, - buffer, - 100); - if (enc_rval.encoded <= 0) { - LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - } - - -//#if defined(ENABLE_ITTI) -//# if !defined(DISABLE_XER_SPRINT).... - -#ifdef USER_MODE - LOG_D(RRC,"[NB-IoT %d] securityModeCommand-NB for UE %x Encoded %zd bits (%zd bytes)\n", - ctxt_pP->module_id, - ctxt_pP->rnti, - enc_rval.encoded, - (enc_rval.encoded+7)/8); -#endif - - if (enc_rval.encoded==-1) { - LOG_E(RRC,"[NB-IoT %d] ASN1 : securityModeCommand-NB encoding failed for UE %x\n", - ctxt_pP->module_id, - ctxt_pP->rnti); - return(-1); - } - - return((enc_rval.encoded+7)/8); -} - -/*do_UECapabilityEnquiry_NB_IoT - very similar to legacy lte*/ -uint8_t do_UECapabilityEnquiry_NB_IoT( - const protocol_ctxt_t* const ctxt_pP, - uint8_t* const buffer, - const uint8_t Transaction_id -) - -{ - - DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; - //no RAT type in NB-IoT - asn_enc_rval_t enc_rval; - - memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t)); - - dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; - dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_ueCapabilityEnquiry_r13; - - dl_dcch_msg_NB_IoT.message.choice.c1.choice.ueCapabilityEnquiry_r13.rrc_TransactionIdentifier = Transaction_id; - - dl_dcch_msg_NB_IoT.message.choice.c1.choice.ueCapabilityEnquiry_r13.criticalExtensions.present = UECapabilityEnquiry_NB__criticalExtensions_PR_c1; - dl_dcch_msg_NB_IoT.message.choice.c1.choice.ueCapabilityEnquiry_r13.criticalExtensions.choice.c1.present = - UECapabilityEnquiry_NB__criticalExtensions__c1_PR_ueCapabilityEnquiry_r13; - - //no ue_CapabilityRequest (list of RAT_Type) - -//only changed "asn_DEF_DL_DCCH_Message_NB" -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_DL_DCCH_Message_NB, (void*)&dl_dcch_msg_NB_IoT); -#endif - enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, - (void*)&dl_dcch_msg_NB_IoT, - buffer, - 100); - if (enc_rval.encoded <= 0) { - LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - } - -//#if defined(ENABLE_ITTI) -//# if !defined(DISABLE_XER_SPRINT).... - -#ifdef USER_MODE - LOG_D(RRC,"[NB-IoT %d] UECapabilityEnquiry-NB for UE %x Encoded %zd bits (%zd bytes)\n", - ctxt_pP->module_id, - ctxt_pP->rnti, - enc_rval.encoded, - (enc_rval.encoded+7)/8); -#endif - - if (enc_rval.encoded==-1) { - LOG_E(RRC,"[NB-IoT %d] ASN1 : UECapabilityEnquiry-NB encoding failed for UE %x\n", - ctxt_pP->module_id, - ctxt_pP->rnti); - return(-1); - } - - return((enc_rval.encoded+7)/8); -} - -/*do_RRCConnectionReconfiguration_NB_IoT-->may convey information for resource configuration - * (including RBs, MAC main configuration and physical channel configuration) - * including any associated dedicated NAS information.*/ -uint16_t do_RRCConnectionReconfiguration_NB_IoT( - const protocol_ctxt_t* const ctxt_pP, - uint8_t *buffer, - uint8_t Transaction_id, - SRB_ToAddModList_NB_r13_t *SRB1_list_NB, //SRB_ConfigList2 (default)--> only SRB1 - DRB_ToAddModList_NB_r13_t *DRB_list_NB_IoT, //DRB_ConfigList (default) - DRB_ToReleaseList_NB_r13_t *DRB_list2_NB_IoT, //is NULL when passed - struct PhysicalConfigDedicated_NB_r13 *physicalConfigDedicated_NB_IoT, - MAC_MainConfig_NB_r13_t *mac_MainConfig_NB_IoT, - struct RRCConnectionReconfiguration_NB_r13_IEs__dedicatedInfoNASList_r13* dedicatedInfoNASList_NB_IoT) - -{ - - //check on DRB_list if contains more than 2 DRB? - - asn_enc_rval_t enc_rval; - DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; - RRCConnectionReconfiguration_NB_t *rrcConnectionReconfiguration_NB; - - - memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t)); - - dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; - dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_rrcConnectionReconfiguration_r13; - rrcConnectionReconfiguration_NB = &dl_dcch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReconfiguration_r13; - - // RRCConnectionReconfiguration - rrcConnectionReconfiguration_NB->rrc_TransactionIdentifier = Transaction_id; - rrcConnectionReconfiguration_NB->criticalExtensions.present = RRCConnectionReconfiguration_NB__criticalExtensions_PR_c1; - rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.present =RRCConnectionReconfiguration_NB__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r13 ; - - //RAdioResourceconfigDedicated - rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13 = - CALLOC(1,sizeof(*rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13)); - rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->srb_ToAddModList_r13 = SRB1_list_NB; //only SRB1 - rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->drb_ToAddModList_r13 = DRB_list_NB_IoT; - rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->drb_ToReleaseList_r13 = DRB_list2_NB_IoT; //NULL - rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->physicalConfigDedicated_r13 = physicalConfigDedicated_NB_IoT; - //FIXME may not used now - //rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->rlf_TimersAndConstants_r13 - - if (mac_MainConfig_NB_IoT!=NULL) { - rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13 = - CALLOC(1, sizeof(*rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13)); - rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13->present - =RadioResourceConfigDedicated_NB_r13__mac_MainConfig_r13_PR_explicitValue_r13; - //why memcopy only this one? - memcpy(&rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13->choice.explicitValue_r13, - mac_MainConfig_NB_IoT, sizeof(*mac_MainConfig_NB_IoT)); - - } else { - rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13=NULL; - } - - //no measConfig, measIDlist - //no mobilityControlInfo - - rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.dedicatedInfoNASList_r13 = dedicatedInfoNASList_NB_IoT; - //mainly used for cell-reselection/handover purposes?? - rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.fullConfig_r13 = NULL; - - enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, - (void*)&dl_dcch_msg_NB_IoT, - buffer, - RRC_BUF_SIZE); - if (enc_rval.encoded <= 0) { - LOG_F(RRC, "ASN1 message encoding failed %s, %li\n", - enc_rval.failed_type->name, enc_rval.encoded); - } - - //changed only asn_DEF_DL_DCCH_Message_NB -#ifdef XER_PRINT - xer_fprint(stdout,&asn_DEF_DL_DCCH_Message_NB,(void*)&dl_dcch_msg_NB_IoT); -#endif - -//#if defined(ENABLE_ITTI) -//# if !defined(DISABLE_XER_SPRINT)... - - - LOG_I(RRC,"RRCConnectionReconfiguration-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); - - return((enc_rval.encoded+7)/8); -} - -/*do_RRCConnectionReestablishmentReject - exactly the same as legacy LTE*/ -uint8_t do_RRCConnectionReestablishmentReject_NB_IoT( - uint8_t Mod_id, - uint8_t* const buffer) -{ - - asn_enc_rval_t enc_rval; - - DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; - RRCConnectionReestablishmentReject_t *rrcConnectionReestablishmentReject; - - memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(DL_CCCH_Message_NB_t)); - dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1; - dl_ccch_msg_NB_IoT.message.choice.c1.present = DL_CCCH_MessageType_NB__c1_PR_rrcConnectionReestablishmentReject_r13; - rrcConnectionReestablishmentReject = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReestablishmentReject_r13; - - // RRCConnectionReestablishmentReject //exactly the same as LTE - rrcConnectionReestablishmentReject->criticalExtensions.present = RRCConnectionReestablishmentReject__criticalExtensions_PR_rrcConnectionReestablishmentReject_r8; - - //Only change in "asn_DEF_DL_CCCH_Message_NB" -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_DL_CCCH_Message_NB, (void*)&dl_ccch_msg_NB_IoT); -#endif - enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, - (void*)&dl_ccch_msg_NB_IoT, - buffer, - 100); - if (enc_rval.encoded <= 0) { - LOG_F(RRC,"ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - } - - //Only change in "asn_DEF_DL_CCCH_Message_NB" -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) - { - char message_string[20000]; - size_t message_string_size; - - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); - } - } -# endif -#endif - -#ifdef USER_MODE - LOG_D(RRC,"RRCConnectionReestablishmentReject Encoded %zd bits (%zd bytes)\n", - enc_rval.encoded,(enc_rval.encoded+7)/8); -#endif - - return((enc_rval.encoded+7)/8); -} - -/*do_RRCConnectionReject_NB_IoT*/ -uint8_t do_RRCConnectionReject_NB_IoT( - uint8_t Mod_id, - uint8_t* const buffer) - -{ - - asn_enc_rval_t enc_rval; - - DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; - RRCConnectionReject_NB_t *rrcConnectionReject_NB_IoT; - - memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(DL_CCCH_Message_NB_t)); - dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1; - dl_ccch_msg_NB_IoT.message.choice.c1.present = DL_CCCH_MessageType_NB__c1_PR_rrcConnectionReject_r13; - rrcConnectionReject_NB_IoT = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReject_r13; - - // RRCConnectionReject-NB_IoT - rrcConnectionReject_NB_IoT->criticalExtensions.present = RRCConnectionReject_NB__criticalExtensions_PR_c1; - rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.present = RRCConnectionReject_NB__criticalExtensions__c1_PR_rrcConnectionReject_r13; - /* let's put an extended wait time of 1s for the moment */ - rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReject_r13.extendedWaitTime_r13 = 1; - //new-use of suspend indication - //If present, this field indicates that the UE should remain suspended and not release its stored context. - rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReject_r13.rrc_SuspendIndication_r13= - CALLOC(1, sizeof(long)); - *(rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReject_r13.rrc_SuspendIndication_r13)= - RRCConnectionReject_NB_r13_IEs__rrc_SuspendIndication_r13_true; - - //Only Modified "asn_DEF_DL_CCCH_Message_NB" -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_DL_CCCH_Message_NB, (void*)&dl_ccch_msg); -#endif - enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, - (void*)&dl_ccch_msg_NB_IoT, - buffer, - 100); - if (enc_rval.encoded <= 0) { - LOG_F(RRC, "ASN1 message encoding failed (%s, %ld)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - } - -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) - { - char message_string[20000]; - size_t message_string_size; - - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); - } - } -# endif -#endif - -#ifdef USER_MODE - LOG_D(RRC,"RRCConnectionReject-NB Encoded %zd bits (%zd bytes)\n", - enc_rval.encoded,(enc_rval.encoded+7)/8); -#endif - - return((enc_rval.encoded+7)/8); -} - - -//no do_MBSFNAreaConfig(..) in NB-IoT -//no do_MeasurementReport(..) in NB-IoT - -/*do_DLInformationTransfer_NB*/ -uint8_t do_DLInformationTransfer_NB_IoT( - uint8_t Mod_id, - uint8_t **buffer, - uint8_t transaction_id, - uint32_t pdu_length, - uint8_t *pdu_buffer) - -{ - ssize_t encoded; - - DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; - - memset(&dl_dcch_msg_NB_IoT, 0, sizeof(DL_DCCH_Message_NB_t)); - - dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; - dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_dlInformationTransfer_r13; - dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.rrc_TransactionIdentifier = transaction_id; - dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.present = DLInformationTransfer_NB__criticalExtensions_PR_c1; - dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.choice.c1.present = DLInformationTransfer_NB__criticalExtensions__c1_PR_dlInformationTransfer_r13; - dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.choice.c1.choice.dlInformationTransfer_r13.dedicatedInfoNAS_r13.size = pdu_length; - dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.choice.c1.choice.dlInformationTransfer_r13.dedicatedInfoNAS_r13.buf = pdu_buffer; - - encoded = uper_encode_to_new_buffer (&asn_DEF_DL_DCCH_Message_NB, NULL, (void*) &dl_dcch_msg_NB_IoT, (void **) buffer); - - //only change in "asn_DEF_DL_DCCH_Message_NB" -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) - { - char message_string[10000]; - size_t message_string_size; - - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_DCCH_Message_NB, (void *)&dl_dcch_msg_NB_IoT)) > 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, RRC_DL_DCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_dl_dcch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_dl_dcch.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); - } - } -# endif -#endif - - return encoded; -} - -/*do_ULInformationTransfer*/ -//for the moment is not needed (UE-SIDE) - -/*OAI_UECapability_t *fill_ue_capability*/ - -/*do_RRCConnectionReestablishment_NB-->used to re-establish SRB1*/ //which parameter to use? -uint8_t do_RRCConnectionReestablishment_NB_IoT( - uint8_t Mod_id, - uint8_t* const buffer, - const uint8_t Transaction_id, - const NB_IoT_DL_FRAME_PARMS* const frame_parms, //to be changed - SRB_ToAddModList_NB_r13_t* SRB_list_NB_IoT) //should contain SRB1 already configured? -{ - - asn_enc_rval_t enc_rval; - DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; - RRCConnectionReestablishment_NB_t* rrcConnectionReestablishment_NB_IoT; - - memset(&dl_ccch_msg_NB_IoT, 0, sizeof(DL_CCCH_Message_NB_t)); - - dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1; - dl_ccch_msg_NB_IoT.message.choice.c1.present = DL_CCCH_MessageType_NB__c1_PR_rrcConnectionReestablishment_r13; - rrcConnectionReestablishment_NB_IoT = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReestablishment_r13; - - //rrcConnectionReestablishment_NB - rrcConnectionReestablishment_NB_IoT->rrc_TransactionIdentifier = Transaction_id; - rrcConnectionReestablishment_NB_IoT->criticalExtensions.present = RRCConnectionReestablishment_NB__criticalExtensions_PR_c1; - rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.present = RRCConnectionReestablishment_NB__criticalExtensions__c1_PR_rrcConnectionReestablishment_r13; - - rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.srb_ToAddModList_r13 = SRB_list_NB_IoT; - rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.drb_ToAddModList_r13 = NULL; - rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.drb_ToReleaseList_r13 = NULL; - rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.rlf_TimersAndConstants_r13= NULL; - rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.mac_MainConfig_r13= NULL; - rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.physicalConfigDedicated_r13 = NULL; - - rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.nextHopChainingCount_r13=0; - - enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, - (void*)&dl_ccch_msg_NB_IoT, - buffer, - RRC_BUF_SIZE); - - if (enc_rval.encoded <= 0) { - LOG_F(RRC, "ASN1 message encoding failed (%s, %li)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - } - -#ifdef XER_PRINT - xer_fprint(stdout,&asn_DEF_DL_CCCH_Message_NB,(void*)&dl_ccch_msg_NB_IoT); -#endif - -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) - { - char message_string[30000]; - size_t message_string_size; - - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); - } - } -# endif -#endif - - LOG_I(RRC,"RRCConnectionReestablishment-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); - return 0; -} - -/*do_RRCConnectionRelease_NB--> is used to command the release of an RRC connection*/ -uint8_t do_RRCConnectionRelease_NB_IoT( - uint8_t Mod_id, - uint8_t *buffer, - const uint8_t Transaction_id) -{ - - asn_enc_rval_t enc_rval; - - DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; - RRCConnectionRelease_NB_t *rrcConnectionRelease_NB_IoT; - - - memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t)); - - dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; - dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_rrcConnectionRelease_r13; - rrcConnectionRelease_NB_IoT = &dl_dcch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionRelease_r13; - - // RRCConnectionRelease - rrcConnectionRelease_NB_IoT->rrc_TransactionIdentifier = Transaction_id; - rrcConnectionRelease_NB_IoT->criticalExtensions.present = RRCConnectionRelease_NB__criticalExtensions_PR_c1; - rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.present =RRCConnectionRelease_NB__criticalExtensions__c1_PR_rrcConnectionRelease_r13 ; - - rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.releaseCause_r13 = ReleaseCause_NB_r13_other; - rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.redirectedCarrierInfo_r13 = NULL; - rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.extendedWaitTime_r13 = NULL; - - //Why allocate memory for non critical extension? - rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.nonCriticalExtension=CALLOC(1, - sizeof(*rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.nonCriticalExtension)); - - enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, - (void*)&dl_dcch_msg_NB_IoT, - buffer, - RRC_BUF_SIZE);//check - - return((enc_rval.encoded+7)/8); -} - - - - +/* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file asn1_msg.c +* \brief primitives to build the asn1 messages +* \author Raymond Knopp, Navid Nikaein and Michele Paffetti +* \date 2011, 2017 +* \version 1.0 +* \company Eurecom +* \email: raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, michele.paffetti@studio.unibo.it +*/ + +#include +#include +#include /* for atoi(3) */ +#include /* for getopt(3) */ +#include /* for strerror(3) */ +#include /* for EX_* exit codes */ +#include /* for errno */ +#include "UTIL/LOG/log.h" +#include +#include /* for _ASN_DEFAULT_STACK_MAX */ +#include +#include "asn1_msg.h" + + + +//#include for NB-IoT------------------- +#include "RRCConnectionRequest-NB.h" +#include "BCCH-DL-SCH-Message-NB.h" +#include "UL-CCCH-Message-NB.h" +#include "UL-DCCH-Message-NB.h" +#include "DL-CCCH-Message-NB.h" +#include "DL-DCCH-Message-NB.h" +#include "EstablishmentCause-NB-r13.h" +#include "RRCConnectionSetup-NB.h" +#include "SRB-ToAddModList-NB-r13.h" +#include "DRB-ToAddModList-NB-r13.h" +#include "RRC/LITE/defs_NB_IoT.h" +#include "RRCConnectionSetupComplete-NB.h" +#include "RRCConnectionReconfigurationComplete-NB.h" +#include "RRCConnectionReconfiguration-NB.h" +#include "MasterInformationBlock-NB.h" +#include "SystemInformation-NB.h" +#include "SystemInformationBlockType1.h" +#include "SIB-Type-NB-r13.h" +#include "RRCConnectionResume-NB.h" +#include "RRCConnectionReestablishment-NB.h" +#include "../defs_NB_IoT.h" +//---------------------------------------- + +//#include "PHY/defs.h" +#include "enb_config.h" + +#if defined(ENABLE_ITTI) +# include "intertask_interface.h" +#endif + + + + +/*do_MIB_NB_NB_IoT*/ +uint8_t do_MIB_NB_IoT( + rrc_eNB_carrier_data_NB_IoT_t *carrier, + uint16_t N_RB_DL,//may not needed--> for NB_IoT only 1 PRB is used + uint32_t frame, + uint32_t hyper_frame) +{ + asn_enc_rval_t enc_rval; + BCCH_BCH_Message_NB_t *mib_NB_IoT = &(carrier->mib_NB_IoT); + + /* + * systemFrameNumber-MSB: (TS 36.331 pag 576) + * define the 4 MSB of the SFN (10 bits). The last significant 6 bits will be acquired implicitly by decoding the NPBCH + * NOTE: 6 LSB will be used for counting the 64 radio frames in the TTI period (640 ms) that is exactly the MIB period + * + * hyperSFN-LSB: + * indicates the 2 least significant bits of the HSFN. The remaining 8 bits are present in SIB1-NB + * NOTE: with the 2 bits we count the 4 HSFN (is 1 SIB1-Nb modification period) while the other 6 count the number of modification periods + * + * + * NOTE: in OAI never modify the SIB messages!!?? + */ + + //XXX check if correct the bit assignment + uint8_t sfn_MSB = (uint8_t)((frame>>6) & 0x0f); // all the 4 bits are set to 1 + uint8_t hsfn_LSB = (uint8_t)(hyper_frame & 0x03); //2 bits set to 1 (0x3 = 0011) + uint16_t spare=0; //11 bits --> use uint16 + + mib_NB_IoT->message.systemFrameNumber_MSB_r13.buf = &sfn_MSB; + mib_NB_IoT->message.systemFrameNumber_MSB_r13.size = 1; //if expressed in byte + mib_NB_IoT->message.systemFrameNumber_MSB_r13.bits_unused = 4; //is byte based (so how many bits you don't use of the 8 bits of a bite + + mib_NB_IoT->message.hyperSFN_LSB_r13.buf= &hsfn_LSB; + mib_NB_IoT->message.hyperSFN_LSB_r13.size= 1; + mib_NB_IoT->message.hyperSFN_LSB_r13.bits_unused = 6; + + //XXX to be set?? + mib_NB_IoT->message.spare.buf = (uint8_t *)&spare; + mib_NB_IoT->message.spare.size = 2; + mib_NB_IoT->message.spare.bits_unused = 5; + + //decide how to set it + mib_NB_IoT->message.schedulingInfoSIB1_r13 =11; //see TS 36.213-->tables 16.4.1.3-3 ecc... + mib_NB_IoT->message.systemInfoValueTag_r13= 0; + mib_NB_IoT->message.ab_Enabled_r13 = 0; + + //to be decided + mib_NB_IoT->message.operationModeInfo_r13.present = MasterInformationBlock_NB__operationModeInfo_r13_PR_inband_SamePCI_r13; + mib_NB_IoT->message.operationModeInfo_r13.choice.inband_SamePCI_r13.eutra_CRS_SequenceInfo_r13 = 0; + + printf("[MIB] Initialization of frame information,sfn_MSB %x, hsfn_LSB %x\n", + (uint32_t)sfn_MSB, + (uint32_t)hsfn_LSB); + + enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_BCH_Message_NB, + (void*)mib_NB_IoT, + carrier->MIB_NB_IoT, + 100); + if(enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + + if (enc_rval.encoded==-1) { + return(-1); + } + + return((enc_rval.encoded+7)/8); + +} + +/*do_SIB1_NB*/ +uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, int CC_id, + rrc_eNB_carrier_data_NB_IoT_t *carrier, + NbIoTRrcConfigurationReq *configuration, + uint32_t frame + ) +{ + BCCH_DL_SCH_Message_NB_t *bcch_message= &(carrier->siblock1_NB_IoT); + SystemInformationBlockType1_NB_t **sib1_NB_IoT= &(carrier->sib1_NB_IoT); + + + asn_enc_rval_t enc_rval; + + PLMN_IdentityInfo_NB_r13_t PLMN_identity_info_NB_IoT; + MCC_MNC_Digit_t dummy_mcc[3],dummy_mnc[3]; + SchedulingInfo_NB_r13_t *schedulingInfo_NB_IoT; + SIB_Type_NB_r13_t *sib_type_NB_IoT; + + + long* attachWithoutPDN_Connectivity = NULL; + attachWithoutPDN_Connectivity = CALLOC(1,sizeof(long)); + long *nrs_CRS_PowerOffset=NULL; + nrs_CRS_PowerOffset = CALLOC(1, sizeof(long)); + long *eutraControlRegionSize=NULL; //this parameter should be set only if we are considering in-band operating mode (samePCI or differentPCI) + eutraControlRegionSize = CALLOC(1,sizeof(long)); + long systemInfoValueTagSI = 0; + + memset(bcch_message,0,sizeof(BCCH_DL_SCH_Message_NB_t)); + bcch_message->message.present = BCCH_DL_SCH_MessageType_NB_PR_c1; + bcch_message->message.choice.c1.present = BCCH_DL_SCH_MessageType_NB__c1_PR_systemInformationBlockType1_r13; + + //allocation + *sib1_NB_IoT = &bcch_message->message.choice.c1.choice.systemInformationBlockType1_r13; + + + /*TS 36.331 v14.2.0 pag 589 + * hyperSFN-MSB + * Indicates the 8 most significant bits of the hyper-SFN. Together with the hyper-LSB in MIB-NB the complete HSFN is build up + */ + //FIXME see if correct + uint8_t hyperSFN_MSB = (uint8_t) ((frame>>2)& 0xff); + + //XXX to be checked + (*sib1_NB_IoT)->hyperSFN_MSB_r13.buf = &hyperSFN_MSB; + (*sib1_NB_IoT)->hyperSFN_MSB_r13.size = 1; + (*sib1_NB_IoT)->hyperSFN_MSB_r13.bits_unused = 0; + + memset(&PLMN_identity_info_NB_IoT,0,sizeof(PLMN_IdentityInfo_NB_r13_t)); + + PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc = CALLOC(1,sizeof(*PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc)); + memset(PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc,0,sizeof(*PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc)); + + asn_set_empty(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list);//.size=0; + + //left as it is??? +#if defined(ENABLE_ITTI) + dummy_mcc[0] = (configuration->mcc / 100) % 10; + dummy_mcc[1] = (configuration->mcc / 10) % 10; + dummy_mcc[2] = (configuration->mcc / 1) % 10; +#else + dummy_mcc[0] = 0; + dummy_mcc[1] = 0; + dummy_mcc[2] = 1; +#endif + ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list,&dummy_mcc[0]); + ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list,&dummy_mcc[1]); + ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list,&dummy_mcc[2]); + + PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list.size=0; + PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list.count=0; + + +#if defined(ENABLE_ITTI) + + if (configuration->mnc >= 100) { + dummy_mnc[0] = (configuration->mnc / 100) % 10; + dummy_mnc[1] = (configuration->mnc / 10) % 10; + dummy_mnc[2] = (configuration->mnc / 1) % 10; + } else { + if (configuration->mnc_digit_length == 2) { + dummy_mnc[0] = (configuration->mnc / 10) % 10; + dummy_mnc[1] = (configuration->mnc / 1) % 10; + dummy_mnc[2] = 0xf; + } else { + dummy_mnc[0] = (configuration->mnc / 100) % 100; + dummy_mnc[1] = (configuration->mnc / 10) % 10; + dummy_mnc[2] = (configuration->mnc / 1) % 10; + } + } + +#else + dummy_mnc[0] = 0; + dummy_mnc[1] = 1; + dummy_mnc[2] = 0xf; +#endif + ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list,&dummy_mnc[0]); + ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list,&dummy_mnc[1]); + + if (dummy_mnc[2] != 0xf) { + ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list,&dummy_mnc[2]); + } + + //still set to "notReserved" as in the previous case + PLMN_identity_info_NB_IoT.cellReservedForOperatorUse_r13=PLMN_IdentityInfo_NB_r13__cellReservedForOperatorUse_r13_notReserved; + + *attachWithoutPDN_Connectivity = 0; + PLMN_identity_info_NB_IoT.attachWithoutPDN_Connectivity_r13 = attachWithoutPDN_Connectivity; + + ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.plmn_IdentityList_r13.list,&PLMN_identity_info_NB_IoT); + + // 16 bits = 2 byte + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf = MALLOC(2); //MALLOC works in byte + + //lefts as it is? +#if defined(ENABLE_ITTI) + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[0] = (configuration->tac >> 8) & 0xff; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[1] = (configuration->tac >> 0) & 0xff; +#else + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[0] = 0x00; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[1] = 0x01; +#endif + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.size=2; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.bits_unused=0; + + // 28 bits --> i have to use 32 bits = 4 byte + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf = MALLOC(8); // why allocate 8 byte? +#if defined(ENABLE_ITTI) + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[0] = (configuration->cell_identity >> 20) & 0xff; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[1] = (configuration->cell_identity >> 12) & 0xff; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[2] = (configuration->cell_identity >> 4) & 0xff; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[3] = (configuration->cell_identity << 4) & 0xf0; +#else + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[0] = 0x00; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[1] = 0x00; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[2] = 0x00; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[3] = 0x10; +#endif + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.size=4; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.bits_unused=4; + + //Still set to "notBarred" as in the previous case + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellBarred_r13=SystemInformationBlockType1_NB__cellAccessRelatedInfo_r13__cellBarred_r13_notBarred; + + //Still Set to "notAllowed" like in the previous case + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.intraFreqReselection_r13=SystemInformationBlockType1_NB__cellAccessRelatedInfo_r13__intraFreqReselection_r13_notAllowed; + + + (*sib1_NB_IoT)->cellSelectionInfo_r13.q_RxLevMin_r13=-65; //which value?? TS 36.331 V14.2.1 pag. 589 + (*sib1_NB_IoT)->cellSelectionInfo_r13.q_QualMin_r13 = 0; //FIXME new parameter for SIB1-NB, not present in SIB1 (for cell reselection but if not used the UE should apply the default value) + + (*sib1_NB_IoT)->p_Max_r13 = CALLOC(1, sizeof(P_Max_t)); + *((*sib1_NB_IoT)->p_Max_r13) = 23; + + //FIXME + (*sib1_NB_IoT)->freqBandIndicator_r13 = +#if defined(ENABLE_ITTI) + configuration->eutra_band; +#else + 5; //if not configured we use band 5 (UL: 824 MHz - 849MHz / DL: 869 MHz - 894 MHz FDD mode) +#endif + + //OPTIONAL new parameters, to be used? + /* + * freqBandInfo_r13 + * multiBandInfoList_r13 + * nrs_CRS_PowerOffset_r13 + * sib1_NB_IoT->downlinkBitmap_r13.choice.subframePattern10_r13 =(is a BIT_STRING) + */ + + + (*sib1_NB_IoT)->downlinkBitmap_r13 = CALLOC(1, sizeof(struct DL_Bitmap_NB_r13)); + ((*sib1_NB_IoT)->downlinkBitmap_r13)->present= DL_Bitmap_NB_r13_PR_NOTHING; + + *eutraControlRegionSize = 1; + (*sib1_NB_IoT)->eutraControlRegionSize_r13 = eutraControlRegionSize; + + + *nrs_CRS_PowerOffset= 0; + (*sib1_NB_IoT)->nrs_CRS_PowerOffset_r13 = nrs_CRS_PowerOffset; + + schedulingInfo_NB_IoT = (SchedulingInfo_NB_r13_t*) malloc (3*sizeof(SchedulingInfo_NB_r13_t)); + sib_type_NB_IoT = (SIB_Type_NB_r13_t *) malloc (3*sizeof(SIB_Type_NB_r13_t)); + + memset(&schedulingInfo_NB_IoT[0],0,sizeof(SchedulingInfo_NB_r13_t)); + memset(&schedulingInfo_NB_IoT[1],0,sizeof(SchedulingInfo_NB_r13_t)); + memset(&schedulingInfo_NB_IoT[2],0,sizeof(SchedulingInfo_NB_r13_t)); + memset(&sib_type_NB_IoT[0],0,sizeof(SIB_Type_NB_r13_t)); + memset(&sib_type_NB_IoT[1],0,sizeof(SIB_Type_NB_r13_t)); + memset(&sib_type_NB_IoT[2],0,sizeof(SIB_Type_NB_r13_t)); + + + // Now, follow the scheduler SIB configuration + // There is only one sib2+sib3 common setting + schedulingInfo_NB_IoT[0].si_Periodicity_r13=SchedulingInfo_NB_r13__si_Periodicity_r13_rf4096; + schedulingInfo_NB_IoT[0].si_RepetitionPattern_r13=SchedulingInfo_NB_r13__si_RepetitionPattern_r13_every2ndRF; //This Indicates the starting radio frames within the SI window used for SI message transmission. + schedulingInfo_NB_IoT[0].si_TB_r13= SchedulingInfo_NB_r13__si_TB_r13_b680;//208 bits + + + // This is for SIB2/3 + /*SIB3 --> There is no mapping information of SIB2 since it is always present + * in the first SystemInformation message + * listed in the schedulingInfoList list. + * */ + sib_type_NB_IoT[0]=SIB_Type_NB_r13_sibType3_NB_r13; + + ASN_SEQUENCE_ADD(&schedulingInfo_NB_IoT[0].sib_MappingInfo_r13.list,&sib_type_NB_IoT[0]); + ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->schedulingInfoList_r13.list,&schedulingInfo_NB_IoT[0]); + + //printf("[ASN Debug] SI P: %ld\n",(*sib1_NB_IoT)->schedulingInfoList_r13.list.array[0]->si_Periodicity_r13); + +#if defined(ENABLE_ITTI) + + if (configuration->frame_type == TDD) +#endif + { + //FIXME in NB-IoT mandatory to be FDD --> so must give an error + LOG_E(RRC,"[NB-IoT %d] Frame Type is TDD --> not supported by NB-IoT, exiting\n", Mod_id); //correct? + exit(-1); + } + + //FIXME which value chose for the following parameter + (*sib1_NB_IoT)->si_WindowLength_r13=SystemInformationBlockType1_NB__si_WindowLength_r13_ms160; + (*sib1_NB_IoT)->si_RadioFrameOffset_r13= 0; + + /*In Nb-IoT change/update of specific SI message can additionally be indicated by a SI message specific value tag + * systemInfoValueTagSI (there is no SystemInfoValueTag in SIB1-NB but only in MIB-NB) + *contained in systemInfoValueTagList_r13 + **/ + //FIXME correct? + (*sib1_NB_IoT)->systemInfoValueTagList_r13 = CALLOC(1, sizeof(struct SystemInfoValueTagList_NB_r13)); + asn_set_empty(&(*sib1_NB_IoT)->systemInfoValueTagList_r13->list); + ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->systemInfoValueTagList_r13->list,&systemInfoValueTagSI); + + +#ifdef XER_PRINT //generate xml files + xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message_NB, (void*)bcch_message); +#endif + + + enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_DL_SCH_Message_NB, + (void*)bcch_message, + carrier->SIB1_NB_IoT, + 100); + + if (enc_rval.encoded > 0){ + LOG_F(RRC,"ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + + +#ifdef USER_MODE + LOG_D(RRC,"[NB-IoT] SystemInformationBlockType1-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); +#endif + + if (enc_rval.encoded==-1) { + return(-1); + } + + return((enc_rval.encoded+7)/8); +} + +/*SIB23_NB_IoT*/ +//to be clarified is it is possible to carry SIB2 and SIB3 in the same SI message for NB-IoT? +uint8_t do_SIB23_NB_IoT(uint8_t Mod_id, + int CC_id, + rrc_eNB_carrier_data_NB_IoT_t *carrier,//MP: this is already a carrier[CC_id] + NbIoTRrcConfigurationReq *configuration ) //openair2/COMMON/rrc_messages_types.h +{ + struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member *sib2_NB_part; + struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member *sib3_NB_part; + + BCCH_DL_SCH_Message_NB_t *bcch_message = &(carrier->systemInformation_NB_IoT); //is the systeminformation-->BCCH_DL_SCH_Message_NB + SystemInformationBlockType2_NB_r13_t *sib2_NB_IoT; + SystemInformationBlockType3_NB_r13_t *sib3_NB_IoT; + + asn_enc_rval_t enc_rval; + RACH_Info_NB_r13_t rach_Info_NB_IoT; + NPRACH_Parameters_NB_r13_t *nprach_parameters; + + //optional + long *connEstFailOffset = NULL; + connEstFailOffset = CALLOC(1, sizeof(long)); + +// RSRP_ThresholdsNPRACH_InfoList_NB_r13_t *rsrp_ThresholdsPrachInfoList; +// RSRP_Range_t rsrp_range; + + ACK_NACK_NumRepetitions_NB_r13_t ack_nack_repetition; + struct NPUSCH_ConfigCommon_NB_r13__dmrs_Config_r13 *dmrs_config; + struct DL_GapConfig_NB_r13 *dl_Gap; + + long *srs_SubframeConfig; + srs_SubframeConfig= CALLOC(1, sizeof(long)); + + + if (bcch_message) { + memset(bcch_message,0,sizeof(BCCH_DL_SCH_Message_NB_t)); + } else { + LOG_E(RRC,"[NB-IoT %d] BCCH_MESSAGE_NB is null, exiting\n", Mod_id); + exit(-1); + } + + //before schould be allocated memory somewhere? +// if (!carrier->sib2_NB_IoT) { +// LOG_E(RRC,"[NB-IoT %d] sib2_NB_IoT is null, exiting\n", Mod_id); +// exit(-1); +// } +// +// if (!carrier->sib3_NB_IoT) { +// LOG_E(RRC,"[NB-IoT %d] sib3_NB_IoT is null, exiting\n", Mod_id); +// exit(-1); +// } + + + LOG_I(RRC,"[NB-IoT %d] Configuration SIB2/3\n", Mod_id); + + sib2_NB_part = CALLOC(1,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); + sib3_NB_part = CALLOC(1,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); + memset(sib2_NB_part,0,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); + memset(sib3_NB_part,0,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); + + sib2_NB_part->present = SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR_sib2_r13; + sib3_NB_part->present = SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR_sib3_r13; + + //may bug if not correct allocation of memory + carrier->sib2_NB_IoT = &sib2_NB_part->choice.sib2_r13; + carrier->sib3_NB_IoT = &sib3_NB_part->choice.sib3_r13; + sib2_NB_IoT = carrier->sib2_NB_IoT; + sib3_NB_IoT = carrier->sib3_NB_IoT; + + nprach_parameters = (NPRACH_Parameters_NB_r13_t *) malloc (3*sizeof(NPRACH_Parameters_NB_r13_t)); + + memset(&nprach_parameters[0],0,sizeof(NPRACH_Parameters_NB_r13_t)); + memset(&nprach_parameters[1],0,sizeof(NPRACH_Parameters_NB_r13_t)); + memset(&nprach_parameters[2],0,sizeof(NPRACH_Parameters_NB_r13_t)); + +/// SIB2-NB----------------------------------------- + + //Barring is manage by ab-Enabled in MIB-NB (but is not a struct as ac-BarringInfo in LTE legacy) + + //RACH Config. Common-------------------------------------------------------------- + sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.preambleTransMax_CE_r13 = + configuration->rach_preambleTransMax_CE_NB; + sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.powerRampingParameters_r13.powerRampingStep = + configuration->rach_powerRampingStep_NB; + sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.powerRampingParameters_r13.preambleInitialReceivedTargetPower = + configuration->rach_preambleInitialReceivedTargetPower_NB; + + rach_Info_NB_IoT.ra_ResponseWindowSize_r13 = configuration->rach_raResponseWindowSize_NB; + rach_Info_NB_IoT.mac_ContentionResolutionTimer_r13 = configuration-> rach_macContentionResolutionTimer_NB; + //rach_infoList max size = maxNPRACH-Resources-NB-r13 = 3 + ASN_SEQUENCE_ADD(&sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.rach_InfoList_r13.list,&rach_Info_NB_IoT); + + //TS 36.331 pag 614 --> if not present the value to infinity sould be used + *connEstFailOffset = 0; + + sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.connEstFailOffset_r13 = connEstFailOffset; /*OPTIONAL*/ + + + // BCCH-Config-NB-IoT---------------------------------------------------------------- + sib2_NB_IoT->radioResourceConfigCommon_r13.bcch_Config_r13.modificationPeriodCoeff_r13 + = configuration->bcch_modificationPeriodCoeff_NB; + + // PCCH-Config-NB-IoT----------------------------------------------------------------- + sib2_NB_IoT->radioResourceConfigCommon_r13.pcch_Config_r13.defaultPagingCycle_r13 + = configuration->pcch_defaultPagingCycle_NB; + sib2_NB_IoT->radioResourceConfigCommon_r13.pcch_Config_r13.nB_r13 = configuration->pcch_nB_NB; + sib2_NB_IoT->radioResourceConfigCommon_r13.pcch_Config_r13.npdcch_NumRepetitionPaging_r13 = configuration-> pcch_npdcch_NumRepetitionPaging_NB; + + //NPRACH-Config-NB-IoT----------------------------------------------------------------- + + sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.rsrp_ThresholdsPrachInfoList_r13 = NULL; + sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.nprach_CP_Length_r13 = configuration->nprach_CP_Length; + /*OPTIONAL*/ +// =CALLOC(1, sizeof(struct RSRP_ThresholdsNPRACH_InfoList_NB_r13)); //fatto uguale dopo +// rsrp_ThresholdsPrachInfoList = sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.rsrp_ThresholdsPrachInfoList_r13; +// rsrp_range = configuration->nprach_rsrp_range_NB; +// ASN_SEQUENCE_ADD(&rsrp_ThresholdsPrachInfoList->list,rsrp_range); + + // According configuration to set the 3 CE level configuration setting + + nprach_parameters[0].nprach_Periodicity_r13 = configuration->nprach_Periodicity[0]; + nprach_parameters[0].nprach_StartTime_r13 = configuration->nprach_StartTime[0]; + nprach_parameters[0].nprach_SubcarrierOffset_r13 = configuration->nprach_SubcarrierOffset[0]; + nprach_parameters[0].nprach_NumSubcarriers_r13 = configuration->nprach_NumSubcarriers[0]; + nprach_parameters[0].numRepetitionsPerPreambleAttempt_r13 = configuration->numRepetitionsPerPreambleAttempt_NB[0]; + nprach_parameters[0].nprach_SubcarrierMSG3_RangeStart_r13 = configuration->nprach_SubcarrierMSG3_RangeStart; + nprach_parameters[0].maxNumPreambleAttemptCE_r13 = configuration->maxNumPreambleAttemptCE_NB; + nprach_parameters[0].npdcch_NumRepetitions_RA_r13 = configuration->npdcch_NumRepetitions_RA[0]; + nprach_parameters[0].npdcch_StartSF_CSS_RA_r13 = configuration->npdcch_StartSF_CSS_RA[0]; + nprach_parameters[0].npdcch_Offset_RA_r13 = configuration->npdcch_Offset_RA[0]; + + nprach_parameters[1].nprach_Periodicity_r13 = configuration->nprach_Periodicity[1]; + nprach_parameters[1].nprach_StartTime_r13 = configuration->nprach_StartTime[1]; + nprach_parameters[1].nprach_SubcarrierOffset_r13 = configuration->nprach_SubcarrierOffset[1]; + nprach_parameters[1].nprach_NumSubcarriers_r13 = configuration->nprach_NumSubcarriers[1]; + nprach_parameters[1].numRepetitionsPerPreambleAttempt_r13 = configuration->numRepetitionsPerPreambleAttempt_NB[1]; + nprach_parameters[1].nprach_SubcarrierMSG3_RangeStart_r13 = configuration->nprach_SubcarrierMSG3_RangeStart; + nprach_parameters[1].maxNumPreambleAttemptCE_r13 = configuration->maxNumPreambleAttemptCE_NB; + nprach_parameters[1].npdcch_NumRepetitions_RA_r13 = configuration->npdcch_NumRepetitions_RA[1]; + nprach_parameters[1].npdcch_StartSF_CSS_RA_r13 = configuration->npdcch_StartSF_CSS_RA[1]; + nprach_parameters[1].npdcch_Offset_RA_r13 = configuration->npdcch_Offset_RA[1]; + + nprach_parameters[2].nprach_Periodicity_r13 = configuration->nprach_Periodicity[2]; + nprach_parameters[2].nprach_StartTime_r13 = configuration->nprach_StartTime[2]; + nprach_parameters[2].nprach_SubcarrierOffset_r13 = configuration->nprach_SubcarrierOffset[2]; + nprach_parameters[2].nprach_NumSubcarriers_r13 = configuration->nprach_NumSubcarriers[2]; + nprach_parameters[2].numRepetitionsPerPreambleAttempt_r13 = configuration->numRepetitionsPerPreambleAttempt_NB[2]; + nprach_parameters[2].nprach_SubcarrierMSG3_RangeStart_r13 = configuration->nprach_SubcarrierMSG3_RangeStart; + nprach_parameters[2].maxNumPreambleAttemptCE_r13 = configuration->maxNumPreambleAttemptCE_NB; + nprach_parameters[2].npdcch_NumRepetitions_RA_r13 = configuration->npdcch_NumRepetitions_RA[2]; + nprach_parameters[2].npdcch_StartSF_CSS_RA_r13 = configuration->npdcch_StartSF_CSS_RA[2]; + nprach_parameters[2].npdcch_Offset_RA_r13 = configuration->npdcch_Offset_RA[2]; + + + //nprach_parameterList have a max size of 3 possible nprach configuration (see maxNPRACH_Resources_NB_r13) + ASN_SEQUENCE_ADD(&sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.nprach_ParametersList_r13.list,&nprach_parameters[0]); + ASN_SEQUENCE_ADD(&sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.nprach_ParametersList_r13.list,&nprach_parameters[1]); + ASN_SEQUENCE_ADD(&sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.nprach_ParametersList_r13.list,&nprach_parameters[2]); + + // NPDSCH-Config NB-IOT + sib2_NB_IoT->radioResourceConfigCommon_r13.npdsch_ConfigCommon_r13.nrs_Power_r13= configuration->npdsch_nrs_Power; + + + //NPUSCH-Config NB-IoT---------------------------------------------------------------- + //list of size 3 (see maxNPRACH_Resources_NB_r13) + ack_nack_repetition = configuration-> npusch_ack_nack_numRepetitions_NB; //is an enumerative + ASN_SEQUENCE_ADD(&(sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.ack_NACK_NumRepetitions_Msg4_r13.list) ,&ack_nack_repetition); + + *srs_SubframeConfig = configuration->npusch_srs_SubframeConfig_NB; + sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.srs_SubframeConfig_r13= srs_SubframeConfig; /*OPTIONAL*/ + + + /*OPTIONAL*/ + dmrs_config = CALLOC(1,sizeof(struct NPUSCH_ConfigCommon_NB_r13__dmrs_Config_r13)); + dmrs_config->threeTone_CyclicShift_r13 = configuration->npusch_threeTone_CyclicShift_r13; + dmrs_config->sixTone_CyclicShift_r13 = configuration->npusch_sixTone_CyclicShift_r13; + + /*OPTIONAL + * -define the base sequence for a DMRS sequence in a cell with multi tone transmission (3,6,12) see TS 36.331 NPUSCH-Config-NB + * -if not defined will be calculated based on the cellID once we configure the phy layer (rrc_mac_config_req) through the config_sib2 */ + dmrs_config->threeTone_BaseSequence_r13 = NULL; + dmrs_config->sixTone_BaseSequence_r13 = NULL; + dmrs_config->twelveTone_BaseSequence_r13 = NULL; + + sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.dmrs_Config_r13 = dmrs_config; + + //ulReferenceSignalsNPUSCH + /*Reference Signal (RS) for UL in NB-IoT is called DRS (Demodulation Reference Signal) + * sequence-group hopping can be enabled or disabled by means of the cell-specific parameter groupHoppingEnabled_r13 + * sequence-group hopping can be disabled for certain specific UE through the parameter groupHoppingDisabled (physicalConfigDedicated) + * groupAssignmentNPUSCH--> is used for generate the sequence-shift pattern + */ + sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.ul_ReferenceSignalsNPUSCH_r13.groupHoppingEnabled_r13= configuration->npusch_groupHoppingEnabled; + sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.ul_ReferenceSignalsNPUSCH_r13.groupAssignmentNPUSCH_r13 =configuration->npusch_groupAssignmentNPUSCH_r13; + + + //dl_GAP---------------------------------------------------------------------------------/*OPTIONAL*/ + dl_Gap = CALLOC(1,sizeof(struct DL_GapConfig_NB_r13)); + dl_Gap->dl_GapDurationCoeff_r13= configuration-> dl_GapDurationCoeff_NB; + dl_Gap->dl_GapPeriodicity_r13= configuration->dl_GapPeriodicity_NB; + dl_Gap->dl_GapThreshold_r13= configuration->dl_GapThreshold_NB; + sib2_NB_IoT->radioResourceConfigCommon_r13.dl_Gap_r13 = dl_Gap; + + + // uplinkPowerControlCommon - NB-IoT------------------------------------------------------ + sib2_NB_IoT->radioResourceConfigCommon_r13.uplinkPowerControlCommon_r13.p0_NominalNPUSCH_r13 = configuration->npusch_p0_NominalNPUSCH; + sib2_NB_IoT->radioResourceConfigCommon_r13.uplinkPowerControlCommon_r13.deltaPreambleMsg3_r13 = configuration->deltaPreambleMsg3; + sib2_NB_IoT->radioResourceConfigCommon_r13.uplinkPowerControlCommon_r13.alpha_r13 = configuration->npusch_alpha; + //no deltaFlist_PUCCH and no UL cyclic prefix + + // UE Timers and Constants -NB-IoT-------------------------------------------------------- + sib2_NB_IoT->ue_TimersAndConstants_r13.t300_r13 = configuration-> ue_TimersAndConstants_t300_NB; + sib2_NB_IoT->ue_TimersAndConstants_r13.t301_r13 = configuration-> ue_TimersAndConstants_t301_NB; + sib2_NB_IoT->ue_TimersAndConstants_r13.t310_r13 = configuration-> ue_TimersAndConstants_t310_NB; + sib2_NB_IoT->ue_TimersAndConstants_r13.t311_r13 = configuration-> ue_TimersAndConstants_t311_NB; + sib2_NB_IoT->ue_TimersAndConstants_r13.n310_r13 = configuration-> ue_TimersAndConstants_n310_NB; + sib2_NB_IoT->ue_TimersAndConstants_r13.n311_r13 = configuration-> ue_TimersAndConstants_n311_NB; + + //other SIB2-NB Parameters-------------------------------------------------------------------------------- + sib2_NB_IoT->freqInfo_r13.additionalSpectrumEmission_r13 = 1; + sib2_NB_IoT->freqInfo_r13.ul_CarrierFreq_r13 = NULL; /*OPTIONAL*/ + + sib2_NB_IoT->timeAlignmentTimerCommon_r13=TimeAlignmentTimer_infinity;//TimeAlignmentTimer_sf5120; + + /*OPTIONAL*/ + sib2_NB_IoT->multiBandInfoList_r13 = NULL; + +/// SIB3-NB------------------------------------------------------- + + sib3_NB_IoT->cellReselectionInfoCommon_r13.q_Hyst_r13=SystemInformationBlockType3_NB_r13__cellReselectionInfoCommon_r13__q_Hyst_r13_dB4; + sib3_NB_IoT->cellReselectionServingFreqInfo_r13.s_NonIntraSearch_r13=0; //or define in configuration? + + sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_RxLevMin_r13 = -70; + //new + sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_QualMin_r13 = CALLOC(1,sizeof(*sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_QualMin_r13)); + *(sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_QualMin_r13)= 10; //a caso + + sib3_NB_IoT->intraFreqCellReselectionInfo_r13.p_Max_r13 = NULL; + sib3_NB_IoT->intraFreqCellReselectionInfo_r13.s_IntraSearchP_r13 = 31; // s_intraSearch --> s_intraSearchP!!! (they call in a different way) + sib3_NB_IoT->intraFreqCellReselectionInfo_r13.t_Reselection_r13=1; + + //how to manage? + sib3_NB_IoT->freqBandInfo_r13 = NULL; + sib3_NB_IoT->multiBandInfoList_r13 = NULL; + + +///BCCH message (generate the SI message) + bcch_message->message.present = BCCH_DL_SCH_MessageType_NB_PR_c1; + bcch_message->message.choice.c1.present = BCCH_DL_SCH_MessageType_NB__c1_PR_systemInformation_r13; + + bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.present = SystemInformation_NB__criticalExtensions_PR_systemInformation_r13; + bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.choice.systemInformation_r13.sib_TypeAndInfo_r13.list.count=0; + + ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.choice.systemInformation_r13.sib_TypeAndInfo_r13.list, + sib2_NB_part); + ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.choice.systemInformation_r13.sib_TypeAndInfo_r13.list, + sib3_NB_part); + +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message_NB, (void*)bcch_message); +#endif + enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_DL_SCH_Message_NB, + (void*)bcch_message, + carrier->SIB23_NB_IoT, + 900); +// AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", +// enc_rval.failed_type->name, enc_rval.encoded); + +//#if defined(ENABLE_ITTI)..... + + +#ifdef USER_MODE + LOG_D(RRC,"[NB-IoT] SystemInformation-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); +#endif + + if (enc_rval.encoded==-1) { + msg("[RRC] ASN1 : SI-NB encoding failed for SIB23_NB_IoT\n"); + return(-1); + } + + carrier->sib2_NB_IoT = sib2_NB_IoT; + carrier->sib3_NB_IoT = sib3_NB_IoT; + + return((enc_rval.encoded+7)/8); +} + +/*do_RRCConnectionSetup_NB_IoT--> the aim is to establish SRB1 and SRB1bis(implicitly)*/ +uint8_t do_RRCConnectionSetup_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, + int CC_id, + uint8_t* const buffer, //Srb0.Tx_buffer.Payload + const uint8_t Transaction_id, + const NB_IoT_DL_FRAME_PARMS* const frame_parms, // maybe not used + SRB_ToAddModList_NB_r13_t** SRB_configList_NB_IoT, //for both SRB1bis and SRB1 + struct PhysicalConfigDedicated_NB_r13** physicalConfigDedicated_NB_IoT +) + +{ + + asn_enc_rval_t enc_rval; + + + //MP:logical channel group not defined for Nb-IoT + + //MP: logical channel priority pag 605 (is 1 for SRB1 and for SRB1bis should be the same) + //long* prioritySRB1 = NULL; + long* prioritySRB1bis = NULL; + BOOLEAN_t* logicalChannelSR_Prohibit =NULL; //pag 605 + BOOLEAN_t* npusch_AllSymbols= NULL; + +// struct SRB_ToAddMod_NB_r13* SRB1_config_NB = NULL; +// struct SRB_ToAddMod_NB_r13__rlc_Config_r13* SRB1_rlc_config_NB = NULL; +// struct SRB_ToAddMod_NB_r13__logicalChannelConfig_r13* SRB1_lchan_config_NB = NULL; + + struct SRB_ToAddMod_NB_r13* SRB1bis_config_NB_IoT = NULL; + struct SRB_ToAddMod_NB_r13__rlc_Config_r13* SRB1bis_rlc_config_NB_IoT = NULL; + struct SRB_ToAddMod_NB_r13__logicalChannelConfig_r13* SRB1bis_lchan_config_NB_IoT = NULL; + + //No UL_specific parameters for NB-IoT in LogicalChanelConfig-NB + + PhysicalConfigDedicated_NB_r13_t* physicalConfigDedicated2_NB_IoT = NULL; + DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; + RRCConnectionSetup_NB_t* rrcConnectionSetup_NB_IoT = NULL; + + memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(DL_CCCH_Message_NB_t)); + dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1; + dl_ccch_msg_NB_IoT.message.choice.c1.present = DL_CCCH_MessageType_NB__c1_PR_rrcConnectionSetup_r13; + rrcConnectionSetup_NB_IoT = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionSetup_r13; + + + if (*SRB_configList_NB_IoT) { + free(*SRB_configList_NB_IoT); + } + *SRB_configList_NB_IoT = CALLOC(1,sizeof(SRB_ToAddModList_NB_r13_t)); + +/// SRB1-------------------- + { +// SRB1_config_NB = CALLOC(1,sizeof(*SRB1_config_NB)); +// +// //no srb_Identity in SRB_ToAddMod_NB +// +// SRB1_rlc_config_NB = CALLOC(1,sizeof(*SRB1_rlc_config_NB)); +// SRB1_config_NB->rlc_Config_r13 = SRB1_rlc_config_NB; +// +// SRB1_rlc_config_NB->present = SRB_ToAddMod_NB_r13__rlc_Config_r13_PR_explicitValue; +// SRB1_rlc_config_NB->choice.explicitValue.present=RLC_Config_NB_r13_PR_am;//the only possible in NB_IoT +// +//// SRB1_rlc_config_NB->choice.explicitValue.choice.am.ul_AM_RLC_r13.t_PollRetransmit_r13 = enb_properties.properties[ctxt_pP->module_id]->srb1_timer_poll_retransmit_r13; +//// SRB1_rlc_config_NB->choice.explicitValue.choice.am.ul_AM_RLC_r13.maxRetxThreshold_r13 = enb_properties.properties[ctxt_pP->module_id]->srb1_max_retx_threshold_r13; +//// //(musT be disabled--> SRB1 config pag 640 specs ) +//// SRB1_rlc_config_NB->choice.explicitValue.choice.am.dl_AM_RLC_r13.enableStatusReportSN_Gap_r13 =NULL; +// +// +// SRB1_rlc_config_NB->choice.explicitValue.choice.am.ul_AM_RLC_r13.t_PollRetransmit_r13 = T_PollRetransmit_NB_r13_ms25000; +// SRB1_rlc_config_NB->choice.explicitValue.choice.am.ul_AM_RLC_r13.maxRetxThreshold_r13 = UL_AM_RLC_NB_r13__maxRetxThreshold_r13_t8; +// //(musT be disabled--> SRB1 config pag 640 specs ) +// SRB1_rlc_config_NB->choice.explicitValue.choice.am.dl_AM_RLC_r13.enableStatusReportSN_Gap_r13 = NULL; +// +// SRB1_lchan_config_NB = CALLOC(1,sizeof(*SRB1_lchan_config_NB)); +// SRB1_config_NB->logicalChannelConfig_r13 = SRB1_lchan_config_NB; +// +// SRB1_lchan_config_NB->present = SRB_ToAddMod_NB_r13__logicalChannelConfig_r13_PR_explicitValue; +// +// +// prioritySRB1 = CALLOC(1, sizeof(long)); +// *prioritySRB1 = 1; +// SRB1_lchan_config_NB->choice.explicitValue.priority_r13 = prioritySRB1; +// +// logicalChannelSR_Prohibit = CALLOC(1, sizeof(BOOLEAN_t)); +// *logicalChannelSR_Prohibit = 1; +// //schould be set to TRUE (specs pag 641) +// SRB1_lchan_config_NB->choice.explicitValue.logicalChannelSR_Prohibit_r13 = logicalChannelSR_Prohibit; +// +// //ADD SRB1 +// ASN_SEQUENCE_ADD(&(*SRB_configList_NB_IoT)->list,SRB1_config_NB); + } + +///SRB1bis (The configuration for SRB1 and SRB1bis is the same) the only difference is the logical channel identity = 3 but not set here + + SRB1bis_config_NB_IoT = CALLOC(1,sizeof(*SRB1bis_config_NB_IoT)); + + //no srb_Identity in SRB_ToAddMod_NB + SRB1bis_rlc_config_NB_IoT = CALLOC(1,sizeof(*SRB1bis_rlc_config_NB_IoT)); + SRB1bis_config_NB_IoT->rlc_Config_r13 = SRB1bis_rlc_config_NB_IoT; + + SRB1bis_rlc_config_NB_IoT->present = SRB_ToAddMod_NB_r13__rlc_Config_r13_PR_explicitValue; + SRB1bis_rlc_config_NB_IoT->choice.explicitValue.present=RLC_Config_NB_r13_PR_am;//MP: the only possible RLC config in NB_IoT + + SRB1bis_rlc_config_NB_IoT->choice.explicitValue.choice.am.ul_AM_RLC_r13.t_PollRetransmit_r13 = T_PollRetransmit_NB_r13_ms25000; + SRB1bis_rlc_config_NB_IoT->choice.explicitValue.choice.am.ul_AM_RLC_r13.maxRetxThreshold_r13 = UL_AM_RLC_NB_r13__maxRetxThreshold_r13_t8; + //(musT be disabled--> SRB1 config pag 640 specs ) + SRB1bis_rlc_config_NB_IoT->choice.explicitValue.choice.am.dl_AM_RLC_r13.enableStatusReportSN_Gap_r13 =NULL; + + SRB1bis_lchan_config_NB_IoT = CALLOC(1,sizeof(*SRB1bis_lchan_config_NB_IoT)); + SRB1bis_config_NB_IoT->logicalChannelConfig_r13 = SRB1bis_lchan_config_NB_IoT; + + SRB1bis_lchan_config_NB_IoT->present = SRB_ToAddMod_NB_r13__logicalChannelConfig_r13_PR_explicitValue; + + prioritySRB1bis = CALLOC(1, sizeof(long)); + *prioritySRB1bis = 1; //same as SRB1? + SRB1bis_lchan_config_NB_IoT->choice.explicitValue.priority_r13 = prioritySRB1bis; + + logicalChannelSR_Prohibit = CALLOC(1, sizeof(BOOLEAN_t)); + *logicalChannelSR_Prohibit = 1; //schould be set to TRUE (specs pag 641) + SRB1bis_lchan_config_NB_IoT->choice.explicitValue.logicalChannelSR_Prohibit_r13 = logicalChannelSR_Prohibit; + + //ADD SRB1bis + //MP: Actually there is no way to distinguish SRB1 and SRB1bis once put in the list + //MP: SRB_ToAddModList_NB_r13_t size = 1 + ASN_SEQUENCE_ADD(&(*SRB_configList_NB_IoT)->list,SRB1bis_config_NB_IoT); + + + // PhysicalConfigDedicated (NPDCCH, NPUSCH, CarrierConfig, UplinkPowerControl) + + physicalConfigDedicated2_NB_IoT = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT)); + *physicalConfigDedicated_NB_IoT = physicalConfigDedicated2_NB_IoT; + + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13= CALLOC(1, sizeof(*physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13)); + physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13 = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13)); + physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13 = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13)); + physicalConfigDedicated2_NB_IoT->uplinkPowerControlDedicated_r13 = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT->uplinkPowerControlDedicated_r13)); + + //no tpc, no cqi and no pucch, no pdsch, no soundingRS, no AntennaInfo, no scheduling request config + + /* + * NB-IoT supports the operation with either one or two antenna ports, AP0 and AP1. + * For the latter case, Space Frequency Block Coding (SFBC) is applied. + * Once selected, the same transmission scheme applies to NPBCH, NPDCCH, and NPDSCH. + * */ + + //FIXME: MP: CarrierConfigDedicated check the set values ---------------------------------------------- + + //DL + + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.dl_CarrierFreq_r13.carrierFreq_r13=0;//random value set + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.downlinkBitmapNonAnchor_r13= CALLOC(1,sizeof(struct DL_CarrierConfigDedicated_NB_r13__downlinkBitmapNonAnchor_r13)); + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.downlinkBitmapNonAnchor_r13->present= + DL_CarrierConfigDedicated_NB_r13__downlinkBitmapNonAnchor_r13_PR_useNoBitmap_r13; + + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.dl_GapNonAnchor_r13 = CALLOC(1,sizeof(struct DL_CarrierConfigDedicated_NB_r13__dl_GapNonAnchor_r13)); + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.dl_GapNonAnchor_r13->present = + DL_CarrierConfigDedicated_NB_r13__dl_GapNonAnchor_r13_PR_useNoGap_r13; + + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.inbandCarrierInfo_r13= NULL; + + //UL + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->ul_CarrierConfig_r13.ul_CarrierFreq_r13= NULL; + + // NPDCCH + physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13->npdcch_NumRepetitions_r13 =0; + physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13->npdcch_Offset_USS_r13 =0; + physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13->npdcch_StartSF_USS_r13=0; + + // NPUSCH //(specs TS 36.331 v14.2.1 pag 643) /* OPTIONAL */ + physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13->ack_NACK_NumRepetitions_r13= NULL; + npusch_AllSymbols= CALLOC(1, sizeof(BOOLEAN_t)); + *npusch_AllSymbols= 1; //TRUE + physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13->npusch_AllSymbols_r13= npusch_AllSymbols; /* OPTIONAL */ + physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13->groupHoppingDisabled_r13=NULL; /* OPTIONAL */ + + // UplinkPowerControlDedicated + physicalConfigDedicated2_NB_IoT->uplinkPowerControlDedicated_r13->p0_UE_NPUSCH_r13 = 0; // 0 dB (specs TS36.331 v14.2.1 pag 643) + + + //Fill the rrcConnectionSetup-NB message + rrcConnectionSetup_NB_IoT->rrc_TransactionIdentifier = Transaction_id; //input value + rrcConnectionSetup_NB_IoT->criticalExtensions.present = RRCConnectionSetup_NB__criticalExtensions_PR_c1; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.present =RRCConnectionSetup_NB__criticalExtensions__c1_PR_rrcConnectionSetup_r13 ; + //MP: carry only SRB1bis at the moment and phyConfigDedicated + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.srb_ToAddModList_r13 = *SRB_configList_NB_IoT; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.drb_ToAddModList_r13 = NULL; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.drb_ToReleaseList_r13 = NULL; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.rlf_TimersAndConstants_r13 = NULL; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.physicalConfigDedicated_r13 = physicalConfigDedicated2_NB_IoT; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.mac_MainConfig_r13 = NULL; + +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_DL_CCCH_Message, (void*)&dl_ccch_msg); +#endif + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, + (void*)&dl_ccch_msg_NB_IoT, + buffer, + 100); + + if (enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + +#ifdef USER_MODE + LOG_D(RRC,"RRCConnectionSetup-NB Encoded %zd bits (%zd bytes), ecause %d\n", + enc_rval.encoded,(enc_rval.encoded+7)/8,ecause); +#endif + + return((enc_rval.encoded+7)/8); +} + +/*do_SecurityModeCommand - exactly the same as previous implementation*/ +uint8_t do_SecurityModeCommand_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t* const buffer, + const uint8_t Transaction_id, + const uint8_t cipheringAlgorithm, + const uint8_t integrityProtAlgorithm) +{ + DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + asn_enc_rval_t enc_rval; + + memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t)); + + dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_securityModeCommand_r13; + + dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.rrc_TransactionIdentifier = Transaction_id; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.present = SecurityModeCommand__criticalExtensions_PR_c1; + + dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.choice.c1.present = + SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8; + + // the two following information could be based on the mod_id + dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm + = (CipheringAlgorithm_r12_t)cipheringAlgorithm; //bug solved + + dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm + = (e_SecurityAlgorithmConfig__integrityProtAlgorithm)integrityProtAlgorithm; + +//only changed "asn_DEF_DL_DCCH_Message_NB" +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_DL_DCCH_Message_NB, (void*)&dl_dcch_msg_NB_IoT); +#endif + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, + (void*)&dl_dcch_msg_NB_IoT, + buffer, + 100); + if (enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + + +//#if defined(ENABLE_ITTI) +//# if !defined(DISABLE_XER_SPRINT).... + +#ifdef USER_MODE + LOG_D(RRC,"[NB-IoT %d] securityModeCommand-NB for UE %x Encoded %zd bits (%zd bytes)\n", + ctxt_pP->module_id, + ctxt_pP->rnti, + enc_rval.encoded, + (enc_rval.encoded+7)/8); +#endif + + if (enc_rval.encoded==-1) { + LOG_E(RRC,"[NB-IoT %d] ASN1 : securityModeCommand-NB encoding failed for UE %x\n", + ctxt_pP->module_id, + ctxt_pP->rnti); + return(-1); + } + + return((enc_rval.encoded+7)/8); +} + +/*do_UECapabilityEnquiry_NB_IoT - very similar to legacy lte*/ +uint8_t do_UECapabilityEnquiry_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t* const buffer, + const uint8_t Transaction_id +) + +{ + + DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + //no RAT type in NB-IoT + asn_enc_rval_t enc_rval; + + memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t)); + + dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_ueCapabilityEnquiry_r13; + + dl_dcch_msg_NB_IoT.message.choice.c1.choice.ueCapabilityEnquiry_r13.rrc_TransactionIdentifier = Transaction_id; + + dl_dcch_msg_NB_IoT.message.choice.c1.choice.ueCapabilityEnquiry_r13.criticalExtensions.present = UECapabilityEnquiry_NB__criticalExtensions_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.ueCapabilityEnquiry_r13.criticalExtensions.choice.c1.present = + UECapabilityEnquiry_NB__criticalExtensions__c1_PR_ueCapabilityEnquiry_r13; + + //no ue_CapabilityRequest (list of RAT_Type) + +//only changed "asn_DEF_DL_DCCH_Message_NB" +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_DL_DCCH_Message_NB, (void*)&dl_dcch_msg_NB_IoT); +#endif + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, + (void*)&dl_dcch_msg_NB_IoT, + buffer, + 100); + if (enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + +//#if defined(ENABLE_ITTI) +//# if !defined(DISABLE_XER_SPRINT).... + +#ifdef USER_MODE + LOG_D(RRC,"[NB-IoT %d] UECapabilityEnquiry-NB for UE %x Encoded %zd bits (%zd bytes)\n", + ctxt_pP->module_id, + ctxt_pP->rnti, + enc_rval.encoded, + (enc_rval.encoded+7)/8); +#endif + + if (enc_rval.encoded==-1) { + LOG_E(RRC,"[NB-IoT %d] ASN1 : UECapabilityEnquiry-NB encoding failed for UE %x\n", + ctxt_pP->module_id, + ctxt_pP->rnti); + return(-1); + } + + return((enc_rval.encoded+7)/8); +} + +/*do_RRCConnectionReconfiguration_NB_IoT-->may convey information for resource configuration + * (including RBs, MAC main configuration and physical channel configuration) + * including any associated dedicated NAS information.*/ +uint16_t do_RRCConnectionReconfiguration_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t *buffer, + uint8_t Transaction_id, + SRB_ToAddModList_NB_r13_t *SRB1_list_NB, //SRB_ConfigList2 (default)--> only SRB1 + DRB_ToAddModList_NB_r13_t *DRB_list_NB_IoT, //DRB_ConfigList (default) + DRB_ToReleaseList_NB_r13_t *DRB_list2_NB_IoT, //is NULL when passed + struct PhysicalConfigDedicated_NB_r13 *physicalConfigDedicated_NB_IoT, + MAC_MainConfig_NB_r13_t *mac_MainConfig_NB_IoT, + struct RRCConnectionReconfiguration_NB_r13_IEs__dedicatedInfoNASList_r13* dedicatedInfoNASList_NB_IoT) + +{ + + //check on DRB_list if contains more than 2 DRB? + + asn_enc_rval_t enc_rval; + DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + RRCConnectionReconfiguration_NB_t *rrcConnectionReconfiguration_NB; + + + memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t)); + + dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_rrcConnectionReconfiguration_r13; + rrcConnectionReconfiguration_NB = &dl_dcch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReconfiguration_r13; + + // RRCConnectionReconfiguration + rrcConnectionReconfiguration_NB->rrc_TransactionIdentifier = Transaction_id; + rrcConnectionReconfiguration_NB->criticalExtensions.present = RRCConnectionReconfiguration_NB__criticalExtensions_PR_c1; + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.present =RRCConnectionReconfiguration_NB__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r13 ; + + //RAdioResourceconfigDedicated + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13 = + CALLOC(1,sizeof(*rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13)); + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->srb_ToAddModList_r13 = SRB1_list_NB; //only SRB1 + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->drb_ToAddModList_r13 = DRB_list_NB_IoT; + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->drb_ToReleaseList_r13 = DRB_list2_NB_IoT; //NULL + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->physicalConfigDedicated_r13 = physicalConfigDedicated_NB_IoT; + //FIXME may not used now + //rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->rlf_TimersAndConstants_r13 + + if (mac_MainConfig_NB_IoT!=NULL) { + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13 = + CALLOC(1, sizeof(*rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13)); + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13->present + =RadioResourceConfigDedicated_NB_r13__mac_MainConfig_r13_PR_explicitValue_r13; + //why memcopy only this one? + memcpy(&rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13->choice.explicitValue_r13, + mac_MainConfig_NB_IoT, sizeof(*mac_MainConfig_NB_IoT)); + + } else { + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13=NULL; + } + + //no measConfig, measIDlist + //no mobilityControlInfo + + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.dedicatedInfoNASList_r13 = dedicatedInfoNASList_NB_IoT; + //mainly used for cell-reselection/handover purposes?? + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.fullConfig_r13 = NULL; + + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, + (void*)&dl_dcch_msg_NB_IoT, + buffer, + RRC_BUF_SIZE); + if (enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed %s, %li\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + + //changed only asn_DEF_DL_DCCH_Message_NB +#ifdef XER_PRINT + xer_fprint(stdout,&asn_DEF_DL_DCCH_Message_NB,(void*)&dl_dcch_msg_NB_IoT); +#endif + +//#if defined(ENABLE_ITTI) +//# if !defined(DISABLE_XER_SPRINT)... + + + LOG_I(RRC,"RRCConnectionReconfiguration-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + + return((enc_rval.encoded+7)/8); +} + +/*do_RRCConnectionReestablishmentReject - exactly the same as legacy LTE*/ +uint8_t do_RRCConnectionReestablishmentReject_NB_IoT( + uint8_t Mod_id, + uint8_t* const buffer) +{ + + asn_enc_rval_t enc_rval; + + DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; + RRCConnectionReestablishmentReject_t *rrcConnectionReestablishmentReject; + + memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(DL_CCCH_Message_NB_t)); + dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1; + dl_ccch_msg_NB_IoT.message.choice.c1.present = DL_CCCH_MessageType_NB__c1_PR_rrcConnectionReestablishmentReject_r13; + rrcConnectionReestablishmentReject = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReestablishmentReject_r13; + + // RRCConnectionReestablishmentReject //exactly the same as LTE + rrcConnectionReestablishmentReject->criticalExtensions.present = RRCConnectionReestablishmentReject__criticalExtensions_PR_rrcConnectionReestablishmentReject_r8; + + //Only change in "asn_DEF_DL_CCCH_Message_NB" +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_DL_CCCH_Message_NB, (void*)&dl_ccch_msg_NB_IoT); +#endif + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, + (void*)&dl_ccch_msg_NB_IoT, + buffer, + 100); + if (enc_rval.encoded <= 0) { + LOG_F(RRC,"ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + + //Only change in "asn_DEF_DL_CCCH_Message_NB" +#if defined(ENABLE_ITTI) +# if !defined(DISABLE_XER_SPRINT) + { + char message_string[20000]; + size_t message_string_size; + + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) { + MessageDef *msg_p; + + msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); + msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; + memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); + } + } +# endif +#endif + +#ifdef USER_MODE + LOG_D(RRC,"RRCConnectionReestablishmentReject Encoded %zd bits (%zd bytes)\n", + enc_rval.encoded,(enc_rval.encoded+7)/8); +#endif + + return((enc_rval.encoded+7)/8); +} + +/*do_RRCConnectionReject_NB_IoT*/ +uint8_t do_RRCConnectionReject_NB_IoT( + uint8_t Mod_id, + uint8_t* const buffer) + +{ + + asn_enc_rval_t enc_rval; + + DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; + RRCConnectionReject_NB_t *rrcConnectionReject_NB_IoT; + + memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(DL_CCCH_Message_NB_t)); + dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1; + dl_ccch_msg_NB_IoT.message.choice.c1.present = DL_CCCH_MessageType_NB__c1_PR_rrcConnectionReject_r13; + rrcConnectionReject_NB_IoT = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReject_r13; + + // RRCConnectionReject-NB_IoT + rrcConnectionReject_NB_IoT->criticalExtensions.present = RRCConnectionReject_NB__criticalExtensions_PR_c1; + rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.present = RRCConnectionReject_NB__criticalExtensions__c1_PR_rrcConnectionReject_r13; + /* let's put an extended wait time of 1s for the moment */ + rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReject_r13.extendedWaitTime_r13 = 1; + //new-use of suspend indication + //If present, this field indicates that the UE should remain suspended and not release its stored context. + rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReject_r13.rrc_SuspendIndication_r13= + CALLOC(1, sizeof(long)); + *(rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReject_r13.rrc_SuspendIndication_r13)= + RRCConnectionReject_NB_r13_IEs__rrc_SuspendIndication_r13_true; + + //Only Modified "asn_DEF_DL_CCCH_Message_NB" +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_DL_CCCH_Message_NB, (void*)&dl_ccch_msg); +#endif + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, + (void*)&dl_ccch_msg_NB_IoT, + buffer, + 100); + if (enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed (%s, %ld)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + +#if defined(ENABLE_ITTI) +# if !defined(DISABLE_XER_SPRINT) + { + char message_string[20000]; + size_t message_string_size; + + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) { + MessageDef *msg_p; + + msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); + msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; + memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); + } + } +# endif +#endif + +#ifdef USER_MODE + LOG_D(RRC,"RRCConnectionReject-NB Encoded %zd bits (%zd bytes)\n", + enc_rval.encoded,(enc_rval.encoded+7)/8); +#endif + + return((enc_rval.encoded+7)/8); +} + + +//no do_MBSFNAreaConfig(..) in NB-IoT +//no do_MeasurementReport(..) in NB-IoT + +/*do_DLInformationTransfer_NB*/ +uint8_t do_DLInformationTransfer_NB_IoT( + uint8_t Mod_id, + uint8_t **buffer, + uint8_t transaction_id, + uint32_t pdu_length, + uint8_t *pdu_buffer) + +{ + ssize_t encoded; + + DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + + memset(&dl_dcch_msg_NB_IoT, 0, sizeof(DL_DCCH_Message_NB_t)); + + dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_dlInformationTransfer_r13; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.rrc_TransactionIdentifier = transaction_id; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.present = DLInformationTransfer_NB__criticalExtensions_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.choice.c1.present = DLInformationTransfer_NB__criticalExtensions__c1_PR_dlInformationTransfer_r13; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.choice.c1.choice.dlInformationTransfer_r13.dedicatedInfoNAS_r13.size = pdu_length; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.choice.c1.choice.dlInformationTransfer_r13.dedicatedInfoNAS_r13.buf = pdu_buffer; + + encoded = uper_encode_to_new_buffer (&asn_DEF_DL_DCCH_Message_NB, NULL, (void*) &dl_dcch_msg_NB_IoT, (void **) buffer); + + //only change in "asn_DEF_DL_DCCH_Message_NB" +#if defined(ENABLE_ITTI) +# if !defined(DISABLE_XER_SPRINT) + { + char message_string[10000]; + size_t message_string_size; + + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_DCCH_Message_NB, (void *)&dl_dcch_msg_NB_IoT)) > 0) { + MessageDef *msg_p; + + msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, RRC_DL_DCCH, message_string_size + sizeof (IttiMsgText)); + msg_p->ittiMsg.rrc_dl_dcch.size = message_string_size; + memcpy(&msg_p->ittiMsg.rrc_dl_dcch.text, message_string, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); + } + } +# endif +#endif + + return encoded; +} + +/*do_ULInformationTransfer*/ +//for the moment is not needed (UE-SIDE) + +/*OAI_UECapability_t *fill_ue_capability*/ + +/*do_RRCConnectionReestablishment_NB-->used to re-establish SRB1*/ //which parameter to use? +uint8_t do_RRCConnectionReestablishment_NB_IoT( + uint8_t Mod_id, + uint8_t* const buffer, + const uint8_t Transaction_id, + const NB_IoT_DL_FRAME_PARMS* const frame_parms, //to be changed + SRB_ToAddModList_NB_r13_t* SRB_list_NB_IoT) //should contain SRB1 already configured? +{ + + asn_enc_rval_t enc_rval; + DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; + RRCConnectionReestablishment_NB_t* rrcConnectionReestablishment_NB_IoT; + + memset(&dl_ccch_msg_NB_IoT, 0, sizeof(DL_CCCH_Message_NB_t)); + + dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1; + dl_ccch_msg_NB_IoT.message.choice.c1.present = DL_CCCH_MessageType_NB__c1_PR_rrcConnectionReestablishment_r13; + rrcConnectionReestablishment_NB_IoT = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReestablishment_r13; + + //rrcConnectionReestablishment_NB + rrcConnectionReestablishment_NB_IoT->rrc_TransactionIdentifier = Transaction_id; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.present = RRCConnectionReestablishment_NB__criticalExtensions_PR_c1; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.present = RRCConnectionReestablishment_NB__criticalExtensions__c1_PR_rrcConnectionReestablishment_r13; + + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.srb_ToAddModList_r13 = SRB_list_NB_IoT; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.drb_ToAddModList_r13 = NULL; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.drb_ToReleaseList_r13 = NULL; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.rlf_TimersAndConstants_r13= NULL; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.mac_MainConfig_r13= NULL; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.physicalConfigDedicated_r13 = NULL; + + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.nextHopChainingCount_r13=0; + + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, + (void*)&dl_ccch_msg_NB_IoT, + buffer, + RRC_BUF_SIZE); + + if (enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed (%s, %li)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + +#ifdef XER_PRINT + xer_fprint(stdout,&asn_DEF_DL_CCCH_Message_NB,(void*)&dl_ccch_msg_NB_IoT); +#endif + +#if defined(ENABLE_ITTI) +# if !defined(DISABLE_XER_SPRINT) + { + char message_string[30000]; + size_t message_string_size; + + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) { + MessageDef *msg_p; + + msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); + msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; + memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); + } + } +# endif +#endif + + LOG_I(RRC,"RRCConnectionReestablishment-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + return 0; +} + +/*do_RRCConnectionRelease_NB--> is used to command the release of an RRC connection*/ +uint8_t do_RRCConnectionRelease_NB_IoT( + uint8_t Mod_id, + uint8_t *buffer, + const uint8_t Transaction_id) +{ + + asn_enc_rval_t enc_rval; + + DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + RRCConnectionRelease_NB_t *rrcConnectionRelease_NB_IoT; + + + memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t)); + + dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_rrcConnectionRelease_r13; + rrcConnectionRelease_NB_IoT = &dl_dcch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionRelease_r13; + + // RRCConnectionRelease + rrcConnectionRelease_NB_IoT->rrc_TransactionIdentifier = Transaction_id; + rrcConnectionRelease_NB_IoT->criticalExtensions.present = RRCConnectionRelease_NB__criticalExtensions_PR_c1; + rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.present =RRCConnectionRelease_NB__criticalExtensions__c1_PR_rrcConnectionRelease_r13 ; + + rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.releaseCause_r13 = ReleaseCause_NB_r13_other; + rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.redirectedCarrierInfo_r13 = NULL; + rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.extendedWaitTime_r13 = NULL; + + //Why allocate memory for non critical extension? + rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.nonCriticalExtension=CALLOC(1, + sizeof(*rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.nonCriticalExtension)); + + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, + (void*)&dl_dcch_msg_NB_IoT, + buffer, + RRC_BUF_SIZE);//check + + return((enc_rval.encoded+7)/8); +} + + + + diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.h b/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.h index e88bdadbd9..6fb073f80d 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.h +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.h @@ -1,293 +1,293 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file asn1_msg.h -* \brief primitives to build the asn1 messages -* \author Raymond Knopp, Navid Nikaein and Michele Paffetti -* \date 2011, 2017 -* \version 1.0 -* \company Eurecom -* \email: raymond.knopp@eurecom.fr ,navid.nikaein@eurecom.fr, michele.paffetti@studio.unibo.it -*/ - -#ifdef USER_MODE -#include -#include -#include /* for atoi(3) */ -#include /* for getopt(3) */ -#include /* for strerror(3) */ -#include /* for EX_* exit codes */ -#include /* for errno */ -#else -#include /* Needed by all modules */ -#endif - -#include -#include /* for _ASN_DEFAULT_STACK_MAX */ - - -#include "RRC/LITE/defs_NB_IoT.h" - -/* - * The variant of the above function which dumps the BASIC-XER (XER_F_BASIC) - * output into the chosen string buffer. - * RETURN VALUES: - * 0: The structure is printed. - * -1: Problem printing the structure. - * WARNING: No sensible error value is returned. - */ - - -/** -\brief Generate configuration for SIB1 (eNB). -@param carrier pointer to Carrier information -@param N_RB_DL Number of downlink PRBs -@param frame radio frame number -@return size of encoded bit stream in bytes*/ -uint8_t do_MIB_NB_IoT( - rrc_eNB_carrier_data_NB_IoT_t *carrier, - uint32_t N_RB_DL, - uint32_t frame, - uint32_t hyper_frame); - - -/** -\brief Generate a default configuration for SIB1-NB (eNB). -@param Mod_id Instance of eNB -@param CC_id Component carrier to configure -@param carrier pointer to Carrier information -@param configuration Pointer Configuration Request structure -@return size of encoded bit stream in bytes*/ - -uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, - int CC_id, - rrc_eNB_carrier_data_NB_IoT_t *carrier, - NbIoTRrcConfigurationReq *configuration, - uint32_t frame - ); - -/** -\brief Generate a default configuration for SIB2/SIB3-NB in one System Information PDU (eNB). -@param Mod_id Index of eNB (used to derive some parameters) -@param buffer Pointer to PER-encoded ASN.1 description of SI-NB PDU -@param systemInformation_NB_IoT Pointer to asn1c C representation of SI-NB PDU -@param sib2_NB Pointer (returned) to sib2_NB component withing SI-NB PDU -@param sib3_NB Pointer (returned) to sib3_NB component withing SI-NB PDU -@return size of encoded bit stream in bytes*/ - -uint8_t do_SIB23_NB_IoT(uint8_t Mod_id, - int CC_id, - rrc_eNB_carrier_data_NB_IoT_t *carrier, - NbIoTRrcConfigurationReq *configuration - ); - -/**(UE-SIDE) -\brief Generate an RRCConnectionRequest-NB UL-CCCH-Message (UE) based on random string or S-TMSI. This -routine only generates an mo-data establishment cause. -@param buffer Pointer to PER-encoded ASN.1 description of UL-DCCH-Message PDU -@param rv 5 byte random string or S-TMSI -@param Mod_id -@returns Size of encoded bit stream in bytes*/ - -uint8_t do_RRCConnectionRequest_NB_IoT(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv); - - -/**(UE -SIDE) -\brief Generate an RRCConnectionSetupComplete-NB UL-DCCH-Message (UE) -@param Mod_id -@param Transaction_id -@param dedicatedInfoNASLength -@param dedicatedInfoNAS -@param buffer Pointer to PER-encoded ASN.1 description of UL-DCCH-Message PDU -@returns Size of encoded bit stream in bytes*/ - -uint8_t do_RRCConnectionSetupComplete_NB_IoT(uint8_t Mod_id, uint8_t* buffer, const uint8_t Transaction_id, const int dedicatedInfoNASLength, - const char* dedicatedInfoNAS); - -/** (UE-SIDE) -\brief Generate an RRCConnectionReconfigurationComplete-NB UL-DCCH-Message (UE) -@param buffer Pointer to PER-encoded ASN.1 description of UL-DCCH-Message PDU -@param ctxt_pP -@param Transaction_id -@returns Size of encoded bit stream in bytes*/ - -uint8_t do_RRCConnectionReconfigurationComplete_NB_IoT( - const protocol_ctxt_t* const ctxt_pP, - uint8_t* buffer, - const uint8_t Transaction_id -); - -/** -\brief Generate an RRCConnectionSetup-NB DL-CCCH-Message (eNB). This routine configures SRB_ToAddMod (SRB1/SRB1bis-NB) and -PhysicalConfigDedicated-NB IEs. -@param ctxt_pP Running context -@param ue_context_pP UE context -@param CC_id Component Carrier ID -@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU -@param transmission_mode Transmission mode for UE (1-9) -@param UE_id UE index for this message -@param Transaction_id Transaction_ID for this message -@param SRB_configList Pointer (returned) to SRB1_config/SRB1bis_config(later) IEs for this UE -@param physicalConfigDedicated_NB Pointer (returned) to PhysicalConfigDedicated-NB IE for this UE -@returns Size of encoded bit stream in bytes*/ - -uint8_t do_RRCConnectionSetup_NB_IoT( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, - int CC_id, - uint8_t* const buffer, //carrier[CC_id].Srb0.Tx_buffer.Payload - const uint8_t Transaction_id, - const NB_IoT_DL_FRAME_PARMS* const frame_parms, //to be changed but not deleted - SRB_ToAddModList_NB_r13_t** SRB_configList_NB_IoT, //in order to be configured--> stanno puntando alla SRB_configlist dell ue_context - struct PhysicalConfigDedicated_NB_r13** physicalConfigDedicated_NB_IoT //in order to be configured--> stanno puntando alla physicalConfigDedicated dell ue_context -); - - -/** - * For which SRB is used in NB-IoT?? -\brief Generate an RRCConnectionReconfiguration-NB DL-DCCH-Message (eNB). This routine configures SRBToAddMod-NB (SRB1) and one DRBToAddMod-NB -(DRB3). PhysicalConfigDedicated-NB is not updated. -@param ctxt_pP Running context -@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU -@param Transaction_id Transaction_ID for this message -@param SRB_list_NB Pointer to SRB List to be added/modified (NULL if no additions/modifications) -@param DRB_list_NB Pointer to DRB List to be added/modified (NULL if no additions/modifications) -@param DRB_list2_NB Pointer to DRB List to be released (NULL if none to be released) -//sps not supported by NB-IoT -@param physicalConfigDedicated_NB Pointer to PhysicalConfigDedicated-NB to be modified (NULL if no modifications) -//measurement not supported by NB-IoT -@param mac_MainConfig Pointer to Mac_MainConfig(NULL if no modifications) -//no CBA functionalities -@returns Size of encoded bit stream in bytes*/ - -uint16_t -do_RRCConnectionReconfiguration_NB_IoT( - const protocol_ctxt_t* const ctxt_pP, - uint8_t *buffer, - uint8_t Transaction_id, - SRB_ToAddModList_NB_r13_t *SRB_list_NB_IoT, - DRB_ToAddModList_NB_r13_t *DRB_list_NB_IoT, - DRB_ToReleaseList_NB_r13_t *DRB_list2_NB_IoT, - struct PhysicalConfigDedicated_NB_r13 *physicalConfigDedicated, - MAC_MainConfig_t *mac_MainConfig, - struct RRCConnectionReconfiguration_NB_r13_IEs__dedicatedInfoNASList_r13* dedicatedInfoNASList_NB_IoT); - -/** - * E-UTRAN applies the procedure as follows: when only for NB-IoT SRB1 and SRB1bis is established - \brief Generate a SecurityModeCommand - @param ctxt_pP Running context - @param buffer Pointer to PER-encoded ASN.1 description - @param Transaction_id Transaction_ID for this message - @param cipheringAlgorithm - @param integrityProtAlgorithm - */ - -uint8_t do_SecurityModeCommand_NB_IoT( - const protocol_ctxt_t* const ctxt_pP, - uint8_t* const buffer, - const uint8_t Transaction_id, - const uint8_t cipheringAlgorithm, - const uint8_t integrityProtAlgorithm); - -/** - * E-UTRAN applies the procedure as follows: when only for NB-IoT SRB1 and SRB1bis is established - \brief Generate a SecurityModeCommand - @param ctxt_pP Running context - @param buffer Pointer to PER-encoded ASN.1 description - @param Transaction_id Transaction_ID for this message - */ - -uint8_t do_UECapabilityEnquiry_NB_IoT( - const protocol_ctxt_t* const ctxt_pP, - uint8_t* const buffer, - const uint8_t Transaction_id -); - - -/** - * There is nothing new in this type of message for NB-IoT (only change in some nomenclature) -\brief Generate an RRCConnectionReestablishmentReject DL-CCCH-Message (eNB). -@param Mod_id Module ID of eNB -@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU -@returns Size of encoded bit stream in bytes*/ - -uint8_t -do_RRCConnectionReestablishmentReject_NB_IoT( - uint8_t Mod_id, - uint8_t* const buffer); - - -/** -\brief Generate an RRCConnectionReject-NB DL-CCCH-Message (eNB). -@param Mod_id Module ID of eNB -@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU -@returns Size of encoded bit stream in bytes*/ -uint8_t -do_RRCConnectionReject_NB_IoT( - uint8_t Mod_id, - uint8_t* const buffer); - - -/** -\brief Generate an RRCConnectionRelease-NB DL-DCCH-Message -@param Mod_id Module ID of eNB -@param buffer Pointer to PER-encoded ASN.1 description -@param transaction_id Transaction index -@returns Size of encoded bit stream in bytes*/ - -uint8_t do_RRCConnectionRelease_NB_IoT(uint8_t Mod_id, uint8_t *buffer,int Transaction_id); - - -uint8_t do_DLInformationTransfer_NB_IoT( - uint8_t Mod_id, - uint8_t **buffer, - uint8_t transaction_id, - uint32_t pdu_length, - uint8_t *pdu_buffer); - -//for now not implemented since UE side -//uint8_t do_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t *pdu_buffer); - -//for now not implemented since UE side??? -//OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) - -/** -\brief Generate an RRCConnectionReestablishment-NB DL-CCCH Message - *@param - * - */ - -uint8_t do_RRCConnectionReestablishment_NB_IoT( - uint8_t Mod_id, - uint8_t* const buffer, - const uint8_t Transaction_id, - const NB_IoT_DL_FRAME_PARMS* const frame_parms, //to be changed - SRB_ToAddModList_NB_r13_t** SRB_configList_NB_IoT - ); - -/** -\brief Generate an RRCConnectionRelease-NB DL-DCCH-Message (eNB) -@param Mod_id Module ID of eNB -@param buffer Pointer to PER-encoded ASN.1 description of DL-DCCH-Message PDU -@param transaction_id Transaction index -@returns Size of encoded bit stream in bytes*/ - -//uint8_t do_RRCConnectionRelease_NB_IoT(uint8_t Mod_id, uint8_t *buffer,int Transaction_id); +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file asn1_msg.h +* \brief primitives to build the asn1 messages +* \author Raymond Knopp, Navid Nikaein and Michele Paffetti +* \date 2011, 2017 +* \version 1.0 +* \company Eurecom +* \email: raymond.knopp@eurecom.fr ,navid.nikaein@eurecom.fr, michele.paffetti@studio.unibo.it +*/ + +#ifdef USER_MODE +#include +#include +#include /* for atoi(3) */ +#include /* for getopt(3) */ +#include /* for strerror(3) */ +#include /* for EX_* exit codes */ +#include /* for errno */ +#else +#include /* Needed by all modules */ +#endif + +#include +#include /* for _ASN_DEFAULT_STACK_MAX */ + + +#include "RRC/LITE/defs_NB_IoT.h" + +/* + * The variant of the above function which dumps the BASIC-XER (XER_F_BASIC) + * output into the chosen string buffer. + * RETURN VALUES: + * 0: The structure is printed. + * -1: Problem printing the structure. + * WARNING: No sensible error value is returned. + */ + + +/** +\brief Generate configuration for SIB1 (eNB). +@param carrier pointer to Carrier information +@param N_RB_DL Number of downlink PRBs +@param frame radio frame number +@return size of encoded bit stream in bytes*/ +uint8_t do_MIB_NB_IoT( + rrc_eNB_carrier_data_NB_IoT_t *carrier, + uint32_t N_RB_DL, + uint32_t frame, + uint32_t hyper_frame); + + +/** +\brief Generate a default configuration for SIB1-NB (eNB). +@param Mod_id Instance of eNB +@param CC_id Component carrier to configure +@param carrier pointer to Carrier information +@param configuration Pointer Configuration Request structure +@return size of encoded bit stream in bytes*/ + +uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, + int CC_id, + rrc_eNB_carrier_data_NB_IoT_t *carrier, + NbIoTRrcConfigurationReq *configuration, + uint32_t frame + ); + +/** +\brief Generate a default configuration for SIB2/SIB3-NB in one System Information PDU (eNB). +@param Mod_id Index of eNB (used to derive some parameters) +@param buffer Pointer to PER-encoded ASN.1 description of SI-NB PDU +@param systemInformation_NB_IoT Pointer to asn1c C representation of SI-NB PDU +@param sib2_NB Pointer (returned) to sib2_NB component withing SI-NB PDU +@param sib3_NB Pointer (returned) to sib3_NB component withing SI-NB PDU +@return size of encoded bit stream in bytes*/ + +uint8_t do_SIB23_NB_IoT(uint8_t Mod_id, + int CC_id, + rrc_eNB_carrier_data_NB_IoT_t *carrier, + NbIoTRrcConfigurationReq *configuration + ); + +/**(UE-SIDE) +\brief Generate an RRCConnectionRequest-NB UL-CCCH-Message (UE) based on random string or S-TMSI. This +routine only generates an mo-data establishment cause. +@param buffer Pointer to PER-encoded ASN.1 description of UL-DCCH-Message PDU +@param rv 5 byte random string or S-TMSI +@param Mod_id +@returns Size of encoded bit stream in bytes*/ + +uint8_t do_RRCConnectionRequest_NB_IoT(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv); + + +/**(UE -SIDE) +\brief Generate an RRCConnectionSetupComplete-NB UL-DCCH-Message (UE) +@param Mod_id +@param Transaction_id +@param dedicatedInfoNASLength +@param dedicatedInfoNAS +@param buffer Pointer to PER-encoded ASN.1 description of UL-DCCH-Message PDU +@returns Size of encoded bit stream in bytes*/ + +uint8_t do_RRCConnectionSetupComplete_NB_IoT(uint8_t Mod_id, uint8_t* buffer, const uint8_t Transaction_id, const int dedicatedInfoNASLength, + const char* dedicatedInfoNAS); + +/** (UE-SIDE) +\brief Generate an RRCConnectionReconfigurationComplete-NB UL-DCCH-Message (UE) +@param buffer Pointer to PER-encoded ASN.1 description of UL-DCCH-Message PDU +@param ctxt_pP +@param Transaction_id +@returns Size of encoded bit stream in bytes*/ + +uint8_t do_RRCConnectionReconfigurationComplete_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t* buffer, + const uint8_t Transaction_id +); + +/** +\brief Generate an RRCConnectionSetup-NB DL-CCCH-Message (eNB). This routine configures SRB_ToAddMod (SRB1/SRB1bis-NB) and +PhysicalConfigDedicated-NB IEs. +@param ctxt_pP Running context +@param ue_context_pP UE context +@param CC_id Component Carrier ID +@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU +@param transmission_mode Transmission mode for UE (1-9) +@param UE_id UE index for this message +@param Transaction_id Transaction_ID for this message +@param SRB_configList Pointer (returned) to SRB1_config/SRB1bis_config(later) IEs for this UE +@param physicalConfigDedicated_NB Pointer (returned) to PhysicalConfigDedicated-NB IE for this UE +@returns Size of encoded bit stream in bytes*/ + +uint8_t do_RRCConnectionSetup_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, + int CC_id, + uint8_t* const buffer, //carrier[CC_id].Srb0.Tx_buffer.Payload + const uint8_t Transaction_id, + const NB_IoT_DL_FRAME_PARMS* const frame_parms, //to be changed but not deleted + SRB_ToAddModList_NB_r13_t** SRB_configList_NB_IoT, //in order to be configured--> stanno puntando alla SRB_configlist dell ue_context + struct PhysicalConfigDedicated_NB_r13** physicalConfigDedicated_NB_IoT //in order to be configured--> stanno puntando alla physicalConfigDedicated dell ue_context +); + + +/** + * For which SRB is used in NB-IoT?? +\brief Generate an RRCConnectionReconfiguration-NB DL-DCCH-Message (eNB). This routine configures SRBToAddMod-NB (SRB1) and one DRBToAddMod-NB +(DRB3). PhysicalConfigDedicated-NB is not updated. +@param ctxt_pP Running context +@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU +@param Transaction_id Transaction_ID for this message +@param SRB_list_NB Pointer to SRB List to be added/modified (NULL if no additions/modifications) +@param DRB_list_NB Pointer to DRB List to be added/modified (NULL if no additions/modifications) +@param DRB_list2_NB Pointer to DRB List to be released (NULL if none to be released) +//sps not supported by NB-IoT +@param physicalConfigDedicated_NB Pointer to PhysicalConfigDedicated-NB to be modified (NULL if no modifications) +//measurement not supported by NB-IoT +@param mac_MainConfig Pointer to Mac_MainConfig(NULL if no modifications) +//no CBA functionalities +@returns Size of encoded bit stream in bytes*/ + +uint16_t +do_RRCConnectionReconfiguration_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t *buffer, + uint8_t Transaction_id, + SRB_ToAddModList_NB_r13_t *SRB_list_NB_IoT, + DRB_ToAddModList_NB_r13_t *DRB_list_NB_IoT, + DRB_ToReleaseList_NB_r13_t *DRB_list2_NB_IoT, + struct PhysicalConfigDedicated_NB_r13 *physicalConfigDedicated, + MAC_MainConfig_t *mac_MainConfig, + struct RRCConnectionReconfiguration_NB_r13_IEs__dedicatedInfoNASList_r13* dedicatedInfoNASList_NB_IoT); + +/** + * E-UTRAN applies the procedure as follows: when only for NB-IoT SRB1 and SRB1bis is established + \brief Generate a SecurityModeCommand + @param ctxt_pP Running context + @param buffer Pointer to PER-encoded ASN.1 description + @param Transaction_id Transaction_ID for this message + @param cipheringAlgorithm + @param integrityProtAlgorithm + */ + +uint8_t do_SecurityModeCommand_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t* const buffer, + const uint8_t Transaction_id, + const uint8_t cipheringAlgorithm, + const uint8_t integrityProtAlgorithm); + +/** + * E-UTRAN applies the procedure as follows: when only for NB-IoT SRB1 and SRB1bis is established + \brief Generate a SecurityModeCommand + @param ctxt_pP Running context + @param buffer Pointer to PER-encoded ASN.1 description + @param Transaction_id Transaction_ID for this message + */ + +uint8_t do_UECapabilityEnquiry_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t* const buffer, + const uint8_t Transaction_id +); + + +/** + * There is nothing new in this type of message for NB-IoT (only change in some nomenclature) +\brief Generate an RRCConnectionReestablishmentReject DL-CCCH-Message (eNB). +@param Mod_id Module ID of eNB +@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU +@returns Size of encoded bit stream in bytes*/ + +uint8_t +do_RRCConnectionReestablishmentReject_NB_IoT( + uint8_t Mod_id, + uint8_t* const buffer); + + +/** +\brief Generate an RRCConnectionReject-NB DL-CCCH-Message (eNB). +@param Mod_id Module ID of eNB +@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU +@returns Size of encoded bit stream in bytes*/ +uint8_t +do_RRCConnectionReject_NB_IoT( + uint8_t Mod_id, + uint8_t* const buffer); + + +/** +\brief Generate an RRCConnectionRelease-NB DL-DCCH-Message +@param Mod_id Module ID of eNB +@param buffer Pointer to PER-encoded ASN.1 description +@param transaction_id Transaction index +@returns Size of encoded bit stream in bytes*/ + +uint8_t do_RRCConnectionRelease_NB_IoT(uint8_t Mod_id, uint8_t *buffer,int Transaction_id); + + +uint8_t do_DLInformationTransfer_NB_IoT( + uint8_t Mod_id, + uint8_t **buffer, + uint8_t transaction_id, + uint32_t pdu_length, + uint8_t *pdu_buffer); + +//for now not implemented since UE side +//uint8_t do_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t *pdu_buffer); + +//for now not implemented since UE side??? +//OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) + +/** +\brief Generate an RRCConnectionReestablishment-NB DL-CCCH Message + *@param + * + */ + +uint8_t do_RRCConnectionReestablishment_NB_IoT( + uint8_t Mod_id, + uint8_t* const buffer, + const uint8_t Transaction_id, + const NB_IoT_DL_FRAME_PARMS* const frame_parms, //to be changed + SRB_ToAddModList_NB_r13_t** SRB_configList_NB_IoT + ); + +/** +\brief Generate an RRCConnectionRelease-NB DL-DCCH-Message (eNB) +@param Mod_id Module ID of eNB +@param buffer Pointer to PER-encoded ASN.1 description of DL-DCCH-Message PDU +@param transaction_id Transaction index +@returns Size of encoded bit stream in bytes*/ + +//uint8_t do_RRCConnectionRelease_NB_IoT(uint8_t Mod_id, uint8_t *buffer,int Transaction_id); diff --git a/openair2/RRC/LITE/defs_NB_IoT.h b/openair2/RRC/LITE/defs_NB_IoT.h index a5fdbb702e..376b66c79a 100644 --- a/openair2/RRC/LITE/defs_NB_IoT.h +++ b/openair2/RRC/LITE/defs_NB_IoT.h @@ -1,570 +1,570 @@ -/* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file RRC/LITE/defs_NB_IoT.h -* \brief NB-IoT RRC struct definitions and function prototypes -* \author Navid Nikaein, Raymond Knopp and Michele Paffetti -* \date 2010 - 2014, 2017 -* \version 1.0 -* \company Eurecom -* \email: navid.nikaein@eurecom.fr, raymond.knopp@eurecom.fr, michele.paffetti@studio.unibo.it -*/ - -#ifndef __OPENAIR_RRC_DEFS_NB_IOT_H__ -#define __OPENAIR_RRC_DEFS_NB_IOT_H__ - - -#include -#include -#include - -#include "collection/tree.h" -#include "rrc_types_NB_IoT.h" -#include "COMMON/platform_constants.h" -#include "COMMON/platform_types.h" -#include "targets/COMMON/openairinterface5g_limits.h" - -#include "COMMON/mac_rrc_primitives.h" - -//-----NB-IoT #include files------- - -//#include "SystemInformationBlockType1-NB.h" -//#include "SystemInformation-NB.h" -#include "RRCConnectionReconfiguration-NB.h" -#include "RRCConnectionReconfigurationComplete-NB.h" -#include "RRCConnectionSetup-NB.h" -#include "RRCConnectionSetupComplete-NB.h" -#include "RRCConnectionRequest-NB.h" -#include "RRCConnectionReestablishmentRequest-NB.h" -#include "BCCH-DL-SCH-Message-NB.h" -#include "BCCH-BCH-Message-NB.h" -#include "AS-Config-NB.h" -#include "AS-Context-NB.h" -#include "UE-Capability-NB-r13.h" //equivalent of UE-EUTRA-Capability.h -//------------------- - -#if defined(ENABLE_ITTI) -# include "intertask_interface.h" -#endif - -/* TODO: be sure this include is correct. - * It solves a problem of compilation of the RRH GW, - * issue #186. - */ -#if !defined(ENABLE_ITTI) -# include "as_message.h" -#endif - -#if defined(ENABLE_USE_MME) -# include "commonDef.h" -#endif - -#if ENABLE_RAL -# include "collection/hashtable/obj_hashtable.h" -#endif - - - -/*I will change the name of the structure for compile purposes--> hope not to undo this process*/ - -typedef unsigned int uid_NB_IoT_t; -#define UID_LINEAR_ALLOCATOR_BITMAP_SIZE_NB_IoT (((NUMBER_OF_UE_MAX_NB_IoT/8)/sizeof(unsigned int)) + 1) - -typedef struct uid_linear_allocator_NB_IoT_s { - unsigned int bitmap[UID_LINEAR_ALLOCATOR_BITMAP_SIZE_NB_IoT]; -} uid_allocator_NB_IoT_t; - - -#define PROTOCOL_RRC_CTXT_UE_FMT PROTOCOL_CTXT_FMT -#define PROTOCOL_RRC_CTXT_UE_ARGS(CTXT_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp) - -#define PROTOCOL_RRC_CTXT_FMT PROTOCOL_CTXT_FMT -#define PROTOCOL_RRC_CTXT_ARGS(CTXT_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp) - - -//left as they are --> used in LAYER2/epenair2_proc.c and UE side -typedef enum UE_STATE_NB_IoT_e { - RRC_INACTIVE_NB_IoT=0, - RRC_IDLE_NB_IoT, - RRC_SI_RECEIVED_NB_IoT, - RRC_CONNECTED_NB_IoT, - RRC_RECONFIGURED_NB_IoT, - RRC_HO_EXECUTION_NB_IoT //maybe not needed? -} UE_STATE_NB_IoT_t; - - -/** @defgroup _rrc RRC - * @ingroup _oai2 - * @{ - */ -typedef struct UE_RRC_INFO_NB_IoT_s { - UE_STATE_NB_IoT_t State; - uint8_t SIB1systemInfoValueTag; - uint32_t SIStatus; - uint32_t SIcnt; -#if defined(Rel10) || defined(Rel14) - uint8_t MCCHStatus[8]; // MAX_MBSFN_AREA -#endif - uint8_t SIwindowsize; //!< Corresponds to the SIB1 si-WindowLength parameter. The unit is ms. Possible values are (final): 1,2,5,10,15,20,40 - uint8_t handoverTarget; - //HO_STATE_t ho_state; - uint16_t SIperiod; //!< Corresponds to the SIB1 si-Periodicity parameter (multiplied by 10). Possible values are (final): 80,160,320,640,1280,2560,5120 - unsigned short UE_index; - uint32_t T300_active; - uint32_t T300_cnt; - uint32_t T304_active; - uint32_t T304_cnt; - uint32_t T310_active; - uint32_t T310_cnt; - uint32_t N310_cnt; - uint32_t N311_cnt; - rnti_t rnti; -} __attribute__ ((__packed__)) UE_RRC_INFO_NB_IoT; - -//#define NUM_PRECONFIGURED_LCHAN (NB_CH_CX*2) //BCCH, CCCH - -#define UE_MODULE_INVALID ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!! -#define UE_INDEX_INVALID ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!! used to be -1 - - - -// HO_STATE is not supported by NB-IoT - -//#define NUMBER_OF_UE_MAX MAX_MOBILES_PER_RG -#define RRM_FREE(p) if ( (p) != NULL) { free(p) ; p=NULL ; } -#define RRM_MALLOC(t,n) (t *) malloc16( sizeof(t) * n ) -#define RRM_CALLOC(t,n) (t *) malloc16( sizeof(t) * n) -#define RRM_CALLOC2(t,s) (t *) malloc16( s ) - -//Measurement Report not supported in NB-IoT - -#define PAYLOAD_SIZE_MAX 1024 -#define RRC_BUF_SIZE 255 -#define UNDEF_SECURITY_MODE 0xff -#define NO_SECURITY_MODE 0x20 - -/* TS 36.331: RRC-TransactionIdentifier ::= INTEGER (0..3) */ -#define RRC_TRANSACTION_IDENTIFIER_NUMBER 3 - -typedef struct UE_S_TMSI_NB_IoT_s { - boolean_t presence; - mme_code_t mme_code; - m_tmsi_t m_tmsi; -} __attribute__ ((__packed__)) UE_S_TMSI_NB_IoT; - - -typedef enum e_rab_satus_NB_IoT_e { - E_RAB_STATUS_NEW_NB_IoT, - E_RAB_STATUS_DONE_NB_IoT, // from the eNB perspective - E_RAB_STATUS_ESTABLISHED_NB_IoT, // get the reconfigurationcomplete form UE - E_RAB_STATUS_FAILED_NB_IoT, -} e_rab_status_NB_IoT_t; - -typedef struct e_rab_param_NB_IoT_s { - e_rab_t param; - uint8_t status; - uint8_t xid; // transaction_id -} __attribute__ ((__packed__)) e_rab_param_NB_IoT_t; - - -//HANDOVER_INFO not implemented in NB-IoT delete - - -#define RRC_HEADER_SIZE_MAX 64 -#define RRC_BUFFER_SIZE_MAX 1024 - -typedef struct { - char Payload[RRC_BUFFER_SIZE_MAX]; - char Header[RRC_HEADER_SIZE_MAX]; - char payload_size; -} RRC_BUFFER_NB_IoT; - -#define RRC_BUFFER_SIZE_NB_IoT sizeof(RRC_BUFFER_NB_IoT) - - -typedef struct RB_INFO_NB_IoT_s { - uint16_t Rb_id; //=Lchan_id - //LCHAN_DESC Lchan_desc[2]; no more used - //MAC_MEAS_REQ_ENTRY *Meas_entry; //may not needed for NB-IoT -} RB_INFO_NB_IoT; - -typedef struct SRB_INFO_NB_IoT_s { - uint16_t Srb_id; //=Lchan_id---> useful for distinguish between SRB1 and SRB1bis? - RRC_BUFFER_NB_IoT Rx_buffer; - RRC_BUFFER_NB_IoT Tx_buffer; - //LCHAN_DESC Lchan_desc[2]; no more used - unsigned int Trans_id; - uint8_t Active; -} SRB_INFO_NB_IoT; - - -typedef struct RB_INFO_TABLE_ENTRY_NB_IoT_s { - RB_INFO_NB_IoT Rb_info; - uint8_t Active; - uint32_t Next_check_frame; - uint8_t Status; -} RB_INFO_TABLE_ENTRY_NB_IoT; - -typedef struct SRB_INFO_TABLE_ENTRY_NB_IoT_s { - SRB_INFO_NB_IoT Srb_info; - uint8_t Active; - uint8_t Status; - uint32_t Next_check_frame; -} SRB_INFO_TABLE_ENTRY_NB_IoT; - -//MEAS_REPORT_LIST_s not implemented in NB-IoT but is used at UE side -//HANDOVER_INFO_UE not implemented in NB-IoT -typedef struct HANDOVER_INFO_UE_NB_IoT_s { - PhysCellId_t targetCellId; - uint8_t measFlag; -} HANDOVER_INFO_UE_NB_IoT; - -//NB-IoT eNB_RRC_UE_NB_IoT_s--(used as a context in eNB --> ue_context in rrc_eNB_ue_context)------ -typedef struct eNB_RRC_UE_NB_IoT_s { - - EstablishmentCause_t establishment_cause; - uint8_t primaryCC_id; - //in NB-IoT only SRB0, SRB1 and SRB1bis (until AS security activation) exist - - /*MP: Concept behind List and List2 - * - * SRB_configList --> is used for the actual list of SRBs that is managed/that should be send over the RRC message - * SRB_configList2--> refers to all the SRBs configured for that specific transaction identifier - * this because in a single transaction one or more SRBs could be established - * and you want to keep memory on what happen for every transaction - * Transaction ID (xid): is used to associate the proper RRC....Complete message received by the UE to the corresponding - * message previously sent by the eNB (e.g. RRCConnectionSetup -- RRCConnectionSetupComplete) - * this because it could happen that more messages are transmitted at the same time - */ - SRB_ToAddModList_NB_r13_t* SRB_configList;//for SRB1 and SRB1bis - SRB_ToAddModList_NB_r13_t* SRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; - DRB_ToAddModList_NB_r13_t* DRB_configList; //for all the DRBs - DRB_ToAddModList_NB_r13_t* DRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; //for the configured DRBs of a xid - uint8_t DRB_active[2];//in LTE was 8 --> at most 2 for NB-IoT - - struct PhysicalConfigDedicated_NB_r13* physicalConfigDedicated_NB_IoT; - MAC_MainConfig_NB_r13_t* mac_MainConfig_NB_IoT; - - //No SPS(semi-persistent scheduling) in NB-IoT - //No Measurement report in NB-IoT - - SRB_INFO_NB_IoT SI; - SRB_INFO_NB_IoT Srb0; - SRB_INFO_TABLE_ENTRY_NB_IoT Srb1; - SRB_INFO_TABLE_ENTRY_NB_IoT Srb1bis; - -#if defined(ENABLE_SECURITY) - /* KeNB as derived from KASME received from EPC */ - uint8_t kenb[32]; -#endif - - /* Used integrity/ciphering algorithms--> maintained the same for NB-IoT */ - e_CipheringAlgorithm_r12 ciphering_algorithm; //Specs. TS 36.331 V14.1.0 pag 432 Change position of chipering enumerative w.r.t previous version - e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm; - - uint8_t Status; - rnti_t rnti; - uint64_t random_ue_identity; - - - - /* Information from UE RRC ConnectionRequest-NB-r13_IE--> NB-IoT */ - UE_S_TMSI_NB_IoT Initialue_identity_s_TMSI; - EstablishmentCause_NB_r13_t establishment_cause_NB_IoT; //different set for NB-IoT - - /* Information from UE RRC ConnectionReestablishmentRequest-NB--> NB-IoT */ - ReestablishmentCause_NB_r13_t reestablishment_cause_NB_IoT; //different set for NB_IoT - - /* UE id for initial connection to S1AP */ - uint16_t ue_initial_id; - - /* Information from S1AP initial_context_setup_req */ - uint32_t eNB_ue_s1ap_id :24; - - security_capabilities_t security_capabilities; - - /* Total number of e_rab already setup in the list */ //NAS list? - uint8_t setup_e_rabs; - /* Number of e_rab to be setup in the list */ //NAS list? - uint8_t nb_of_e_rabs; - /* list of e_rab to be setup by RRC layers */ - e_rab_param_NB_IoT_t e_rab[NB_RB_MAX_NB_IOT];//[S1AP_MAX_E_RAB]; - - // LG: For GTPV1 TUNNELS - uint32_t enb_gtp_teid[S1AP_MAX_E_RAB]; - transport_layer_addr_t enb_gtp_addrs[S1AP_MAX_E_RAB]; - rb_id_t enb_gtp_ebi[S1AP_MAX_E_RAB]; - - //Which timers are referring to? - uint32_t ul_failure_timer; - uint32_t ue_release_timer; - //threshold of the release timer--> set in RRCConnectionRelease - uint32_t ue_release_timer_thres; -} eNB_RRC_UE_NB_IoT_t; -//-------------------------------------------------------------------------------- - -typedef uid_NB_IoT_t ue_uid_t; - - -//generally variable called: ue_context_pP -typedef struct rrc_eNB_ue_context_NB_IoT_s { - - /* Tree related data */ - RB_ENTRY(rrc_eNB_ue_context_NB_IoT_s) entries; - - /* Uniquely identifies the UE between MME and eNB within the eNB. - * This id is encoded on 24bits. - */ - rnti_t ue_id_rnti; - - // another key for protocol layers but should not be used as a key for RB tree - ue_uid_t local_uid; - - /* UE id for initial connection to S1AP */ - struct eNB_RRC_UE_NB_IoT_s ue_context; //context of ue in the e-nB - -} rrc_eNB_ue_context_NB_IoT_t; - - - -//---NB-IoT (completely changed)------------------------------- -//called "carrier"--> data from PHY layer -typedef struct { - - // buffer that contains the encoded messages - uint8_t *MIB_NB_IoT; - uint8_t sizeof_MIB_NB_IoT; - - uint8_t *SIB1_NB_IoT; - uint8_t sizeof_SIB1_NB_IoT; - uint8_t *SIB23_NB_IoT; - uint8_t sizeof_SIB23_NB_IoT; - - - //not actually implemented in OAI - uint8_t *SIB4_NB_IoT; - uint8_t sizeof_SIB4_NB_IoT; - uint8_t *SIB5_NB_IoT; - uint8_t sizeof_SIB5_NB_IoT; - uint8_t *SIB14_NB_IoT; - uint8_t sizeof_SIB14_NB_IoT; - uint8_t *SIB16_NB_IoT; - uint8_t sizeof_SIB16_NB_IoT; - - //TS 36.331 V14.2.1 -// uint8_t *SIB15_NB; -// uint8_t sizeof_SIB15_NB; -// uint8_t *SIB20_NB; -// uint8_t sizeof_SIB20_NB; -// uint8_t *SIB22_NB; -// uint8_t sizeof_SIB22_NB; - - //implicit parameters needed - int Ncp; //cyclic prefix for DL - int Ncp_UL; //cyclic prefix for UL - int p_eNB; //number of tx antenna port - int p_rx_eNB; //number of receiving antenna ports - uint32_t dl_CarrierFreq; //detected by the UE - uint32_t ul_CarrierFreq; //detected by the UE - uint16_t physCellId; //not stored in the MIB-NB but is getting through NPSS/NSSS - - //are the only static one (memory has been already allocated) - BCCH_BCH_Message_NB_t mib_NB_IoT; - BCCH_DL_SCH_Message_NB_t siblock1_NB_IoT; //SIB1-NB - BCCH_DL_SCH_Message_NB_t systemInformation_NB_IoT; //SI - - SystemInformationBlockType1_NB_t *sib1_NB_IoT; - SystemInformationBlockType2_NB_r13_t *sib2_NB_IoT; - SystemInformationBlockType3_NB_r13_t *sib3_NB_IoT; - //not implemented yet - SystemInformationBlockType4_NB_r13_t *sib4_NB_IoT; - SystemInformationBlockType5_NB_r13_t *sib5_NB_IoT; - SystemInformationBlockType14_NB_r13_t *sib14_NB_IoT; - SystemInformationBlockType16_NB_r13_t *sib16_NB_IoT; - - - SRB_INFO_NB_IoT SI; - SRB_INFO_NB_IoT Srb0; - - uint8_t **MCCH_MESSAGE; // probably not needed , but added to remove errors - uint8_t sizeof_MCCH_MESSAGE[8];// but added to remove errors - SRB_INFO_NB_IoT MCCH_MESS[8];// MAX_MBSFN_AREA - /*future implementation TS 36.331 V14.2.1 - SystemInformationBlockType15_NB_r14_t *sib15; - SystemInformationBlockType20_NB_r14_t *sib20; - SystemInformationBlockType22_NB_r14_t *sib22; - - uint8_t SCPTM_flag; - uint8_t sizeof_SC_MCHH_MESS[]; - SC_MCCH_Message_NB_t scptm;*/ - - -} rrc_eNB_carrier_data_NB_IoT_t; -//--------------------------------------------------- - - - -//---NB-IoT---(completely change)--------------------- -typedef struct eNB_RRC_INST_NB_IoT_s { - - rrc_eNB_carrier_data_NB_IoT_t carrier[MAX_NUM_CCs]; - - uid_allocator_NB_IoT_t uid_allocator; // for rrc_ue_head - RB_HEAD(rrc_ue_tree_NB_IoT_s, rrc_eNB_ue_context_NB_IoT_s) rrc_ue_head; // ue_context tree key search by rnti - - uint8_t Nb_ue; - - hash_table_t *initial_id2_s1ap_ids; // key is content is rrc_ue_s1ap_ids_t - hash_table_t *s1ap_id2_s1ap_ids ; // key is content is rrc_ue_s1ap_ids_t - - //RRC configuration - RrcConfigurationReq configuration; //rrc_messages_types.h - - // other PLMN parameters - /// Mobile country code - int mcc; - /// Mobile network code - int mnc; - /// number of mnc digits - int mnc_digit_length; - - // other RAN parameters //FIXME: to be checked--> depends on APP layer - int srb1_timer_poll_retransmit; - int srb1_max_retx_threshold; - int srb1_timer_reordering; - int srb1_timer_status_prohibit; - int srs_enable[MAX_NUM_CCs]; - - -} eNB_RRC_INST_NB_IoT; - -#define RRC_HEADER_SIZE_MAX_NB_IoT 64 -#define MAX_UE_CAPABILITY_SIZE_NB_IoT 255 - -//not needed for the moment -typedef struct OAI_UECapability_NB_IoT_s { - uint8_t sdu[MAX_UE_CAPABILITY_SIZE_NB_IoT]; - uint8_t sdu_size; -////NB-IoT------ - UE_Capability_NB_r13_t UE_Capability_NB_IoT; //replace the UE_EUTRA_Capability of LTE -} OAI_UECapability_NB_IoT_t; - -#define RRC_BUFFER_SIZE_MAX_NB_IoT 1024 - - - -typedef struct UE_RRC_INST_NB_IoT_s { - Rrc_State_NB_IoT_t RrcState; - Rrc_Sub_State_NB_IoT_t RrcSubState; -# if defined(ENABLE_USE_MME) - plmn_t plmnID; - Byte_t rat; - as_nas_info_t initialNasMsg; -# endif - OAI_UECapability_NB_IoT_t *UECap; - uint8_t *UECapability; - uint8_t UECapability_size; - - UE_RRC_INFO_NB_IoT Info[NB_SIG_CNX_UE]; - - SRB_INFO_NB_IoT Srb0[NB_SIG_CNX_UE]; - SRB_INFO_TABLE_ENTRY_NB_IoT Srb1[NB_CNX_UE]; - SRB_INFO_TABLE_ENTRY_NB_IoT Srb2[NB_CNX_UE]; - HANDOVER_INFO_UE_NB_IoT HandoverInfoUe; - /* - uint8_t *SIB1[NB_CNX_UE]; - uint8_t sizeof_SIB1[NB_CNX_UE]; - uint8_t *SI[NB_CNX_UE]; - uint8_t sizeof_SI[NB_CNX_UE]; - uint8_t SIB1Status[NB_CNX_UE]; - uint8_t SIStatus[NB_CNX_UE]; - SystemInformationBlockType1_t *sib1[NB_CNX_UE]; - SystemInformation_t *si[NB_CNX_UE]; //!< Temporary storage for an SI message. Decoding happens in decode_SI(). - */ - SystemInformationBlockType2_t *sib2[NB_CNX_UE]; - /* - SystemInformationBlockType3_t *sib3[NB_CNX_UE]; - SystemInformationBlockType4_t *sib4[NB_CNX_UE]; - SystemInformationBlockType5_t *sib5[NB_CNX_UE]; - SystemInformationBlockType6_t *sib6[NB_CNX_UE]; - SystemInformationBlockType7_t *sib7[NB_CNX_UE]; - SystemInformationBlockType8_t *sib8[NB_CNX_UE]; - SystemInformationBlockType9_t *sib9[NB_CNX_UE]; - SystemInformationBlockType10_t *sib10[NB_CNX_UE]; - SystemInformationBlockType11_t *sib11[NB_CNX_UE]; - -#if defined(Rel10) || defined(Rel14) - uint8_t MBMS_flag; - uint8_t *MCCH_MESSAGE[NB_CNX_UE]; - uint8_t sizeof_MCCH_MESSAGE[NB_CNX_UE]; - uint8_t MCCH_MESSAGEStatus[NB_CNX_UE]; - MBSFNAreaConfiguration_r9_t *mcch_message[NB_CNX_UE]; - SystemInformationBlockType12_r9_t *sib12[NB_CNX_UE]; - SystemInformationBlockType13_r9_t *sib13[NB_CNX_UE]; -#endif -#ifdef CBA - uint8_t num_active_cba_groups; - uint16_t cba_rnti[NUM_MAX_CBA_GROUP]; -#endif - uint8_t num_srb; - struct SRB_ToAddMod *SRB1_config[NB_CNX_UE]; - struct SRB_ToAddMod *SRB2_config[NB_CNX_UE]; - struct DRB_ToAddMod *DRB_config[NB_CNX_UE][8]; - rb_id_t *defaultDRB; // remember the ID of the default DRB - MeasObjectToAddMod_t *MeasObj[NB_CNX_UE][MAX_MEAS_OBJ]; - struct ReportConfigToAddMod *ReportConfig[NB_CNX_UE][MAX_MEAS_CONFIG]; - */ - struct QuantityConfig *QuantityConfig[NB_CNX_UE]; - /* - struct MeasIdToAddMod *MeasId[NB_CNX_UE][MAX_MEAS_ID]; - MEAS_REPORT_LIST *measReportList[NB_CNX_UE][MAX_MEAS_ID]; - uint32_t measTimer[NB_CNX_UE][MAX_MEAS_ID][6]; // 6 neighboring cells - RSRP_Range_t s_measure; - struct MeasConfig__speedStatePars *speedStatePars; - struct PhysicalConfigDedicated *physicalConfigDedicated[NB_CNX_UE]; - struct SPS_Config *sps_Config[NB_CNX_UE]; - MAC_MainConfig_t *mac_MainConfig[NB_CNX_UE]; - MeasGapConfig_t *measGapConfig[NB_CNX_UE]; - double filter_coeff_rsrp; // [7] ??? - double filter_coeff_rsrq; // [7] ??? - float rsrp_db[7]; - float rsrq_db[7]; - float rsrp_db_filtered[7]; - float rsrq_db_filtered[7]; -#if ENABLE_RAL - obj_hash_table_t *ral_meas_thresholds; - ral_transaction_id_t scan_transaction_id; -#endif -#if defined(ENABLE_SECURITY) - // KeNB as computed from parameters within USIM card // - uint8_t kenb[32]; -#endif - - // Used integrity/ciphering algorithms // - CipheringAlgorithm_r12_t ciphering_algorithm; - e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm; - */ -} UE_RRC_INST_NB_IoT; - - -#include "proto_NB_IoT.h" //should be put here otherwise compilation error - -#endif -/** @} */ +/* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file RRC/LITE/defs_NB_IoT.h +* \brief NB-IoT RRC struct definitions and function prototypes +* \author Navid Nikaein, Raymond Knopp and Michele Paffetti +* \date 2010 - 2014, 2017 +* \version 1.0 +* \company Eurecom +* \email: navid.nikaein@eurecom.fr, raymond.knopp@eurecom.fr, michele.paffetti@studio.unibo.it +*/ + +#ifndef __OPENAIR_RRC_DEFS_NB_IOT_H__ +#define __OPENAIR_RRC_DEFS_NB_IOT_H__ + + +#include +#include +#include + +#include "collection/tree.h" +#include "rrc_types_NB_IoT.h" +#include "COMMON/platform_constants.h" +#include "COMMON/platform_types.h" +#include "targets/COMMON/openairinterface5g_limits.h" + +#include "COMMON/mac_rrc_primitives.h" + +//-----NB-IoT #include files------- + +//#include "SystemInformationBlockType1-NB.h" +//#include "SystemInformation-NB.h" +#include "RRCConnectionReconfiguration-NB.h" +#include "RRCConnectionReconfigurationComplete-NB.h" +#include "RRCConnectionSetup-NB.h" +#include "RRCConnectionSetupComplete-NB.h" +#include "RRCConnectionRequest-NB.h" +#include "RRCConnectionReestablishmentRequest-NB.h" +#include "BCCH-DL-SCH-Message-NB.h" +#include "BCCH-BCH-Message-NB.h" +#include "AS-Config-NB.h" +#include "AS-Context-NB.h" +#include "UE-Capability-NB-r13.h" //equivalent of UE-EUTRA-Capability.h +//------------------- + +#if defined(ENABLE_ITTI) +# include "intertask_interface.h" +#endif + +/* TODO: be sure this include is correct. + * It solves a problem of compilation of the RRH GW, + * issue #186. + */ +#if !defined(ENABLE_ITTI) +# include "as_message.h" +#endif + +#if defined(ENABLE_USE_MME) +# include "commonDef.h" +#endif + +#if ENABLE_RAL +# include "collection/hashtable/obj_hashtable.h" +#endif + + + +/*I will change the name of the structure for compile purposes--> hope not to undo this process*/ + +typedef unsigned int uid_NB_IoT_t; +#define UID_LINEAR_ALLOCATOR_BITMAP_SIZE_NB_IoT (((NUMBER_OF_UE_MAX_NB_IoT/8)/sizeof(unsigned int)) + 1) + +typedef struct uid_linear_allocator_NB_IoT_s { + unsigned int bitmap[UID_LINEAR_ALLOCATOR_BITMAP_SIZE_NB_IoT]; +} uid_allocator_NB_IoT_t; + + +#define PROTOCOL_RRC_CTXT_UE_FMT PROTOCOL_CTXT_FMT +#define PROTOCOL_RRC_CTXT_UE_ARGS(CTXT_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp) + +#define PROTOCOL_RRC_CTXT_FMT PROTOCOL_CTXT_FMT +#define PROTOCOL_RRC_CTXT_ARGS(CTXT_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp) + + +//left as they are --> used in LAYER2/epenair2_proc.c and UE side +typedef enum UE_STATE_NB_IoT_e { + RRC_INACTIVE_NB_IoT=0, + RRC_IDLE_NB_IoT, + RRC_SI_RECEIVED_NB_IoT, + RRC_CONNECTED_NB_IoT, + RRC_RECONFIGURED_NB_IoT, + RRC_HO_EXECUTION_NB_IoT //maybe not needed? +} UE_STATE_NB_IoT_t; + + +/** @defgroup _rrc RRC + * @ingroup _oai2 + * @{ + */ +typedef struct UE_RRC_INFO_NB_IoT_s { + UE_STATE_NB_IoT_t State; + uint8_t SIB1systemInfoValueTag; + uint32_t SIStatus; + uint32_t SIcnt; +#if defined(Rel10) || defined(Rel14) + uint8_t MCCHStatus[8]; // MAX_MBSFN_AREA +#endif + uint8_t SIwindowsize; //!< Corresponds to the SIB1 si-WindowLength parameter. The unit is ms. Possible values are (final): 1,2,5,10,15,20,40 + uint8_t handoverTarget; + //HO_STATE_t ho_state; + uint16_t SIperiod; //!< Corresponds to the SIB1 si-Periodicity parameter (multiplied by 10). Possible values are (final): 80,160,320,640,1280,2560,5120 + unsigned short UE_index; + uint32_t T300_active; + uint32_t T300_cnt; + uint32_t T304_active; + uint32_t T304_cnt; + uint32_t T310_active; + uint32_t T310_cnt; + uint32_t N310_cnt; + uint32_t N311_cnt; + rnti_t rnti; +} __attribute__ ((__packed__)) UE_RRC_INFO_NB_IoT; + +//#define NUM_PRECONFIGURED_LCHAN (NB_CH_CX*2) //BCCH, CCCH + +#define UE_MODULE_INVALID ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!! +#define UE_INDEX_INVALID ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!! used to be -1 + + + +// HO_STATE is not supported by NB-IoT + +//#define NUMBER_OF_UE_MAX MAX_MOBILES_PER_RG +#define RRM_FREE(p) if ( (p) != NULL) { free(p) ; p=NULL ; } +#define RRM_MALLOC(t,n) (t *) malloc16( sizeof(t) * n ) +#define RRM_CALLOC(t,n) (t *) malloc16( sizeof(t) * n) +#define RRM_CALLOC2(t,s) (t *) malloc16( s ) + +//Measurement Report not supported in NB-IoT + +#define PAYLOAD_SIZE_MAX 1024 +#define RRC_BUF_SIZE 255 +#define UNDEF_SECURITY_MODE 0xff +#define NO_SECURITY_MODE 0x20 + +/* TS 36.331: RRC-TransactionIdentifier ::= INTEGER (0..3) */ +#define RRC_TRANSACTION_IDENTIFIER_NUMBER 3 + +typedef struct UE_S_TMSI_NB_IoT_s { + boolean_t presence; + mme_code_t mme_code; + m_tmsi_t m_tmsi; +} __attribute__ ((__packed__)) UE_S_TMSI_NB_IoT; + + +typedef enum e_rab_satus_NB_IoT_e { + E_RAB_STATUS_NEW_NB_IoT, + E_RAB_STATUS_DONE_NB_IoT, // from the eNB perspective + E_RAB_STATUS_ESTABLISHED_NB_IoT, // get the reconfigurationcomplete form UE + E_RAB_STATUS_FAILED_NB_IoT, +} e_rab_status_NB_IoT_t; + +typedef struct e_rab_param_NB_IoT_s { + e_rab_t param; + uint8_t status; + uint8_t xid; // transaction_id +} __attribute__ ((__packed__)) e_rab_param_NB_IoT_t; + + +//HANDOVER_INFO not implemented in NB-IoT delete + + +#define RRC_HEADER_SIZE_MAX 64 +#define RRC_BUFFER_SIZE_MAX 1024 + +typedef struct { + char Payload[RRC_BUFFER_SIZE_MAX]; + char Header[RRC_HEADER_SIZE_MAX]; + char payload_size; +} RRC_BUFFER_NB_IoT; + +#define RRC_BUFFER_SIZE_NB_IoT sizeof(RRC_BUFFER_NB_IoT) + + +typedef struct RB_INFO_NB_IoT_s { + uint16_t Rb_id; //=Lchan_id + //LCHAN_DESC Lchan_desc[2]; no more used + //MAC_MEAS_REQ_ENTRY *Meas_entry; //may not needed for NB-IoT +} RB_INFO_NB_IoT; + +typedef struct SRB_INFO_NB_IoT_s { + uint16_t Srb_id; //=Lchan_id---> useful for distinguish between SRB1 and SRB1bis? + RRC_BUFFER_NB_IoT Rx_buffer; + RRC_BUFFER_NB_IoT Tx_buffer; + //LCHAN_DESC Lchan_desc[2]; no more used + unsigned int Trans_id; + uint8_t Active; +} SRB_INFO_NB_IoT; + + +typedef struct RB_INFO_TABLE_ENTRY_NB_IoT_s { + RB_INFO_NB_IoT Rb_info; + uint8_t Active; + uint32_t Next_check_frame; + uint8_t Status; +} RB_INFO_TABLE_ENTRY_NB_IoT; + +typedef struct SRB_INFO_TABLE_ENTRY_NB_IoT_s { + SRB_INFO_NB_IoT Srb_info; + uint8_t Active; + uint8_t Status; + uint32_t Next_check_frame; +} SRB_INFO_TABLE_ENTRY_NB_IoT; + +//MEAS_REPORT_LIST_s not implemented in NB-IoT but is used at UE side +//HANDOVER_INFO_UE not implemented in NB-IoT +typedef struct HANDOVER_INFO_UE_NB_IoT_s { + PhysCellId_t targetCellId; + uint8_t measFlag; +} HANDOVER_INFO_UE_NB_IoT; + +//NB-IoT eNB_RRC_UE_NB_IoT_s--(used as a context in eNB --> ue_context in rrc_eNB_ue_context)------ +typedef struct eNB_RRC_UE_NB_IoT_s { + + EstablishmentCause_t establishment_cause; + uint8_t primaryCC_id; + //in NB-IoT only SRB0, SRB1 and SRB1bis (until AS security activation) exist + + /*MP: Concept behind List and List2 + * + * SRB_configList --> is used for the actual list of SRBs that is managed/that should be send over the RRC message + * SRB_configList2--> refers to all the SRBs configured for that specific transaction identifier + * this because in a single transaction one or more SRBs could be established + * and you want to keep memory on what happen for every transaction + * Transaction ID (xid): is used to associate the proper RRC....Complete message received by the UE to the corresponding + * message previously sent by the eNB (e.g. RRCConnectionSetup -- RRCConnectionSetupComplete) + * this because it could happen that more messages are transmitted at the same time + */ + SRB_ToAddModList_NB_r13_t* SRB_configList;//for SRB1 and SRB1bis + SRB_ToAddModList_NB_r13_t* SRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; + DRB_ToAddModList_NB_r13_t* DRB_configList; //for all the DRBs + DRB_ToAddModList_NB_r13_t* DRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; //for the configured DRBs of a xid + uint8_t DRB_active[2];//in LTE was 8 --> at most 2 for NB-IoT + + struct PhysicalConfigDedicated_NB_r13* physicalConfigDedicated_NB_IoT; + MAC_MainConfig_NB_r13_t* mac_MainConfig_NB_IoT; + + //No SPS(semi-persistent scheduling) in NB-IoT + //No Measurement report in NB-IoT + + SRB_INFO_NB_IoT SI; + SRB_INFO_NB_IoT Srb0; + SRB_INFO_TABLE_ENTRY_NB_IoT Srb1; + SRB_INFO_TABLE_ENTRY_NB_IoT Srb1bis; + +#if defined(ENABLE_SECURITY) + /* KeNB as derived from KASME received from EPC */ + uint8_t kenb[32]; +#endif + + /* Used integrity/ciphering algorithms--> maintained the same for NB-IoT */ + e_CipheringAlgorithm_r12 ciphering_algorithm; //Specs. TS 36.331 V14.1.0 pag 432 Change position of chipering enumerative w.r.t previous version + e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm; + + uint8_t Status; + rnti_t rnti; + uint64_t random_ue_identity; + + + + /* Information from UE RRC ConnectionRequest-NB-r13_IE--> NB-IoT */ + UE_S_TMSI_NB_IoT Initialue_identity_s_TMSI; + EstablishmentCause_NB_r13_t establishment_cause_NB_IoT; //different set for NB-IoT + + /* Information from UE RRC ConnectionReestablishmentRequest-NB--> NB-IoT */ + ReestablishmentCause_NB_r13_t reestablishment_cause_NB_IoT; //different set for NB_IoT + + /* UE id for initial connection to S1AP */ + uint16_t ue_initial_id; + + /* Information from S1AP initial_context_setup_req */ + uint32_t eNB_ue_s1ap_id :24; + + security_capabilities_t security_capabilities; + + /* Total number of e_rab already setup in the list */ //NAS list? + uint8_t setup_e_rabs; + /* Number of e_rab to be setup in the list */ //NAS list? + uint8_t nb_of_e_rabs; + /* list of e_rab to be setup by RRC layers */ + e_rab_param_NB_IoT_t e_rab[NB_RB_MAX_NB_IOT];//[S1AP_MAX_E_RAB]; + + // LG: For GTPV1 TUNNELS + uint32_t enb_gtp_teid[S1AP_MAX_E_RAB]; + transport_layer_addr_t enb_gtp_addrs[S1AP_MAX_E_RAB]; + rb_id_t enb_gtp_ebi[S1AP_MAX_E_RAB]; + + //Which timers are referring to? + uint32_t ul_failure_timer; + uint32_t ue_release_timer; + //threshold of the release timer--> set in RRCConnectionRelease + uint32_t ue_release_timer_thres; +} eNB_RRC_UE_NB_IoT_t; +//-------------------------------------------------------------------------------- + +typedef uid_NB_IoT_t ue_uid_t; + + +//generally variable called: ue_context_pP +typedef struct rrc_eNB_ue_context_NB_IoT_s { + + /* Tree related data */ + RB_ENTRY(rrc_eNB_ue_context_NB_IoT_s) entries; + + /* Uniquely identifies the UE between MME and eNB within the eNB. + * This id is encoded on 24bits. + */ + rnti_t ue_id_rnti; + + // another key for protocol layers but should not be used as a key for RB tree + ue_uid_t local_uid; + + /* UE id for initial connection to S1AP */ + struct eNB_RRC_UE_NB_IoT_s ue_context; //context of ue in the e-nB + +} rrc_eNB_ue_context_NB_IoT_t; + + + +//---NB-IoT (completely changed)------------------------------- +//called "carrier"--> data from PHY layer +typedef struct { + + // buffer that contains the encoded messages + uint8_t *MIB_NB_IoT; + uint8_t sizeof_MIB_NB_IoT; + + uint8_t *SIB1_NB_IoT; + uint8_t sizeof_SIB1_NB_IoT; + uint8_t *SIB23_NB_IoT; + uint8_t sizeof_SIB23_NB_IoT; + + + //not actually implemented in OAI + uint8_t *SIB4_NB_IoT; + uint8_t sizeof_SIB4_NB_IoT; + uint8_t *SIB5_NB_IoT; + uint8_t sizeof_SIB5_NB_IoT; + uint8_t *SIB14_NB_IoT; + uint8_t sizeof_SIB14_NB_IoT; + uint8_t *SIB16_NB_IoT; + uint8_t sizeof_SIB16_NB_IoT; + + //TS 36.331 V14.2.1 +// uint8_t *SIB15_NB; +// uint8_t sizeof_SIB15_NB; +// uint8_t *SIB20_NB; +// uint8_t sizeof_SIB20_NB; +// uint8_t *SIB22_NB; +// uint8_t sizeof_SIB22_NB; + + //implicit parameters needed + int Ncp; //cyclic prefix for DL + int Ncp_UL; //cyclic prefix for UL + int p_eNB; //number of tx antenna port + int p_rx_eNB; //number of receiving antenna ports + uint32_t dl_CarrierFreq; //detected by the UE + uint32_t ul_CarrierFreq; //detected by the UE + uint16_t physCellId; //not stored in the MIB-NB but is getting through NPSS/NSSS + + //are the only static one (memory has been already allocated) + BCCH_BCH_Message_NB_t mib_NB_IoT; + BCCH_DL_SCH_Message_NB_t siblock1_NB_IoT; //SIB1-NB + BCCH_DL_SCH_Message_NB_t systemInformation_NB_IoT; //SI + + SystemInformationBlockType1_NB_t *sib1_NB_IoT; + SystemInformationBlockType2_NB_r13_t *sib2_NB_IoT; + SystemInformationBlockType3_NB_r13_t *sib3_NB_IoT; + //not implemented yet + SystemInformationBlockType4_NB_r13_t *sib4_NB_IoT; + SystemInformationBlockType5_NB_r13_t *sib5_NB_IoT; + SystemInformationBlockType14_NB_r13_t *sib14_NB_IoT; + SystemInformationBlockType16_NB_r13_t *sib16_NB_IoT; + + + SRB_INFO_NB_IoT SI; + SRB_INFO_NB_IoT Srb0; + + uint8_t **MCCH_MESSAGE; // probably not needed , but added to remove errors + uint8_t sizeof_MCCH_MESSAGE[8];// but added to remove errors + SRB_INFO_NB_IoT MCCH_MESS[8];// MAX_MBSFN_AREA + /*future implementation TS 36.331 V14.2.1 + SystemInformationBlockType15_NB_r14_t *sib15; + SystemInformationBlockType20_NB_r14_t *sib20; + SystemInformationBlockType22_NB_r14_t *sib22; + + uint8_t SCPTM_flag; + uint8_t sizeof_SC_MCHH_MESS[]; + SC_MCCH_Message_NB_t scptm;*/ + + +} rrc_eNB_carrier_data_NB_IoT_t; +//--------------------------------------------------- + + + +//---NB-IoT---(completely change)--------------------- +typedef struct eNB_RRC_INST_NB_IoT_s { + + rrc_eNB_carrier_data_NB_IoT_t carrier[MAX_NUM_CCs]; + + uid_allocator_NB_IoT_t uid_allocator; // for rrc_ue_head + RB_HEAD(rrc_ue_tree_NB_IoT_s, rrc_eNB_ue_context_NB_IoT_s) rrc_ue_head; // ue_context tree key search by rnti + + uint8_t Nb_ue; + + hash_table_t *initial_id2_s1ap_ids; // key is content is rrc_ue_s1ap_ids_t + hash_table_t *s1ap_id2_s1ap_ids ; // key is content is rrc_ue_s1ap_ids_t + + //RRC configuration + RrcConfigurationReq configuration; //rrc_messages_types.h + + // other PLMN parameters + /// Mobile country code + int mcc; + /// Mobile network code + int mnc; + /// number of mnc digits + int mnc_digit_length; + + // other RAN parameters //FIXME: to be checked--> depends on APP layer + int srb1_timer_poll_retransmit; + int srb1_max_retx_threshold; + int srb1_timer_reordering; + int srb1_timer_status_prohibit; + int srs_enable[MAX_NUM_CCs]; + + +} eNB_RRC_INST_NB_IoT; + +#define RRC_HEADER_SIZE_MAX_NB_IoT 64 +#define MAX_UE_CAPABILITY_SIZE_NB_IoT 255 + +//not needed for the moment +typedef struct OAI_UECapability_NB_IoT_s { + uint8_t sdu[MAX_UE_CAPABILITY_SIZE_NB_IoT]; + uint8_t sdu_size; +////NB-IoT------ + UE_Capability_NB_r13_t UE_Capability_NB_IoT; //replace the UE_EUTRA_Capability of LTE +} OAI_UECapability_NB_IoT_t; + +#define RRC_BUFFER_SIZE_MAX_NB_IoT 1024 + + + +typedef struct UE_RRC_INST_NB_IoT_s { + Rrc_State_NB_IoT_t RrcState; + Rrc_Sub_State_NB_IoT_t RrcSubState; +# if defined(ENABLE_USE_MME) + plmn_t plmnID; + Byte_t rat; + as_nas_info_t initialNasMsg; +# endif + OAI_UECapability_NB_IoT_t *UECap; + uint8_t *UECapability; + uint8_t UECapability_size; + + UE_RRC_INFO_NB_IoT Info[NB_SIG_CNX_UE]; + + SRB_INFO_NB_IoT Srb0[NB_SIG_CNX_UE]; + SRB_INFO_TABLE_ENTRY_NB_IoT Srb1[NB_CNX_UE]; + SRB_INFO_TABLE_ENTRY_NB_IoT Srb2[NB_CNX_UE]; + HANDOVER_INFO_UE_NB_IoT HandoverInfoUe; + /* + uint8_t *SIB1[NB_CNX_UE]; + uint8_t sizeof_SIB1[NB_CNX_UE]; + uint8_t *SI[NB_CNX_UE]; + uint8_t sizeof_SI[NB_CNX_UE]; + uint8_t SIB1Status[NB_CNX_UE]; + uint8_t SIStatus[NB_CNX_UE]; + SystemInformationBlockType1_t *sib1[NB_CNX_UE]; + SystemInformation_t *si[NB_CNX_UE]; //!< Temporary storage for an SI message. Decoding happens in decode_SI(). + */ + SystemInformationBlockType2_t *sib2[NB_CNX_UE]; + /* + SystemInformationBlockType3_t *sib3[NB_CNX_UE]; + SystemInformationBlockType4_t *sib4[NB_CNX_UE]; + SystemInformationBlockType5_t *sib5[NB_CNX_UE]; + SystemInformationBlockType6_t *sib6[NB_CNX_UE]; + SystemInformationBlockType7_t *sib7[NB_CNX_UE]; + SystemInformationBlockType8_t *sib8[NB_CNX_UE]; + SystemInformationBlockType9_t *sib9[NB_CNX_UE]; + SystemInformationBlockType10_t *sib10[NB_CNX_UE]; + SystemInformationBlockType11_t *sib11[NB_CNX_UE]; + +#if defined(Rel10) || defined(Rel14) + uint8_t MBMS_flag; + uint8_t *MCCH_MESSAGE[NB_CNX_UE]; + uint8_t sizeof_MCCH_MESSAGE[NB_CNX_UE]; + uint8_t MCCH_MESSAGEStatus[NB_CNX_UE]; + MBSFNAreaConfiguration_r9_t *mcch_message[NB_CNX_UE]; + SystemInformationBlockType12_r9_t *sib12[NB_CNX_UE]; + SystemInformationBlockType13_r9_t *sib13[NB_CNX_UE]; +#endif +#ifdef CBA + uint8_t num_active_cba_groups; + uint16_t cba_rnti[NUM_MAX_CBA_GROUP]; +#endif + uint8_t num_srb; + struct SRB_ToAddMod *SRB1_config[NB_CNX_UE]; + struct SRB_ToAddMod *SRB2_config[NB_CNX_UE]; + struct DRB_ToAddMod *DRB_config[NB_CNX_UE][8]; + rb_id_t *defaultDRB; // remember the ID of the default DRB + MeasObjectToAddMod_t *MeasObj[NB_CNX_UE][MAX_MEAS_OBJ]; + struct ReportConfigToAddMod *ReportConfig[NB_CNX_UE][MAX_MEAS_CONFIG]; + */ + struct QuantityConfig *QuantityConfig[NB_CNX_UE]; + /* + struct MeasIdToAddMod *MeasId[NB_CNX_UE][MAX_MEAS_ID]; + MEAS_REPORT_LIST *measReportList[NB_CNX_UE][MAX_MEAS_ID]; + uint32_t measTimer[NB_CNX_UE][MAX_MEAS_ID][6]; // 6 neighboring cells + RSRP_Range_t s_measure; + struct MeasConfig__speedStatePars *speedStatePars; + struct PhysicalConfigDedicated *physicalConfigDedicated[NB_CNX_UE]; + struct SPS_Config *sps_Config[NB_CNX_UE]; + MAC_MainConfig_t *mac_MainConfig[NB_CNX_UE]; + MeasGapConfig_t *measGapConfig[NB_CNX_UE]; + double filter_coeff_rsrp; // [7] ??? + double filter_coeff_rsrq; // [7] ??? + float rsrp_db[7]; + float rsrq_db[7]; + float rsrp_db_filtered[7]; + float rsrq_db_filtered[7]; +#if ENABLE_RAL + obj_hash_table_t *ral_meas_thresholds; + ral_transaction_id_t scan_transaction_id; +#endif +#if defined(ENABLE_SECURITY) + // KeNB as computed from parameters within USIM card // + uint8_t kenb[32]; +#endif + + // Used integrity/ciphering algorithms // + CipheringAlgorithm_r12_t ciphering_algorithm; + e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm; + */ +} UE_RRC_INST_NB_IoT; + + +#include "proto_NB_IoT.h" //should be put here otherwise compilation error + +#endif +/** @} */ diff --git a/openair2/RRC/LITE/extern_NB_IoT.h b/openair2/RRC/LITE/extern_NB_IoT.h index 39b49ecc03..f5e2f32575 100644 --- a/openair2/RRC/LITE/extern_NB_IoT.h +++ b/openair2/RRC/LITE/extern_NB_IoT.h @@ -1,63 +1,63 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file vars.h -* \brief rrc external vars -* \author Navid Nikaein and Raymond Knopp, Michele Paffetti -* \date 2011-2017 -* \version 1.0 -* \company Eurecom -* \email: navid.nikaein@eurecom.fr, michele.paffetti@studio.unibo.it -*/ - -#ifndef __OPENAIR_RRC_EXTERN_NB_IOT_H__ -#define __OPENAIR_RRC_EXTERN_NB_IOT_H__ -#include "RRC/LITE/defs_NB_IoT.h" -#include "PHY_INTERFACE/IF_Module_NB_IoT.h" -#include "LAYER2/RLC/rlc.h" -#include "LogicalChannelConfig-NB-r13.h" -#include "LAYER2/MAC/defs_NB_IoT.h" +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file vars.h +* \brief rrc external vars +* \author Navid Nikaein and Raymond Knopp, Michele Paffetti +* \date 2011-2017 +* \version 1.0 +* \company Eurecom +* \email: navid.nikaein@eurecom.fr, michele.paffetti@studio.unibo.it +*/ + +#ifndef __OPENAIR_RRC_EXTERN_NB_IOT_H__ +#define __OPENAIR_RRC_EXTERN_NB_IOT_H__ +#include "RRC/LITE/defs_NB_IoT.h" +#include "PHY_INTERFACE/IF_Module_NB_IoT.h" +#include "LAYER2/RLC/rlc.h" +#include "LogicalChannelConfig-NB-r13.h" +#include "LAYER2/MAC/defs_NB_IoT.h" + +#include "common/ran_context.h" + + +//MP: NOTE:XXX some of the parameters defined in vars_nb_iot are called by the extern.h file so not replicated here + +extern UE_RRC_INST_NB_IoT *UE_rrc_inst_NB_IoT; + +extern eNB_RRC_INST_NB_IoT *eNB_rrc_inst_NB_IoT; +extern PHY_Config_NB_IoT_t *config_INFO; + +extern rlc_info_t Rlc_info_am_NB_IoT,Rlc_info_am_config_NB_IoT; +extern uint8_t DRB2LCHAN_NB_IoT[2]; +extern LogicalChannelConfig_NB_r13_t SRB1bis_logicalChannelConfig_defaultValue_NB_IoT; +extern LogicalChannelConfig_NB_r13_t SRB1_logicalChannelConfig_defaultValue_NB_IoT; + +extern uint16_t T300_NB_IoT[8]; +extern uint16_t T301_NB_IoT[8]; +extern uint16_t T310_NB_IoT[8]; +extern uint16_t T311_NB_IoT[8]; +extern uint16_t N310_NB_IoT[8]; +extern uint16_t N311_NB_IoT[8]; +extern uint8_t *get_NB_IoT_MIB(struct eNB_RRC_INST_NB_IoT_s *nb_iot_rrc); +#endif + -#include "common/ran_context.h" - - -//MP: NOTE:XXX some of the parameters defined in vars_nb_iot are called by the extern.h file so not replicated here - -extern UE_RRC_INST_NB_IoT *UE_rrc_inst_NB_IoT; - -extern eNB_RRC_INST_NB_IoT *eNB_rrc_inst_NB_IoT; -extern PHY_Config_NB_IoT_t *config_INFO; - -extern rlc_info_t Rlc_info_am_NB_IoT,Rlc_info_am_config_NB_IoT; -extern uint8_t DRB2LCHAN_NB_IoT[2]; -extern LogicalChannelConfig_NB_r13_t SRB1bis_logicalChannelConfig_defaultValue_NB_IoT; -extern LogicalChannelConfig_NB_r13_t SRB1_logicalChannelConfig_defaultValue_NB_IoT; - -extern uint16_t T300_NB_IoT[8]; -extern uint16_t T301_NB_IoT[8]; -extern uint16_t T310_NB_IoT[8]; -extern uint16_t T311_NB_IoT[8]; -extern uint16_t N310_NB_IoT[8]; -extern uint16_t N311_NB_IoT[8]; -extern uint8_t *get_NB_IoT_MIB(struct eNB_RRC_INST_NB_IoT_s *nb_iot_rrc); -#endif - - diff --git a/openair2/RRC/LITE/proto_NB_IoT.h b/openair2/RRC/LITE/proto_NB_IoT.h index e346204912..b2218517fc 100644 --- a/openair2/RRC/LITE/proto_NB_IoT.h +++ b/openair2/RRC/LITE/proto_NB_IoT.h @@ -1,260 +1,260 @@ -/* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file proto_NB_IoT.h - * \brief RRC functions prototypes for eNB and UE for NB-IoT - * \author Navid Nikaein, Raymond Knopp and Michele Paffetti - * \date 2010 - 2014 - * \email navid.nikaein@eurecom.fr, michele.paffetti@studio.unibo.it - * \version 1.0 - - */ -/** \addtogroup _rrc - * @{ - */ - -#include "RRC/LITE/defs_NB_IoT.h" -#include "pdcp.h" -#include "rlc.h" -#include "extern_NB_IoT.h" -#include "LAYER2/MAC/defs_NB_IoT.h" -/*NOTE: no static function should be declared in this header file (e.g. init_SI_NB)*/ - -/*------------------------common_nb_iot.c----------------------------------------*/ - -/** \brief configure BCCH & CCCH Logical Channels and associated rrc_buffers, configure associated SRBs - */ -void openair_rrc_on_NB_IoT(const protocol_ctxt_t* const ctxt_pP); - -void rrc_config_buffer_NB_IoT(SRB_INFO_NB_IoT *srb_info, uint8_t Lchan_type, uint8_t Role); - -int L3_xface_init_NB_IoT(void); - -void openair_rrc_top_init_eNB_NB_IoT(void); - -//void rrc_top_cleanup(void); -->seems not to be used - -//rrc_t310_expiration-->seems not to be used - -/** \brief Function to update timers every subframe. For UE it updates T300,T304 and T310. -@param ctxt_pP running context -@param enb_index -@param CC_id -*/ -RRC_status_t rrc_rx_tx_NB_IoT(protocol_ctxt_t* const ctxt_pP, const uint8_t enb_index, const int CC_id); - -//long binary_search_int(int elements[], long numElem, int value);--> seems not to be used -//long binary_search_float(float elements[], long numElem, float value);--> used only at UE side - - - -//--------------------------------------- - - -//defined in L2_interface -//called by rx_sdu only in case of CCCH message (e.g RRCConnectionRequest-NB) -int8_t mac_rrc_data_ind_eNB_NB_IoT( - const module_id_t module_idP, - const int CC_id, - const frame_t frameP, - const sub_frame_t sub_frameP, - const rnti_t rntiP, - const rb_id_t srb_idP,//could be skipped since always go through the CCCH channel - const uint8_t* sduP, - const sdu_size_t sdu_lenP -); -//------------------------------------------- - -//defined in L2_interface -void dump_ue_list_NB_IoT(UE_list_NB_IoT_t *listP, int ul_flag); -//------------------------------------------- - - -//defined in L2_interface -void mac_eNB_rrc_ul_failure_NB_IoT( - const module_id_t mod_idP, - const int CC_idP, - const frame_t frameP, - const sub_frame_t subframeP, - const rnti_t rntiP); -//------------------------------------------ - -//defined in eNB_scheduler_primitives.c -int rrc_mac_remove_ue_NB_IoT( - module_id_t mod_idP, - rnti_t rntiP); -//------------------------------------------ -//defined in L2_interface -void mac_eNB_rrc_ul_in_sync_NB_IoT( - const module_id_t mod_idP, - const int CC_idP, - const frame_t frameP, - const sub_frame_t subframeP, - const rnti_t rntiP); -//------------------------------------------ -//defined in L2_interface -int mac_eNB_get_rrc_status_NB_IoT( - const module_id_t Mod_idP, - const rnti_t rntiP -); -//--------------------------- - - -/*-----------eNB procedures (rrc_eNB_nb_iot.c)---------------*/ - -//---Initialization-------------- -void openair_eNB_rrc_on_NB_IoT( - const protocol_ctxt_t* const ctxt_pP -); - -void rrc_config_buffer_NB_IoT( - SRB_INFO_NB_IoT* Srb_info, - uint8_t Lchan_type, - uint8_t Role -); - -char openair_rrc_eNB_configuration_NB_IoT( - const module_id_t enb_mod_idP, - NbIoTRrcConfigurationReq* configuration -); - -//----------------------------- -/**\brief RRC eNB task. (starting of the RRC state machine) - \param void *args_p Pointer on arguments to start the task. */ -void *rrc_enb_task_NB_IoT(void *args_p); - -/**\brief Entry routine to decode a UL-CCCH-Message-NB. Invokes PER decoder and parses message. - \param ctxt_pP Running context - \param Srb_info Pointer to SRB0 information structure (buffer, etc.)*/ -int rrc_eNB_decode_ccch_NB_IoT( - protocol_ctxt_t* const ctxt_pP, - const SRB_INFO_NB_IoT* const Srb_info, - const int CC_id -); - -/**\brief Entry routine to decode a UL-DCCH-Message-NB. Invokes PER decoder and parses message. - \param ctxt_pP Context - \param Rx_sdu Pointer Received Message - \param sdu_size Size of incoming SDU*/ -int rrc_eNB_decode_dcch_NB_IoT( - const protocol_ctxt_t* const ctxt_pP, - const rb_id_t Srb_id, - const uint8_t* const Rx_sdu, - const sdu_size_t sdu_sizeP -); - -/**\brief Generate RRCConnectionReestablishmentReject-NB - \param ctxt_pP Running context - \param ue_context_pP UE context - \param CC_id Component Carrier ID*/ -void rrc_eNB_generate_RRCConnectionReestablishmentReject_NB_IoT( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, - const int CC_id -); - -void rrc_eNB_generate_RRCConnectionReject_NB_IoT( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, - const int CC_id -); - -void rrc_eNB_generate_RRCConnectionSetup_NB_IoT( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, - const int CC_id -); - -void rrc_eNB_process_RRCConnectionReconfigurationComplete_NB_IoT( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_NB_IoT_t* ue_context_pP, - const uint8_t xid //transaction identifier -); - - -void //was under ITTI -rrc_eNB_reconfigure_DRBs_NB_IoT(const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_NB_IoT_t* ue_context_pP); - -void //was under ITTI -rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_NB_IoT( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP -// const uint8_t ho_state - ); - -void rrc_eNB_process_RRCConnectionSetupComplete_NB_IoT( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_NB_IoT_t* ue_context_pP, - RRCConnectionSetupComplete_NB_r13_IEs_t * rrcConnectionSetupComplete_NB -); - -void rrc_eNB_generate_SecurityModeCommand_NB_IoT( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP -); - -void rrc_eNB_generate_UECapabilityEnquiry_NB_IoT( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP -); - -void rrc_eNB_generate_defaultRRCConnectionReconfiguration_NB_IoT(const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP - //no HO flag - ); - - -/// Utilities------------------------------------------------ - -void rrc_eNB_free_UE_NB_IoT( - const module_id_t enb_mod_idP, - const struct rrc_eNB_ue_context_NB_IoT_s* const ue_context_pP - ); - -void rrc_eNB_free_mem_UE_context_NB_IoT( - const protocol_ctxt_t* const ctxt_pP, - struct rrc_eNB_ue_context_NB_IoT_s* const ue_context_pP -); - - - -/**\brief Function to get the next transaction identifier. - \param module_idP Instance ID for CH/eNB - \return a transaction identifier*/ -uint8_t rrc_eNB_get_next_transaction_identifier_NB_IoT(module_id_t module_idP); - - -int rrc_init_global_param_NB_IoT(void); - -//L2_interface.c -int8_t mac_rrc_data_req_eNB_NB_IoT( - const module_id_t Mod_idP, - const int CC_id, - const frame_t frameP, - const frame_t h_frameP, - const sub_frame_t subframeP, //need for the case in which both SIB1-NB_IoT and SIB23-NB_IoT will be scheduled in the same frame - const rb_id_t Srb_id, - uint8_t* const buffer_pP, - uint8_t flag -); - - - +/* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file proto_NB_IoT.h + * \brief RRC functions prototypes for eNB and UE for NB-IoT + * \author Navid Nikaein, Raymond Knopp and Michele Paffetti + * \date 2010 - 2014 + * \email navid.nikaein@eurecom.fr, michele.paffetti@studio.unibo.it + * \version 1.0 + + */ +/** \addtogroup _rrc + * @{ + */ + +#include "RRC/LITE/defs_NB_IoT.h" +#include "pdcp.h" +#include "rlc.h" +#include "extern_NB_IoT.h" +#include "LAYER2/MAC/defs_NB_IoT.h" +/*NOTE: no static function should be declared in this header file (e.g. init_SI_NB)*/ + +/*------------------------common_nb_iot.c----------------------------------------*/ + +/** \brief configure BCCH & CCCH Logical Channels and associated rrc_buffers, configure associated SRBs + */ +void openair_rrc_on_NB_IoT(const protocol_ctxt_t* const ctxt_pP); + +void rrc_config_buffer_NB_IoT(SRB_INFO_NB_IoT *srb_info, uint8_t Lchan_type, uint8_t Role); + +int L3_xface_init_NB_IoT(void); + +void openair_rrc_top_init_eNB_NB_IoT(void); + +//void rrc_top_cleanup(void); -->seems not to be used + +//rrc_t310_expiration-->seems not to be used + +/** \brief Function to update timers every subframe. For UE it updates T300,T304 and T310. +@param ctxt_pP running context +@param enb_index +@param CC_id +*/ +RRC_status_t rrc_rx_tx_NB_IoT(protocol_ctxt_t* const ctxt_pP, const uint8_t enb_index, const int CC_id); + +//long binary_search_int(int elements[], long numElem, int value);--> seems not to be used +//long binary_search_float(float elements[], long numElem, float value);--> used only at UE side + + + +//--------------------------------------- + + +//defined in L2_interface +//called by rx_sdu only in case of CCCH message (e.g RRCConnectionRequest-NB) +int8_t mac_rrc_data_ind_eNB_NB_IoT( + const module_id_t module_idP, + const int CC_id, + const frame_t frameP, + const sub_frame_t sub_frameP, + const rnti_t rntiP, + const rb_id_t srb_idP,//could be skipped since always go through the CCCH channel + const uint8_t* sduP, + const sdu_size_t sdu_lenP +); +//------------------------------------------- + +//defined in L2_interface +void dump_ue_list_NB_IoT(UE_list_NB_IoT_t *listP, int ul_flag); +//------------------------------------------- + + +//defined in L2_interface +void mac_eNB_rrc_ul_failure_NB_IoT( + const module_id_t mod_idP, + const int CC_idP, + const frame_t frameP, + const sub_frame_t subframeP, + const rnti_t rntiP); +//------------------------------------------ + +//defined in eNB_scheduler_primitives.c +int rrc_mac_remove_ue_NB_IoT( + module_id_t mod_idP, + rnti_t rntiP); +//------------------------------------------ +//defined in L2_interface +void mac_eNB_rrc_ul_in_sync_NB_IoT( + const module_id_t mod_idP, + const int CC_idP, + const frame_t frameP, + const sub_frame_t subframeP, + const rnti_t rntiP); +//------------------------------------------ +//defined in L2_interface +int mac_eNB_get_rrc_status_NB_IoT( + const module_id_t Mod_idP, + const rnti_t rntiP +); +//--------------------------- + + +/*-----------eNB procedures (rrc_eNB_nb_iot.c)---------------*/ + +//---Initialization-------------- +void openair_eNB_rrc_on_NB_IoT( + const protocol_ctxt_t* const ctxt_pP +); + +void rrc_config_buffer_NB_IoT( + SRB_INFO_NB_IoT* Srb_info, + uint8_t Lchan_type, + uint8_t Role +); + +char openair_rrc_eNB_configuration_NB_IoT( + const module_id_t enb_mod_idP, + NbIoTRrcConfigurationReq* configuration +); + +//----------------------------- +/**\brief RRC eNB task. (starting of the RRC state machine) + \param void *args_p Pointer on arguments to start the task. */ +void *rrc_enb_task_NB_IoT(void *args_p); + +/**\brief Entry routine to decode a UL-CCCH-Message-NB. Invokes PER decoder and parses message. + \param ctxt_pP Running context + \param Srb_info Pointer to SRB0 information structure (buffer, etc.)*/ +int rrc_eNB_decode_ccch_NB_IoT( + protocol_ctxt_t* const ctxt_pP, + const SRB_INFO_NB_IoT* const Srb_info, + const int CC_id +); + +/**\brief Entry routine to decode a UL-DCCH-Message-NB. Invokes PER decoder and parses message. + \param ctxt_pP Context + \param Rx_sdu Pointer Received Message + \param sdu_size Size of incoming SDU*/ +int rrc_eNB_decode_dcch_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + const rb_id_t Srb_id, + const uint8_t* const Rx_sdu, + const sdu_size_t sdu_sizeP +); + +/**\brief Generate RRCConnectionReestablishmentReject-NB + \param ctxt_pP Running context + \param ue_context_pP UE context + \param CC_id Component Carrier ID*/ +void rrc_eNB_generate_RRCConnectionReestablishmentReject_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, + const int CC_id +); + +void rrc_eNB_generate_RRCConnectionReject_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, + const int CC_id +); + +void rrc_eNB_generate_RRCConnectionSetup_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, + const int CC_id +); + +void rrc_eNB_process_RRCConnectionReconfigurationComplete_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* ue_context_pP, + const uint8_t xid //transaction identifier +); + + +void //was under ITTI +rrc_eNB_reconfigure_DRBs_NB_IoT(const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* ue_context_pP); + +void //was under ITTI +rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP +// const uint8_t ho_state + ); + +void rrc_eNB_process_RRCConnectionSetupComplete_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* ue_context_pP, + RRCConnectionSetupComplete_NB_r13_IEs_t * rrcConnectionSetupComplete_NB +); + +void rrc_eNB_generate_SecurityModeCommand_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP +); + +void rrc_eNB_generate_UECapabilityEnquiry_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP +); + +void rrc_eNB_generate_defaultRRCConnectionReconfiguration_NB_IoT(const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP + //no HO flag + ); + + +/// Utilities------------------------------------------------ + +void rrc_eNB_free_UE_NB_IoT( + const module_id_t enb_mod_idP, + const struct rrc_eNB_ue_context_NB_IoT_s* const ue_context_pP + ); + +void rrc_eNB_free_mem_UE_context_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + struct rrc_eNB_ue_context_NB_IoT_s* const ue_context_pP +); + + + +/**\brief Function to get the next transaction identifier. + \param module_idP Instance ID for CH/eNB + \return a transaction identifier*/ +uint8_t rrc_eNB_get_next_transaction_identifier_NB_IoT(module_id_t module_idP); + + +int rrc_init_global_param_NB_IoT(void); + +//L2_interface.c +int8_t mac_rrc_data_req_eNB_NB_IoT( + const module_id_t Mod_idP, + const int CC_id, + const frame_t frameP, + const frame_t h_frameP, + const sub_frame_t subframeP, //need for the case in which both SIB1-NB_IoT and SIB23-NB_IoT will be scheduled in the same frame + const rb_id_t Srb_id, + uint8_t* const buffer_pP, + uint8_t flag +); + + + From 445524bc879a71df38fba0f133810fae94f45694 Mon Sep 17 00:00:00 2001 From: Eino Virtanen Date: Mon, 12 Mar 2018 15:50:04 +0100 Subject: [PATCH 183/195] fix building protobuf when user name is not the same as primary group name --- cmake_targets/tools/build_helper | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 706cd05fe9..3bb051f291 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -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" From 3da8cac59b23ba1900e2c0e39a4a375ce10c3994 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 15 Mar 2018 10:48:16 +0100 Subject: [PATCH 184/195] bugfix: try to release HARQ processes properly The code is too complex. This commit may not be enough. --- openair1/SCHED/phy_procedures_lte_eNb.c | 88 ++++++++------ .../LAYER2/MAC/eNB_scheduler_primitives.c | 114 ++++++++++++++++-- openair2/LAYER2/MAC/pre_processor.c | 2 +- 3 files changed, 157 insertions(+), 47 deletions(-) diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 6c2e580947..780d3a1a6f 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -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); } -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; @@ -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]; 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<round >= after_rounds) { + dlsch0_harq->status = SCH_IDLE; + /*if ((dlsch1_harq == NULL)|| + ((dlsch1_harq!=NULL)&& + (dlsch1_harq->status == SCH_IDLE)))*/ + dlsch0->harq_mask &= ~(1<rnti); } @@ -1496,17 +1500,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<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_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 T_TRACER /* 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, 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<o_ACK[i] == 1); + release_harq(eNB,UE_id,1,frame,subframe,1<o_ACK[i] == 1); } } } @@ -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]); 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 T_TRACER if (harq_ack[0] != 1) @@ -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[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); } @@ -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]); 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; @@ -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[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 @@ -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]); 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; @@ -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[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; @@ -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 == 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) @@ -1800,26 +1819,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; } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 341db67934..110afc1a5a 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -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", diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index e7458c347f..2cdcfc7de8 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -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 { From d3938147725db69918d28cf89fbb093632caf474 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 19 Mar 2018 10:28:16 +0100 Subject: [PATCH 185/195] bugfix: send UL NACK (on PHICH) at the right place The PHICH was not programmed for the last round (4) because it was not programmed in rx_sdu but in schedule_ulsch_rnti, only in case of a programmed retransmission (there is obviously no retransmission programmed after the last round). The case of Msg3 is not handled. To be done somehow. --- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 32 +++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index b4fb025ea4..9ccb0e66ab 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -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", From 318e4a345ec29d69837009d55395c44dfe666f1a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 20 Mar 2018 14:41:58 +0100 Subject: [PATCH 186/195] free configmodule memory when shutting down It is possible to restart the lte-softmodem via the FlexRAN controller. For this to work, the end_configmodule() method needs to be called when shutting the lte-softmodem down so that the configuration can be read again during a restart. --- targets/RT/USER/lte-softmodem.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 03313146df..29bbf44756 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1209,9 +1209,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 TO TERMINATE\n"); @@ -1271,6 +1268,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); From e7a60fc992a7b8de4bc01be9bc9a1c3a5f6ad40b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 22 Mar 2018 16:14:30 +0100 Subject: [PATCH 187/195] FlexRAN: make agent_id for identification purposes, discern from mod_id The agent_id is a uint64 consisting of: module ID (i.e. mod_id, the several instances of OAI at once, 16 bit), the enb_id from the configuration file (32 bit) and the cell_id from the configuration file (16 bit). The module ID is part of the agent ID but it is easier to have it directly in the struct. --- openair2/ENB_APP/enb_config.c | 110 +++++++++++++++++++++++--- openair2/ENB_APP/flexran_agent.c | 13 +-- openair2/ENB_APP/flexran_agent_defs.h | 17 ++-- 3 files changed, 110 insertions(+), 30 deletions(-) diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 5e9c320f57..e0ab70154e 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -60,37 +60,121 @@ 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; 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; } } diff --git a/openair2/ENB_APP/flexran_agent.c b/openair2/ENB_APP/flexran_agent.c index bd46ecc49d..8d5cdbc06b 100644 --- a/openair2/ENB_APP/flexran_agent.c +++ b/openair2/ENB_APP/flexran_agent.c @@ -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 diff --git a/openair2/ENB_APP/flexran_agent_defs.h b/openair2/ENB_APP/flexran_agent_defs.h index 6364bc6281..aa71dd33fa 100644 --- a/openair2/ENB_APP/flexran_agent_defs.h +++ b/openair2/ENB_APP/flexran_agent_defs.h @@ -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 */ From 1854826053939de6fad8640565d40c152c3a30a0 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 22 Mar 2018 16:40:08 +0100 Subject: [PATCH 188/195] FlexRAN: send agent_id (aka enb_id) --- openair2/ENB_APP/MESSAGES/V2/flexran.proto | 2 +- openair2/ENB_APP/flexran_agent_common.c | 104 ++++++++++----------- 2 files changed, 52 insertions(+), 54 deletions(-) diff --git a/openair2/ENB_APP/MESSAGES/V2/flexran.proto b/openair2/ENB_APP/MESSAGES/V2/flexran.proto index b54fc171c6..9255372340 100644 --- a/openair2/ENB_APP/MESSAGES/V2/flexran.proto +++ b/openair2/ENB_APP/MESSAGES/V2/flexran.proto @@ -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; } diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index 6d32aeedbb..a7f74c1f22 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -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,43 +831,43 @@ 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]->init_nr_pdcch_ofdm_sym = flexran_get_num_pdcch_symb(mod_id,i); cell_conf[i]->has_init_nr_pdcch_ofdm_sym = 0; //TODO: Fill in with actual value /* Protocol__FlexSiConfig *si_config; */ @@ -880,10 +879,10 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F /* 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->sib1_length = get_sib1_length(mod_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->si_window_length = (uint32_t) get_si_window_length(mod_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; */ @@ -908,22 +907,22 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F /* } */ /* cell_conf[i]->si_config = si_config; */ - cell_conf[i]->dl_bandwidth = flexran_get_N_RB_DL(enb_id,i); + 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; } @@ -932,17 +931,17 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F cell_conf[i]->antenna_ports_count = 1; 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]->subframe_assignment = flexran_get_subframe_assignment(mod_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]->special_subframe_patterns = flexran_get_special_subframe_assignment(mod_id,i); cell_conf[i]->has_special_subframe_patterns = 0; //TODO: Fill in with actual value, The MBSFN radio frame period cell_conf[i]->n_mbsfn_subframe_config_rfperiod = 0; @@ -954,7 +953,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 +964,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 +975,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; } From d54d41512576c78741db2388d3922c0d0d77b524 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 22 Mar 2018 17:47:18 +0100 Subject: [PATCH 189/195] FlexRAN: add Information in enb_config_reply msg --- openair2/ENB_APP/flexran_agent_common.c | 51 ++++++++++++------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index a7f74c1f22..4b0a22300f 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -866,26 +866,25 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F 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(mod_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(mod_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(mod_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]->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) */ @@ -905,8 +904,9 @@ 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]->si_config = si_config; + cell_conf[i]->dl_bandwidth = flexran_get_N_RB_DL(mod_id,i); cell_conf[i]->has_dl_bandwidth = 1; @@ -927,8 +927,7 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F } 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(mod_id,i) == 1) { @@ -937,12 +936,10 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F 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(mod_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]->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 = 0; + 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; From 9c47c860bcce8902ba714b96173dfaa65757322f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 23 Mar 2018 09:20:19 +0100 Subject: [PATCH 190/195] FlexRAN: RCconfig_flexran(): only read necessary information if the FlexRAN agent is disabled, do not read all the data and skip reading of more information --- openair2/ENB_APP/enb_config.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index e0ab70154e..aa5bbdb3c7 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -137,6 +137,9 @@ void RCconfig_flexran() 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 = 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)); From 5fdc3077db40c461c8aac2cc7afd402d01bec77b Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 23 Mar 2018 10:07:47 +0100 Subject: [PATCH 191/195] disable U-plane inactivity timer. It is annoying and does not seem to work properly. To be checked/reworked if needed. Keep in mind that we also want oaisim to be functional. --- openair2/LAYER2/MAC/eNB_scheduler.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index a7c79a70d5..8dab2a9b71 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -423,12 +423,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 From e7bca7fdacdf8c37da91dde390710f4e12709b4d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 23 Mar 2018 10:13:41 +0100 Subject: [PATCH 192/195] Disable ITTI dump If anyone needs it, it's a simple matter of reverting this basic commit. --- common/utils/itti/intertask_interface.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/common/utils/itti/intertask_interface.c b/common/utils/itti/intertask_interface.c index 85b5fef509..1d38a3692b 100644 --- a/common/utils/itti/intertask_interface.c +++ b/common/utils/itti/intertask_interface.c @@ -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 */ 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) { @@ -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 */ 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) { @@ -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); +#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); @@ -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.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 ()); @@ -915,7 +927,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) From 3a0d9339dc136cb5acce1760a0c2bd9eaeb7b5fd Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 23 Mar 2018 10:14:55 +0100 Subject: [PATCH 193/195] bugfix: fix a memory leak When doing TCP downlink traffic with iperf for several hours, the memory consumption of lte-softmodem does not stop to grow. After analysis, this commit seems to be the only fix needed. To be checked somehow. --- openair3/GTPV1-U/gtpv1u_eNB.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c index 7f63e8c1ce..7ba3d88a87 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB.c +++ b/openair3/GTPV1-U/gtpv1u_eNB.c @@ -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 //----------------------- From 16cb7eba64b70fb054451b5c60619e5539524c36 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 23 Mar 2018 10:23:05 +0100 Subject: [PATCH 194/195] remove start_background_system from eNB softmodem This is only needed by the UE code, to setup IP settings. The eNB does not need this. (To be reverted if this is wrong.) --- targets/RT/USER/lte-softmodem.c | 1 - 1 file changed, 1 deletion(-) diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 03313146df..48169adffa 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -904,7 +904,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"); } From ff3c929ecf5d25c0550e66f8eb62a788cd88947a Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 23 Mar 2018 15:15:51 +0100 Subject: [PATCH 195/195] fix PHY simulators compilation Only ulsim and dlsim compile. The others (dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim) have been disabled. Command line to compile: ./build_oai --phy_simulators --- cmake_targets/CMakeLists.txt | 3 ++- cmake_targets/build_oai | 7 ++++++- openair2/RRC/LITE/defs_NB_IoT.h | 3 +++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index a22babc33f..34b868642d 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -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) @@ -2238,6 +2238,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} diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index f5be69d3fa..d7b98bce41 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -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 diff --git a/openair2/RRC/LITE/defs_NB_IoT.h b/openair2/RRC/LITE/defs_NB_IoT.h index 376b66c79a..c8565d52bd 100644 --- a/openair2/RRC/LITE/defs_NB_IoT.h +++ b/openair2/RRC/LITE/defs_NB_IoT.h @@ -35,6 +35,9 @@ #include #include +#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"