Commit 6642b467 authored by Robert Schmidt's avatar Robert Schmidt

Implement PDU session estab through NGAP Initial UE Context Setup

This commit allows the gNB to handle PDU sessions that the core requests
to setup during the NGAP Initial UE Context Setup. Previously, we only
managed them as part of PDU Session Resource Setup Request.

The RRC will, depending on whether a PDU session is in the NGAP Initial
UE Context Setup, either directly trigger the Security Command, or first
do a bearer setup at the CU-UP. Some asserts have been lifted, as now
the PDU sessions might be present before the RRC Connection is fully
established.

Implement the correct forwarding of the bearers in an F1 UE Context
Setup Request message.

This solves bug #672.
parent c818e9b5
...@@ -69,7 +69,6 @@ static void f1_setup_request_direct(const f1ap_setup_req_t *req) ...@@ -69,7 +69,6 @@ static void f1_setup_request_direct(const f1ap_setup_req_t *req)
static void ue_context_setup_response_direct(const f1ap_ue_context_setup_t *req, const f1ap_ue_context_setup_t *resp) static void ue_context_setup_response_direct(const f1ap_ue_context_setup_t *req, const f1ap_ue_context_setup_t *resp)
{ {
DevAssert(req->drbs_to_be_setup_length == resp->drbs_to_be_setup_length); DevAssert(req->drbs_to_be_setup_length == resp->drbs_to_be_setup_length);
AssertFatal(req->drbs_to_be_setup_length == 0, "not implemented\n");
(void) req; /* we don't need the request -- it is to set up GTP in F1 case */ (void) req; /* we don't need the request -- it is to set up GTP in F1 case */
MessageDef *msg = itti_alloc_new_message (TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_SETUP_RESP); MessageDef *msg = itti_alloc_new_message (TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_SETUP_RESP);
...@@ -85,6 +84,13 @@ static void ue_context_setup_response_direct(const f1ap_ue_context_setup_t *req, ...@@ -85,6 +84,13 @@ static void ue_context_setup_response_direct(const f1ap_ue_context_setup_t *req,
for (int i = 0; i < f1ap_msg->srbs_to_be_setup_length; ++i) for (int i = 0; i < f1ap_msg->srbs_to_be_setup_length; ++i)
f1ap_msg->srbs_to_be_setup[i] = resp->srbs_to_be_setup[i]; f1ap_msg->srbs_to_be_setup[i] = resp->srbs_to_be_setup[i];
} }
if (resp->drbs_to_be_setup_length > 0) {
DevAssert(resp->drbs_to_be_setup != NULL);
f1ap_msg->drbs_to_be_setup_length = resp->drbs_to_be_setup_length;
f1ap_msg->drbs_to_be_setup = calloc(f1ap_msg->drbs_to_be_setup_length, sizeof(*f1ap_msg->drbs_to_be_setup));
for (int i = 0; i < f1ap_msg->drbs_to_be_setup_length; ++i)
f1ap_msg->drbs_to_be_setup[i] = resp->drbs_to_be_setup[i];
}
f1ap_msg->du_to_cu_rrc_information = malloc(sizeof(*resp->du_to_cu_rrc_information)); f1ap_msg->du_to_cu_rrc_information = malloc(sizeof(*resp->du_to_cu_rrc_information));
AssertFatal(f1ap_msg->du_to_cu_rrc_information != NULL, "out of memory\n"); AssertFatal(f1ap_msg->du_to_cu_rrc_information != NULL, "out of memory\n");
......
...@@ -103,7 +103,6 @@ static void f1_setup_request_f1ap(const f1ap_setup_req_t *req) ...@@ -103,7 +103,6 @@ static void f1_setup_request_f1ap(const f1ap_setup_req_t *req)
static void ue_context_setup_response_f1ap(const f1ap_ue_context_setup_t *req, const f1ap_ue_context_setup_t *resp) static void ue_context_setup_response_f1ap(const f1ap_ue_context_setup_t *req, const f1ap_ue_context_setup_t *resp)
{ {
DevAssert(req->drbs_to_be_setup_length == resp->drbs_to_be_setup_length); DevAssert(req->drbs_to_be_setup_length == resp->drbs_to_be_setup_length);
AssertFatal(req->drbs_to_be_setup_length == 0, "not implmented\n");
DevAssert(req->srbs_to_be_setup_length == resp->srbs_to_be_setup_length); DevAssert(req->srbs_to_be_setup_length == resp->srbs_to_be_setup_length);
MessageDef *msg = itti_alloc_new_message (TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_SETUP_RESP); MessageDef *msg = itti_alloc_new_message (TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_SETUP_RESP);
...@@ -118,6 +117,13 @@ static void ue_context_setup_response_f1ap(const f1ap_ue_context_setup_t *req, c ...@@ -118,6 +117,13 @@ static void ue_context_setup_response_f1ap(const f1ap_ue_context_setup_t *req, c
for (int i = 0; i < f1ap_msg->srbs_to_be_setup_length; ++i) for (int i = 0; i < f1ap_msg->srbs_to_be_setup_length; ++i)
f1ap_msg->srbs_to_be_setup[i] = resp->srbs_to_be_setup[i]; f1ap_msg->srbs_to_be_setup[i] = resp->srbs_to_be_setup[i];
} }
if (resp->drbs_to_be_setup_length > 0) {
DevAssert(resp->drbs_to_be_setup != NULL);
f1ap_msg->drbs_to_be_setup_length = resp->drbs_to_be_setup_length;
f1ap_msg->drbs_to_be_setup = calloc(f1ap_msg->drbs_to_be_setup_length, sizeof(*f1ap_msg->drbs_to_be_setup));
for (int i = 0; i < f1ap_msg->drbs_to_be_setup_length; ++i)
f1ap_msg->drbs_to_be_setup[i] = resp->drbs_to_be_setup[i];
}
f1ap_msg->du_to_cu_rrc_information = malloc(sizeof(*resp->du_to_cu_rrc_information)); f1ap_msg->du_to_cu_rrc_information = malloc(sizeof(*resp->du_to_cu_rrc_information));
AssertFatal(f1ap_msg->du_to_cu_rrc_information != NULL, "out of memory\n"); AssertFatal(f1ap_msg->du_to_cu_rrc_information != NULL, "out of memory\n");
......
...@@ -51,8 +51,20 @@ static void ue_context_setup_request_f1ap(sctp_assoc_t assoc_id, const f1ap_ue_c ...@@ -51,8 +51,20 @@ static void ue_context_setup_request_f1ap(sctp_assoc_t assoc_id, const f1ap_ue_c
f1ap_ue_context_setup_t *f1ap_msg = &F1AP_UE_CONTEXT_SETUP_REQ(msg); f1ap_ue_context_setup_t *f1ap_msg = &F1AP_UE_CONTEXT_SETUP_REQ(msg);
*f1ap_msg = *req; *f1ap_msg = *req;
AssertFatal(req->cu_to_du_rrc_information == NULL, "cu_to_du_rrc_information not supported yet\n"); AssertFatal(req->cu_to_du_rrc_information == NULL, "cu_to_du_rrc_information not supported yet\n");
AssertFatal(req->drbs_to_be_setup == NULL, "drbs_to_be_setup not supported yet\n"); if (req->drbs_to_be_setup_length > 0) {
AssertFatal(req->srbs_to_be_setup == NULL, "drbs_to_be_setup not supported yet\n"); int n = req->drbs_to_be_setup_length;
f1ap_msg->drbs_to_be_setup_length = n;
f1ap_msg->drbs_to_be_setup = calloc(n, sizeof(*f1ap_msg->drbs_to_be_setup));
AssertFatal(f1ap_msg->drbs_to_be_setup != NULL, "out of memory\n");
memcpy(f1ap_msg->drbs_to_be_setup, req->drbs_to_be_setup, n * sizeof(*f1ap_msg->drbs_to_be_setup));
}
if (req->srbs_to_be_setup_length > 0) {
int n = req->srbs_to_be_setup_length;
f1ap_msg->srbs_to_be_setup_length = n;
f1ap_msg->srbs_to_be_setup = calloc(n, sizeof(*f1ap_msg->srbs_to_be_setup));
AssertFatal(f1ap_msg->srbs_to_be_setup != NULL, "out of memory\n");
memcpy(f1ap_msg->srbs_to_be_setup, req->srbs_to_be_setup, n * sizeof(*f1ap_msg->srbs_to_be_setup));
}
if (req->rrc_container_length > 0) { if (req->rrc_container_length > 0) {
f1ap_msg->rrc_container = calloc(req->rrc_container_length, sizeof(*f1ap_msg->rrc_container)); f1ap_msg->rrc_container = calloc(req->rrc_container_length, sizeof(*f1ap_msg->rrc_container));
AssertFatal(f1ap_msg->rrc_container != NULL, "out of memory\n"); AssertFatal(f1ap_msg->rrc_container != NULL, "out of memory\n");
......
...@@ -81,7 +81,9 @@ int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2 ...@@ -81,7 +81,9 @@ int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2
void void
rrc_gNB_generate_SecurityModeCommand( rrc_gNB_generate_SecurityModeCommand(
const protocol_ctxt_t *const ctxt_pP, const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP rrc_gNB_ue_context_t *const ue_context_pP,
int n_drbs,
const f1ap_drb_to_be_setup_t *drbs
); );
unsigned int rrc_gNB_get_next_transaction_identifier(module_id_t gnb_mod_idP); unsigned int rrc_gNB_get_next_transaction_identifier(module_id_t gnb_mod_idP);
......
...@@ -509,7 +509,6 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co ...@@ -509,7 +509,6 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co
{ {
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
AssertFatal(ue_p->nb_of_pdusessions == 0, "logic bug: PDU sessions present before RRC Connection established\n");
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
ue_p->xids[xid] = RRC_DEFAULT_RECONF; ue_p->xids[xid] = RRC_DEFAULT_RECONF;
...@@ -551,14 +550,16 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co ...@@ -551,14 +550,16 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co
uint32_t ssb_arfcn = get_ssb_arfcn(cell_info, du->mib, du->sib1); uint32_t ssb_arfcn = get_ssb_arfcn(cell_info, du->mib, du->sib1);
measconfig = get_defaultMeasConfig(ssb_arfcn, band, scs); measconfig = get_defaultMeasConfig(ssb_arfcn, band, scs);
} }
NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, false);
NR_DRB_ToAddModList_t *DRBs = createDRBlist(ue_p, false);
uint8_t buffer[RRC_BUF_SIZE] = {0}; uint8_t buffer[RRC_BUF_SIZE] = {0};
int size = do_RRCReconfiguration(ue_p, int size = do_RRCReconfiguration(ue_p,
buffer, buffer,
RRC_BUF_SIZE, RRC_BUF_SIZE,
xid, xid,
NULL, //*SRB_configList2, SRBs,
NULL, //*DRB_configList, DRBs,
NULL, NULL,
NULL, NULL,
measconfig, measconfig,
...@@ -566,6 +567,8 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co ...@@ -566,6 +567,8 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co
ue_p->masterCellGroup); ue_p->masterCellGroup);
AssertFatal(size > 0, "cannot encode RRCReconfiguration in %s()\n", __func__); AssertFatal(size > 0, "cannot encode RRCReconfiguration in %s()\n", __func__);
free_defaultMeasConfig(measconfig); free_defaultMeasConfig(measconfig);
freeSRBlist(SRBs);
freeDRBlist(DRBs);
if (LOG_DEBUGFLAG(DEBUG_ASN1)) { if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, ue_p->masterCellGroup); xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, ue_p->masterCellGroup);
...@@ -1759,6 +1762,11 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance ...@@ -1759,6 +1762,11 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance
if (LOG_DEBUGFLAG(DEBUG_ASN1)) if (LOG_DEBUGFLAG(DEBUG_ASN1))
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, UE->masterCellGroup); xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, UE->masterCellGroup);
if (resp->drbs_to_be_setup_length > 0) {
AssertFatal(resp->srbs_to_be_setup_length > 0 && resp->srbs_to_be_setup[0].srb_id == 2, "logic bug: we set up DRBs, so need to have both SRB1&SRB2\n");
e1_send_bearer_updates(rrc, UE, resp->drbs_to_be_setup_length, resp->drbs_to_be_setup);
}
/* at this point, we don't have to do anything: the UE context setup request /* at this point, we don't have to do anything: the UE context setup request
* includes the Security Command, whose response will trigger the following * includes the Security Command, whose response will trigger the following
* messages (UE capability, to be specific) */ * messages (UE capability, to be specific) */
...@@ -2006,7 +2014,7 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp ...@@ -2006,7 +2014,7 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp
/* Instruction towards the DU for SRB2 configuration */ /* Instruction towards the DU for SRB2 configuration */
int nb_srb = 0; int nb_srb = 0;
f1ap_srb_to_be_setup_t srbs[1]; f1ap_srb_to_be_setup_t srbs[1] = {0};
if (UE->Srb[2].Active == 0) { if (UE->Srb[2].Active == 0) {
activate_srb(UE, 2); activate_srb(UE, 2);
nb_srb = 1; nb_srb = 1;
...@@ -2017,7 +2025,8 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp ...@@ -2017,7 +2025,8 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp
if (!UE->as_security_active) { if (!UE->as_security_active) {
/* no AS security active, need to send UE context setup req with security /* no AS security active, need to send UE context setup req with security
* command (and the bearers) */ * command (and the bearers) */
AssertFatal(false, "not implemented yet\n"); protocol_ctxt_t ctxt = {.rntiMaybeUEid = UE->rrc_ue_id};
rrc_gNB_generate_SecurityModeCommand(&ctxt, ue_context_p, nb_drb, drbs);
return; return;
} }
...@@ -2387,7 +2396,9 @@ static void rrc_deliver_ue_ctxt_setup_req(void *deliver_pdu_data, ue_id_t ue_id, ...@@ -2387,7 +2396,9 @@ static void rrc_deliver_ue_ctxt_setup_req(void *deliver_pdu_data, ue_id_t ue_id,
void void
rrc_gNB_generate_SecurityModeCommand( rrc_gNB_generate_SecurityModeCommand(
const protocol_ctxt_t *const ctxt_pP, const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP rrc_gNB_ue_context_t *const ue_context_pP,
int n_drbs,
const f1ap_drb_to_be_setup_t *drbs
) )
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
{ {
...@@ -2413,6 +2424,16 @@ rrc_gNB_generate_SecurityModeCommand( ...@@ -2413,6 +2424,16 @@ rrc_gNB_generate_SecurityModeCommand(
cu2du.uE_CapabilityRAT_ContainerList_length = ue_p->ue_cap_buffer.len; cu2du.uE_CapabilityRAT_ContainerList_length = ue_p->ue_cap_buffer.len;
} }
int nb_srb = 0;
f1ap_srb_to_be_setup_t srb_buf[1] = {0};
f1ap_srb_to_be_setup_t *srbs = 0;
if (n_drbs > 0) {
nb_srb = 1;
srb_buf[0].srb_id = 2;
srb_buf[0].lcid = 2;
srbs = srb_buf;
}
/* the callback will fill the UE context setup request and forward it */ /* the callback will fill the UE context setup request and forward it */
f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id);
RETURN_IF_INVALID_ASSOC_ID(ue_data); RETURN_IF_INVALID_ASSOC_ID(ue_data);
...@@ -2424,8 +2445,10 @@ rrc_gNB_generate_SecurityModeCommand( ...@@ -2424,8 +2445,10 @@ rrc_gNB_generate_SecurityModeCommand(
.plmn.mnc_digit_length = rrc->configuration.mnc_digit_length[0], .plmn.mnc_digit_length = rrc->configuration.mnc_digit_length[0],
.nr_cellid = rrc->nr_cellid, .nr_cellid = rrc->nr_cellid,
.servCellId = 0, /* TODO: correct value? */ .servCellId = 0, /* TODO: correct value? */
.srbs_to_be_setup = 0, /* no new SRBs */ .srbs_to_be_setup_length = nb_srb,
.drbs_to_be_setup = 0, /* no new DRBs */ .srbs_to_be_setup = srbs,
.drbs_to_be_setup_length = n_drbs,
.drbs_to_be_setup = (f1ap_drb_to_be_setup_t *) drbs,
.cu_to_du_rrc_information = cu2du_p, .cu_to_du_rrc_information = cu2du_p,
}; };
deliver_ue_ctxt_setup_data_t data = {.rrc = rrc, .setup_req = &ue_context_setup_req, .assoc_id = ue_data.du_assoc_id }; deliver_ue_ctxt_setup_data_t data = {.rrc = rrc, .setup_req = &ue_context_setup_req, .assoc_id = ue_data.du_assoc_id };
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment