diff --git a/common/utils/msc/msc.h b/common/utils/msc/msc.h index 77ff6fd62fb4a6b09eca75a73788a9218c347cab..aab872cfe150607a06f6f19b2a23c435d57f82e3 100644 --- a/common/utils/msc/msc.h +++ b/common/utils/msc/msc.h @@ -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, diff --git a/openair2/COMMON/gtpv1_u_messages_def.h b/openair2/COMMON/gtpv1_u_messages_def.h index 8531ce16a04503eb15460d371e71949ad0ef099a..86103dd91151b910a930814211c7119631b4e451 100644 --- a/openair2/COMMON/gtpv1_u_messages_def.h +++ b/openair2/COMMON/gtpv1_u_messages_def.h @@ -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) diff --git a/openair2/COMMON/gtpv1_u_messages_types.h b/openair2/COMMON/gtpv1_u_messages_types.h index c7e247f0fa83587a5b08895ff80ffb0a42597477..8fde34300060ffc4264b40e24ca30b1098a56b83 100644 --- a/openair2/COMMON/gtpv1_u_messages_types.h +++ b/openair2/COMMON/gtpv1_u_messages_types.h @@ -40,7 +40,10 @@ #define GTPV1U_ENB_END_MARKER_IND(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uEndMarkerInd #define GTPV1U_ENB_S1_REQ(mSGpTR) (mSGpTR)->ittiMsg.gtpv1uS1Req -#define GTPV1U_GNB_NG_REQ(mSGpTR) (mSGpTR)->ittiMsg.gtpv1uNGReq + +#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_ */ diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h index a2b40815d6952543f0d674392e8f673bdd06d185..af746b91933620ff657dbb752c91e48b51bf80c6 100644 --- a/openair2/COMMON/ngap_messages_types.h +++ b/openair2/COMMON/ngap_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 { diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 27fb9a78297d49e9270ba586740a55428101d66c..09964eda7c154d5ee8f4f6425b287ecbe8abf85e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -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 diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 5de9e96d853d5a13cad3e420d50db74f1e229322..e6e9e370cbf6bf71f5307c2e7a1d1b6955919174 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -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 -) + uint8_t Transaction_id, + 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); +} + diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h index 44947c04edcb0acbc35ea4f0a4e547bda033a8b0..bfc4942138ef96e11dbaa9a114b9fa4240369543 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.h +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h @@ -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, @@ -106,11 +106,18 @@ uint8_t do_NR_SA_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, 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); + const protocol_ctxt_t *const ctxt_pP, + uint8_t *buffer, + uint8_t Transaction_id, + 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, @@ -138,4 +145,23 @@ do_NR_DLInformationTransfer( uint8_t do_NR_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, - uint8_t *pdu_buffer); \ No newline at end of file + 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); + diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 9345093ba7f05921d95241808be3354d665d20d5..e051ae082bc297090e0eb6430c20e06975c565a7 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -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 { @@ -323,7 +326,7 @@ typedef struct gNB_RRC_UE_s { NR_EstablishmentCause_t establishment_cause; /* Information from UE RRC ConnectionReestablishmentRequest */ - NR_ReestablishmentCause_t reestablishment_cause; + NR_ReestablishmentCause_t reestablishment_cause; /* UE id for initial connection to S1AP */ uint16_t ue_initial_id; @@ -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; //--------------------------------------------------- diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index a38134970ef55db926c42f81d4766f50c341d73c..80812a7df467cd91b22c68fba383b6ebfb9e6e7d 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -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); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 679c9d0b3c44d4fd2dc790d137aba04150822225..fb35ede347f113519d40e5e3b211750230c1b085 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -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, @@ -486,23 +564,120 @@ rrc_gNB_process_RRCSetupComplete( //----------------------------------------------------------------------------- void rrc_gNB_generate_defaultRRCReconfiguration( - const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *ue_context_pP ) //----------------------------------------------------------------------------- { - // 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]; - - 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"); + uint8_t buffer[RRC_BUF_SIZE]; + uint16_t size; + 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; + } + + 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, @@ -526,15 +701,15 @@ rrc_gNB_generate_defaultRRCReconfiguration( 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); + 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, @@ -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,31 +1340,25 @@ 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; - uint64_t random_value = 0; - - dec_rval = uper_decode( NULL, - &asn_DEF_NR_UL_CCCH_Message, - (void **)&ul_ccch_msg, - (uint8_t *) buffer, - 100, - 0, - 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; - } + NR_RRCReestablishmentRequest_IEs_t rrcReestablishmentRequest; + uint64_t random_value = 0; + int i; + + dec_rval = uper_decode( NULL, + &asn_DEF_NR_UL_CCCH_Message, + (void **)&ul_ccch_msg, + (uint8_t *) buffer, + 100, + 0, + 0); - 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: + if (dec_rval.consumed == 0) { /* TODO */ LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_FMT" Received PR_NOTHING on UL-CCCH-Message\n", @@ -833,7 +1452,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, LOG_E(RRC, "%s:%d:%s: rrc_gNB_get_next_free_ue_context returned NULL\n", __FILE__, __LINE__, __FUNCTION__); } - if (ue_context_p != NULL) { + if (ue_context_p != NULL) { ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence = TRUE; ue_context_p->ue_context.ng_5G_S_TMSI_Part1 = s_tmsi_part1; } @@ -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) diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 97f23cffe362e255385f2da9ad3398c7ddcf9a51..1136fcb19a4aa7adb03c851dfcc2f223a9f36d1b 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -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(>PV1U_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; +} diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.h b/openair2/RRC/NR/rrc_gNB_NGAP.h index 85f4f183e641488e28a18d35dd9fd3ccc29e6b64..f13c468f94f7141b28866725f9b2ae9aa67b4c80 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.h +++ b/openair2/RRC/NR/rrc_gNB_NGAP.h @@ -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 diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c index 757c35d7bc255ba8106a0dc84655147a59f117e4..988db09cc1e2573cd14c3b8cec6a436ab837cf7d 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.c +++ b/openair2/RRC/NR/rrc_gNB_UE_context.c @@ -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; } diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 4085e41aac41c33fdf2b8f90742d1577cb1c328a..28646384cf17826329978a9e238903c2146351ef 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -183,15 +183,15 @@ 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++; + // Add the new E-RABs at the corresponding rrc ue context of the gNB + 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 diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index c031d1c5afd5e3f528706e87605e87298de462fb..2f5919e3d15c4c7d2a4b3feb457b360b022222dc 100755 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -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; @@ -1394,81 +1404,83 @@ static void rrc_ue_generate_RRCSetupComplete( } int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB_INFO *const Srb_info, const uint8_t gNB_index ){ - NR_DL_CCCH_Message_t *dl_ccch_msg=NULL; - asn_dec_rval_t dec_rval; - int rval=0; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_IN); - // LOG_D(RRC,"[UE %d] Decoding DL-CCCH message (%d bytes), State %d\n",ue_mod_idP,Srb_info->Rx_buffer.payload_size, - // NR_UE_rrc_inst[ue_mod_idP].Info[gNB_index].State); - dec_rval = uper_decode(NULL, - &asn_DEF_NR_DL_CCCH_Message, - (void **)&dl_ccch_msg, - (uint8_t *)Srb_info->Rx_buffer.Payload, - 100,0,0); - - // if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout,&asn_DEF_NR_DL_CCCH_Message,(void *)dl_ccch_msg); - // } - - if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) { - LOG_E(RRC,"[UE %d] Frame %d : Failed to decode DL-CCCH-Message (%zu bytes)\n",ctxt_pP->module_id,ctxt_pP->frame,dec_rval.consumed); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT); - return -1; - } - - if (dl_ccch_msg->message.present == NR_DL_CCCH_MessageType_PR_c1) { - if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State == NR_RRC_SI_RECEIVED) { - switch (dl_ccch_msg->message.choice.c1->present) { - case NR_DL_CCCH_MessageType__c1_PR_NOTHING: - LOG_I(NR_RRC, "[UE%d] Frame %d : Received PR_NOTHING on DL-CCCH-Message\n", - ctxt_pP->module_id, - ctxt_pP->frame); - rval = 0; - break; - - case NR_DL_CCCH_MessageType__c1_PR_rrcReject: - LOG_I(NR_RRC, - "[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReject \n", - ctxt_pP->module_id, - ctxt_pP->frame); - rval = 0; - break; - - case NR_DL_CCCH_MessageType__c1_PR_rrcSetup: - LOG_I(NR_RRC, - "[UE%d][RAPROC] Frame %d : Logical Channel DL-CCCH (SRB0), Received NR_RRCSetup RNTI %x\n", - 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; - - nr_rrc_ue_process_masterCellGroup( - ctxt_pP, - gNB_index, - &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup); - nr_sa_rrc_ue_process_radioBearerConfig( - ctxt_pP, - gNB_index, - &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig); - nr_rrc_set_state (ctxt_pP->module_id, RRC_STATE_CONNECTED); - nr_rrc_set_sub_state (ctxt_pP->module_id, RRC_SUB_STATE_CONNECTED); - NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].rnti = ctxt_pP->rnti; - rrc_ue_generate_RRCSetupComplete( - ctxt_pP, - gNB_index, - dl_ccch_msg->message.choice.c1->choice.rrcSetup->rrc_TransactionIdentifier, - NR_UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity); - rval = 0; - break; - - default: - LOG_E(NR_RRC, "[UE%d] Frame %d : Unknown message\n", - ctxt_pP->module_id, - ctxt_pP->frame); - rval = -1; - break; + NR_DL_CCCH_Message_t *dl_ccch_msg=NULL; + asn_dec_rval_t dec_rval; + int rval=0; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_IN); + // LOG_D(RRC,"[UE %d] Decoding DL-CCCH message (%d bytes), State %d\n",ue_mod_idP,Srb_info->Rx_buffer.payload_size, + // NR_UE_rrc_inst[ue_mod_idP].Info[gNB_index].State); + dec_rval = uper_decode(NULL, + &asn_DEF_NR_DL_CCCH_Message, + (void **)&dl_ccch_msg, + (uint8_t *)Srb_info->Rx_buffer.Payload, + 100,0,0); + + // if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout,&asn_DEF_NR_DL_CCCH_Message,(void *)dl_ccch_msg); + // } + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) { + LOG_E(RRC,"[UE %d] Frame %d : Failed to decode DL-CCCH-Message (%zu bytes)\n",ctxt_pP->module_id,ctxt_pP->frame,dec_rval.consumed); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT); + return -1; + } + + if (dl_ccch_msg->message.present == NR_DL_CCCH_MessageType_PR_c1) { + if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State == NR_RRC_SI_RECEIVED) { + switch (dl_ccch_msg->message.choice.c1->present) { + case NR_DL_CCCH_MessageType__c1_PR_NOTHING: + LOG_I(NR_RRC, "[UE%d] Frame %d : Received PR_NOTHING on DL-CCCH-Message\n", + ctxt_pP->module_id, + ctxt_pP->frame); + rval = 0; + break; + + case NR_DL_CCCH_MessageType__c1_PR_rrcReject: + LOG_I(NR_RRC, + "[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReject \n", + ctxt_pP->module_id, + ctxt_pP->frame); + rval = 0; + break; + + case NR_DL_CCCH_MessageType__c1_PR_rrcSetup: + LOG_I(NR_RRC, + "[UE%d][RAPROC] Frame %d : Logical Channel DL-CCCH (SRB0), Received NR_RRCSetup RNTI %x\n", + 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; + + nr_rrc_ue_process_masterCellGroup( + ctxt_pP, + gNB_index, + &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup); + nr_sa_rrc_ue_process_radioBearerConfig( + ctxt_pP, + gNB_index, + &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig); + nr_rrc_set_state (ctxt_pP->module_id, RRC_STATE_CONNECTED); + nr_rrc_set_sub_state (ctxt_pP->module_id, RRC_SUB_STATE_CONNECTED); + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].rnti = ctxt_pP->rnti; + rrc_ue_generate_RRCSetupComplete( + ctxt_pP, + gNB_index, + dl_ccch_msg->message.choice.c1->choice.rrcSetup->rrc_TransactionIdentifier, + NR_UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity); + rval = 0; + break; + + default: + LOG_E(NR_RRC, "[UE%d] Frame %d : Unknown message\n", + ctxt_pP->module_id, + ctxt_pP->frame); + rval = -1; + break; + } } } } @@ -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,32 +2333,38 @@ 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 - as_nas_info_t initialNasMsg; - memset(&initialNasMsg, 0, sizeof(as_nas_info_t)); - generateRegistrationComplete(&initialNasMsg, NULL); - if(initialNasMsg.length > 0){ - MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_RRC_NRUE, NAS_UPLINK_DATA_REQ); - NAS_UPLINK_DATA_REQ(message_p).UEid = ctxt_pP->module_id; - NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)initialNasMsg.data; - NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = initialNasMsg.length; - itti_send_msg_to_task(TASK_RRC_NRUE, ctxt_pP->instance, message_p); - LOG_I(NR_RRC, " Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n"); - } - as_nas_info_t pduEstablishMsg; - memset(&pduEstablishMsg, 0, sizeof(as_nas_info_t)); - generatePduSessionEstablishRequest(&pduEstablishMsg); - if(initialNasMsg.length > 0){ - MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_RRC_NRUE, NAS_UPLINK_DATA_REQ); - NAS_UPLINK_DATA_REQ(message_p).UEid = ctxt_pP->module_id; - NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)pduEstablishMsg.data; - NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = pduEstablishMsg.length; - 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"); - } + if (AMF_MODE_ENABLED) { + as_nas_info_t initialNasMsg; + memset(&initialNasMsg, 0, sizeof(as_nas_info_t)); + generateRegistrationComplete(&initialNasMsg, NULL); + if(initialNasMsg.length > 0){ + MessageDef *message_p; + message_p = itti_alloc_new_message(TASK_RRC_NRUE, NAS_UPLINK_DATA_REQ); + NAS_UPLINK_DATA_REQ(message_p).UEid = ctxt_pP->module_id; + NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)initialNasMsg.data; + NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = initialNasMsg.length; + itti_send_msg_to_task(TASK_RRC_NRUE, ctxt_pP->instance, message_p); + LOG_I(NR_RRC, " Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n"); + } + as_nas_info_t pduEstablishMsg; + memset(&pduEstablishMsg, 0, sizeof(as_nas_info_t)); + generatePduSessionEstablishRequest(&pduEstablishMsg); + if(initialNasMsg.length > 0){ + MessageDef *message_p; + message_p = itti_alloc_new_message(TASK_RRC_NRUE, NAS_UPLINK_DATA_REQ); + NAS_UPLINK_DATA_REQ(message_p).UEid = ctxt_pP->module_id; + NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)pduEstablishMsg.data; + NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = pduEstablishMsg.length; + 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; @@ -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 +} diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index d9a291f5a3de8e3a7827f60393fcd2d47e4b0de0..8be356a90b7fd12a5407c3c605cb919ea1d5ce44 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -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; diff --git a/openair2/SIMULATION/NR_RRC/itti_sim.c b/openair2/SIMULATION/NR_RRC/itti_sim.c index 4fb784f84dbce5701f51746342a9a75bf5921f4b..de72b764f2a5f1e8e6942466f4fa7592ed56b0ab 100644 --- a/openair2/SIMULATION/NR_RRC/itti_sim.c +++ b/openair2/SIMULATION/NR_RRC/itti_sim.c @@ -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 diff --git a/openair3/GTPV1-U/gtpv1u_gNB.c b/openair3/GTPV1-U/gtpv1u_gNB.c index 8d8a01243744826ce734759ae4bff2966f057fe1..4fde588e9f12ffa82aaf938cad7843f880c15d32 100644 --- a/openair3/GTPV1-U/gtpv1u_gNB.c +++ b/openair3/GTPV1-U/gtpv1u_gNB.c @@ -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 **)>pv1u_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 **)>pv1u_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 **)>pv1u_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)); diff --git a/openair3/GTPV1-U/gtpv1u_gNB_task.h b/openair3/GTPV1-U/gtpv1u_gNB_task.h index 5e16b0ed0cbc328e17846264e8d5c89f466b418a..fcfaa90304fae93b8094f15af132d81033d86c41 100644 --- a/openair3/GTPV1-U/gtpv1u_gNB_task.h +++ b/openair3/GTPV1-U/gtpv1u_gNB_task.h @@ -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_ */ diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index e0c207ce9350f527eb9be86a0392e3e5910004c6..2c07de8dd5abfea1d460c0f0b09d5d672a724f80 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -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)); diff --git a/openair3/NGAP/ngap_gNB_handlers.c b/openair3/NGAP/ngap_gNB_handlers.c index 6051e917b45db58f5a7e715486f3beb72072b8d2..fe500d896b357819a3c256edfa20103988ea98bb 100644 --- a/openair3/NGAP/ngap_gNB_handlers.c +++ b/openair3/NGAP/ngap_gNB_handlers.c @@ -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; diff --git a/openair3/NGAP/ngap_gNB_nas_procedures.c b/openair3/NGAP/ngap_gNB_nas_procedures.c index 27afd1e397edb144c04c32eaf97edaf644732bf1..039b5fc7f8122e141dd7c9c6b2aedf8ffb467a0a 100644 --- a/openair3/NGAP/ngap_gNB_nas_procedures.c +++ b/openair3/NGAP/ngap_gNB_nas_procedures.c @@ -852,21 +852,22 @@ int ngap_gNB_initial_ctxt_resp( return -1; } - MSC_LOG_TX_MESSAGE( - MSC_NGAP_GNB, - MSC_NGAP_AMF, - (const char *)buffer, - length, - MSC_AS_TIME_FMT" InitialContextSetup successfulOutcome gNB_ue_ngap_id %u amf_ue_ngap_id %u", - 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), - initial_ctxt_resp_p->gNB_ue_ngap_id, - ue_context_p->amf_ue_ngap_id); - /* UE associated signalling -> use the allocated stream */ - 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); - - return 0; + MSC_LOG_TX_MESSAGE( + MSC_NGAP_GNB, + MSC_NGAP_AMF, + (const char *)buffer, + length, + MSC_AS_TIME_FMT" InitialContextSetup successfulOutcome gNB_ue_ngap_id %u amf_ue_ngap_id %u", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + 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); + + return 0; } //------------------------------------------------------------------------------ @@ -1421,7 +1422,52 @@ int ngap_gNB_pdusession_release_resp(instance_t instance, 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_PDUSessionResourceReleasedListRelRes; + 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)); + ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceReleasedListRelRes; + 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;