diff --git a/CMakeLists.txt b/CMakeLists.txt index af48eca7b3..c34e3cbbd7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1271,6 +1271,7 @@ set(L2_NR_SRC ${NR_RRC_DIR}/rrc_gNB_radio_bearers.c ${NR_RRC_DIR}/rrc_gNB_cuup.c ${NR_RRC_DIR}/rrc_gNB_du.c + ${NR_RRC_DIR}/rrc_gNB_mobility.c ) set(L2_SRC_UE diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index aebbed95b0..14d08e9c45 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -112,23 +112,6 @@ typedef struct nr_e_rab_param_s { uint8_t xid; // transaction_id } __attribute__ ((__packed__)) nr_e_rab_param_t; - -typedef struct HANDOVER_INFO_NR_s { - uint8_t ho_prepare; - uint8_t ho_complete; - uint8_t modid_s; //module_idP of serving cell - uint8_t modid_t; //module_idP of target cell - uint8_t ueid_s; //UE index in serving cell - uint8_t ueid_t; //UE index in target cell - - // NR not define at this moment - //AS_Config_t as_config; /* these two parameters are taken from 36.331 section 10.2.2: HandoverPreparationInformation-r8-IEs */ - //AS_Context_t as_context; /* They are mandatory for HO */ - - uint8_t buf[NR_RRC_BUF_SIZE]; /* ASN.1 encoded handoverCommandMessage */ - int size; /* size of above message in bytes */ -} NR_HANDOVER_INFO; - typedef struct nr_rrc_guami_s { uint16_t mcc; uint16_t mnc; @@ -214,6 +197,9 @@ typedef enum { RRC_UECAPABILITY_ENQUIRY, } rrc_action_t; +/* forward declaration */ +typedef struct nr_handover_context_s nr_handover_context_t; + typedef struct gNB_RRC_UE_s { time_t last_seen; // last time this UE has been accessed @@ -222,7 +208,7 @@ typedef struct gNB_RRC_UE_s { NR_SRB_INFO_TABLE_ENTRY Srb[NR_NUM_SRB]; NR_MeasConfig_t *measConfig; - NR_HANDOVER_INFO *handover_info; + nr_handover_context_t *ho_context; NR_MeasResults_t *measResults; bool as_security_active; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 7b0333db85..df865c02a8 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -77,6 +77,7 @@ #include "rrc_gNB_NGAP.h" #include "rrc_gNB_du.h" +#include "rrc_gNB_mobility.h" #include "rrc_gNB_GTPV1U.h" diff --git a/openair2/RRC/NR/rrc_gNB_mobility.c b/openair2/RRC/NR/rrc_gNB_mobility.c new file mode 100644 index 0000000000..72ae57b67e --- /dev/null +++ b/openair2/RRC/NR/rrc_gNB_mobility.c @@ -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 + */ + +#include + +#include "assertions.h" +#include "rrc_gNB_mobility.h" + +typedef enum { HO_CTX_BOTH, HO_CTX_SOURCE, HO_CTX_TARGET } ho_ctx_type_t; +static nr_handover_context_t *alloc_ho_ctx(ho_ctx_type_t type) +{ + nr_handover_context_t *ho_ctx = calloc(1, sizeof(*ho_ctx)); + AssertFatal(ho_ctx != NULL, "out of memory\n"); + if (type == HO_CTX_SOURCE || type == HO_CTX_BOTH) { + ho_ctx->source = calloc(1, sizeof(*ho_ctx->source)); + AssertFatal(ho_ctx->source != NULL, "out of memory\n"); + } + if (type == HO_CTX_TARGET || type == HO_CTX_BOTH) { + ho_ctx->target = calloc(1, sizeof(*ho_ctx->target)); + AssertFatal(ho_ctx->target != NULL, "out of memory\n"); + } + return ho_ctx; +} + +static void free_ho_ctx(nr_handover_context_t *ho_ctx) +{ + free(ho_ctx->source); + free(ho_ctx->target); + free(ho_ctx); +} diff --git a/openair2/RRC/NR/rrc_gNB_mobility.h b/openair2/RRC/NR/rrc_gNB_mobility.h new file mode 100644 index 0000000000..fefa39982b --- /dev/null +++ b/openair2/RRC/NR/rrc_gNB_mobility.h @@ -0,0 +1,69 @@ +/* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef RRC_GNB_MOBILITY_H_ +#define RRC_GNB_MOBILITY_H_ + +#include + +/* forward declarations */ +typedef struct gNB_RRC_INST_s gNB_RRC_INST; +typedef struct gNB_RRC_UE_s gNB_RRC_UE_t; +typedef struct nr_rrc_du_container_t nr_rrc_du_container_t; + +typedef void (*ho_cancel_t)(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue); +typedef struct nr_ho_source_cu { + /// pointer to the (source) DU structure + const nr_rrc_du_container_t *du; + /// (source) DU UE ID; in F1, the DU UE ID will change to the new (target) DU + /// UE ID during handover, and the CU needs to keep track of this in case of + /// reestablishment + uint32_t du_ue_id; + /// old (source) RNTI (to recognize a UE during reestablishment) + rnti_t old_rnti; + /// function pointer to announce the handover cancellation, e.g., + /// reestablishment + ho_cancel_t ho_cancel; +} nr_ho_source_cu_t; + +/* acknowledgement of handover request. buf+len is the RRC Reconfiguration */ +typedef void (*ho_req_ack_t)(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue, uint8_t *buf, uint32_t len); +typedef void (*ho_success_t)(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue); +typedef struct nr_ho_target_cu { + /// pointer to the (target) DU structure + const nr_rrc_du_container_t *du; + /// (target) DU UE ID; the (source) DU UE ID will change to the new (target) + /// DU UE ID after sending a reconfiguration, which is later than when + /// receiving this ID + uint32_t du_ue_id; + /// new (target) RNTI (as for du_ue_id) + rnti_t new_rnti; + /// function pointer to announce handover request acknowledgment + ho_req_ack_t ho_req_ack; + /// function pointer to announce handover success + ho_success_t ho_success; +} nr_ho_target_cu_t; + +typedef struct nr_handover_context_s { + nr_ho_source_cu_t *source; + nr_ho_target_cu_t *target; +} nr_handover_context_t; + +#endif /* RRC_GNB_MOBILITY_H_ */