From 44d309a69da5979c8ec5943aa2650591ea4e07d7 Mon Sep 17 00:00:00 2001 From: luis_pereira87 <lpereira@allbesmart.pt> Date: Wed, 3 Aug 2022 09:34:27 +0100 Subject: [PATCH] Implementation of RRC NR_Paging message at gNB --- doc/FEATURE_SET.md | 3 +- openair2/COMMON/f1ap_messages_def.h | 6 +- openair2/COMMON/f1ap_messages_types.h | 13 +++ openair2/F1AP/dummy_enb.c | 7 ++ openair2/F1AP/f1ap_cu_paging.c | 96 ++++++++++++++++++- openair2/F1AP/f1ap_cu_paging.h | 11 ++- openair2/F1AP/f1ap_cu_task.c | 7 ++ openair2/F1AP/f1ap_decoder.c | 4 + openair2/F1AP/f1ap_du_paging.c | 68 +++++++++++++- openair2/F1AP/f1ap_du_paging.h | 12 ++- openair2/F1AP/f1ap_handlers.c | 3 +- openair2/RRC/LTE/rrc_defs.h | 4 +- openair2/RRC/NR/MESSAGES/asn1_msg.c | 48 ++++++++++ openair2/RRC/NR/MESSAGES/asn1_msg.h | 1 + openair2/RRC/NR/nr_rrc_proto.h | 6 ++ openair2/RRC/NR/rrc_gNB.c | 128 ++++++++++++++++++++++++++ openair2/RRC/NR/rrc_gNB_NGAP.c | 34 +++++++ openair2/RRC/NR/rrc_gNB_NGAP.h | 6 ++ openair3/UTILS/conversions.h | 21 +++++ 19 files changed, 463 insertions(+), 15 deletions(-) diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index e69c8328bc1..3f7ffc9fdb2 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -357,7 +357,8 @@ The following features are valid for the gNB and the 5G-NR UE. - RRCSetupRequest/RRCSetup/RRCSetupComplete - RRC Uplink/Downlink Information transfer carrying NAS messages transparently - RRC Reconfiguration/Reconfiguration complete - - Support for master cell group configuration + - Paging + - Support for master cell group configuration - Interface with NGAP for the interactions with the AMF - Interface with F1AP for CU/DU split deployment option - Periodic RRC measurements of serving cell (no A/B events) diff --git a/openair2/COMMON/f1ap_messages_def.h b/openair2/COMMON/f1ap_messages_def.h index f28e0e5ddfc..5db598409fe 100644 --- a/openair2/COMMON/f1ap_messages_def.h +++ b/openair2/COMMON/f1ap_messages_def.h @@ -40,7 +40,6 @@ MESSAGE_DEF(F1AP_UL_RRC_MESSAGE , MESSAGE_PRIORITY_MED, f1ap_ul_r MESSAGE_DEF(F1AP_UE_CONTEXT_RELEASE_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_release_req_t, f1ap_ue_context_release_req) MESSAGE_DEF(F1AP_UE_CONTEXT_RELEASE_CMD, MESSAGE_PRIORITY_MED, f1ap_ue_context_release_cmd_t, f1ap_ue_context_release_cmd) - /* RRC -> F1AP messages */ MESSAGE_DEF(F1AP_DL_RRC_MESSAGE , MESSAGE_PRIORITY_MED, f1ap_dl_rrc_message_t , f1ap_dl_rrc_message ) //MESSAGE_DEF(F1AP_INITIAL_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_initial_context_setup_req_t , f1ap_initial_context_setup_req ) @@ -49,6 +48,5 @@ MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_se MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_modification_req) MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_modification_resp) - - - +/* CU -> DU*/ +MESSAGE_DEF(F1AP_PAGING_IND, MESSAGE_PRIORITY_MED, f1ap_paging_ind_t, f1ap_paging_ind) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index cbc4d1c6f2d..e6150059919 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -50,6 +50,8 @@ #define F1AP_UE_CONTEXT_RELEASE_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_req #define F1AP_UE_CONTEXT_RELEASE_CMD(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_req +#define F1AP_PAGING_IND(mSGpTR) (mSGpTR)->ittiMsg.f1ap_paging_ind + /* Length of the transport layer address string * 160 bits / 8 bits by char. */ @@ -424,4 +426,15 @@ typedef struct f1ap_ue_context_release_s { } f1ap_ue_context_release_req_t, f1ap_ue_context_release_cmd_t, f1ap_ue_context_release_cplt_t; +typedef struct f1ap_paging_ind_s { + uint16_t ueidentityindexvalue; + uint64_t fiveg_s_tmsi; + uint8_t fiveg_s_tmsi_length; + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + uint64_t nr_cellid; + uint8_t paging_drx; +} f1ap_paging_ind_t; + #endif /* F1AP_MESSAGES_TYPES_H_ */ diff --git a/openair2/F1AP/dummy_enb.c b/openair2/F1AP/dummy_enb.c index 08a5b906eed..afb4a1048af 100644 --- a/openair2/F1AP/dummy_enb.c +++ b/openair2/F1AP/dummy_enb.c @@ -52,3 +52,10 @@ abort(); int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) { abort(); } + +int rrc_gNB_generate_pcch_msg(uint32_t tmsi, + uint8_t paging_drx, + instance_t instance, + uint8_t CC_id) { + abort(); +} diff --git a/openair2/F1AP/f1ap_cu_paging.c b/openair2/F1AP/f1ap_cu_paging.c index b6bbedba2f0..5bc56643e19 100644 --- a/openair2/F1AP/f1ap_cu_paging.c +++ b/openair2/F1AP/f1ap_cu_paging.c @@ -19,8 +19,8 @@ * contact@openairinterface.org */ -/*! \file f1ap_du_interface_management.h - * \brief f1ap interface management for DU +/*! \file f1ap_cu_paging.c + * \brief f1ap interface paging for CU * \author EURECOM/NTUST * \date 2018 * \version 0.1 @@ -28,4 +28,94 @@ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr * \note * \warning - */ \ No newline at end of file + */ + +#include "f1ap_common.h" +#include "f1ap_encoder.h" +#include "f1ap_itti_messaging.h" +#include "f1ap_cu_paging.h" + +extern f1ap_setup_req_t *f1ap_du_data_from_du; + +int CU_send_Paging(instance_t instance, f1ap_paging_ind_t *paging) { + F1AP_F1AP_PDU_t pdu; + F1AP_Paging_t *out; + F1AP_PagingIEs_t *ie; + + uint8_t *buffer; + uint32_t len; + + memset(&pdu, 0, sizeof(pdu)); + pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage = (F1AP_InitiatingMessage_t *)calloc(1, sizeof(F1AP_InitiatingMessage_t)); + pdu.choice.initiatingMessage->procedureCode = F1AP_ProcedureCode_id_Paging; + pdu.choice.initiatingMessage->criticality = F1AP_Criticality_reject; + pdu.choice.initiatingMessage->value.present = F1AP_InitiatingMessage__value_PR_Paging; + out = &pdu.choice.initiatingMessage->value.choice.Paging; + + /* mandatory */ + /* UEIdentityIndexValue */ + ie = (F1AP_PagingIEs_t *)calloc(1, sizeof(F1AP_PagingIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_UEIdentityIndexValue; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_PagingIEs__value_PR_UEIdentityIndexValue; + ie->value.choice.UEIdentityIndexValue.present = F1AP_UEIdentityIndexValue_PR_indexLength10; + UEIDENTITYINDEX_TO_BIT_STRING(paging->ueidentityindexvalue, &ie->value.choice.UEIdentityIndexValue.choice.indexLength10); + //LOG_D(F1AP, "indexLength10 %d \n", BIT_STRING_to_uint32(&ie->value.choice.UEIdentityIndexValue.choice.indexLength10)); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* PagingIdentity */ + ie = (F1AP_PagingIEs_t *)calloc(1, sizeof(F1AP_PagingIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_PagingIdentity; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_PagingIEs__value_PR_PagingIdentity; + ie->value.choice.PagingIdentity.present = F1AP_PagingIdentity_PR_cNUEPagingIdentity; + ie->value.choice.PagingIdentity.choice.cNUEPagingIdentity = (F1AP_CNUEPagingIdentity_t*)calloc(1, sizeof(F1AP_CNUEPagingIdentity_t)); + ie->value.choice.PagingIdentity.choice.cNUEPagingIdentity->present = F1AP_CNUEPagingIdentity_PR_fiveG_S_TMSI; + FIVEG_S_TMSI_TO_BIT_STRING(paging->fiveg_s_tmsi, + &ie->value.choice.PagingIdentity.choice.cNUEPagingIdentity->choice.fiveG_S_TMSI); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + /* PagingDRX */ + ie = (F1AP_PagingIEs_t *)calloc(1, sizeof(F1AP_PagingIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_PagingDRX; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_PagingIEs__value_PR_PagingDRX; + ie->value.choice.PagingDRX = paging->paging_drx; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* PagingCell_list */ + ie = (F1AP_PagingIEs_t *)calloc(1, sizeof(F1AP_PagingIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_PagingCell_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_PagingIEs__value_PR_PagingCell_list; + F1AP_PagingCell_ItemIEs_t *itemies; + F1AP_PagingCell_Item_t item; + memset((void *)&item, 0, sizeof(F1AP_PagingCell_Item_t)); + itemies = (F1AP_PagingCell_ItemIEs_t *)calloc(1, sizeof(F1AP_PagingCell_ItemIEs_t)); + itemies->id = F1AP_ProtocolIE_ID_id_PagingCell_Item; + itemies->criticality = F1AP_Criticality_reject; + itemies->value.present = F1AP_PagingCell_ItemIEs__value_PR_PagingCell_Item; + F1AP_NRCGI_t nRCGI; + MCC_MNC_TO_PLMNID(paging->mcc, + paging->mnc, + paging->mnc_digit_length, + &nRCGI.pLMN_Identity); + NR_CELL_ID_TO_BIT_STRING(paging->nr_cellid, &nRCGI.nRCellIdentity); + item.nRCGI = nRCGI; + itemies->value.choice.PagingCell_Item = item; + ASN_SEQUENCE_ADD(&ie->value.choice.PagingCell_list, itemies); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* encode */ + if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1 Paging failure\n"); + return -1; + } + + f1ap_itti_send_sctp_data_req(true, instance, buffer, len, 0); + return 0; +} \ No newline at end of file diff --git a/openair2/F1AP/f1ap_cu_paging.h b/openair2/F1AP/f1ap_cu_paging.h index b6bbedba2f0..5cff651fcc4 100644 --- a/openair2/F1AP/f1ap_cu_paging.h +++ b/openair2/F1AP/f1ap_cu_paging.h @@ -19,8 +19,8 @@ * contact@openairinterface.org */ -/*! \file f1ap_du_interface_management.h - * \brief f1ap interface management for DU +/*! \file f1ap_cu_paging.h + * \brief f1ap interface paging for CU * \author EURECOM/NTUST * \date 2018 * \version 0.1 @@ -28,4 +28,9 @@ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr * \note * \warning - */ \ No newline at end of file + */ + +#ifndef F1AP_CU_PAGING_H_ +#define F1AP_CU_PAGING_H_ +int CU_send_Paging(instance_t instance, f1ap_paging_ind_t *paging); +#endif /* F1AP_DU_PAGING_H_ */ diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c index b521d0c83dc..b2d2c872d1e 100644 --- a/openair2/F1AP/f1ap_cu_task.c +++ b/openair2/F1AP/f1ap_cu_task.c @@ -34,6 +34,7 @@ #include "f1ap_cu_interface_management.h" #include "f1ap_cu_rrc_message_transfer.h" #include "f1ap_cu_ue_context_management.h" +#include "f1ap_cu_paging.h" #include "f1ap_cu_task.h" #include <openair3/ocp-gtpu/gtp_itf.h> @@ -193,6 +194,12 @@ void *F1AP_CU_task(void *arg) { &F1AP_UE_CONTEXT_RELEASE_CMD(received_msg)); break; + case F1AP_PAGING_IND: + LOG_I(F1AP, "CU Task Received F1AP_PAGING_IND\n"); + CU_send_Paging(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + &F1AP_PAGING_IND(received_msg)); + break; + // case F1AP_SETUP_RESPONSE: // This is from RRC // CU_send_F1_SETUP_RESPONSE(instance, *f1ap_setup_ind, &(F1AP_SETUP_RESP) f1ap_setup_resp) // break; diff --git a/openair2/F1AP/f1ap_decoder.c b/openair2/F1AP/f1ap_decoder.c index 60b3f94310e..6d1c60c67df 100644 --- a/openair2/F1AP/f1ap_decoder.c +++ b/openair2/F1AP/f1ap_decoder.c @@ -83,6 +83,10 @@ static int f1ap_decode_initiating_message(F1AP_F1AP_PDU_t *pdu) { LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextModification\n", __func__); break; + case F1AP_ProcedureCode_id_Paging: + LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_Paging\n", __func__); + break; + // case F1AP_ProcedureCode_id_InitialContextSetup: // res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu); // message_id = F1AP_INITIAL_CONTEXT_SETUP_LOG; diff --git a/openair2/F1AP/f1ap_du_paging.c b/openair2/F1AP/f1ap_du_paging.c index b6bbedba2f0..46f17fd64d0 100644 --- a/openair2/F1AP/f1ap_du_paging.c +++ b/openair2/F1AP/f1ap_du_paging.c @@ -28,4 +28,70 @@ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr * \note * \warning - */ \ No newline at end of file + */ +#include "f1ap_common.h" +#include "f1ap_du_paging.h" +#include "conversions.h" +#include "asn1_conversions.h" +#include "openair2/RRC/LTE/rrc_proto.h" + +int DU_handle_Paging(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + F1AP_Paging_t *paging; + F1AP_PagingIEs_t *ie; + long tmsi; + uint8_t pagingdrx; + uint8_t *fiveg_tmsi_buf = NULL; + + DevAssert(pdu); + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_F1AP_F1AP_PDU, pdu); + } + + paging = &pdu->choice.initiatingMessage->value.choice.Paging; + // get UEIdentityIndexValue + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_PagingIEs_t, ie, paging, + F1AP_ProtocolIE_ID_id_UEIdentityIndexValue, true); + + LOG_D(F1AP, "indexLength10 %d\n", BIT_STRING_to_uint32(&ie->value.choice.UEIdentityIndexValue.choice.indexLength10)); + + // get PagingIdentity + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_PagingIEs_t, ie, paging, + F1AP_ProtocolIE_ID_id_PagingIdentity, true); + + if(ie != NULL){ + fiveg_tmsi_buf = ie->value.choice.PagingIdentity.choice.cNUEPagingIdentity->choice.fiveG_S_TMSI.buf; + + tmsi = ((long)fiveg_tmsi_buf[0] << 40) + + ((long)fiveg_tmsi_buf[1] << 32) + + (fiveg_tmsi_buf[2] << 24) + + (fiveg_tmsi_buf[3] << 16) + + (fiveg_tmsi_buf[4] << 8) + + fiveg_tmsi_buf[5]; + + LOG_D(F1AP, "tmsi %ld\n", tmsi); + } + + // get PagingDRX + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_PagingIEs_t, ie, paging, + F1AP_ProtocolIE_ID_id_PagingDRX, true); + + if(ie != NULL) { + pagingdrx = (uint8_t)ie->value.choice.PagingDRX; + } + + LOG_D(F1AP, "pagingdrx %u\n", pagingdrx); + + // get PagingCell_List + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_PagingIEs_t, ie, paging, + F1AP_ProtocolIE_ID_id_PagingCell_List, true); + + for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + rrc_gNB_generate_pcch_msg((uint32_t)tmsi, pagingdrx, instance, CC_id); + } + + return 0; +} \ No newline at end of file diff --git a/openair2/F1AP/f1ap_du_paging.h b/openair2/F1AP/f1ap_du_paging.h index b6bbedba2f0..3e1806ae022 100644 --- a/openair2/F1AP/f1ap_du_paging.h +++ b/openair2/F1AP/f1ap_du_paging.h @@ -28,4 +28,14 @@ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr * \note * \warning - */ \ No newline at end of file + */ + +#ifndef F1AP_DU_PAGING_H_ +#define F1AP_DU_PAGING_H_ + +int DU_handle_Paging(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + +#endif /* F1AP_DU_PAGING_H_ */ diff --git a/openair2/F1AP/f1ap_handlers.c b/openair2/F1AP/f1ap_handlers.c index 0812a976f63..f3db249e096 100644 --- a/openair2/F1AP/f1ap_handlers.c +++ b/openair2/F1AP/f1ap_handlers.c @@ -38,6 +38,7 @@ #include "f1ap_du_rrc_message_transfer.h" #include "f1ap_cu_ue_context_management.h" #include "f1ap_du_ue_context_management.h" +#include "f1ap_du_paging.h" /* Handlers matrix. Only f1 related procedure present here */ f1ap_message_processing_t f1ap_messages_processing[][3] = { @@ -61,7 +62,7 @@ f1ap_message_processing_t f1ap_messages_processing[][3] = { { 0, 0, 0 }, /* UEInactivityNotification */ { 0, 0, 0 }, /* GNBDUResourceCoordination */ { 0, 0, 0 }, /* SystemInformationDeliveryCommand */ - { 0, 0, 0 }, /* Paging */ + { DU_handle_Paging, 0, 0 }, /* Paging */ { 0, 0, 0 }, /* Notify */ { 0, 0, 0 }, /* WriteReplaceWarning */ { 0, 0, 0 }, /* PWSCancel */ diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index 4d1dfaf5aa4..f0fc2275ac4 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -917,11 +917,13 @@ typedef struct UE_RRC_INST_s { } UE_RRC_INST; typedef struct UE_PF_PO_s { - bool enable_flag; /* flag indicate whether current object is used */ + bool enable_flag; /* flag indicate whether current object is used */ uint16_t ue_index_value; /* UE index value */ uint8_t PF_min; /* minimal value of Paging Frame (PF) */ uint8_t PO; /* Paging Occasion (PO) */ uint32_t T; /* DRX cycle */ + uint8_t PF_offset; + uint8_t i_s; } UE_PF_PO_t; #include "rrc_proto.h" diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 710a984307f..932a768d64f 100755 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -74,6 +74,8 @@ #include "NR_RRCReconfigurationComplete-IEs.h" #include "NR_DLInformationTransfer.h" #include "NR_RRCReestablishmentRequest.h" +#include "NR_PCCH-Message.h" +#include "NR_PagingRecord.h" #include "NR_UE-CapabilityRequestFilterNR.h" #include "common/utils/nr/nr_common.h" #if defined(NR_Rel16) @@ -136,6 +138,7 @@ #include "intertask_interface.h" #include "common/ran_context.h" +#include "conversions.h" //#define XER_PRINT @@ -2132,3 +2135,48 @@ NR_MeasConfig_t *get_defaultMeasConfig(const gNB_RrcConfigurationReq *conf) return mc; } + +uint8_t do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi) { + LOG_D(NR_RRC, "[gNB %d] do_NR_Paging start\n", Mod_id); + asn_enc_rval_t enc_rval; + NR_PCCH_Message_t pcch_msg; + NR_PagingRecord_t *paging_record_p = NULL; + pcch_msg.message.present = NR_PCCH_MessageType_PR_c1; + pcch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_PCCH_MessageType__c1)); + pcch_msg.message.choice.c1->present = NR_PCCH_MessageType__c1_PR_paging; + pcch_msg.message.choice.c1->choice.paging = CALLOC(1,sizeof(NR_Paging_t)); + pcch_msg.message.choice.c1->choice.paging->pagingRecordList = CALLOC(1,sizeof(*pcch_msg.message.choice.c1->choice.paging->pagingRecordList)); + pcch_msg.message.choice.c1->choice.paging->nonCriticalExtension = NULL; + asn_set_empty(&pcch_msg.message.choice.c1->choice.paging->pagingRecordList->list); + pcch_msg.message.choice.c1->choice.paging->pagingRecordList->list.count = 0; + + if ((paging_record_p = calloc(1, sizeof(NR_PagingRecord_t))) == NULL) { + /* Possible error on calloc */ + return (-1); + } + + memset(paging_record_p, 0, sizeof(NR_PagingRecord_t)); + + /* convert ue_paging_identity_t to PagingUE_Identity_t */ + paging_record_p->ue_Identity.present = NR_PagingUE_Identity_PR_ng_5G_S_TMSI; + // set ng_5G_S_TMSI + INT32_TO_BIT_STRING(tmsi, &paging_record_p->ue_Identity.choice.ng_5G_S_TMSI); + + /* add to list */ + ASN_SEQUENCE_ADD(&pcch_msg.message.choice.c1->choice.paging->pagingRecordList->list, paging_record_p); + LOG_D(NR_RRC, "[gNB %d] do_Paging paging_record: PagingRecordList.count %d\n", + Mod_id, pcch_msg.message.choice.c1->choice.paging->pagingRecordList->list.count); + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_PCCH_Message, NULL, (void *)&pcch_msg, buffer, RRC_BUF_SIZE); + + if(enc_rval.encoded == -1) { + LOG_I(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return -1; + } + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_PCCH_Message, (void *)&pcch_msg); + } + + 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 997adb2bd27..241c2deb483 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.h +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h @@ -193,5 +193,6 @@ do_RRCReestablishmentComplete( int64_t rrc_TransactionIdentifier); NR_MeasConfig_t *get_defaultMeasConfig(const gNB_RrcConfigurationReq *conf); +uint8_t do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi); #endif /* __RRC_NR_MESSAGES_ASN1_MSG__H__ */ diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index ea7f07965f5..57aee7a6b2b 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -219,4 +219,10 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag, uint8_t *const kUPenc, uint8_t *const kUPint, struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); + +int rrc_gNB_generate_pcch_msg(uint32_t tmsi, + uint8_t paging_drx, + instance_t instance, + uint8_t CC_id); + #endif diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index d885b961432..edc4a8dcfbe 100755 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -4024,6 +4024,10 @@ void *rrc_gnb_task(void *args_p) { rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(msg_p, msg_name_p, instance); break; + case NGAP_PAGING_IND: + rrc_gNB_process_PAGING_IND(msg_p, msg_name_p, instance); + break; + default: LOG_E(NR_RRC, "[gNB %ld] Received unexpected message %s\n", instance, msg_name_p); break; @@ -4218,6 +4222,130 @@ rrc_gNB_generate_RRCRelease( ue_context_pP->ue_context.ue_release_timer_rrc = 1; } } + +int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t instance, uint8_t CC_id){ + const unsigned int Ttab[4] = {32,64,128,256}; + uint8_t Tc; + uint8_t Tue; + uint32_t pfoffset; + uint32_t N; /* N: min(T,nB). total count of PF in one DRX cycle */ + uint32_t Ns = 0; /* Ns: max(1,nB/T) */ + uint8_t i_s; /* i_s = floor(UE_ID/N) mod Ns */ + uint32_t T; /* DRX cycle */ + uint32_t length; + uint8_t buffer[RRC_BUF_SIZE]; + struct NR_SIB1 *sib1 = RC.nrrrc[instance]->carrier.siblock1->message.choice.c1->choice.systemInformationBlockType1; + + /* get default DRX cycle from configuration */ + Tc = sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.defaultPagingCycle; + + Tue = paging_drx; + /* set T = min(Tc,Tue) */ + T = Tc < Tue ? Ttab[Tc] : Ttab[Tue]; + /* set N = PCCH-Config->nAndPagingFrameOffset */ + switch (sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.nAndPagingFrameOffset.present) { + case NR_PCCH_Config__nAndPagingFrameOffset_PR_oneT: + N = T; + pfoffset = 0; + break; + case NR_PCCH_Config__nAndPagingFrameOffset_PR_halfT: + N = T/2; + pfoffset = 1; + break; + case NR_PCCH_Config__nAndPagingFrameOffset_PR_quarterT: + N = T/4; + pfoffset = 3; + break; + case NR_PCCH_Config__nAndPagingFrameOffset_PR_oneEighthT: + N = T/8; + pfoffset = 7; + break; + case NR_PCCH_Config__nAndPagingFrameOffset_PR_oneSixteenthT: + N = T/16; + pfoffset = 15; + break; + default: + LOG_E(RRC, "[gNB %ld] In rrc_gNB_generate_pcch_msg: pfoffset error (pfoffset %d)\n", + instance, sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.nAndPagingFrameOffset.present); + return (-1); + + } + + switch (sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.ns) { + case NR_PCCH_Config__ns_four: + if(*sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->pagingSearchSpace == 0){ + LOG_E(RRC, "[gNB %ld] In rrc_gNB_generate_pcch_msg: ns error only 1 or 2 is allowed when pagingSearchSpace is 0\n", + instance); + return (-1); + } else { + Ns = 4; + } + break; + case NR_PCCH_Config__ns_two: + Ns = 2; + break; + case NR_PCCH_Config__ns_one: + Ns = 1; + break; + default: + LOG_E(RRC, "[gNB %ld] In rrc_gNB_generate_pcch_msg: ns error (ns %ld)\n", + instance, sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.ns); + return (-1); + } + + /* insert data to UE_PF_PO or update data in UE_PF_PO */ + pthread_mutex_lock(&ue_pf_po_mutex); + uint8_t i = 0; + + for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if ((UE_PF_PO[CC_id][i].enable_flag == true && UE_PF_PO[CC_id][i].ue_index_value == (uint16_t)(tmsi%1024)) + || (UE_PF_PO[CC_id][i].enable_flag != true)) { + /* set T = min(Tc,Tue) */ + UE_PF_PO[CC_id][i].T = T; + /* set UE_ID */ + UE_PF_PO[CC_id][i].ue_index_value = (uint16_t)(tmsi%1024); + /* calculate PF and PO */ + /* set PF_min and PF_offset: (SFN + PF_offset) mod T = (T div N)*(UE_ID mod N) */ + UE_PF_PO[CC_id][i].PF_min = (T / N) * (UE_PF_PO[CC_id][i].ue_index_value % N); + UE_PF_PO[CC_id][i].PF_offset = pfoffset; + /* set i_s */ + /* i_s = floor(UE_ID/N) mod Ns */ + i_s = (uint8_t)((UE_PF_PO[CC_id][i].ue_index_value / N) % Ns); + UE_PF_PO[CC_id][i].i_s = i_s; + + // TODO,set PO + + if (UE_PF_PO[CC_id][i].enable_flag == true) { + //paging exist UE log + LOG_D(NR_RRC,"[gNB %ld] CC_id %d In rrc_gNB_generate_pcch_msg: Update exist UE %d, T %d, N %d, PF %d, i_s %d, PF_offset %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, + T, N, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].i_s, UE_PF_PO[CC_id][i].PF_offset); + } else { + /* set enable_flag */ + UE_PF_PO[CC_id][i].enable_flag = true; + //paging new UE log + LOG_D(NR_RRC,"[gNB %ld] CC_id %d In rrc_gNB_generate_pcch_msg: Insert a new UE %d, T %d, N %d, PF %d, i_s %d, PF_offset %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, + T, N, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].i_s, UE_PF_PO[CC_id][i].PF_offset); + } + break; + } + } + + pthread_mutex_unlock(&ue_pf_po_mutex); + + /* Create message for PDCP (DLInformationTransfer_t) */ + length = do_NR_Paging (instance, + buffer, + tmsi); + + if (length == -1) { + LOG_I(NR_RRC, "do_Paging error\n"); + return -1; + } + // TODO, send message to pdcp + + return 0; +} + void nr_rrc_trigger(protocol_ctxt_t *ctxt, int CC_id, int frame, int subframe) { MessageDef *message_p; diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 9900da9d66c..8e9d3f7939e 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -1714,3 +1714,37 @@ void nr_rrc_rx_tx(void) { } +/*------------------------------------------------------------------------------*/ +int rrc_gNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance_t instance) { + + for (uint16_t tai_size = 0; tai_size < NGAP_PAGING_IND(msg_p).tai_size; tai_size++) { + LOG_I(NR_RRC,"[gNB %ld] In NGAP_PAGING_IND: MCC %d, MNC %d, TAC %d\n", instance, NGAP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc, + NGAP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc, NGAP_PAGING_IND(msg_p).tac[tai_size]); + + for (uint8_t j = 0; j < RC.nrrrc[instance]->configuration.num_plmn; j++) { + if (RC.nrrrc[instance]->configuration.mcc[j] == NGAP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc + && RC.nrrrc[instance]->configuration.mnc[j] == NGAP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc + && RC.nrrrc[instance]->configuration.tac == NGAP_PAGING_IND(msg_p).tac[tai_size]) { + for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + if (NODE_IS_CU(RC.nrrrc[instance]->node_type)) { + MessageDef *m = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_PAGING_IND); + F1AP_PAGING_IND (m).mcc = RC.nrrrc[j]->configuration.mcc[0]; + F1AP_PAGING_IND (m).mnc = RC.nrrrc[j]->configuration.mnc[0]; + F1AP_PAGING_IND (m).mnc_digit_length = RC.nrrrc[j]->configuration.mnc_digit_length[0]; + F1AP_PAGING_IND (m).nr_cellid = RC.nrrrc[j]->nr_cellid; + F1AP_PAGING_IND (m).ueidentityindexvalue = (uint16_t)(NGAP_PAGING_IND(msg_p).ue_paging_identity.s_tmsi.m_tmsi%1024); + F1AP_PAGING_IND (m).fiveg_s_tmsi = NGAP_PAGING_IND(msg_p).ue_paging_identity.s_tmsi.m_tmsi; + F1AP_PAGING_IND (m).paging_drx = NGAP_PAGING_IND(msg_p).paging_drx; + LOG_E(F1AP, "ueidentityindexvalue %u fiveg_s_tmsi %ld paging_drx %u\n", F1AP_PAGING_IND (m).ueidentityindexvalue, F1AP_PAGING_IND (m).fiveg_s_tmsi, F1AP_PAGING_IND (m).paging_drx); + itti_send_msg_to_task(TASK_CU_F1, instance, m); + } else { + rrc_gNB_generate_pcch_msg(NGAP_PAGING_IND(msg_p).ue_paging_identity.s_tmsi.m_tmsi,(uint8_t)NGAP_PAGING_IND(msg_p).paging_drx, instance, CC_id); + } // end of nodetype check + } // end of cc loop + } // end of mcc mnc check + } // end of num_plmn + } // end of tai size + + return 0; +} + diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.h b/openair2/RRC/NR/rrc_gNB_NGAP.h index 5833c8aac21..a03e4df41fb 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.h +++ b/openair2/RRC/NR/rrc_gNB_NGAP.h @@ -189,4 +189,10 @@ nr_rrc_pdcp_config_security( const uint8_t send_security_mode_command ); +int +rrc_gNB_process_PAGING_IND( + MessageDef *msg_p, + const char *msg_name, + instance_t instance); + #endif diff --git a/openair3/UTILS/conversions.h b/openair3/UTILS/conversions.h index ad53c6f27d8..6e961781f0f 100644 --- a/openair3/UTILS/conversions.h +++ b/openair3/UTILS/conversions.h @@ -544,6 +544,27 @@ do { \ (bITsTRING)->bits_unused = 4; \ } while(0) +#define UEIDENTITYINDEX_TO_BIT_STRING(mACRO, bITsTRING) \ +do { \ + (bITsTRING)->buf = calloc(2, sizeof(uint8_t)); \ + (bITsTRING)->buf[0] = (mACRO) >> 2; \ + (bITsTRING)->buf[1] = ((mACRO) & 0x03)<<6; \ + (bITsTRING)->size = 2; \ + (bITsTRING)->bits_unused = 6; \ +} while(0) + +#define FIVEG_S_TMSI_TO_BIT_STRING(mACRO, bITsTRING) \ +do { \ + (bITsTRING)->buf = calloc(6, sizeof(uint8_t)); \ + (bITsTRING)->buf[0] = ((mACRO) >> 40) & 0xff; \ + (bITsTRING)->buf[1] = ((mACRO) >> 32) & 0xff; \ + (bITsTRING)->buf[2] = ((mACRO) >> 24) & 0xff; \ + (bITsTRING)->buf[3] = ((mACRO) >> 16) & 0xff; \ + (bITsTRING)->buf[4] = ((mACRO) >> 8 ) & 0xff; \ + (bITsTRING)->buf[5] = ((mACRO) & 0xff); \ + (bITsTRING)->size = 6; \ + (bITsTRING)->bits_unused = 0; \ +} while(0) /* Used to format an uint32_t containing an ipv4 address */ #define IPV4_ADDR "%u.%u.%u.%u" -- GitLab