Commit 37d52bdf authored by wujing's avatar wujing

Merge branch 'develop_SA_SIM' into develop_SA_L3

 Conflicts:
	openair2/RRC/NR/nr_rrc_proto.h
	openair2/RRC/NR/rrc_gNB.c
	openair2/RRC/NR_UE/rrc_UE.c
	openair2/RRC/NR_UE/rrc_defs.h
	openair3/NGAP/ngap_gNB_nas_procedures.c
parents 19118c13 a53d6795
......@@ -48,6 +48,7 @@ typedef enum {
MSC_MAC_ENB,
MSC_RLC_ENB,
MSC_PDCP_ENB,
MSC_PDCP_GNB,
MSC_RRC_ENB,
MSC_RRC_GNB,
MSC_IP_ENB,
......
......@@ -30,4 +30,7 @@ MESSAGE_DEF(GTPV1U_ENB_DATA_FORWARDING_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_dat
MESSAGE_DEF(GTPV1U_ENB_END_MARKER_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_end_marker_req_t, Gtpv1uEndMarkerReq)
MESSAGE_DEF(GTPV1U_ENB_END_MARKER_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_end_marker_ind_t, Gtpv1uEndMarkerInd)
MESSAGE_DEF(GTPV1U_ENB_S1_REQ, MESSAGE_PRIORITY_MED, Gtpv1uS1Req, gtpv1uS1Req)
MESSAGE_DEF(GTPV1U_GNB_DELETE_TUNNEL_REQ, MESSAGE_PRIORITY_MED, gtpv1u_gnb_delete_tunnel_req_t, NRGtpv1uDeleteTunnelReq)
MESSAGE_DEF(GTPV1U_GNB_DELETE_TUNNEL_RESP, MESSAGE_PRIORITY_MED, gtpv1u_gnb_delete_tunnel_resp_t, NRGtpv1uDeleteTunnelResp)
MESSAGE_DEF(GTPV1U_GNB_NG_REQ, MESSAGE_PRIORITY_MED, Gtpv1uNGReq, gtpv1uNGReq)
......@@ -40,6 +40,9 @@
#define GTPV1U_ENB_END_MARKER_IND(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uEndMarkerInd
#define GTPV1U_ENB_S1_REQ(mSGpTR) (mSGpTR)->ittiMsg.gtpv1uS1Req
#define GTPV1U_GNB_DELETE_TUNNEL_REQ(mSGpTR) (mSGpTR)->ittiMsg.NRGtpv1uDeleteTunnelReq
#define GTPV1U_GNB_DELETE_TUNNEL_RESP(mSGpTR) (mSGpTR)->ittiMsg.NRGtpv1uDeleteTunnelResp
#define GTPV1U_GNB_NG_REQ(mSGpTR) (mSGpTR)->ittiMsg.gtpv1uNGReq
#define GTPV1U_ALL_TUNNELS_TEID (teid_t)0xFFFFFFFF
......@@ -195,4 +198,16 @@ typedef struct gtpv1u_gnb_create_tunnel_resp_s {
transport_layer_addr_t gnb_addr;
} gtpv1u_gnb_create_tunnel_resp_t;
typedef struct gtpv1u_gnb_delete_tunnel_req_s {
rnti_t rnti;
uint8_t num_pdusession;
pdusessionid_t pdusession_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
} gtpv1u_gnb_delete_tunnel_req_t;
typedef struct gtpv1u_gnb_delete_tunnel_resp_s {
rnti_t rnti;
uint8_t status; ///< Status of NGU endpoint deleteion (Failed = 0xFF or Success = 0x0)
teid_t gnb_NGu_teid; ///< local NGU Tunnel Endpoint Identifier to be deleted
} gtpv1u_gnb_delete_tunnel_resp_t;
#endif /* GTPV1_U_MESSAGES_TYPES_H_ */
......@@ -741,6 +741,10 @@ typedef struct ngap_ue_release_command_s {
typedef struct pdusession_release_s {
/* Unique pdusession_id for the UE. */
uint8_t pdusession_id;
/* Octet string data */
uint8_t *transfer_buffer;
/* Length of the octet string */
uint32_t transfer_length;
} pdusession_release_t;
typedef struct ngap_ue_release_req_s {
......
......@@ -523,6 +523,7 @@ typedef struct gNB_MAC_INST_s {
/// UL handle
uint32_t ul_handle;
UE_info_t UE_info;
// MAC function execution peformance profiler
/// processing time of eNB scheduler
......
......@@ -69,6 +69,7 @@
#include "NR_RRCReconfigurationComplete.h"
#include "NR_RRCReconfigurationComplete-IEs.h"
#include "NR_DLInformationTransfer.h"
#include "NR_RRCReestablishmentRequest.h"
#if defined(NR_Rel16)
#include "NR_SCS-SpecificCarrier.h"
#include "NR_TDD-UL-DL-ConfigCommon.h"
......@@ -652,7 +653,7 @@ uint8_t do_RRCSetup(const protocol_ctxt_t *const ctxt_pP,
int CC_id,
uint8_t *const buffer,
const uint8_t transaction_id,
NR_SRB_ToAddModList_t *SRB_configList)
NR_SRB_ToAddModList_t **SRB_configList)
//------------------------------------------------------------------------------
{
asn_enc_rval_t enc_rval;;
......@@ -684,19 +685,19 @@ uint8_t do_RRCSetup(const protocol_ctxt_t *const ctxt_pP,
/****************************** radioBearerConfig ******************************/
/* Configure SRB1 */
if (SRB_configList) {
free(SRB_configList);
if (*SRB_configList) {
free(*SRB_configList);
}
SRB_configList = calloc(1, sizeof(NR_SRB_ToAddModList_t));
*SRB_configList = calloc(1, sizeof(NR_SRB_ToAddModList_t));
// SRB1
/* TODO */
SRB1_config = calloc(1, sizeof(NR_SRB_ToAddMod_t));
SRB1_config->srb_Identity = 1;
// pdcp_Config->t_Reordering
SRB1_config->pdcp_Config = pdcp_Config;
ie->radioBearerConfig.srb_ToAddModList = SRB_configList;
ASN_SEQUENCE_ADD(&SRB_configList->list, SRB1_config);
ie->radioBearerConfig.srb_ToAddModList = *SRB_configList;
ASN_SEQUENCE_ADD(&(*SRB_configList)->list, SRB1_config);
ie->radioBearerConfig.srb3_ToRelease = NULL;
ie->radioBearerConfig.drb_ToAddModList = NULL;
......@@ -954,26 +955,25 @@ uint8_t do_NR_RRCRelease(uint8_t *buffer,
return((enc_rval.encoded+7)/8);
}
//------------------------------------------------------------------------------
uint16_t do_RRCReconfiguration(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
uint8_t *buffer,
uint8_t Transaction_id,
gNB_RRC_INST *gnb_rrc_inst
)
NR_SRB_ToAddModList_t *SRB_configList,
NR_DRB_ToAddModList_t *DRB_configList,
NR_DRB_ToReleaseList_t *DRB_releaseList,
NR_SecurityConfig_t *security_config,
NR_SDAP_Config_t *sdap_config,
NR_MeasConfig_t *meas_config,
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList
*dedicatedNAS_MessageList,
NR_MAC_CellGroupConfig_t *mac_CellGroupConfig)
//------------------------------------------------------------------------------
{
NR_DL_DCCH_Message_t dl_dcch_msg;
asn_enc_rval_t enc_rval;
NR_RRCReconfiguration_IEs_t *ie;
NR_SRB_ToAddModList_t *SRB_configList = NULL;
NR_SRB_ToAddModList_t *SRB_configList2 = NULL;
NR_SRB_ToAddMod_t *SRB2_config = NULL;
NR_DRB_ToAddModList_t *DRB_configList = NULL;
NR_DRB_ToAddModList_t *DRB_configList2 = NULL;
NR_DRB_ToAddMod_t *DRB_config = NULL;
NR_SDAP_Config_t *sdap_config = NULL;
NR_SecurityConfig_t *security_config = NULL;
NR_DedicatedNAS_Message_t *dedicatedNAS_Message = NULL;
memset(&dl_dcch_msg, 0, sizeof(NR_DL_DCCH_Message_t));
dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1;
......@@ -985,73 +985,6 @@ uint16_t do_RRCReconfiguration(
dl_dcch_msg.message.choice.c1->choice.rrcReconfiguration->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration;
/******************** Radio Bearer Config ********************/
/* Configure SRB2 */
SRB_configList2 = ue_context_pP->ue_context.SRB_configList2[Transaction_id];
SRB_configList = ue_context_pP->ue_context.SRB_configList;
SRB_configList = CALLOC(1, sizeof(*SRB_configList));
memset(SRB_configList, 0, sizeof(*SRB_configList));
if (SRB_configList2) {
free(SRB_configList2);
}
SRB_configList2 = CALLOC(1, sizeof(*SRB_configList2));
memset(SRB_configList2, 0, sizeof(*SRB_configList2));
SRB2_config = CALLOC(1, sizeof(*SRB2_config));
SRB2_config->srb_Identity = 2;
ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config);
ASN_SEQUENCE_ADD(&SRB_configList2->list, SRB2_config);
/* Configure DRB */
DRB_configList = ue_context_pP->ue_context.DRB_configList;
if (DRB_configList) {
free(DRB_configList);
}
DRB_configList = CALLOC(1, sizeof(*DRB_configList));
memset(DRB_configList, 0, sizeof(*DRB_configList));
DRB_configList2 = ue_context_pP->ue_context.DRB_configList2[Transaction_id];
if (DRB_configList2) {
free(DRB_configList2);
}
DRB_configList2 = CALLOC(1, sizeof(*DRB_configList2));
memset(DRB_configList2, 0, sizeof(*DRB_configList2));
DRB_config = CALLOC(1, sizeof(*DRB_config));
DRB_config->drb_Identity = 1;
DRB_config->cnAssociation = CALLOC(1, sizeof(*DRB_config->cnAssociation));
DRB_config->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config;
// TODO sdap_Config
sdap_config = CALLOC(1, sizeof(NR_SDAP_Config_t));
memset(sdap_config, 0, sizeof(NR_SDAP_Config_t));
DRB_config->cnAssociation->choice.sdap_Config = sdap_config;
// TODO pdcp_Config
DRB_config->reestablishPDCP = NULL;
DRB_config->recoverPDCP = NULL;
DRB_config->pdcp_Config = calloc(1, sizeof(*DRB_config->pdcp_Config));
DRB_config->pdcp_Config->drb = calloc(1,sizeof(*DRB_config->pdcp_Config->drb));
DRB_config->pdcp_Config->drb->discardTimer = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->discardTimer));
*DRB_config->pdcp_Config->drb->discardTimer = NR_PDCP_Config__drb__discardTimer_ms30;
DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL));
*DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL));
*DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits;
DRB_config->pdcp_Config->drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
DRB_config->pdcp_Config->drb->headerCompression.choice.notUsed = 0;
DRB_config->pdcp_Config->drb->integrityProtection = NULL;
DRB_config->pdcp_Config->drb->statusReportRequired = NULL;
DRB_config->pdcp_Config->drb->outOfOrderDelivery = NULL;
DRB_config->pdcp_Config->moreThanOneRLC = NULL;
DRB_config->pdcp_Config->t_Reordering = calloc(1, sizeof(*DRB_config->pdcp_Config->t_Reordering));
*DRB_config->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms0;
DRB_config->pdcp_Config->ext1 = NULL;
ASN_SEQUENCE_ADD(&DRB_configList->list, DRB_config);
ASN_SEQUENCE_ADD(&DRB_configList2->list, DRB_config);
/* Configure Security */
// security_config = CALLOC(1, sizeof(NR_SecurityConfig_t));
// security_config->securityAlgorithmConfig = CALLOC(1, sizeof(*ie->radioBearerConfig->securityConfig->securityAlgorithmConfig));
......@@ -1066,7 +999,7 @@ uint16_t do_RRCReconfiguration(
ie->radioBearerConfig->drb_ToAddModList = DRB_configList;
ie->radioBearerConfig->securityConfig = security_config;
ie->radioBearerConfig->srb3_ToRelease = NULL;
ie->radioBearerConfig->drb_ToReleaseList = NULL;
ie->radioBearerConfig->drb_ToReleaseList = DRB_releaseList;
/******************** Secondary Cell Group ********************/
// rrc_gNB_carrier_data_t *carrier = &(gnb_rrc_inst->carrier);
......@@ -1079,16 +1012,12 @@ uint16_t do_RRCReconfiguration(
/******************** Meas Config ********************/
// measConfig
ie->measConfig = NULL;
ie->measConfig = meas_config;
// lateNonCriticalExtension
ie->lateNonCriticalExtension = NULL;
// nonCriticalExtension
ie->nonCriticalExtension = calloc(1, sizeof(NR_RRCReconfiguration_v1530_IEs_t));
dedicatedNAS_Message = calloc(1, sizeof(NR_DedicatedNAS_Message_t));
dedicatedNAS_Message->buf = ue_context_pP->ue_context.nas_pdu.buffer;
dedicatedNAS_Message->size = ue_context_pP->ue_context.nas_pdu.length;
ie->nonCriticalExtension->dedicatedNAS_MessageList = calloc(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList));
ASN_SEQUENCE_ADD(&ie->nonCriticalExtension->dedicatedNAS_MessageList->list, dedicatedNAS_Message);
ie->nonCriticalExtension->dedicatedNAS_MessageList = dedicatedNAS_MessageList;
dl_dcch_msg.message.choice.c1->choice.rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration = ie;
......@@ -1329,3 +1258,202 @@ uint8_t do_NR_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8
return encoded;
}
uint8_t do_RRCReestablishmentRequest(uint8_t Mod_id, uint8_t *buffer, uint16_t c_rnti) {
asn_enc_rval_t enc_rval;
NR_UL_CCCH_Message_t ul_ccch_msg;
NR_RRCReestablishmentRequest_t *rrcReestablishmentRequest;
uint8_t buf[2];
memset((void *)&ul_ccch_msg,0,sizeof(NR_UL_CCCH_Message_t));
ul_ccch_msg.message.present = NR_UL_CCCH_MessageType_PR_c1;
ul_ccch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_UL_CCCH_MessageType__c1));
ul_ccch_msg.message.choice.c1->present = NR_UL_CCCH_MessageType__c1_PR_rrcReestablishmentRequest;
ul_ccch_msg.message.choice.c1->choice.rrcReestablishmentRequest = CALLOC(1, sizeof(NR_RRCReestablishmentRequest_t));
rrcReestablishmentRequest = ul_ccch_msg.message.choice.c1->choice.rrcReestablishmentRequest;
// test
rrcReestablishmentRequest->rrcReestablishmentRequest.reestablishmentCause = NR_ReestablishmentCause_reconfigurationFailure;
rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.c_RNTI = c_rnti;
rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.physCellId = 0;
rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf = buf;
rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[0] = 0x08;
rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[1] = 0x32;
rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.size = 2;
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_UL_CCCH_Message, (void *)&ul_ccch_msg);
}
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_CCCH_Message,
NULL,
(void *)&ul_ccch_msg,
buffer,
100);
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
LOG_D(NR_RRC,"[UE] RRCReestablishmentRequest Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8);
return((enc_rval.encoded+7)/8);
}
//------------------------------------------------------------------------------
uint8_t
do_RRCReestablishment(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
int CC_id,
uint8_t *const buffer,
//const uint8_t transmission_mode,
const uint8_t Transaction_id,
NR_SRB_ToAddModList_t **SRB_configList
) {
asn_enc_rval_t enc_rval;
//long *logicalchannelgroup = NULL;
struct NR_SRB_ToAddMod *SRB1_config = NULL;
struct NR_SRB_ToAddMod *SRB2_config = NULL;
//gNB_RRC_INST *nrrrc = RC.nrrrc[ctxt_pP->module_id];
NR_DL_DCCH_Message_t dl_dcch_msg;
NR_RRCReestablishment_t *rrcReestablishment = NULL;
int i = 0;
ue_context_pP->ue_context.reestablishment_xid = Transaction_id;
NR_SRB_ToAddModList_t **SRB_configList2 = NULL;
SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[Transaction_id];
if (*SRB_configList2) {
free(*SRB_configList2);
}
*SRB_configList2 = CALLOC(1, sizeof(NR_SRB_ToAddModList_t));
memset((void *)&dl_dcch_msg, 0, sizeof(NR_DL_DCCH_Message_t));
dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1;
dl_dcch_msg.message.choice.c1 = calloc(1,sizeof(struct NR_DL_DCCH_MessageType__c1));
dl_dcch_msg.message.choice.c1->present = NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment;
dl_dcch_msg.message.choice.c1->choice.rrcReestablishment = CALLOC(1,sizeof(NR_RRCReestablishment_t));
rrcReestablishment = dl_dcch_msg.message.choice.c1->choice.rrcReestablishment;
// get old configuration of SRB2
if (*SRB_configList != NULL) {
for (i = 0; (i < (*SRB_configList)->list.count) && (i < 3); i++) {
LOG_D(NR_RRC, "(*SRB_configList)->list.array[%d]->srb_Identity=%ld\n",
i, (*SRB_configList)->list.array[i]->srb_Identity);
if ((*SRB_configList)->list.array[i]->srb_Identity == 2 ) {
SRB2_config = (*SRB_configList)->list.array[i];
} else if ((*SRB_configList)->list.array[i]->srb_Identity == 1 ) {
SRB1_config = (*SRB_configList)->list.array[i];
}
}
}
if (SRB1_config == NULL) {
// default SRB1 configuration
LOG_W(NR_RRC,"SRB1 configuration does not exist in SRB configuration list, use default\n");
/// SRB1
SRB1_config = CALLOC(1, sizeof(*SRB1_config));
SRB1_config->srb_Identity = 1;
}
if (SRB2_config == NULL) {
LOG_W(NR_RRC,"SRB2 configuration does not exist in SRB configuration list\n");
} else {
ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config);
}
if (*SRB_configList) {
free(*SRB_configList);
}
*SRB_configList = CALLOC(1, sizeof(LTE_SRB_ToAddModList_t));
ASN_SEQUENCE_ADD(&(*SRB_configList)->list,SRB1_config);
rrcReestablishment->rrc_TransactionIdentifier = Transaction_id;
rrcReestablishment->criticalExtensions.present = NR_RRCReestablishment__criticalExtensions_PR_rrcReestablishment;
rrcReestablishment->criticalExtensions.choice.rrcReestablishment = CALLOC(1,sizeof(NR_RRCReestablishment_IEs_t));
uint8_t KgNB_star[32] = { 0 };
/** TODO
uint16_t pci = nrrrc->carrier[CC_id].physCellId;
uint32_t earfcn_dl = (uint32_t)freq_to_arfcn10(RC.mac[ctxt_pP->module_id]->common_channels[CC_id].eutra_band,
nrrrc->carrier[CC_id].dl_CarrierFreq);
bool is_rel8_only = true;
if (earfcn_dl > 65535) {
is_rel8_only = false;
}
LOG_D(NR_RRC, "pci=%d, eutra_band=%d, downlink_frequency=%d, earfcn_dl=%u, is_rel8_only=%s\n",
pci,
RC.mac[ctxt_pP->module_id]->common_channels[CC_id].eutra_band,
nrrrc->carrier[CC_id].dl_CarrierFreq,
earfcn_dl,
is_rel8_only == true ? "true": "false");
*/
if (ue_context_pP->ue_context.nh_ncc >= 0) {
//TODO derive_keNB_star(ue_context_pP->ue_context.nh, pci, earfcn_dl, is_rel8_only, KgNB_star);
rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nextHopChainingCount = ue_context_pP->ue_context.nh_ncc;
} else { // first HO
//TODO derive_keNB_star (ue_context_pP->ue_context.kgnb, pci, earfcn_dl, is_rel8_only, KgNB_star);
// LG: really 1
rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nextHopChainingCount = 0;
}
// copy KgNB_star to ue_context_pP->ue_context.kgnb
memcpy (ue_context_pP->ue_context.kgnb, KgNB_star, 32);
ue_context_pP->ue_context.kgnb_ncc = 0;
rrcReestablishment->criticalExtensions.choice.rrcReestablishment->lateNonCriticalExtension = NULL;
rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nonCriticalExtension = NULL;
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg);
}
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_DCCH_Message,
NULL,
(void *)&dl_dcch_msg,
buffer,
100);
if(enc_rval.encoded == -1) {
LOG_E(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
return -1;
}
LOG_D(NR_RRC,"RRCReestablishment Encoded %u bits (%u bytes)\n",
(uint32_t)enc_rval.encoded, (uint32_t)(enc_rval.encoded+7)/8);
return((enc_rval.encoded+7)/8);
}
uint8_t
do_RRCReestablishmentComplete(uint8_t *buffer, int64_t rrc_TransactionIdentifier) {
asn_enc_rval_t enc_rval;
NR_UL_DCCH_Message_t ul_dcch_msg;
NR_RRCReestablishmentComplete_t *rrcReestablishmentComplete;
memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t));
ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1;
ul_dcch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_UL_DCCH_MessageType__c1));
ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete;
ul_dcch_msg.message.choice.c1->choice.rrcReestablishmentComplete = CALLOC(1, sizeof(NR_RRCReestablishmentComplete_t));
rrcReestablishmentComplete = ul_dcch_msg.message.choice.c1->choice.rrcReestablishmentComplete;
rrcReestablishmentComplete->rrc_TransactionIdentifier = rrc_TransactionIdentifier;
rrcReestablishmentComplete->criticalExtensions.present = NR_RRCReestablishmentComplete__criticalExtensions_PR_rrcReestablishmentComplete;
rrcReestablishmentComplete->criticalExtensions.choice.rrcReestablishmentComplete = CALLOC(1, sizeof(NR_RRCReestablishmentComplete_IEs_t));
rrcReestablishmentComplete->criticalExtensions.choice.rrcReestablishmentComplete->lateNonCriticalExtension = NULL;
rrcReestablishmentComplete->criticalExtensions.choice.rrcReestablishmentComplete->nonCriticalExtension = NULL;
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_UL_CCCH_Message, (void *)&ul_dcch_msg);
}
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message,
NULL,
(void *)&ul_dcch_msg,
buffer,
100);
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
LOG_D(NR_RRC,"[UE] RRCReestablishmentComplete Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8);
return((enc_rval.encoded+7)/8);
}
......@@ -91,7 +91,7 @@ uint8_t do_RRCSetup(const protocol_ctxt_t *const ctxt_pP,
int CC_id,
uint8_t *const buffer,
const uint8_t transaction_id,
NR_SRB_ToAddModList_t *SRB_configList);
NR_SRB_ToAddModList_t **SRB_configList);
uint8_t do_NR_SecurityModeCommand(
const protocol_ctxt_t *const ctxt_pP,
uint8_t *const buffer,
......@@ -107,10 +107,17 @@ uint8_t do_NR_RRCRelease(uint8_t *buffer,
uint8_t Transaction_id);
uint16_t do_RRCReconfiguration(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
uint8_t *buffer,
uint8_t Transaction_id,
gNB_RRC_INST *gnb_rrc_inst);
NR_SRB_ToAddModList_t *SRB_configList,
NR_DRB_ToAddModList_t *DRB_configList,
NR_DRB_ToReleaseList_t *DRB_releaseList,
NR_SecurityConfig_t *security_config,
NR_SDAP_Config_t *sdap_config,
NR_MeasConfig_t *meas_config,
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList
*dedicatedNAS_MessageList,
NR_MAC_CellGroupConfig_t *mac_CellGroupConfig);
uint8_t do_RRCSetupComplete(uint8_t Mod_id,
uint8_t *buffer,
......@@ -139,3 +146,22 @@ do_NR_DLInformationTransfer(
uint8_t do_NR_ULInformationTransfer(uint8_t **buffer,
uint32_t pdu_length,
uint8_t *pdu_buffer);
uint8_t do_RRCReestablishmentRequest(uint8_t Mod_id, uint8_t *buffer, uint16_t c_rnti);
uint8_t
do_RRCReestablishment(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
int CC_id,
uint8_t *const buffer,
//const uint8_t transmission_mode,
const uint8_t Transaction_id,
NR_SRB_ToAddModList_t **SRB_configList
);
uint8_t
do_RRCReestablishmentComplete(
uint8_t *buffer,
int64_t rrc_TransactionIdentifier);
......@@ -261,7 +261,10 @@ typedef enum pdu_session_satus_e {
PDU_SESSION_STATUS_NEW,
PDU_SESSION_STATUS_DONE,
PDU_SESSION_STATUS_ESTABLISHED,
PDU_SESSION_STATUS_REESTABLISHED, // after HO
PDU_SESSION_STATUS_TOMODIFY, // ENDC NSA
PDU_SESSION_STATUS_FAILED,
PDU_SESSION_STATUS_TORELEASE // to release DRB between eNB and UE
} pdu_session_status_t;
typedef struct pdu_session_param_s {
......@@ -342,6 +345,8 @@ typedef struct gNB_RRC_UE_s {
uint8_t nb_of_e_rabs;
/* Total number of pdu session already setup in the list */
uint8_t setup_pdu_sessions;
/* Number of e_rab to be setup in the list */
uint8_t nb_of_e_rabs;
/* Number of pdu session to be setup in the list */
uint8_t nb_of_pdusessions;
/* Number of e_rab to be modified in the list */
......@@ -349,10 +354,14 @@ typedef struct gNB_RRC_UE_s {
uint8_t nb_of_failed_e_rabs;
e_rab_param_t modify_e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB];
/* list of e_rab to be setup by RRC layers */
/* list of pdu session to be setup by RRC layers */
e_rab_param_t e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB];
pdu_session_param_t pdusession[NR_NB_RB_MAX];//[NGAP_MAX_PDU_SESSION];
//release e_rabs
uint8_t nb_release_of_e_rabs;
e_rab_failed_t e_rabs_release_failed[S1AP_MAX_E_RAB];
uint8_t nb_release_of_pdusessions;
pdusession_failed_t pdusessions_release_failed[NGAP_MAX_PDUSESSION];
// LG: For GTPV1 TUNNELS
uint32_t gnb_gtp_teid[S1AP_MAX_E_RAB];
transport_layer_addr_t gnb_gtp_addrs[S1AP_MAX_E_RAB];
......@@ -371,6 +380,9 @@ typedef struct gNB_RRC_UE_s {
uint32_t ue_reestablishment_timer;
uint32_t ue_reestablishment_timer_thres;
uint8_t e_rab_release_command_flag;
uint8_t pdu_session_release_command_flag;
uint32_t ue_rrc_inactivity_timer;
int8_t reestablishment_xid;
//------------------------------------------------------------------------------//
NR_CellGroupId_t cellGroupId;
struct NR_SpCellConfig *spCellConfig;
......@@ -429,6 +441,8 @@ typedef struct {
NR_SRB_INFO SI;
NR_SRB_INFO Srb0;
int initial_csi_index[MAX_NR_RRC_UE_CONTEXTS];
int physCellId;
int p_gNB;
} rrc_gNB_carrier_data_t;
//---------------------------------------------------
......
......@@ -145,3 +145,11 @@ nr_rrc_data_req(
int
nr_rrc_mac_remove_ue(module_id_t mod_idP,
rnti_t rntiP);
void
rrc_gNB_generate_dedicatedRRCReconfiguration_release(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
uint8_t xid,
uint32_t nas_length,
uint8_t *nas_buffer);
......@@ -54,6 +54,7 @@
#include "NR_UL-CCCH-Message.h"
#include "NR_RRCSetupRequest-IEs.h"
#include "NR_RRCSetupComplete-IEs.h"
#include "NR_RRCReestablishmentRequest-IEs.h"
#include "rlc.h"
#include "rrc_eNB_UE_context.h"
......@@ -119,6 +120,7 @@ extern rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * con
static inline uint64_t bitStr_to_uint64(BIT_STRING_t *asn);
mui_t rrc_gNB_mui = 0;
uint8_t first_rrcreconfiguration = 0;
///---------------------------------------------------------------------------------------------------------------///
///---------------------------------------------------------------------------------------------------------------///
......@@ -417,6 +419,82 @@ rrc_gNB_generate_RRCSetup(
#endif
}
//-----------------------------------------------------------------------------
void
rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(
const protocol_ctxt_t *const ctxt_pP,
const int CC_id
)
//-----------------------------------------------------------------------------
{
LOG_I(NR_RRC, "generate RRCSetup for RRCReestablishmentRequest \n");
NR_SRB_ToAddModList_t **SRB_configList = NULL;
rrc_gNB_ue_context_t *ue_context_pP = NULL;
gNB_RRC_INST *rrc_instance_p = RC.nrrrc[ctxt_pP->module_id];
ue_context_pP = rrc_gNB_get_next_free_ue_context(ctxt_pP, rrc_instance_p, 0);
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
SRB_configList = &ue_p->SRB_configList;
ue_p->Srb0.Tx_buffer.payload_size = do_RRCSetup(ctxt_pP,
ue_context_pP,
CC_id,
(uint8_t *) ue_p->Srb0.Tx_buffer.Payload,
rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id),
SRB_configList);
LOG_DUMPMSG(NR_RRC, DEBUG_RRC,
(char *)(ue_p->Srb0.Tx_buffer.Payload),
ue_p->Srb0.Tx_buffer.payload_size,
"[MSG] RRC Setup\n");
LOG_D(NR_RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT" RRC_gNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_gNB\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
rrc_mac_config_req_gNB(rrc_instance_p->module_id,
rrc_instance_p->carrier.ssb_SubcarrierOffset,
rrc_instance_p->carrier.pdsch_AntennaPorts,
rrc_instance_p->carrier.pusch_TargetSNRx10,
rrc_instance_p->carrier.pucch_TargetSNRx10,
(NR_ServingCellConfigCommon_t *)rrc_instance_p->carrier.servingcellconfigcommon,
0,
ue_context_pP->ue_context.rnti,
(NR_CellGroupConfig_t *)NULL
);
MSC_LOG_TX_MESSAGE(
MSC_RRC_GNB,
MSC_RRC_UE,
ue_p->Srb0.Tx_buffer.Header, // LG WARNING
ue_p->Srb0.Tx_buffer.payload_size,
MSC_AS_TIME_FMT" RRCSetup UE %x size %u",
MSC_AS_TIME_ARGS(ctxt_pP),
ue_context_pP->ue_context.rnti,
ue_p->Srb0.Tx_buffer.payload_size);
LOG_I(NR_RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
ue_p->Srb0.Tx_buffer.payload_size);
// activate release timer, if RRCSetupComplete not received after 100 frames, remove UE
ue_context_pP->ue_context.ue_release_timer = 1;
// remove UE after 10 frames after RRCConnectionRelease is triggered
ue_context_pP->ue_context.ue_release_timer_thres = 1000;
/* init timers */
// ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0;
#ifdef ITTI_SIM
MessageDef *message_p;
uint8_t *message_buffer;
message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM,
ue_p->Srb0.Tx_buffer.payload_size);
memcpy (message_buffer, (uint8_t*)ue_p->Srb0.Tx_buffer.Payload, ue_p->Srb0.Tx_buffer.payload_size);
message_p = itti_alloc_new_message (TASK_RRC_GNB, GNB_RRC_CCCH_DATA_IND);
GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer;
GNB_RRC_CCCH_DATA_IND (message_p).size = ue_p->Srb0.Tx_buffer.payload_size;
itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
#endif
}
void
rrc_gNB_generate_RRCReject(
const protocol_ctxt_t *const ctxt_pP,
......@@ -491,18 +569,115 @@ rrc_gNB_generate_defaultRRCReconfiguration(
)
//-----------------------------------------------------------------------------
{
// gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
uint8_t buffer[RRC_BUF_SIZE];
uint16_t size;
gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id];
NR_SRB_ToAddModList_t **SRB_configList2 = NULL;
NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList;
NR_DRB_ToAddModList_t **DRB_configList = 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;
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList
*dedicatedNAS_MessageList = NULL;
NR_DedicatedNAS_Message_t *dedicatedNAS_Message = NULL;
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
/******************** Radio Bearer Config ********************/
/* Configure SRB2 */
SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid];
if (*SRB_configList2) {
free(*SRB_configList2);
}
*SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
memset(*SRB_configList2, 0, sizeof(**SRB_configList2));
SRB2_config = CALLOC(1, sizeof(*SRB2_config));
SRB2_config->srb_Identity = 2;
ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config);
ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config);
/* Configure DRB */
DRB_configList = &ue_context_pP->ue_context.DRB_configList;
if (*DRB_configList) {
free(*DRB_configList);
}
*DRB_configList = CALLOC(1, sizeof(**DRB_configList));
memset(*DRB_configList, 0, sizeof(**DRB_configList));
DRB_configList2 = &ue_context_pP->ue_context.DRB_configList2[xid];
if (*DRB_configList2) {
free(*DRB_configList2);
}
*DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2));
memset(*DRB_configList2, 0, sizeof(**DRB_configList2));
DRB_config = CALLOC(1, sizeof(*DRB_config));
DRB_config->drb_Identity = 1;
DRB_config->cnAssociation = CALLOC(1, sizeof(*DRB_config->cnAssociation));
DRB_config->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config;
// TODO sdap_Config
sdap_config = CALLOC(1, sizeof(NR_SDAP_Config_t));
memset(sdap_config, 0, sizeof(NR_SDAP_Config_t));
DRB_config->cnAssociation->choice.sdap_Config = sdap_config;
// TODO pdcp_Config
DRB_config->reestablishPDCP = NULL;
DRB_config->recoverPDCP = NULL;
DRB_config->pdcp_Config = calloc(1, sizeof(*DRB_config->pdcp_Config));
DRB_config->pdcp_Config->drb = calloc(1,sizeof(*DRB_config->pdcp_Config->drb));
DRB_config->pdcp_Config->drb->discardTimer = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->discardTimer));
*DRB_config->pdcp_Config->drb->discardTimer = NR_PDCP_Config__drb__discardTimer_ms30;
DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL));
*DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL));
*DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits;
DRB_config->pdcp_Config->drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
DRB_config->pdcp_Config->drb->headerCompression.choice.notUsed = 0;
DRB_config->pdcp_Config->drb->integrityProtection = NULL;
DRB_config->pdcp_Config->drb->statusReportRequired = NULL;
DRB_config->pdcp_Config->drb->outOfOrderDelivery = NULL;
DRB_config->pdcp_Config->moreThanOneRLC = NULL;
DRB_config->pdcp_Config->t_Reordering = calloc(1, sizeof(*DRB_config->pdcp_Config->t_Reordering));
*DRB_config->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms0;
DRB_config->pdcp_Config->ext1 = NULL;
ASN_SEQUENCE_ADD(&(*DRB_configList)->list, DRB_config);
ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config);
dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList));
if (ue_context_pP->ue_context.nas_pdu_flag == 1) {
dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t));
memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t));
OCTET_STRING_fromBuf(dedicatedNAS_Message,
(char *)ue_context_pP->ue_context.nas_pdu.buffer,
ue_context_pP->ue_context.nas_pdu.length);
ASN_SEQUENCE_ADD(&dedicatedNAS_MessageList->list, dedicatedNAS_Message);
}
/* If list is empty free the list and reset the address */
if (dedicatedNAS_MessageList->list.count == 0) {
free(dedicatedNAS_MessageList);
dedicatedNAS_MessageList = NULL;
}
size = do_RRCReconfiguration(ctxt_pP, ue_context_pP, buffer,
rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id),
gnb_rrc_inst);
LOG_DUMPMSG(NR_RRC, DEBUG_RRC,(char *)buffer, size, "[MSG] RRC Reconfiguration\n");
memset(buffer, 0, RRC_BUF_SIZE);
size = do_RRCReconfiguration(ctxt_pP, buffer,
xid,
*SRB_configList2,
*DRB_configList,
NULL,
NULL,
NULL,
NULL,
dedicatedNAS_MessageList,
NULL);
free(ue_context_pP->ue_context.nas_pdu.buffer);
LOG_DUMPMSG(NR_RRC, DEBUG_RRC,(char *)buffer, size, "[MSG] RRC Reconfiguration\n");
LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE id %x)\n",
ctxt_pP->module_id,
ctxt_pP->frame,
......@@ -528,9 +703,9 @@ rrc_gNB_generate_defaultRRCReconfiguration(
#ifdef ITTI_SIM
MessageDef *message_p;
uint8_t *message_buffer;
message_buffer = itti_malloc (TASK_RRC_GNB_SIM, TASK_RRC_UE_SIM, size);
message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, size);
memcpy (message_buffer, buffer, size);
message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, GNB_RRC_DCCH_DATA_IND);
message_p = itti_alloc_new_message (TASK_RRC_GNB, GNB_RRC_DCCH_DATA_IND);
GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
GNB_RRC_DCCH_DATA_IND (message_p).size = size;
......@@ -548,6 +723,112 @@ rrc_gNB_generate_defaultRRCReconfiguration(
// rrc_rlc_config_asn1_req
}
//-----------------------------------------------------------------------------
void
rrc_gNB_generate_dedicatedRRCReconfiguration_release(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
uint8_t xid,
uint32_t nas_length,
uint8_t *nas_buffer)
//-----------------------------------------------------------------------------
{
uint8_t buffer[RRC_BUF_SIZE];
int i;
uint16_t size = 0;
NR_DRB_ToReleaseList_t **DRB_Release_configList2 = NULL;
NR_DRB_Identity_t *DRB_release;
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList
*dedicatedNAS_MessageList = NULL;
NR_DedicatedNAS_Message_t *dedicatedNAS_Message = NULL;
DRB_Release_configList2 = &ue_context_pP->ue_context.DRB_Release_configList2[xid];
if (*DRB_Release_configList2) {
free(*DRB_Release_configList2);
}
*DRB_Release_configList2 = CALLOC(1, sizeof(**DRB_Release_configList2));
for(i = 0; i < NB_RB_MAX; i++) {
if((ue_context_pP->ue_context.pdusession[i].status == PDU_SESSION_STATUS_TORELEASE) && ue_context_pP->ue_context.pdusession[i].xid == xid) {
DRB_release = CALLOC(1, sizeof(NR_DRB_Identity_t));
*DRB_release = i+1;
ASN_SEQUENCE_ADD(&(*DRB_Release_configList2)->list, DRB_release);
}
}
/* If list is empty free the list and reset the address */
if (nas_length > 0) {
dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList));
dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t));
memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t));
OCTET_STRING_fromBuf(dedicatedNAS_Message,
(char *)nas_buffer,
nas_length);
ASN_SEQUENCE_ADD(&dedicatedNAS_MessageList->list, dedicatedNAS_Message);
LOG_I(NR_RRC,"add NAS info with size %d\n", nas_length);
} else {
LOG_W(NR_RRC,"dedlicated NAS list is empty\n");
}
memset(buffer, 0, RRC_BUF_SIZE);
size = do_RRCReconfiguration(ctxt_pP, buffer, xid,
NULL,
NULL,
*DRB_Release_configList2,
NULL,
NULL,
NULL,
dedicatedNAS_MessageList,
NULL);
ue_context_pP->ue_context.pdu_session_release_command_flag = 1;
LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size,
"[MSG] RRC Reconfiguration\n");
/* Free all NAS PDUs */
if (nas_length > 0) {
/* Free the NAS PDU buffer and invalidate it */
free(nas_buffer);
}
LOG_I(NR_RRC,
"[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE RNTI %x)\n",
ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti);
LOG_D(NR_RRC,
"[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_gNB_mui, ctxt_pP->module_id, DCCH);
MSC_LOG_TX_MESSAGE(
MSC_RRC_GNB,
MSC_RRC_UE,
buffer,
size,
MSC_AS_TIME_FMT" dedicated NR_RRCReconfiguration UE %x MUI %d size %u",
MSC_AS_TIME_ARGS(ctxt_pP),
ue_context_pP->ue_context.rnti,
rrc_gNB_mui,
size);
#ifdef ITTI_SIM
MessageDef *message_p;
uint8_t *message_buffer;
message_buffer = itti_malloc (TASK_RRC_GNB_SIM, TASK_RRC_UE_SIM, size);
memcpy (message_buffer, buffer, size);
message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, GNB_RRC_DCCH_DATA_IND);
GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
GNB_RRC_DCCH_DATA_IND (message_p).size = size;
itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
#else
nr_rrc_data_req(
ctxt_pP,
DCCH,
rrc_gNB_mui++,
SDU_CONFIRM_NO,
size,
buffer,
PDCP_TRANSMISSION_MODE_CONTROL);
#endif
}
//-----------------------------------------------------------------------------
/*
* Process the RRC Reconfiguration Complete from the UE
......@@ -567,7 +848,7 @@ rrc_gNB_process_RRCReconfigurationComplete(
NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid];
NR_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid];
NR_DRB_Identity_t *drb_id_p = NULL;
uint8_t nr_DRB2LCHAN[8];
// uint8_t nr_DRB2LCHAN[8];
ue_context_pP->ue_context.ue_reestablishment_timer = 0;
......@@ -707,6 +988,350 @@ rrc_gNB_process_RRCReconfigurationComplete(
ue_context_pP->ue_context.DRB_Release_configList2[xid] = NULL;
}
}
//-----------------------------------------------------------------------------
void
rrc_gNB_generate_RRCReestablishment(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
const int CC_id)
//-----------------------------------------------------------------------------
{
// int UE_id = -1;
//NR_LogicalChannelConfig_t *SRB1_logicalChannelConfig = NULL;
NR_SRB_ToAddModList_t **SRB_configList;
// NR_SRB_ToAddMod_t *SRB1_config = NULL;
//rrc_gNB_carrier_data_t *carrier = NULL;
gNB_RRC_UE_t *ue_context = NULL;
module_id_t module_id = ctxt_pP->module_id;
// uint16_t rnti = ctxt_pP->rnti;
SRB_configList = &(ue_context_pP->ue_context.SRB_configList);
//carrier = &(RC.nrrrc[ctxt_pP->module_id]->carrier);
ue_context = &(ue_context_pP->ue_context);
ue_context->Srb0.Tx_buffer.payload_size = do_RRCReestablishment(ctxt_pP,
ue_context_pP,
CC_id,
(uint8_t *) ue_context->Srb0.Tx_buffer.Payload,
//(uint8_t) carrier->p_gNB, // at this point we do not have the UE capability information, so it can only be TM1 or TM2
rrc_gNB_get_next_transaction_identifier(module_id),
SRB_configList
//&(ue_context->physicalConfigDedicated)
);
/* Configure SRB1 for UE */
if (*SRB_configList != NULL) {
for (int cnt = 0; cnt < (*SRB_configList)->list.count; cnt++) {
if ((*SRB_configList)->list.array[cnt]->srb_Identity == 1) {
// SRB1_config = (*SRB_configList)->list.array[cnt];
}
LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" RRC_gNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_gNB\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
// rrc_mac_config_req_eNB
}
} // if (*SRB_configList != NULL)
MSC_LOG_TX_MESSAGE(MSC_RRC_GNB,
MSC_RRC_UE,
ue_context->Srb0.Tx_buffer.Header,
ue_context->Srb0.Tx_buffer.payload_size,
MSC_AS_TIME_FMT" NR_RRCReestablishment UE %x size %u",
MSC_AS_TIME_ARGS(ctxt_pP),
ue_context->rnti,
ue_context->Srb0.Tx_buffer.payload_size);
LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-DCCH, Generating NR_RRCReestablishment (bytes %d)\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
ue_context->Srb0.Tx_buffer.payload_size);
#if(0)
UE_id = find_nr_UE_id(module_id, rnti);
if (UE_id != -1) {
/* Activate reject timer, if RRCComplete not received after 10 frames, reject UE */
RC.nrmac[module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1;
/* Reject UE after 10 frames, LTE_RRCConnectionReestablishmentReject is triggered */
RC.nrmac[module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 100;
} else {
LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Generating NR_RRCReestablishment without UE_id(MAC) rnti %x\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
rnti);
}
#endif
#ifdef ITTI_SIM
MessageDef *message_p;
uint8_t *message_buffer;
message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, ue_context->Srb0.Tx_buffer.payload_size);
memcpy (message_buffer, (uint8_t *) ue_context->Srb0.Tx_buffer.Payload, ue_context->Srb0.Tx_buffer.payload_size);
message_p = itti_alloc_new_message (TASK_RRC_GNB, GNB_RRC_DCCH_DATA_IND);
GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
GNB_RRC_DCCH_DATA_IND (message_p).size = ue_context->Srb0.Tx_buffer.payload_size;
itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
#endif
}
//-----------------------------------------------------------------------------
void
rrc_gNB_process_RRCConnectionReestablishmentComplete(
const protocol_ctxt_t *const ctxt_pP,
const rnti_t reestablish_rnti,
rrc_gNB_ue_context_t *ue_context_pP,
const uint8_t xid
)
//-----------------------------------------------------------------------------
{
LOG_I(NR_RRC,
PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, processing NR_RRCConnectionReestablishmentComplete from UE (SRB1 Active)\n",
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
NR_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList;
NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.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;
uint8_t buffer[RRC_BUF_SIZE];
uint16_t size;
uint8_t next_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
int ret = 0;
ue_context_pP->ue_context.Status = NR_RRC_CONNECTED;
ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED
ue_context_pP->ue_context.reestablishment_xid = next_xid;
SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[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]);
}
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_context_pP->ue_context.SRB_configList2[%d])\n", xid);
SRB2_config = (*SRB_configList2)->list.array[i];
break;
}
}
}
// SRB2_config = CALLOC(1, sizeof(*SRB2_config));
// SRB2_config->srb_Identity = 2;
SRB_configList2 = &(ue_context_pP->ue_context.SRB_configList2[next_xid]);
DRB_configList2 = &(ue_context_pP->ue_context.DRB_configList2[next_xid]);
if (*SRB_configList2) {
free(*SRB_configList2);
LOG_D(NR_RRC, "free(ue_context_pP->ue_context.SRB_configList2[%d])\n", next_xid);
}
*SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
if (SRB2_config != NULL) {
// Add SRB2 to SRB configuration list
ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config);
ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config);
LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_context_pP->ue_context.SRB_configList\n",
SRB2_config->srb_Identity);
LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_context_pP->ue_context.SRB_configList2[%d]\n",
SRB2_config->srb_Identity, next_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_context_pP->ue_context.DRB_configList2[%d])\n", next_xid);
}
*DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2));
if (DRB_configList != NULL) {
LOG_D(NR_RRC, "get DRB_config from (ue_context_pP->ue_context.DRB_configList)\n");
for (i = 0; (i < DRB_configList->list.count) && (i < 3); i++) {
DRB_config = DRB_configList->list.array[i];
// Add DRB to DRB configuration list, for LTE_RRCConnectionReconfigurationComplete
ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config);
}
}
ue_context_pP->ue_context.Srb1.Active = 1;
//ue_context_pP->ue_context.Srb2.Srb_info.Srb_id = 2;
if (AMF_MODE_ENABLED) {
hashtable_rc_t h_rc;
int j;
rrc_ue_ngap_ids_t *rrc_ue_ngap_ids_p = NULL;
uint16_t ue_initial_id = ue_context_pP->ue_context.ue_initial_id;
uint32_t gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id;
gNB_RRC_INST *rrc_instance_p = RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)];
if (gNB_ue_ngap_id > 0) {
h_rc = hashtable_get(rrc_instance_p->ngap_id2_ngap_ids, (hash_key_t)gNB_ue_ngap_id, (void **)&rrc_ue_ngap_ids_p);
if (h_rc == HASH_TABLE_OK) {
rrc_ue_ngap_ids_p->ue_rnti = ctxt_pP->rnti;
}
}
if (ue_initial_id != 0) {
h_rc = hashtable_get(rrc_instance_p->initial_id2_ngap_ids, (hash_key_t)ue_initial_id, (void **)&rrc_ue_ngap_ids_p);
if (h_rc == HASH_TABLE_OK) {
rrc_ue_ngap_ids_p->ue_rnti = ctxt_pP->rnti;
}
}
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req;
/* Save e RAB information for later */
memset(&create_tunnel_req, 0, sizeof(create_tunnel_req));
for ( j = 0, i = 0; i < NB_RB_MAX; i++) {
if (ue_context_pP->ue_context.pdusession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_context_pP->ue_context.pdusession[i].status == PDU_SESSION_STATUS_DONE) {
create_tunnel_req.pdusession_id[j] = ue_context_pP->ue_context.pdusession[i].param.pdusession_id;
create_tunnel_req.upf_NGu_teid[j] = ue_context_pP->ue_context.pdusession[i].param.gtp_teid;
memcpy(create_tunnel_req.upf_addr[j].buffer,
ue_context_pP->ue_context.pdusession[i].param.upf_addr.buffer,
sizeof(uint8_t)*20);
create_tunnel_req.upf_addr[j].length = ue_context_pP->ue_context.pdusession[i].param.upf_addr.length;
j++;
}
}
create_tunnel_req.rnti = ctxt_pP->rnti; // warning put zero above
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);
// update s1u tunnel failed,reset rnti?
if (gNB_ue_ngap_id > 0) {
h_rc = hashtable_get(rrc_instance_p->ngap_id2_ngap_ids, (hash_key_t)gNB_ue_ngap_id, (void **)&rrc_ue_ngap_ids_p);
if (h_rc == HASH_TABLE_OK ) {
rrc_ue_ngap_ids_p->ue_rnti = reestablish_rnti;
}
}
if (ue_initial_id != 0) {
h_rc = hashtable_get(rrc_instance_p->initial_id2_ngap_ids, (hash_key_t)ue_initial_id, (void **)&rrc_ue_ngap_ids_p);
if (h_rc == HASH_TABLE_OK ) {
rrc_ue_ngap_ids_p->ue_rnti = reestablish_rnti;
}
}
ue_context_pP->ue_context.ue_release_timer_s1 = 1;
ue_context_pP->ue_context.ue_release_timer_thres_s1 = 100;
ue_context_pP->ue_context.ue_release_timer = 0;
ue_context_pP->ue_context.ue_reestablishment_timer = 0;
ue_context_pP->ue_context.ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ
ue_context_pP->ue_context.ul_failure_timer = 0;
return;
}
} /* AMF_MODE_ENABLED */
/* Update RNTI in ue_context */
ue_context_pP->ue_id_rnti = ctxt_pP->rnti; // here ue_id_rnti is just a key, may be something else
ue_context_pP->ue_context.rnti = ctxt_pP->rnti;
if (AMF_MODE_ENABLED) {
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, "set security successfully \n");
}
/* Add all NAS PDUs to the list */
for (i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) {
/* TODO parameters yet to process ... */
/* TODO should test if pdu session are Ok before! */
ue_context_pP->ue_context.pdusession[i].status = PDU_SESSION_STATUS_DONE;
ue_context_pP->ue_context.pdusession[i].xid = xid;
LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n",
i, ue_context_pP->ue_context.pdusession[i].status, "PDU_SESSION_STATUS_DONE");
}
memset(buffer, 0, RRC_BUF_SIZE);
size = do_RRCReconfiguration(ctxt_pP, buffer,
xid,
*SRB_configList2,
DRB_configList,
NULL,
NULL,
NULL,
NULL, // MeasObj_list,
NULL,
NULL);
LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size,
"[MSG] RRC Reconfiguration\n");
/* Free all NAS PDUs */
for (i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) {
if (ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer != NULL) {
/* Free the NAS PDU buffer and invalidate it */
free(ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer);
ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer = NULL;
}
}
if(size==65535) {
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_RRCConnectionReconfiguration (bytes %d, UE id %x)\n",
ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti);
LOG_D(NR_RRC,
"[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_gNB_mui, ctxt_pP->module_id, DCCH);
MSC_LOG_TX_MESSAGE(
MSC_RRC_GNB,
MSC_RRC_UE,
buffer,
size,
MSC_AS_TIME_FMT" LTE_RRCConnectionReconfiguration UE %x MUI %d size %u",
MSC_AS_TIME_ARGS(ctxt_pP),
ue_context_pP->ue_context.rnti,
rrc_gNB_mui,
size);
#ifdef ITTI_SIM
MessageDef *message_p;
uint8_t *message_buffer;
message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, size);
memcpy (message_buffer, buffer, size);
message_p = itti_alloc_new_message (TASK_RRC_GNB, GNB_RRC_DCCH_DATA_IND);
GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
GNB_RRC_DCCH_DATA_IND (message_p).size = size;
itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p);
#else
nr_rrc_data_req(
ctxt_pP,
DCCH,
rrc_gNB_mui++,
SDU_CONFIRM_NO,
size,
buffer,
PDCP_TRANSMISSION_MODE_CONTROL);
#endif
}
}
//-----------------------------------------------------------------------------
/*------------------------------------------------------------------------------*/
......@@ -715,12 +1340,15 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP,
int buffer_length,
const int CC_id)
{
module_id_t Idx;
asn_dec_rval_t dec_rval;
NR_UL_CCCH_Message_t *ul_ccch_msg = NULL;
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id];
NR_RRCSetupRequest_IEs_t *rrcSetupRequest = NULL;
NR_RRCReestablishmentRequest_IEs_t rrcReestablishmentRequest;
uint64_t random_value = 0;
int i;
dec_rval = uper_decode( NULL,
&asn_DEF_NR_UL_CCCH_Message,
......@@ -731,15 +1359,6 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP,
0);
if (dec_rval.consumed == 0) {
/* TODO */
LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" FATAL Error in receiving CCCH\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
return -1;
}
if (ul_ccch_msg->message.present == NR_UL_CCCH_MessageType_PR_c1) {
switch (ul_ccch_msg->message.choice.c1->present) {
case NR_UL_CCCH_MessageType__c1_PR_NOTHING:
/* TODO */
LOG_I(NR_RRC,
PROTOCOL_NR_RRC_CTXT_FMT" Received PR_NOTHING on UL-CCCH-Message\n",
......@@ -864,6 +1483,217 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP,
CC_id);
break;
case NR_UL_CCCH_MessageType__c1_PR_rrcReestablishmentRequest:
LOG_I(NR_RRC, "receive rrcReestablishmentRequest message \n");
LOG_DUMPMSG(NR_RRC, DEBUG_RRC,(char *)(buffer), buffer_length,
"[MSG] RRC Reestablishment Request\n");
LOG_D(NR_RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT"MAC_gNB--- MAC_DATA_IND (rrcReestablishmentRequest on SRB0) --> RRC_gNB\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
rrcReestablishmentRequest = ul_ccch_msg->message.choice.c1->choice.rrcReestablishmentRequest->rrcReestablishmentRequest;
LOG_I(NR_RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest cause %s\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
((rrcReestablishmentRequest.reestablishmentCause == NR_ReestablishmentCause_otherFailure) ? "Other Failure" :
(rrcReestablishmentRequest.reestablishmentCause == NR_ReestablishmentCause_handoverFailure) ? "Handover Failure" :
"reconfigurationFailure"));
{
uint16_t c_rnti = 0;
if (rrcReestablishmentRequest.ue_Identity.physCellId != RC.nrrrc[ctxt_pP->module_id]->carrier.physCellId) {
/* UE was moving from previous cell so quickly that RRCReestablishment for previous cell was recieved in this cell */
LOG_E(NR_RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest ue_Identity.physCellId(%ld) is not equal to current physCellId(%d), fallback to RRC establishment\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
rrcReestablishmentRequest.ue_Identity.physCellId,
RC.nrrrc[ctxt_pP->module_id]->carrier.physCellId);
rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id);
break;
}
LOG_D(NR_RRC, "physCellId is %ld\n", rrcReestablishmentRequest.ue_Identity.physCellId);
for (i = 0; i < rrcReestablishmentRequest.ue_Identity.shortMAC_I.size; i++) {
LOG_D(NR_RRC, "rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[%d] = %x\n",
i, rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[i]);
}
if (rrcReestablishmentRequest.ue_Identity.c_RNTI < 0 ||
rrcReestablishmentRequest.ue_Identity.c_RNTI > 65535) {
/* c_RNTI range error should not happen */
LOG_E(NR_RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest c_RNTI range error, fallback to RRC establishment\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id);
break;
}
c_rnti = rrcReestablishmentRequest.ue_Identity.c_RNTI;
LOG_I(NR_RRC, "c_rnti is %x\n", c_rnti);
ue_context_p = rrc_gNB_get_ue_context(gnb_rrc_inst, c_rnti);
if (ue_context_p == NULL) {
LOG_E(NR_RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest without UE context, fallback to RRC establishment\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id);
break;
}
#if(0)
int UE_id = find_nr_UE_id(ctxt_pP->module_id, c_rnti);
if(UE_id == -1) {
LOG_E(NR_RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest without UE_id(MAC) rnti %x, fallback to RRC establishment\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),c_rnti);
rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id);
break;
}
//previous rnti
rnti_t previous_rnti = 0;
for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
if (reestablish_rnti_map[i][1] == c_rnti) {
previous_rnti = reestablish_rnti_map[i][0];
break;
}
}
if(previous_rnti != 0) {
UE_id = find_nr_UE_id(ctxt_pP->module_id, previous_rnti);
if(UE_id == -1) {
LOG_E(NR_RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT" RRCReestablishmentRequest without UE_id(MAC) previous rnti %x, fallback to RRC establishment\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),previous_rnti);
rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id);
break;
}
}
#endif
//c-plane not end
if((ue_context_p->ue_context.Status != NR_RRC_RECONFIGURED) && (ue_context_p->ue_context.reestablishment_cause == NR_ReestablishmentCause_spare1)) {
LOG_E(NR_RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest (UE %x c-plane is not end), RRC establishment failed \n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),c_rnti);
/* TODO RRC Release ? */
break;
}
if(ue_context_p->ue_context.ue_reestablishment_timer > 0) {
LOG_E(NR_RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT" RRRCReconfigurationComplete(Previous) don't receive, delete the Previous UE,\nprevious Status %d, new Status NR_RRC_RECONFIGURED\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
ue_context_p->ue_context.Status
);
ue_context_p->ue_context.Status = NR_RRC_RECONFIGURED;
protocol_ctxt_t ctxt_old_p;
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt_old_p,
ctxt_pP->instance,
GNB_FLAG_YES,
c_rnti,
ctxt_pP->frame,
ctxt_pP->subframe);
rrc_gNB_process_RRCReconfigurationComplete(&ctxt_old_p,
ue_context_p,
ue_context_p->ue_context.reestablishment_xid);
for (uint8_t pdusessionid = 0; pdusessionid < ue_context_p->ue_context.nb_of_pdusessions; pdusessionid++) {
if (ue_context_p->ue_context.pdusession[pdusessionid].status == PDU_SESSION_STATUS_DONE) {
ue_context_p->ue_context.pdusession[pdusessionid].status = PDU_SESSION_STATUS_ESTABLISHED;
} else {
ue_context_p->ue_context.pdusession[pdusessionid].status = PDU_SESSION_STATUS_FAILED;
}
}
}
LOG_D(NR_RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT" UE context: %p\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
ue_context_p);
/* reset timers */
ue_context_p->ue_context.ul_failure_timer = 0;
ue_context_p->ue_context.ue_release_timer = 0;
ue_context_p->ue_context.ue_reestablishment_timer = 0;
// ue_context_p->ue_context.ue_release_timer_s1 = 0;
ue_context_p->ue_context.ue_release_timer_rrc = 0;
ue_context_p->ue_context.reestablishment_xid = -1;
// insert C-RNTI to map
for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
if (reestablish_rnti_map[i][0] == 0) {
reestablish_rnti_map[i][0] = ctxt_pP->rnti;
reestablish_rnti_map[i][1] = c_rnti;
LOG_D(NR_RRC, "reestablish_rnti_map[%d] [0] %x, [1] %x\n",
i, reestablish_rnti_map[i][0], reestablish_rnti_map[i][1]);
break;
}
}
ue_context_p->ue_context.reestablishment_cause = rrcReestablishmentRequest.reestablishmentCause;
LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Accept reestablishment request from UE physCellId %ld cause %ld\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
rrcReestablishmentRequest.ue_Identity.physCellId,
ue_context_p->ue_context.reestablishment_cause);
ue_context_p->ue_context.primaryCC_id = CC_id;
//LG COMMENT Idx = (ue_mod_idP * NB_RB_MAX) + DCCH;
Idx = DCCH;
// SRB1
ue_context_p->ue_context.Srb1.Active = 1;
ue_context_p->ue_context.Srb1.Srb_info.Srb_id = Idx;
memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[0],
&DCCH_LCHAN_DESC,
LCHAN_DESC_SIZE);
memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[1],
&DCCH_LCHAN_DESC,
LCHAN_DESC_SIZE);
// SRB2: set it to go through SRB1 with id 1 (DCCH)
ue_context_p->ue_context.Srb2.Active = 1;
ue_context_p->ue_context.Srb2.Srb_info.Srb_id = Idx;
memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[0],
&DCCH_LCHAN_DESC,
LCHAN_DESC_SIZE);
memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[1],
&DCCH_LCHAN_DESC,
LCHAN_DESC_SIZE);
rrc_gNB_generate_RRCReestablishment(ctxt_pP, ue_context_p, CC_id);
LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT"CALLING RLC CONFIG SRB1 (rbid %d)\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
Idx);
MSC_LOG_TX_MESSAGE(MSC_RRC_GNB,
MSC_PDCP_GNB,
NULL,
0,
MSC_AS_TIME_FMT" CONFIG_REQ UE %x SRB",
MSC_AS_TIME_ARGS(ctxt_pP),
ue_context_p->ue_context.rnti);
// nr_rrc_pdcp_config_asn1_req(ctxt_pP,
// ue_context_p->ue_context.SRB_configList,
// NULL,
// NULL,
// 0xff,
// NULL,
// NULL,
// NULL,
// NULL,
// NULL,
// NULL);
// if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
// nr_rrc_rlc_config_asn1_req(ctxt_pP,
// ue_context_p->ue_context.SRB_configList,
// NULL,
// NULL,
// NULL,
// NULL);
// }
}
break;
case NR_UL_CCCH_MessageType__c1_PR_rrcResumeRequest:
LOG_I(NR_RRC, "receive rrcResumeRequest message \n");
/* TODO */
......@@ -924,7 +1754,8 @@ rrc_gNB_decode_dcch(
asn_dec_rval_t dec_rval;
NR_UL_DCCH_Message_t *ul_dcch_msg = NULL;
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
// NR_RRCSetupComplete_t *rrcSetupComplete = NULL;
MessageDef *msg_delete_tunnels_p = NULL;
uint8_t xid;
int i;
......@@ -1289,6 +2120,78 @@ rrc_gNB_decode_dcch(
rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p);
break;
case NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete:
LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP,
"[MSG] NR_RRC Connection Reestablishment Complete\n");
MSC_LOG_RX_MESSAGE(
MSC_RRC_GNB,
MSC_RRC_UE,
Rx_sdu,
sdu_sizeP,
MSC_AS_TIME_FMT" NR_RRCConnectionReestablishmentComplete UE %x size %u",
MSC_AS_TIME_ARGS(ctxt_pP),
ue_context_p->ue_context.rnti,
sdu_sizeP);
LOG_I(NR_RRC,
PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes "
"(rrcConnectionReestablishmentComplete) ---> RRC_gNB\n",
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
DCCH,
sdu_sizeP);
{
rnti_t reestablish_rnti = 0;
// select C-RNTI from map
for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
if (reestablish_rnti_map[i][0] == ctxt_pP->rnti) {
reestablish_rnti = reestablish_rnti_map[i][1];
ue_context_p = rrc_gNB_get_ue_context(
RC.nrrrc[ctxt_pP->module_id],
reestablish_rnti);
// clear currentC-RNTI from map
reestablish_rnti_map[i][0] = 0;
reestablish_rnti_map[i][1] = 0;
LOG_D(NR_RRC, "reestablish_rnti_map[%d] [0] %x, [1] %x\n",
i, reestablish_rnti_map[i][0], reestablish_rnti_map[i][1]);
break;
}
}
if (!ue_context_p) {
LOG_E(NR_RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCConnectionReestablishmentComplete without UE context, falt\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
break;
}
#if(0)
//clear
int UE_id = find_nr_UE_id(ctxt_pP->module_id, ctxt_pP->rnti);
if(UE_id == -1) {
LOG_E(NR_RRC,
PROTOCOL_RRC_CTXT_UE_FMT" NR_RRCConnectionReestablishmentComplete without UE_id(MAC) rnti %x, fault\n",
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti);
break;
}
RC.nrmac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0;
#endif
ue_context_p->ue_context.reestablishment_xid = -1;
if (ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete->criticalExtensions.present ==
NR_RRCReestablishmentComplete__criticalExtensions_PR_rrcReestablishmentComplete) {
rrc_gNB_process_RRCConnectionReestablishmentComplete(ctxt_pP, reestablish_rnti, ue_context_p,
ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete->rrc_TransactionIdentifier);
}
//ue_context_p->ue_context.ue_release_timer = 0;
ue_context_p->ue_context.ue_reestablishment_timer = 1;
// remove UE after 100 frames after LTE_RRCConnectionReestablishmentRelease is triggered
ue_context_p->ue_context.ue_reestablishment_timer_thres = 1000;
}
break;
default:
break;
}
......@@ -1357,12 +2260,12 @@ void *rrc_gnb_task(void *args_p) {
/* Messages from MAC */
case NR_RRC_MAC_CCCH_DATA_IND:
// PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
// NR_RRC_MAC_CCCH_DATA_IND(msg_p).gnb_index,
// GNB_FLAG_YES,
// NR_RRC_MAC_CCCH_DATA_IND(msg_p).rnti,
// msg_p->ittiMsgHeader.lte_time.frame,
// msg_p->ittiMsgHeader.lte_time.slot);
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
NR_RRC_MAC_CCCH_DATA_IND(msg_p).gnb_index,
GNB_FLAG_YES,
NR_RRC_MAC_CCCH_DATA_IND(msg_p).rnti,
msg_p->ittiMsgHeader.lte_time.frame,
msg_p->ittiMsgHeader.lte_time.slot);
LOG_I(NR_RRC,"Decoding CCCH : inst %d, CC_id %d, ctxt %p, sib_info_p->Rx_buffer.payload_size %d\n",
instance,
NR_RRC_MAC_CCCH_DATA_IND(msg_p).CC_id,
......@@ -1383,12 +2286,12 @@ void *rrc_gnb_task(void *args_p) {
/* Messages from PDCP */
case NR_RRC_DCCH_DATA_IND:
// PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
// instance,
// ENB_FLAG_YES,
// RRC_DCCH_DATA_IND(msg_p).rnti,
// msg_p->ittiMsgHeader.lte_time.frame,
// msg_p->ittiMsgHeader.lte_time.slot);
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
instance,
GNB_FLAG_YES,
NR_RRC_DCCH_DATA_IND(msg_p).rnti,
msg_p->ittiMsgHeader.lte_time.frame,
msg_p->ittiMsgHeader.lte_time.slot);
LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Received on DCCH %d %s\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(&ctxt),
NR_RRC_DCCH_DATA_IND(msg_p).dcch_index,
......@@ -1407,6 +2310,13 @@ void *rrc_gnb_task(void *args_p) {
rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(msg_p, msg_name_p, instance);
break;
case NGAP_PDUSESSION_RELEASE_COMMAND:
rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(msg_p, msg_name_p, instance);
break;
case GTPV1U_GNB_DELETE_TUNNEL_RESP:
break;
/*
#if defined(ENABLE_USE_MME)
......
......@@ -1230,3 +1230,165 @@ rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(
LOG_I(NR_RRC,"Send message to ngap: NGAP_UE_CAPABILITIES_IND\n");
}
//------------------------------------------------------------------------------
void
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
uint8_t xid
)
//------------------------------------------------------------------------------
{
int pdu_sessions_released = 0;
MessageDef *msg_p;
msg_p = itti_alloc_new_message (TASK_RRC_GNB, NGAP_PDUSESSION_RELEASE_RESPONSE);
NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id;
for (int i = 0; i < NB_RB_MAX; i++) {
if (xid == ue_context_pP->ue_context.pdusession[i].xid) {
NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).pdusession_release[pdu_sessions_released].pdusession_id =
ue_context_pP->ue_context.pdusession[i].param.pdusession_id;
pdu_sessions_released++;
//clear
memset(&ue_context_pP->ue_context.pdusession[i], 0, sizeof(pdu_session_param_t));
}
}
NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).nb_of_pdusessions_released = pdu_sessions_released;
NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).nb_of_pdusessions_failed = ue_context_pP->ue_context.nb_release_of_pdusessions;
memcpy(&(NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).pdusessions_failed[0]), &ue_context_pP->ue_context.pdusessions_release_failed[0],
sizeof(pdusession_failed_t)*ue_context_pP->ue_context.nb_release_of_pdusessions);
ue_context_pP->ue_context.setup_pdu_sessions -= pdu_sessions_released;
LOG_I(NR_RRC,"NGAP PDUSESSION RELEASE RESPONSE: GNB_UE_NGAP_ID %d release_pdu_sessions %d setup_pdu_sessions %d \n",
NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).gNB_ue_ngap_id,
pdu_sessions_released, ue_context_pP->ue_context.setup_pdu_sessions);
itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p);
//clear xid
for(int i = 0; i < NB_RB_MAX; i++) {
ue_context_pP->ue_context.pdusession[i].xid = -1;
}
//clear release pdusessions
ue_context_pP->ue_context.nb_release_of_pdusessions = 0;
memset(&ue_context_pP->ue_context.pdusessions_release_failed[0], 0, sizeof(pdusession_failed_t)*NGAP_MAX_PDUSESSION);
}
//------------------------------------------------------------------------------
int
rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(
MessageDef *msg_p,
const char *msg_name,
instance_t instance
)
//------------------------------------------------------------------------------
{
uint32_t gNB_ue_ngap_id;
rrc_gNB_ue_context_t *ue_context_p = NULL;
protocol_ctxt_t ctxt;
pdusession_release_t pdusession_release_params[NGAP_MAX_PDUSESSION];
uint8_t nb_pdusessions_torelease;
MessageDef *msg_delete_tunnels_p = NULL;
uint8_t xid;
int i, pdusession;
uint8_t b_existed,is_existed;
uint8_t pdusession_release_drb = 0;
memcpy(&pdusession_release_params[0], &(NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).pdusession_release_params[0]),
sizeof(pdusession_release_t)*NGAP_MAX_PDUSESSION);
gNB_ue_ngap_id = NGAP_PDUSESSION_RELEASE_COMMAND(msg_p).gNB_ue_ngap_id;
nb_pdusessions_torelease = NGAP_PDUSESSION_RELEASE_COMMAND(msg_p).nb_pdusessions_torelease;
if (nb_pdusessions_torelease > NGAP_MAX_PDUSESSION) {
return -1;
}
ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, UE_INITIAL_ID_INVALID, gNB_ue_ngap_id);
LOG_I(NR_RRC, "[gNB %d] Received %s: gNB_ue_ngap_id %d \n", instance, msg_name, gNB_ue_ngap_id);
if (ue_context_p != NULL) {
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0);
xid = rrc_gNB_get_next_transaction_identifier(ctxt.module_id);
LOG_I(NR_RRC,"PDU Session Release Command: AMF_UE_NGAP_ID %lu GNB_UE_NGAP_ID %d release_pdusessions %d \n",
NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).amf_ue_ngap_id&0x000000FFFFFFFFFF, gNB_ue_ngap_id, nb_pdusessions_torelease);
for (pdusession = 0; pdusession < nb_pdusessions_torelease; pdusession++) {
b_existed = 0;
is_existed = 0;
for (i = pdusession-1; i >= 0; i--) {
if (pdusession_release_params[pdusession].pdusession_id == pdusession_release_params[i].pdusession_id) {
is_existed = 1;
break;
}
}
if(is_existed == 1) {
// pdusession_id is existed
continue;
}
for (i = 0; i < NR_NB_RB_MAX; i++) {
if (pdusession_release_params[pdusession].pdusession_id == ue_context_p->ue_context.pdusession[i].param.pdusession_id) {
b_existed = 1;
break;
}
}
if(b_existed == 0) {
// no pdusession_id
LOG_I(NR_RRC, "no pdusession_id \n");
ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].pdusession_id = pdusession_release_params[pdusession].pdusession_id;
ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].cause = NGAP_CAUSE_RADIO_NETWORK;
ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].cause_value = 30;
ue_context_p->ue_context.nb_release_of_pdusessions++;
} else {
if(ue_context_p->ue_context.pdusession[i].status == PDU_SESSION_STATUS_FAILED) {
ue_context_p->ue_context.pdusession[i].xid = xid;
continue;
} else if(ue_context_p->ue_context.pdusession[i].status == PDU_SESSION_STATUS_ESTABLISHED) {
LOG_I(NR_RRC, "RELEASE pdusession %d \n", ue_context_p->ue_context.pdusession[i].param.pdusession_id);
ue_context_p->ue_context.pdusession[i].status = PDU_SESSION_STATUS_TORELEASE;
ue_context_p->ue_context.pdusession[i].xid = xid;
pdusession_release_drb++;
} else {
// pdusession_id status NG
ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].pdusession_id = pdusession_release_params[pdusession].pdusession_id;
ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].cause = NGAP_CAUSE_RADIO_NETWORK;
ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].cause_value = 0;
ue_context_p->ue_context.nb_release_of_pdusessions++;
}
}
}
if(pdusession_release_drb > 0) {
//TODO RRCReconfiguration To UE
LOG_I(NR_RRC, "Send RRCReconfiguration To UE \n");
rrc_gNB_generate_dedicatedRRCReconfiguration_release(&ctxt, ue_context_p, xid, NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).nas_pdu.length, NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).nas_pdu.buffer);
} else {
//gtp tunnel delete
LOG_I(NR_RRC, "gtp tunnel delete \n");
msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_GNB, GTPV1U_GNB_DELETE_TUNNEL_REQ);
memset(&GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p)));
GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
for(i = 0; i < NB_RB_MAX; i++) {
if(xid == ue_context_p->ue_context.pdusession[i].xid) {
GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).pdusession_id[GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_pdusession++] = ue_context_p->ue_context.gnb_gtp_psi[i];
ue_context_p->ue_context.gnb_gtp_teid[i] = 0;
memset(&ue_context_p->ue_context.gnb_gtp_addrs[i], 0, sizeof(ue_context_p->ue_context.gnb_gtp_addrs[i]));
ue_context_p->ue_context.gnb_gtp_psi[i] = 0;
}
}
itti_send_msg_to_task(TASK_GTPV1_U, instance, msg_delete_tunnels_p);
//NGAP_PDUSESSION_RELEASE_RESPONSE
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(&ctxt, ue_context_p, xid);
LOG_I(NR_RRC, "Send PDU Session Release Response \n");
}
} else {
LOG_E(NR_RRC, "PDU Session Release Command: AMF_UE_NGAP_ID %lu GNB_UE_NGAP_ID %d Error ue_context_p NULL \n",
NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).amf_ue_ngap_id&0x000000FFFFFFFFFF, NGAP_PDUSESSION_RELEASE_COMMAND(msg_p).gNB_ue_ngap_id);
return -1;
}
return 0;
}
......@@ -142,4 +142,25 @@ rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(
NR_UL_DCCH_Message_t *const ul_dcch_msg
);
int
rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(
MessageDef *msg_p,
const char *msg_name,
instance_t instance
);
void
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
uint8_t xid
);
void
nr_rrc_pdcp_config_security(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
const uint8_t send_security_mode_command
);
#endif
......@@ -134,6 +134,7 @@ rrc_gNB_allocate_new_UE_context(
new_p->local_uid = nr_uid_linear_allocator_new(rrc_instance_pP);
for(int i = 0; i < NB_RB_MAX; i++) {
new_p->ue_context.e_rab[i].xid = -1;
new_p->ue_context.pdusession[i].xid = -1;
new_p->ue_context.modify_e_rab[i].xid = -1;
}
......
......@@ -184,14 +184,14 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
if (m->nb_e_rabs_tobeadded>0) {
for (int i=0; i<m->nb_e_rabs_tobeadded; i++) {
// Add the new E-RABs at the corresponding rrc ue context of the gNB
ue_context_p->ue_context.pdusession[i].param.pdusession_id = m->e_rabs_tobeadded[i].e_rab_id;
ue_context_p->ue_context.pdusession[i].param.gtp_teid = m->e_rabs_tobeadded[i].gtp_teid;
memcpy(&ue_context_p->ue_context.pdusession[i].param.upf_addr, &m->e_rabs_tobeadded[i].sgw_addr, sizeof(transport_layer_addr_t));
ue_context_p->ue_context.nb_of_pdusessions++;
ue_context_p->ue_context.e_rab[i].param.e_rab_id = m->e_rabs_tobeadded[i].e_rab_id;
ue_context_p->ue_context.e_rab[i].param.gtp_teid = m->e_rabs_tobeadded[i].gtp_teid;
memcpy(&ue_context_p->ue_context.e_rab[i].param.sgw_addr, &m->e_rabs_tobeadded[i].sgw_addr, sizeof(transport_layer_addr_t));
ue_context_p->ue_context.nb_of_e_rabs++;
//Fill the required E-RAB specific information for the creation of the S1-U tunnel between the gNB and the SGW
create_tunnel_req.eps_bearer_id[i] = ue_context_p->ue_context.pdusession[i].param.pdusession_id;
create_tunnel_req.sgw_S1u_teid[i] = ue_context_p->ue_context.pdusession[i].param.gtp_teid;
memcpy(&create_tunnel_req.sgw_addr[i], &ue_context_p->ue_context.pdusession[i].param.upf_addr, sizeof(transport_layer_addr_t));
create_tunnel_req.eps_bearer_id[i] = ue_context_p->ue_context.e_rab[i].param.e_rab_id;
create_tunnel_req.sgw_S1u_teid[i] = ue_context_p->ue_context.e_rab[i].param.gtp_teid;
memcpy(&create_tunnel_req.sgw_addr[i], &ue_context_p->ue_context.e_rab[i].param.sgw_addr, sizeof(transport_layer_addr_t));
inde_list[i] = i;
LOG_I(RRC,"S1-U tunnel: index %d target sgw ip %d.%d.%d.%d length %d gtp teid %u\n",
i,
......@@ -218,8 +218,8 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).nb_e_rabs_admitted_tobeadded = m->nb_e_rabs_tobeadded;
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).target_assoc_id = m->target_assoc_id;
for(int i=0; i<ue_context_p->ue_context.nb_of_pdusessions; i++) {
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].e_rab_id = ue_context_p->ue_context.pdusession[i].param.pdusession_id;
for(int i=0; i<ue_context_p->ue_context.nb_of_e_rabs; i++) {
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].e_rab_id = ue_context_p->ue_context.e_rab[i].param.e_rab_id;
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gtp_teid = create_tunnel_resp.enb_S1u_teid[i];
memcpy(&X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr, &create_tunnel_resp.enb_addr, sizeof(transport_layer_addr_t));
//The length field in the X2AP targetting structure is expected in bits but the create_tunnel_resp returns the address length in bytes
......
......@@ -117,7 +117,17 @@ uint8_t do_NR_RRCReconfigurationComplete(
const uint8_t Transaction_id
);
void rrc_ue_generate_RRCReestablishmentRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index );
void
nr_rrc_ue_generate_rrcReestablishmentComplete(
const protocol_ctxt_t *const ctxt_pP,
NR_RRCReestablishment_t *rrcReestablishment,
uint8_t gNB_index
);
mui_t nr_rrc_mui=0;
uint8_t first_rrcreconfigurationcomplete = 0;
static Rrc_State_NR_t nr_rrc_get_state (module_id_t ue_mod_idP) {
return NR_UE_rrc_inst[ue_mod_idP].nrRrcState;
......@@ -1440,6 +1450,7 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB
ctxt_pP->module_id,
ctxt_pP->frame,
ctxt_pP->rnti);
// Get configuration
// Release T300 timer
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T300_active = 0;
......@@ -1472,6 +1483,7 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB
}
}
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
return rval;
......@@ -2252,6 +2264,7 @@ void nr_rrc_ue_generate_RRCReconfigurationComplete( const protocol_ctxt_t *const
UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
UE_RRC_DCCH_DATA_IND (message_p).size = size;
itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p);
#else
rrc_data_req_ue (
ctxt_pP,
......@@ -2320,7 +2333,11 @@ nr_rrc_ue_decode_dcch(
nr_rrc_ue_generate_RRCReconfigurationComplete(ctxt_pP,
gNB_indexP,
dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration->rrc_TransactionIdentifier);
if (first_rrcreconfigurationcomplete == 0) {
first_rrcreconfigurationcomplete = 1;
#ifdef ITTI_SIM
if (AMF_MODE_ENABLED) {
as_nas_info_t initialNasMsg;
memset(&initialNasMsg, 0, sizeof(as_nas_info_t));
generateRegistrationComplete(&initialNasMsg, NULL);
......@@ -2345,8 +2362,10 @@ nr_rrc_ue_decode_dcch(
itti_send_msg_to_task(TASK_RRC_NRUE, ctxt_pP->instance, message_p);
LOG_I(NR_RRC, " Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n");
}
}
#endif
}
}
break;
case NR_DL_DCCH_MessageType__c1_PR_rrcResume:
......@@ -2375,6 +2394,14 @@ nr_rrc_ue_decode_dcch(
gNB_indexP);
break;
case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment:
LOG_I(NR_RRC,
"[UE%d] Frame %d : Logical Channel DL-DCCH (SRB1), Received RRCReestablishment\n",
ctxt_pP->module_id,
ctxt_pP->frame);
nr_rrc_ue_generate_rrcReestablishmentComplete(
ctxt_pP,
dl_dcch_msg->message.choice.c1->choice.rrcReestablishment,
gNB_indexP);
break;
case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer:
{
......@@ -2515,8 +2542,8 @@ void *rrc_nrue_task( void *args_p ) {
memcpy (srb_info_p->Rx_buffer.Payload, NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu,
NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size);
srb_info_p->Rx_buffer.payload_size = NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size;
// PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_NO, RRC_MAC_CCCH_DATA_IND (msg_p).rnti, RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0);
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0, NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0);
// PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0, NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
nr_rrc_ue_decode_ccch (&ctxt,
srb_info_p,
NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
......@@ -2728,3 +2755,59 @@ nr_rrc_ue_process_ueCapabilityEnquiry(
}
}
}
//-----------------------------------------------------------------------------
void rrc_ue_generate_RRCReestablishmentRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index )
{
NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size =
do_RRCReestablishmentRequest(
ctxt_pP->module_id,
(uint8_t *)NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload, 1);
LOG_I(NR_RRC,"[UE %d] : Frame %d, Logical Channel UL-CCCH (SRB0), Generating RRCReestablishmentRequest (bytes %d, gNB %d)\n",
ctxt_pP->module_id, ctxt_pP->frame, NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size, gNB_index);
for (int i=0; i<NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size; i++) {
LOG_T(NR_RRC,"%x.",NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload[i]);
}
LOG_T(NR_RRC,"\n");
#ifdef ITTI_SIM
MessageDef *message_p;
uint8_t *message_buffer;
message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,
NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size);
memcpy (message_buffer, (uint8_t*)NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload,
NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size);
message_p = itti_alloc_new_message (TASK_RRC_NRUE, UE_RRC_CCCH_DATA_IND);
UE_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer;
UE_RRC_CCCH_DATA_IND (message_p).size = NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size;
itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p);
#endif
}
void
nr_rrc_ue_generate_rrcReestablishmentComplete(
const protocol_ctxt_t *const ctxt_pP,
NR_RRCReestablishment_t *rrcReestablishment,
uint8_t gNB_index
)
//-----------------------------------------------------------------------------
{
uint32_t length;
uint8_t buffer[100];
length = do_RRCReestablishmentComplete(buffer, rrcReestablishment->rrc_TransactionIdentifier);
#ifdef ITTI_SIM
MessageDef *message_p;
uint8_t *message_buffer;
message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,length);
memcpy (message_buffer, buffer, length);
message_p = itti_alloc_new_message (TASK_RRC_NRUE, UE_RRC_DCCH_DATA_IND);
UE_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
UE_RRC_DCCH_DATA_IND (message_p).size = length;
itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p);
#endif
}
......@@ -126,7 +126,6 @@ typedef struct NR_UE_RRC_INST_s {
/* KeNB as computed from parameters within USIM card */
uint8_t kgnb[32];
/* Used integrity/ciphering algorithms */
//RRC_LIST_TYPE(NR_SecurityAlgorithmConfig_t, NR_SecurityAlgorithmConfig) SecurityAlgorithmConfig_list;
NR_CipheringAlgorithm_t cipheringAlgorithm;
......
......@@ -104,7 +104,7 @@ int config_sync_var=-1;
openair0_config_t openair0_cfg[MAX_CARDS];
volatile int start_gNB = 0;
//volatile int start_gNB = 0;
volatile int oai_exit = 0;
//static int wait_for_sync = 0;
......@@ -543,7 +543,7 @@ int main( int argc, char **argv )
}
AMF_MODE_ENABLED = !IS_SOFTMODEM_NOS1;
// AMF_MODE_ENABLED = 0;
// AMF_MODE_ENABLED = 0;
NGAP_CONF_MODE = !IS_SOFTMODEM_NOS1; //!get_softmodem_params()->phy_test;
#if T_TRACER
......
......@@ -551,6 +551,173 @@ gtpv1u_create_ngu_tunnel(
return ret;
}
int gtpv1u_update_ngu_tunnel(
const instance_t instanceP,
const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP,
const rnti_t prior_rnti
) {
/* Local tunnel end-point identifier */
teid_t ngu_teid = 0;
nr_gtpv1u_teid_data_t *gtpv1u_teid_data_p = NULL;
nr_gtpv1u_ue_data_t *gtpv1u_ue_data_p = NULL;
nr_gtpv1u_ue_data_t *gtpv1u_ue_data_new_p = NULL;
//MessageDef *message_p = NULL;
hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS;
int i,j;
uint8_t bearers_num = 0,bearers_total = 0;
//-----------------------
// PDCP->GTPV1U mapping
//-----------------------
hash_rc = hashtable_get(RC.nr_gtpv1u_data_g->ue_mapping, prior_rnti, (void **)&gtpv1u_ue_data_p);
if(hash_rc != HASH_TABLE_OK) {
LOG_E(GTPU,"Error get ue_mapping(rnti=%x) from GTPV1U hashtable error\n", prior_rnti);
return -1;
}
gtpv1u_ue_data_new_p = calloc (1, sizeof(nr_gtpv1u_ue_data_t));
memcpy(gtpv1u_ue_data_new_p,gtpv1u_ue_data_p,sizeof(nr_gtpv1u_ue_data_t));
gtpv1u_ue_data_new_p->ue_id = create_tunnel_req_pP->rnti;
hash_rc = hashtable_insert(RC.nr_gtpv1u_data_g->ue_mapping, create_tunnel_req_pP->rnti, gtpv1u_ue_data_new_p);
//AssertFatal(hash_rc == HASH_TABLE_OK, "Error inserting ue_mapping in GTPV1U hashtable");
if ( hash_rc != HASH_TABLE_OK ) {
LOG_E(GTPU,"Failed to insert ue_mapping(rnti=%x) in GTPV1U hashtable\n",create_tunnel_req_pP->rnti);
return -1;
} else {
LOG_I(GTPU, "inserting ue_mapping(rnti=%x) in GTPV1U hashtable\n",
create_tunnel_req_pP->rnti);
}
hash_rc = hashtable_remove(RC.nr_gtpv1u_data_g->ue_mapping, prior_rnti);
LOG_I(GTPU, "hashtable_remove ue_mapping(rnti=%x) in GTPV1U hashtable\n",
prior_rnti);
//-----------------------
// GTPV1U->PDCP mapping
//-----------------------
bearers_total =gtpv1u_ue_data_new_p->num_bearers;
for(j = 0; j<GTPV1U_MAX_BEARERS_ID; j++) {
if(gtpv1u_ue_data_new_p->bearers[j].state != BEARER_IN_CONFIG)
continue;
bearers_num++;
for (i = 0; i < create_tunnel_req_pP->num_tunnels; i++) {
if(j == (create_tunnel_req_pP->pdusession_id[i]-GTPV1U_BEARER_OFFSET))
break;
}
if(i < create_tunnel_req_pP->num_tunnels) {
ngu_teid = gtpv1u_ue_data_new_p->bearers[j].teid_gNB;
hash_rc = hashtable_get(RC.nr_gtpv1u_data_g->teid_mapping, ngu_teid, (void **)&gtpv1u_teid_data_p);
if (hash_rc == HASH_TABLE_OK) {
gtpv1u_teid_data_p->ue_id = create_tunnel_req_pP->rnti;
gtpv1u_teid_data_p->pdu_session_id = create_tunnel_req_pP->pdusession_id[i];
LOG_I(GTPU, "updata teid_mapping te_id %u (prior_rnti %x rnti %x) in GTPV1U hashtable\n",
ngu_teid,prior_rnti,create_tunnel_req_pP->rnti);
} else {
LOG_W(GTPU, "Error get teid mapping(s1u_teid=%u) from GTPV1U hashtable", ngu_teid);
}
} else {
ngu_teid = gtpv1u_ue_data_new_p->bearers[j].teid_gNB;
hash_rc = hashtable_remove(RC.nr_gtpv1u_data_g->teid_mapping, ngu_teid);
if (hash_rc != HASH_TABLE_OK) {
LOG_D(GTPU, "Removed user rnti %x , enb S1U teid %u not found\n", prior_rnti, ngu_teid);
}
gtpv1u_ue_data_new_p->bearers[j].state = BEARER_DOWN;
gtpv1u_ue_data_new_p->num_bearers--;
LOG_I(GTPU, "delete teid_mapping te_id %u (rnti%x) bearer_id %d in GTPV1U hashtable\n",
ngu_teid,prior_rnti,j+GTPV1U_BEARER_OFFSET);;
}
if(bearers_num > bearers_total)
break;
}
return 0;
}
//-----------------------------------------------------------------------------
int gtpv1u_delete_ngu_tunnel(
const instance_t instanceP,
const gtpv1u_gnb_delete_tunnel_req_t *const req_pP) {
NwGtpv1uUlpApiT stack_req;
NwGtpv1uRcT rc = NW_GTPV1U_FAILURE;
MessageDef *message_p = NULL;
nr_gtpv1u_ue_data_t *gtpv1u_ue_data_p = NULL;
hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS;
teid_t teid_gNB = 0;
int pdusession_index = 0;
message_p = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_GNB_DELETE_TUNNEL_RESP);
GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).rnti = req_pP->rnti;
GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).status = 0;
hash_rc = hashtable_get(RC.nr_gtpv1u_data_g->ue_mapping, req_pP->rnti, (void **)&gtpv1u_ue_data_p);
if (hash_rc == HASH_TABLE_OK) {
for (pdusession_index = 0; pdusession_index < req_pP->num_pdusession; pdusession_index++) {
teid_gNB = gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].teid_gNB;
LOG_D(GTPU, "Rx GTPV1U_ENB_DELETE_TUNNEL user rnti %x eNB S1U teid %u eps bearer id %u\n",
req_pP->rnti, teid_gNB, req_pP->pdusession_id[pdusession_index]);
{
memset(&stack_req, 0, sizeof(NwGtpv1uUlpApiT));
stack_req.apiType = NW_GTPV1U_ULP_API_DESTROY_TUNNEL_ENDPOINT;
LOG_D(GTPU, "gtpv1u_delete_ngu_tunnel pdusession %u %u\n",
req_pP->pdusession_id[pdusession_index],
teid_gNB);
stack_req.apiInfo.destroyTunnelEndPointInfo.hStackSessionHandle =
gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].teid_gNB_stack_session;
rc = nwGtpv1uProcessUlpReq(RC.nr_gtpv1u_data_g->gtpv1u_stack, &stack_req);
LOG_D(GTPU, ".\n");
}
if (rc != NW_GTPV1U_OK) {
GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).status |= 0xFF;
LOG_E(GTPU, "NW_GTPV1U_ULP_API_DESTROY_TUNNEL_ENDPOINT failed");
}
//-----------------------
// PDCP->GTPV1U mapping
//-----------------------
gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].state = BEARER_DOWN;
gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].teid_gNB = 0;
gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].teid_upf = 0;
gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].upf_ip_addr = 0;
gtpv1u_ue_data_p->num_bearers -= 1;
if (gtpv1u_ue_data_p->num_bearers == 0) {
hash_rc = hashtable_remove(RC.nr_gtpv1u_data_g->ue_mapping, req_pP->rnti);
LOG_D(GTPU, "Removed user rnti %x,no more bearers configured\n", req_pP->rnti);
}
//-----------------------
// GTPV1U->PDCP mapping
//-----------------------
hash_rc = hashtable_remove(RC.nr_gtpv1u_data_g->teid_mapping, teid_gNB);
if (hash_rc != HASH_TABLE_OK) {
LOG_D(GTPU, "Removed user rnti %x , gNB NGU teid %u not found\n", req_pP->rnti, teid_gNB);
}
}
}// else silently do nothing
LOG_D(GTPU, "Tx GTPV1U_GNB_DELETE_TUNNEL_RESP user rnti %x gNB NGU teid %u status %u\n",
GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).rnti,
GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).gnb_NGu_teid,
GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).status);
MSC_LOG_TX_MESSAGE(
MSC_GTPU_GNB,
MSC_RRC_GNB,
NULL,0,
"0 GTPV1U_GNB_DELETE_TUNNEL_RESP rnti %x teid %x",
GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).rnti,
teid_gNB);
return itti_send_msg_to_task(TASK_RRC_GNB, instanceP, message_p);
}
//-----------------------------------------------------------------------------
static int gtpv1u_gNB_send_init_udp(const Gtpv1uNGReq *req) {
// Create and alloc new message
......@@ -603,6 +770,10 @@ void *gtpv1u_gNB_process_itti_msg(void *notUsed) {
gtpv1u_ng_req(instance, &received_message_p->ittiMsg.gtpv1uNGReq);
break;
case GTPV1U_GNB_DELETE_TUNNEL_REQ:
gtpv1u_delete_ngu_tunnel(instance, &received_message_p->ittiMsg.NRGtpv1uDeleteTunnelReq);
break;
case TERMINATE_MESSAGE: {
if (RC.nr_gtpv1u_data_g->ue_mapping != NULL) {
hashtable_destroy (&(RC.nr_gtpv1u_data_g->ue_mapping));
......
......@@ -40,5 +40,12 @@ gtpv1u_create_ngu_tunnel(
const gtpv1u_gnb_create_tunnel_req_t * const create_tunnel_req_pP,
gtpv1u_gnb_create_tunnel_resp_t * const create_tunnel_resp_pP);
int
gtpv1u_update_ngu_tunnel(
const instance_t instanceP,
const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP,
const rnti_t prior_rnti
);
#endif /* GTPV1U_GNB_TASK_H_ */
......@@ -525,6 +525,8 @@ void generateSecurityModeComplete(as_nas_info_t *initialNasMsg)
}
void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransparentContainer *sortransparentcontainer) {
//wait send RRCReconfigurationComplete and InitialContextSetupResponse
sleep(1);
int length = 0;
int size = 0;
fgs_nas_message_t nas_msg;
......@@ -603,6 +605,8 @@ void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransparentCo
}
void generatePduSessionEstablishRequest(as_nas_info_t *initialNasMsg){
//wait send RegistrationComplete
usleep(100*150);
int size = 0;
fgs_nas_message_t nas_msg;
memset(&nas_msg, 0, sizeof(fgs_nas_message_t));
......
......@@ -1754,7 +1754,7 @@ int ngap_gNB_handle_pdusession_modify_request(uint32_t assoc_id,
return 0;
}
// handle e-rab release command and send it to rrc_end
// handle pdu session release command and send it to rrc_end
static
int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id,
uint32_t stream,
......@@ -1772,7 +1772,7 @@ int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id,
container = &pdu->choice.initiatingMessage->value.choice.PDUSessionResourceReleaseCommand;
if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) {
NGAP_ERROR("[SCTP %d] Received E-RAB release command for non existing AMF context\n", assoc_id);
NGAP_ERROR("[SCTP %d] Received pdu session release command for non existing AMF context\n", assoc_id);
return -1;
}
......@@ -1805,11 +1805,11 @@ int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id,
}
/* Initial context request = UE-related procedure -> stream != 0 */
if (stream == 0) {
NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n",
assoc_id, stream);
return -1;
}
// if (stream == 0) {
// NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n",
// assoc_id, stream);
// return -1;
// }
ue_desc_p->rx_stream = stream;
......@@ -1818,7 +1818,7 @@ int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id,
(uint64_t)ue_desc_p->amf_ue_ngap_id, amf_ue_ngap_id);
}
NGAP_DEBUG("[SCTP %d] Received E-RAB release command for gNB_UE_NGAP_ID %lu amf_ue_ngap_id %lu\n",
NGAP_DEBUG("[SCTP %d] Received pdu session release command for gNB_UE_NGAP_ID %lu amf_ue_ngap_id %lu\n",
assoc_id, gnb_ue_ngap_id, amf_ue_ngap_id);
message_p = itti_alloc_new_message(TASK_NGAP, NGAP_PDUSESSION_RELEASE_COMMAND);
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).gNB_ue_ngap_id = gnb_ue_ngap_id;
......@@ -1850,7 +1850,18 @@ int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id,
item_p = (NGAP_PDUSessionResourceToReleaseItemRelCmd_t *)ie->value.choice.PDUSessionResourceToReleaseListRelCmd.list.array[i];
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].pdusession_id = item_p->pDUSessionID;
NGAP_DEBUG("[SCTP] Received E-RAB release command for pDUSessionID id %ld\n", item_p->pDUSessionID);
if(item_p->pDUSessionResourceReleaseCommandTransfer.size > 0) {
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_length = item_p->pDUSessionResourceReleaseCommandTransfer.size;
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_buffer = malloc(sizeof(uint8_t) * item_p->pDUSessionResourceReleaseCommandTransfer.size);
memcpy(NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_buffer,
item_p->pDUSessionResourceReleaseCommandTransfer.buf,
item_p->pDUSessionResourceReleaseCommandTransfer.size);
}else {
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_length = 0;
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_buffer = NULL;
NGAP_ERROR("[NGAP] Received pdu session release command for pDUSessionResourceReleaseCommandTransfer is NULL!\n");
}
NGAP_DEBUG("[NGAP] Received pdu session release command for pDUSessionID id %ld\n", item_p->pDUSessionID);
}
} else {
return -1;
......
......@@ -862,6 +862,7 @@ int ngap_gNB_initial_ctxt_resp(
initial_ctxt_resp_p->gNB_ue_ngap_id,
ue_context_p->amf_ue_ngap_id);
/* UE associated signalling -> use the allocated stream */
LOG_I(NR_RRC,"Send message to sctp: NGAP_InitialContextSetupResponse\n");
ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance,
ue_context_p->amf_ref->assoc_id, buffer,
length, ue_context_p->tx_stream);
......@@ -1416,6 +1417,22 @@ int ngap_gNB_pdusession_release_resp(instance_t instance,
ie->value.choice.RAN_UE_NGAP_ID = pdusession_release_resp_p->gNB_ue_ngap_id;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* optional */
if (pdusession_release_resp_p->nb_of_pdusessions_released > 0) {
ie = (NGAP_PDUSessionResourceReleaseResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleaseResponseIEs_t));
ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceReleasedListRelRes;
ie->criticality = NGAP_Criticality_ignore;
ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_AMF_UE_NGAP_ID;
asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* mandatory */
ie = (NGAP_PDUSessionResourceReleaseResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleaseResponseIEs_t));
ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID;
ie->criticality = NGAP_Criticality_ignore;
ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_RAN_UE_NGAP_ID;
ie->value.choice.RAN_UE_NGAP_ID = pdusession_release_resp_p->gNB_ue_ngap_id;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* optional */
if (pdusession_release_resp_p->nb_of_pdusessions_released > 0) {
ie = (NGAP_PDUSessionResourceReleaseResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleaseResponseIEs_t));
......@@ -1423,6 +1440,35 @@ int ngap_gNB_pdusession_release_resp(instance_t instance,
ie->criticality = NGAP_Criticality_ignore;
ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_PDUSessionResourceReleasedListRelRes;
for (i = 0; i < pdusession_release_resp_p->nb_of_pdusessions_released; i++) {
NGAP_PDUSessionResourceReleasedItemRelRes_t *item;
item = (NGAP_PDUSessionResourceReleasedItemRelRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleasedItemRelRes_t));
item->pDUSessionID = pdusession_release_resp_p->pdusession_release[i].pdusession_id;
if(pdusession_release_resp_p->pdusession_release[i].transfer_length > 0){
item->pDUSessionResourceReleaseResponseTransfer.size = pdusession_release_resp_p->pdusession_release[i].transfer_length;
item->pDUSessionResourceReleaseResponseTransfer.buf = malloc(sizeof(uint8_t) * pdusession_release_resp_p->pdusession_release[i].transfer_length);
memcpy(item->pDUSessionResourceReleaseResponseTransfer.buf,
pdusession_release_resp_p->pdusession_release[i].transfer_buffer,
pdusession_release_resp_p->pdusession_release[i].transfer_length);
}else {
item->pDUSessionResourceReleaseResponseTransfer.size = 0;
item->pDUSessionResourceReleaseResponseTransfer.buf = NULL;
NGAP_DEBUG("pdusession_release_resp: transfer_buffer is NULL!\n");
#ifdef ITTI_SIM
//For testing only
item->pDUSessionResourceReleaseResponseTransfer.buf = malloc(sizeof(uint8_t) * 1);
item->pDUSessionResourceReleaseResponseTransfer.size = 1;
uint8_t temp = 0;
memcpy(item->pDUSessionResourceReleaseResponseTransfer.buf,
&temp,
item->pDUSessionResourceReleaseResponseTransfer.size);
#endif
}
NGAP_DEBUG("pdusession_release_resp: pdusession ID %ld\n", item->pDUSessionID);
ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceReleasedListRelRes.list, item);
}
for (i = 0; i < pdusession_release_resp_p->nb_of_pdusessions_released; i++) {
NGAP_PDUSessionResourceReleasedItemRelRes_t *item;
item = (NGAP_PDUSessionResourceReleasedItemRelRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleasedItemRelRes_t));
......
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