diff --git a/ci-scripts/conf_files/gnb-cucp.sa.f1.quectel.conf b/ci-scripts/conf_files/gnb-cucp.sa.f1.quectel.conf index 99a530ca39..8cebc8640a 100644 --- a/ci-scripts/conf_files/gnb-cucp.sa.f1.quectel.conf +++ b/ci-scripts/conf_files/gnb-cucp.sa.f1.quectel.conf @@ -58,6 +58,14 @@ gNBs = } ); +pdcp = { + drb = { + sn_size = "len18bits" + t_reordering = "ms100" + discard_timer = "infinity" + } +} + security = { # preferred ciphering algorithms # the first one of the list that an UE supports in chosen diff --git a/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf b/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf index 3626cec227..45482642b9 100644 --- a/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf +++ b/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf @@ -163,6 +163,31 @@ gNBs = } ); +rlc = { + srb = { + t_poll_retransmit = "ms45" + t_reassembly = "ms25" + t_status_prohibit = "ms0" + poll_pdu = "infinity" + poll_byte = "infinity" + max_retx_threshold = "t8" + sn_field_length = "size12" + } + drb_am = { + t_poll_retransmit = "ms45" + t_reassembly = "ms15" + t_status_prohibit = "ms15" + poll_pdu = "p64" + poll_byte = "kB500" + max_retx_threshold = "t32" + sn_field_length = "size18" + } + drb_um = { + t_reassembly = "ms15" + sn_field_length = "size12" + } +} + MACRLCs = ( { num_cc = 1; diff --git a/common/config/config_paramdesc.h b/common/config/config_paramdesc.h index 6947f6531d..9d80c7050c 100644 --- a/common/config/config_paramdesc.h +++ b/common/config/config_paramdesc.h @@ -53,7 +53,7 @@ #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 +#define CONFIG_MAX_NUMCHECKVAL 64 typedef struct paramdef paramdef_t; typedef struct configmodule_interface configmodule_interface_t; typedef union checkedparam { diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 6238c09a2e..b858945018 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -714,12 +714,36 @@ printf("%d\n", slot); .timer_config.n311 = 1, .timer_config.t319 = 400, .num_agg_level_candidates = {0, 0, 1, 1, 0}}; + const nr_rlc_configuration_t rlc_config = { + .srb = { + .t_poll_retransmit = 45, + .t_reassembly = 35, + .t_status_prohibit = 0, + .poll_pdu = -1, + .poll_byte = -1, + .max_retx_threshold = 8, + .sn_field_length = 12, + }, + .drb_am = { + .t_poll_retransmit = 45, + .t_reassembly = 15, + .t_status_prohibit = 15, + .poll_pdu = 64, + .poll_byte = 1024 * 500, + .max_retx_threshold = 32, + .sn_field_length = 18, + }, + .drb_um = { + .t_reassembly = 15, + .sn_field_length = 12, + } + }; RC.nb_nr_macrlc_inst = 1; RC.nb_nr_mac_CC = (int*)malloc(RC.nb_nr_macrlc_inst*sizeof(int)); for (i = 0; i < RC.nb_nr_macrlc_inst; i++) RC.nb_nr_mac_CC[i] = 1; - mac_top_init_gNB(ngran_gNB, scc, NULL, &conf); + mac_top_init_gNB(ngran_gNB, scc, NULL, &conf, &rlc_config); gNB_mac = RC.nrmac[0]; nr_mac_config_scc(RC.nrmac[0], scc, &conf); diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 4c12530f30..4e127fe0b7 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -668,12 +668,36 @@ int main(int argc, char *argv[]) .timer_config.t311 = 3000, .timer_config.n311 = 1, .timer_config.t319 = 400}; + const nr_rlc_configuration_t rlc_config = { + .srb = { + .t_poll_retransmit = 45, + .t_reassembly = 35, + .t_status_prohibit = 0, + .poll_pdu = -1, + .poll_byte = -1, + .max_retx_threshold = 8, + .sn_field_length = 12, + }, + .drb_am = { + .t_poll_retransmit = 45, + .t_reassembly = 15, + .t_status_prohibit = 15, + .poll_pdu = 64, + .poll_byte = 1024 * 500, + .max_retx_threshold = 32, + .sn_field_length = 18, + }, + .drb_um = { + .t_reassembly = 15, + .sn_field_length = 12, + } + }; RC.nb_nr_macrlc_inst = 1; RC.nb_nr_mac_CC = (int*)malloc(RC.nb_nr_macrlc_inst*sizeof(int)); for (i = 0; i < RC.nb_nr_macrlc_inst; i++) RC.nb_nr_mac_CC[i] = 1; - mac_top_init_gNB(ngran_gNB, scc, NULL /* scd will be updated further below */, &conf); + mac_top_init_gNB(ngran_gNB, scc, NULL /* scd will be updated further below */, &conf, &rlc_config); nr_mac_config_scc(RC.nrmac[0], scc, &conf); NR_ServingCellConfig_t *scd = calloc(1,sizeof(NR_ServingCellConfig_t)); diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index a2112d46eb..ec732a4f91 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -846,7 +846,11 @@ static void verify_section_notset(configmodule_interface_t *cfg, char *aprefix, paramlist_def_t pl = {0}; strncpy(pl.listname, secname, sizeof(pl.listname) - 1); config_getlist(cfg, &pl, NULL, 0, aprefix); - AssertFatal(pl.numelt == 0, "Section \"%s.%s\" not allowed in this config, please remove it\n", aprefix ? aprefix : "", secname); + AssertFatal(pl.numelt == 0, + "Section \"%s%s%s\" not allowed in this config, please remove it\n", + aprefix ? aprefix : "", + aprefix ? "." : "", + secname); } void RCconfig_verify(configmodule_interface_t *cfg, ngran_node_t node_type) { @@ -879,6 +883,7 @@ void RCconfig_verify(configmodule_interface_t *cfg, ngran_node_t node_type) verify_section_notset(cfg, NULL, CONFIG_STRING_L1_LIST); verify_section_notset(cfg, NULL, CONFIG_STRING_RU_LIST); verify_section_notset(cfg, NULL, CONFIG_STRING_MACRLC_LIST); + verify_section_notset(cfg, NULL, CONFIG_STRING_NR_RLC_LIST); } else if (NODE_IS_DU(node_type)) { // verify that there is no bearer config verify_gnb_param_notset(gnbp, GNB_ENABLE_SDAP_IDX, GNB_CONFIG_STRING_ENABLE_SDAP); @@ -886,6 +891,7 @@ void RCconfig_verify(configmodule_interface_t *cfg, ngran_node_t node_type) verify_section_notset(cfg, GNB_CONFIG_STRING_GNB_LIST ".[0]", GNB_CONFIG_STRING_AMF_IP_ADDRESS); verify_section_notset(cfg, NULL, CONFIG_STRING_SECURITY); + verify_section_notset(cfg, NULL, CONFIG_STRING_NR_PDCP_LIST); } // else nothing to be checked /* other possible verifications: PNF, VNF, CU-CP, CU-UP, ...? */ @@ -1467,6 +1473,55 @@ static seq_arr_t *fill_du_sibs(paramdef_t *GNBparamarray) return du_SIBs; } +void config_rlc(configmodule_interface_t *cfg, nr_rlc_configuration_t *rlc_config) +{ + /* SRB configuration */ + paramdef_t rlc_srb_params[] = NR_RLC_SRB_GLOBALPARAMS_DESC; + int ret = config_get(cfg, rlc_srb_params, sizeofArray(rlc_srb_params), CONFIG_STRING_NR_RLC_SRB); + AssertFatal(ret >= 0, "problem reading NR RLC configuration from configuration file\n"); + + rlc_config->srb.t_poll_retransmit = config_get_processedint(cfg, &rlc_srb_params[CONFIG_NR_RLC_SRB_T_POLL_RETRANSMIT_IDX]); + rlc_config->srb.t_reassembly = config_get_processedint(cfg, &rlc_srb_params[CONFIG_NR_RLC_SRB_T_REASSEMBLY_IDX]); + rlc_config->srb.t_status_prohibit = config_get_processedint(cfg, &rlc_srb_params[CONFIG_NR_RLC_SRB_T_STATUS_PROHIBIT_IDX]); + rlc_config->srb.poll_pdu = config_get_processedint(cfg, &rlc_srb_params[CONFIG_NR_RLC_SRB_POLL_PDU_IDX]); + rlc_config->srb.poll_byte = config_get_processedint(cfg, &rlc_srb_params[CONFIG_NR_RLC_SRB_POLL_BYTE_IDX]); + rlc_config->srb.max_retx_threshold = config_get_processedint(cfg, &rlc_srb_params[CONFIG_NR_RLC_SRB_MAX_RETX_THRESHOLD_IDX]); + rlc_config->srb.sn_field_length = config_get_processedint(cfg, &rlc_srb_params[CONFIG_NR_RLC_SRB_SN_FIELD_LENGTH_IDX]); + + /* DRB AM configuration */ + paramdef_t rlc_drb_am_params[] = NR_RLC_DRB_AM_GLOBALPARAMS_DESC; + ret = config_get(cfg, rlc_drb_am_params, sizeofArray(rlc_drb_am_params), CONFIG_STRING_NR_RLC_DRB_AM); + AssertFatal(ret >= 0, "problem reading NR RLC configuration from configuration file\n"); + + rlc_config->drb_am.t_poll_retransmit = config_get_processedint(cfg, &rlc_drb_am_params[CONFIG_NR_RLC_DRB_AM_T_POLL_RETRANSMIT_IDX]); + rlc_config->drb_am.t_reassembly = config_get_processedint(cfg, &rlc_drb_am_params[CONFIG_NR_RLC_DRB_AM_T_REASSEMBLY_IDX]); + rlc_config->drb_am.t_status_prohibit = config_get_processedint(cfg, &rlc_drb_am_params[CONFIG_NR_RLC_DRB_AM_T_STATUS_PROHIBIT_IDX]); + rlc_config->drb_am.poll_pdu = config_get_processedint(cfg, &rlc_drb_am_params[CONFIG_NR_RLC_DRB_AM_POLL_PDU_IDX]); + rlc_config->drb_am.poll_byte = config_get_processedint(cfg, &rlc_drb_am_params[CONFIG_NR_RLC_DRB_AM_POLL_BYTE_IDX]); + rlc_config->drb_am.max_retx_threshold = config_get_processedint(cfg, &rlc_drb_am_params[CONFIG_NR_RLC_DRB_AM_MAX_RETX_THRESHOLD_IDX]); + rlc_config->drb_am.sn_field_length = config_get_processedint(cfg, &rlc_drb_am_params[CONFIG_NR_RLC_DRB_AM_SN_FIELD_LENGTH_IDX]); + + /* DRB UM configuration */ + paramdef_t rlc_drb_um_params[] = NR_RLC_DRB_UM_GLOBALPARAMS_DESC; + ret = config_get(cfg, rlc_drb_um_params, sizeofArray(rlc_drb_um_params), CONFIG_STRING_NR_RLC_DRB_UM); + AssertFatal(ret >= 0, "problem reading NR RLC configuration from configuration file\n"); + + rlc_config->drb_um.t_reassembly = config_get_processedint(cfg, &rlc_drb_um_params[CONFIG_NR_RLC_DRB_UM_T_REASSEMBLY_IDX]); + rlc_config->drb_um.sn_field_length = config_get_processedint(cfg, &rlc_drb_um_params[CONFIG_NR_RLC_DRB_UM_SN_FIELD_LENGTH_IDX]); +} + +void config_pdcp(configmodule_interface_t *cfg, nr_pdcp_configuration_t *pdcp_config) +{ + /* DRB configuration */ + paramdef_t pdcp_params[] = NR_PDCP_DRB_GLOBALPARAMS_DESC; + int ret = config_get(cfg, pdcp_params, sizeofArray(pdcp_params), CONFIG_STRING_NR_PDCP_DRB); + AssertFatal(ret >= 0, "problem reading NR PDCP configuration from configuration file\n"); + + pdcp_config->drb.sn_size = config_get_processedint(cfg, &pdcp_params[CONFIG_NR_PDCP_DRB_SN_SIZE_IDX]); + pdcp_config->drb.t_reordering = config_get_processedint(cfg, &pdcp_params[CONFIG_NR_PDCP_DRB_T_REORDERING_IDX]); + pdcp_config->drb.discard_timer = config_get_processedint(cfg, &pdcp_params[CONFIG_NR_PDCP_DRB_DISCARD_TIMER_IDX]); +} + void RCconfig_nr_macrlc(configmodule_interface_t *cfg) { int j = 0; @@ -1612,8 +1667,12 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) NR_ServingCellConfig_t *scd = get_scd_config(cfg); if (MacRLC_ParamList.numelt > 0) { + /* NR RLC config is needed by mac_top_init_gNB() */ + nr_rlc_configuration_t default_rlc_config; + config_rlc(cfg, &default_rlc_config); + ngran_node_t node_type = get_node_type(); - mac_top_init_gNB(node_type, scc, scd, &config); + mac_top_init_gNB(node_type, scc, scd, &config, &default_rlc_config); RC.nb_nr_mac_CC = (int *)malloc(RC.nb_nr_macrlc_inst * sizeof(int)); for (j = 0; j < RC.nb_nr_macrlc_inst; j++) { @@ -2142,6 +2201,9 @@ gNB_RRC_INST *RCconfig_NRRRC() if (!NODE_IS_DU(rrc->node_type)) config_security(rrc); + config_rlc(config_get_if(), &rrc->rlc_config); + config_pdcp(config_get_if(), &rrc->pdcp_config); + return rrc; } diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index 99eb8847af..cc2c412a81 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -680,5 +680,215 @@ typedef enum { /*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -#endif +#define CONFIG_STRING_NR_RLC_LIST "rlc" +#define CONFIG_STRING_NR_PDCP_LIST "pdcp" +#define CONFIG_NR_RLC_T_POLL_RETRANSMIT "t_poll_retransmit" +#define CONFIG_NR_RLC_T_REASSEMBLY "t_reassembly" +#define CONFIG_NR_RLC_T_STATUS_PROHIBIT "t_status_prohibit" +#define CONFIG_NR_RLC_POLL_PDU "poll_pdu" +#define CONFIG_NR_RLC_POLL_BYTE "poll_byte" +#define CONFIG_NR_RLC_MAX_RETX_THRESHOLD "max_retx_threshold" +#define CONFIG_NR_RLC_SN_FIELD_LENGTH "sn_field_length" + +/*----------------------------------------------------------------------*/ +/* nr rlc srb configuration */ +/*----------------------------------------------------------------------*/ + +#define CONFIG_STRING_NR_RLC_SRB "rlc.srb" + +#define CONFIG_NR_RLC_SRB_T_POLL_RETRANSMIT_IDX 0 +#define CONFIG_NR_RLC_SRB_T_REASSEMBLY_IDX 1 +#define CONFIG_NR_RLC_SRB_T_STATUS_PROHIBIT_IDX 2 +#define CONFIG_NR_RLC_SRB_POLL_PDU_IDX 3 +#define CONFIG_NR_RLC_SRB_POLL_BYTE_IDX 4 +#define CONFIG_NR_RLC_SRB_MAX_RETX_THRESHOLD_IDX 5 +#define CONFIG_NR_RLC_SRB_SN_FIELD_LENGTH_IDX 6 + +#define NR_RLC_SRB_GLOBALPARAMS_DESC { \ + { .optname = CONFIG_NR_RLC_T_POLL_RETRANSMIT, \ + .defstrval = "ms45", \ + .helpstr = "poll retransmit timer", .paramflags = 0, .strptr = NULL, .type = TYPE_STRING, .numelt = 0, \ + .chkPptr = &(checkedparam_t){ .s3a = { .f3a = config_checkstr_assign_integer, \ + .okstrval = { VALUES_NR_RLC_T_POLL_RETRANSMIT_STR }, \ + .setintval = { VALUES_NR_RLC_T_POLL_RETRANSMIT }, \ + .num_okstrval = SIZEOF_NR_RLC_T_POLL_RETRANSMIT }}}, \ + { .optname = CONFIG_NR_RLC_T_REASSEMBLY, \ + .defstrval = "ms35", \ + .helpstr = "reassembly timer", .paramflags = 0, .strptr = NULL, .type = TYPE_STRING, .numelt = 0, \ + .chkPptr = &(checkedparam_t){ .s3a = { .f3a = config_checkstr_assign_integer, \ + .okstrval = { VALUES_NR_RLC_T_REASSEMBLY_STR }, \ + .setintval = { VALUES_NR_RLC_T_REASSEMBLY }, \ + .num_okstrval = SIZEOF_NR_RLC_T_REASSEMBLY }}}, \ + { .optname = CONFIG_NR_RLC_T_STATUS_PROHIBIT, \ + .defstrval = "ms0", \ + .helpstr = "status prohibit timer", .paramflags = 0, .strptr = NULL, .type = TYPE_STRING, .numelt = 0, \ + .chkPptr = &(checkedparam_t){ .s3a = { .f3a = config_checkstr_assign_integer, \ + .okstrval = { VALUES_NR_RLC_T_STATUS_PROHIBIT_STR }, \ + .setintval = { VALUES_NR_RLC_T_STATUS_PROHIBIT }, \ + .num_okstrval = SIZEOF_NR_RLC_T_STATUS_PROHIBIT }}}, \ + { .optname = CONFIG_NR_RLC_POLL_PDU, \ + .defstrval = "infinity", \ + .helpstr = "pollPDU", .paramflags = 0, .strptr = NULL, .type = TYPE_STRING, .numelt = 0, \ + .chkPptr = &(checkedparam_t){ .s3a = { .f3a = config_checkstr_assign_integer, \ + .okstrval = { VALUES_NR_RLC_POLL_PDU_STR }, \ + .setintval = { VALUES_NR_RLC_POLL_PDU }, \ + .num_okstrval = SIZEOF_NR_RLC_POLL_PDU }}}, \ + { .optname = CONFIG_NR_RLC_POLL_BYTE, \ + .defstrval = "infinity", \ + .helpstr = "pollByte", .paramflags = 0, .strptr = NULL, .type = TYPE_STRING, .numelt = 0, \ + .chkPptr = &(checkedparam_t){ .s3a = { .f3a = config_checkstr_assign_integer, \ + .okstrval = { VALUES_NR_RLC_POLL_BYTE_STR }, \ + .setintval = { VALUES_NR_RLC_POLL_BYTE }, \ + .num_okstrval = SIZEOF_NR_RLC_POLL_BYTE }}}, \ + { .optname = CONFIG_NR_RLC_MAX_RETX_THRESHOLD, \ + .defstrval = "t8", \ + .helpstr = "max reTX threshold", .paramflags = 0, .strptr = NULL, .type = TYPE_STRING, .numelt = 0, \ + .chkPptr = &(checkedparam_t){ .s3a = { .f3a = config_checkstr_assign_integer, \ + .okstrval = { VALUES_NR_RLC_MAX_RETX_THRESHOLD_STR }, \ + .setintval = { VALUES_NR_RLC_MAX_RETX_THRESHOLD }, \ + .num_okstrval = SIZEOF_NR_RLC_MAX_RETX_THRESHOLD }}}, \ + { .optname = CONFIG_NR_RLC_SN_FIELD_LENGTH, \ + .defstrval = "size12", \ + .helpstr = "SN size", .paramflags = 0, .strptr = NULL, .type = TYPE_STRING, .numelt = 0, \ + .chkPptr = &(checkedparam_t){ .s3a = { .f3a = config_checkstr_assign_integer, \ + .okstrval = { VALUES_NR_RLC_SN_FIELD_LENGTH_AM_STR }, \ + .setintval = { VALUES_NR_RLC_SN_FIELD_LENGTH_AM }, \ + .num_okstrval = SIZEOF_NR_RLC_SN_FIELD_LENGTH_AM }}}, \ +} + +/*----------------------------------------------------------------------*/ +/* nr rlc drb am configuration */ +/*----------------------------------------------------------------------*/ + +#define CONFIG_STRING_NR_RLC_DRB_AM "rlc.drb_am" + +#define CONFIG_NR_RLC_DRB_AM_T_POLL_RETRANSMIT_IDX 0 +#define CONFIG_NR_RLC_DRB_AM_T_REASSEMBLY_IDX 1 +#define CONFIG_NR_RLC_DRB_AM_T_STATUS_PROHIBIT_IDX 2 +#define CONFIG_NR_RLC_DRB_AM_POLL_PDU_IDX 3 +#define CONFIG_NR_RLC_DRB_AM_POLL_BYTE_IDX 4 +#define CONFIG_NR_RLC_DRB_AM_MAX_RETX_THRESHOLD_IDX 5 +#define CONFIG_NR_RLC_DRB_AM_SN_FIELD_LENGTH_IDX 6 + +#define NR_RLC_DRB_AM_GLOBALPARAMS_DESC { \ + { .optname = CONFIG_NR_RLC_T_POLL_RETRANSMIT, \ + .defstrval = "ms45", \ + .helpstr = "poll retransmit timer", .paramflags = 0, .strptr = NULL, .type = TYPE_STRING, .numelt = 0, \ + .chkPptr = &(checkedparam_t){ .s3a = { .f3a = config_checkstr_assign_integer, \ + .okstrval = { VALUES_NR_RLC_T_POLL_RETRANSMIT_STR }, \ + .setintval = { VALUES_NR_RLC_T_POLL_RETRANSMIT }, \ + .num_okstrval = SIZEOF_NR_RLC_T_POLL_RETRANSMIT }}}, \ + { .optname = CONFIG_NR_RLC_T_REASSEMBLY, \ + .defstrval = "ms15", \ + .helpstr = "reassembly timer", .paramflags = 0, .strptr = NULL, .type = TYPE_STRING, .numelt = 0, \ + .chkPptr = &(checkedparam_t){ .s3a = { .f3a = config_checkstr_assign_integer, \ + .okstrval = { VALUES_NR_RLC_T_REASSEMBLY_STR }, \ + .setintval = { VALUES_NR_RLC_T_REASSEMBLY }, \ + .num_okstrval = SIZEOF_NR_RLC_T_REASSEMBLY }}}, \ + { .optname = CONFIG_NR_RLC_T_STATUS_PROHIBIT, \ + .defstrval = "ms15", \ + .helpstr = "status prohibit timer", .paramflags = 0, .strptr = NULL, .type = TYPE_STRING, .numelt = 0, \ + .chkPptr = &(checkedparam_t){ .s3a = { .f3a = config_checkstr_assign_integer, \ + .okstrval = { VALUES_NR_RLC_T_STATUS_PROHIBIT_STR }, \ + .setintval = { VALUES_NR_RLC_T_STATUS_PROHIBIT }, \ + .num_okstrval = SIZEOF_NR_RLC_T_STATUS_PROHIBIT }}}, \ + { .optname = CONFIG_NR_RLC_POLL_PDU, \ + .defstrval = "p64", \ + .helpstr = "pollPDU", .paramflags = 0, .strptr = NULL, .type = TYPE_STRING, .numelt = 0, \ + .chkPptr = &(checkedparam_t){ .s3a = { .f3a = config_checkstr_assign_integer, \ + .okstrval = { VALUES_NR_RLC_POLL_PDU_STR }, \ + .setintval = { VALUES_NR_RLC_POLL_PDU }, \ + .num_okstrval = SIZEOF_NR_RLC_POLL_PDU }}}, \ + { .optname = CONFIG_NR_RLC_POLL_BYTE, \ + .defstrval = "kB500", \ + .helpstr = "pollByte", .paramflags = 0, .strptr = NULL, .type = TYPE_STRING, .numelt = 0, \ + .chkPptr = &(checkedparam_t){ .s3a = { .f3a = config_checkstr_assign_integer, \ + .okstrval = { VALUES_NR_RLC_POLL_BYTE_STR }, \ + .setintval = { VALUES_NR_RLC_POLL_BYTE }, \ + .num_okstrval = SIZEOF_NR_RLC_POLL_BYTE }}}, \ + { .optname = CONFIG_NR_RLC_MAX_RETX_THRESHOLD, \ + .defstrval = "t32", \ + .helpstr = "max reTX threshold", .paramflags = 0, .strptr = NULL, .type = TYPE_STRING, .numelt = 0, \ + .chkPptr = &(checkedparam_t){ .s3a = { .f3a = config_checkstr_assign_integer, \ + .okstrval = { VALUES_NR_RLC_MAX_RETX_THRESHOLD_STR }, \ + .setintval = { VALUES_NR_RLC_MAX_RETX_THRESHOLD }, \ + .num_okstrval = SIZEOF_NR_RLC_MAX_RETX_THRESHOLD }}}, \ + { .optname = CONFIG_NR_RLC_SN_FIELD_LENGTH, \ + .defstrval = "size18", \ + .helpstr = "SN size", .paramflags = 0, .strptr = NULL, .type = TYPE_STRING, .numelt = 0, \ + .chkPptr = &(checkedparam_t){ .s3a = { .f3a = config_checkstr_assign_integer, \ + .okstrval = { VALUES_NR_RLC_SN_FIELD_LENGTH_AM_STR }, \ + .setintval = { VALUES_NR_RLC_SN_FIELD_LENGTH_AM }, \ + .num_okstrval = SIZEOF_NR_RLC_SN_FIELD_LENGTH_AM }}}, \ +} + +/*----------------------------------------------------------------------*/ +/* nr rlc drb um configuration */ +/*----------------------------------------------------------------------*/ + +#define CONFIG_STRING_NR_RLC_DRB_UM "rlc.drb_um" + +#define CONFIG_NR_RLC_DRB_UM_T_REASSEMBLY_IDX 0 +#define CONFIG_NR_RLC_DRB_UM_SN_FIELD_LENGTH_IDX 1 + +#define NR_RLC_DRB_UM_GLOBALPARAMS_DESC { \ + { .optname = CONFIG_NR_RLC_T_REASSEMBLY, \ + .defstrval = "ms15", \ + .helpstr = "reassembly timer", .paramflags = 0, .strptr = NULL, .type = TYPE_STRING, .numelt = 0, \ + .chkPptr = &(checkedparam_t){ .s3a = { .f3a = config_checkstr_assign_integer, \ + .okstrval = { VALUES_NR_RLC_T_REASSEMBLY_STR }, \ + .setintval = { VALUES_NR_RLC_T_REASSEMBLY }, \ + .num_okstrval = SIZEOF_NR_RLC_T_REASSEMBLY }}}, \ + { .optname = CONFIG_NR_RLC_SN_FIELD_LENGTH, \ + .defstrval = "size12", \ + .helpstr = "SN size", .paramflags = 0, .strptr = NULL, .type = TYPE_STRING, .numelt = 0, \ + .chkPptr = &(checkedparam_t){ .s3a = { .f3a = config_checkstr_assign_integer, \ + .okstrval = { VALUES_NR_RLC_SN_FIELD_LENGTH_UM_STR }, \ + .setintval = { VALUES_NR_RLC_SN_FIELD_LENGTH_UM }, \ + .num_okstrval = SIZEOF_NR_RLC_SN_FIELD_LENGTH_UM }}}, \ +} + +/*----------------------------------------------------------------------*/ + +#define CONFIG_NR_PDCP_SN_SIZE "sn_size" +#define CONFIG_NR_PDCP_T_REORDERING "t_reordering" +#define CONFIG_NR_PDCP_DISCARD_TIMER "discard_timer" + +/*----------------------------------------------------------------------*/ +/* nr pdcp drb configuration */ +/*----------------------------------------------------------------------*/ + +#define CONFIG_STRING_NR_PDCP_DRB "pdcp.drb" + +#define CONFIG_NR_PDCP_DRB_SN_SIZE_IDX 0 +#define CONFIG_NR_PDCP_DRB_T_REORDERING_IDX 1 +#define CONFIG_NR_PDCP_DRB_DISCARD_TIMER_IDX 2 + +#define NR_PDCP_DRB_GLOBALPARAMS_DESC { \ + { .optname = CONFIG_NR_PDCP_SN_SIZE, \ + .defstrval = "len18bits", \ + .helpstr = "SN size", .paramflags = 0, .strptr = NULL, .type = TYPE_STRING, .numelt = 0, \ + .chkPptr = &(checkedparam_t){ .s3a = { .f3a = config_checkstr_assign_integer, \ + .okstrval = { VALUES_NR_PDCP_SN_SIZE_STR }, \ + .setintval = { VALUES_NR_PDCP_SN_SIZE }, \ + .num_okstrval = SIZEOF_NR_PDCP_SN_SIZE }}}, \ + { .optname = CONFIG_NR_PDCP_T_REORDERING, \ + .defstrval = "ms100", \ + .helpstr = "reordering timer", .paramflags = 0, .strptr = NULL, .type = TYPE_STRING, .numelt = 0, \ + .chkPptr = &(checkedparam_t){ .s3a = { .f3a = config_checkstr_assign_integer, \ + .okstrval = { VALUES_NR_PDCP_T_REORDERING_STR }, \ + .setintval = { VALUES_NR_PDCP_T_REORDERING }, \ + .num_okstrval = SIZEOF_NR_PDCP_T_REORDERING }}}, \ + { .optname = CONFIG_NR_PDCP_DISCARD_TIMER, \ + .defstrval = "infinity", \ + .helpstr = "discard timer", .paramflags = 0, .strptr = NULL, .type = TYPE_STRING, .numelt = 0, \ + .chkPptr = &(checkedparam_t){ .s3a = { .f3a = config_checkstr_assign_integer, \ + .okstrval = { VALUES_NR_PDCP_DISCARD_TIMER_STR }, \ + .setintval = { VALUES_NR_PDCP_DISCARD_TIMER }, \ + .num_okstrval = SIZEOF_NR_PDCP_DISCARD_TIMER }}} \ +} + +/*----------------------------------------------------------------------*/ + +#endif diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 5ceff85296..2e6a778163 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -3326,7 +3326,7 @@ bool prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE) int srb_id = 1; const NR_ServingCellConfigCommon_t *scc = mac->common_channels[CC_id].ServingCellConfigCommon; const NR_ServingCellConfig_t *sccd = UE->is_redcap ? NULL : mac->common_channels[CC_id].pre_ServingCellConfig; - NR_CellGroupConfig_t *cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, sccd, &mac->radio_config); + NR_CellGroupConfig_t *cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, sccd, &mac->radio_config, &mac->rlc_config); ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); UE->CellGroup = cellGroupConfig; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index f0b59c73de..a61e2f8f89 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -34,6 +34,7 @@ #include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h" #include "NR_TAG-Id.h" #include "common/ngran_types.h" +#include "openair2/LAYER2/nr_pdcp/nr_pdcp_configuration.h" void set_cset_offset(uint16_t); void get_K1_K2(int N1, int N2, int *K1, int *K2, int layers); @@ -52,7 +53,8 @@ void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_alloca void mac_top_init_gNB(ngran_node_t node_type, NR_ServingCellConfigCommon_t *scc, NR_ServingCellConfig_t *scd, - const nr_mac_config_t *conf); + const nr_mac_config_t *conf, + const nr_rlc_configuration_t *default_rlc_config); void mac_top_destroy_gNB(gNB_MAC_INST *mac); void nr_mac_send_f1_setup_req(void); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 28c129cb58..a5999e50b1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -221,19 +221,21 @@ void gnb_du_configuration_update_acknowledge(const f1ap_gnb_du_configuration_upd LOG_I(MAC, "received gNB-DU configuration update acknowledge\n"); } -static NR_RLC_BearerConfig_t *get_bearerconfig_from_srb(const f1ap_srb_to_be_setup_t *srb) +static NR_RLC_BearerConfig_t *get_bearerconfig_from_srb(const f1ap_srb_to_be_setup_t *srb, + const nr_rlc_configuration_t *rlc_config) { long priority = srb->srb_id == 2 ? 3 : 1; // see 38.331 sec 9.2.1 e_NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration bucket = NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms5; - return get_SRB_RLC_BearerConfig(get_lcid_from_srbid(srb->srb_id), priority, bucket); + return get_SRB_RLC_BearerConfig(get_lcid_from_srbid(srb->srb_id), priority, bucket, rlc_config); } static int handle_ue_context_srbs_setup(NR_UE_info_t *UE, int srbs_len, const f1ap_srb_to_be_setup_t *req_srbs, f1ap_srb_to_be_setup_t **resp_srbs, - NR_CellGroupConfig_t *cellGroupConfig) + NR_CellGroupConfig_t *cellGroupConfig, + const nr_rlc_configuration_t *rlc_config) { DevAssert(req_srbs != NULL && resp_srbs != NULL && cellGroupConfig != NULL); @@ -241,7 +243,7 @@ static int handle_ue_context_srbs_setup(NR_UE_info_t *UE, AssertFatal(*resp_srbs != NULL, "out of memory\n"); for (int i = 0; i < srbs_len; i++) { const f1ap_srb_to_be_setup_t *srb = &req_srbs[i]; - NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_srb(srb); + NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_srb(srb, rlc_config); nr_rlc_add_srb(UE->rnti, srb->srb_id, rlc_BearerConfig); int priority = rlc_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->priority; @@ -265,11 +267,12 @@ static int handle_ue_context_srbs_setup(NR_UE_info_t *UE, return srbs_len; } -static NR_RLC_BearerConfig_t *get_bearerconfig_from_drb(const f1ap_drb_to_be_setup_t *drb) +static NR_RLC_BearerConfig_t *get_bearerconfig_from_drb(const f1ap_drb_to_be_setup_t *drb, + const nr_rlc_configuration_t *rlc_config) { const NR_RLC_Config_PR rlc_conf = drb->rlc_mode == F1AP_RLC_MODE_AM ? NR_RLC_Config_PR_am : NR_RLC_Config_PR_um_Bi_Directional; long priority = 13; // hardcoded for the moment - return get_DRB_RLC_BearerConfig(get_lcid_from_drbid(drb->drb_id), drb->drb_id, rlc_conf, priority); + return get_DRB_RLC_BearerConfig(get_lcid_from_drbid(drb->drb_id), drb->drb_id, rlc_conf, priority, rlc_config); } static int get_non_dynamic_priority(int fiveqi) @@ -304,7 +307,8 @@ static int handle_ue_context_drbs_setup(NR_UE_info_t *UE, int drbs_len, const f1ap_drb_to_be_setup_t *req_drbs, f1ap_drb_to_be_setup_t **resp_drbs, - NR_CellGroupConfig_t *cellGroupConfig) + NR_CellGroupConfig_t *cellGroupConfig, + const nr_rlc_configuration_t *rlc_config) { DevAssert(req_drbs != NULL && resp_drbs != NULL && cellGroupConfig != NULL); instance_t f1inst = get_f1_gtp_instance(); @@ -316,7 +320,7 @@ static int handle_ue_context_drbs_setup(NR_UE_info_t *UE, for (int i = 0; i < drbs_len; i++) { const f1ap_drb_to_be_setup_t *drb = &req_drbs[i]; f1ap_drb_to_be_setup_t *resp_drb = &(*resp_drbs)[i]; - NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_drb(drb); + NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_drb(drb, rlc_config); nr_rlc_add_drb(UE->rnti, drb->drb_id, rlc_BearerConfig); nr_lc_config_t c = {.lcid = rlc_BearerConfig->logicalChannelIdentity, .nssai = drb->nssai}; @@ -557,7 +561,7 @@ static NR_UE_info_t *create_new_UE(gNB_MAC_INST *mac, uint32_t cu_id, const NR_C const NR_ServingCellConfig_t *sccd = cc->pre_ServingCellConfig; const nr_mac_config_t *configuration = &mac->radio_config; if (is_SA) { - cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, sccd, &mac->radio_config); + cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, sccd, &mac->radio_config, &mac->rlc_config); cellGroupConfig->spCellConfig->reconfigurationWithSync = get_reconfiguration_with_sync(UE->rnti, UE->uid, scc); } else { NR_UE_NR_Capability_t *cap = get_ue_nr_cap_from_cg_config_info(cgci); @@ -649,7 +653,8 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) req->srbs_to_be_setup_length, req->srbs_to_be_setup, &resp.srbs_to_be_setup, - new_CellGroup); + new_CellGroup, + &mac->rlc_config); } if (req->drbs_to_be_setup_length > 0) { @@ -657,7 +662,8 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) req->drbs_to_be_setup_length, req->drbs_to_be_setup, &resp.drbs_to_be_setup, - new_CellGroup); + new_CellGroup, + &mac->rlc_config); } if (req->rrc_container != NULL) { @@ -747,7 +753,8 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) req->srbs_to_be_setup_length, req->srbs_to_be_setup, &resp.srbs_to_be_setup, - new_CellGroup); + new_CellGroup, + &mac->rlc_config); } if (req->drbs_to_be_setup_length > 0) { @@ -755,7 +762,8 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) req->drbs_to_be_setup_length, req->drbs_to_be_setup, &resp.drbs_to_be_setup, - new_CellGroup); + new_CellGroup, + &mac->rlc_config); } if (req->drbs_to_be_released_length > 0) { diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 9c8e414f52..0acc6fe0d2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -236,7 +236,8 @@ static void mac_rrc_init(gNB_MAC_INST *mac, ngran_node_t node_type) void mac_top_init_gNB(ngran_node_t node_type, NR_ServingCellConfigCommon_t *scc, NR_ServingCellConfig_t *scd, - const nr_mac_config_t *config) + const nr_mac_config_t *config, + const nr_rlc_configuration_t *default_rlc_config) { module_id_t i; gNB_MAC_INST *nrmac; @@ -272,6 +273,7 @@ void mac_top_init_gNB(ngran_node_t node_type, RC.nrmac[i]->common_channels[0].ServingCellConfigCommon = scc; RC.nrmac[i]->radio_config = *config; + RC.nrmac[i]->rlc_config = *default_rlc_config; RC.nrmac[i]->common_channels[0].pre_ServingCellConfig = scd; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index d97783604f..70b53552e7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -45,6 +45,7 @@ #include "common/utils/ds/seq_arr.h" #include "common/utils/nr/nr_common.h" #include "common/utils/ds/byte_array.h" +#include "openair2/LAYER2/nr_rlc/nr_rlc_configuration.h" #define NR_SCHED_LOCK(lock) \ do { \ @@ -899,6 +900,7 @@ typedef struct gNB_MAC_INST_s { nr_pp_impl_ul pre_processor_ul; nr_mac_config_t radio_config; + nr_rlc_configuration_t rlc_config; NR_UE_sched_ctrl_t *sched_ctrlCommon; NR_sched_pdcch_t *sched_pdcch_otherSI; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c index 22c2207be1..d361352e9f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c @@ -40,6 +40,7 @@ #include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h" #include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" #include "openair3/UTILS/conversions.h" +#include "LAYER2/nr_rlc/nr_rlc_asn1_utils.h" #include "NR_MeasurementTimingConfiguration.h" #include "uper_decoder.h" @@ -3338,7 +3339,10 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid, return SpCellConfig; } -NR_RLC_BearerConfig_t *get_SRB_RLC_BearerConfig(long channelId, long priority, long bucketSizeDuration) +NR_RLC_BearerConfig_t *get_SRB_RLC_BearerConfig(long channelId, + long priority, + long bucketSizeDuration, + const nr_rlc_configuration_t *default_rlc_config) { NR_RLC_BearerConfig_t *rlc_BearerConfig = NULL; rlc_BearerConfig = calloc(1, sizeof(NR_RLC_BearerConfig_t)); @@ -3352,15 +3356,15 @@ NR_RLC_BearerConfig_t *get_SRB_RLC_BearerConfig(long channelId, long priority, l rlc_Config->present = NR_RLC_Config_PR_am; rlc_Config->choice.am = calloc(1, sizeof(*rlc_Config->choice.am)); rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = calloc(1, sizeof(NR_SN_FieldLengthAM_t)); - *(rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength) = NR_SN_FieldLengthAM_size12; - rlc_Config->choice.am->dl_AM_RLC.t_Reassembly = NR_T_Reassembly_ms35; - rlc_Config->choice.am->dl_AM_RLC.t_StatusProhibit = NR_T_StatusProhibit_ms0; + *(rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength) = encode_sn_field_length_am(default_rlc_config->srb.sn_field_length); + rlc_Config->choice.am->dl_AM_RLC.t_Reassembly = encode_t_reassembly(default_rlc_config->srb.t_reassembly); + rlc_Config->choice.am->dl_AM_RLC.t_StatusProhibit = encode_t_status_prohibit(default_rlc_config->srb.t_status_prohibit); rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = calloc(1, sizeof(NR_SN_FieldLengthAM_t)); - *(rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength) = NR_SN_FieldLengthAM_size12; - rlc_Config->choice.am->ul_AM_RLC.t_PollRetransmit = NR_T_PollRetransmit_ms45; - rlc_Config->choice.am->ul_AM_RLC.pollPDU = NR_PollPDU_infinity; - rlc_Config->choice.am->ul_AM_RLC.pollByte = NR_PollByte_infinity; - rlc_Config->choice.am->ul_AM_RLC.maxRetxThreshold = NR_UL_AM_RLC__maxRetxThreshold_t8; + *(rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength) = encode_sn_field_length_am(default_rlc_config->srb.sn_field_length); + rlc_Config->choice.am->ul_AM_RLC.t_PollRetransmit = encode_t_poll_retransmit(default_rlc_config->srb.t_poll_retransmit); + rlc_Config->choice.am->ul_AM_RLC.pollPDU = encode_poll_pdu(default_rlc_config->srb.poll_pdu); + rlc_Config->choice.am->ul_AM_RLC.pollByte = encode_poll_byte(default_rlc_config->srb.poll_byte); + rlc_Config->choice.am->ul_AM_RLC.maxRetxThreshold = encode_max_retx_threshold(default_rlc_config->srb.max_retx_threshold); rlc_BearerConfig->rlc_Config = rlc_Config; NR_LogicalChannelConfig_t *logicalChannelConfig = calloc(1, sizeof(NR_LogicalChannelConfig_t)); @@ -3381,7 +3385,9 @@ NR_RLC_BearerConfig_t *get_SRB_RLC_BearerConfig(long channelId, long priority, l return rlc_BearerConfig; } -static void nr_drb_config(struct NR_RLC_Config *rlc_Config, NR_RLC_Config_PR rlc_config_pr) +static void nr_drb_config(struct NR_RLC_Config *rlc_Config, + NR_RLC_Config_PR rlc_config_pr, + const nr_rlc_configuration_t *default_rlc_config) { switch (rlc_config_pr) { case NR_RLC_Config_PR_um_Bi_Directional: @@ -3390,25 +3396,25 @@ static void nr_drb_config(struct NR_RLC_Config *rlc_Config, NR_RLC_Config_PR rlc rlc_Config->choice.um_Bi_Directional = calloc(1, sizeof(*rlc_Config->choice.um_Bi_Directional)); rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = calloc(1, sizeof(*rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength)); - *rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12; + *rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = encode_sn_field_length_um(default_rlc_config->drb_um.sn_field_length); rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = calloc(1, sizeof(*rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength)); - *rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12; - rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.t_Reassembly = NR_T_Reassembly_ms15; + *rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = encode_sn_field_length_um(default_rlc_config->drb_um.sn_field_length); + rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.t_Reassembly = encode_t_reassembly(default_rlc_config->drb_um.t_reassembly); break; case NR_RLC_Config_PR_am: // RLC AM Bearer configuration rlc_Config->choice.am = calloc(1, sizeof(*rlc_Config->choice.am)); rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = calloc(1, sizeof(*rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength)); - *rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size18; - rlc_Config->choice.am->ul_AM_RLC.t_PollRetransmit = NR_T_PollRetransmit_ms45; - rlc_Config->choice.am->ul_AM_RLC.pollPDU = NR_PollPDU_p64; - rlc_Config->choice.am->ul_AM_RLC.pollByte = NR_PollByte_kB500; - rlc_Config->choice.am->ul_AM_RLC.maxRetxThreshold = NR_UL_AM_RLC__maxRetxThreshold_t32; + *rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = encode_sn_field_length_am(default_rlc_config->drb_am.sn_field_length); + rlc_Config->choice.am->ul_AM_RLC.t_PollRetransmit = encode_t_poll_retransmit(default_rlc_config->drb_am.t_poll_retransmit); + rlc_Config->choice.am->ul_AM_RLC.pollPDU = encode_poll_pdu(default_rlc_config->drb_am.poll_pdu); + rlc_Config->choice.am->ul_AM_RLC.pollByte = encode_poll_byte(default_rlc_config->drb_am.poll_byte); + rlc_Config->choice.am->ul_AM_RLC.maxRetxThreshold = encode_max_retx_threshold(default_rlc_config->drb_am.max_retx_threshold); rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = calloc(1, sizeof(*rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength)); - *rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size18; - rlc_Config->choice.am->dl_AM_RLC.t_Reassembly = NR_T_Reassembly_ms15; - rlc_Config->choice.am->dl_AM_RLC.t_StatusProhibit = NR_T_StatusProhibit_ms15; + *rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = encode_sn_field_length_am(default_rlc_config->drb_am.sn_field_length); + rlc_Config->choice.am->dl_AM_RLC.t_Reassembly = encode_t_reassembly(default_rlc_config->drb_am.t_reassembly); + rlc_Config->choice.am->dl_AM_RLC.t_StatusProhibit = encode_t_status_prohibit(default_rlc_config->drb_am.t_status_prohibit); break; default: AssertFatal(false, "RLC config type %d not handled\n", rlc_config_pr); @@ -3417,7 +3423,11 @@ static void nr_drb_config(struct NR_RLC_Config *rlc_Config, NR_RLC_Config_PR rlc rlc_Config->present = rlc_config_pr; } -NR_RLC_BearerConfig_t *get_DRB_RLC_BearerConfig(long lcChannelId, long drbId, NR_RLC_Config_PR rlc_conf, long priority) +NR_RLC_BearerConfig_t *get_DRB_RLC_BearerConfig(long lcChannelId, + long drbId, + NR_RLC_Config_PR rlc_conf, + long priority, + const nr_rlc_configuration_t *default_rlc_config) { NR_RLC_BearerConfig_t *rlc_BearerConfig = calloc(1, sizeof(NR_RLC_BearerConfig_t)); rlc_BearerConfig->logicalChannelIdentity = lcChannelId; @@ -3427,7 +3437,7 @@ NR_RLC_BearerConfig_t *get_DRB_RLC_BearerConfig(long lcChannelId, long drbId, NR rlc_BearerConfig->reestablishRLC = NULL; NR_RLC_Config_t *rlc_Config = calloc(1, sizeof(NR_RLC_Config_t)); - nr_drb_config(rlc_Config, rlc_conf); + nr_drb_config(rlc_Config, rlc_conf, default_rlc_config); rlc_BearerConfig->rlc_Config = rlc_Config; NR_LogicalChannelConfig_t *logicalChannelConfig = calloc(1, sizeof(NR_LogicalChannelConfig_t)); @@ -3451,7 +3461,8 @@ NR_RLC_BearerConfig_t *get_DRB_RLC_BearerConfig(long lcChannelId, long drbId, NR NR_CellGroupConfig_t *get_initial_cellGroupConfig(int uid, const NR_ServingCellConfigCommon_t *scc, const NR_ServingCellConfig_t *servingcellconfigdedicated, - const nr_mac_config_t *configuration) + const nr_mac_config_t *configuration, + const nr_rlc_configuration_t *default_rlc_config) { NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(*cellGroupConfig)); cellGroupConfig->cellGroupId = 0; @@ -3460,7 +3471,7 @@ NR_CellGroupConfig_t *get_initial_cellGroupConfig(int uid, /* TS38.331 9.2.1 Default SRB configurations */ cellGroupConfig->rlc_BearerToAddModList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList)); NR_RLC_BearerConfig_t *rlc_BearerConfig = - get_SRB_RLC_BearerConfig(1, 1, NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms1000); + get_SRB_RLC_BearerConfig(1, 1, NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms1000, default_rlc_config); asn1cSeqAdd(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig); cellGroupConfig->rlc_BearerToReleaseList = NULL; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h index d5a7f8d40a..cdb4f5b792 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h @@ -31,6 +31,7 @@ #include "NR_UL-CCCH-Message.h" #include "f1ap_messages_types.h" #include "common/platform_types.h" +#include "openair2/LAYER2/nr_rlc/nr_rlc_configuration.h" struct NR_MeasurementTimingConfiguration; struct NR_PDSCH_TimeDomainResourceAllocationList; @@ -84,7 +85,8 @@ NR_SIB19_r17_t *get_SIB19_NR(const NR_ServingCellConfigCommon_t *scc); NR_CellGroupConfig_t *get_initial_cellGroupConfig(int uid, const NR_ServingCellConfigCommon_t *scc, const NR_ServingCellConfig_t *servingcellconfigdedicated, - const nr_mac_config_t *configuration); + const nr_mac_config_t *configuration, + const nr_rlc_configuration_t *default_rlc_config); void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, const int uid, NR_UE_NR_Capability_t *uecap, @@ -107,7 +109,14 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC NR_ReconfigurationWithSync_t *get_reconfiguration_with_sync(rnti_t rnti, uid_t uid, const NR_ServingCellConfigCommon_t *scc); -NR_RLC_BearerConfig_t *get_SRB_RLC_BearerConfig(long channelId, long priority, long bucketSizeDuration); -NR_RLC_BearerConfig_t *get_DRB_RLC_BearerConfig(long lcChannelId, long drbId, NR_RLC_Config_PR rlc_conf, long priority); +NR_RLC_BearerConfig_t *get_SRB_RLC_BearerConfig(long channelId, + long priority, + long bucketSizeDuration, + const nr_rlc_configuration_t *default_rlc_config); +NR_RLC_BearerConfig_t *get_DRB_RLC_BearerConfig(long lcChannelId, + long drbId, + NR_RLC_Config_PR rlc_conf, + long priority, + const nr_rlc_configuration_t *default_rlc_config); #endif diff --git a/openair2/LAYER2/nr_pdcp/asn1_utils.c b/openair2/LAYER2/nr_pdcp/asn1_utils.c index 6b45a73acf..5ec86be3c6 100644 --- a/openair2/LAYER2/nr_pdcp/asn1_utils.c +++ b/openair2/LAYER2/nr_pdcp/asn1_utils.c @@ -19,63 +19,30 @@ * contact@openairinterface.org */ +#include "nr_pdcp_asn1_utils.h" #include "common/utils/LOG/log.h" #include "nr_pdcp_entity.h" +#include "nr_pdcp_configuration.h" -int decode_t_reordering(int v) -{ - static const int tab[36] = {0, 1, 2, 4, 5, 8, 10, 15, 20, 30, 40, 50, 60, 80, 100, 120, 140, 160, - 180, 200, 220, 240, 260, 280, 300, 500, 750, 1000, 1250, 1500, 1750, 2000, 2250, 2500, 2750, 3000}; - - if (v < 0 || v > 35) { - LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); - exit(1); - } - - return tab[v]; +#define ENCODE_DECODE(a, b) \ +int decode_##a(int v) \ +{ \ + static const int tab[] = { VALUES_NR_PDCP_##b }; \ + AssertFatal(v >= 0 && v < SIZEOF_NR_PDCP_##b, \ + "bad encoded value " #a " %d\n", v); \ + return tab[v]; \ +} \ + \ +int encode_##a(int v) \ +{ \ + static const int tab[] = { VALUES_NR_PDCP_##b }; \ + for (int ret = 0; ret < SIZEOF_NR_PDCP_##b; ret++) \ + if (tab[ret] == v) \ + return ret; \ + AssertFatal(0, "bad " #a " value %d\n", v); \ } -int decode_sn_size_ul(long s) -{ - if (s == 0) return SHORT_SN_SIZE; - if (s == 1) return LONG_SN_SIZE; - LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); - exit(1); -} - -int decode_sn_size_dl(long s) -{ - if (s == 0) return SHORT_SN_SIZE; - if (s == 1) return LONG_SN_SIZE; - LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); - exit(1); -} - -int decode_discard_timer(long v) -{ - static const int tab[16] = { - 10, - 20, - 30, - 40, - 50, - 60, - 75, - 100, - 150, - 200, - 250, - 300, - 500, - 750, - 1500, - -1, - }; - - if (v < 0 || v > 15) { - LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); - exit(1); - } - - return tab[v]; -} +ENCODE_DECODE(t_reordering, T_REORDERING) +ENCODE_DECODE(sn_size_ul, SN_SIZE) +ENCODE_DECODE(sn_size_dl, SN_SIZE) +ENCODE_DECODE(discard_timer, DISCARD_TIMER) diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_asn1_utils.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_asn1_utils.h index d525bce287..2628b29069 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_asn1_utils.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_asn1_utils.h @@ -23,8 +23,13 @@ #define _OPENAIR2_LAYER2_NR_PDCP_ASN1_UTILS_H_ int decode_t_reordering(int v); -int decode_sn_size_ul(long s); -int decode_sn_size_dl(long s); -int decode_discard_timer(long v); +int decode_sn_size_ul(int v); +int decode_sn_size_dl(int v); +int decode_discard_timer(int v); + +int encode_t_reordering(int v); +int encode_sn_size_ul(int v); +int encode_sn_size_dl(int v); +int encode_discard_timer(int v); #endif /* _OPENAIR2_LAYER2_NR_PDCP_ASN1_UTILS_H_ */ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_configuration.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_configuration.h new file mode 100644 index 0000000000..f7eac08bd2 --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_configuration.h @@ -0,0 +1,70 @@ +/* + * 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 + */ + +#ifndef _NR_PDCP_CONFIGURATION_H_ +#define _NR_PDCP_CONFIGURATION_H_ + +#ifndef INT_LIST_SIZE +#define INT_LIST_SIZE(x) (sizeof((int[]){x})/sizeof(int)) +#endif + +/* values taken from 3GPP TS 38.331 version 17.3.0 */ + +#define VALUES_NR_PDCP_SN_SIZE \ + 12, 18 + +#define VALUES_NR_PDCP_SN_SIZE_STR \ + "len12bits", "len18bits" + +#define SIZEOF_NR_PDCP_SN_SIZE INT_LIST_SIZE(VALUES_NR_PDCP_SN_SIZE) + +#define VALUES_NR_PDCP_T_REORDERING \ + 0, 1, 2, 4, 5, 8, 10, 15, 20, 30, 40, 50, \ + 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260, 280, \ + 300, 500, 750, 1000, 1250, 1500, 1750, 2000, 2250, 2500, 2750, 3000, \ + -1 /* -1 means infinity */ \ + +#define VALUES_NR_PDCP_T_REORDERING_STR \ + "ms0", "ms1", "ms2", "ms4", "ms5", "ms8", "ms10", "ms15", "ms20", "ms30", "ms40", "ms50", \ + "ms60", "ms80", "ms100", "ms120", "ms140", "ms160", "ms180", "ms200", "ms220", "ms240", "ms260", "ms280", \ + "ms300", "ms500", "ms750", "ms1000", "ms1250", "ms1500", "ms1750", "ms2000", "ms2250", "ms2500", "ms2750", "ms3000", \ + "infinity" + +#define SIZEOF_NR_PDCP_T_REORDERING INT_LIST_SIZE(VALUES_NR_PDCP_T_REORDERING) + +#define VALUES_NR_PDCP_DISCARD_TIMER \ + 10, 20, 30, 40, 50, 60, 75, 100, 150, 200, 250, 300, 500, 750, 1500, -1 /* -1 means infinity */ + +#define VALUES_NR_PDCP_DISCARD_TIMER_STR \ + "ms10", "ms20", "ms30", "ms40", "ms50", "ms60", "ms75", "ms100", "ms150", "ms200", "ms250", "ms300", "ms500", "ms750", "ms1500", "infinity" + +#define SIZEOF_NR_PDCP_DISCARD_TIMER INT_LIST_SIZE(VALUES_NR_PDCP_DISCARD_TIMER) + +/* configuration of NR PDCP, coming from configuration file */ +typedef struct { + struct { + int sn_size; + int t_reordering; + int discard_timer; + } drb; +} nr_pdcp_configuration_t; + +#endif /* _NR_PDCP_CONFIGURATION_H_ */ diff --git a/openair2/LAYER2/nr_rlc/asn1_utils.c b/openair2/LAYER2/nr_rlc/asn1_utils.c index fd64d89481..f6b3422751 100644 --- a/openair2/LAYER2/nr_rlc/asn1_utils.c +++ b/openair2/LAYER2/nr_rlc/asn1_utils.c @@ -19,157 +19,33 @@ * contact@openairinterface.org */ +#include "nr_rlc_asn1_utils.h" #include "rlc.h" +#include "nr_rlc_configuration.h" -int decode_t_reassembly(int v) -{ - static const int tab[31] = {0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, - 80, 85, 90, 95, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200}; - - if (v < 0 || v > 30) { - LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); - exit(1); - } - - return tab[v]; +#define ENCODE_DECODE(a, b) \ +int decode_##a(int v) \ +{ \ + static const int tab[] = { VALUES_NR_RLC_##b }; \ + AssertFatal(v >= 0 && v < SIZEOF_NR_RLC_##b, \ + "bad encoded value " #a " %d\n", v); \ + return tab[v]; \ +} \ + \ +int encode_##a(int v) \ +{ \ + static const int tab[] = { VALUES_NR_RLC_##b }; \ + for (int ret = 0; ret < SIZEOF_NR_RLC_##b; ret++) \ + if (tab[ret] == v) \ + return ret; \ + AssertFatal(0, "bad " #a " value %d\n", v); \ } -int decode_t_status_prohibit(int v) -{ - static const int tab[62] = {0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, - 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, - 160, 165, 170, 175, 180, 185, 190, 195, 200, 205, 210, 215, 220, 225, 230, 235, - 240, 245, 250, 300, 350, 400, 450, 500, 800, 1000, 1200, 1600, 2000, 2400}; - - if (v < 0 || v > 61) { - LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); - exit(1); - } - - return tab[v]; -} - -int decode_t_poll_retransmit(int v) -{ - static const int tab[59] = {5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, - 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180, 185, 190, 195, 200, - 205, 210, 215, 220, 225, 230, 235, 240, 245, 250, 300, 350, 400, 450, 500, 800, 1000, 2000, 4000}; - - if (v < 0 || v > 58) { - LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); - exit(1); - } - - return tab[v]; -} - -int decode_poll_pdu(int v) -{ - static const int tab[24] = { - 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 6144, - 8192, 12288, 16384, 20480, 24576, 28672, 32768, 40960, 49152, 57344, 65536, -1 /* -1 means infinity */ - }; - - if (v < 0 || v > 23) { - LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); - exit(1); - } - - return tab[v]; -} - -int decode_poll_byte(int v) -{ - static const int tab[44] = { - /* KB */ - 1024 * 1, - 1024 * 2, - 1024 * 5, - 1024 * 8, - 1024 * 10, - 1024 * 15, - 1024 * 25, - 1024 * 50, - 1024 * 75, - 1024 * 100, - 1024 * 125, - 1024 * 250, - 1024 * 375, - 1024 * 500, - 1024 * 750, - 1024 * 1000, - 1024 * 1250, - 1024 * 1500, - 1024 * 2000, - 1024 * 3000, - 1024 * 4000, - 1024 * 4500, - 1024 * 5000, - 1024 * 5500, - 1024 * 6000, - 1024 * 6500, - 1024 * 7000, - 1024 * 7500, - /* MB */ - 1024 * 1024 * 8, - 1024 * 1024 * 9, - 1024 * 1024 * 10, - 1024 * 1024 * 11, - 1024 * 1024 * 12, - 1024 * 1024 * 13, - 1024 * 1024 * 14, - 1024 * 1024 * 15, - 1024 * 1024 * 16, - 1024 * 1024 * 17, - 1024 * 1024 * 18, - 1024 * 1024 * 20, - 1024 * 1024 * 25, - 1024 * 1024 * 30, - 1024 * 1024 * 40, - -1 /* -1 means infinity */ - }; - - if (v < 0 || v > 43) { - LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); - exit(1); - } - - if (tab[v] == -1) return -1; - return tab[v]; -} - -int decode_max_retx_threshold(int v) -{ - static const int tab[8] = {1, 2, 3, 4, 6, 8, 16, 32}; - - if (v < 0 || v > 7) { - LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); - exit(1); - } - - return tab[v]; -} - -int decode_sn_field_length_um(int v) -{ - static const int tab[2] = {6, 12}; - - if (v < 0 || v > 1) { - LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); - exit(1); - } - - return tab[v]; -} - -int decode_sn_field_length_am(int v) -{ - static const int tab[2] = {12, 18}; - - if (v < 0 || v > 1) { - LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); - exit(1); - } - - return tab[v]; -} +ENCODE_DECODE(t_reassembly, T_REASSEMBLY) +ENCODE_DECODE(t_status_prohibit, T_STATUS_PROHIBIT) +ENCODE_DECODE(t_poll_retransmit, T_POLL_RETRANSMIT) +ENCODE_DECODE(poll_pdu, POLL_PDU) +ENCODE_DECODE(poll_byte, POLL_BYTE) +ENCODE_DECODE(max_retx_threshold, MAX_RETX_THRESHOLD) +ENCODE_DECODE(sn_field_length_am, SN_FIELD_LENGTH_AM) +ENCODE_DECODE(sn_field_length_um, SN_FIELD_LENGTH_UM) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_asn1_utils.h b/openair2/LAYER2/nr_rlc/nr_rlc_asn1_utils.h index 6f010b02da..cbeb445105 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_asn1_utils.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_asn1_utils.h @@ -31,4 +31,13 @@ int decode_max_retx_threshold(int v); int decode_sn_field_length_um(int v); int decode_sn_field_length_am(int v); +int encode_t_reassembly(int v); +int encode_t_status_prohibit(int v); +int encode_t_poll_retransmit(int v); +int encode_poll_pdu(int v); +int encode_poll_byte(int v); +int encode_max_retx_threshold(int v); +int encode_sn_field_length_um(int v); +int encode_sn_field_length_am(int v); + #endif /* _OPENAIR2_LAYER2_NR_RLC_ASN1_UTILS_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_configuration.h b/openair2/LAYER2/nr_rlc/nr_rlc_configuration.h new file mode 100644 index 0000000000..467e451152 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_configuration.h @@ -0,0 +1,160 @@ +/* + * 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 + */ + +#ifndef _NR_RLC_CONFIGURATION_H_ +#define _NR_RLC_CONFIGURATION_H_ + +#ifndef INT_LIST_SIZE +#define INT_LIST_SIZE(x) (sizeof((int[]){x})/sizeof(int)) +#endif + +/* values taken from 3GPP TS 38.331 version 17.3.0 */ + +#define VALUES_NR_RLC_T_POLL_RETRANSMIT \ + 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, \ + 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, \ + 145, 150, 155, 160, 165, 170, 175, 180, 185, 190, 195, 200, 205, 210, \ + 215, 220, 225, 230, 235, 240, 245, 250, 300, 350, 400, 450, 500, 800, \ + 1000, 2000, 4000, 1, 2, 4 + +#define VALUES_NR_RLC_T_POLL_RETRANSMIT_STR \ + "ms5", "ms10", "ms15", "ms20", "ms25", "ms30", "ms35", "ms40", "ms45", "ms50", "ms55", "ms60", "ms65", "ms70", \ + "ms75", "ms80", "ms85", "ms90", "ms95", "ms100", "ms105", "ms110", "ms115", "ms120", "ms125", "ms130", "ms135", "ms140", \ + "ms145", "ms150", "ms155", "ms160", "ms165", "ms170", "ms175", "ms180", "ms185", "ms190", "ms195", "ms200", "ms205", "ms210", \ + "ms215", "ms220", "ms225", "ms230", "ms235", "ms240", "ms245", "ms250", "ms300", "ms350", "ms400", "ms450", "ms500", "ms800", \ + "ms1000", "ms2000", "ms4000", "ms1", "ms2", "ms4" + +#define SIZEOF_NR_RLC_T_POLL_RETRANSMIT INT_LIST_SIZE(VALUES_NR_RLC_T_POLL_RETRANSMIT) + +#define VALUES_NR_RLC_T_REASSEMBLY \ + 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, \ + 80, 85, 90, 95, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200 + +#define VALUES_NR_RLC_T_REASSEMBLY_STR \ + "ms0", "ms5", "ms10", "ms15", "ms20", "ms25", "ms30", "ms35", "ms40", "ms45", "ms50", "ms55", "ms60", "ms65", "ms70", "ms75", \ + "ms80", "ms85", "ms90", "ms95", "ms100", "ms110", "ms120", "ms130", "ms140", "ms150", "ms160", "ms170", "ms180", "ms190", "ms200" + +#define SIZEOF_NR_RLC_T_REASSEMBLY INT_LIST_SIZE(VALUES_NR_RLC_T_REASSEMBLY) + +#define VALUES_NR_RLC_T_STATUS_PROHIBIT \ + 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, \ + 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, \ + 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, \ + 180, 185, 190, 195, 200, 205, 210, 215, 220, 225, 230, 235, \ + 240, 245, 250, 300, 350, 400, 450, 500, 800, 1000, 1200, 1600, \ + 2000, 2400 + +#define VALUES_NR_RLC_T_STATUS_PROHIBIT_STR \ + "ms0", "ms5", "ms10", "ms15", "ms20", "ms25", "ms30", "ms35", "ms40", "ms45", "ms50", "ms55", \ + "ms60", "ms65", "ms70", "ms75", "ms80", "ms85", "ms90", "ms95", "ms100", "ms105", "ms110", "ms115", \ + "ms120", "ms125", "ms130", "ms135", "ms140", "ms145", "ms150", "ms155", "ms160", "ms165", "ms170", "ms175", \ + "ms180", "ms185", "ms190", "ms195", "ms200", "ms205", "ms210", "ms215", "ms220", "ms225", "ms230", "ms235", \ + "ms240", "ms245", "ms250", "ms300", "ms350", "ms400", "ms450", "ms500", "ms800", "ms1000", "ms1200", "ms1600", \ + "ms2000", "ms2400" + +#define SIZEOF_NR_RLC_T_STATUS_PROHIBIT INT_LIST_SIZE(VALUES_NR_RLC_T_STATUS_PROHIBIT) + +#define VALUES_NR_RLC_POLL_PDU \ + 4, 8, 16, 32, 64, 128, 256, 512, 1024, \ + 2048, 4096, 6144, 8192, 12288, 16384, 20480, 24576, 28672, \ + 32768, 40960, 49152, 57344, 65536, -1 /* -1 means infinity */ + +#define VALUES_NR_RLC_POLL_PDU_STR \ + "p4", "p8", "p16", "p32", "p64", "p128", "p256", "p512", "p1024", \ + "p2048", "p4096", "p6144", "p8192", "p12288", "p16384", "p20480", "p24576", "p28672", \ + "p32768", "p40960", "p49152", "p57344", "p65536", "infinity" + +#define SIZEOF_NR_RLC_POLL_PDU INT_LIST_SIZE(VALUES_NR_RLC_POLL_PDU) + +#define VALUES_NR_RLC_POLL_BYTE \ + /* KB */ \ + 1024 * 1, 1024 * 2, 1024 * 5, 1024 * 8, 1024 * 10, 1024 * 15, 1024 * 25, 1024 * 50, 1024 * 75, \ + 1024 * 100, 1024 * 125, 1024 * 250, 1024 * 375, 1024 * 500, 1024 * 750, 1024 * 1000, 1024 * 1250, \ + 1024 * 1500, 1024 * 2000, 1024 * 3000, 1024 * 4000, 1024 * 4500, 1024 * 5000, 1024 * 5500, \ + 1024 * 6000, 1024 * 6500, 1024 * 7000, 1024 * 7500, \ + /* MB */ \ + 1024 * 1024 * 8, 1024 * 1024 * 9, 1024 * 1024 * 10, 1024 * 1024 * 11, 1024 * 1024 * 12, \ + 1024 * 1024 * 13, 1024 * 1024 * 14, 1024 * 1024 * 15, 1024 * 1024 * 16, 1024 * 1024 * 17, \ + 1024 * 1024 * 18, 1024 * 1024 * 20, 1024 * 1024 * 25, 1024 * 1024 * 30, 1024 * 1024 * 40, \ + -1 /* -1 means infinity */ + +#define VALUES_NR_RLC_POLL_BYTE_STR \ + "kB1", "kB2", "kB5", "kB8", "kB10", "kB15", "kB25", "kB50", "kB75", \ + "kB100", "kB125", "kB250", "kB375", "kB500", "kB750", "kB1000", "kB1250", \ + "kB1500", "kB2000", "kB3000", "kB4000", "kB4500", "kB5000", "kB5500", \ + "kB6000", "kB6500", "kB7000", "kB7500", \ + "mB8", "mB9", "mB10", "mB11", "mB12", "mB13", "mB14", "mB15", \ + "mB16", "mB17", "mB18", "mB20", "mB25", "mB30", "mB40", \ + "infinity" + +#define SIZEOF_NR_RLC_POLL_BYTE INT_LIST_SIZE(VALUES_NR_RLC_POLL_BYTE) + +#define VALUES_NR_RLC_MAX_RETX_THRESHOLD \ + 1, 2, 3, 4, 6, 8, 16, 32 + +#define VALUES_NR_RLC_MAX_RETX_THRESHOLD_STR \ + "t1", "t2", "t3", "t4", "t6", "t8", "t16", "t32" + +#define SIZEOF_NR_RLC_MAX_RETX_THRESHOLD INT_LIST_SIZE(VALUES_NR_RLC_MAX_RETX_THRESHOLD) + +#define VALUES_NR_RLC_SN_FIELD_LENGTH_AM \ + 12, 18 + +#define VALUES_NR_RLC_SN_FIELD_LENGTH_AM_STR \ + "size12", "size18" + +#define SIZEOF_NR_RLC_SN_FIELD_LENGTH_AM INT_LIST_SIZE(VALUES_NR_RLC_SN_FIELD_LENGTH_AM) + +#define VALUES_NR_RLC_SN_FIELD_LENGTH_UM \ + 6, 12 + +#define VALUES_NR_RLC_SN_FIELD_LENGTH_UM_STR \ + "size6", "size12" + +#define SIZEOF_NR_RLC_SN_FIELD_LENGTH_UM INT_LIST_SIZE(VALUES_NR_RLC_SN_FIELD_LENGTH_UM) + +/* configuration of NR RLC, coming from configuration file */ +typedef struct { + struct { + int t_poll_retransmit; + int t_reassembly; + int t_status_prohibit; + int poll_pdu; + int poll_byte; + int max_retx_threshold; + int sn_field_length; + } srb; + struct { + int t_poll_retransmit; + int t_reassembly; + int t_status_prohibit; + int poll_pdu; + int poll_byte; + int max_retx_threshold; + int sn_field_length; + } drb_am; + struct { + int t_reassembly; + int sn_field_length; + } drb_um; +} nr_rlc_configuration_t; + +#endif /* _NR_RLC_CONFIGURATION_H_ */ diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 6ab4ffc2fc..ad973bdc5f 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -46,6 +46,7 @@ #include "LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "asn1_msg.h" #include "../nr_rrc_proto.h" +#include "LAYER2/nr_pdcp/nr_pdcp_asn1_utils.h" #include "openair3/SECU/key_nas_deriver.h" @@ -274,7 +275,8 @@ int do_RRCReject(uint8_t *const buffer) NR_RadioBearerConfig_t *get_default_rbconfig(int eps_bearer_id, int rb_id, e_NR_CipheringAlgorithm ciphering_algorithm, - e_NR_SecurityConfig__keyToUse key_to_use) + e_NR_SecurityConfig__keyToUse key_to_use, + const nr_pdcp_configuration_t *pdcp_config) { NR_RadioBearerConfig_t *rbconfig = calloc(1, sizeof(*rbconfig)); rbconfig->srb_ToAddModList = NULL; @@ -289,9 +291,9 @@ NR_RadioBearerConfig_t *get_default_rbconfig(int eps_bearer_id, drb_ToAddMod->recoverPDCP = NULL; drb_ToAddMod->pdcp_Config = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config)); asn1cCalloc(drb_ToAddMod->pdcp_Config->drb, drb); - asn1cCallocOne(drb->discardTimer, NR_PDCP_Config__drb__discardTimer_infinity); - asn1cCallocOne(drb->pdcp_SN_SizeUL, NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits); - asn1cCallocOne(drb->pdcp_SN_SizeDL, NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits); + asn1cCallocOne(drb->discardTimer, encode_discard_timer(pdcp_config->drb.discard_timer)); + asn1cCallocOne(drb->pdcp_SN_SizeUL, encode_sn_size_ul(pdcp_config->drb.sn_size)); + asn1cCallocOne(drb->pdcp_SN_SizeDL, encode_sn_size_dl(pdcp_config->drb.sn_size)); drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed; drb->headerCompression.choice.notUsed = 0; drb->integrityProtection = NULL; @@ -299,7 +301,7 @@ NR_RadioBearerConfig_t *get_default_rbconfig(int eps_bearer_id, drb->outOfOrderDelivery = NULL; drb_ToAddMod->pdcp_Config->moreThanOneRLC = NULL; - asn1cCallocOne(drb_ToAddMod->pdcp_Config->t_Reordering, NR_PDCP_Config__t_Reordering_ms100); + asn1cCallocOne(drb_ToAddMod->pdcp_Config->t_Reordering, encode_t_reordering(pdcp_config->drb.t_reordering)); drb_ToAddMod->pdcp_Config->ext1 = NULL; asn1cSeqAdd(&rbconfig->drb_ToAddModList->list,drb_ToAddMod); diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h index 83be12d87b..3ac4695eba 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.h +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h @@ -53,6 +53,7 @@ #include "ds/seq_arr.h" #include "ds/byte_array.h" #include "rrc_messages_types.h" +#include "openair2/LAYER2/nr_pdcp/nr_pdcp_configuration.h" struct asn_TYPE_descriptor_s; typedef struct { @@ -86,7 +87,8 @@ int do_RRCReject(uint8_t *const buffer); NR_RadioBearerConfig_t *get_default_rbconfig(int eps_bearer_id, int rb_id, e_NR_CipheringAlgorithm ciphering_algorithm, - e_NR_SecurityConfig__keyToUse key_to_use); + e_NR_SecurityConfig__keyToUse key_to_use, + const nr_pdcp_configuration_t *pdcp_config); int do_RRCSetup(uint8_t *const buffer, size_t buffer_size, diff --git a/openair2/RRC/NR/MESSAGES/tests/CMakeLists.txt b/openair2/RRC/NR/MESSAGES/tests/CMakeLists.txt index 3f7bf45c0e..980d6160e8 100644 --- a/openair2/RRC/NR/MESSAGES/tests/CMakeLists.txt +++ b/openair2/RRC/NR/MESSAGES/tests/CMakeLists.txt @@ -1,4 +1,7 @@ -add_executable(test_asn1_msg test_asn1_msg.cpp) +add_executable(test_asn1_msg + test_asn1_msg.cpp + ${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/asn1_utils.c) target_link_libraries(test_asn1_msg PRIVATE nr_rrc SECURITY minimal_lib GTest::gtest UTIL) add_dependencies(tests test_asn1_msg) add_test(NAME test_asn1_msg diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 640803af2f..f2434eceaf 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -54,6 +54,8 @@ #include "NR_UE-MRDC-Capability.h" #include "NR_UE-NR-Capability.h" #include "intertask_interface.h" +#include "openair2/LAYER2/nr_pdcp/nr_pdcp_configuration.h" +#include "openair2/LAYER2/nr_rlc/nr_rlc_configuration.h" typedef enum { NR_RRC_OK=0, @@ -383,6 +385,8 @@ typedef struct gNB_RRC_INST_s { RB_HEAD(rrc_cuup_tree, nr_rrc_cuup_container_t) cuups; // CU-UPs, indexed by assoc_id size_t num_cuups; + nr_pdcp_configuration_t pdcp_config; + nr_rlc_configuration_t rlc_config; } gNB_RRC_INST; #define UE_LOG_FMT "(cellID %lx, UE ID %d RNTI %04x)" diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 1ff31acae1..9fd4306962 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -397,7 +397,8 @@ bool trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession pduSession, rrc->configuration.enable_sdap, rrc->security.do_drb_integrity, - rrc->security.do_drb_ciphering); + rrc->security.do_drb_ciphering, + &rrc->pdcp_config); pdu->numDRB2Setup = 1; // One DRB per PDU Session. TODO: Remove hardcoding for (int j=0; j < pdu->numDRB2Setup; j++) { diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index deabe38327..8ac172a21e 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -141,7 +141,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, x2ap_ENDC_sgnb_addition_req_t *m, sctp_ uint32_t cgci_len = 0; if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1) { DevAssert(m == NULL); - UE->rb_config = get_default_rbconfig(10 /* EPS bearer ID */, 1 /* drb ID */, NR_CipheringAlgorithm_nea0, NR_SecurityConfig__keyToUse_master); + UE->rb_config = get_default_rbconfig(10 /* EPS bearer ID */, 1 /* drb ID */, NR_CipheringAlgorithm_nea0, NR_SecurityConfig__keyToUse_master, &rrc->pdcp_config); cgci_len = cg_config_info_from_ue_cap_file(sizeof tmp, tmp); DevAssert(cgci_len > 0); cgci_buf = tmp; @@ -223,7 +223,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, x2ap_ENDC_sgnb_addition_req_t *m, sctp_ exit(1); } - UE->rb_config = get_default_rbconfig(m->e_rabs_tobeadded[0].e_rab_id, m->e_rabs_tobeadded[0].drb_ID, cipher_algo, NR_SecurityConfig__keyToUse_secondary); + UE->rb_config = get_default_rbconfig(m->e_rabs_tobeadded[0].e_rab_id, m->e_rabs_tobeadded[0].drb_ID, cipher_algo, NR_SecurityConfig__keyToUse_secondary, &rrc->pdcp_config); } if(m!=NULL) { diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.c b/openair2/RRC/NR/rrc_gNB_radio_bearers.c index 35ae278b2a..e22ee7ffd6 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.c +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.c @@ -30,6 +30,7 @@ #include "common/utils/T/T.h" #include "ngap_messages_types.h" #include "oai_asn1.h" +#include "openair2/LAYER2/nr_pdcp/nr_pdcp_asn1_utils.h" rrc_pdu_session_param_t *find_pduSession(gNB_RRC_UE_t *ue, int id, bool create) { @@ -71,13 +72,16 @@ drb_t *get_drb(gNB_RRC_UE_t *ue, uint8_t drb_id) return &ue->established_drbs[drb_id - 1]; } -void set_default_drb_pdcp_config(struct pdcp_config_s *pdcp_config, int do_drb_integrity, int do_drb_ciphering) +void set_default_drb_pdcp_config(struct pdcp_config_s *pdcp_config, + int do_drb_integrity, + int do_drb_ciphering, + const nr_pdcp_configuration_t *default_pdcp_config) { AssertError(pdcp_config != NULL, return, "Failed to set default PDCP configuration for DRB!\n"); - pdcp_config->discardTimer = NR_PDCP_Config__drb__discardTimer_infinity; - pdcp_config->pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits; - pdcp_config->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits; - pdcp_config->t_Reordering = NR_PDCP_Config__t_Reordering_ms100; + pdcp_config->discardTimer = encode_discard_timer(default_pdcp_config->drb.discard_timer); + pdcp_config->pdcp_SN_SizeDL = encode_sn_size_dl(default_pdcp_config->drb.sn_size); + pdcp_config->pdcp_SN_SizeUL = encode_sn_size_ul(default_pdcp_config->drb.sn_size); + pdcp_config->t_Reordering = encode_t_reordering(default_pdcp_config->drb.t_reordering); pdcp_config->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed; pdcp_config->headerCompression.NotUsed = 0; pdcp_config->integrityProtection = do_drb_integrity ? NR_PDCP_Config__drb__integrityProtection_enabled : 1; @@ -99,7 +103,8 @@ drb_t *generateDRB(gNB_RRC_UE_t *ue, const rrc_pdu_session_param_t *pduSession, bool enable_sdap, int do_drb_integrity, - int do_drb_ciphering) + int do_drb_ciphering, + const nr_pdcp_configuration_t *pdcp_config) { DevAssert(ue != NULL); @@ -130,7 +135,7 @@ drb_t *generateDRB(gNB_RRC_UE_t *ue, est_drb->status = DRB_ACTIVE; } /* PDCP Configuration */ - set_default_drb_pdcp_config(&est_drb->pdcp_config, do_drb_integrity, do_drb_ciphering); + set_default_drb_pdcp_config(&est_drb->pdcp_config, do_drb_integrity, do_drb_ciphering, pdcp_config); drb_t *rrc_drb = get_drb(ue, drb_id); DevAssert(rrc_drb == est_drb); /* to double check that we create the same which we would retrieve */ diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.h b/openair2/RRC/NR/rrc_gNB_radio_bearers.h index 133e17627f..4a249496ff 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.h +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.h @@ -49,13 +49,15 @@ drb_t *get_drb(gNB_RRC_UE_t *ue, uint8_t drb_id); /// @param enable_sdap If true the SDAP header will be added to the packet, else it will not add or search for SDAP header. /// @param do_drb_integrity /// @param do_drb_ciphering +/// @param pdcp_config /// @return returns a pointer to the generated DRB structure drb_t *generateDRB(gNB_RRC_UE_t *ue, uint8_t drb_id, const rrc_pdu_session_param_t *pduSession, bool enable_sdap, int do_drb_integrity, - int do_drb_ciphering); + int do_drb_ciphering, + const nr_pdcp_configuration_t *pdcp_config); /// @brief return the next available (inactive) DRB ID of UE ue uint8_t get_next_available_drb_id(gNB_RRC_UE_t *ue);