Merge remote-tracking branch 'origin/nr-rrcreestablishment-fix-multipdu-proper-commits' into integration_2023_w14
This commit is contained in:
@@ -271,6 +271,40 @@ typedef struct pdu_session_param_s {
|
||||
uint8_t cause_value;
|
||||
} rrc_pdu_session_param_t;
|
||||
|
||||
typedef struct drb_s {
|
||||
int status;
|
||||
int defaultDRBid;
|
||||
int drb_id;
|
||||
int reestablishPDCP;
|
||||
int recoverPDCP;
|
||||
int daps_Config_r16;
|
||||
struct cnAssociation_s {
|
||||
int present;
|
||||
int eps_BearerIdentity;
|
||||
struct sdap_config_s {
|
||||
bool defaultDRB;
|
||||
int pdusession_id;
|
||||
int sdap_HeaderDL;
|
||||
int sdap_HeaderUL;
|
||||
int mappedQoS_FlowsToAdd[QOSFLOW_MAX_VALUE];
|
||||
} sdap_config;
|
||||
} cnAssociation;
|
||||
struct pdcp_config_s {
|
||||
int discardTimer;
|
||||
int pdcp_SN_SizeUL;
|
||||
int pdcp_SN_SizeDL;
|
||||
int t_Reordering;
|
||||
int integrityProtection;
|
||||
struct headerCompression_s {
|
||||
int NotUsed;
|
||||
int present;
|
||||
} headerCompression;
|
||||
struct ext1_s {
|
||||
int cipheringDisabled;
|
||||
} ext1;
|
||||
} pdcp_config;
|
||||
} drb_t;
|
||||
|
||||
typedef struct gNB_RRC_UE_s {
|
||||
uint8_t primaryCC_id;
|
||||
NR_SRB_ToAddModList_t *SRB_configList;
|
||||
@@ -278,6 +312,7 @@ typedef struct gNB_RRC_UE_s {
|
||||
NR_DRB_ToAddModList_t *DRB_configList;
|
||||
NR_DRB_ToAddModList_t *DRB_configList2[NR_RRC_TRANSACTION_IDENTIFIER_NUMBER];
|
||||
NR_DRB_ToReleaseList_t *DRB_Release_configList2[NR_RRC_TRANSACTION_IDENTIFIER_NUMBER];
|
||||
drb_t established_drbs[NGAP_MAX_DRBS_PER_UE];
|
||||
uint8_t DRB_active[NGAP_MAX_DRBS_PER_UE];
|
||||
|
||||
NR_SRB_INFO_TABLE_ENTRY Srb[maxSRBs]; // 3gpp max is 3 SRBs, number 1..3, we waste the entry 0 for code simplicity
|
||||
|
||||
+196
-118
@@ -643,7 +643,8 @@ void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP,
|
||||
if(drb_is_active(ue_p, drb_id)){ /* Non-GBR flow using the same DRB or a GBR flow with no available DRBs*/
|
||||
nb_drb_to_setup--;
|
||||
} else {
|
||||
NR_DRB_ToAddMod_t *DRB_config = generateDRB(ue_p, drb_id, &ue_p->pduSession[i], rrc->configuration.enable_sdap, rrc->security.do_drb_integrity, rrc->security.do_drb_ciphering);
|
||||
generateDRB(ue_p, drb_id, &ue_p->pduSession[i], rrc->configuration.enable_sdap, rrc->security.do_drb_integrity, rrc->security.do_drb_ciphering);
|
||||
NR_DRB_ToAddMod_t *DRB_config = generateDRB_ASN1(&ue_p->established_drbs[drb_id-1]);
|
||||
if (drb_id_to_setup_start == 0)
|
||||
drb_id_to_setup_start = DRB_config->drb_Identity;
|
||||
asn1cSeqAdd(&ue_p->DRB_configList->list, DRB_config);
|
||||
@@ -1279,39 +1280,38 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP,
|
||||
nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
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)
|
||||
//-----------------------------------------------------------------------------
|
||||
/*
|
||||
* Handle RRC Reestablishment Complete Functions
|
||||
*/
|
||||
|
||||
/// @brief Function used in RRCReestablishmentComplete procedure to reestablish the SRB2.
|
||||
/// @param old_xid The old RRC transaction id.
|
||||
/// @param new_xid The new RRC transaction id.
|
||||
void RRCReestablishmentComplete_fill_SRB2_configList(const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *ue_context_pP,
|
||||
const uint8_t old_xid,
|
||||
const uint8_t new_xid)
|
||||
{
|
||||
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
||||
LOG_I(NR_RRC, "[RAPROC] UE %04x Logical Channel UL-DCCH, processing NR_RRCReestablishmentComplete from UE (SRB1 Active)\n", ue_p->rnti);
|
||||
|
||||
NR_DRB_ToAddModList_t *DRB_configList = ue_p->DRB_configList;
|
||||
NR_SRB_ToAddMod_t *SRB2_config = NULL;
|
||||
NR_SRB_ToAddModList_t *SRB_configList = ue_p->SRB_configList;
|
||||
NR_SRB_ToAddModList_t **SRB_configList2 = NULL;
|
||||
NR_DRB_ToAddModList_t **DRB_configList2 = NULL;
|
||||
NR_SRB_ToAddMod_t *SRB2_config = NULL;
|
||||
NR_DRB_ToAddMod_t *DRB_config = NULL;
|
||||
//NR_SDAP_Config_t *sdap_config = NULL;
|
||||
int i = 0;
|
||||
NR_SRB_ToAddModList_t **SRB_configList2 = NULL;
|
||||
|
||||
uint8_t new_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
|
||||
int ret = 0;
|
||||
ue_p->StatusRrc = NR_RRC_CONNECTED;
|
||||
ue_p->ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED
|
||||
ue_p->reestablishment_xid = new_xid;
|
||||
SRB_configList2 = &ue_p->SRB_configList2[xid];
|
||||
SRB_configList2 = &ue_p->SRB_configList2[old_xid];
|
||||
|
||||
// get old configuration of SRB2
|
||||
if (*SRB_configList2 != NULL) {
|
||||
if((*SRB_configList2)->list.count!=0) {
|
||||
LOG_D(NR_RRC, "SRB_configList2(%p) count is %d\n SRB_configList2->list.array[0] addr is %p",
|
||||
SRB_configList2, (*SRB_configList2)->list.count, (*SRB_configList2)->list.array[0]);
|
||||
if ((*SRB_configList2)->list.count != 0) {
|
||||
LOG_D(NR_RRC,
|
||||
"RRC Reestablishment - SRB_configList2(%p) count is %d\n SRB_configList2->list.array[0] addr is %p\n",
|
||||
SRB_configList2,
|
||||
(*SRB_configList2)->list.count,
|
||||
(*SRB_configList2)->list.array[0]);
|
||||
}
|
||||
|
||||
for (i = 0; (i < (*SRB_configList2)->list.count) && (i < 3); i++) {
|
||||
if ((*SRB_configList2)->list.array[i]->srb_Identity == 2 ) {
|
||||
LOG_D(NR_RRC, "get SRB2_config from (ue_p->SRB_configList2[%d])\n", xid);
|
||||
for (int i = 0; (i < (*SRB_configList2)->list.count) && (i < 3); i++) {
|
||||
if ((*SRB_configList2)->list.array[i]->srb_Identity == 2) {
|
||||
LOG_D(NR_RRC, "RRC Reestablishment - get SRB2_config from (ue_p->SRB_configList2[%d])\n", old_xid);
|
||||
SRB2_config = (*SRB_configList2)->list.array[i];
|
||||
SRB2_config->reestablishPDCP = CALLOC(1, sizeof(*SRB2_config->reestablishPDCP));
|
||||
*SRB2_config->reestablishPDCP = NR_SRB_ToAddMod__reestablishPDCP_true;
|
||||
@@ -1320,15 +1320,11 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx
|
||||
}
|
||||
}
|
||||
|
||||
// SRB2_config = CALLOC(1, sizeof(*SRB2_config));
|
||||
// SRB2_config->srb_Identity = 2;
|
||||
|
||||
SRB_configList2 = &(ue_p->SRB_configList2[new_xid]);
|
||||
DRB_configList2 = &(ue_p->DRB_configList2[new_xid]);
|
||||
|
||||
if (*SRB_configList2) {
|
||||
free(*SRB_configList2);
|
||||
LOG_D(NR_RRC, "free(ue_p->SRB_configList2[%d])\n", new_xid);
|
||||
LOG_D(NR_RRC, "RRC Reestablishment - free(ue_p->SRB_configList2[%d])\n", new_xid);
|
||||
}
|
||||
|
||||
*SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
|
||||
@@ -1337,42 +1333,74 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx
|
||||
// Add SRB2 to SRB configuration list
|
||||
asn1cSeqAdd(&SRB_configList->list, SRB2_config);
|
||||
asn1cSeqAdd(&(*SRB_configList2)->list, SRB2_config);
|
||||
LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_p->SRB_configList\n", SRB2_config->srb_Identity);
|
||||
LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_p->SRB_configList2[%d]\n", SRB2_config->srb_Identity, new_xid);
|
||||
LOG_D(NR_RRC, "RRC Reestablishment - Add SRB2_config (srb_Identity:%ld) to ue_p->SRB_configList\n", SRB2_config->srb_Identity);
|
||||
LOG_D(NR_RRC,
|
||||
"RRC Reestablishment - Add SRB2_config (srb_Identity:%ld) to ue_p->SRB_configList2[%d]\n",
|
||||
SRB2_config->srb_Identity,
|
||||
new_xid);
|
||||
} else {
|
||||
// SRB configuration list only contains SRB1.
|
||||
LOG_W(NR_RRC,"SRB2 configuration does not exist in SRB configuration list\n");
|
||||
}
|
||||
|
||||
if (*DRB_configList2) {
|
||||
free(*DRB_configList2);
|
||||
LOG_D(NR_RRC, "free(ue_p->DRB_configList2[%d])\n", new_xid);
|
||||
}
|
||||
|
||||
*DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2));
|
||||
|
||||
if (DRB_configList != NULL) {
|
||||
LOG_D(NR_RRC, "get DRB_config from (ue_p->DRB_configList)\n");
|
||||
|
||||
for (i = 0; (i < DRB_configList->list.count) && (i < 3); i++) {
|
||||
DRB_config = DRB_configList->list.array[i];
|
||||
asn1cCallocOne(DRB_config->reestablishPDCP, NR_DRB_ToAddMod__reestablishPDCP_true);
|
||||
// Add DRB to DRB configuration list, for LTE_RRCConnectionReconfigurationComplete
|
||||
asn1cSeqAdd(&(*DRB_configList2)->list, DRB_config);
|
||||
}
|
||||
LOG_W(NR_RRC, "RRC Reestablishment - SRB2 configuration does not exist in SRB configuration list\n");
|
||||
}
|
||||
|
||||
ue_p->Srb[1].Active = 1;
|
||||
|
||||
if (get_softmodem_params()->sa) {
|
||||
LOG_W(NR_RRC, "Rework identity mapping need to be done properly!\n");
|
||||
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0};
|
||||
uint8_t send_security_mode_command = false;
|
||||
nr_rrc_pdcp_config_security(ctxt_pP, ue_context_pP, send_security_mode_command);
|
||||
LOG_D(NR_RRC, "RRC Reestablishment - set security successfully \n");
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Function used in RRCReestablishmentComplete procedure to reestablish the DRBs
|
||||
/// that the UE previously had, it gets the information from the established_drbs
|
||||
/// struct.
|
||||
/// @param new_xid The new RRC transaction id.
|
||||
void RRCReestablishmentComplete_fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *ue_context_pP,
|
||||
const uint8_t new_xid)
|
||||
{
|
||||
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
||||
NR_DRB_ToAddMod_t *DRB_config = NULL;
|
||||
NR_DRB_ToAddModList_t **DRB_configList2 = &(ue_p->DRB_configList2[new_xid]);
|
||||
|
||||
if (*DRB_configList2) {
|
||||
free(*DRB_configList2);
|
||||
LOG_D(NR_RRC, "RRC Reestablishment - free(ue_p->DRB_configList2[%d])\n", new_xid);
|
||||
}
|
||||
|
||||
*DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2));
|
||||
|
||||
for (int i = 0; i < NGAP_MAX_DRBS_PER_UE; i++) {
|
||||
if (ue_p->established_drbs[i].status != DRB_INACTIVE) {
|
||||
ue_p->established_drbs[i].reestablishPDCP = NR_DRB_ToAddMod__reestablishPDCP_true;
|
||||
DRB_config = generateDRB_ASN1(&ue_p->established_drbs[i]);
|
||||
asn1cCallocOne(DRB_config->reestablishPDCP, NR_DRB_ToAddMod__reestablishPDCP_true);
|
||||
asn1cSeqAdd(&(*DRB_configList2)->list, DRB_config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @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 */
|
||||
int j;
|
||||
|
||||
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.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;
|
||||
@@ -1383,14 +1411,11 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx
|
||||
}
|
||||
|
||||
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);
|
||||
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, "gtpv1u_update_ngu_tunnel failed,start to release UE %x\n", reestablish_rnti);
|
||||
if (ret != 0) {
|
||||
LOG_E(NR_RRC, "RRC Reestablishment - gtpv1u_update_ngu_tunnel failed,start to release UE %x\n", reestablish_rnti);
|
||||
ue_p->ue_release_timer_s1 = 1;
|
||||
ue_p->ue_release_timer_thres_s1 = 100;
|
||||
ue_p->ue_release_timer = 0;
|
||||
@@ -1400,34 +1425,72 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Function tha processes RRCReestablishmentComplete message sent by the UE, after RRCReestasblishment request.
|
||||
/// @param ctxt_pP Protocol context containing information regarding the UE and gNB
|
||||
/// @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)
|
||||
{
|
||||
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
||||
LOG_I(NR_RRC,
|
||||
"[RAPROC] UE %04x Logical Channel UL-DCCH, processing NR_RRCReestablishmentComplete from UE (SRB1 Active)\n",
|
||||
ue_p->rnti);
|
||||
|
||||
int i = 0;
|
||||
|
||||
uint8_t new_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
|
||||
ue_p->StatusRrc = NR_RRC_CONNECTED;
|
||||
ue_p->ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED
|
||||
ue_p->reestablishment_xid = new_xid;
|
||||
|
||||
RRCReestablishmentComplete_fill_SRB2_configList(ctxt_pP, ue_context_pP, xid, new_xid);
|
||||
RRCReestablishmentComplete_fill_DRB_configList(ctxt_pP, ue_context_pP, new_xid);
|
||||
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, "Updating UEid from %04x to %lx\n", ue_p->rnti, ctxt_pP->rntiMaybeUEid);
|
||||
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);
|
||||
|
||||
if (get_softmodem_params()->sa) {
|
||||
uint8_t send_security_mode_command = false;
|
||||
nr_rrc_pdcp_config_security(
|
||||
ctxt_pP,
|
||||
ue_context_pP,
|
||||
send_security_mode_command ? 0 : 1);
|
||||
LOG_D(NR_RRC, "set security successfully \n");
|
||||
}
|
||||
|
||||
uint8_t drb_id_to_setup_start = DRB_configList ? DRB_configList->list.array[0]->drb_Identity : 1;
|
||||
uint8_t nb_drb_to_setup = DRB_configList ? DRB_configList->list.count : ue_p->nb_of_pdusessions;
|
||||
/* TODO: hardcoded to 13 for the time being, to be changed? */
|
||||
long drb_priority[NGAP_MAX_DRBS_PER_UE] = {13};
|
||||
|
||||
/* Add all NAS PDUs to the list */
|
||||
for (i = 0; i < ue_p->nb_of_pdusessions; i++) {
|
||||
/* TODO parameters yet to process ... */
|
||||
/* TODO should test if pdu session are Ok before! */
|
||||
ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE;
|
||||
ue_p->pduSession[i].xid = xid;
|
||||
LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", i, ue_p->pduSession[i].status, "PDU_SESSION_STATUS_DONE");
|
||||
}
|
||||
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t));
|
||||
|
||||
@@ -1435,51 +1498,62 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx
|
||||
ue_p->masterCellGroup->spCellConfig = ue_p->spCellConfigReestablishment;
|
||||
ue_p->spCellConfigReestablishment = NULL;
|
||||
cellGroupConfig->spCellConfig = ue_p->masterCellGroup->spCellConfig;
|
||||
cellGroupConfig->physicalCellGroupConfig = ue_p->masterCellGroup->physicalCellGroupConfig;
|
||||
cellGroupConfig->physicalCellGroupConfig = ue_p->masterCellGroup->physicalCellGroupConfig;
|
||||
|
||||
fill_mastercellGroupConfig(cellGroupConfig, ue_p->masterCellGroup, rrc->um_on_default_drb, (drb_id_to_setup_start < 2) ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority);
|
||||
uint8_t drb_id_to_setup_start = ue_p->DRB_configList ? ue_p->DRB_configList->list.array[0]->drb_Identity : 1;
|
||||
uint8_t nb_drb_to_setup = ue_p->DRB_configList ? ue_p->DRB_configList->list.count : ue_p->nb_of_pdusessions;
|
||||
/* TODO: hardcoded to 13 for the time being, to be changed? */
|
||||
long drb_priority[NGAP_MAX_DRBS_PER_UE] = {13};
|
||||
|
||||
for(i = 0; i < cellGroupConfig->rlc_BearerToAddModList->list.count; i++) {
|
||||
cellGroupConfig->rlc_BearerToAddModList->list.array[i]->reestablishRLC = CALLOC(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList->list.array[i]->reestablishRLC));
|
||||
fill_mastercellGroupConfig(cellGroupConfig,
|
||||
ue_p->masterCellGroup,
|
||||
rrc->um_on_default_drb,
|
||||
(drb_id_to_setup_start < 2) ? 1 : 0,
|
||||
drb_id_to_setup_start,
|
||||
nb_drb_to_setup,
|
||||
drb_priority);
|
||||
|
||||
for (i = 0; i < cellGroupConfig->rlc_BearerToAddModList->list.count; i++) {
|
||||
cellGroupConfig->rlc_BearerToAddModList->list.array[i]->reestablishRLC =
|
||||
CALLOC(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList->list.array[i]->reestablishRLC));
|
||||
*cellGroupConfig->rlc_BearerToAddModList->list.array[i]->reestablishRLC = NR_RLC_BearerConfig__reestablishRLC_true;
|
||||
}
|
||||
|
||||
uint8_t buffer[RRC_BUF_SIZE] = {0};
|
||||
int size = do_RRCReconfiguration(ctxt_pP,
|
||||
buffer,
|
||||
RRC_BUF_SIZE,
|
||||
new_xid,
|
||||
*SRB_configList2,
|
||||
DRB_configList,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, // MeasObj_list,
|
||||
NULL,
|
||||
ue_context_pP,
|
||||
&rrc->carrier,
|
||||
NULL,
|
||||
NULL,
|
||||
cellGroupConfig);
|
||||
buffer,
|
||||
RRC_BUF_SIZE,
|
||||
new_xid,
|
||||
ue_p->SRB_configList2[new_xid],
|
||||
ue_p->DRB_configList2[new_xid],
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, // MeasObj_list,
|
||||
NULL,
|
||||
ue_context_pP,
|
||||
&rrc->carrier,
|
||||
NULL,
|
||||
NULL,
|
||||
cellGroupConfig);
|
||||
|
||||
LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Reconfiguration\n");
|
||||
LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buffer, size, "[MSG] RRC Reconfiguration\n");
|
||||
|
||||
/* Free all NAS PDUs */
|
||||
for (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;
|
||||
}
|
||||
}
|
||||
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_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",
|
||||
"[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,
|
||||
@@ -1493,12 +1567,16 @@ cellGroupConfig->physicalCellGroupConfig = ue_p->masterCellGroup->physicalCellGr
|
||||
}
|
||||
|
||||
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 && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated
|
||||
uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig
|
||||
&& ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated
|
||||
&& ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList
|
||||
? NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS
|
||||
: NR_RRC_RECONFIGURATION_DELAY_MS;
|
||||
|
||||
nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, ue_p->rnti, *RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, delay_ms);
|
||||
nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id,
|
||||
ue_p->rnti,
|
||||
*RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing,
|
||||
delay_ms);
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -36,65 +36,109 @@ rrc_pdu_session_param_t *find_pduSession(gNB_RRC_UE_t *ue, int id, bool create)
|
||||
return ue->pduSession + j;
|
||||
}
|
||||
|
||||
NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *ue, uint8_t drb_id, rrc_pdu_session_param_t *pduSession, bool enable_sdap, int do_drb_integrity, int do_drb_ciphering)
|
||||
void generateDRB(gNB_RRC_UE_t *ue,
|
||||
uint8_t drb_id,
|
||||
rrc_pdu_session_param_t *pduSession,
|
||||
bool enable_sdap,
|
||||
int do_drb_integrity,
|
||||
int do_drb_ciphering)
|
||||
{
|
||||
int i;
|
||||
int qos_flow_index;
|
||||
drb_t *est_drb = &ue->established_drbs[drb_id - 1];
|
||||
if (est_drb->status == DRB_INACTIVE) {
|
||||
/* DRB Management */
|
||||
est_drb->drb_id = drb_id;
|
||||
est_drb->reestablishPDCP = -1;
|
||||
est_drb->recoverPDCP = -1;
|
||||
for (i = 0; i < NGAP_MAX_DRBS_PER_UE; i++) {
|
||||
if ((est_drb->cnAssociation.sdap_config.pdusession_id == 0
|
||||
|| est_drb->cnAssociation.sdap_config.pdusession_id == pduSession->param.pdusession_id)
|
||||
&& est_drb->defaultDRBid == 0) {
|
||||
est_drb->cnAssociation.sdap_config.defaultDRB = true;
|
||||
est_drb->defaultDRBid = drb_id;
|
||||
}
|
||||
}
|
||||
/* SDAP Configuration */
|
||||
est_drb->cnAssociation.present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config;
|
||||
est_drb->cnAssociation.sdap_config.pdusession_id = pduSession->param.pdusession_id;
|
||||
if (enable_sdap) {
|
||||
est_drb->cnAssociation.sdap_config.sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present;
|
||||
est_drb->cnAssociation.sdap_config.sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_present;
|
||||
} else {
|
||||
est_drb->cnAssociation.sdap_config.sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent;
|
||||
est_drb->cnAssociation.sdap_config.sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent;
|
||||
}
|
||||
for (qos_flow_index = 0; qos_flow_index < pduSession->param.nb_qos; qos_flow_index++) {
|
||||
est_drb->cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] = pduSession->param.qos[qos_flow_index].qfi;
|
||||
if (pduSession->param.qos[qos_flow_index].fiveQI > 5)
|
||||
est_drb->status = DRB_ACTIVE_NONGBR;
|
||||
else
|
||||
est_drb->status = DRB_ACTIVE;
|
||||
}
|
||||
/* PDCP Configuration */
|
||||
est_drb->pdcp_config.discardTimer = NR_PDCP_Config__drb__discardTimer_infinity;
|
||||
est_drb->pdcp_config.pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits;
|
||||
est_drb->pdcp_config.pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
|
||||
est_drb->pdcp_config.t_Reordering = NR_PDCP_Config__t_Reordering_ms100;
|
||||
est_drb->pdcp_config.headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
|
||||
est_drb->pdcp_config.headerCompression.NotUsed = 0;
|
||||
if (do_drb_integrity)
|
||||
est_drb->pdcp_config.integrityProtection = NR_PDCP_Config__drb__integrityProtection_enabled;
|
||||
else
|
||||
est_drb->pdcp_config.integrityProtection = 1;
|
||||
if (do_drb_ciphering)
|
||||
est_drb->pdcp_config.ext1.cipheringDisabled = 1;
|
||||
else
|
||||
est_drb->pdcp_config.ext1.cipheringDisabled = NR_PDCP_Config__ext1__cipheringDisabled_true;
|
||||
}
|
||||
}
|
||||
|
||||
NR_DRB_ToAddMod_t *generateDRB_ASN1(const drb_t *drb_asn1)
|
||||
{
|
||||
NR_DRB_ToAddMod_t *DRB_config = CALLOC(1, sizeof(*DRB_config));
|
||||
DRB_config->drb_Identity = drb_id;
|
||||
NR_SDAP_Config_t *SDAP_config = CALLOC(1, sizeof(NR_SDAP_Config_t));
|
||||
|
||||
asn1cCalloc(DRB_config->cnAssociation, association);
|
||||
association->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config;
|
||||
asn1cCalloc(SDAP_config->mappedQoS_FlowsToAdd, sdapFlows);
|
||||
asn1cCalloc(DRB_config->pdcp_Config, pdcpConfig);
|
||||
asn1cCalloc(pdcpConfig->drb, drb);
|
||||
|
||||
DRB_config->drb_Identity = drb_asn1->drb_id;
|
||||
association->present = drb_asn1->cnAssociation.present;
|
||||
|
||||
/* SDAP Configuration */
|
||||
NR_SDAP_Config_t *SDAP_config = CALLOC(1, sizeof(NR_SDAP_Config_t));
|
||||
asn1cCalloc(SDAP_config->mappedQoS_FlowsToAdd, sdapFlows);
|
||||
SDAP_config->pdu_Session = drb_asn1->cnAssociation.sdap_config.pdusession_id;
|
||||
SDAP_config->sdap_HeaderDL = drb_asn1->cnAssociation.sdap_config.sdap_HeaderDL;
|
||||
SDAP_config->sdap_HeaderUL = drb_asn1->cnAssociation.sdap_config.sdap_HeaderUL;
|
||||
SDAP_config->defaultDRB = drb_asn1->cnAssociation.sdap_config.defaultDRB;
|
||||
|
||||
SDAP_config->pdu_Session = pduSession->param.pdusession_id;
|
||||
|
||||
if (enable_sdap) {
|
||||
SDAP_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present;
|
||||
SDAP_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_present;
|
||||
} else {
|
||||
SDAP_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent;
|
||||
SDAP_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent;
|
||||
}
|
||||
|
||||
SDAP_config->defaultDRB = true;
|
||||
|
||||
for (int qos_flow_index = 0; qos_flow_index < pduSession->param.nb_qos; qos_flow_index++)
|
||||
{
|
||||
asn1cSequenceAdd(sdapFlows->list, NR_QFI_t, qfi);
|
||||
*qfi = pduSession->param.qos[qos_flow_index].qfi;
|
||||
if(pduSession->param.qos[qos_flow_index].fiveQI > 5)
|
||||
pduSession->param.used_drbs[drb_id - 1] = DRB_ACTIVE_NONGBR;
|
||||
else
|
||||
pduSession->param.used_drbs[drb_id - 1] = DRB_ACTIVE;
|
||||
for (int qos_flow_index = 0; qos_flow_index < QOSFLOW_MAX_VALUE; qos_flow_index++) {
|
||||
if (drb_asn1->cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] != 0) {
|
||||
asn1cSequenceAdd(sdapFlows->list, NR_QFI_t, qfi);
|
||||
*qfi = drb_asn1->cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index];
|
||||
}
|
||||
}
|
||||
|
||||
association->choice.sdap_Config = SDAP_config;
|
||||
|
||||
/* PDCP Configuration */
|
||||
asn1cCalloc(DRB_config->pdcp_Config, pdcpConfig);
|
||||
asn1cCalloc(pdcpConfig->drb, drb);
|
||||
asn1cCallocOne(drb->discardTimer, drb_asn1->pdcp_config.discardTimer);
|
||||
asn1cCallocOne(drb->pdcp_SN_SizeUL, drb_asn1->pdcp_config.pdcp_SN_SizeUL);
|
||||
asn1cCallocOne(drb->pdcp_SN_SizeDL, drb_asn1->pdcp_config.pdcp_SN_SizeDL);
|
||||
asn1cCallocOne(pdcpConfig->t_Reordering, drb_asn1->pdcp_config.t_Reordering);
|
||||
|
||||
asn1cCallocOne(drb->discardTimer, NR_PDCP_Config__drb__discardTimer_infinity);
|
||||
drb->headerCompression.present = drb_asn1->pdcp_config.headerCompression.present;
|
||||
drb->headerCompression.choice.notUsed = drb_asn1->pdcp_config.headerCompression.NotUsed;
|
||||
|
||||
asn1cCallocOne(drb->pdcp_SN_SizeUL, NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits);
|
||||
asn1cCallocOne(drb->pdcp_SN_SizeDL, NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits);
|
||||
|
||||
drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
|
||||
drb->headerCompression.choice.notUsed = 0;
|
||||
|
||||
asn1cCallocOne(pdcpConfig->t_Reordering, NR_PDCP_Config__t_Reordering_ms100);
|
||||
|
||||
if (do_drb_integrity) {
|
||||
asn1cCallocOne(drb->integrityProtection, NR_PDCP_Config__drb__integrityProtection_enabled);
|
||||
if (!drb_asn1->pdcp_config.integrityProtection) {
|
||||
asn1cCallocOne(drb->integrityProtection, drb_asn1->pdcp_config.integrityProtection);
|
||||
}
|
||||
if (!do_drb_ciphering) {
|
||||
if (!drb_asn1->pdcp_config.ext1.cipheringDisabled) {
|
||||
asn1cCalloc(pdcpConfig->ext1, ext1);
|
||||
asn1cCallocOne(ext1->cipheringDisabled, NR_PDCP_Config__ext1__cipheringDisabled_true);
|
||||
asn1cCallocOne(ext1->cipheringDisabled, drb_asn1->pdcp_config.ext1.cipheringDisabled);
|
||||
}
|
||||
|
||||
ue->DRB_active[drb_id-1] = DRB_ACTIVE;
|
||||
|
||||
return DRB_config;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,24 @@
|
||||
#define GBR_FLOW (1)
|
||||
#define NONGBR_FLOW (0)
|
||||
|
||||
NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *rrc_ue, uint8_t drb_id, rrc_pdu_session_param_t *pduSession, bool enable_sdap, int do_drb_integrity, int do_drb_ciphering);
|
||||
/// @brief Generates an ASN1 DRB-ToAddMod, from the established_drbs in gNB_RRC_UE_t.
|
||||
/// @param drb_t drb_asn1
|
||||
/// @return Returns the ASN1 DRB-ToAddMod structs.
|
||||
NR_DRB_ToAddMod_t *generateDRB_ASN1(const drb_t *drb_asn1);
|
||||
/// @brief Creates and stores a DRB in the gNB_RRC_UE_t struct, it doesn't create the actual entity,
|
||||
/// to create the actual entity use the generateDRB_ASN1.
|
||||
/// @param ue The gNB_RRC_UE_t struct that holds information for the UEs
|
||||
/// @param drb_id The Data Radio Bearer Identity to be created for the established DRB.
|
||||
/// @param pduSession The PDU Session that the DRB is created for.
|
||||
/// @param enable_sdap If true the SDAP header will be added to the packet, else it will not add or search for SDAP header.
|
||||
/// @param do_drb_integrity
|
||||
/// @param do_drb_ciphering
|
||||
void generateDRB(gNB_RRC_UE_t *ue,
|
||||
uint8_t drb_id,
|
||||
rrc_pdu_session_param_t *pduSession,
|
||||
bool enable_sdap,
|
||||
int do_drb_integrity,
|
||||
int do_drb_ciphering);
|
||||
uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession, bool is_gbr);
|
||||
bool drb_is_active(gNB_RRC_UE_t *ue, uint8_t drb_id);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user