mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
Compare commits
2 Commits
pre-commit
...
pdu-sessio
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2fb1c76fc6 | ||
|
|
05a569fa92 |
@@ -475,6 +475,16 @@ typedef struct pdu_session_to_mod_s {
|
||||
DRB_nGRAN_to_mod_t DRBnGRanModList[E1AP_MAX_NUM_DRBS];
|
||||
} pdu_session_to_mod_t;
|
||||
|
||||
/**
|
||||
* PDU Session Resource To Remove List (clause 9.3.3.12)
|
||||
*/
|
||||
typedef struct pdu_session_to_rem_s {
|
||||
// PDU Session ID (M)
|
||||
long sessionId;
|
||||
// Cause (O)
|
||||
e1ap_cause_t cause;
|
||||
} pdu_session_to_rem_t;
|
||||
|
||||
/**
|
||||
* Bearer Context Setup Request message, clause 9.2.2.1 of 3GPP TS 38.463
|
||||
*/
|
||||
@@ -534,6 +544,9 @@ typedef struct e1ap_bearer_mod_req_s {
|
||||
// NG-RAN PDU Session Resource To Modify List (O)
|
||||
int numPDUSessionsMod;
|
||||
pdu_session_to_mod_t pduSessionMod[E1AP_MAX_NUM_PDU_SESSIONS];
|
||||
// NG-RAN PDU Session Resource To Remove List (O)
|
||||
int numPDUSessionsRem;
|
||||
pdu_session_to_rem_t pduSessionRem[E1AP_MAX_NUM_PDU_SESSIONS];
|
||||
} e1ap_bearer_mod_req_t;
|
||||
|
||||
typedef struct e1ap_bearer_release_cmd_s {
|
||||
|
||||
@@ -380,7 +380,6 @@ static int handle_ue_context_drbs_release(NR_UE_info_t *UE,
|
||||
NR_CellGroupConfig_t *cellGroupConfig)
|
||||
{
|
||||
DevAssert(req_drbs != NULL && cellGroupConfig != NULL);
|
||||
instance_t f1inst = get_f1_gtp_instance();
|
||||
|
||||
cellGroupConfig->rlc_BearerToReleaseList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToReleaseList));
|
||||
AssertFatal(cellGroupConfig->rlc_BearerToReleaseList != NULL, "out of memory\n");
|
||||
@@ -401,8 +400,6 @@ static int handle_ue_context_drbs_release(NR_UE_info_t *UE,
|
||||
if (idx < cellGroupConfig->rlc_BearerToAddModList->list.count) {
|
||||
nr_mac_remove_lcid(&UE->UE_sched_ctrl, lcid);
|
||||
nr_rlc_release_entity(UE->rnti, lcid);
|
||||
if (f1inst >= 0)
|
||||
newGtpuDeleteOneTunnel(f1inst, UE->rnti, drb->id);
|
||||
asn_sequence_del(&cellGroupConfig->rlc_BearerToAddModList->list, idx, 1);
|
||||
long *plcid = malloc(sizeof(*plcid));
|
||||
AssertFatal(plcid, "out of memory\n");
|
||||
|
||||
@@ -247,7 +247,7 @@ void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req)
|
||||
*/
|
||||
void e1_bearer_context_modif(const e1ap_bearer_mod_req_t *req)
|
||||
{
|
||||
AssertFatal(req->numPDUSessionsMod > 0, "need at least one PDU session to modify\n");
|
||||
AssertFatal(req->numPDUSessionsMod > 0 || req->numPDUSessionsRem > 0, "need at least one PDU session to modify\n");
|
||||
|
||||
e1ap_bearer_modif_resp_t modif = {
|
||||
.gNB_cu_cp_ue_id = req->gNB_cu_cp_ue_id,
|
||||
@@ -330,6 +330,16 @@ void e1_bearer_context_modif(const e1ap_bearer_mod_req_t *req)
|
||||
}
|
||||
}
|
||||
|
||||
/* PDU Session Resource To Remove List (see 9.3.3.12 of TS 38.463) */
|
||||
for (int i = 0; i < req->numPDUSessionsRem; i++) {
|
||||
instance_t f1inst = get_f1_gtp_instance();
|
||||
instance_t n3inst = get_n3_gtp_instance();
|
||||
instance_t inst = f1inst >= 0 ? f1inst : n3inst; // is there F1-U?
|
||||
newGtpuDeleteOneTunnel(inst, req->gNB_cu_up_ue_id, req->pduSessionRem[i].sessionId);
|
||||
nr_pdcp_release_from_pdusession(req->gNB_cu_up_ue_id, req->pduSessionRem[i].sessionId);
|
||||
nr_sdap_delete_entity(req->gNB_cu_up_ue_id, req->pduSessionRem[i].sessionId);
|
||||
}
|
||||
|
||||
get_e1_if()->bearer_modif_response(&modif);
|
||||
}
|
||||
|
||||
|
||||
@@ -926,6 +926,18 @@ void nr_pdcp_release_drb(ue_id_t ue_id, int drb_id)
|
||||
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
|
||||
}
|
||||
|
||||
void nr_pdcp_release_from_pdusession(ue_id_t ue_id, long pdusession_id)
|
||||
{
|
||||
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
|
||||
nr_pdcp_ue_t *ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id);
|
||||
for (int i = 0; i < MAX_DRBS_PER_UE; i++) {
|
||||
const nr_pdcp_entity_t *drb = ue->drb[i];
|
||||
if (drb && drb->pdusession_id == pdusession_id)
|
||||
nr_pdcp_release_drb(ue_id, i + 1);
|
||||
}
|
||||
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
|
||||
}
|
||||
|
||||
void nr_pdcp_reestablishment(ue_id_t ue_id,
|
||||
int rb_id,
|
||||
bool srb_flag,
|
||||
|
||||
@@ -69,6 +69,7 @@ void nr_pdcp_reconfigure_srb(ue_id_t ue_id, int srb_id, long t_Reordering);
|
||||
void nr_pdcp_reconfigure_drb(ue_id_t ue_id, int drb_id, NR_PDCP_Config_t *pdcp_config);
|
||||
void nr_pdcp_release_srb(ue_id_t ue_id, int srb_id);
|
||||
void nr_pdcp_release_drb(ue_id_t ue_id, int drb_id);
|
||||
void nr_pdcp_release_from_pdusession(ue_id_t ue_id, long pdusession_id);
|
||||
|
||||
void add_srb(int is_gnb,
|
||||
ue_id_t UEid,
|
||||
|
||||
@@ -689,7 +689,7 @@ static void rrc_gNB_generate_dedicatedRRCReconfiguration(gNB_RRC_INST *rrc, gNB_
|
||||
{
|
||||
/* do not re-establish PDCP for any bearer */
|
||||
nr_rrc_reconfig_param_t params = get_RRCReconfiguration_params(rrc, ue_p, 0, false);
|
||||
ue_p->xids[params.transaction_id] = RRC_PDUSESSION_ESTABLISH;
|
||||
ue_p->xids[params.transaction_id] = RRC_DEDICATED_RECONF;
|
||||
byte_array_t msg = rrc_gNB_encode_RRCReconfiguration(rrc, ue_p, params);
|
||||
if (msg.len <= 0) {
|
||||
LOG_E(NR_RRC, "UE %d: Failed to generate RRCReconfiguration\n", ue_p->rrc_ue_id);
|
||||
@@ -697,10 +697,11 @@ static void rrc_gNB_generate_dedicatedRRCReconfiguration(gNB_RRC_INST *rrc, gNB_
|
||||
}
|
||||
|
||||
for (int i = 0; i < ue_p->nb_of_pdusessions; i++) {
|
||||
if (ue_p->pduSession[i].param.nas_pdu.buf != NULL) {
|
||||
if (params.num_nas_msg > 0) {
|
||||
ue_p->pduSession[i].xid = params.transaction_id;
|
||||
ue_p->xids[params.transaction_id] = RRC_PDUSESSION_ESTABLISH;
|
||||
}
|
||||
if (ue_p->pduSession[i].status < PDU_SESSION_STATUS_ESTABLISHED) {
|
||||
if (ue_p->pduSession[i].status == PDU_SESSION_STATUS_NEW || ue_p->pduSession[i].status == PDU_SESSION_STATUS_RELEASED) {
|
||||
ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE;
|
||||
}
|
||||
}
|
||||
@@ -792,24 +793,46 @@ void rrc_gNB_modify_dedicatedRRCReconfiguration(gNB_RRC_INST *rrc, gNB_RRC_UE_t
|
||||
free_byte_array(msg);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef struct deliver_ue_ctxt_modification_data_t {
|
||||
gNB_RRC_INST *rrc;
|
||||
f1ap_ue_context_mod_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;
|
||||
byte_array_t rrc_cont = {.buf = (uint8_t *)buf, .len = size};
|
||||
data->modification_req->rrc_container = &rrc_cont;
|
||||
data->rrc->mac_rrc.ue_context_modification_request(data->assoc_id, data->modification_req);
|
||||
}
|
||||
void rrc_gNB_generate_dedicatedRRCReconfiguration_release(gNB_RRC_INST *rrc,
|
||||
gNB_RRC_UE_t *ue_p,
|
||||
uint8_t xid,
|
||||
uint32_t nas_length,
|
||||
uint8_t *nas_buffer)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
NR_DRB_ToReleaseList_t *DRB_Release_configList2 = CALLOC(sizeof(*DRB_Release_configList2), 1);
|
||||
f1ap_drb_to_release_t rel_drbs[32];
|
||||
int n_rel_drbs = 0;
|
||||
|
||||
NR_DRB_ToReleaseList_t *drb_release_list = calloc_or_fail(1, sizeof(*drb_release_list));
|
||||
if (!ue_p->DRB_ReleaseList)
|
||||
ue_p->DRB_ReleaseList = calloc_or_fail(1, sizeof(*ue_p->DRB_ReleaseList));
|
||||
|
||||
for (int i = 0; i < NB_RB_MAX; i++) {
|
||||
if ((ue_p->pduSession[i].status == PDU_SESSION_STATUS_TORELEASE) && ue_p->pduSession[i].xid == xid) {
|
||||
asn1cSequenceAdd(DRB_Release_configList2->list, NR_DRB_Identity_t, DRB_release);
|
||||
asn1cSequenceAdd(drb_release_list->list, NR_DRB_Identity_t, DRB_release);
|
||||
asn1cSequenceAdd(ue_p->DRB_ReleaseList->list, NR_DRB_Identity_t, DRB_release2);
|
||||
*DRB_release = i + 1;
|
||||
*DRB_release2 = i + 1;
|
||||
rel_drbs[n_rel_drbs].id = *DRB_release;
|
||||
n_rel_drbs++;
|
||||
memset(&ue_p->established_drbs[i], 0, sizeof(drb_t));
|
||||
}
|
||||
}
|
||||
|
||||
nr_rrc_reconfig_param_t params = {.drb_release_list = DRB_Release_configList2, .transaction_id = xid};
|
||||
nr_rrc_reconfig_param_t params = {.drb_release_list = drb_release_list, .transaction_id = xid};
|
||||
if (nas_length > 0) {
|
||||
params.dedicated_NAS_msg_list[params.num_nas_msg].buf = nas_buffer;
|
||||
params.dedicated_NAS_msg_list[params.num_nas_msg++].len = nas_length;
|
||||
@@ -821,8 +844,30 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration_release(gNB_RRC_INST *rrc,
|
||||
}
|
||||
LOG_DUMPMSG(NR_RRC, DEBUG_RRC, msg.buf, msg.len, "[MSG] RRC Reconfiguration\n");
|
||||
LOG_I(NR_RRC, "UE %d: Generate NR_RRCReconfiguration (bytes %ld)\n", ue_p->rrc_ue_id, msg.len);
|
||||
const uint32_t msg_id = NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration;
|
||||
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DL_SCH_LCID_DCCH, msg_id, msg.buf, msg.len);
|
||||
|
||||
f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id);
|
||||
plmn_id_t plmn = rrc->configuration.plmn[0];
|
||||
uint64_t nr_cellid = rrc->nr_cellid;
|
||||
f1ap_ue_context_mod_req_t ue_context_modif_req = {
|
||||
.gNB_CU_ue_id = ue_p->rrc_ue_id,
|
||||
.gNB_DU_ue_id = ue_data.secondary_ue,
|
||||
.plmn = &plmn,
|
||||
.nr_cellid = &nr_cellid,
|
||||
.servCellIndex = 0,
|
||||
.drbs_rel_len = n_rel_drbs,
|
||||
.drbs_rel = (f1ap_drb_to_release_t *)rel_drbs,
|
||||
};
|
||||
deliver_ue_ctxt_modification_data_t data = {.rrc = rrc,
|
||||
.modification_req = &ue_context_modif_req,
|
||||
.assoc_id = ue_data.du_assoc_id};
|
||||
nr_pdcp_data_req_srb(ue_p->rrc_ue_id,
|
||||
DL_SCH_LCID_DCCH,
|
||||
rrc_gNB_mui++,
|
||||
msg.len,
|
||||
(unsigned char *const)msg.buf,
|
||||
rrc_deliver_ue_ctxt_modif_req,
|
||||
&data);
|
||||
|
||||
free_RRCReconfiguration_params(params);
|
||||
free_byte_array(msg);
|
||||
}
|
||||
@@ -1771,8 +1816,6 @@ static void handle_rrcReconfigurationComplete(gNB_RRC_INST *rrc, gNB_RRC_UE_t *U
|
||||
|
||||
switch (UE->xids[xid]) {
|
||||
case RRC_PDUSESSION_RELEASE: {
|
||||
gtpv1u_gnb_delete_tunnel_req_t req = {0};
|
||||
gtpv1u_delete_ngu_tunnel(rrc->module_id, &req);
|
||||
// NGAP_PDUSESSION_RELEASE_RESPONSE
|
||||
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(rrc, UE, xid);
|
||||
} break;
|
||||
|
||||
@@ -1436,14 +1436,15 @@ void rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(gNB_RRC_INST *rrc, gNB_RRC_UE
|
||||
memset(resp, 0, sizeof(*resp));
|
||||
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) {
|
||||
for (int i = 0; i < NGAP_MAX_PDU_SESSION; i++) {
|
||||
if (UE->pduSession[i].status == PDU_SESSION_STATUS_TORELEASE && xid == UE->pduSession[i].xid) {
|
||||
resp->pdusession_release[pdu_sessions_released].pdusession_id = UE->pduSession[i].param.pdusession_id;
|
||||
pdu_sessions_released++;
|
||||
//clear
|
||||
memset(&UE->pduSession[i], 0, sizeof(*UE->pduSession));
|
||||
UE->pduSession[i].status = PDU_SESSION_STATUS_RELEASED;
|
||||
LOG_W(NR_RRC, "Released pdu session, but code to finish to free memory\n");
|
||||
UE->nb_of_pdusessions--;
|
||||
LOG_W(NR_RRC, "Released pdu session, current nb_of_pdusessions %d for UE %x\n", UE->nb_of_pdusessions, UE->rnti);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1472,7 +1473,7 @@ int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_
|
||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||
LOG_I(
|
||||
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;
|
||||
e1ap_bearer_mod_req_t req = {0};
|
||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(rrc->module_id);
|
||||
UE->xids[xid] = RRC_PDUSESSION_RELEASE;
|
||||
for (int pdusession = 0; pdusession < cmd->nb_pdusessions_torelease; pdusession++) {
|
||||
@@ -1491,14 +1492,23 @@ int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_
|
||||
continue;
|
||||
}
|
||||
if (pduSession->status == PDU_SESSION_STATUS_ESTABLISHED) {
|
||||
found = true;
|
||||
LOG_I(NR_RRC, "RELEASE pdusession %d \n", pduSession->param.pdusession_id);
|
||||
req.pduSessionRem[req.numPDUSessionsRem].sessionId = pduSession->param.pdusession_id;
|
||||
req.pduSessionRem[req.numPDUSessionsRem].cause.type = E1AP_CAUSE_RADIO_NETWORK;
|
||||
req.pduSessionRem[req.numPDUSessionsRem].cause.value = E1AP_RADIO_CAUSE_NORMAL_RELEASE;
|
||||
req.numPDUSessionsRem++;
|
||||
pduSession->status = PDU_SESSION_STATUS_TORELEASE;
|
||||
pduSession->xid = xid;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
if (req.numPDUSessionsRem > 0) {
|
||||
if (ue_associated_to_cuup(rrc, UE)) {
|
||||
req.gNB_cu_cp_ue_id = UE->rrc_ue_id;
|
||||
req.gNB_cu_up_ue_id = UE->rrc_ue_id;
|
||||
sctp_assoc_t assoc_id = get_existing_cuup_for_ue(rrc, UE);
|
||||
rrc->cucp_cuup.bearer_context_mod(assoc_id, &req);
|
||||
}
|
||||
// TODO RRCReconfiguration To UE
|
||||
LOG_I(NR_RRC, "Send RRCReconfiguration To UE \n");
|
||||
rrc_gNB_generate_dedicatedRRCReconfiguration_release(rrc, UE, xid, cmd->nas_pdu.len, cmd->nas_pdu.buf);
|
||||
|
||||
@@ -43,17 +43,23 @@ void cp_pdusession(pdusession_t *dst, const pdusession_t *src)
|
||||
|
||||
rrc_pdu_session_param_t *find_pduSession(gNB_RRC_UE_t *ue, int id, bool create)
|
||||
{
|
||||
int j;
|
||||
for (j = 0; j < ue->nb_of_pdusessions; j++)
|
||||
if (id == ue->pduSession[j].param.pdusession_id)
|
||||
break;
|
||||
if (j == ue->nb_of_pdusessions) {
|
||||
if (create)
|
||||
ue->nb_of_pdusessions++;
|
||||
else
|
||||
return NULL;
|
||||
for (int j = 0; j < NGAP_MAX_PDU_SESSION; j++) {
|
||||
if (ue->pduSession[j].param.pdusession_id == id)
|
||||
return &ue->pduSession[j];
|
||||
}
|
||||
return ue->pduSession + j;
|
||||
|
||||
if (create && ue->nb_of_pdusessions < NGAP_MAX_PDU_SESSION) {
|
||||
ue->nb_of_pdusessions++;
|
||||
AssertFatal(ue->nb_of_pdusessions <= NGAP_MAX_PDU_SESSION,
|
||||
"nb_of_pdusessions %i exceeds NGAP_MAX_PDU_SESSION %i\n",
|
||||
ue->nb_of_pdusessions,
|
||||
NGAP_MAX_PDU_SESSION);
|
||||
for (int j = 0; j < NGAP_MAX_PDU_SESSION; j++) {
|
||||
if (ue->pduSession[j].param.pdusession_id == 0)
|
||||
return &ue->pduSession[j];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rrc_pdu_session_param_t *find_pduSession_from_drbId(gNB_RRC_UE_t *ue, int drb_id)
|
||||
|
||||
@@ -611,7 +611,8 @@ bool nr_sdap_delete_entity(ue_id_t ue_id, int pdusession_id)
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
LOG_E(SDAP, "Entity does not exist or it was not found.\n");
|
||||
if (!ret)
|
||||
LOG_E(SDAP, "Entity does not exist or it was not found.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user