Handle UE context setup resp for HO: trigger reconfiguration on source
In this commit, handle the reception of a UE context setup response, in the case of handover. In that case, store the gNB-DU UE ID and C-RNTI of the UE at the target DU, and trigger a reconfiguration towards the UE at the source DU via the callback. To ensure that the CU-UP's PDCP is SN-aligned with the UE, use cuup_notify_reestablishment() to reset the bearers with PDCP reestablishment, which has already been implemented in the last commit. Co-authored-by: batuhanduyuler <batuhan.duyuler@firecell.io> Co-authored-by: rmagueta <rmagueta@allbesmart.pt>
This commit is contained in:
co-authored by
batuhanduyuler
rmagueta
parent
7b163f1688
commit
0e20c4c257
@@ -1864,7 +1864,27 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance
|
||||
cuup_notify_reestablishment(rrc, UE);
|
||||
}
|
||||
|
||||
rrc_gNB_generate_dedicatedRRCReconfiguration(rrc, UE);
|
||||
if (UE->ho_context == NULL) {
|
||||
rrc_gNB_generate_dedicatedRRCReconfiguration(rrc, UE);
|
||||
} else {
|
||||
// case of handover
|
||||
// handling of "target CU" information
|
||||
DevAssert(UE->ho_context->target != NULL);
|
||||
DevAssert(resp->crnti != NULL);
|
||||
UE->ho_context->target->du_ue_id = resp->gNB_DU_ue_id;
|
||||
UE->ho_context->target->new_rnti = *resp->crnti;
|
||||
|
||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(0);
|
||||
UE->xids[xid] = RRC_DEDICATED_RECONF;
|
||||
uint8_t buffer[NR_RRC_BUF_SIZE] = {0};
|
||||
int size = rrc_gNB_encode_RRCReconfiguration(rrc, UE, xid, NULL, buffer, sizeof(buffer), true);
|
||||
DevAssert(size > 0 && size <= sizeof(buffer));
|
||||
|
||||
// TODO N2 38.413 sec 9.3.1.21: admitted PDU sessions (in UE), Target to
|
||||
// Source Transparent Container (9.3.1.21) which encodes the RRC
|
||||
// reconfiguration above
|
||||
UE->ho_context->target->ho_req_ack(rrc, UE, buffer, size);
|
||||
}
|
||||
}
|
||||
|
||||
static void rrc_CU_process_ue_context_release_request(MessageDef *msg_p)
|
||||
|
||||
@@ -31,6 +31,11 @@
|
||||
#include "rrc_gNB_UE_context.h"
|
||||
#include "openair2/F1AP/f1ap_ids.h"
|
||||
#include "MESSAGES/asn1_msg.h"
|
||||
#include "nr_pdcp/nr_pdcp_oai_api.h"
|
||||
#include "openair3/SECU/key_nas_deriver.h"
|
||||
|
||||
/* declared in rrc_gNB.c: should be cleaned up through helper function? useful? */
|
||||
extern mui_t rrc_gNB_mui;
|
||||
|
||||
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)
|
||||
@@ -198,6 +203,75 @@ void nr_rrc_trigger_n2_ho(gNB_RRC_INST *rrc, int nr_cgi, uint8_t *ho_prep_info,
|
||||
}
|
||||
*/
|
||||
|
||||
typedef struct deliver_ue_ctxt_modification_data_t {
|
||||
gNB_RRC_INST *rrc;
|
||||
f1ap_ue_context_modif_req_t *modification_req;
|
||||
sctp_assoc_t assoc_id;
|
||||
} deliver_ue_ctxt_modification_data_t;
|
||||
static void rrc_deliver_ue_ctxt_modif_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);
|
||||
deliver_ue_ctxt_modification_data_t *data = deliver_pdu_data;
|
||||
data->modification_req->rrc_container = (uint8_t*)buf;
|
||||
data->modification_req->rrc_container_length = size;
|
||||
data->rrc->mac_rrc.ue_context_modification_request(data->assoc_id, data->modification_req);
|
||||
}
|
||||
static void rrc_gNB_trigger_reconfiguration_for_handover(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue, uint8_t *rrc_reconf, int rrc_reconf_len)
|
||||
{
|
||||
f1_ue_data_t ue_data = cu_get_f1_ue_data(ue->rrc_ue_id);
|
||||
|
||||
TransmActionInd_t transmission_action_indicator = TransmActionInd_STOP;
|
||||
RETURN_IF_INVALID_ASSOC_ID(ue_data.du_assoc_id);
|
||||
f1ap_ue_context_modif_req_t ue_context_modif_req = {
|
||||
.gNB_CU_ue_id = ue->rrc_ue_id,
|
||||
.gNB_DU_ue_id = ue_data.secondary_ue,
|
||||
.plmn.mcc = rrc->configuration.mcc[0],
|
||||
.plmn.mnc = rrc->configuration.mnc[0],
|
||||
.plmn.mnc_digit_length = rrc->configuration.mnc_digit_length[0],
|
||||
.nr_cellid = rrc->nr_cellid, // TODO target cell ID
|
||||
.servCellId = 0, // TODO: correct value?
|
||||
.ReconfigComplOutcome = RRCreconf_success,
|
||||
.transm_action_ind = &transmission_action_indicator,
|
||||
};
|
||||
deliver_ue_ctxt_modification_data_t data = {.rrc = rrc,
|
||||
.modification_req = &ue_context_modif_req,
|
||||
.assoc_id = ue_data.du_assoc_id};
|
||||
int srb_id = 1;
|
||||
nr_pdcp_data_req_srb(ue->rrc_ue_id,
|
||||
srb_id,
|
||||
rrc_gNB_mui++,
|
||||
rrc_reconf_len,
|
||||
(unsigned char *const)rrc_reconf,
|
||||
rrc_deliver_ue_ctxt_modif_req,
|
||||
&data);
|
||||
}
|
||||
|
||||
static void nr_rrc_f1_ho_acknowledge(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, uint8_t *rrc_reconf_buf, uint32_t rrc_reconf_len)
|
||||
{
|
||||
// N2/Xn HO: fill with UE caps, as-context, rrc reconf, send to source CU
|
||||
// also, fill the UE->rnti from the new one (in F1 case, happens after
|
||||
// confirmation of ue ctxt modif
|
||||
|
||||
// F1 HO: handling of "source CU" information
|
||||
DevAssert(UE->ho_context->source != NULL);
|
||||
rrc_gNB_trigger_reconfiguration_for_handover(rrc, UE, rrc_reconf_buf, rrc_reconf_len);
|
||||
LOG_A(NR_RRC, "HO acknowledged: Send reconfiguration for UE %u/RNTI %04x...\n", UE->rrc_ue_id, UE->rnti);
|
||||
|
||||
/* Re-establish SRB2 according to clause 5.3.5.6.3 of 3GPP TS 38.331
|
||||
* (SRB1 is re-established with RRCReestablishment message)
|
||||
*/
|
||||
int srb_id = 2;
|
||||
if (UE->Srb[srb_id].Active) {
|
||||
nr_pdcp_entity_security_keys_and_algos_t security_parameters;
|
||||
/* Derive the keys from kgnb */
|
||||
nr_derive_key(RRC_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, security_parameters.ciphering_key);
|
||||
nr_derive_key(RRC_INT_ALG, UE->integrity_algorithm, UE->kgnb, security_parameters.integrity_key);
|
||||
security_parameters.integrity_algorithm = UE->integrity_algorithm;
|
||||
security_parameters.ciphering_algorithm = UE->ciphering_algorithm;
|
||||
nr_pdcp_reestablishment(UE->rrc_ue_id, srb_id, true, &security_parameters);
|
||||
}
|
||||
}
|
||||
|
||||
void nr_rrc_trigger_f1_ho(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue, nr_rrc_du_container_t *source_du, nr_rrc_du_container_t *target_du)
|
||||
{
|
||||
DevAssert(rrc != NULL);
|
||||
@@ -212,7 +286,7 @@ void nr_rrc_trigger_f1_ho(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue, nr_rrc_du_contain
|
||||
// here: target Cell is preselected, target CU has access to UE information
|
||||
// and therefore also the PDU sessions. Orig RRC reconfiguration should be in
|
||||
// handover preparation information
|
||||
ho_req_ack_t ack = NULL;
|
||||
ho_req_ack_t ack = nr_rrc_f1_ho_acknowledge;
|
||||
ho_success_t success = NULL;
|
||||
ho_cancel_t cancel = NULL;
|
||||
nr_initiate_handover(rrc, ue, source_du, target_du, buf, size, ack, success, cancel);
|
||||
|
||||
Reference in New Issue
Block a user