diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d06d30c17..948f623f2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -413,6 +413,7 @@ target_link_libraries(x2ap PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) set(F1AP_DIR ${OPENAIR2_DIR}/F1AP) add_library(f1ap ${F1AP_DIR}/f1ap_common.c + ${F1AP_DIR}/f1ap_ids.c ${F1AP_DIR}/f1ap_cu_interface_management.c ${F1AP_DIR}/f1ap_cu_paging.c ${F1AP_DIR}/f1ap_cu_rrc_message_transfer.c @@ -431,7 +432,7 @@ add_library(f1ap ${F1AP_DIR}/f1ap_itti_messaging.c) target_include_directories(f1ap PUBLIC F1AP_DIR) target_link_libraries(f1ap PUBLIC asn1_f1ap) -target_link_libraries(f1ap PRIVATE ngap nr_rrc) +target_link_libraries(f1ap PRIVATE ngap nr_rrc HASHTABLE) # LPP ############## diff --git a/ci-scripts/xml_files/container_sa_b200_quectel.xml b/ci-scripts/xml_files/container_sa_b200_quectel.xml index 121b836769..0296ecfe93 100644 --- a/ci-scripts/xml_files/container_sa_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_b200_quectel.xml @@ -111,7 +111,7 @@ IdleSleep Sleep - 20 + 10 @@ -168,14 +168,14 @@ Custom_Command Trigger Reestablishment ofqot - echo ci force_reestab | nc -N 192.168.68.194 9090 | grep -E 'force-remove UE RNTI [0-9a-f]{4} from RLC to trigger reestablishment' + echo ci force_reestab | nc -N 192.168.68.194 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment' yes Custom_Command Verify Reestablishment ofqot - echo ci get_reestab_count | nc -N 192.168.68.194 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1 reconf_after_reestab 1' + echo ci get_reestab_count | nc -N 192.168.68.194 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1' yes diff --git a/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml b/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml index a20ea8845e..1f28fce309 100644 --- a/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml @@ -39,6 +39,10 @@ 110011 110001 150001 + 160001 + 100002 + 160002 + 150001 110011 110001 150000 @@ -114,7 +118,7 @@ IdleSleep Sleep - 20 + 10 @@ -184,6 +188,21 @@ single-ue + + Custom_Command + Trigger Reestablishment (on DU) + ofqot + echo ci force_reestab | nc -N 192.168.68.195 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment' + yes + + + Custom_Command + Verify Reestablishment (on CU) + ofqot + echo ci get_reestab_count | nc -N 192.168.68.194 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1' + yes + + Undeploy_Object Undeploy CU-DU diff --git a/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml b/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml index 0d4dd8f27e..d603b3f1ea 100644 --- a/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml @@ -105,7 +105,7 @@ IdleSleep Sleep - 20 + 10 @@ -162,14 +162,14 @@ Custom_Command Trigger Reestablishment ofqot - echo ci force_reestab | nc -N 192.168.68.194 9090 | grep -E 'force-remove UE RNTI [0-9a-f]{4} from RLC to trigger reestablishment' + echo ci force_reestab | nc -N 192.168.68.194 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment' yes Custom_Command Verify Reestablishment ofqot - echo ci get_reestab_count | nc -N 192.168.68.194 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1 reconf_after_reestab 1' + echo ci get_reestab_count | nc -N 192.168.68.194 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1' yes diff --git a/ci-scripts/yaml_files/sa_f1_b200_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_f1_b200_gnb/docker-compose.yml index e40dc686d7..2be92cdb38 100644 --- a/ci-scripts/yaml_files/sa_f1_b200_gnb/docker-compose.yml +++ b/ci-scripts/yaml_files/sa_f1_b200_gnb/docker-compose.yml @@ -6,7 +6,7 @@ services: privileged: true container_name: sa-cu-gnb environment: - USE_ADDITIONAL_OPTIONS: --sa --log_config.global_log_options level,nocolor,time,line_num,function + USE_ADDITIONAL_OPTIONS: --sa --telnetsrv --telnetsrv.shrmod ci --log_config.global_log_options level,nocolor,time,line_num,function volumes: - ../../conf_files/gnb-cu.sa.band78.106prb.usrpb200.conf:/opt/oai-gnb/etc/gnb.conf networks: @@ -26,7 +26,7 @@ services: container_name: sa-du-b200-gnb environment: USE_B2XX: 'yes' - USE_ADDITIONAL_OPTIONS: --sa --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx -E --log_config.global_log_options level,nocolor,time,line_num,function --gNBs.[0].min_rxtxtime 2 --gNBs.[0].do_CSIRS 1 --gNBs.[0].do_SRS 1 --RUs.[0].att_rx 14 --RUs.[0].att_tx 14 + USE_ADDITIONAL_OPTIONS: --sa --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx -E --telnetsrv --telnetsrv.shrmod ci --log_config.global_log_options level,nocolor,time,line_num,function --gNBs.[0].min_rxtxtime 2 --gNBs.[0].do_CSIRS 1 --gNBs.[0].do_SRS 1 --RUs.[0].att_rx 14 --RUs.[0].att_tx 14 volumes: - ../../conf_files/gnb-du.sa.band78.106prb.usrpb200.conf:/opt/oai-gnb/etc/gnb.conf - /dev:/dev diff --git a/common/utils/telnetsrv/telnetsrv_ci.c b/common/utils/telnetsrv/telnetsrv_ci.c index 3f4930d02b..2d7019b00e 100644 --- a/common/utils/telnetsrv/telnetsrv_ci.c +++ b/common/utils/telnetsrv/telnetsrv_ci.c @@ -28,15 +28,17 @@ #include #include "openair2/RRC/NR/rrc_gNB_UE_context.h" -#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h" +#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h" +#include "openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h" +#include "openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h" #define TELNETSERVERCODE #include "telnetsrv.h" #define ERROR_MSG_RET(mSG, aRGS...) do { prnt(mSG, ##aRGS); return 1; } while (0) -static int get_single_ue_rnti(void) +static int get_single_ue_rnti_mac(void) { NR_UE_info_t *ue = NULL; UE_iterator(RC.nrmac[0]->UE_info.list, it) { @@ -48,11 +50,6 @@ static int get_single_ue_rnti(void) if (!ue) return -1; - // verify it exists in RRC as well - rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], ue->rnti); - if (!rrcue) - return -1; - return ue->rnti; } @@ -61,7 +58,7 @@ int get_single_rnti(char *buf, int debug, telnet_printfunc_t prnt) if (buf) ERROR_MSG_RET("no parameter allowed\n"); - int rnti = get_single_ue_rnti(); + int rnti = get_single_ue_rnti_mac(); if (rnti < 1) ERROR_MSG_RET("different number of UEs\n"); @@ -71,23 +68,32 @@ int get_single_rnti(char *buf, int debug, telnet_printfunc_t prnt) int get_reestab_count(char *buf, int debug, telnet_printfunc_t prnt) { + if (!RC.nrrrc) + ERROR_MSG_RET("no RRC present, cannot list counts\n"); + rrc_gNB_ue_context_t *ue = NULL; int rnti = -1; if (!buf) { - rnti = get_single_ue_rnti(); - if (rnti < 1) - ERROR_MSG_RET("no UE found\n"); + rrc_gNB_ue_context_t *l = NULL; + int n = 0; + RB_FOREACH(l, rrc_nr_ue_tree_s, &RC.nrrrc[0]->rrc_ue_head) { + if (ue == NULL) ue = l; + n++; + } + if (!ue) + ERROR_MSG_RET("could not find any UE in RRC\n"); + if (n > 1) + ERROR_MSG_RET("more than one UE in RRC present\n"); } else { rnti = strtol(buf, NULL, 16); if (rnti < 1 || rnti >= 0xfffe) ERROR_MSG_RET("RNTI needs to be [1,0xfffe]\n"); + ue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti); + if (!ue) + ERROR_MSG_RET("could not find UE with RNTI %04x in RRC\n"); } - rrc_gNB_ue_context_t *ue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti); - if (!ue) - ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti); - prnt("UE RNTI %04x reestab %d reconf_after_reestab %d\n", - rnti, + ue->ue_context.rnti, ue->ue_context.ue_reestablishment_counter, ue->ue_context.ue_reconfiguration_after_reestablishment_counter); return 0; @@ -95,9 +101,11 @@ int get_reestab_count(char *buf, int debug, telnet_printfunc_t prnt) int trigger_reestab(char *buf, int debug, telnet_printfunc_t prnt) { + if (!RC.nrmac) + ERROR_MSG_RET("no MAC/RLC present, cannot trigger reestablishment\n"); int rnti = -1; if (!buf) { - rnti = get_single_ue_rnti(); + rnti = get_single_ue_rnti_mac(); if (rnti < 1) ERROR_MSG_RET("no UE found\n"); } else { @@ -106,13 +114,9 @@ int trigger_reestab(char *buf, int debug, telnet_printfunc_t prnt) ERROR_MSG_RET("RNTI needs to be [1,0xfffe]\n"); } - // verify it exists in RRC as well - rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti); - if (!rrcue) - ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti); + nr_rlc_test_trigger_reestablishment(rnti); - nr_rlc_remove_ue(rnti); - prnt("force-remove UE RNTI %04x from RLC to trigger reestablishment\n", rnti); + prnt("Reset RLC counters of UE RNTI %04x to trigger reestablishment\n", rnti); return 0; } diff --git a/executables/nr-cuup.c b/executables/nr-cuup.c index ffa50a766b..81d255b87d 100644 --- a/executables/nr-cuup.c +++ b/executables/nr-cuup.c @@ -27,6 +27,7 @@ #include "common/ran_context.h" #include "nfapi/oai_integration/vendor_ext.h" #include "openair2/F1AP/f1ap_common.h" +#include "openair2/F1AP/f1ap_ids.h" #include "openair2/GNB_APP/gnb_config.h" #include "nr_pdcp/nr_pdcp_oai_api.h" @@ -134,6 +135,7 @@ int main(int argc, char **argv) rc = itti_create_task(TASK_CUUP_E1, E1AP_CUUP_task, NULL); AssertFatal(rc >= 0, "Create task for CUUP E1 failed\n"); nr_pdcp_layer_init(); + cu_init_f1_ue_data(); // for CU-UP/CP mapping: we use the same MessageDef *msg = RCconfig_NR_CU_E1(true); AssertFatal(msg != NULL, "Send init to task for E1AP UP failed\n"); itti_send_msg_to_task(TASK_CUUP_E1, 0, msg); diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h index 7a88344efc..7a1a8b2698 100644 --- a/openair2/COMMON/e1ap_messages_types.h +++ b/openair2/COMMON/e1ap_messages_types.h @@ -156,7 +156,6 @@ typedef struct pdu_session_to_setup_s { typedef struct e1ap_bearer_setup_req_s { uint32_t gNB_cu_cp_ue_id; uint32_t gNB_cu_up_ue_id; - rnti_t rnti; uint64_t cipheringAlgorithm; uint64_t integrityProtectionAlgorithm; char encryptionKey[128]; @@ -216,8 +215,8 @@ typedef struct pdu_session_setup_s { } pdu_session_setup_t; typedef struct e1ap_bearer_setup_resp_s { - uint64_t gNB_cu_cp_ue_id; - uint64_t gNB_cu_up_ue_id; + uint32_t gNB_cu_cp_ue_id; + uint32_t gNB_cu_up_ue_id; int numDRBs; drb_setup_t DRBList[E1AP_MAX_NUM_DRBS]; int numPDUSessions; diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 08cc03c4fa..3d594a695e 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -286,8 +286,7 @@ typedef struct f1ap_dl_rrc_message_s { uint32_t gNB_CU_ue_id; uint32_t gNB_DU_ue_id; - uint32_t old_gNB_DU_ue_id; - uint16_t rnti; + uint32_t *old_gNB_DU_ue_id; uint8_t srb_id; uint8_t execute_duplication; uint8_t *rrc_container; @@ -318,7 +317,8 @@ typedef struct f1ap_initial_ul_rrc_message_s { } f1ap_initial_ul_rrc_message_t; typedef struct f1ap_ul_rrc_message_s { - uint16_t rnti; + uint32_t gNB_CU_ue_id; + uint32_t gNB_DU_ue_id; uint8_t srb_id; uint8_t *rrc_container; int rrc_container_length; @@ -378,9 +378,8 @@ typedef enum ReconfigurationCompl_e { } ReconfigurationCompl_t; typedef struct f1ap_ue_context_setup_s { - uint32_t gNB_CU_ue_id; // BK: need to replace by use from rnti + uint32_t gNB_CU_ue_id; uint32_t gNB_DU_ue_id; - uint16_t rnti; // SpCell Info uint16_t mcc; uint16_t mnc; @@ -419,7 +418,8 @@ typedef enum F1ap_Cause_e { } f1ap_Cause_t; typedef struct f1ap_ue_context_release_s { - uint16_t rnti; + uint32_t gNB_CU_ue_id; + uint32_t gNB_DU_ue_id; f1ap_Cause_t cause; long cause_value; uint8_t *rrc_container; diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 6c33ddf973..27eb9f5848 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -1095,7 +1095,7 @@ static int fill_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_setup_req_t *setupReq, ieC2->id = E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID; ieC2->criticality = E1AP_Criticality_reject; ieC2->value.present = E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_UP_UE_E1AP_ID; - ieC2->value.choice.GNB_CU_UP_UE_E1AP_ID = bearerCxt->gNB_cu_cp_ue_id; + ieC2->value.choice.GNB_CU_UP_UE_E1AP_ID = bearerCxt->gNB_cu_up_ue_id; /* optional */ /* */ asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationRequestIEs_t, ieC3); diff --git a/openair2/E1AP/e1ap_api.c b/openair2/E1AP/e1ap_api.c index cf167f64e8..9cec6b69f3 100644 --- a/openair2/E1AP/e1ap_api.c +++ b/openair2/E1AP/e1ap_api.c @@ -30,6 +30,7 @@ #include "openair2/RRC/LTE/MESSAGES/asn1_msg.h" #include "openair3/SECU/key_nas_deriver.h" #include "openair3/ocp-gtpu/gtp_itf.h" +#include "openair2/F1AP/f1ap_ids.h" #include "e1ap_asnc.h" #include "e1ap_common.h" #include "e1ap.h" @@ -109,7 +110,7 @@ static int drb_config_N3gtpu_create(e1ap_bearer_setup_req_t * const req, fill_DRB_configList_e1(&DRB_configList, pdu); } create_tunnel_req.num_tunnels = req->numPDUSessions; - create_tunnel_req.ue_id = (req->gNB_cu_cp_ue_id & 0xFFFF); + create_tunnel_req.ue_id = req->gNB_cu_cp_ue_id; // Create N3 tunnel int ret = gtpv1u_create_ngu_tunnel(instance, &create_tunnel_req, create_tunnel_resp, nr_pdcp_data_req_drb, sdap_data_req); @@ -136,6 +137,11 @@ void process_e1_bearer_context_setup_req(instance_t instance, e1ap_bearer_setup_ AssertFatal(inst, ""); gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp_N3={0}; + uint32_t gNB_cu_up_ue_id = req ->gNB_cu_cp_ue_id; + LOG_I(E1AP, "adding UE with CU-CP UE ID %d and CU-UP UE ID %d\n", req->gNB_cu_cp_ue_id, gNB_cu_up_ue_id); + f1_ue_data_t ue_data = {.secondary_ue = req->gNB_cu_cp_ue_id}; + cu_add_f1_ue_data(gNB_cu_up_ue_id, &ue_data); + // GTP tunnel for UL drb_config_N3gtpu_create(req, &create_tunnel_resp_N3, inst->gtpInstN3); @@ -148,6 +154,7 @@ void process_e1_bearer_context_setup_req(instance_t instance, e1ap_bearer_setup_ fill_e1ap_bearer_setup_resp(resp, req, inst->gtpInstF1U, req->gNB_cu_cp_ue_id, inst->setupReq.remotePortF1U, my_addr); resp->gNB_cu_cp_ue_id = req->gNB_cu_cp_ue_id; + resp->gNB_cu_up_ue_id = gNB_cu_up_ue_id; resp->numPDUSessions = req->numPDUSessions; for (int i=0; i < req->numPDUSessions; i++) { pdu_session_setup_t *pduSetup = resp->pduSession + i; diff --git a/openair2/F1AP/CMakeLists.txt b/openair2/F1AP/CMakeLists.txt index 7537bd661d..e6490b96b0 100644 --- a/openair2/F1AP/CMakeLists.txt +++ b/openair2/F1AP/CMakeLists.txt @@ -1 +1,8 @@ add_subdirectory(MESSAGES) + +if(ENABLE_TESTS) + add_executable(f1ap_ids_test f1ap_ids_test.c f1ap_ids.c) + target_link_libraries(f1ap_ids_test UTIL HASHTABLE minimal_lib) + add_dependencies(tests f1ap_ids_test) + add_test(NAME F1AP_ID_test COMMAND f1ap_ids_test) +endif() diff --git a/openair2/F1AP/f1ap_common.c b/openair2/F1AP/f1ap_common.c index f417a1c337..f396d570df 100644 --- a/openair2/F1AP/f1ap_common.c +++ b/openair2/F1AP/f1ap_common.c @@ -66,123 +66,6 @@ void createF1inst(F1_t isCU, instance_t instanceP, f1ap_setup_req_t *req) { } } -int f1ap_add_ue(F1_t isCu, - instance_t instanceP, - rnti_t rntiP) { - f1ap_cudu_inst_t *f1_inst=getCxt(isCu, instanceP); - - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - if (f1_inst->f1ap_ue[i].rnti == rntiP) { - f1_inst->f1ap_ue[i].f1ap_uid = i; - LOG_I(F1AP, "Updating the index of UE with RNTI %x and du_ue_f1ap_id %ld\n", f1_inst->f1ap_ue[i].rnti, f1_inst->f1ap_ue[i].du_ue_f1ap_id); - return i; - } - } - - // We didn't find the rnti - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - if (f1_inst->f1ap_ue[i].rnti == 0 ) { - f1_inst->f1ap_ue[i].rnti = rntiP; - f1_inst->f1ap_ue[i].f1ap_uid = i; - f1_inst->f1ap_ue[i].du_ue_f1ap_id = rntiP; - f1_inst->f1ap_ue[i].cu_ue_f1ap_id = rntiP; - f1_inst->num_ues++; - LOG_I(F1AP, "Adding a new UE with RNTI %x and cu/du ue_f1ap_id %ld\n", f1_inst->f1ap_ue[i].rnti, f1_inst->f1ap_ue[i].du_ue_f1ap_id); - return i; - } - } - - return -1; -} - - -int f1ap_remove_ue(F1_t isCu, instance_t instanceP, - rnti_t rntiP) { - f1ap_cudu_inst_t *f1_inst=getCxt(isCu, instanceP); - - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - if (f1_inst->f1ap_ue[i].rnti == rntiP) { - f1_inst->f1ap_ue[i].rnti = 0; - break; - } - } - - f1_inst->num_ues--; - return 0; -} - -int f1ap_get_du_ue_f1ap_id(F1_t isCu, instance_t instanceP, - rnti_t rntiP) { - f1ap_cudu_inst_t *f1_inst=getCxt(isCu, instanceP); - - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - if (f1_inst->f1ap_ue[i].rnti == rntiP) { - return f1_inst->f1ap_ue[i].du_ue_f1ap_id; - } - } - - return -1; -} - -int f1ap_get_cu_ue_f1ap_id(F1_t isCu, instance_t instanceP, - rnti_t rntiP) { - f1ap_cudu_inst_t *f1_inst=getCxt(isCu, instanceP); - - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - if (f1_inst->f1ap_ue[i].rnti == rntiP) { - return f1_inst->f1ap_ue[i].cu_ue_f1ap_id; - } - } - - return -1; -} - -int f1ap_get_rnti_by_du_id(F1_t isCu, instance_t instanceP, - instance_t du_ue_f1ap_id ) { - f1ap_cudu_inst_t *f1_inst=getCxt(isCu, instanceP); - - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - if (f1_inst->f1ap_ue[i].du_ue_f1ap_id == du_ue_f1ap_id) { - return f1_inst->f1ap_ue[i].rnti; - } - } - - return -1; -} - -int f1ap_get_rnti_by_cu_id(F1_t isCu, instance_t instanceP, - instance_t cu_ue_f1ap_id ) { - f1ap_cudu_inst_t *f1_inst=getCxt(isCu, instanceP); - - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - if (f1_inst->f1ap_ue[i].cu_ue_f1ap_id == cu_ue_f1ap_id) { - return f1_inst->f1ap_ue[i].rnti; - } - } - - return -1; -} - -int f1ap_du_add_cu_ue_id(instance_t instanceP, - instance_t du_ue_f1ap_id, - instance_t cu_ue_f1ap_id) { - f1ap_cudu_inst_t *f1_inst=getCxt(DUtype, instanceP); - instance_t f1ap_uid=-1; - - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - if (f1_inst->f1ap_ue[i].du_ue_f1ap_id == du_ue_f1ap_id) { - f1ap_uid=i; - break; - } - } - - if (f1ap_uid < 0 || f1ap_uid >= MAX_MOBILES_PER_GNB) - return -1; - - f1_inst->f1ap_ue[f1ap_uid].cu_ue_f1ap_id = cu_ue_f1ap_id; - LOG_D(F1AP, "Adding cu_ue_f1ap_id %ld for UE with RNTI %x\n", cu_ue_f1ap_id, f1_inst->f1ap_ue[f1ap_uid].rnti); - return 0; -} int f1ap_assoc_id(F1_t isCu, instance_t instanceP) { f1ap_setup_req_t *f1_inst=f1ap_req(isCu, instanceP); diff --git a/openair2/F1AP/f1ap_common.h b/openair2/F1AP/f1ap_common.h index ff492820d7..a346d9682a 100644 --- a/openair2/F1AP/f1ap_common.h +++ b/openair2/F1AP/f1ap_common.h @@ -427,30 +427,6 @@ uint8_t F1AP_get_next_transaction_identifier(instance_t mod_idP, instance_t cu_m f1ap_cudu_inst_t *getCxt(F1_t isCU, instance_t instanceP); void createF1inst(F1_t isCU, instance_t instanceP, f1ap_setup_req_t *req); -int f1ap_add_ue(F1_t isCu, - instance_t instanceP, - rnti_t rntiP); - -int f1ap_remove_ue(F1_t isCu, instance_t instanceP, - rnti_t rntiP); - -int f1ap_get_du_ue_f1ap_id (F1_t isCu, instance_t instanceP, - rnti_t rntiP); - -int f1ap_get_cu_ue_f1ap_id (F1_t isCu, instance_t instanceP, - rnti_t rntiP); - - -int f1ap_get_rnti_by_du_id(F1_t isCu, instance_t instanceP, - instance_t du_ue_f1ap_id ); - - -int f1ap_get_rnti_by_cu_id(F1_t isCu, instance_t instanceP, - instance_t cu_ue_f1ap_id ); - -int f1ap_du_add_cu_ue_id(instance_t instanceP, - instance_t du_ue_f1ap_id, - instance_t cu_ue_f1ap_id); int f1ap_assoc_id(F1_t isCu, instance_t instanceP); diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c index 5c3b100efd..13bc9954a3 100644 --- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c @@ -32,6 +32,7 @@ #include "f1ap_common.h" #include "f1ap_encoder.h" +#include "f1ap_ids.h" #include "f1ap_itti_messaging.h" #include "f1ap_cu_rrc_message_transfer.h" #include "common/ran_context.h" @@ -53,9 +54,6 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, MessageDef *message_p; F1AP_InitialULRRCMessageTransfer_t *container; F1AP_InitialULRRCMessageTransferIEs_t *ie; - rnti_t rnti; - sdu_size_t ccch_sdu_len; - int CC_id =0; DevAssert(pdu != NULL); if (stream != 0) { @@ -68,6 +66,8 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, /* GNB_DU_UE_F1AP_ID */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); + uint32_t du_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID; + /* NRCGI * Fixme: process NRCGI */ @@ -78,7 +78,7 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, /* RNTI */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_C_RNTI, true); - rnti = ie->value.choice.C_RNTI; + rnti_t rnti = ie->value.choice.C_RNTI; F1AP_InitialULRRCMessageTransferIEs_t *rrccont; F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, rrccont, container, F1AP_ProtocolIE_ID_id_RRCContainer, true); @@ -88,51 +88,22 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, du2cu, container, F1AP_ProtocolIE_ID_id_DUtoCURRCContainer, false); - int f1ap_uid = f1ap_add_ue(CUtype, instance, rnti); - - if (f1ap_uid < 0 ) { - LOG_E(F1AP, "Failed to add UE \n"); - return -1; - } - // create an ITTI message and copy SDU - if (f1ap_req(true, instance)->cell_type==CELL_MACRO_GNB) { - message_p = itti_alloc_new_message (TASK_CU_F1, 0, F1AP_INITIAL_UL_RRC_MESSAGE); - f1ap_initial_ul_rrc_message_t *ul_rrc = &F1AP_INITIAL_UL_RRC_MESSAGE(message_p); - ul_rrc->nr_cellid = nr_cellid; // CU instance - ul_rrc->crnti = rnti; - ul_rrc->rrc_container_length = rrccont->value.choice.RRCContainer.size; - ul_rrc->rrc_container = malloc(ul_rrc->rrc_container_length); - memcpy(ul_rrc->rrc_container, rrccont->value.choice.RRCContainer.buf, ul_rrc->rrc_container_length); - AssertFatal(du2cu != NULL, "no masterCellGroup in initial UL RRC message\n"); - ul_rrc->du2cu_rrc_container_length = du2cu->value.choice.DUtoCURRCContainer.size; - ul_rrc->du2cu_rrc_container = malloc(ul_rrc->du2cu_rrc_container_length); - memcpy(ul_rrc->du2cu_rrc_container, du2cu->value.choice.DUtoCURRCContainer.buf, ul_rrc->du2cu_rrc_container_length); - itti_send_msg_to_task(TASK_RRC_GNB, instance, message_p); - } else { - message_p = itti_alloc_new_message (TASK_CU_F1, 0, RRC_MAC_CCCH_DATA_IND); - memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); - ccch_sdu_len = rrccont->value.choice.RRCContainer.size; - memcpy(RRC_MAC_CCCH_DATA_IND (message_p).sdu, rrccont->value.choice.RRCContainer.buf, - ccch_sdu_len); - NR_RRC_MAC_CCCH_DATA_IND (message_p).frame = 0; - NR_RRC_MAC_CCCH_DATA_IND (message_p).slot = 0; - NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = ccch_sdu_len; - NR_RRC_MAC_CCCH_DATA_IND (message_p).nr_cellid = nr_cellid; // CU instance - NR_RRC_MAC_CCCH_DATA_IND (message_p).rnti = rnti; - NR_RRC_MAC_CCCH_DATA_IND (message_p).CC_id = CC_id; - if (du2cu) { - NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container = malloc(sizeof(OCTET_STRING_t)); - NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->size = du2cu->value.choice.DUtoCURRCContainer.size; - NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->buf = malloc(du2cu->value.choice.DUtoCURRCContainer.size); - memcpy(NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->buf, - du2cu->value.choice.DUtoCURRCContainer.buf, - du2cu->value.choice.DUtoCURRCContainer.size); - } - itti_send_msg_to_task (TASK_RRC_ENB, instance, message_p); - } + AssertFatal(f1ap_req(true, instance)->cell_type == CELL_MACRO_GNB, "illegal cell type %d\n", f1ap_req(true, instance)->cell_type); + message_p = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_INITIAL_UL_RRC_MESSAGE); + f1ap_initial_ul_rrc_message_t *ul_rrc = &F1AP_INITIAL_UL_RRC_MESSAGE(message_p); + ul_rrc->gNB_DU_ue_id = du_ue_id; + ul_rrc->nr_cellid = nr_cellid; // CU instance + ul_rrc->crnti = rnti; + ul_rrc->rrc_container_length = rrccont->value.choice.RRCContainer.size; + ul_rrc->rrc_container = malloc(ul_rrc->rrc_container_length); + memcpy(ul_rrc->rrc_container, rrccont->value.choice.RRCContainer.buf, ul_rrc->rrc_container_length); + AssertFatal(du2cu != NULL, "no masterCellGroup in initial UL RRC message\n"); + ul_rrc->du2cu_rrc_container_length = du2cu->value.choice.DUtoCURRCContainer.size; + ul_rrc->du2cu_rrc_container = malloc(ul_rrc->du2cu_rrc_container_length); + memcpy(ul_rrc->du2cu_rrc_container, du2cu->value.choice.DUtoCURRCContainer.buf, ul_rrc->du2cu_rrc_container_length); + itti_send_msg_to_task(TASK_RRC_GNB, instance, message_p); - //getCxt(true,ITTI_MSG_DESTINATION_ID(message_p))->f1ap_ue[f1ap_uid].du_ue_f1ap_id = du_ue_f1ap_id; return 0; } @@ -161,26 +132,28 @@ int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t instance, ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; ie1->criticality = F1AP_Criticality_reject; ie1->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(CUtype, instance, f1ap_dl_rrc->rnti); - LOG_D(F1AP, "Setting GNB_CU_UE_F1AP_ID %llu associated with UE RNTI %x (instance %ld)\n", - (unsigned long long int)ie1->value.choice.GNB_CU_UE_F1AP_ID, f1ap_dl_rrc->rnti, instance); + DevAssert(f1ap_dl_rrc->gNB_CU_ue_id != 0); + ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_dl_rrc->gNB_CU_ue_id; + /* mandatory */ /* c2. GNB_DU_UE_F1AP_ID */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie2); ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(CUtype, instance, f1ap_dl_rrc->rnti); - LOG_D(F1AP, "GNB_DU_UE_F1AP_ID %llu associated with UE RNTI %x \n", (unsigned long long int)ie2->value.choice.GNB_DU_UE_F1AP_ID, f1ap_dl_rrc->rnti); + DevAssert(f1ap_dl_rrc->gNB_DU_ue_id != 0); + ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_dl_rrc->gNB_DU_ue_id; + /* optional */ /* c3. oldgNB_DU_UE_F1AP_ID */ - /* if (f1ap_dl_rrc->old_gNB_DU_ue_id != 0xFFFFFFFF) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie3); - ie3->id = F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID; - ie3->criticality = F1AP_Criticality_reject; - ie3->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_NOTHING; - ie3->value.choice.oldgNB_DU_UE_F1AP_ID = f1ap_dl_rrc->old_gNB_DU_ue_id; - }*/ + if (f1ap_dl_rrc->old_gNB_DU_ue_id != NULL) { + asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie3); + ie3->id = F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID; + ie3->criticality = F1AP_Criticality_reject; + ie3->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID_1; + ie3->value.choice.GNB_DU_UE_F1AP_ID_1 = *f1ap_dl_rrc->old_gNB_DU_ue_id; + } + /* mandatory */ /* c4. SRBID */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie4); @@ -267,14 +240,19 @@ int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t instance, F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); cu_ue_f1ap_id = ie->value.choice.GNB_CU_UE_F1AP_ID; - LOG_D(F1AP, "cu_ue_f1ap_id %lu associated with RNTI %x\n", - cu_ue_f1ap_id, f1ap_get_rnti_by_cu_id(CUtype, instance, cu_ue_f1ap_id)); /* GNB_DU_UE_F1AP_ID */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID; - LOG_D(F1AP, "du_ue_f1ap_id %lu associated with RNTI %x\n", - du_ue_f1ap_id, f1ap_get_rnti_by_cu_id(CUtype, instance, du_ue_f1ap_id)); + /* the RLC-PDCP does not transport the DU UE ID (yet), so we drop it here. + * For the moment, let's hope this won't become relevant; to sleep in peace, + * let's put an assert to check that it is the expected DU UE ID. */ + f1_ue_data_t ue_data = cu_get_f1_ue_data(cu_ue_f1ap_id); + AssertFatal(ue_data.secondary_ue == du_ue_f1ap_id, + "unexpected DU UE ID %d received, expected it to be %ld\n", + ue_data.secondary_ue, + du_ue_f1ap_id); + /* mandatory */ /* SRBID */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container, @@ -294,7 +272,7 @@ int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t instance, protocol_ctxt_t ctxt={0}; ctxt.instance = instance; ctxt.module_id = instance; - ctxt.rntiMaybeUEid = f1ap_get_rnti_by_cu_id(CUtype, instance, cu_ue_f1ap_id); + ctxt.rntiMaybeUEid = cu_ue_f1ap_id; ctxt.enb_flag = 1; ctxt.eNB_index = 0; mem_block_t *mb = get_free_mem_block(ie->value.choice.RRCContainer.size,__func__); diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index 8fdee52abb..a72a359c5b 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -82,7 +82,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; ie1->criticality = F1AP_Criticality_reject; ie1->value.present = F1AP_UEContextSetupRequestIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(CUtype, instance, f1ap_ue_context_setup_req->rnti); //f1ap_ue_context_setup_req->gNB_CU_ue_id; + ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_ue_context_setup_req->gNB_CU_ue_id; /* optional */ /* c2. GNB_DU_UE_F1AP_ID */ @@ -91,7 +91,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_ignore; ie2->value.present = F1AP_UEContextSetupRequestIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(CUtype, instance, f1ap_ue_context_setup_req->rnti); //*f1ap_ue_context_setup_req->gNB_DU_ue_id; + ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_ue_context_setup_req->gNB_DU_ue_id; } /* mandatory */ @@ -510,7 +510,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, /* Use a dummy address and teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU */ transport_layer_addr_t addr = { .length= 32, .buffer= { 0 } }; f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(CUtype, instance)->gtpInst, - f1ap_ue_context_setup_req->rnti, + f1ap_ue_context_setup_req->gNB_CU_ue_id, f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id, f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id, 0xFFFF, // We will set the right value from DU answer @@ -654,8 +654,6 @@ int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); f1ap_ue_context_setup_resp->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID; LOG_D(F1AP, "f1ap_ue_context_setup_resp->gNB_DU_ue_id is: %d \n", f1ap_ue_context_setup_resp->gNB_DU_ue_id); - f1ap_ue_context_setup_resp->rnti = - f1ap_get_rnti_by_du_id(CUtype, instance, f1ap_ue_context_setup_resp->gNB_DU_ue_id); // DUtoCURRCInformation F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupResponseIEs_t, ie, container, F1AP_ProtocolIE_ID_id_DUtoCURRCInformation, true); @@ -695,7 +693,7 @@ int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address); OCTET_STRING_TO_UINT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid); GtpuUpdateTunnelOutgoingAddressAndTeid(getCxt(CUtype, instance)->gtpInst, - f1ap_ue_context_setup_resp->rnti, + f1ap_ue_context_setup_resp->gNB_DU_ue_id, (ebi_t)drbs_setup_item_p->dRBID, drb_p->up_dl_tnl[0].tl_address, drb_p->up_dl_tnl[0].teid); @@ -786,17 +784,12 @@ int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, uint32_t assoc_id, /* GNB_CU_UE_F1AP_ID */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); - const rnti_t rnti = f1ap_get_rnti_by_cu_id(true, instance, - ie->value.choice.GNB_CU_UE_F1AP_ID); - req->rnti = rnti; + req->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID; /* GNB_DU_UE_F1AP_ID */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); - const rnti_t rnti2 = f1ap_get_rnti_by_du_id(CUtype, instance, - ie->value.choice.GNB_DU_UE_F1AP_ID); - AssertFatal(rnti == rnti2, "RNTI obtained through DU ID (%x) is different from CU ID (%x)\n", - rnti2, rnti); + req->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID; /* Cause */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container, @@ -857,14 +850,14 @@ int CU_send_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; ie1->criticality = F1AP_Criticality_reject; ie1->value.present = F1AP_UEContextReleaseCommandIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(CUtype, instance, cmd->rnti); + ie1->value.choice.GNB_CU_UE_F1AP_ID = cmd->gNB_CU_ue_id; /* mandatory */ /* c2. GNB_DU_UE_F1AP_ID */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseCommandIEs_t, ie2); ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_UEContextReleaseCommandIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(CUtype, instance, cmd->rnti); + ie2->value.choice.GNB_DU_UE_F1AP_ID = cmd->gNB_DU_ue_id; /* mandatory */ /* c3. Cause */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseCommandIEs_t, ie3); @@ -933,19 +926,18 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, F1AP_UEContextReleaseComplete_t *container; F1AP_UEContextReleaseCompleteIEs_t *ie; DevAssert(pdu); + MessageDef *msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_RELEASE_COMPLETE); + f1ap_ue_context_release_complete_t *complete = &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_p); container = &pdu->choice.successfulOutcome->value.choice.UEContextReleaseComplete; /* GNB_CU_UE_F1AP_ID */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCompleteIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); - const rnti_t rnti = f1ap_get_rnti_by_cu_id(CUtype, instance, - ie->value.choice.GNB_CU_UE_F1AP_ID); + complete->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID; /* GNB_DU_UE_F1AP_ID */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCompleteIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); - const rnti_t rnti2 = f1ap_get_rnti_by_du_id(CUtype, instance, - ie->value.choice.GNB_DU_UE_F1AP_ID); - AssertFatal(rnti == rnti2, "RNTI obtained through DU ID (%x) is different from CU ID (%x)\n", - rnti2, rnti); + complete->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID; + /* Optional*/ /* CriticalityDiagnostics */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCompleteIEs_t, ie, container, @@ -959,24 +951,8 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, // F1AP_CriticalityDiagnostics_IE_List } - protocol_ctxt_t ctxt; - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, instance, GNB_FLAG_YES, rnti, 0, 0, instance); + itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p); - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[instance], rnti); - - if (ue_context_p) { - MessageDef *msg = itti_alloc_new_message(TASK_CU_F1, 0, NGAP_UE_CONTEXT_RELEASE_COMPLETE); - NGAP_UE_CONTEXT_RELEASE_COMPLETE(msg).gNB_ue_ngap_id = ue_context_p->ue_context.gNB_ue_ngap_id; - itti_send_msg_to_task(TASK_NGAP, instance, msg); - rrc_gNB_remove_ue_context(RC.nrrrc[instance], ue_context_p); - } else { - LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti); - } - - nr_pdcp_remove_UE(ctxt.rntiMaybeUEid); - - LOG_I(F1AP, "Received UE CONTEXT RELEASE COMPLETE: Removing CU UE entry for RNTI %x\n", rnti); - f1ap_remove_ue(CUtype, instance, rnti); return 0; } @@ -1002,14 +978,14 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; ie1->criticality = F1AP_Criticality_reject; ie1->value.present = F1AP_UEContextModificationRequestIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(CUtype, instance, f1ap_ue_context_modification_req->rnti);; + ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_ue_context_modification_req->gNB_CU_ue_id; /* mandatory */ /* c2. GNB_DU_UE_F1AP_ID */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie2); ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_UEContextModificationRequestIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(CUtype, instance, f1ap_ue_context_modification_req->rnti);; + ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_ue_context_modification_req->gNB_DU_ue_id; /* optional */ /* c3. NRCGI */ @@ -1618,9 +1594,6 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, LOG_D(F1AP, "f1ap_ue_context_modification_resp->gNB_DU_ue_id is: %d \n", f1ap_ue_context_modification_resp->gNB_DU_ue_id); - f1ap_ue_context_modification_resp->rnti = - f1ap_get_rnti_by_du_id(CUtype, instance, f1ap_ue_context_modification_resp->gNB_DU_ue_id); - // DUtoCURRCInformation F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container, F1AP_ProtocolIE_ID_id_DUtoCURRCInformation, false); @@ -1656,7 +1629,7 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address); OCTET_STRING_TO_UINT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid); GtpuUpdateTunnelOutgoingAddressAndTeid(getCxt(CUtype, instance)->gtpInst, - f1ap_ue_context_modification_resp->rnti, + f1ap_ue_context_modification_resp->gNB_CU_ue_id, (ebi_t)drbs_setupmod_item_p->dRBID, drb_p->up_dl_tnl[0].tl_address, drb_p->up_dl_tnl[0].teid); diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 5fc8daef3f..bcb38029cd 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -50,6 +50,7 @@ #include "asn1_msg.h" #include "intertask_interface.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h" +#include #include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h" @@ -60,8 +61,6 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, F1AP_F1AP_PDU_t *pdu) { F1AP_DLRRCMessageTransfer_t *container; F1AP_DLRRCMessageTransferIEs_t *ie; - uint64_t cu_ue_f1ap_id; - uint64_t du_ue_f1ap_id; int executeDuplication; //uint64_t subscriberProfileIDforRFP; //uint64_t rAT_FrequencySelectionPriority; @@ -70,26 +69,23 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, /* GNB_CU_UE_F1AP_ID */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); - cu_ue_f1ap_id = ie->value.choice.GNB_CU_UE_F1AP_ID; - LOG_D(F1AP, "cu_ue_f1ap_id %lu \n", cu_ue_f1ap_id); + uint32_t cu_ue_f1ap_id = ie->value.choice.GNB_CU_UE_F1AP_ID; /* GNB_DU_UE_F1AP_ID */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); - du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID; - LOG_D(F1AP, "du_ue_f1ap_id %lu associated with UE RNTI %x \n", - du_ue_f1ap_id, - f1ap_get_rnti_by_du_id(DUtype, instance, du_ue_f1ap_id)); // this should be the one transmitted via initial ul rrc message transfer - - if (f1ap_du_add_cu_ue_id(instance,du_ue_f1ap_id, cu_ue_f1ap_id) < 0 ) { - LOG_E(F1AP, "Failed to find the F1AP UID \n"); - //return -1; - } + uint32_t du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID; /* optional */ /* oldgNB_DU_UE_F1AP_ID */ - if (0) { - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container, - F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID, true); + uint32_t *old_gNB_DU_ue_id = NULL; + uint32_t old_gNB_DU_ue_id_stack = 0; + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID, false); + if (ie) { + /* strange: it is not named OLD_GNB_DU_UE... */ + old_gNB_DU_ue_id_stack = ie->value.choice.GNB_DU_UE_F1AP_ID_1; + old_gNB_DU_ue_id = &old_gNB_DU_ue_id_stack; + gtpv1u_update_ue_id(getCxt(false, instance)->gtpInst, old_gNB_DU_ue_id_stack, du_ue_f1ap_id); } /* mandatory */ @@ -135,34 +131,24 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, } f1ap_dl_rrc_message_t dl_rrc = { + .gNB_CU_ue_id = cu_ue_f1ap_id, + .gNB_DU_ue_id = du_ue_f1ap_id, + .old_gNB_DU_ue_id = old_gNB_DU_ue_id, .rrc_container_length = ie->value.choice.RRCContainer.size, .rrc_container = ie->value.choice.RRCContainer.buf, - .rnti = f1ap_get_rnti_by_du_id(DUtype, instance, du_ue_f1ap_id), .srb_id = srb_id }; - dl_rrc_message(instance, &dl_rrc); + dl_rrc_message_transfer(&dl_rrc); return 0; } /* UL RRC Message Transfer */ -int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, - int CC_idP, - int UE_id, - rnti_t rntiP, - const uint8_t *sduP, - sdu_size_t sdu_lenP, - const uint8_t *sdu2P, - sdu_size_t sdu2_lenP) { +int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, const f1ap_initial_ul_rrc_message_t *msg) +{ F1AP_F1AP_PDU_t pdu= {0}; F1AP_InitialULRRCMessageTransfer_t *out; uint8_t *buffer=NULL; uint32_t len=0; - int f1ap_uid = f1ap_add_ue (DUtype, instanceP, rntiP); - - if (f1ap_uid < 0 ) { - LOG_E(F1AP, "Failed to add UE \n"); - return -1; - } /* Create */ /* 0. Message Type */ @@ -178,7 +164,7 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, ie1->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie1->criticality = F1AP_Criticality_reject; ie1->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie1->value.choice.GNB_DU_UE_F1AP_ID = getCxt(DUtype, instanceP)->f1ap_ue[f1ap_uid].du_ue_f1ap_id; + ie1->value.choice.GNB_DU_UE_F1AP_ID = msg->gNB_DU_ue_id; /* mandatory */ /* c2. NRCGI */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie2); @@ -193,25 +179,25 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, ie3->id = F1AP_ProtocolIE_ID_id_C_RNTI; ie3->criticality = F1AP_Criticality_reject; ie3->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_C_RNTI; - ie3->value.choice.C_RNTI=rntiP; + ie3->value.choice.C_RNTI = msg->crnti; /* mandatory */ /* c4. RRCContainer */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie4); ie4->id = F1AP_ProtocolIE_ID_id_RRCContainer; ie4->criticality = F1AP_Criticality_reject; ie4->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_RRCContainer; - OCTET_STRING_fromBuf(&ie4->value.choice.RRCContainer, (const char *)sduP, sdu_lenP); + OCTET_STRING_fromBuf(&ie4->value.choice.RRCContainer, (const char *)msg->rrc_container, msg->rrc_container_length); /* optional */ /* c5. DUtoCURRCContainer */ - if (sdu2P) { + if (msg->du2cu_rrc_container != NULL) { asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie5); ie5->id = F1AP_ProtocolIE_ID_id_DUtoCURRCContainer; ie5->criticality = F1AP_Criticality_reject; ie5->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_DUtoCURRCContainer; OCTET_STRING_fromBuf(&ie5->value.choice.DUtoCURRCContainer, - (const char *)sdu2P, - sdu2_lenP); + (const char *)msg->du2cu_rrc_container, + msg->du2cu_rrc_container_length); } /* mandatory */ /* c6. Transaction ID (integer value) */ @@ -231,16 +217,19 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, return 0; } - -int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, - const f1ap_ul_rrc_message_t *msg) { - const rnti_t rnti = msg->rnti; +int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_message_t *msg) +{ F1AP_F1AP_PDU_t pdu= {0}; F1AP_ULRRCMessageTransfer_t *out; uint8_t *buffer = NULL; uint32_t len; - LOG_D(F1AP, "[DU %ld] %s: size %d UE RNTI %x in SRB %d\n", - instance, __func__, msg->rrc_container_length, rnti, msg->srb_id); + LOG_D(F1AP, + "[DU %ld] %s: size %d UE RNTI %x in SRB %d\n", + instance, + __func__, + msg->rrc_container_length, + msg->gNB_DU_ue_id, + msg->srb_id); //for (int i = 0;i < msg->rrc_container_length; i++) // printf("%02x ", msg->rrc_container[i]); //printf("\n"); @@ -258,14 +247,14 @@ int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; ie1->criticality = F1AP_Criticality_reject; ie1->value.present = F1AP_ULRRCMessageTransferIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(DUtype, instance, rnti); + ie1->value.choice.GNB_CU_UE_F1AP_ID = msg->gNB_CU_ue_id; /* mandatory */ /* c2. GNB_DU_UE_F1AP_ID */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_ULRRCMessageTransferIEs_t, ie2); ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_ULRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, rnti); + ie2->value.choice.GNB_DU_UE_F1AP_ID = msg->gNB_DU_ue_id; /* mandatory */ /* c3. SRBID */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_ULRRCMessageTransferIEs_t, ie3); diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.h b/openair2/F1AP/f1ap_du_rrc_message_transfer.h index 7a0c1f8974..f784b7a0cf 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.h +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.h @@ -43,13 +43,6 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_message_t *msg); -int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, - int CC_idP, - int UE_id, - rnti_t rntiP, - const uint8_t *sduP, - sdu_size_t sdu_lenP, - const uint8_t *sdu2P, - sdu_size_t sdu2_lenP); +int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, const f1ap_initial_ul_rrc_message_t *msg); #endif /* F1AP_DU_RRC_MESSAGE_TRANSFER_H_ */ diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index 098f957194..a7af049c2a 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -145,7 +145,7 @@ void *F1AP_DU_task(void *arg) { case F1AP_INITIAL_UL_RRC_MESSAGE: // from rrc { f1ap_initial_ul_rrc_message_t *msgRrc = &F1AP_INITIAL_UL_RRC_MESSAGE(msg); - DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(0, 0, 0, msgRrc->crnti, msgRrc->rrc_container, msgRrc->rrc_container_length, msgRrc->du2cu_rrc_container, msgRrc->du2cu_rrc_container_length); + DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(myInstance, msgRrc); } break; case F1AP_UL_RRC_MESSAGE: // to rrc diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index 05833e3fad..2430b2f870 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -77,21 +77,8 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, /* GNB_DU_UE_F1AP_ID */ F1AP_UEContextSetupRequestIEs_t *ieDU_UE; F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ieDU_UE, container, - F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, false); - - if (ieDU_UE) { - f1ap_ue_context_setup_req->gNB_DU_ue_id = - ieDU_UE->value.choice.GNB_DU_UE_F1AP_ID; - f1ap_ue_context_setup_req->rnti = - f1ap_get_rnti_by_du_id(DUtype, instance, f1ap_ue_context_setup_req->gNB_DU_ue_id); - } else { - f1ap_ue_context_setup_req->gNB_DU_ue_id = -1; - f1ap_ue_context_setup_req->rnti = - f1ap_get_rnti_by_cu_id(DUtype, instance, f1ap_ue_context_setup_req->gNB_CU_ue_id); - } - - if(f1ap_ue_context_setup_req->rnti<0) - LOG_E(F1AP, "Could not retrieve UE rnti based on the CU/DU UE id \n"); + F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); + f1ap_ue_context_setup_req->gNB_DU_ue_id = ieDU_UE->value.choice.GNB_DU_UE_F1AP_ID; /* SpCell_ID */ F1AP_UEContextSetupRequestIEs_t *ieNet; @@ -247,7 +234,7 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_UEContextSetupResponseIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, resp->rnti); + ie2->value.choice.GNB_DU_UE_F1AP_ID = resp->gNB_DU_ue_id; /* mandatory */ /* c3. DUtoCURRCInformation */ @@ -285,7 +272,8 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup ie4->criticality = F1AP_Criticality_ignore; ie4->value.present = F1AP_UEContextSetupResponseIEs__value_PR_C_RNTI; //C_RNTI_TO_BIT_STRING(rntiP, &ie->value.choice.C_RNTI); - ie4->value.choice.C_RNTI=resp->rnti; + ie4->value.choice.C_RNTI=0; + AssertFatal(false, "not implemented\n"); LOG_E(F1AP,"RNTI to code!\n"); } @@ -586,14 +574,14 @@ int DU_send_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; ie1->criticality = F1AP_Criticality_reject; ie1->value.present = F1AP_UEContextReleaseRequestIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(DUtype, instance, req->rnti); + ie1->value.choice.GNB_CU_UE_F1AP_ID = req->gNB_CU_ue_id; /* mandatory */ /* c2. GNB_DU_UE_F1AP_ID */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseRequestIEs_t, ie2); ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_UEContextReleaseRequestIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, req->rnti); + ie2->value.choice.GNB_DU_UE_F1AP_ID = req->gNB_DU_ue_id; /* mandatory */ /* c3. Cause */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseRequestIEs_t, ie3); @@ -654,13 +642,11 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, uint32_t assoc_id, // GNB_CU_UE_F1AP_ID F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); - f1ap_ue_context_release_cmd->rnti = f1ap_get_rnti_by_cu_id(DUtype, instance, ie->value.choice.GNB_CU_UE_F1AP_ID); + f1ap_ue_context_release_cmd->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID; // GNB_DU_UE_F1AP_ID F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); - const rnti_t rnti = f1ap_get_rnti_by_du_id(DUtype, instance, - ie->value.choice.GNB_DU_UE_F1AP_ID); - AssertFatal(f1ap_ue_context_release_cmd->rnti == rnti, "RNTI obtained through DU ID (%x) is different from CU ID (%x)\n", rnti, f1ap_ue_context_release_cmd->rnti); + f1ap_ue_context_release_cmd->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID; // We don't need the Cause // Optional RRC Container: if present, send to UE @@ -721,14 +707,14 @@ int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_ue_context_rel ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; ie1->criticality = F1AP_Criticality_reject; ie1->value.present = F1AP_UEContextReleaseCompleteIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(DUtype, instance, complete->rnti); + ie1->value.choice.GNB_CU_UE_F1AP_ID = complete->gNB_CU_ue_id; /* mandatory */ /* c2. GNB_DU_UE_F1AP_ID */ asn1cSequenceAdd(out->protocolIEs.list,F1AP_UEContextReleaseCompleteIEs_t, ie2); ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_UEContextReleaseCompleteIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, complete->rnti); + ie2->value.choice.GNB_DU_UE_F1AP_ID = complete->gNB_DU_ue_id; /* optional -> currently not used */ /* c3. CriticalityDiagnostics */ //if (0) { @@ -790,7 +776,6 @@ int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_ue_context_rel buffer, len, getCxt(false, instance)->default_sctp_stream_id); - f1ap_remove_ue(DUtype, instance, complete->rnti); return 0; } @@ -825,12 +810,6 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, uint32_t asso F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieDU_UE, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); f1ap_ue_context_modification_req->gNB_DU_ue_id = ieDU_UE->value.choice.GNB_DU_UE_F1AP_ID; - f1ap_ue_context_modification_req->rnti = f1ap_get_rnti_by_du_id(DUtype, instance, f1ap_ue_context_modification_req->gNB_DU_ue_id); - - if(f1ap_ue_context_modification_req->rnti<0) - LOG_E(F1AP, "Could not retrieve UE rnti based on the DU UE id \n"); - else - LOG_D(F1AP, "Retrieved rnti is: %d \n", f1ap_ue_context_modification_req->rnti); /* SRB */ F1AP_UEContextModificationRequestIEs_t *ieSrb; @@ -944,7 +923,7 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, uint32_t asso ieRRC->value.choice.RRCContainer.buf, ieRRC->value.choice.RRCContainer.size); protocol_ctxt_t ctxt; // decode RRC Container and act on the message type - ctxt.rntiMaybeUEid = f1ap_ue_context_modification_req->rnti; + ctxt.rntiMaybeUEid = f1ap_ue_context_modification_req->gNB_DU_ue_id; ctxt.instance = instance; ctxt.module_id = instance; ctxt.enb_flag = 1; @@ -991,7 +970,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_UEContextModificationResponseIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, resp->rnti); + ie2->value.choice.GNB_DU_UE_F1AP_ID = resp->gNB_DU_ue_id; /* optional */ /* c3. ResourceCoordinationTransferContainer */ @@ -1057,7 +1036,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex memcpy(tl_addr.buffer, &drb->up_ul_tnl[0].tl_address, sizeof(drb->up_ul_tnl[0].tl_address)); tl_addr.length = sizeof(drb->up_ul_tnl[0].tl_address) * 8; drb->up_dl_tnl[j].teid = newGtpuCreateTunnel(getCxt(false, instance)->gtpInst, - resp->rnti, + resp->gNB_DU_ue_id, drb->drb_id, drb->drb_id, drb->up_ul_tnl[j].teid, diff --git a/openair2/F1AP/f1ap_ids.c b/openair2/F1AP/f1ap_ids.c new file mode 100644 index 0000000000..e467e074fd --- /dev/null +++ b/openair2/F1AP/f1ap_ids.c @@ -0,0 +1,157 @@ +/* + * 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 + */ + +/* "standalone" module to store a "secondary" UE ID for each UE in DU/CU. + * Separate from the rest of F1, as it is also relevant for monolithic. */ + +#include "f1ap_ids.h" + +#include +#include "common/utils/hashtable/hashtable.h" +#include "common/utils/assertions.h" + + +/* we have separate versions for CU and DU, as both CU&DU might coexist in the + * same process */ +static hash_table_t *cu2du_ue_mapping; +static pthread_mutex_t cu2du_mutex = PTHREAD_MUTEX_INITIALIZER; + +void cu_init_f1_ue_data(void) +{ + pthread_mutex_lock(&cu2du_mutex); + DevAssert(cu2du_ue_mapping == NULL); + cu2du_ue_mapping = hashtable_create(1319, NULL, free); // 1319 is prime, default hash func (unit), free() + DevAssert(cu2du_ue_mapping != NULL); + pthread_mutex_unlock(&cu2du_mutex); +} + +bool cu_add_f1_ue_data(uint32_t ue_id, const f1_ue_data_t *data) +{ + pthread_mutex_lock(&cu2du_mutex); + DevAssert(cu2du_ue_mapping != NULL); + uint64_t key = ue_id; + if (hashtable_is_key_exists(cu2du_ue_mapping, key) == HASH_TABLE_OK) { + pthread_mutex_unlock(&cu2du_mutex); + return false; + } + f1_ue_data_t *idata = malloc(sizeof(*idata)); + AssertFatal(idata != NULL, "cannot allocate memory\n"); + *idata = *data; + hashtable_rc_t ret = hashtable_insert(cu2du_ue_mapping, key, idata); + pthread_mutex_unlock(&cu2du_mutex); + return ret == HASH_TABLE_OK; +} + +bool cu_exists_f1_ue_data(uint32_t ue_id) +{ + pthread_mutex_lock(&cu2du_mutex); + DevAssert(cu2du_ue_mapping != NULL); + uint64_t key = ue_id; + hashtable_rc_t ret = hashtable_is_key_exists(cu2du_ue_mapping, key); + pthread_mutex_unlock(&cu2du_mutex); + return ret == HASH_TABLE_OK; +} + +f1_ue_data_t cu_get_f1_ue_data(uint32_t ue_id) +{ + pthread_mutex_lock(&cu2du_mutex); + DevAssert(cu2du_ue_mapping != NULL); + uint64_t key = ue_id; + void *data = NULL; + hashtable_rc_t ret = hashtable_get(cu2du_ue_mapping, key, &data); + AssertFatal(ret == HASH_TABLE_OK && data != NULL, "element for ue_id %d not found\n", ue_id); + f1_ue_data_t ued = *(f1_ue_data_t *)data; + pthread_mutex_unlock(&cu2du_mutex); + return ued; +} + +bool cu_remove_f1_ue_data(uint32_t ue_id) +{ + pthread_mutex_lock(&cu2du_mutex); + DevAssert(cu2du_ue_mapping != NULL); + uint64_t key = ue_id; + hashtable_rc_t ret = hashtable_remove(cu2du_ue_mapping, key); + pthread_mutex_unlock(&cu2du_mutex); + return ret == HASH_TABLE_OK; +} + +/* DU version below */ +static hash_table_t *du2cu_ue_mapping; +static pthread_mutex_t du2cu_mutex = PTHREAD_MUTEX_INITIALIZER; + +void du_init_f1_ue_data(void) +{ + pthread_mutex_lock(&du2cu_mutex); + DevAssert(du2cu_ue_mapping == NULL); + du2cu_ue_mapping = hashtable_create(1319, NULL, free); // 1319 is prime, default hash func (unit), free() + DevAssert(du2cu_ue_mapping != NULL); + pthread_mutex_unlock(&du2cu_mutex); +} + +bool du_add_f1_ue_data(uint32_t ue_id, const f1_ue_data_t *data) +{ + pthread_mutex_lock(&du2cu_mutex); + DevAssert(du2cu_ue_mapping != NULL); + uint64_t key = ue_id; + if (hashtable_is_key_exists(du2cu_ue_mapping, key) == HASH_TABLE_OK) { + pthread_mutex_unlock(&du2cu_mutex); + return false; + } + f1_ue_data_t *idata = malloc(sizeof(*idata)); + AssertFatal(idata != NULL, "cannot allocate memory\n"); + *idata = *data; + hashtable_rc_t ret = hashtable_insert(du2cu_ue_mapping, key, idata); + pthread_mutex_unlock(&du2cu_mutex); + return ret == HASH_TABLE_OK; +} + +bool du_exists_f1_ue_data(uint32_t ue_id) +{ + pthread_mutex_lock(&du2cu_mutex); + DevAssert(du2cu_ue_mapping != NULL); + uint64_t key = ue_id; + hashtable_rc_t ret = hashtable_is_key_exists(du2cu_ue_mapping, key); + pthread_mutex_unlock(&du2cu_mutex); + return ret == HASH_TABLE_OK; +} + +f1_ue_data_t du_get_f1_ue_data(uint32_t ue_id) +{ + pthread_mutex_lock(&du2cu_mutex); + DevAssert(du2cu_ue_mapping != NULL); + uint64_t key = ue_id; + void *data = NULL; + hashtable_rc_t ret = hashtable_get(du2cu_ue_mapping, key, &data); + AssertFatal(ret == HASH_TABLE_OK && data != NULL, "element for ue_id %d not found\n", ue_id); + f1_ue_data_t ued = *(f1_ue_data_t *)data; + pthread_mutex_unlock(&du2cu_mutex); + return ued; +} + +bool du_remove_f1_ue_data(uint32_t ue_id) +{ + pthread_mutex_lock(&du2cu_mutex); + DevAssert(du2cu_ue_mapping != NULL); + uint64_t key = ue_id; + hashtable_rc_t ret = hashtable_remove(du2cu_ue_mapping, key); + pthread_mutex_unlock(&du2cu_mutex); + return ret == HASH_TABLE_OK; +} diff --git a/openair2/F1AP/f1ap_ids.h b/openair2/F1AP/f1ap_ids.h new file mode 100644 index 0000000000..96b146f6ba --- /dev/null +++ b/openair2/F1AP/f1ap_ids.h @@ -0,0 +1,48 @@ +/* + * 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 + */ + +/* "standalone" module to store a "secondary" UE ID for each UE in DU/CU. + * Separate from the rest of F1, as it is also relevant for monolithic. */ + +#ifndef F1AP_IDS_H_ +#define F1AP_IDS_H_ + +#include +#include + +typedef struct f1_ue_data_t { + uint32_t secondary_ue; + /* can be extended with F1-specific data also relevant for monolithic */ +} f1_ue_data_t; + +void cu_init_f1_ue_data(void); +bool cu_add_f1_ue_data(uint32_t ue_id, const f1_ue_data_t *data); +bool cu_exists_f1_ue_data(uint32_t ue_id); +f1_ue_data_t cu_get_f1_ue_data(uint32_t ue_id); +bool cu_remove_f1_ue_data(uint32_t ue_id); + +void du_init_f1_ue_data(void); +bool du_add_f1_ue_data(uint32_t ue_id, const f1_ue_data_t *data); +bool du_exists_f1_ue_data(uint32_t ue_id); +f1_ue_data_t du_get_f1_ue_data(uint32_t ue_id); +bool du_remove_f1_ue_data(uint32_t ue_id); + +#endif /* F1AP_IDS_H_ */ diff --git a/openair2/F1AP/f1ap_ids_test.c b/openair2/F1AP/f1ap_ids_test.c new file mode 100644 index 0000000000..3007db566a --- /dev/null +++ b/openair2/F1AP/f1ap_ids_test.c @@ -0,0 +1,42 @@ +/* + * 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 + */ + +#include +#include +#include +#include "common/utils/assertions.h" +#include "f1ap_ids.h" + +int main() +{ + du_init_f1_ue_data(); + int rnti = 13; + f1_ue_data_t data = {.secondary_ue = 1}; + bool ret = du_add_f1_ue_data(rnti, &data); + DevAssert(ret); + ret = du_add_f1_ue_data(rnti, &data); + DevAssert(!ret); + bool exists = du_exists_f1_ue_data(rnti); + DevAssert(exists); + f1_ue_data_t rdata = du_get_f1_ue_data(rnti); + DevAssert(rdata.secondary_ue == data.secondary_ue); + return 0; +} diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index 8899be18e6..3d980dd217 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -79,7 +79,7 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) { // set up PDCP, RLC, MAC nr_pdcp_layer_init(); - nr_pdcp_add_drbs(ENB_FLAG_NO, nr_ue_mac_inst->crnti, 0, rbconfig->drb_ToAddModList, 0, NULL, NULL, &rlc_bearer_list); + nr_pdcp_add_drbs(ENB_FLAG_NO, nr_ue_mac_inst->crnti, rbconfig->drb_ToAddModList, 0, NULL, NULL, &rlc_bearer_list); nr_rlc_add_drb(nr_ue_mac_inst->crnti, rbconfig->drb_ToAddModList->list.array[0]->drb_Identity, rlc_rbconfig); nr_ue_mac_inst->logicalChannelBearer_exist[0] = true; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index e0c5879e9c..165251e9f4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -2083,7 +2083,7 @@ static void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, s // Pause scheduling according to: // 3GPP TS 38.331 Section 12 Table 12.1-1: UE performance requirements for RRC procedures for UEs - const NR_ServingCellConfig_t *servingCellConfig = UE->CellGroup ? UE->CellGroup->spCellConfig->spCellConfigDedicated : NULL; + const NR_ServingCellConfig_t *servingCellConfig = UE->CellGroup && UE->CellGroup->spCellConfig ? UE->CellGroup->spCellConfig->spCellConfigDedicated : NULL; uint32_t delay_ms = servingCellConfig && servingCellConfig->downlinkBWP_ToAddModList ? NR_RRC_SETUP_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_SETUP_DELAY_MS; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 68a44fa0cf..81ea2edcb7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -47,6 +47,7 @@ #include "RRC/NR/MESSAGES/asn1_msg.h" #include "intertask_interface.h" +#include "openair2/F1AP/f1ap_ids.h" #include "T.h" @@ -1992,22 +1993,7 @@ void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_alloca destroy_nr_list(&sched_ctrl->retrans_ul_harq); uid_linear_allocator_free(uia, UE->uid); LOG_I(NR_MAC, "Remove NR rnti 0x%04x\n", UE->rnti); - const rnti_t rnti = UE->rnti; free(UE); - - /* clear RA process(es?) associated to the UE */ - for (int cc_id = 0; cc_id < NFAPI_CC_MAX; cc_id++) { - for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { - NR_COMMON_channels_t *cc = &ccPtr[cc_id]; - if (cc->ra[i].rnti == rnti) { - LOG_D(NR_MAC, "free RA process %d for rnti %04x\n", i, rnti); - /* is it enough? */ - cc->ra[i].cfra = false; - cc->ra[i].rnti = 0; - cc->ra[i].crnti = 0; - } - } - } } @@ -2922,6 +2908,7 @@ void send_initial_ul_rrc_message(gNB_MAC_INST *mac, int rnti, const uint8_t *sdu const f1ap_initial_ul_rrc_message_t ul_rrc_msg = { /* TODO: add mcc, mnc, cell_id, ..., is not available at MAC yet */ + .gNB_DU_ue_id = rnti, .crnti = rnti, .rrc_container = (uint8_t *) sdu, .rrc_container_length = sdu_len, @@ -2997,8 +2984,10 @@ void nr_mac_check_ul_failure(const gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ct /* to trigger only once: trigger when ul_failure_timer == 1, but timer will * stop at 0 and we wait for a UE release command from upper layers */ if (sched_ctrl->ul_failure_timer == 1) { + f1_ue_data_t ue_data = du_get_f1_ue_data(rnti); f1ap_ue_context_release_complete_t complete = { - .rnti = rnti, + .gNB_CU_ue_id = ue_data.secondary_ue, + .gNB_DU_ue_id = rnti, .cause = F1AP_CAUSE_RADIO_NETWORK, .cause_value = 12, // F1AP_CauseRadioNetwork_rl_failure_others }; 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 582420a0b4..0a450a1198 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -22,6 +22,7 @@ #include "mac_rrc_dl_handler.h" #include "mac_proto.h" +#include "openair2/F1AP/f1ap_ids.h" #include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "openair2/RRC/NR/MESSAGES/asn1_msg.h" @@ -100,7 +101,6 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) f1ap_ue_context_setup_t resp = { .gNB_CU_ue_id = req->gNB_CU_ue_id, .gNB_DU_ue_id = req->gNB_DU_ue_id, - .rnti = req->rnti, }; if (req->cu_to_du_rrc_information != NULL) { @@ -111,11 +111,11 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) NR_SCHED_LOCK(&mac->sched_lock); - NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, req->rnti); - AssertFatal(UE != NULL, "did not find UE with RNTI %04x, but UE Context Setup Failed not implemented\n", req->rnti); + NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, req->gNB_DU_ue_id); + AssertFatal(UE != NULL, "did not find UE with RNTI %04x, but UE Context Setup Failed not implemented\n", req->gNB_DU_ue_id); if (req->srbs_to_be_setup_length > 0) { - resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(req->rnti, + resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(req->gNB_DU_ue_id, req->srbs_to_be_setup_length, req->srbs_to_be_setup, &resp.srbs_to_be_setup, @@ -123,7 +123,7 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) } if (req->drbs_to_be_setup_length > 0) { - resp.drbs_to_be_setup_length = handle_ue_context_drbs_setup(req->rnti, + resp.drbs_to_be_setup_length = handle_ue_context_drbs_setup(req->gNB_DU_ue_id, req->drbs_to_be_setup_length, req->drbs_to_be_setup, &resp.drbs_to_be_setup, @@ -131,7 +131,7 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) } if (req->rrc_container != NULL) - nr_rlc_srb_recv_sdu(req->rnti, DCCH, req->rrc_container, req->rrc_container_length); + nr_rlc_srb_recv_sdu(req->gNB_DU_ue_id, DCCH, req->rrc_container, req->rrc_container_length); //nr_mac_update_cellgroup() resp.du_to_cu_rrc_information = calloc(1, sizeof(du_to_cu_rrc_information_t)); @@ -171,7 +171,6 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) f1ap_ue_context_modif_resp_t resp = { .gNB_CU_ue_id = req->gNB_CU_ue_id, .gNB_DU_ue_id = req->gNB_DU_ue_id, - .rnti = req->rnti, }; if (req->cu_to_du_rrc_information != NULL) { @@ -181,10 +180,10 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) } NR_SCHED_LOCK(&mac->sched_lock); - NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, req->rnti); + NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, req->gNB_DU_ue_id); if (req->srbs_to_be_setup_length > 0) { - resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(req->rnti, + resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(req->gNB_DU_ue_id, req->srbs_to_be_setup_length, req->srbs_to_be_setup, &resp.srbs_to_be_setup, @@ -192,7 +191,7 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) } if (req->drbs_to_be_setup_length > 0) { - resp.drbs_to_be_setup_length = handle_ue_context_drbs_setup(req->rnti, + resp.drbs_to_be_setup_length = handle_ue_context_drbs_setup(req->gNB_DU_ue_id, req->drbs_to_be_setup_length, req->drbs_to_be_setup, &resp.drbs_to_be_setup, @@ -200,7 +199,7 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) } if (req->rrc_container != NULL) - nr_rlc_srb_recv_sdu(req->rnti, DCCH, req->rrc_container, req->rrc_container_length); + nr_rlc_srb_recv_sdu(req->gNB_DU_ue_id, DCCH, req->rrc_container, req->rrc_container_length); if (req->ReconfigComplOutcome != RRCreconf_info_not_present && req->ReconfigComplOutcome != RRCreconf_success) { LOG_E(NR_MAC, @@ -224,7 +223,7 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) resp.du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded + 7) >> 3; /* works? */ - nr_mac_update_cellgroup(RC.nrmac[0], req->rnti, UE->CellGroup); + nr_mac_update_cellgroup(RC.nrmac[0], req->gNB_DU_ue_id, UE->CellGroup); } NR_SCHED_UNLOCK(&mac->sched_lock); @@ -249,32 +248,100 @@ void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd) /* mark UE as to be deleted after PUSCH failure */ gNB_MAC_INST *mac = RC.nrmac[0]; pthread_mutex_lock(&mac->sched_lock); - NR_UE_info_t *UE = find_nr_UE(&mac->UE_info, cmd->rnti); + NR_UE_info_t *UE = find_nr_UE(&mac->UE_info, cmd->gNB_DU_ue_id); if (UE->UE_sched_ctrl.ul_failure || cmd->rrc_container_length == 0) { /* The UE is already not connected anymore or we have nothing to forward*/ - nr_rlc_remove_ue(cmd->rnti); - mac_remove_nr_ue(mac, cmd->rnti); + nr_rlc_remove_ue(cmd->gNB_DU_ue_id); + mac_remove_nr_ue(mac, cmd->gNB_DU_ue_id); } else { /* UE is in sync: forward release message and mark to be deleted * after UL failure */ - nr_rlc_srb_recv_sdu(cmd->rnti, cmd->srb_id, cmd->rrc_container, cmd->rrc_container_length); + nr_rlc_srb_recv_sdu(cmd->gNB_DU_ue_id, cmd->srb_id, cmd->rrc_container, cmd->rrc_container_length); nr_mac_trigger_release_timer(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs); } pthread_mutex_unlock(&mac->sched_lock); f1ap_ue_context_release_complete_t complete = { - .rnti = cmd->rnti, + .gNB_CU_ue_id = cmd->gNB_CU_ue_id, + .gNB_DU_ue_id = cmd->gNB_DU_ue_id, }; mac->mac_rrc.ue_context_release_complete(&complete); - if (cmd->rrc_container) - free(cmd->rrc_container); + du_remove_f1_ue_data(cmd->gNB_DU_ue_id); } -int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) +void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc) { - LOG_D(NR_MAC, "DL RRC Message Transfer with %d bytes for RNTI %04x SRB %d\n", dl_rrc->rrc_container_length, dl_rrc->rnti, dl_rrc->srb_id); + LOG_D(NR_MAC, + "DL RRC Message Transfer with %d bytes for RNTI %04x SRB %d\n", + dl_rrc->rrc_container_length, + dl_rrc->gNB_DU_ue_id, + dl_rrc->srb_id); - nr_rlc_srb_recv_sdu(dl_rrc->rnti, dl_rrc->srb_id, dl_rrc->rrc_container, dl_rrc->rrc_container_length); - return 0; + gNB_MAC_INST *mac = RC.nrmac[0]; + pthread_mutex_lock(&mac->sched_lock); + /* check first that the scheduler knows such UE */ + NR_UE_info_t *UE = find_nr_UE(&mac->UE_info, dl_rrc->gNB_DU_ue_id); + if (UE == NULL) { + LOG_E(MAC, "ERROR: unknown UE with RNTI %04x, ignoring DL RRC Message Transfer\n", dl_rrc->gNB_DU_ue_id); + pthread_mutex_unlock(&mac->sched_lock); + return; + } + pthread_mutex_unlock(&mac->sched_lock); + + if (!du_exists_f1_ue_data(dl_rrc->gNB_DU_ue_id)) { + LOG_I(NR_MAC, "No CU UE ID stored for UE RNTI %04x, adding CU UE ID %d\n", dl_rrc->gNB_DU_ue_id, dl_rrc->gNB_CU_ue_id); + f1_ue_data_t new_ue_data = {.secondary_ue = dl_rrc->gNB_CU_ue_id}; + du_add_f1_ue_data(dl_rrc->gNB_DU_ue_id, &new_ue_data); + } + + if (UE->expect_reconfiguration && dl_rrc->srb_id == DCCH) { + /* we expected a reconfiguration, and this is on DCCH. We assume this is + * the reconfiguration; nr_mac_update_cellgroup() brings the config into + * the form expected by nr_mac_update_timers(), and we set the timer to + * apply the real configuration at expiration. + * Calling it nr_mac_update_cellgroup() is misleading, and using an + * intermediate buffer seems not necessary. This is for historical reasons, + * when we only had pointer to an RRC structure, and wanted to duplicate + * the contents to be applied later. The actually interesting function here + * is also configure_UE_BWP(), only called in nr_mac_update_timers(). + * TODO: This should be cleaned up when the whole CellGroupConfig is + * handled entirely at the DU: no intermediate buffer, trigger the timer + * from a function (there is nr_mac_enable_ue_rrc_processing_timer(), which + * is called from the RRC, hence locks the scheduler, which we cannot use). */ + LOG_I(NR_MAC, "triggering rrc_processing_timer time UE %04x\n", UE->rnti); + pthread_mutex_lock(&mac->sched_lock); + nr_mac_update_cellgroup(mac, dl_rrc->gNB_DU_ue_id, UE->reconfigCellGroup); + pthread_mutex_unlock(&mac->sched_lock); + const uint16_t sl_ahead = mac->if_inst->sl_ahead; + NR_SubcarrierSpacing_t scs = 1; + int delay = 10; + UE->UE_sched_ctrl.rrc_processing_timer = (delay << scs) + sl_ahead; + } + + if (dl_rrc->old_gNB_DU_ue_id != NULL) { + AssertFatal(*dl_rrc->old_gNB_DU_ue_id != dl_rrc->gNB_DU_ue_id, + "logic bug: current and old gNB DU UE ID cannot be the same\n"); + /* 38.401 says: "Find UE context based on old gNB-DU UE F1AP ID, replace + * old C-RNTI/PCI with new C-RNTI/PCI". So we delete the new contexts + * below, then change the C-RNTI of the old one to the new one */ + NR_UE_info_t *oldUE = find_nr_UE(&mac->UE_info, *dl_rrc->old_gNB_DU_ue_id); + DevAssert(oldUE); + pthread_mutex_lock(&mac->sched_lock); + /* 38.331 5.3.7.2 says that the UE releases the spCellConfig, so we drop it + * from the current configuration. Also, expect the reconfiguration from + * the CU, so save the old UE's CellGroup for the new UE */ + UE->CellGroup->spCellConfig = NULL; + nr_mac_update_cellgroup(mac, dl_rrc->gNB_DU_ue_id, UE->CellGroup); + UE->reconfigCellGroup = oldUE->CellGroup; + UE->expect_reconfiguration = true; + oldUE->CellGroup = NULL; + mac_remove_nr_ue(mac, *dl_rrc->old_gNB_DU_ue_id); + pthread_mutex_unlock(&mac->sched_lock); + nr_rlc_remove_ue(dl_rrc->gNB_DU_ue_id); + nr_rlc_update_rnti(*dl_rrc->old_gNB_DU_ue_id, dl_rrc->gNB_DU_ue_id); + } + + /* the DU ue id is the RNTI */ + nr_rlc_srb_recv_sdu(dl_rrc->gNB_DU_ue_id, dl_rrc->srb_id, dl_rrc->rrc_container, dl_rrc->rrc_container_length); } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h index 808277a7f4..859e128b4a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h @@ -29,6 +29,6 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req); void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req); void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd); -int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc); +void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc); #endif /* MAC_RRC_DL_HANDLER_H */ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c index 6780fad873..a024abe6af 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c @@ -64,7 +64,6 @@ static void ue_context_modification_response_direct(const f1ap_ue_context_modif_ f1ap_msg->gNB_CU_ue_id = resp->gNB_CU_ue_id; f1ap_msg->gNB_DU_ue_id = resp->gNB_DU_ue_id; - f1ap_msg->rnti = resp->rnti; f1ap_msg->mcc = resp->mcc; f1ap_msg->mnc = resp->mnc; f1ap_msg->mnc_digit_length = resp->mnc_digit_length; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c index f122a13c34..644decc21c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c @@ -106,7 +106,7 @@ static void ue_context_release_request_f1ap(const f1ap_ue_context_release_req_t* static void ue_context_release_complete_f1ap(const f1ap_ue_context_release_complete_t *complete) { - newGtpuDeleteAllTunnels(0, complete->rnti); + newGtpuDeleteAllTunnels(0, complete->gNB_DU_ue_id); MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_COMPLETE); f1ap_ue_context_release_complete_t *f1ap_msg = &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg); diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index cdba0b676b..7fd559fdcd 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -40,6 +40,7 @@ #include "nr_rlc/nr_rlc_oai_api.h" #include "RRC/NR/MESSAGES/asn1_msg.h" //#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" +#include "openair2/F1AP/f1ap_ids.h" #include "common/ran_context.h" #include "executables/softmodem-common.h" @@ -283,7 +284,7 @@ void mac_top_init_gNB(ngran_node_t node_type) * will output the packets at a local interface, which is in line with * the noS1 mode. Hence, below, we simply hardcode ENB_FLAG_NO */ // setup PDCP, RLC - nr_pdcp_add_drbs(ENB_FLAG_NO, 0x1234, 0, rbconfig->drb_ToAddModList, 0, NULL, NULL, &rlc_bearer_list); + nr_pdcp_add_drbs(ENB_FLAG_NO, 0x1234, rbconfig->drb_ToAddModList, 0, NULL, NULL, &rlc_bearer_list); nr_rlc_add_drb(0x1234, rbconfig->drb_ToAddModList->list.array[0]->drb_Identity, rlc_rbconfig); // free memory @@ -301,5 +302,7 @@ void mac_top_init_gNB(ngran_node_t node_type) memset(&nrmac->UE_info, 0, sizeof(nrmac->UE_info)); } + du_init_f1_ue_data(); + srand48(0); } diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 4e30c74a5c..457497679a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -46,19 +46,19 @@ #define NR_SCHED_LOCK(lock) \ do { \ int rc = pthread_mutex_lock(lock); \ - AssertFatal(rc == 0, "error while locking scheduler mutex\n"); \ + AssertFatal(rc == 0, "error while locking scheduler mutex, pthread_mutex_lock() returned %d\n", rc); \ } while (0) #define NR_SCHED_UNLOCK(lock) \ do { \ int rc = pthread_mutex_unlock(lock); \ - AssertFatal(rc == 0, "error while locking scheduler mutex\n"); \ + AssertFatal(rc == 0, "error while locking scheduler mutex, pthread_mutex_unlock() returned %d\n", rc); \ } while (0) #define NR_SCHED_ENSURE_LOCKED(lock)\ do {\ int rc = pthread_mutex_trylock(lock); \ - AssertFatal(rc == EBUSY, "this function should be called with the scheduler mutex locked\n");\ + AssertFatal(rc == EBUSY, "this function should be called with the scheduler mutex locked, pthread_mutex_trylock() returned %d\n", rc);\ } while (0) /* Commmon */ @@ -675,7 +675,11 @@ typedef struct { NR_UE_DL_BWP_t current_DL_BWP; NR_UE_UL_BWP_t current_UL_BWP; NR_mac_stats_t mac_stats; + /// currently active CellGroupConfig NR_CellGroupConfig_t *CellGroup; + /// CellGroupConfig that is to be activated after the next reconfiguration + NR_CellGroupConfig_t *reconfigCellGroup; + bool expect_reconfiguration; char cg_buf[32768]; /* arbitrary size */ asn_enc_rval_t enc_rval; // UE selected beam index diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c index d56c22f609..97370c5964 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c @@ -32,7 +32,7 @@ void e1_add_drb(int is_gnb, unsigned char *ciphering_key, unsigned char *integrity_key) { - add_drb_am(is_gnb, ue_id, 0, s, ciphering_algorithm, integrity_algorithm, + add_drb_am(is_gnb, ue_id, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key); LOG_I(PDCP, "%s:%s:%d: added DRB for UE ID %ld\n", __FILE__, __FUNCTION__, __LINE__, ue_id); } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h index f45f3f0458..3c16996126 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h @@ -45,7 +45,7 @@ void nr_pdcp_e1_add_drbs(eNB_flag_t enb_flag, uint8_t *const kUPenc, uint8_t *const kUPint); -void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, ue_id_t reestablish_ue_id, struct NR_DRB_ToAddMod *s, +void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_DRB_ToAddMod *s, int ciphering_algorithm, int integrity_algorithm, unsigned char *ciphering_key, diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 7a798d7b81..be22753026 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -36,6 +36,7 @@ #include "oai_asn1.h" #include "nr_pdcp_oai_api.h" #include "LAYER2/nr_rlc/nr_rlc_oai_api.h" +#include "openair2/F1AP/f1ap_ids.h" #include #include "openair2/SDAP/nr_sdap/nr_sdap.h" #include "nr_pdcp_e1_api.h" @@ -632,7 +633,9 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity, if (IS_SOFTMODEM_NOS1 || UE_NAS_USE_TUN) { LOG_D(PDCP, "IP packet received with size %d, to be sent to SDAP interface, UE ID/RNTI: %ld\n", size, ue->rntiMaybeUEid); - sdap_data_ind(entity->rb_id, entity->is_gnb, entity->has_sdap_rx, entity->pdusession_id, ue->rntiMaybeUEid, buf, size); + // in NoS1 mode: the SDAP should write() packets to an FD (TUN interface), + // so below, set is_gnb == 0 to do that + sdap_data_ind(entity->rb_id, 0, entity->has_sdap_rx, entity->pdusession_id, ue->rntiMaybeUEid, buf, size); } else{ for (i = 0; i < MAX_DRBS_PER_UE; i++) { @@ -653,11 +656,24 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity, } } -static void deliver_pdu_drb(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, - char *buf, int size, int sdu_id) +static void deliver_pdu_drb_ue(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, + char *buf, int size, int sdu_id) { DevAssert(deliver_pdu_data == NULL); - protocol_ctxt_t ctxt = { .enb_flag = 1, .rntiMaybeUEid = ue_id }; + protocol_ctxt_t ctxt = { .enb_flag = 0, .rntiMaybeUEid = ue_id }; + + mem_block_t *memblock = get_free_mem_block(size, __FUNCTION__); + memcpy(memblock->data, buf, size); + LOG_D(PDCP, "%s(): (drb %d) calling rlc_data_req size %d UE %ld/%04lx\n", __func__, rb_id, size, ctxt.rntiMaybeUEid, ctxt.rntiMaybeUEid); + enqueue_rlc_data_req(&ctxt, 0, MBMS_FLAG_NO, rb_id, sdu_id, 0, size, memblock); +} + +static void deliver_pdu_drb_gnb(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, + char *buf, int size, int sdu_id) +{ + DevAssert(deliver_pdu_data == NULL); + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_id); + protocol_ctxt_t ctxt = { .enb_flag = 1, .rntiMaybeUEid = ue_data.secondary_ue }; if (NODE_IS_CU(node_type)) { MessageDef *message_p = itti_alloc_new_message_sized(TASK_PDCP_ENB, 0, @@ -668,12 +684,11 @@ static void deliver_pdu_drb(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, AssertFatal(message_p != NULL, "OUT OF MEMORY"); gtpv1u_tunnel_data_req_t *req=>PV1U_TUNNEL_DATA_REQ(message_p); uint8_t *gtpu_buffer_p = (uint8_t*)(req+1); - memcpy(gtpu_buffer_p+GTPU_HEADER_OVERHEAD_MAX, - buf, size); + memcpy(gtpu_buffer_p + GTPU_HEADER_OVERHEAD_MAX, buf, size); req->buffer = gtpu_buffer_p; req->length = size; req->offset = GTPU_HEADER_OVERHEAD_MAX; - req->ue_id = ue_id; + req->ue_id = ue_id; // use CU UE ID as GTP will use that to look up TEID req->bearer_id = rb_id; LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size); extern instance_t CUuniqInstance; @@ -682,8 +697,6 @@ static void deliver_pdu_drb(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, mem_block_t *memblock = get_free_mem_block(size, __FUNCTION__); memcpy(memblock->data, buf, size); LOG_D(PDCP, "%s(): (drb %d) calling rlc_data_req size %d\n", __func__, rb_id, size); - //for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)memblock->data[i]); - //printf("\n"); enqueue_rlc_data_req(&ctxt, 0, MBMS_FLAG_NO, rb_id, sdu_id, 0, size, memblock); } } @@ -710,7 +723,11 @@ srb_found: MessageDef *message_p = itti_alloc_new_message(TASK_PDCP_GNB, 0, F1AP_UL_RRC_MESSAGE); AssertFatal(message_p != NULL, "OUT OF MEMORY\n"); f1ap_ul_rrc_message_t *ul_rrc = &F1AP_UL_RRC_MESSAGE(message_p); - ul_rrc->rnti = ue->rntiMaybeUEid; + ul_rrc->gNB_CU_ue_id = ue->rntiMaybeUEid; + /* look up the correct secondary UE ID to provide complete information to + * RRC, the RLC-PDCP interface does not transport this information */ + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue->rntiMaybeUEid); + ul_rrc->gNB_DU_ue_id = ue_data.secondary_ue; ul_rrc->srb_id = srb_id; ul_rrc->rrc_container = malloc(size); AssertFatal(ul_rrc->rrc_container != NULL, "OUT OF MEMORY\n"); @@ -740,19 +757,6 @@ void deliver_pdu_srb_rlc(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, enqueue_rlc_data_req(&ctxt, 1, MBMS_FLAG_NO, srb_id, sdu_id, 0, size, memblock); } -void deliver_pdu_srb_f1(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, - char *buf, int size, int sdu_id) -{ - DevAssert(deliver_pdu_data != NULL); - gNB_RRC_INST *rrc = deliver_pdu_data; - f1ap_dl_rrc_message_t dl_rrc = {.old_gNB_DU_ue_id = 0xFFFFFF, - .rrc_container = (uint8_t *)buf, - .rrc_container_length = size, - .rnti = ue_id, - .srb_id = srb_id}; - rrc->mac_rrc.dl_rrc_message_transfer(0, &dl_rrc); -} - static void add_srb(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_SRB_ToAddMod *s, int ciphering_algorithm, int integrity_algorithm, unsigned char *ciphering_key, unsigned char *integrity_key) { nr_pdcp_entity_t *pdcp_srb; @@ -784,7 +788,7 @@ static void add_srb(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_SRB_ToAddMod *s nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } -void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, ue_id_t reestablish_ue_id, struct NR_DRB_ToAddMod *s, int ciphering_algorithm, int integrity_algorithm, unsigned char *ciphering_key, unsigned char *integrity_key) +void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_DRB_ToAddMod *s, int ciphering_algorithm, int integrity_algorithm, unsigned char *ciphering_key, unsigned char *integrity_key) { nr_pdcp_entity_t *pdcp_drb; nr_pdcp_ue_t *ue; @@ -860,8 +864,10 @@ void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, ue_id_t reestablish_ue_id, st LOG_W(PDCP, "%s:%d:%s: warning DRB %d already exist for UE ID/RNTI %ld, do nothing\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rntiMaybeUEid); } else { pdcp_drb = new_nr_pdcp_entity(NR_PDCP_DRB_AM, is_gnb, drb_id, pdusession_id, - has_sdap_rx, has_sdap_tx, - deliver_sdu_drb, ue, deliver_pdu_drb, ue, + has_sdap_rx, has_sdap_tx, deliver_sdu_drb, ue, + is_gnb ? + deliver_pdu_drb_gnb : deliver_pdu_drb_ue, + ue, sn_size_dl, t_reordering, discard_timer, has_ciphering ? ciphering_algorithm : 0, has_integrity ? integrity_algorithm : 0, @@ -869,14 +875,6 @@ void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, ue_id_t reestablish_ue_id, st has_integrity ? integrity_key : NULL); nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb); - if (reestablish_ue_id > 0) { - nr_pdcp_ue_t *reestablish_ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, reestablish_ue_id); - if (reestablish_ue != NULL) { - pdcp_drb->tx_next = reestablish_ue->drb[drb_id - 1]->tx_next; - LOG_I(PDCP, "Applying tx_next %d in DRB %d from old UEid %lx to new UEid %lx\n", reestablish_ue->drb[drb_id - 1]->tx_next, drb_id, reestablish_ue_id, rntiMaybeUEid); - } - } - LOG_D(PDCP, "%s:%d:%s: added drb %d to UE ID/RNTI %ld\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rntiMaybeUEid); new_nr_sdap_entity(is_gnb, has_sdap_rx, has_sdap_tx, rntiMaybeUEid, pdusession_id, is_sdap_DefaultDRB, drb_id, mappedQFIs2Add, mappedQFIs2AddCount); @@ -886,7 +884,6 @@ void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, ue_id_t reestablish_ue_id, st static void add_drb(int is_gnb, ue_id_t rntiMaybeUEid, - ue_id_t reestablish_ue_id, struct NR_DRB_ToAddMod *s, NR_RLC_Config_t *rlc_Config, int ciphering_algorithm, @@ -896,12 +893,12 @@ static void add_drb(int is_gnb, { switch (rlc_Config->present) { case NR_RLC_Config_PR_am: - add_drb_am(is_gnb, rntiMaybeUEid, reestablish_ue_id, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key); + add_drb_am(is_gnb, rntiMaybeUEid, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key); break; case NR_RLC_Config_PR_um_Bi_Directional: // add_drb_um(rntiMaybeUEid, s); /* hack */ - add_drb_am(is_gnb, rntiMaybeUEid, reestablish_ue_id, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key); + add_drb_am(is_gnb, rntiMaybeUEid, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key); break; default: LOG_E(PDCP, "%s:%d:%s: fatal: unhandled DRB type\n", @@ -923,7 +920,6 @@ void nr_pdcp_add_srbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, NR_SRB_ToAddMo void nr_pdcp_add_drbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, - ue_id_t reestablish_ue_id, NR_DRB_ToAddModList_t *const drb2add_list, const uint8_t security_modeP, uint8_t *const kUPenc, @@ -932,7 +928,7 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag, { if (drb2add_list != NULL) { for (int i = 0; i < drb2add_list->list.count; i++) { - add_drb(enb_flag, rntiMaybeUEid, reestablish_ue_id, drb2add_list->list.array[i], rlc_bearer2add_list->list.array[i]->rlc_Config, security_modeP & 0x0f, (security_modeP >> 4) & 0x0f, kUPenc, kUPint); + add_drb(enb_flag, rntiMaybeUEid, drb2add_list->list.array[i], rlc_bearer2add_list->list.array[i]->rlc_Config, security_modeP & 0x0f, (security_modeP >> 4) & 0x0f, kUPenc, kUPint); } } else LOG_W(PDCP, "nr_pdcp_add_drbs() with void list\n"); @@ -1065,6 +1061,39 @@ bool nr_pdcp_data_req_srb(ue_id_t ue_id, return 1; } +void nr_pdcp_reestablishment(ue_id_t ue_id) +{ + // TODO implement this on a per RB basis following TS 38.323 Sec 5.1.2 + nr_pdcp_manager_lock(nr_pdcp_ue_manager); + nr_pdcp_ue_t *ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id); + if (ue == NULL) { + LOG_E(PDCP, "Cannot find PDCP entity for UE %lx\n", ue_id); + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); + return; + } + + for (int i = 0; i < 3; i++) { + nr_pdcp_entity_t *srb = ue->srb[i]; + if (srb != NULL) { + srb->tx_next = 0; + srb->rx_next = 0; + srb->rx_deliv = 0; + srb->rx_reord = 0; + } + } + + for (int i = 0; i < MAX_DRBS_PER_UE; i++) { + nr_pdcp_entity_t *drb = ue->drb[i]; + if (drb != NULL) { + // drb->tx_next = 0; // Should continue from the previous value + drb->rx_next = 0; + //drb->rx_deliv = 0; // should continue from the previous value + drb->rx_reord = 0; + } + } + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); +} + bool nr_pdcp_data_req_drb(protocol_ctxt_t *ctxt_pP, const srb_flag_t srb_flagP, const rb_id_t rb_id, diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h index 0fd23d2f6b..f00ab98422 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h @@ -48,7 +48,6 @@ bool pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP, void nr_pdcp_add_drbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, - ue_id_t reestablish_ue_id, NR_DRB_ToAddModList_t *const drb2add_list, const uint8_t security_modeP, uint8_t *const kUPenc, @@ -58,6 +57,7 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag, void nr_DRB_preconfiguration(ue_id_t crntiMaybeUEid); bool nr_pdcp_remove_UE(ue_id_t ue_id); +void nr_pdcp_reestablishment(ue_id_t ue_id); void nr_pdcp_config_set_security(ue_id_t ue_id, const rb_id_t rb_id, @@ -80,10 +80,7 @@ bool cu_f1u_data_req(protocol_ctxt_t *ctxt_pP, typedef void (*deliver_pdu)(void *data, ue_id_t ue_id, int srb_id, char *buf, int size, int sdu_id); /* default implementation of deliver_pdu */ -void deliver_pdu_srb_rlc(void *data, ue_id_t ue_id, int srb_id, char *buf, - int size, int sdu_id); -void deliver_pdu_srb_f1(void *data, ue_id_t ue_id, int srb_id, char *buf, - int size, int sdu_id); +void deliver_pdu_srb_rlc(void *data, ue_id_t ue_id, int srb_id, char *buf, int size, int sdu_id); bool nr_pdcp_data_req_srb(ue_id_t ue_id, const rb_id_t rb_id, const mui_t muiP, diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index f4097d721b..7d17829e4f 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -39,6 +39,7 @@ #include "NR_UL-CCCH-Message.h" #include "openair2/F1AP/f1ap_du_rrc_message_transfer.h" +#include "openair2/F1AP/f1ap_ids.h" extern RAN_CONTEXT_t RC; @@ -425,11 +426,18 @@ rb_found: ctx.eNB_index = 0; ctx.brOption = 0; + is_enb = nr_rlc_manager_get_enb_flag(nr_rlc_ue_manager); + /* used fields? */ ctx.module_id = 0; + /* CU (PDCP, RRC, SDAP) use a different ID than RNTI, so below set the CU UE + * ID if in gNB, else use RNTI normally */ ctx.rntiMaybeUEid = ue->rnti; + if (is_enb) { + f1_ue_data_t ue_data = du_get_f1_ue_data(ue->rnti); + ctx.rntiMaybeUEid = ue_data.secondary_ue; + } - is_enb = nr_rlc_manager_get_enb_flag(nr_rlc_ue_manager); ctx.enb_flag = is_enb; if (is_enb) { @@ -453,7 +461,8 @@ rb_found: msg = itti_alloc_new_message(TASK_RLC_ENB, 0, F1AP_UL_RRC_MESSAGE); uint8_t *message_buffer = itti_malloc (TASK_RLC_ENB, TASK_DU_F1, size); memcpy (message_buffer, buf, size); - F1AP_UL_RRC_MESSAGE(msg).rnti = ue->rnti; + F1AP_UL_RRC_MESSAGE(msg).gNB_CU_ue_id = ctx.rntiMaybeUEid; + F1AP_UL_RRC_MESSAGE(msg).gNB_DU_ue_id = ue->rnti; F1AP_UL_RRC_MESSAGE(msg).srb_id = rb_id; F1AP_UL_RRC_MESSAGE(msg).rrc_container = message_buffer; F1AP_UL_RRC_MESSAGE(msg).rrc_container_length = size; @@ -467,7 +476,7 @@ rb_found: memcpy(req->buffer,buf,size); req->length=size; req->offset=0; - req->ue_id=ue->rnti; + req->ue_id=ue->rnti; // use RNTI here, which GTP will use to look up TEID req->bearer_id=rb_id; LOG_D(RLC, "Received uplink user-plane traffic at RLC-DU to be sent to the CU, size %d \n", size); extern instance_t DUuniqInstance; @@ -477,6 +486,7 @@ rb_found: } } + /* UE or monolithic gNB */ memblock = get_free_mem_block(size, __func__); if (memblock == NULL) { LOG_E(RLC, "%s:%d:%s: ERROR: get_free_mem_block failed\n", __FILE__, __LINE__, __FUNCTION__); @@ -1000,6 +1010,45 @@ rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x) return RLC_OP_STATUS_OK; } +bool nr_rlc_update_rnti(int from_rnti, int to_rnti) +{ + nr_rlc_manager_lock(nr_rlc_ue_manager); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, from_rnti); + if (ue == NULL) { + nr_rlc_manager_unlock(nr_rlc_ue_manager); + LOG_E(RLC, "Cannot find RLC entity for UE %04x\n", from_rnti); + return false; + } + ue->rnti = to_rnti; + LOG_I(RLC, "Update old UE RNTI %04x context to RNTI %04x\n", from_rnti, to_rnti); + for (int i = 0; i < sizeof(ue->srb) / sizeof(ue->srb[0]); ++i) + if (ue->srb[i]) + ue->srb[i]->reestablishment(ue->srb[i]); + for (int i = 0; i < sizeof(ue->drb) / sizeof(ue->drb[0]); ++i) + if (ue->drb[i]) + ue->drb[i]->reestablishment(ue->drb[i]); + nr_rlc_manager_unlock(nr_rlc_ue_manager); + return true; +} + +/* This function is for testing purposes. At least on a COTS UE, it will + * trigger a reestablishment. */ +void nr_rlc_test_trigger_reestablishment(int rnti) +{ + nr_rlc_manager_lock(nr_rlc_ue_manager); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + if (ue == NULL) { + nr_rlc_manager_unlock(nr_rlc_ue_manager); + LOG_E(RLC, "Cannot find RLC entity for UE %04x\n", rnti); + return; + } + /* we simply assume the SRB exists, because the scheduler creates it as soon + * as the UE context is created. */ + nr_rlc_entity_t *ent = ue->srb[0]; + ent->reestablishment(ent); + nr_rlc_manager_unlock(nr_rlc_ue_manager); +} + void nr_rlc_tick(int frame, int subframe) { if (frame != nr_rlc_current_time_last_frame || diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h index 3b4bce7176..15fe286435 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h @@ -43,6 +43,10 @@ void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_Beare void nr_rlc_add_drb(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig); void nr_rlc_remove_ue(int rnti); +bool nr_rlc_update_rnti(int from_rnti, int to_rnti); + +/* test function for CI to trigger reestablishments */ +void nr_rlc_test_trigger_reestablishment(int rnti); int nr_rlc_get_available_tx_space( const rnti_t rntiP, diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index 0f524a0241..3334842616 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -52,16 +52,6 @@ extern RAN_CONTEXT_t RC; -void nr_rrc_mac_remove_ue(rnti_t rntiMaybeUEid) -{ - nr_rlc_remove_ue(rntiMaybeUEid); - - gNB_MAC_INST *nrmac = RC.nrmac[0]; - NR_SCHED_LOCK(&nrmac->sched_lock); - mac_remove_nr_ue(nrmac, rntiMaybeUEid); - NR_SCHED_UNLOCK(&nrmac->sched_lock); -} - void nr_rrc_mac_update_cellgroup(rnti_t rntiMaybeUEid, NR_CellGroupConfig_t *cgc) { gNB_MAC_INST *nrmac = RC.nrmac[0]; diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 75446708a9..3935c18bfe 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -783,7 +783,7 @@ int16_t do_RRCReconfiguration( } if(cellGroupConfig!=NULL){ - update_cellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.gNB_ue_ngap_id, ue_context_pP ? ue_context_pP->ue_context.UE_Capability_nr : NULL, configuration); + update_cellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.rrc_ue_id, ue_context_pP ? ue_context_pP->ue_context.UE_Capability_nr : NULL, configuration); enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, NULL, @@ -1100,8 +1100,7 @@ uint8_t do_RRCReestablishmentRequest(uint8_t Mod_id, uint8_t *buffer, uint16_t c } //------------------------------------------------------------------------------ -int do_RRCReestablishment(const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *const ue_context_pP, +int do_RRCReestablishment(rrc_gNB_ue_context_t *const ue_context_pP, int CC_id, uint8_t *const buffer, size_t buffer_size, @@ -1126,7 +1125,8 @@ int do_RRCReestablishment(const protocol_ctxt_t *const ctxt_pP, rrcReestablishment->criticalExtensions.present = NR_RRCReestablishment__criticalExtensions_PR_rrcReestablishment; rrcReestablishment->criticalExtensions.choice.rrcReestablishment = CALLOC(1, sizeof(NR_RRCReestablishment_IEs_t)); - uint16_t pci = RC.nrrrc[ctxt_pP->module_id]->carrier.physCellId; + int module_id = 0; + uint16_t pci = RC.nrrrc[module_id]->carrier.physCellId; uint32_t nr_arfcn_dl = (uint64_t)*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB; LOG_I(NR_RRC, "Reestablishment update key pci=%d, earfcn_dl=%u\n", pci, nr_arfcn_dl); diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h index 27782d8a97..5e9a9fa756 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.h +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h @@ -172,8 +172,7 @@ uint8_t do_NR_ULInformationTransfer(uint8_t **buffer, uint8_t do_RRCReestablishmentRequest(uint8_t Mod_id, uint8_t *buffer, uint16_t c_rnti); -int do_RRCReestablishment(const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *const ue_context_pP, +int do_RRCReestablishment(rrc_gNB_ue_context_t *const ue_context_pP, int CC_id, uint8_t *const buffer, size_t buffer_size, diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c index 9c4e6462a4..9dccef4286 100644 --- a/openair2/RRC/NR/cucp_cuup_direct.c +++ b/openair2/RRC/NR/cucp_cuup_direct.c @@ -61,7 +61,7 @@ void fill_e1ap_bearer_setup_resp(e1ap_bearer_setup_resp_t *resp, drbSetup->numUpParam = 1; drbSetup->UpParamList[0].tlAddress = my_addr; drbSetup->UpParamList[0].teId = newGtpuCreateTunnel(gtpInst, - (ue_id & 0xFFFF), + ue_id, drb2Setup->id, drb2Setup->id, 0xFFFF, // We will set the right value from DU answer @@ -117,7 +117,7 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p, create_tunnel_req.outgoing_teid[i] = pdu->param.gtp_teid; } create_tunnel_req.num_tunnels = UE->nb_of_pdusessions; - create_tunnel_req.ue_id = UE->rnti; + create_tunnel_req.ue_id = UE->rrc_ue_id; int ret = gtpv1u_create_ngu_tunnel(getCxtE1(instance)->gtpInstN3, &create_tunnel_req, &create_tunnel_resp, @@ -150,8 +150,7 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p, LOG_D(NR_RRC, "Configuring PDCP DRBs for UE %x\n", UE->rnti); nr_pdcp_add_drbs(ctxt_p->enb_flag, - ctxt_p->rntiMaybeUEid, - 0, + UE->rrc_ue_id, DRB_configList, (UE->integrity_algorithm << 4) | UE->ciphering_algorithm, kUPenc, @@ -163,10 +162,10 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p, static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const req, instance_t instance) { - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[instance], req->rnti); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], req->gNB_cu_cp_ue_id); gNB_RRC_UE_t *UE = &ue_context_p->ue_context; protocol_ctxt_t ctxt = {0}; - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0, 0); e1ap_bearer_setup_resp_t resp = {0}; resp.numPDUSessions = req->numPDUSessions; @@ -198,7 +197,7 @@ static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const in_addr_t my_addr = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr); instance_t gtpInst = getCxt(CUtype, instance)->gtpInst; // GTP tunnel for DL - fill_e1ap_bearer_setup_resp(&resp, req, gtpInst, UE->rnti, remote_port, my_addr); + fill_e1ap_bearer_setup_resp(&resp, req, gtpInst, UE->rrc_ue_id, remote_port, my_addr); } // actually, we should receive the corresponding context setup response // message at the RRC and always react to this one. So in the following, we @@ -212,7 +211,7 @@ static void cucp_cuup_bearer_context_mod_direct(e1ap_bearer_setup_req_t *const r if (!NODE_IS_CU(RC.nrrrc[0]->node_type)) return; instance_t gtpInst = getCxt(CUtype, instance)->gtpInst; - CU_update_UP_DL_tunnel(req, gtpInst, req->rnti); + CU_update_UP_DL_tunnel(req, gtpInst, req->gNB_cu_cp_ue_id); } void cucp_cuup_message_transfer_direct_init(gNB_RRC_INST *rrc) { diff --git a/openair2/RRC/NR/mac_rrc_dl.h b/openair2/RRC/NR/mac_rrc_dl.h index 2728174603..94920f6f64 100644 --- a/openair2/RRC/NR/mac_rrc_dl.h +++ b/openair2/RRC/NR/mac_rrc_dl.h @@ -29,7 +29,7 @@ typedef void (*ue_context_setup_request_func_t)(const f1ap_ue_context_setup_t *r typedef void (*ue_context_modification_request_func_t)(const f1ap_ue_context_modif_req_t *req); typedef void (*ue_context_release_command_func_t)(const f1ap_ue_context_release_cmd_t *cmd); -typedef void (*dl_rrc_message_transfer_func_t)(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc); +typedef void (*dl_rrc_message_transfer_func_t)(const f1ap_dl_rrc_message_t *dl_rrc); struct nr_mac_rrc_dl_if_s; void mac_rrc_dl_direct_init(struct nr_mac_rrc_dl_if_s *mac_rrc); diff --git a/openair2/RRC/NR/mac_rrc_dl_direct.c b/openair2/RRC/NR/mac_rrc_dl_direct.c index 2d436c19e3..eeec72e132 100644 --- a/openair2/RRC/NR/mac_rrc_dl_direct.c +++ b/openair2/RRC/NR/mac_rrc_dl_direct.c @@ -24,17 +24,10 @@ #include "mac_rrc_dl.h" #include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h" -static void dl_rrc_message_transfer_direct(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) -{ - /* TODO how to manage inter-thread communication? */ - - dl_rrc_message(module_id, dl_rrc); -} - void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc) { mac_rrc->ue_context_setup_request = ue_context_setup_request; mac_rrc->ue_context_modification_request = ue_context_modification_request; mac_rrc->ue_context_release_command = ue_context_release_command; - mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_direct; + mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer; } diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c index 5bfeda2dc8..3f3b0f800f 100644 --- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c +++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c @@ -76,23 +76,34 @@ static void ue_context_release_command_f1ap(const f1ap_ue_context_release_cmd_t MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD); f1ap_ue_context_release_cmd_t *msg = &F1AP_UE_CONTEXT_RELEASE_CMD(message_p); *msg = *cmd; + if (cmd->rrc_container_length > 0) { + msg->rrc_container = calloc(cmd->rrc_container_length, sizeof(*msg->rrc_container)); + AssertFatal(msg->rrc_container != NULL, "out of memory\n"); + msg->rrc_container_length = cmd->rrc_container_length; + memcpy(msg->rrc_container, cmd->rrc_container, cmd->rrc_container_length); + } itti_send_msg_to_task (TASK_CU_F1, 0, message_p); } -static void dl_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) +static void dl_rrc_message_transfer_f1ap(const f1ap_dl_rrc_message_t *dl_rrc) { /* TODO call F1AP function directly? no real-time constraint here */ MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_DL_RRC_MESSAGE); f1ap_dl_rrc_message_t *msg = &F1AP_DL_RRC_MESSAGE(message_p); *msg = *dl_rrc; + if (dl_rrc->old_gNB_DU_ue_id) { + msg->old_gNB_DU_ue_id = malloc(sizeof(*msg->old_gNB_DU_ue_id)); + AssertFatal(msg->old_gNB_DU_ue_id != NULL, "out of memory\n"); + *msg->old_gNB_DU_ue_id = *dl_rrc->old_gNB_DU_ue_id; + } if (dl_rrc->rrc_container) { msg->rrc_container = malloc(dl_rrc->rrc_container_length); AssertFatal(msg->rrc_container != NULL, "out of memory\n"); msg->rrc_container_length = dl_rrc->rrc_container_length; memcpy(msg->rrc_container, dl_rrc->rrc_container, dl_rrc->rrc_container_length); } - itti_send_msg_to_task (TASK_CU_F1, module_id, message_p); + itti_send_msg_to_task (TASK_CU_F1, 0, message_p); } void mac_rrc_dl_f1ap_init(nr_mac_rrc_dl_if_t *mac_rrc) diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 51ef9d0f8d..f9c821736c 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -235,7 +235,6 @@ typedef enum { } rrc_action_t; typedef struct gNB_RRC_UE_s { - uint8_t primaryCC_id; drb_t established_drbs[MAX_DRBS_PER_UE]; uint8_t DRB_active[MAX_DRBS_PER_UE]; @@ -255,9 +254,6 @@ typedef struct gNB_RRC_UE_s { NR_RRCReconfiguration_t *reconfig; NR_RadioBearerConfig_t *rb_config; - /* Pointer to save spCellConfig during RRC Reestablishment procedures */ - NR_SpCellConfig_t *spCellConfigReestablishment; - ImsiMobileIdentity_t imsi; /* KgNB as derived from KASME received from EPC */ @@ -283,12 +279,7 @@ typedef struct gNB_RRC_UE_s { /* Information from UE RRCReestablishmentRequest */ NR_ReestablishmentCause_t reestablishment_cause; - /* UE id for initial connection to S1AP */ - uint16_t ue_initial_id; - - /* Information from S1AP initial_context_setup_req */ - uint32_t gNB_ue_s1ap_id :24; - uint32_t gNB_ue_ngap_id; + uint32_t rrc_ue_id; uint64_t amf_ue_ngap_id; nr_rrc_guami_t ue_guami; @@ -383,11 +374,6 @@ typedef struct cucp_cuup_if_s { cucp_cuup_bearer_context_setup_func_t bearer_context_mod; } cucp_cuup_if_t; -typedef struct nr_reestablish_rnti_map_s { - ue_id_t ue_id; - rnti_t c_rnti; -} nr_reestablish_rnti_map_t; - //---NR---(completely change)--------------------- typedef struct gNB_RRC_INST_s { @@ -435,8 +421,6 @@ typedef struct gNB_RRC_INST_s { // security configuration (preferred algorithms) nr_security_configuration_t security; - nr_reestablish_rnti_map_t nr_reestablish_rnti_map[MAX_MOBILES_PER_GNB]; - nr_mac_rrc_dl_if_t mac_rrc; cucp_cuup_if_t cucp_cuup; diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index fd9f38a3fb..7502662da3 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -119,7 +119,6 @@ void *rrc_gnb_task(void *args_p); \ *reOffset Pointer to RE Offset Value */ void rrc_config_dl_ptrs_params(NR_BWP_Downlink_t *bwp, long *ptrsNrb, long *ptrsMcs, long *epre_Ratio, long *reOffset); -void nr_rrc_mac_remove_ue(rnti_t rntiP); void nr_rrc_mac_update_cellgroup(rnti_t rntiMaybeUEid, NR_CellGroupConfig_t *cgc); int8_t nr_mac_rrc_bwp_switch_req(const module_id_t module_idP, @@ -164,7 +163,6 @@ void nr_pdcp_add_srbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, NR_SRB_ToAddMo void nr_pdcp_add_drbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, - ue_id_t reestablish_ue_id, NR_DRB_ToAddModList_t *const drb2add_list, const uint8_t security_modeP, uint8_t *const kUPenc, @@ -172,4 +170,7 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag, struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t instance, uint8_t CC_id); + +void nr_rrc_transfer_protected_rrc_message(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue_p, uint8_t srb_id, const uint8_t* buffer, int size); + #endif diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index f731ed0fbe..1fa458a309 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -97,6 +97,7 @@ #include #include "openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h" #include "openair2/F1AP/f1ap_common.h" +#include "openair2/F1AP/f1ap_ids.h" #include "openair2/SDAP/nr_sdap/nr_sdap_entity.h" #include "cucp_cuup_if.h" @@ -186,26 +187,6 @@ static void freeDRBlist(NR_DRB_ToAddModList_t *list) //ASN_STRUCT_FREE(asn_DEF_NR_DRB_ToAddModList, list); return; } -static void nr_rrc_addmod_srbs(int rnti, - const NR_SRB_INFO_TABLE_ENTRY *srb_list, - const int nb_srb, - const struct NR_CellGroupConfig__rlc_BearerToAddModList *bearer_list) -{ - if (srb_list == NULL || bearer_list == NULL) - return; - - for (int i = 0; i < nb_srb; i++) { - if (srb_list[i].Active) - for (int j = 0; j < bearer_list->list.count; j++) { - const NR_RLC_BearerConfig_t *bearer = bearer_list->list.array[j]; - if (bearer->servedRadioBearer != NULL - && bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity - && i == bearer->servedRadioBearer->choice.srb_Identity) { - nr_rlc_add_srb(rnti, i, bearer); - } - } - } -} static void nr_rrc_addmod_drbs(int rnti, const NR_DRB_ToAddModList_t *drb_list, @@ -227,6 +208,29 @@ static void nr_rrc_addmod_drbs(int rnti, } } +typedef struct deliver_dl_rrc_message_data_s { + const gNB_RRC_INST *rrc; + f1ap_dl_rrc_message_t *dl_rrc; +} deliver_dl_rrc_message_data_t; +static void rrc_deliver_dl_rrc_message(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, char *buf, int size, int sdu_id) +{ + DevAssert(deliver_pdu_data != NULL); + deliver_dl_rrc_message_data_t *data = (deliver_dl_rrc_message_data_t *)deliver_pdu_data; + data->dl_rrc->rrc_container = (uint8_t *)buf; + data->dl_rrc->rrc_container_length = size; + DevAssert(data->dl_rrc->srb_id == srb_id); + data->rrc->mac_rrc.dl_rrc_message_transfer(data->dl_rrc); +} + + +void nr_rrc_transfer_protected_rrc_message(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue_p, uint8_t srb_id, const uint8_t* buffer, int size) +{ + DevAssert(size > 0); + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); + f1ap_dl_rrc_message_t dl_rrc = {.gNB_CU_ue_id = ue_p->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, .srb_id = srb_id}; + deliver_dl_rrc_message_data_t data = {.rrc = rrc, .dl_rrc = &dl_rrc}; + nr_pdcp_data_req_srb(ue_p->rrc_ue_id, srb_id, rrc_gNB_mui++, size, (unsigned char *const)buffer, rrc_deliver_dl_rrc_message, &data); +} ///---------------------------------------------------------------------------------------------------------------/// ///---------------------------------------------------------------------------------------------------------------/// @@ -310,6 +314,7 @@ static void rrc_gNB_CU_DU_init(gNB_RRC_INST *rrc) AssertFatal(0 == 1, "Unknown node type %d\n", rrc->node_type); break; } + cu_init_f1_ue_data(); } static void openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigurationReq *configuration) @@ -422,25 +427,6 @@ static void freeSRBlist(NR_SRB_ToAddModList_t *l) LOG_E(NR_RRC, "Call free SRB list on NULL pointer\n"); } -static void apply_macrlc_config(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *const ue_context_pP, const protocol_ctxt_t *const ctxt_pP) -{ - NR_CellGroupConfig_t *cgc = get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup : NULL; - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - nr_rrc_mac_update_cellgroup(ue_p->rnti, cgc); - nr_rrc_addmod_srbs(ctxt_pP->rntiMaybeUEid, ue_p->Srb, maxSRBs, cgc->rlc_BearerToAddModList); - NR_DRB_ToAddModList_t *DRBs = fill_DRB_configList(ue_p); - nr_rrc_addmod_drbs(ctxt_pP->rntiMaybeUEid, DRBs, cgc->rlc_BearerToAddModList); - freeDRBlist(DRBs); -} - -void apply_macrlc_config_reest(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *const ue_context_pP, const protocol_ctxt_t *const ctxt_pP, ue_id_t ue_id) -{ - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - nr_rrc_mac_update_cellgroup(ue_id, ue_p->masterCellGroup); - - nr_rrc_addmod_srbs(ctxt_pP->rntiMaybeUEid, ue_p->Srb, maxSRBs, ue_p->masterCellGroup->rlc_BearerToAddModList); -} - //----------------------------------------------------------------------------- static void rrc_gNB_generate_RRCSetup(instance_t instance, rnti_t rnti, @@ -466,74 +452,18 @@ static void rrc_gNB_generate_RRCSetup(instance_t instance, (char *)buf, size, "[MSG] RRC Setup\n"); - nr_pdcp_add_srbs(true, rnti, SRBs, 0, NULL, NULL); + nr_pdcp_add_srbs(true, ue_p->rrc_ue_id, SRBs, 0, NULL, NULL); freeSRBlist(SRBs); + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); f1ap_dl_rrc_message_t dl_rrc = { - .old_gNB_DU_ue_id = 0xFFFFFF, + .gNB_CU_ue_id = ue_p->rrc_ue_id, + .gNB_DU_ue_id = ue_data.secondary_ue, .rrc_container = buf, .rrc_container_length = size, - .rnti = ue_p->rnti, .srb_id = CCCH }; - rrc->mac_rrc.dl_rrc_message_transfer(instance, &dl_rrc); -} - -//----------------------------------------------------------------------------- -static int rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id_t module_id, rnti_t rnti, const int CC_id) -//----------------------------------------------------------------------------- -{ - LOG_I(NR_RRC, "generate RRCSetup for RRCReestablishmentRequest \n"); - rrc_gNB_ue_context_t *ue_context_pP = NULL; - gNB_RRC_INST *rrc_instance_p = RC.nrrrc[module_id]; - - ue_context_pP = rrc_gNB_create_ue_context(rnti, rrc_instance_p, 0); - - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - unsigned char buf[1024]; - uint8_t xid = rrc_gNB_get_next_transaction_identifier(module_id); - ue_p->xids[xid] = RRC_SETUP_FOR_REESTABLISHMENT; - NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, true); - - int size = do_RRCSetup(ue_context_pP, buf, xid, NULL, 0, &rrc_instance_p->configuration, SRBs); - AssertFatal(size > 0, "do_RRCSetup failed\n"); - AssertFatal(size <= 1024, "memory corruption\n"); - - AssertFatal(size>0,"Error generating RRCSetup for RRCReestablishmentRequest\n"); - - LOG_DUMPMSG(NR_RRC, DEBUG_RRC, - (char *)buf, - size, - "[MSG] RRC Setup\n"); - - LOG_D(NR_RRC, "RRC_gNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_gNB for rnti %04x\n", rnti); - freeSRBlist(SRBs); - - // update SCC and MIB/SIB (two calls) - nr_mac_config_scc(RC.nrmac[rrc_instance_p->module_id], - rrc_instance_p->configuration.pdsch_AntennaPorts, - rrc_instance_p->configuration.pusch_AntennaPorts, - rrc_instance_p->configuration.sib1_tda, - rrc_instance_p->configuration.minRXTXTIME, - rrc_instance_p->carrier.servingcellconfigcommon); - nr_mac_config_mib(RC.nrmac[rrc_instance_p->module_id], rrc_instance_p->carrier.mib); - nr_mac_config_sib1(RC.nrmac[rrc_instance_p->module_id], rrc_instance_p->carrier.siblock1); - - LOG_I(NR_RRC, " [RAPROC] rnti: %04x Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n", rnti, size); - // configure MAC - protocol_ctxt_t ctxt = {0}; - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, 0, GNB_FLAG_YES, rnti, 0, 0); - apply_macrlc_config(rrc_instance_p, ue_context_pP, &ctxt); - - f1ap_dl_rrc_message_t dl_rrc = { - .old_gNB_DU_ue_id = 0xFFFFFF, - .rrc_container = buf, - .rrc_container_length = size, - .rnti = ue_p->rnti, - .srb_id = CCCH - }; - rrc_instance_p->mac_rrc.dl_rrc_message_transfer(module_id, &dl_rrc); - return xid; + rrc->mac_rrc.dl_rrc_message_transfer(&dl_rrc); } static void rrc_gNB_generate_RRCReject(module_id_t module_id, rrc_gNB_ue_context_t *const ue_context_pP) @@ -554,18 +484,17 @@ static void rrc_gNB_generate_RRCReject(module_id_t module_id, rrc_gNB_ue_context "[MSG] RRCReject \n"); LOG_I(NR_RRC, " [RAPROC] ue %04x Logical Channel DL-CCCH, Generating NR_RRCReject (bytes %d)\n", ue_p->rnti, size); + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); f1ap_dl_rrc_message_t dl_rrc = { - .gNB_CU_ue_id = 0, - .gNB_DU_ue_id = 0, - .old_gNB_DU_ue_id = 0xFFFFFF, + .gNB_CU_ue_id = ue_p->rrc_ue_id, + .gNB_DU_ue_id = ue_data.secondary_ue, .rrc_container = buf, .rrc_container_length = size, - .rnti = ue_p->rnti, .srb_id = CCCH, .execute_duplication = 1, .RAT_frequency_priority_information.en_dc = 0 }; - rrc->mac_rrc.dl_rrc_message_transfer(module_id, &dl_rrc); + rrc->mac_rrc.dl_rrc_message_transfer(&dl_rrc); } //----------------------------------------------------------------------------- @@ -580,6 +509,7 @@ static void rrc_gNB_process_RRCSetupComplete(const protocol_ctxt_t *const ctxt_p ue_context_pP->ue_context.Srb[1].Active = 1; ue_context_pP->ue_context.Srb[2].Active = 0; ue_context_pP->ue_context.StatusRrc = NR_RRC_CONNECTED; + AssertFatal(ctxt_pP->rntiMaybeUEid == ue_context_pP->ue_context.rrc_ue_id, "logic bug: inconsistent IDs, must use CU UE ID!\n"); if (get_softmodem_params()->sa) { rrc_gNB_send_NGAP_NAS_FIRST_REQ(ctxt_pP, ue_context_pP, rrcSetupComplete); @@ -668,7 +598,7 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co ue_context_pP->ue_context.rnti); AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n"); - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc); + nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size); if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) { gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; @@ -775,7 +705,7 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const c ctxt_pP->module_id, DCCH); - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc); + nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size); if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) { nr_rrc_mac_update_cellgroup(ue_context_pP->ue_context.rnti, ue_context_pP->ue_context.masterCellGroup); @@ -928,7 +858,7 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( DCCH); gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc); + nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size); if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) { uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated @@ -1009,7 +939,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( DCCH); gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc); + nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size); if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) { uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated @@ -1046,35 +976,18 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co /* Refresh SRBs/DRBs */ LOG_D(NR_RRC, "Configuring PDCP DRBs/SRBs for UE %04x\n", ue_p->rnti); - ue_id_t reestablish_ue_id = 0; - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &(RC.nrrrc[ctxt_pP->module_id])->nr_reestablish_rnti_map[i]; - if (nr_reestablish_rnti_map->ue_id == ctxt_pP->rntiMaybeUEid) { - ue_context_pP->ue_context.ue_reconfiguration_after_reestablishment_counter++; - reestablish_ue_id = nr_reestablish_rnti_map[i].c_rnti; - LOG_D(NR_RRC, - "Removing reestablish_rnti_map[%d] UEid %lx, RNTI %04x\n", - i, - nr_reestablish_rnti_map->ue_id, - nr_reestablish_rnti_map->c_rnti); - // clear current C-RNTI from map - nr_reestablish_rnti_map->ue_id = 0; - nr_reestablish_rnti_map->c_rnti = 0; - break; - } - } - NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, false); + ue_context_pP->ue_context.ue_reconfiguration_after_reestablishment_counter++; + NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, false); nr_pdcp_add_srbs(ctxt_pP->enb_flag, - ctxt_pP->rntiMaybeUEid, + ue_p->rrc_ue_id, SRBs, (ue_p->integrity_algorithm << 4) | ue_p->ciphering_algorithm, kRRCenc, kRRCint); freeSRBlist(SRBs); nr_pdcp_add_drbs(ctxt_pP->enb_flag, - ctxt_pP->rntiMaybeUEid, - reestablish_ue_id, + ue_p->rrc_ue_id, DRB_configList, (ue_p->integrity_algorithm << 4) | ue_p->ciphering_algorithm, kUPenc, @@ -1145,34 +1058,23 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co } //----------------------------------------------------------------------------- -void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP, - const uint8_t *masterCellGroup_from_DU, - NR_ServingCellConfigCommon_t *scc, - const int CC_id) +static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context_pP, + const uint8_t *masterCellGroup_from_DU, + NR_ServingCellConfigCommon_t *scc, + const rnti_t old_rnti) //----------------------------------------------------------------------------- { - // int UE_id = -1; - // NR_LogicalChannelConfig_t *SRB1_logicalChannelConfig = NULL; - // NR_SRB_ToAddMod_t *SRB1_config = NULL; - // rrc_gNB_carrier_data_t *carrier = NULL; - module_id_t module_id = ctxt_pP->module_id; - gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; + module_id_t module_id = 0; + gNB_RRC_INST *rrc = RC.nrrrc[module_id]; int enable_ciphering = 0; gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - // Need to drop spCellConfig when there is a RRCReestablishment - // Save spCellConfig in spCellConfigReestablishment to recover after Reestablishment is completed - ue_p->spCellConfigReestablishment = ue_p->masterCellGroup->spCellConfig; - ue_p->masterCellGroup->spCellConfig = NULL; - uint8_t buffer[RRC_BUF_SIZE] = {0}; uint8_t xid = rrc_gNB_get_next_transaction_identifier(module_id); ue_p->xids[xid] = RRC_REESTABLISH; NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, true); - int size = do_RRCReestablishment(ctxt_pP, - ue_context_pP, - CC_id, + int size = do_RRCReestablishment(ue_context_pP, + 0 /* CC_id */, buffer, RRC_BUF_SIZE, xid, @@ -1192,101 +1094,27 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, nr_derive_key(RRC_ENC_ALG, ue_p->ciphering_algorithm, ue_p->kgnb, kRRCenc); nr_derive_key(RRC_INT_ALG, ue_p->integrity_algorithm, ue_p->kgnb, kRRCint); - - /* Configure SRB1 for UE */ - nr_pdcp_add_srbs(ctxt_pP->enb_flag, ctxt_pP->rntiMaybeUEid, SRBs, 0, NULL, NULL); - LOG_D(NR_RRC, "UE %04x --- MAC_CONFIG_REQ (SRB1) ---> MAC_gNB\n", ue_p->rnti); freeSRBlist(SRBs); - LOG_I(NR_RRC, "Set PDCP security RNTI %04lx nca %ld nia %d in RRCReestablishment\n", ctxt_pP->rntiMaybeUEid, ue_p->ciphering_algorithm, ue_p->integrity_algorithm); + LOG_I(NR_RRC, "Set PDCP security UE %d RNTI %04x nca %ld nia %d in RRCReestablishment\n", ue_p->rrc_ue_id, ue_p->rnti, ue_p->ciphering_algorithm, ue_p->integrity_algorithm); uint8_t security_mode = enable_ciphering ? ue_p->ciphering_algorithm | (ue_p->integrity_algorithm << 4) : 0 | (ue_p->integrity_algorithm << 4); - nr_pdcp_config_set_security(ctxt_pP->rntiMaybeUEid, + nr_pdcp_config_set_security(ue_p->rrc_ue_id, DCCH, security_mode, kRRCenc, kRRCint, kUPenc); + nr_pdcp_reestablishment(ue_p->rrc_ue_id); - if (!NODE_IS_CU(rrc->node_type)) { - apply_macrlc_config_reest(rrc, ue_context_pP, ctxt_pP, ctxt_pP->rntiMaybeUEid); - } - - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc); -} - -/// @brief Function used in RRCReestablishmentComplete procedure to update the NGU Tunnels. -/// @param reestablish_rnti is the old C-RNTI -void RRCReestablishmentComplete_update_ngu_tunnel(const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP, - const rnti_t reestablish_rnti) -{ - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - int i = 0; - int j = 0; - int ret = 0; - - if (get_softmodem_params()->sa) { - LOG_W(NR_RRC, "RRC Reestablishment - Rework identity mapping need to be done properly!\n"); - gtpv1u_gnb_create_tunnel_req_t create_tunnel_req = {0}; - /* Save e RAB information for later */ - - for (j = 0, i = 0; i < NB_RB_MAX; i++) { - if (ue_p->pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_p->pduSession[i].status == PDU_SESSION_STATUS_DONE) { - create_tunnel_req.pdusession_id[j] = ue_p->pduSession[i].param.pdusession_id; - create_tunnel_req.incoming_rb_id[j] = i + 1; - create_tunnel_req.outgoing_teid[j] = ue_p->pduSession[i].param.gtp_teid; - // to be developped, use the first QFI only - create_tunnel_req.outgoing_qfi[j] = ue_p->pduSession[i].param.qos[0].qfi; - memcpy(create_tunnel_req.dst_addr[j].buffer, ue_p->pduSession[i].param.upf_addr.buffer, sizeof(uint8_t) * 20); - create_tunnel_req.dst_addr[j].length = ue_p->pduSession[i].param.upf_addr.length; - j++; - } - } - - create_tunnel_req.ue_id = ctxt_pP->rntiMaybeUEid; // warning put zero above - create_tunnel_req.num_tunnels = j; - ret = gtpv1u_update_ngu_tunnel(ctxt_pP->instance, &create_tunnel_req, reestablish_rnti); - - if (ret != 0) { - LOG_E(NR_RRC, "RRC Reestablishment - gtpv1u_update_ngu_tunnel failed,start to release UE %x\n", reestablish_rnti); - AssertFatal(false, "not implemented\n"); - return; - } - } -} - -/// @brief Function used in RRCReestablishmentComplete procedure to update the NAS PDUSessions and the xid. -/// @param old_xid Refers to the old transaction identifier passed to rrc_gNB_process_RRCReestablishmentComplete as xid. -/// @todo parameters yet to process inside the for loop. -/// @todo should test if pdu session are Ok before! inside the for loop. -void RRCReestablishmentComplete_nas_pdu_update(rrc_gNB_ue_context_t *ue_context_pP, const uint8_t old_xid) -{ - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - /* Add all NAS PDUs to the list */ - for (int i = 0; i < ue_p->nb_of_pdusessions; i++) { - ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE; - ue_p->pduSession[i].xid = old_xid; - LOG_D(NR_RRC, - "RRC Reestablishment - setting the status for the default DRB (index %d) to (%d,%s)\n", - i, - ue_p->pduSession[i].status, - "PDU_SESSION_STATUS_DONE"); - } -} - -/// @brief Function used in RRCReestablishmentComplete procedure to Free all the NAS PDU buffers. -void RRCReestablishmentComplete_nas_pdu_free(rrc_gNB_ue_context_t *ue_context_pP) -{ - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - /* Free all NAS PDUs */ - for (int i = 0; i < ue_p->nb_of_pdusessions; i++) { - if (ue_p->pduSession[i].param.nas_pdu.buffer != NULL) { - /* Free the NAS PDU buffer and invalidate it */ - free(ue_p->pduSession[i].param.nas_pdu.buffer); - ue_p->pduSession[i].param.nas_pdu.buffer = NULL; - } - } + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); + uint32_t old_gNB_DU_ue_id = old_rnti; + f1ap_dl_rrc_message_t dl_rrc = {.gNB_CU_ue_id = ue_p->rrc_ue_id, + .gNB_DU_ue_id = ue_data.secondary_ue, + .srb_id = DCCH, + .old_gNB_DU_ue_id = &old_gNB_DU_ue_id}; + deliver_dl_rrc_message_data_t data = {.rrc = rrc, .dl_rrc = &dl_rrc}; + nr_pdcp_data_req_srb(ue_p->rrc_ue_id, DCCH, rrc_gNB_mui++, size, (unsigned char *const)buffer, rrc_deliver_dl_rrc_message, &data); } /// @brief Function tha processes RRCReestablishmentComplete message sent by the UE, after RRCReestasblishment request. @@ -1294,10 +1122,9 @@ void RRCReestablishmentComplete_nas_pdu_free(rrc_gNB_ue_context_t *ue_context_pP /// @param reestablish_rnti is the old C-RNTI /// @param ue_context_pP UE context container information regarding the UE /// @param xid Transaction Identifier used in RRC messages -void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP, - const rnti_t reestablish_rnti, - rrc_gNB_ue_context_t *ue_context_pP, - const uint8_t xid) +static void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *ue_context_pP, + const uint8_t xid) { gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; LOG_I(NR_RRC, @@ -1316,19 +1143,10 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx nr_rrc_pdcp_config_security(ctxt_pP, ue_context_pP, send_security_mode_command); LOG_D(NR_RRC, "RRC Reestablishment - set security successfully \n"); } - RRCReestablishmentComplete_update_ngu_tunnel(ctxt_pP, ue_context_pP, reestablish_rnti); - RRCReestablishmentComplete_nas_pdu_update(ue_context_pP, xid); - - /* Update RNTI in ue_context */ - LOG_I(NR_RRC, "RRC Reestablishment - Updating UEid from %04x to %lx\n", ue_p->rnti, ctxt_pP->rntiMaybeUEid); - rrc_gNB_update_ue_context_rnti(ctxt_pP->rntiMaybeUEid, RC.nrrrc[ctxt_pP->module_id], ue_p->gNB_ue_ngap_id); gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); - // Revert spCellConfig stored in spCellConfigReestablishment before had been dropped during RRC Reestablishment - ue_p->masterCellGroup->spCellConfig = ue_p->spCellConfigReestablishment; - ue_p->spCellConfigReestablishment = NULL; cellGroupConfig->spCellConfig = ue_p->masterCellGroup->spCellConfig; cellGroupConfig->mac_CellGroupConfig = ue_p->masterCellGroup->mac_CellGroupConfig; cellGroupConfig->physicalCellGroupConfig = ue_p->masterCellGroup->physicalCellGroupConfig; @@ -1371,32 +1189,13 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx freeDRBlist(DRBs); LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buffer, size, "[MSG] RRC Reconfiguration\n"); - RRCReestablishmentComplete_nas_pdu_free(ue_context_pP); - - if (size < 0) { - LOG_E(NR_RRC, "RRC decode err!!! do_RRCReconfiguration\n"); - return; - } else { - LOG_I(NR_RRC, - "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE id %04x)\n", - ctxt_pP->module_id, - ctxt_pP->frame, - size, - ue_p->rnti); - LOG_D(NR_RRC, - "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (RRCReconfiguration to UE %04x MUI %d) --->][PDCP][MOD " - "%u][RB %u]\n", - ctxt_pP->frame, - ctxt_pP->module_id, - size, - ue_p->rnti, - rrc_gNB_mui, - ctxt_pP->module_id, - DCCH); - - nr_rrc_mac_update_cellgroup(ue_context_pP->ue_context.rnti, cellGroupConfig); - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc); - } + AssertFatal(size > 0, "cannot encode RRC Reconfiguration\n"); + LOG_I(NR_RRC, + "UE %d RNTI %04x: Generate NR_RRCReconfiguration after reestablishment complete (bytes %d)\n", + ue_p->rrc_ue_id, + ue_p->rnti, + size); + nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size); if (NODE_IS_DU(RC.nrrrc[ctxt_pP->module_id]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[ctxt_pP->module_id]->node_type)) { uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig @@ -1451,7 +1250,7 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP nr_rrc_mac_update_cellgroup(ue_context_pP->ue_context.rnti, masterCellGroup); gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc); + nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size); if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) { uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated @@ -1466,17 +1265,18 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP } /*------------------------------------------------------------------------------*/ -static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint8_t *buffer, int buffer_length, const uint8_t *du_to_cu_rrc_container, int du_to_cu_rrc_container_len) +static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *msg) { - module_id_t Idx; asn_dec_rval_t dec_rval; NR_UL_CCCH_Message_t *ul_ccch_msg = NULL; gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[module_id]; NR_RRCSetupRequest_IEs_t *rrcSetupRequest = NULL; NR_RRCReestablishmentRequest_IEs_t rrcReestablishmentRequest; + rnti_t rnti = msg->crnti; - LOG_I(NR_RRC, "Decoding CCCH: RNTI %04x, payload_size %d\n", rnti, buffer_length); - dec_rval = uper_decode(NULL, &asn_DEF_NR_UL_CCCH_Message, (void **) &ul_ccch_msg, buffer, buffer_length, 0, 0); + LOG_I(NR_RRC, "Decoding CCCH: RNTI %04x, payload_size %d\n", rnti, msg->rrc_container_length); + dec_rval = + uper_decode(NULL, &asn_DEF_NR_UL_CCCH_Message, (void **)&ul_ccch_msg, msg->rrc_container, msg->rrc_container_length, 0, 0); if (dec_rval.code != RC_OK || dec_rval.consumed == 0) { LOG_E(NR_RRC, " FATAL Error in receiving CCCH\n"); @@ -1492,12 +1292,9 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint case NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest: LOG_D(NR_RRC, "Received RRCSetupRequest on UL-CCCH-Message (UE rnti %04x)\n", rnti); - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, rnti); - if (ue_context_p != NULL) { - LOG_W(NR_RRC, "Got RRC setup request for a already registered RNTI %x, dropping the old one and give up this rrcSetupRequest\n", ue_context_p->ue_context.rnti); - rrc_gNB_remove_ue_context(gnb_rrc_inst, ue_context_p); - } else { + { rrcSetupRequest = &ul_ccch_msg->message.choice.c1->choice.rrcSetupRequest->rrcSetupRequest; + rrc_gNB_ue_context_t *ue_context_p = NULL; if (NR_InitialUE_Identity_PR_randomValue == rrcSetupRequest->ue_Identity.present) { /* randomValue BIT STRING (SIZE (39)) */ if (rrcSetupRequest->ue_Identity.choice.randomValue.size != 5) { // 39-bit random value @@ -1515,7 +1312,7 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint AssertFatal(false, "not implemented\n"); } - ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value); + ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value, msg->gNB_DU_ue_id); } else if (NR_InitialUE_Identity_PR_ng_5G_S_TMSI_Part1 == rrcSetupRequest->ue_Identity.present) { /* TODO */ /* <5G-S-TMSI> = <5G-TMSI> 48-bit */ @@ -1534,20 +1331,14 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint if ((ue_context_p = rrc_gNB_ue_context_5g_s_tmsi_exist(gnb_rrc_inst, s_tmsi_part1))) { gNB_RRC_UE_t *UE = &ue_context_p->ue_context; LOG_I(NR_RRC, " 5G-S-TMSI-Part1 exists, old rnti %04x => %04x\n", UE->rnti, rnti); - - // TODO: MAC structures should not be accessed directly from the RRC! An implementation using the F1 interface should be developed. - if (!NODE_IS_CU(RC.nrrrc[0]->node_type)) { - nr_rrc_mac_remove_ue(ue_context_p->ue_context.rnti); - } else { - AssertFatal(false, "not implemented: need to switch RNTI in MAC via DL RRC Message Transfer\n"); - } + AssertFatal(false, "not implemented\n"); /* replace rnti in the context */ UE->rnti = rnti; } else { LOG_I(NR_RRC, "UE %04x 5G-S-TMSI-Part1 doesn't exist, setting ng_5G_S_TMSI_Part1 => %ld\n", rnti, s_tmsi_part1); - ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, s_tmsi_part1); + ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, s_tmsi_part1, msg->gNB_DU_ue_id); if (ue_context_p == NULL) { LOG_E(NR_RRC, "rrc_gNB_get_next_free_ue_context returned NULL\n"); return -1; @@ -1561,7 +1352,7 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint uint64_t random_value = 0; memcpy(((uint8_t *)&random_value) + 3, rrcSetupRequest->ue_Identity.choice.randomValue.buf, rrcSetupRequest->ue_Identity.choice.randomValue.size); - ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value); + ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value, msg->gNB_DU_ue_id); LOG_E(NR_RRC, "RRCSetupRequest without random UE identity or S-TMSI not supported, let's reject the UE %04x\n", rnti); rrc_gNB_generate_RRCReject(module_id, ue_context_p); break; @@ -1572,9 +1363,9 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint UE->Srb[1].Active = 1; rrc_gNB_generate_RRCSetup(module_id, rnti, - rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, rnti), - du_to_cu_rrc_container, - du_to_cu_rrc_container_len); + ue_context_p, + msg->du2cu_rrc_container, + msg->du2cu_rrc_container_length); } break; @@ -1583,86 +1374,81 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint break; case NR_UL_CCCH_MessageType__c1_PR_rrcReestablishmentRequest: { - LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)(buffer), buffer_length, "[MSG] RRC Reestablishment Request\n"); + LOG_DUMPMSG(NR_RRC, + DEBUG_RRC, + (char *)(msg->rrc_container), + msg->rrc_container_length, + "[MSG] RRC Reestablishment Request\n"); rrcReestablishmentRequest = ul_ccch_msg->message.choice.c1->choice.rrcReestablishmentRequest->rrcReestablishmentRequest; const NR_ReestablishmentCause_t cause = rrcReestablishmentRequest.reestablishmentCause; const long physCellId = rrcReestablishmentRequest.ue_Identity.physCellId; LOG_I(NR_RRC, - "UE %04x NR_RRCReestablishmentRequest cause %s\n", + "UE %04x physCellId %ld NR_RRCReestablishmentRequest cause %s\n", rnti, - ((cause == NR_ReestablishmentCause_otherFailure) ? "Other Failure" - : (cause == NR_ReestablishmentCause_handoverFailure) ? "Handover Failure" - : "reconfigurationFailure")); - uint8_t xid = -1; + physCellId, + cause == NR_ReestablishmentCause_otherFailure + ? "Other Failure" + : (cause == NR_ReestablishmentCause_handoverFailure ? "Handover Failure" : "reconfigurationFailure")); if (physCellId != gnb_rrc_inst->carrier.physCellId) { /* UE was moving from previous cell so quickly that RRCReestablishment for previous cell was received in this cell */ LOG_E(NR_RRC, " NR_RRCReestablishmentRequest ue_Identity.physCellId(%ld) is not equal to current physCellId(%ld), fallback to RRC establishment\n", physCellId, gnb_rrc_inst->carrier.physCellId); - xid = rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0); + /* 38.401 8.7: "If the UE accessed from a gNB-DU other than the + * original one, the gNB-CU should trigger the UE Context Setup + * procedure" we did not implement this yet; TBD for Multi-DU */ + AssertFatal(false, "not implemented\n"); break; } - LOG_I(NR_RRC, "physCellId: %ld\n", physCellId); - for (int i = 0; i < rrcReestablishmentRequest.ue_Identity.shortMAC_I.size; i++) { LOG_D(NR_RRC, "rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[%d] = %x\n", i, rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[i]); } - // 3GPP TS 38.321 version 15.13.0 Section 7.1 Table 7.1-1: RNTI values - if (rrcReestablishmentRequest.ue_Identity.c_RNTI < 0x1 || rrcReestablishmentRequest.ue_Identity.c_RNTI > 0xffef) { - /* c_RNTI range error should not happen */ - LOG_E(NR_RRC, "NR_RRCReestablishmentRequest c_RNTI range error, fallback to RRC establishment\n"); - xid = rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0); + rnti_t old_rnti = rrcReestablishmentRequest.ue_Identity.c_RNTI; + // TODO: we need to check within a specific DU! + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, old_rnti); + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + /* in case we need to do RRC Setup, give the UE a new random identity */ + uint64_t random_value; + fill_random(&random_value, sizeof(random_value)); + random_value = random_value & 0x7fffffffff; /* random value is 39 bits */ + if (ue_context_p == NULL) { + LOG_E(NR_RRC, "NR_RRCReestablishmentRequest without UE context, fallback to RRC setup\n"); + ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value, msg->gNB_DU_ue_id); + ue_context_p->ue_context.Srb[1].Active = 1; + rrc_gNB_generate_RRCSetup(module_id, rnti, ue_context_p, msg->du2cu_rrc_container, msg->du2cu_rrc_container_length); break; } - rnti_t c_rnti = rrcReestablishmentRequest.ue_Identity.c_RNTI; - LOG_I(NR_RRC, "c_RNTI: %04x\n", c_rnti); - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, c_rnti); - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - if (ue_context_p == NULL) { - LOG_E(NR_RRC, "NR_RRCReestablishmentRequest without UE context, fallback to RRC establishment\n"); - xid = rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, c_rnti, 0); - break; - } - // c-plane not end - if ((UE->StatusRrc != NR_RRC_RECONFIGURED) && (UE->reestablishment_cause == NR_ReestablishmentCause_spare1)) { - LOG_E(NR_RRC, "NR_RRCReestablishmentRequest (UE %x c-plane is not end), RRC establishment failed\n", c_rnti); - /* TODO RRC Release ? */ + // 3GPP TS 38.321 version 15.13.0 Section 7.1 Table 7.1-1: RNTI values + if (rrcReestablishmentRequest.ue_Identity.c_RNTI < 0x1 || rrcReestablishmentRequest.ue_Identity.c_RNTI > 0xffef) { + /* c_RNTI range error should not happen */ + LOG_E(NR_RRC, + "NR_RRCReestablishmentRequest c_RNTI %04lx range error, fallback to RRC setup\n", + rrcReestablishmentRequest.ue_Identity.c_RNTI); + ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value, msg->gNB_DU_ue_id); + ue_context_p->ue_context.Srb[1].Active = 1; + rrc_gNB_generate_RRCSetup(module_id, rnti, ue_context_p, msg->du2cu_rrc_container, msg->du2cu_rrc_container_length); break; } /* TODO: start timer in ITTI and drop UE if it does not come back */ - (void) xid; /* xid currently not used */ - // Insert C-RNTI to map - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &gnb_rrc_inst->nr_reestablish_rnti_map[i]; - LOG_I(NR_RRC, "Insert nr_reestablish_rnti_map[%d] UEid: %lx, RNTI: %04x\n", i, nr_reestablish_rnti_map->ue_id, nr_reestablish_rnti_map->c_rnti); - if (nr_reestablish_rnti_map->ue_id == 0) { - nr_reestablish_rnti_map->ue_id = rnti; - nr_reestablish_rnti_map->c_rnti = c_rnti; - LOG_W(NR_RRC, "Insert nr_reestablish_rnti_map[%d] UEid: %lx, RNTI: %04x bug in UEid to fix \n", i, nr_reestablish_rnti_map->ue_id, nr_reestablish_rnti_map->c_rnti); - break; - } - } + // update with new RNTI, and update secondary UE association + UE->rnti = rnti; + cu_remove_f1_ue_data(UE->rrc_ue_id); + f1_ue_data_t ue_data = {.secondary_ue = rnti}; + cu_add_f1_ue_data(UE->rrc_ue_id, &ue_data); UE->reestablishment_cause = cause; LOG_D(NR_RRC, "Accept RRCReestablishmentRequest from UE physCellId %ld cause %ld\n", physCellId, cause); - UE->primaryCC_id = 0; - // LG COMMENT Idx = (ue_mod_idP * NB_RB_MAX) + DCCH; - Idx = DCCH; - // SRB1 - UE->Srb[1].Active = 1; - // SRB2: set it to go through SRB1 with id 1 (DCCH) - UE->Srb[2].Active = 1; - protocol_ctxt_t ctxt = {.rntiMaybeUEid = rnti, .module_id = module_id, .instance = module_id, .enb_flag = 1, .eNB_index = module_id}; - rrc_gNB_generate_RRCReestablishment(&ctxt, ue_context_p, du_to_cu_rrc_container, gnb_rrc_inst->carrier.servingcellconfigcommon, 0); - - LOG_I(NR_RRC, "CALLING RLC CONFIG SRB1 (rbid %d)\n", Idx); + rrc_gNB_generate_RRCReestablishment(ue_context_p, + msg->du2cu_rrc_container, + gnb_rrc_inst->carrier.servingcellconfigcommon, + old_rnti); } break; case NR_UL_CCCH_MessageType__c1_PR_rrcSystemInfoRequest: @@ -1721,48 +1507,18 @@ static void rrc_gNB_process_MeasurementReport(rrc_gNB_ue_context_t *ue_context, } static int handle_rrcReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *ue_context_p, const NR_RRCReestablishmentComplete_t *reestablishment_complete) { - rnti_t reestablish_rnti = 0; - gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id]; - rrc_gNB_ue_context_t *ue_context_p = NULL; - gNB_RRC_UE_t *UE = NULL; - // Select C-RNTI from map - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &gnb_rrc_inst->nr_reestablish_rnti_map[i]; - LOG_I(NR_RRC, - "nr_reestablish_rnti_map[%d] UEid %lx, RNTI %04x, ctxt_pP->rntiMaybeUEid: %lx\n", - i, - nr_reestablish_rnti_map->ue_id, - nr_reestablish_rnti_map->c_rnti, - ctxt_pP->rntiMaybeUEid); - if (nr_reestablish_rnti_map->ue_id == ctxt_pP->rntiMaybeUEid) { - LOG_I(NR_RRC, - "Removing nr_reestablish_rnti_map[%d] UEid %lx, RNTI %04x\n", - i, - nr_reestablish_rnti_map->ue_id, - nr_reestablish_rnti_map->c_rnti); - reestablish_rnti = nr_reestablish_rnti_map->c_rnti; - ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, reestablish_rnti); - UE = &ue_context_p->ue_context; - break; - } - } - - if (ue_context_p == NULL || UE == NULL) { - LOG_E(RRC, "no UE found for reestablishment. ERROR: should send reply\n"); - return -1; - } + DevAssert(ue_context_p != NULL); + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; DevAssert(reestablishment_complete->criticalExtensions.present == NR_RRCReestablishmentComplete__criticalExtensions_PR_rrcReestablishmentComplete); rrc_gNB_process_RRCReestablishmentComplete(ctxt_pP, - reestablish_rnti, ue_context_p, reestablishment_complete->rrc_TransactionIdentifier); - nr_rrc_mac_remove_ue(reestablish_rnti); - UE->ue_reestablishment_counter++; return 0; } @@ -1954,18 +1710,21 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_ case RRC_DEFAULT_RECONF: rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p); break; + case RRC_REESTABLISH_COMPLETE: + /* do nothing */ + break; default: - LOG_E(RRC, "Received unexpected xid: %d\n", xid); + LOG_E(RRC, "Received unexpected transaction type %d for xid %d\n", UE->xids[xid], xid); successful_reconfig = false; break; } } gNB_RRC_INST *rrc = RC.nrrrc[0]; + f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id); f1ap_ue_context_modif_req_t ue_context_modif_req = { - .gNB_CU_ue_id = 0xffffffff, /* filled by F1 for the moment */ - .gNB_DU_ue_id = 0xffffffff, /* filled by F1 for the moment */ - .rnti = UE->rnti, + .gNB_CU_ue_id = UE->rrc_ue_id, + .gNB_DU_ue_id = ue_data.secondary_ue, .mcc = rrc->configuration.mcc[0], .mnc = rrc->configuration.mnc[0], .mnc_digit_length = rrc->configuration.mnc_digit_length[0], @@ -1984,6 +1743,13 @@ int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP, { gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id]; + /* we look up by CU UE ID! Do NOT change back to RNTI! */ + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rntiMaybeUEid); + if (!ue_context_p) { + LOG_E(RRC, "could not find UE context for CU UE ID %lu, aborting transaction\n", ctxt_pP->rntiMaybeUEid); + return -1; + } + if ((Srb_id != 1) && (Srb_id != 2)) { LOG_E(NR_RRC, "Received message on SRB%ld, should not have ...\n", Srb_id); } else { @@ -2011,8 +1777,6 @@ int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP, xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg); } - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, ctxt_pP->rntiMaybeUEid); - if (ul_dcch_msg->message.present == NR_UL_DCCH_MessageType_PR_c1) { switch (ul_dcch_msg->message.choice.c1->present) { case NR_UL_DCCH_MessageType__c1_PR_NOTHING: @@ -2104,7 +1868,7 @@ int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP, break; case NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete: - if (handle_rrcReestablishmentComplete(ctxt_pP, ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete) + if (handle_rrcReestablishmentComplete(ctxt_pP, ue_context_p, ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete) == -1) return -1; break; @@ -2222,7 +1986,7 @@ void rrc_gNB_process_initial_ul_rrc_message(const f1ap_initial_ul_rrc_message_t i = 0; LOG_W(RRC, "initial UL RRC message nr_cellid %ld does not match RRC's %ld\n", ul_rrc->nr_cellid, RC.nrrrc[0]->nr_cellid); } - nr_rrc_gNB_decode_ccch(i, ul_rrc->crnti, ul_rrc->rrc_container, ul_rrc->rrc_container_length, ul_rrc->du2cu_rrc_container, ul_rrc->du2cu_rrc_container_length); + nr_rrc_gNB_decode_ccch(i, ul_rrc); if (ul_rrc->rrc_container) free(ul_rrc->rrc_container); @@ -2246,7 +2010,11 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance { f1ap_ue_context_setup_t *resp = &F1AP_UE_CONTEXT_SETUP_RESP(msg_p); gNB_RRC_INST *rrc = RC.nrrrc[instance]; - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, resp->rnti); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, resp->gNB_CU_ue_id); + if (!ue_context_p) { + LOG_E(RRC, "could not find UE context for CU UE ID %u, aborting transaction\n", resp->gNB_CU_ue_id); + return; + } gNB_RRC_UE_t *UE = &ue_context_p->ue_context; NR_CellGroupConfig_t *cellGroupConfig = NULL; @@ -2275,10 +2043,14 @@ static void rrc_CU_process_ue_context_release_request(MessageDef *msg_p) const int instance = 0; f1ap_ue_context_release_req_t *req = &F1AP_UE_CONTEXT_RELEASE_REQ(msg_p); gNB_RRC_INST *rrc = RC.nrrrc[instance]; - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, req->rnti); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, req->gNB_CU_ue_id); + if (!ue_context_p) { + LOG_E(RRC, "could not find UE context for CU UE ID %u, aborting transaction\n", req->gNB_CU_ue_id); + return; + } /* TODO: marshall types correctly */ - LOG_I(NR_RRC, "received UE Context Release Request for UE %04x, forwarding to AMF\n", req->rnti); + LOG_I(NR_RRC, "received UE Context Release Request for UE %u, forwarding to AMF\n", req->gNB_CU_ue_id); rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(instance, ue_context_p, NGAP_CAUSE_RADIO_NETWORK, @@ -2290,29 +2062,37 @@ static void rrc_CU_process_ue_context_release_complete(MessageDef *msg_p) const int instance = 0; f1ap_ue_context_release_complete_t *complete = &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_p); gNB_RRC_INST *rrc = RC.nrrrc[instance]; - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, complete->rnti); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, complete->gNB_CU_ue_id); + if (!ue_context_p) { + LOG_E(RRC, "could not find UE context for CU UE ID %u, aborting transaction\n", complete->gNB_CU_ue_id); + return; + } gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - nr_pdcp_remove_UE(UE->rnti); - newGtpuDeleteAllTunnels(instance, UE->rnti); - rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance, UE->gNB_ue_ngap_id); - LOG_I(NR_RRC, "removed UE %04x \n", UE->rnti); + nr_pdcp_remove_UE(UE->rrc_ue_id); + newGtpuDeleteAllTunnels(instance, UE->rrc_ue_id); + rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance, UE->rrc_ue_id); + LOG_I(NR_RRC, "removed UE CU UE ID %u/RNTI %04x \n", UE->rrc_ue_id, UE->rnti); rrc_gNB_remove_ue_context(rrc, ue_context_p); } static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, instance_t instance) { f1ap_ue_context_modif_resp_t *resp = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg_p); - protocol_ctxt_t ctxt = {.rntiMaybeUEid = resp->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance}; + protocol_ctxt_t ctxt = {.rntiMaybeUEid = resp->gNB_CU_ue_id, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance}; gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, resp->rnti); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, resp->gNB_CU_ue_id); + if (!ue_context_p) { + LOG_E(RRC, "could not find UE context for CU UE ID %u, aborting transaction\n", resp->gNB_CU_ue_id); + return; + } gNB_RRC_UE_t *UE = &ue_context_p->ue_context; if (resp->drbs_to_be_setup_length > 0) { e1ap_bearer_setup_req_t req = {0}; req.numPDUSessionsMod = UE->nb_of_pdusessions; - req.gNB_cu_cp_ue_id = UE->gNB_ue_ngap_id; - req.rnti = UE->rnti; + req.gNB_cu_cp_ue_id = UE->rrc_ue_id; + req.gNB_cu_up_ue_id = UE->rrc_ue_id; for (int i = 0; i < req.numPDUSessionsMod; i++) { req.pduSessionMod[i].numDRB2Modify = resp->drbs_to_be_setup_length; for (int j = 0; j < resp->drbs_to_be_setup_length; j++) { @@ -2561,10 +2341,10 @@ void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_contex srbs[0].lcid = 2; } + f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id); f1ap_ue_context_modif_req_t ue_context_modif_req = { - .gNB_CU_ue_id = 0xffffffff, /* filled by F1 for the moment */ - .gNB_DU_ue_id = 0xffffffff, /* filled by F1 for the moment */ - .rnti = UE->rnti, + .gNB_CU_ue_id = UE->rrc_ue_id, + .gNB_DU_ue_id = ue_data.secondary_ue, .mcc = rrc->configuration.mcc[0], .mnc = rrc->configuration.mnc[0], .mnc_digit_length = rrc->configuration.mnc_digit_length[0], @@ -2582,9 +2362,16 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp // Find the UE context from UE ID and send ITTI message to F1AP to send UE context modification message to DU rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], resp->gNB_cu_cp_ue_id); - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + AssertFatal(ue_context_p != NULL, "did not find UE with CU UE ID %d\n", resp->gNB_cu_cp_ue_id); protocol_ctxt_t ctxt = {0}; - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, resp->gNB_cu_cp_ue_id, 0, 0, 0); + + // currently: we don't have "infrastructure" to save the CU-UP UE ID, so we + // assume (and below check) that CU-UP UE ID == CU-CP UE ID + AssertFatal(resp->gNB_cu_cp_ue_id == resp->gNB_cu_up_ue_id, + "cannot handle CU-UP UE ID different from CU-CP UE ID (%d vs %d)\n", + resp->gNB_cu_cp_ue_id, + resp->gNB_cu_up_ue_id); gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0}; create_tunnel_resp.num_tunnels = resp->numPDUSessions; @@ -2624,6 +2411,36 @@ static void print_rrc_meas(FILE *f, const NR_MeasResults_t *measresults) } } +static const char *get_rrc_connection_status_text(NR_UE_STATE_t state) +{ + switch (state) { + case NR_RRC_INACTIVE: return "inactive"; + case NR_RRC_IDLE: return "idle"; + case NR_RRC_SI_RECEIVED: return "SI-received"; + case NR_RRC_CONNECTED: return "connected"; + case NR_RRC_RECONFIGURED: return "reconfigured"; + case NR_RRC_HO_EXECUTION: return "HO-execution"; + default: AssertFatal(false, "illegal RRC state %d\n", state); return "illegal"; + } + return "illegal"; +} + +static const char *get_pdusession_status_text(pdu_session_status_t status) +{ + switch (status) { + case PDU_SESSION_STATUS_NEW: return "new"; + case PDU_SESSION_STATUS_DONE: return "done"; + case PDU_SESSION_STATUS_ESTABLISHED: return "established"; + case PDU_SESSION_STATUS_REESTABLISHED: return "reestablished"; + case PDU_SESSION_STATUS_TOMODIFY: return "to-modify"; + case PDU_SESSION_STATUS_FAILED: return "failed"; + case PDU_SESSION_STATUS_TORELEASE: return "to-release"; + case PDU_SESSION_STATUS_RELEASED: return "released"; + default: AssertFatal(false, "illegal PDU status code %d\n", status); return "illegal"; + } + return "illegal"; +} + static void write_rrc_stats(const gNB_RRC_INST *rrc) { const char *filename = "nrRRC_stats.log"; @@ -2633,19 +2450,33 @@ static void write_rrc_stats(const gNB_RRC_INST *rrc) return; } + int i = 0; rrc_gNB_ue_context_t *ue_context_p = NULL; /* cast is necessary to eliminate warning "discards ‘const’ qualifier" */ RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &((gNB_RRC_INST *)rrc)->rrc_ue_head) { const gNB_RRC_UE_t *ue_ctxt = &ue_context_p->ue_context; - const rnti_t rnti = ue_ctxt->rnti; - - fprintf(f, "NR RRC UE rnti %04x:", rnti); + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_ctxt->rrc_ue_id); + fprintf(f, + "UE %d CU UE ID %d DU UE ID %d RNTI %04x random identity %016lx", + i, + ue_ctxt->rrc_ue_id, + ue_data.secondary_ue, + ue_ctxt->rnti, + ue_ctxt->random_ue_identity); if (ue_ctxt->Initialue_identity_5g_s_TMSI.presence) fprintf(f, " S-TMSI %x", ue_ctxt->Initialue_identity_5g_s_TMSI.fiveg_tmsi); + fprintf(f, ":\n"); - fprintf(f, "\n"); + fprintf(f, " RRC status %s\n", get_rrc_connection_status_text(ue_ctxt->StatusRrc)); + + if (ue_ctxt->nb_of_pdusessions == 0) + fprintf(f, " (no PDU sessions)\n"); + for (int nb_pdu = 0; nb_pdu < ue_ctxt->nb_of_pdusessions; ++nb_pdu) { + const rrc_pdu_session_param_t *pdu = &ue_ctxt->pduSession[nb_pdu]; + fprintf(f, " PDU session %d ID %d status %s\n", nb_pdu, pdu->param.pdusession_id, get_pdusession_status_text(pdu->status)); + } if (ue_ctxt->UE_Capability_nr) { fprintf(f, @@ -2659,6 +2490,7 @@ static void write_rrc_stats(const gNB_RRC_INST *rrc) if (ue_ctxt->measResults) print_rrc_meas(f, ue_ctxt->measResults); + ++i; } fclose(f); @@ -2714,7 +2546,7 @@ void *rrc_gnb_task(void *args_p) { PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, - F1AP_UL_RRC_MESSAGE(msg_p).rnti, + F1AP_UL_RRC_MESSAGE(msg_p).gNB_CU_ue_id, 0, 0); LOG_D(NR_RRC, @@ -2827,25 +2659,17 @@ void *rrc_gnb_task(void *args_p) { } } +typedef struct deliver_ue_ctxt_setup_data_t { + gNB_RRC_INST *rrc; + f1ap_ue_context_setup_t *setup_req; +} deliver_ue_ctxt_setup_data_t; static void rrc_deliver_ue_ctxt_setup_req(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, char *buf, int size, int sdu_id) { DevAssert(deliver_pdu_data != NULL); - gNB_RRC_INST *rrc = deliver_pdu_data; - f1ap_ue_context_setup_t ue_context_setup_req = { - .gNB_CU_ue_id = 0xffffffff, /* filled by F1 for the moment */ - .gNB_DU_ue_id = 0xffffffff, /* filled by F1 for the moment */ - .rnti = ue_id, - .mcc = rrc->configuration.mcc[0], - .mnc = rrc->configuration.mnc[0], - .mnc_digit_length = rrc->configuration.mnc_digit_length[0], - .nr_cellid = rrc->nr_cellid, - .servCellId = 0, /* TODO: correct value? */ - .srbs_to_be_setup = 0, /* no new SRBs */ - .drbs_to_be_setup = 0, /* no new DRBs */ - .rrc_container = (uint8_t*) buf, /* security mode command */ - .rrc_container_length = size, - }; - rrc->mac_rrc.ue_context_setup_request(&ue_context_setup_req); + deliver_ue_ctxt_setup_data_t *data = deliver_pdu_data; + data->setup_req->rrc_container = (uint8_t*)buf; + data->setup_req->rrc_container_length = size; + data->rrc->mac_rrc.ue_context_setup_request(data->setup_req); } //----------------------------------------------------------------------------- @@ -2870,7 +2694,20 @@ rrc_gNB_generate_SecurityModeCommand( AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n"); /* the callback will fill the UE context setup request and forward it */ - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_setup_req, rrc); + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); + f1ap_ue_context_setup_t ue_context_setup_req = { + .gNB_CU_ue_id = ue_p->rrc_ue_id, + .gNB_DU_ue_id = ue_data.secondary_ue, + .mcc = rrc->configuration.mcc[0], + .mnc = rrc->configuration.mnc[0], + .mnc_digit_length = rrc->configuration.mnc_digit_length[0], + .nr_cellid = rrc->nr_cellid, + .servCellId = 0, /* TODO: correct value? */ + .srbs_to_be_setup = 0, /* no new SRBs */ + .drbs_to_be_setup = 0, /* no new DRBs */ + }; + deliver_ue_ctxt_setup_data_t data = {.rrc = rrc, .setup_req = &ue_context_setup_req}; + nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_setup_req, &data); } void @@ -2896,25 +2733,21 @@ rrc_gNB_generate_UECapabilityEnquiry( gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n"); - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc); + const gNB_RRC_UE_t *ue = &ue_context_pP->ue_context; + nr_rrc_transfer_protected_rrc_message(rrc, ue, DCCH, buffer, size); } +typedef struct deliver_ue_ctxt_release_data_t { + gNB_RRC_INST *rrc; + f1ap_ue_context_release_cmd_t *release_cmd; +} deliver_ue_ctxt_release_data_t; static void rrc_deliver_ue_ctxt_release_cmd(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, char *buf, int size, int sdu_id) { DevAssert(deliver_pdu_data != NULL); - gNB_RRC_INST *rrc = deliver_pdu_data; - uint8_t *rrc_container = malloc(size); - AssertFatal(rrc_container != NULL, "out of memory\n"); - memcpy(rrc_container, buf, size); - f1ap_ue_context_release_cmd_t ue_context_release_cmd = { - .rnti = ue_id, /* TODO: proper IDs! */ - .cause = F1AP_CAUSE_RADIO_NETWORK, - .cause_value = 10, // 10 = F1AP_CauseRadioNetwork_normal_release - .srb_id = srb_id, - .rrc_container = rrc_container, - .rrc_container_length = size, - }; - rrc->mac_rrc.ue_context_release_command(&ue_context_release_cmd); + deliver_ue_ctxt_release_data_t *data = deliver_pdu_data; + data->release_cmd->rrc_container = (uint8_t*) buf; + data->release_cmd->rrc_container_length = size; + data->rrc->mac_rrc.ue_context_release_command(data->release_cmd); } //----------------------------------------------------------------------------- @@ -2938,7 +2771,17 @@ rrc_gNB_generate_RRCRelease( size); gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_release_cmd, rrc); + const gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; + f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id); + f1ap_ue_context_release_cmd_t ue_context_release_cmd = { + .gNB_CU_ue_id = UE->rrc_ue_id, + .gNB_DU_ue_id = ue_data.secondary_ue, + .cause = F1AP_CAUSE_RADIO_NETWORK, + .cause_value = 10, // 10 = F1AP_CauseRadioNetwork_normal_release + .srb_id = DCCH, + }; + deliver_ue_ctxt_release_data_t data = {.rrc = rrc, .release_cmd = &ue_context_release_cmd}; + nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_release_cmd, &data); /* UE will be freed after UE context release complete */ } diff --git a/openair2/RRC/NR/rrc_gNB_GTPV1U.c b/openair2/RRC/NR/rrc_gNB_GTPV1U.c index e7bbe5835e..3ef3e62d51 100644 --- a/openair2/RRC/NR/rrc_gNB_GTPV1U.c +++ b/openair2/RRC/NR/rrc_gNB_GTPV1U.c @@ -52,7 +52,8 @@ int rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ctxt_ } LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT " RX CREATE_TUNNEL_RESP num tunnels %u \n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), create_tunnel_resp_pP->num_tunnels); - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid); + /* we look up by CU UE ID! Do NOT change back to RNTI! */ + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid); if (!ue_context_p) { LOG_E(NR_RRC, "UE table error\n"); return -1; @@ -83,7 +84,8 @@ int nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ct } LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT " RX CREATE_TUNNEL_RESP num tunnels %u \n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), create_tunnel_resp_pP->num_tunnels); - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid); + /* we look up by CU UE ID! Do NOT change back to RNTI! */ + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid); if (!ue_context_p) { LOG_E(NR_RRC, "UE table error\n"); return -1; diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index f0a7f3b90f..8a9a08abd7 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -58,6 +58,7 @@ #include "NR_UE-CapabilityRAT-ContainerList.h" #include "NGAP_CauseRadioNetwork.h" #include "f1ap_messages_types.h" +#include "openair2/F1AP/f1ap_ids.h" #include "openair2/E1AP/e1ap_asnc.h" #include "NGAP_asn_constant.h" #include "NGAP_PDUSessionResourceSetupRequestTransfer.h" @@ -182,7 +183,7 @@ rrc_gNB_send_NGAP_NAS_FIRST_REQ( ngap_nas_first_req_t *req = &NGAP_NAS_FIRST_REQ(message_p); memset(req, 0, sizeof(*req)); - req->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; + req->gNB_ue_ngap_id = UE->rrc_ue_id; /* Assume that cause is coded in the same way in RRC and NGap, just check that the value is in NGap range */ AssertFatal(UE->establishment_cause < NGAP_RRC_CAUSE_LAST, "Establishment cause invalid (%jd/%d) for gNB %d!", UE->establishment_cause, NGAP_RRC_CAUSE_LAST, ctxt_pP->module_id); @@ -370,7 +371,7 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t itti_send_msg_to_task(TASK_NGAP, instance, msg_fail_p); return (-1); } - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0); + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0); UE->amf_ue_ngap_id = req->amf_ue_ngap_id; uint8_t nb_pdusessions_tosetup = req->nb_of_pdusessions; if (nb_pdusessions_tosetup) { @@ -391,7 +392,7 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t memcpy(create_tunnel_req.dst_addr[i].buffer, req->pdusession_param[i].upf_addr.buffer, sizeof(create_tunnel_req.dst_addr[i].buffer)); LOG_I(NR_RRC, "PDUSESSION SETUP: local index %d teid %u, pdusession id %d \n", i, create_tunnel_req.outgoing_teid[i], create_tunnel_req.pdusession_id[i]); } - create_tunnel_req.ue_id = UE->rnti; + create_tunnel_req.ue_id = UE->rrc_ue_id; gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp = {0}; int ret = gtpv1u_create_ngu_tunnel(instance, &create_tunnel_req, &create_tunnel_resp, nr_pdcp_data_req_drb, sdap_data_req); if (ret != 0) { @@ -436,7 +437,7 @@ void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(const protocol_ctxt_t *const c ngap_initial_context_setup_resp_t *resp = &NGAP_INITIAL_CONTEXT_SETUP_RESP(msg_p); gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; - resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; + resp->gNB_ue_ngap_id = UE->rrc_ue_id; for (int pdusession = 0; pdusession < UE->nb_of_pdusessions; pdusession++) { rrc_pdu_session_param_t *session = &UE->pduSession[pdusession]; @@ -607,7 +608,7 @@ int rrc_gNB_process_NGAP_DOWNLINK_NAS(MessageDef *msg_p, instance_t instance, mu } gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0); + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0); /* Create message for PDCP (DLInformationTransfer_t) */ length = do_NR_DLInformationTransfer(instance, &buffer, rrc_gNB_get_next_transaction_identifier(instance), req->nas_pdu.length, req->nas_pdu.buffer); @@ -618,7 +619,7 @@ int rrc_gNB_process_NGAP_DOWNLINK_NAS(MessageDef *msg_p, instance_t instance, mu AssertFatal(!NODE_IS_DU(RC.nrrrc[ctxt.module_id]->node_type), "illegal node type DU: receiving NGAP messages at this node\n"); /* Transfer data to PDCP */ rb_id_t srb_id = UE->Srb[2].Active ? DCCH1 : DCCH; - nr_pdcp_data_req_srb(ctxt.rntiMaybeUEid, srb_id, (*rrc_gNB_mui)++, length, buffer, deliver_pdu_srb_f1, RC.nrrrc[instance]); + nr_rrc_transfer_protected_rrc_message(RC.nrrrc[instance], UE, srb_id, buffer, length); return 0; } @@ -641,7 +642,7 @@ rrc_gNB_send_NGAP_UPLINK_NAS( pdu_length = ulInformationTransfer->criticalExtensions.choice.ulInformationTransfer->dedicatedNAS_Message->size; pdu_buffer = ulInformationTransfer->criticalExtensions.choice.ulInformationTransfer->dedicatedNAS_Message->buf; msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_UPLINK_NAS); - NGAP_UPLINK_NAS(msg_p).gNB_ue_ngap_id = UE->gNB_ue_ngap_id; + NGAP_UPLINK_NAS(msg_p).gNB_ue_ngap_id = UE->rrc_ue_id; NGAP_UPLINK_NAS (msg_p).nas_pdu.length = pdu_length; NGAP_UPLINK_NAS (msg_p).nas_pdu.buffer = pdu_buffer; // extract_imsi(NGAP_UPLINK_NAS (msg_p).nas_pdu.buffer, @@ -668,7 +669,7 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP( msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_PDUSESSION_SETUP_RESP); ngap_pdusession_setup_resp_t *resp = &NGAP_PDUSESSION_SETUP_RESP(msg_p); gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; - resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; + resp->gNB_ue_ngap_id = UE->rrc_ue_id; for (int pdusession = 0; pdusession < UE->nb_of_pdusessions; pdusession++) { rrc_pdu_session_param_t *session = &UE->pduSession[pdusession]; @@ -745,7 +746,7 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins return ; } - UE->gNB_ue_ngap_id = msg->gNB_ue_ngap_id; + UE->rrc_ue_id = msg->gNB_ue_ngap_id; UE->amf_ue_ngap_id = msg->amf_ue_ngap_id; e1ap_bearer_setup_req_t bearer_req = {0}; @@ -759,7 +760,6 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins session->pdusessionTransfer = msg->pdusession_setup_params[i].pdusessionTransfer; decodePDUSessionResourceSetup(session); bearer_req.gNB_cu_cp_ue_id = msg->gNB_ue_ngap_id; - bearer_req.rnti = UE->rnti; bearer_req.cipheringAlgorithm = UE->ciphering_algorithm; bearer_req.integrityProtectionAlgorithm = UE->integrity_algorithm; nr_derive_key(UP_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, (uint8_t *)bearer_req.encryptionKey); @@ -925,7 +925,7 @@ int rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(MessageDef *msg_p, instance_t ins return (-1); } gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0); + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0); ctxt.eNB_index = 0; bool all_failed = true; for (int i = 0; i < req->nb_pdusessions_tomodify; i++) { @@ -1009,7 +1009,7 @@ rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP( ngap_pdusession_modify_resp_t *resp = &NGAP_PDUSESSION_MODIFY_RESP(msg_p); LOG_I(NR_RRC, "send message NGAP_PDUSESSION_MODIFY_RESP \n"); - resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; + resp->gNB_ue_ngap_id = UE->rrc_ue_id; for (int i = 0; i < UE->nb_of_pdusessions; i++) { if (xid != UE->pduSession[i].xid) { @@ -1087,7 +1087,7 @@ void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(const module_id_t gnb_mod_idP, con MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_REQ); ngap_ue_release_req_t *req = &NGAP_UE_CONTEXT_RELEASE_REQ(msg); memset(req, 0, sizeof(*req)); - req->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; + req->gNB_ue_ngap_id = UE->rrc_ue_id; req->cause = causeP; req->cause_value = cause_valueP; for (int i = 0; i < UE->nb_of_pdusessions; i++) { @@ -1152,7 +1152,7 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_ } gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0); + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0); ctxt.eNB_index = 0; rrc_gNB_generate_RRCRelease(&ctxt, ue_context_p); return 0; @@ -1202,7 +1202,7 @@ void rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(const protocol_ctxt_t *const ctxt_pP, msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_UE_CAPABILITIES_IND); ngap_ue_cap_info_ind_t *ind = &NGAP_UE_CAPABILITIES_IND(msg_p); memset(ind, 0, sizeof(*ind)); - ind->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; + ind->gNB_ue_ngap_id = UE->rrc_ue_id; ind->ue_radio_cap.length = encoded; ind->ue_radio_cap.buffer = buf2; itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p); @@ -1224,7 +1224,7 @@ rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE( msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_PDUSESSION_RELEASE_RESPONSE); ngap_pdusession_release_resp_t *resp = &NGAP_PDUSESSION_RELEASE_RESPONSE(msg_p); memset(resp, 0, sizeof(*resp)); - resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id; + resp->gNB_ue_ngap_id = UE->rrc_ue_id; for (int i = 0; i < UE->nb_of_pdusessions; i++) { if (xid == UE->pduSession[i].xid) { @@ -1239,7 +1239,7 @@ rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE( resp->nb_of_pdusessions_released = pdu_sessions_released; resp->nb_of_pdusessions_failed = 0; - LOG_I(NR_RRC, "NGAP PDUSESSION RELEASE RESPONSE: GNB_UE_NGAP_ID %u release_pdu_sessions %d\n", resp->gNB_ue_ngap_id, pdu_sessions_released); + LOG_I(NR_RRC, "NGAP PDUSESSION RELEASE RESPONSE: rrc_ue_id %u release_pdu_sessions %d\n", resp->gNB_ue_ngap_id, pdu_sessions_released); itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p); } @@ -1264,9 +1264,9 @@ int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_ LOG_I(NR_RRC, "[gNB %ld] gNB_ue_ngap_id %u \n", instance, gNB_ue_ngap_id); gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0); + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0); LOG_I( - NR_RRC, "PDU Session Release Command: AMF_UE_NGAP_ID %lu GNB_UE_NGAP_ID %u release_pdusessions %d \n", cmd->amf_ue_ngap_id, gNB_ue_ngap_id, cmd->nb_pdusessions_torelease); + NR_RRC, "PDU Session Release Command: AMF_UE_NGAP_ID %lu rrc_ue_id %u release_pdusessions %d \n", cmd->amf_ue_ngap_id, gNB_ue_ngap_id, cmd->nb_pdusessions_torelease); bool found = false; uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt.module_id); UE->xids[xid] = RRC_PDUSESSION_RELEASE; diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c index 2d2742aa4a..8a8c0bdd2e 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.c +++ b/openair2/RRC/NR/rrc_gNB_UE_context.c @@ -35,17 +35,18 @@ #include "common/utils/LOG/log.h" #include "rrc_gNB_UE_context.h" +#include "openair2/F1AP/f1ap_ids.h" //------------------------------------------------------------------------------ int rrc_gNB_compare_ue_rnti_id(rrc_gNB_ue_context_t *c1_pP, rrc_gNB_ue_context_t *c2_pP) //------------------------------------------------------------------------------ { - if (c1_pP->ue_context.gNB_ue_ngap_id > c2_pP->ue_context.gNB_ue_ngap_id) { + if (c1_pP->ue_context.rrc_ue_id > c2_pP->ue_context.rrc_ue_id) { return 1; } - if (c1_pP->ue_context.gNB_ue_ngap_id < c2_pP->ue_context.gNB_ue_ngap_id) { + if (c1_pP->ue_context.rrc_ue_id < c2_pP->ue_context.rrc_ue_id) { return -1; } @@ -66,12 +67,12 @@ rrc_gNB_ue_context_t *rrc_gNB_allocate_new_ue_context(gNB_RRC_INST *rrc_instance LOG_E(NR_RRC, "Cannot allocate new ue context\n"); return NULL; } - new_p->ue_context.gNB_ue_ngap_id = uid_linear_allocator_new(&rrc_instance_pP->uid_allocator); + new_p->ue_context.rrc_ue_id = uid_linear_allocator_new(&rrc_instance_pP->uid_allocator) + 1; for(int i = 0; i < NB_RB_MAX; i++) new_p->ue_context.pduSession[i].xid = -1; - LOG_I(NR_RRC, "Returning new RRC UE context RRC ue id: %d\n", new_p->ue_context.gNB_ue_ngap_id); + LOG_I(NR_RRC, "Returning new RRC UE context RRC ue id: %d\n", new_p->ue_context.rrc_ue_id); return(new_p); } @@ -82,7 +83,7 @@ rrc_gNB_ue_context_t *rrc_gNB_get_ue_context(gNB_RRC_INST *rrc_instance_pP, ue_i { rrc_gNB_ue_context_t temp; /* gNB ue rrc id = 24 bits wide */ - temp.ue_context.gNB_ue_ngap_id = ue; + temp.ue_context.rrc_ue_id = ue; return RB_FIND(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, &temp); } @@ -120,7 +121,8 @@ void rrc_gNB_remove_ue_context(gNB_RRC_INST *rrc_instance_pP, rrc_gNB_ue_context } RB_REMOVE(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_pP); - uid_linear_allocator_free(&rrc_instance_pP->uid_allocator, ue_context_pP->ue_context.gNB_ue_ngap_id); + uid_linear_allocator_free(&rrc_instance_pP->uid_allocator, ue_context_pP->ue_context.rrc_ue_id - 1); + cu_remove_f1_ue_data(ue_context_pP->ue_context.rrc_ue_id); rrc_gNB_free_mem_ue_context(ue_context_pP); LOG_I(NR_RRC, "Removed UE context\n"); } @@ -153,35 +155,33 @@ rrc_gNB_ue_context_t *rrc_gNB_ue_context_5g_s_tmsi_exist(gNB_RRC_INST *rrc_insta return NULL; } -void rrc_gNB_update_ue_context_rnti(rnti_t rnti, gNB_RRC_INST *rrc_instance_pP, uint32_t gNB_ue_ngap_id) -{ - // rnti will need to be a fast access key, with indexing, today it is sequential search - // This function will update the index when it will be made - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc_instance_pP, gNB_ue_ngap_id); - if (ue_context_p) - ue_context_p->ue_context.rnti = rnti; - else - LOG_E(NR_RRC, "update rnti on a wrong UE id\n"); -} //----------------------------------------------------------------------------- // return a new ue context structure if ue_identityP, rnti not found in collection -rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(rnti_t rnti, gNB_RRC_INST *rrc_instance_pP, const uint64_t ue_identityP) +rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(rnti_t rnti, + gNB_RRC_INST *rrc_instance_pP, + const uint64_t ue_identityP, + uint32_t du_ue_id) //----------------------------------------------------------------------------- { - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc_instance_pP, rnti); - - if (ue_context_p) { - LOG_E(NR_RRC, "Cannot create new UE context, already exist rnti: %04x\n", rnti); - return ue_context_p; - } - - ue_context_p = rrc_gNB_allocate_new_ue_context(rrc_instance_pP); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_allocate_new_ue_context(rrc_instance_pP); if (ue_context_p == NULL) return NULL; - ue_context_p->ue_context.rnti = rnti; - ue_context_p->ue_context.random_ue_identity = ue_identityP; + gNB_RRC_UE_t *ue = &ue_context_p->ue_context; + ue->rnti = rnti; + ue->random_ue_identity = ue_identityP; + f1_ue_data_t ue_data = {.secondary_ue = du_ue_id}; + AssertFatal(!cu_exists_f1_ue_data(ue->rrc_ue_id), + "UE F1 Context for ID %d already exists, logic bug\n", + ue->rrc_ue_id); + cu_add_f1_ue_data(ue->rrc_ue_id, &ue_data); + RB_INSERT(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_p); - LOG_W(NR_RRC, " Created new UE context rnti: %04x, random ue id %lx, RRC ue id %u\n", rnti, ue_identityP, ue_context_p->ue_context.gNB_ue_ngap_id); + LOG_I(NR_RRC, + "Created new UE context: CU UE ID %u DU UE ID %u (rnti: %04x, random ue id %lx)\n", + ue->rrc_ue_id, + du_ue_id, + ue->rnti, + ue->random_ue_identity); return ue_context_p; } diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.h b/openair2/RRC/NR/rrc_gNB_UE_context.h index 9c1ec2c164..3ec0852af6 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.h +++ b/openair2/RRC/NR/rrc_gNB_UE_context.h @@ -50,7 +50,9 @@ void rrc_gNB_remove_ue_context(gNB_RRC_INST* rrc_instance_pP, rrc_gNB_ue_context rrc_gNB_ue_context_t* rrc_gNB_ue_context_random_exist(gNB_RRC_INST* rrc_instance_pP, const uint64_t ue_identityP); rrc_gNB_ue_context_t* rrc_gNB_ue_context_5g_s_tmsi_exist(gNB_RRC_INST* rrc_instance_pP, const uint64_t s_TMSI); -void rrc_gNB_update_ue_context_rnti(rnti_t rnti, gNB_RRC_INST* rrc_instance_pP, uint32_t gNB_ue_ngap_id); -rrc_gNB_ue_context_t* rrc_gNB_create_ue_context(rnti_t rnti, gNB_RRC_INST* rrc_instance_pP, const uint64_t ue_identityP); +rrc_gNB_ue_context_t* rrc_gNB_create_ue_context(rnti_t rnti, + gNB_RRC_INST* rrc_instance_pP, + const uint64_t ue_identityP, + uint32_t du_ue_id); #endif diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 656c7d0663..f0d89051df 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -41,6 +41,7 @@ #include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" #include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h" +#include "openair2/F1AP/f1ap_ids.h" #include "executables/softmodem-common.h" #include "executables/nr-softmodem.h" #include @@ -248,14 +249,11 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a 1, 1, configuration, - ue_context_p->ue_context.gNB_ue_ngap_id); + ue_context_p->ue_context.rrc_ue_id); AssertFatal(UE->secondaryCellGroup != NULL, "out of memory\n"); xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, UE->secondaryCellGroup); - fill_default_reconfig(carrier->servingcellconfigcommon, scc, reconfig_ies, UE->secondaryCellGroup, UE->UE_Capability_nr, configuration, ue_context_p->ue_context.gNB_ue_ngap_id); - // the UE context is not yet inserted in the RRC UE manager - // rrc_gNB_update_ue_context_rnti(UE->secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity, rrc, - // UE->gNB_ue_ngap_id); + fill_default_reconfig(carrier->servingcellconfigcommon, scc, reconfig_ies, UE->secondaryCellGroup, UE->UE_Capability_nr, configuration, ue_context_p->ue_context.rrc_ue_id); UE->rnti = UE->secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity; NR_CG_Config_t *CG_Config = calloc(1,sizeof(*CG_Config)); memset((void *)CG_Config,0,sizeof(*CG_Config)); @@ -288,7 +286,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a create_tunnel_req.sgw_S1u_teid[i]); } - create_tunnel_req.rnti = ue_context_p->ue_context.rnti; + create_tunnel_req.rnti = ue_context_p->ue_context.rrc_ue_id; create_tunnel_req.num_tunnels = m->nb_e_rabs_tobeadded; RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[rrc->module_id]->rrc_ue_head, ue_context_p); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, rrc->module_id); @@ -343,20 +341,31 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(0), msg); //Check right id instead of hardcoding } + // below we configure the stack. In SA, we fully adopted F1, meaning that + // layers use different IDs (MAC/RLC use RNTI as DU UE ID, above use NGAP ID + // as CU UE ID. + uint32_t du_ue_id = ue_context_p->ue_context.rnti; + static uint32_t rrc_ue_id = 0; + rrc_ue_id++; + f1_ue_data_t du_ue_data = {.secondary_ue = rrc_ue_id}; + du_add_f1_ue_data(du_ue_id, &du_ue_data); + f1_ue_data_t cu_ue_data = {.secondary_ue = du_ue_id}; + cu_add_f1_ue_data(rrc_ue_id, &cu_ue_data); + LOG_I(RRC, "Assign CU UE ID %d and DU UE ID %d to UE RNTI %04x\n", rrc_ue_id, du_ue_id, ue_context_p->ue_context.rnti); + // configure MAC and RLC bool ret = false; if (get_softmodem_params()->phy_test) { // phytest mode: we don't set up RA, etc - ret = nr_mac_add_test_ue(RC.nrmac[rrc->module_id] , ue_context_p->ue_context.rnti, ue_context_p->ue_context.secondaryCellGroup); + ret = nr_mac_add_test_ue(RC.nrmac[rrc->module_id], du_ue_id, ue_context_p->ue_context.secondaryCellGroup); } else { NR_SCHED_LOCK(&RC.nrmac[rrc->module_id]->sched_lock); - ret = nr_mac_prepare_ra_ue(RC.nrmac[rrc->module_id], ue_context_p->ue_context.rnti, ue_context_p->ue_context.secondaryCellGroup); + ret = nr_mac_prepare_ra_ue(RC.nrmac[rrc->module_id], du_ue_id, ue_context_p->ue_context.secondaryCellGroup); NR_SCHED_UNLOCK(&RC.nrmac[rrc->module_id]->sched_lock); } AssertFatal(ret, "cannot add NSA UE in MAC, aborting\n"); - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, rrc->module_id); - if (get_softmodem_params()->do_ra) ctxt.enb_flag = 0; + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, rrc_ue_id, 0, 0, rrc->module_id); LOG_W(RRC, "Calling RRC PDCP/RLC ASN1 request functions for protocol context %p with module_id %d, rnti %lx, frame %d, subframe %d eNB_index %d \n", &ctxt, @@ -367,14 +376,14 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a ctxt.eNB_index); nr_pdcp_add_drbs(ctxt.enb_flag, - ctxt.rntiMaybeUEid, - 0, + rrc_ue_id, ue_context_p->ue_context.rb_config->drb_ToAddModList, (ue_context_p->ue_context.integrity_algorithm << 4) | ue_context_p->ue_context.ciphering_algorithm, kUPenc, kUPint, ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList); + ctxt.rntiMaybeUEid = du_ue_id; // assume only a single bearer const NR_DRB_ToAddModList_t *drb_list = ue_context_p->ue_context.rb_config->drb_ToAddModList; DevAssert(drb_list->list.count == 1); diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 01a0178b62..73c3fa1593 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1675,7 +1675,6 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP, // Refresh DRBs nr_pdcp_add_drbs(ctxt_pP->enb_flag, ctxt_pP->rntiMaybeUEid, - 0, radioBearerConfig->drb_ToAddModList, ue_rrc->cipheringAlgorithm | (ue_rrc->integrityProtAlgorithm << 4), kUPenc, diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index 5a75b8953a..d7cc496439 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -768,31 +768,31 @@ int gtpv1u_create_ngu_tunnel(const instance_t instance, return !GTPNOK; } -int gtpv1u_update_ngu_tunnel(const instance_t instanceP, const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP, const ue_id_t prior_ue_id) +int gtpv1u_update_ue_id(const instance_t instanceP, ue_id_t old_ue_id, ue_id_t new_ue_id) { - LOG_D(GTPU, "[%ld] Update tunnels from UEid %lx to UEid %lx\n", instanceP, prior_ue_id, create_tunnel_req_pP->ue_id); - pthread_mutex_lock(&globGtp.gtp_lock); auto inst = &globGtp.instances[compatInst(instanceP)]; - auto it = inst->ue2te_mapping.find(prior_ue_id); + auto it = inst->ue2te_mapping.find(old_ue_id); if (it == inst->ue2te_mapping.end()) { - LOG_W(GTPU, "[%ld] Delete GTP tunnels for UEid: %lx, but no tunnel exits\n", instanceP, prior_ue_id); + LOG_W(GTPU, "[%ld] Update GTP tunnels for UEid: %lx, but no tunnel exits\n", instanceP, old_ue_id); pthread_mutex_unlock(&globGtp.gtp_lock); return GTPNOK; } - for (int i = 0; i < create_tunnel_req_pP->num_tunnels; i++) { - teid_t incoming_teid = inst->ue2te_mapping[prior_ue_id].bearers[create_tunnel_req_pP->pdusession_id[i]].teid_incoming; - if (globGtp.te2ue_mapping[incoming_teid].ue_id == prior_ue_id) { - globGtp.te2ue_mapping[incoming_teid].ue_id = create_tunnel_req_pP->ue_id; + for (unsigned i = 0; i < it->second.bearers.size(); ++i) { + teid_t incoming_teid = inst->ue2te_mapping[old_ue_id].bearers[i].teid_incoming; + if (globGtp.te2ue_mapping[incoming_teid].ue_id == old_ue_id) { + globGtp.te2ue_mapping[incoming_teid].ue_id = new_ue_id; } } - inst->ue2te_mapping[create_tunnel_req_pP->ue_id] = it->second; + inst->ue2te_mapping[new_ue_id] = it->second; inst->ue2te_mapping.erase(it); pthread_mutex_unlock(&globGtp.gtp_lock); + + LOG_I(GTPU, "[%ld] Updated tunnels from UEid %lx to UEid %lx\n", instanceP, old_ue_id, new_ue_id); return !GTPNOK; } diff --git a/openair3/ocp-gtpu/gtp_itf.h b/openair3/ocp-gtpu/gtp_itf.h index 9592070ca9..f8228677fc 100644 --- a/openair3/ocp-gtpu/gtp_itf.h +++ b/openair3/ocp-gtpu/gtp_itf.h @@ -76,11 +76,8 @@ extern "C" { int gtpv1u_delete_ngu_tunnel( const instance_t instance, gtpv1u_gnb_delete_tunnel_req_t *req); - - int gtpv1u_update_ngu_tunnel( const instance_t instanceP, - const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP, - const ue_id_t prior_rnti - ); + + int gtpv1u_update_ue_id(const instance_t instanceP, ue_id_t old_ue_id, ue_id_t new_ue_id); // New API teid_t newGtpuCreateTunnel(instance_t instance,