From 2f232889aea97c88d1a9891ec1a101894b7df2d6 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS <laurent.thomas@open-cells.com> Date: Wed, 10 Apr 2024 12:02:34 +0200 Subject: [PATCH] synchronous work between PDCP and RRC for DCCCH messages --- cmake_targets/build_oai | 2 +- openair2/COMMON/pdcp_messages_def.h | 5 +- openair2/COMMON/pdcp_messages_types.h | 18 ++ openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c | 2 +- openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 112 ++++++---- openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h | 13 +- openair2/RRC/NR/nr_rrc_common.h | 2 +- openair2/RRC/NR_UE/rrc_UE.c | 239 +++++++++++----------- 8 files changed, 222 insertions(+), 171 deletions(-) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 5594b856afb..42317728f9c 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -510,7 +510,7 @@ function main() { # e.g., cmake_targets/ran_build/build, hence the ../../.. CMAKE_CMD="$CMAKE_CMD ../../.." echo_info "Running \"$CMAKE_CMD\"" - eval $CMAKE_CMD + $CMAKE_CMD compilations $BUILD_DIR all.txt $TARGET_LIST ################### # Doxygen Support # diff --git a/openair2/COMMON/pdcp_messages_def.h b/openair2/COMMON/pdcp_messages_def.h index 5392c9e04df..a9b7b940420 100644 --- a/openair2/COMMON/pdcp_messages_def.h +++ b/openair2/COMMON/pdcp_messages_def.h @@ -35,5 +35,6 @@ MESSAGE_DEF(RRC_NRUE_CAP_INFO_IND, MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataIn MESSAGE_DEF(RRC_DCCH_DATA_COPY_IND, MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataInd, rrc_dcch_data_copy_ind) // gNB -MESSAGE_DEF(NR_RRC_DCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, NRRrcDcchDataReq, nr_rrc_dcch_data_req) -MESSAGE_DEF(NR_RRC_DCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, NRRrcDcchDataInd, nr_rrc_dcch_data_ind) +MESSAGE_DEF(NR_RRC_DCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, NRRrcDcchDataReq, nr_rrc_dcch_data_req) +MESSAGE_DEF(NR_RRC_DCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, NRRrcDcchDataInd, nr_rrc_dcch_data_ind) +MESSAGE_DEF(NR_RRC_DCCH_DATA_RESP, MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataResp, nr_rrc_dcch_data_resp) diff --git a/openair2/COMMON/pdcp_messages_types.h b/openair2/COMMON/pdcp_messages_types.h index b97fdef9861..f64147c011c 100644 --- a/openair2/COMMON/pdcp_messages_types.h +++ b/openair2/COMMON/pdcp_messages_types.h @@ -55,8 +55,25 @@ typedef struct RrcDcchDataReq_s { uint16_t rnti; uint8_t module_id; uint8_t eNB_index; + int returnTask; // itti circular include, impossible to use the correct enum } RrcDcchDataReq; +#include "openair2/RRC/NR/nr_rrc_common.h" +#define maxMSGs (10) +#define maxSZ (maxMSGs * 100) +typedef struct RrcDcchDataResp_s { + bool doCyphering; + bool doIntegrity; + uint8_t integrityProtAlgorithm; + uint8_t cipheringAlgorithm; + uint8_t kRRCenc[NR_K_KEY_SIZE]; + uint8_t kUPenc[NR_K_KEY_SIZE]; + uint8_t kRRCint[NR_K_KEY_SIZE]; + int srbID; + uint8_t buffer[maxSZ]; + int sz[maxMSGs]; +} RrcDcchDataResp; + typedef struct RrcDcchDataInd_s { uint32_t frame; uint8_t dcch_index; @@ -100,6 +117,7 @@ typedef struct NRRrcDcchDataInd_s { uint8_t gNB_index; // LG: needed in UE /* 'msg_integrity' is needed for RRC to check integrity of the PDCP SDU */ nr_pdcp_integrity_data_t msg_integrity; + bool integrityResult; } NRRrcDcchDataInd; typedef struct RrcPcchDataReq_s { diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c index 712bbf6b0cc..6d0be065e3f 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c @@ -308,7 +308,7 @@ static bool nr_pdcp_entity_check_integrity(struct nr_pdcp_entity_t *entity, const nr_pdcp_integrity_data_t *msg_integrity) { if (!entity->has_integrity) - return false; + return true; int header_size = msg_integrity->header_size; diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 17b1b024080..fa71aa99077 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -777,12 +777,53 @@ srb_found: memcpy(rrc_buffer_p, buf, size); MessageDef *message_p = itti_alloc_new_message(TASK_PDCP_UE, 0, NR_RRC_DCCH_DATA_IND); AssertFatal(message_p != NULL, "OUT OF MEMORY\n"); - NR_RRC_DCCH_DATA_IND(message_p).dcch_index = srb_id; - NR_RRC_DCCH_DATA_IND(message_p).sdu_p = rrc_buffer_p; - NR_RRC_DCCH_DATA_IND(message_p).sdu_size = size; - memcpy(&NR_RRC_DCCH_DATA_IND(message_p).msg_integrity, msg_integrity, sizeof(*msg_integrity)); - ue_id_t ue_id = ue->ue_id; - itti_send_msg_to_task(TASK_RRC_NRUE, ue_id, message_p); + nr_pdcp_entity_t *rb = nr_pdcp_get_rb(ue, srb_id, true); + NR_RRC_DCCH_DATA_IND(message_p) = + (NRRrcDcchDataInd){.dcch_index = srb_id, + .sdu_p = rrc_buffer_p, + .sdu_size = size, + .msg_integrity = *msg_integrity, + .integrityResult = rb->check_integrity(rb, (const uint8_t *)buf, size, msg_integrity)}; + itti_send_msg_to_task(TASK_RRC_NRUE, ue->ue_id, message_p); + MessageDef *Resp; + itti_receive_msg(TASK_PDCP_UE, &Resp); + if (Resp == NULL) + return; + RrcDcchDataResp *returned = &Resp->ittiMsg.nr_rrc_dcch_data_resp; + if (returned->doCyphering) { + // configure lower layers to apply SRB integrity protection and ciphering + for (i = 0; i < sizeofArray(ue->srb); i++) { + nr_pdcp_entity_t *rb = nr_pdcp_get_rb(ue, i, true); + if (rb) + rb->set_security(rb, returned->integrityProtAlgorithm, (char *)returned->kRRCint, 0, (char *)returned->kRRCenc); + } + } + if (returned->srbID) { + nr_pdcp_entity_t *rb = nr_pdcp_get_rb(ue, returned->srbID, true); + if (rb) { + char *ptr = (char *)returned->buffer; + for (int i = 0; i < sizeofArray(returned->sz) && returned->sz[i]; i++) { + int max_size = nr_max_pdcp_pdu_size(returned->sz[i]); + char pdu_buf[max_size]; + int pdu_size = rb->process_sdu(rb, ptr, returned->sz[i], 0, pdu_buf, max_size); + deliver_pdu_srb_rlc(NULL, ue->ue_id, returned->srbID, pdu_buf, pdu_size, 0); + ptr += returned->sz[i]; + } + } + } + if (returned->doCyphering) { + // configure lower layers to apply SRB integrity protection and ciphering + for (i = 0; i < sizeofArray(ue->srb); i++) { + nr_pdcp_entity_t *rb = nr_pdcp_get_rb(ue, i, true); + if (rb) + rb->set_security(rb, + returned->integrityProtAlgorithm, + (char *)returned->kRRCint, + returned->cipheringAlgorithm, + (char *)returned->kRRCenc); + } + } + itti_free(ITTI_MSG_ORIGIN_ID(Resp), Resp); } } @@ -801,7 +842,8 @@ void add_srb(int is_gnb, int ciphering_algorithm, int integrity_algorithm, unsigned char *ciphering_key, - unsigned char *integrity_key) + unsigned char *integrity_key, + bool alreadyLocked) { nr_pdcp_entity_t *pdcp_srb; nr_pdcp_ue_t *ue; @@ -811,7 +853,8 @@ void add_srb(int is_gnb, if (s->pdcp_Config != NULL && s->pdcp_Config->t_Reordering != NULL) t_Reordering = decode_t_reordering(*s->pdcp_Config->t_Reordering); - nr_pdcp_manager_lock(nr_pdcp_ue_manager); + if (!alreadyLocked) + nr_pdcp_manager_lock(nr_pdcp_ue_manager); ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, UEid); if (nr_pdcp_get_rb(ue, srb_id, true) != NULL) { LOG_E(PDCP, "warning SRB %d already exist for UE ID %ld, do nothing\n", srb_id, UEid); @@ -837,7 +880,8 @@ void add_srb(int is_gnb, LOG_D(PDCP, "added srb %d to UE ID %ld\n", srb_id, UEid); } - nr_pdcp_manager_unlock(nr_pdcp_ue_manager); + if (!alreadyLocked) + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } void add_drb(int is_gnb, @@ -846,7 +890,8 @@ void add_drb(int is_gnb, int ciphering_algorithm, int integrity_algorithm, unsigned char *ciphering_key, - unsigned char *integrity_key) + unsigned char *integrity_key, + bool alreadyLocked) { nr_pdcp_entity_t *pdcp_drb; nr_pdcp_ue_t *ue; @@ -910,8 +955,8 @@ void add_drb(int is_gnb, exit(1); } - - nr_pdcp_manager_lock(nr_pdcp_ue_manager); + if (!alreadyLocked) + nr_pdcp_manager_lock(nr_pdcp_ue_manager); ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, UEid); if (nr_pdcp_get_rb(ue, drb_id, false) != NULL) { LOG_W(PDCP, "warning DRB %d already exist for UE ID %ld, do nothing\n", drb_id, UEid); @@ -940,7 +985,8 @@ void add_drb(int is_gnb, mappedQFIs2Add, mappedQFIs2AddCount); } - nr_pdcp_manager_unlock(nr_pdcp_ue_manager); + if (!alreadyLocked) + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } void nr_pdcp_add_srbs(eNB_flag_t enb_flag, @@ -952,7 +998,14 @@ void nr_pdcp_add_srbs(eNB_flag_t enb_flag, { if (srb2add_list != NULL) { for (int i = 0; i < srb2add_list->list.count; i++) { - add_srb(enb_flag, UEid, srb2add_list->list.array[i], security_modeP & 0x0f, (security_modeP >> 4) & 0x0f, kRRCenc, kRRCint); + add_srb(enb_flag, + UEid, + srb2add_list->list.array[i], + security_modeP & 0x0f, + (security_modeP >> 4) & 0x0f, + kRRCenc, + kRRCint, + false); } } else LOG_W(PDCP, "nr_pdcp_add_srbs() with void list\n"); @@ -973,7 +1026,8 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag, security_modeP & 0x0f, (security_modeP >> 4) & 0x0f, kUPenc, - kUPint); + kUPint, + false); } } else LOG_W(PDCP, "nr_pdcp_add_drbs() with void list\n"); @@ -1059,34 +1113,6 @@ void nr_pdcp_config_set_security(ue_id_t ue_id, nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } -bool nr_pdcp_check_integrity_srb(ue_id_t ue_id, - int srb_id, - const uint8_t *msg, - int msg_size, - const nr_pdcp_integrity_data_t *msg_integrity) -{ - nr_pdcp_ue_t *ue; - nr_pdcp_entity_t *rb; - - nr_pdcp_manager_lock(nr_pdcp_ue_manager); - - ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id); - - rb = nr_pdcp_get_rb(ue, srb_id, true); - - if (rb == NULL) { - nr_pdcp_manager_unlock(nr_pdcp_ue_manager); - LOG_E(PDCP, "no SRB found (ue_id %ld, rb_id %d)\n", ue_id, srb_id); - return false; - } - - bool ret = rb->check_integrity(rb, msg, msg_size, msg_integrity); - - nr_pdcp_manager_unlock(nr_pdcp_ue_manager); - - return ret; -} - bool nr_pdcp_data_req_srb(ue_id_t ue_id, const rb_id_t rb_id, const mui_t muiP, diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h index 99f7fcdc816..119d5bec643 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h @@ -59,7 +59,8 @@ void add_drb(int is_gnb, int ciphering_algorithm, int integrity_algorithm, unsigned char *ciphering_key, - unsigned char *integrity_key); + unsigned char *integrity_key, + bool alreadyLocked); void nr_pdcp_remove_UE(ue_id_t ue_id); void nr_pdcp_reestablishment(ue_id_t ue_id, int rb_id, bool srb_flag); @@ -71,14 +72,14 @@ void nr_pdcp_reconfigure_drb(ue_id_t ue_id, int drb_id, NR_PDCP_Config_t *pdcp_c void nr_pdcp_release_srb(ue_id_t ue_id, int srb_id); void nr_pdcp_release_drb(ue_id_t ue_id, int drb_id); - void add_srb(int is_gnb, ue_id_t UEid, struct NR_SRB_ToAddMod *s, int ciphering_algorithm, int integrity_algorithm, unsigned char *ciphering_key, - unsigned char *integrity_key); + unsigned char *integrity_key, + bool alreadyLocked); void nr_pdcp_config_set_security(ue_id_t ue_id, const rb_id_t rb_id, @@ -87,12 +88,6 @@ void nr_pdcp_config_set_security(ue_id_t ue_id, uint8_t *const kRRCint_pP, uint8_t *const kUPenc_pP); -bool nr_pdcp_check_integrity_srb(ue_id_t ue_id, - int srb_id, - const uint8_t *msg, - int msg_size, - const nr_pdcp_integrity_data_t *msg_integrity); - bool cu_f1u_data_req(protocol_ctxt_t *ctxt_pP, const srb_flag_t srb_flagP, const rb_id_t rb_id, diff --git a/openair2/RRC/NR/nr_rrc_common.h b/openair2/RRC/NR/nr_rrc_common.h index e1ff2e703e2..26837fb7aa5 100644 --- a/openair2/RRC/NR/nr_rrc_common.h +++ b/openair2/RRC/NR/nr_rrc_common.h @@ -24,7 +24,7 @@ #include <stdio.h> #include <stdlib.h> -#include <stdint.h> +#include <stdint.h> #define NR_RRC_HEADER_SIZE_MAX 64 #define NR_RRC_BUFFER_SIZE_MAX 1024 diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 980f793c0af..7686c4719c1 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -139,19 +139,37 @@ static void nr_rrc_manage_rlc_bearers(NR_UE_RRC_INST_t *rrc, static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, NR_RadioBearerConfig_t *const radioBearerConfig); -static void nr_rrc_ue_generate_rrcReestablishmentComplete(const NR_UE_RRC_INST_t *rrc, const NR_RRCReestablishment_t *rrcReestablishment); +static void nr_rrc_ue_generate_rrcReestablishmentComplete(const NR_UE_RRC_INST_t *rrc, + const NR_RRCReestablishment_t *rrcReestablishment, + RrcDcchDataResp *returned); static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_len); static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc, int gNB_index, NR_RRCReconfiguration_t *rrcReconfiguration); -static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECapabilityEnquiry_t *UECapabilityEnquiry); +static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, + NR_UECapabilityEnquiry_t *UECapabilityEnquiry, + RrcDcchDataResp *returned); static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc, OCTET_STRING_t *masterCellGroup, long *fullConfig); static void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measConfig, NR_UE_Timers_Constants_t *timers); +static char *getRetBuf(RrcDcchDataResp *returned, int *maxSz, int **setSz) +{ + char *ptr = (char *)returned->buffer; + *maxSz = sizeof(returned->buffer); + int i; + for (i = 0; i < sizeofArray(returned->sz) && returned->sz[i]; i++) { + ptr += returned->sz[i]; + *maxSz -= returned->sz[i]; + } + *setSz = returned->sz + i; + AssertFatal(*maxSz > 0 && i < sizeofArray(returned->sz), "Buffers too small, change source code\n"); + return ptr; +} + static NR_RB_status_t get_DRB_status(const NR_UE_RRC_INST_t *rrc, NR_DRB_Identity_t drb_id) { AssertFatal(drb_id > 0 && drb_id < 33, "Invalid DRB ID %ld\n", drb_id); @@ -1009,7 +1027,9 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc, int srb_id, const uint8_t *msg, int msg_size, - const nr_pdcp_integrity_data_t *msg_integrity) + const nr_pdcp_integrity_data_t *msg_integrity, + const bool integrity_pass, + RrcDcchDataResp *returned) { LOG_I(NR_RRC, "Receiving from SRB1 (DL-DCCH), Processing securityModeCommand\n"); @@ -1047,23 +1067,15 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc, ue_rrc->integrityProtAlgorithm = *securityConfigSMC->securityAlgorithmConfig.integrityProtAlgorithm; } - uint8_t kRRCenc[NR_K_KEY_SIZE] = {0}; - uint8_t kUPenc[NR_K_KEY_SIZE] = {0}; - uint8_t kRRCint[NR_K_KEY_SIZE] = {0}; - nr_derive_key(UP_ENC_ALG, ue_rrc->cipheringAlgorithm, ue_rrc->kgnb, kUPenc); - nr_derive_key(RRC_ENC_ALG, ue_rrc->cipheringAlgorithm, ue_rrc->kgnb, kRRCenc); - nr_derive_key(RRC_INT_ALG, ue_rrc->integrityProtAlgorithm, ue_rrc->kgnb, kRRCint); + nr_derive_key(UP_ENC_ALG, ue_rrc->cipheringAlgorithm, ue_rrc->kgnb, returned->kUPenc); + nr_derive_key(RRC_ENC_ALG, ue_rrc->cipheringAlgorithm, ue_rrc->kgnb, returned->kRRCenc); + nr_derive_key(RRC_INT_ALG, ue_rrc->integrityProtAlgorithm, ue_rrc->kgnb, returned->kRRCint); log_dump(NR_RRC, ue_rrc->kgnb, 32, LOG_DUMP_CHAR, "deriving kRRCenc, kRRCint and kUPenc from KgNB="); /* for SecurityModeComplete, ciphering is not activated yet, only integrity */ - uint8_t security_mode = ue_rrc->integrityProtAlgorithm << 4; - // configure lower layers to apply SRB integrity protection and ciphering - for (int i = 1; i < NR_NUM_SRB; i++) { - if (ue_rrc->Srb[i] == RB_ESTABLISHED) - nr_pdcp_config_set_security(ue_rrc->ue_id, i, security_mode, kRRCenc, kRRCint, kUPenc); - } - + returned->integrityProtAlgorithm = ue_rrc->integrityProtAlgorithm; + returned->cipheringAlgorithm = ue_rrc->cipheringAlgorithm; NR_UL_DCCH_Message_t ul_dcch_msg = {0}; ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1; @@ -1071,7 +1083,6 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc, // the SecurityModeCommand message needs to pass the integrity protection check // for the UE to declare AS security to be activated - bool integrity_pass = nr_pdcp_check_integrity_srb(ue_rrc->ue_id, srb_id, msg, msg_size, msg_integrity); if (!integrity_pass) { /* - continue using the configuration used prior to the reception of the SecurityModeCommand message, i.e. * neither apply integrity protection nor ciphering. @@ -1084,68 +1095,40 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc, modeFailure->criticalExtensions.present = NR_SecurityModeFailure__criticalExtensions_PR_securityModeFailure; asn1cCalloc(modeFailure->criticalExtensions.choice.securityModeFailure, ext); ext->nonCriticalExtension = NULL; + } else { + /* integrity passed, send SecurityModeComplete */ + c1->present = NR_UL_DCCH_MessageType__c1_PR_securityModeComplete; - uint8_t buffer[200]; - asn_enc_rval_t enc_rval = - uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, NULL, (void *)&ul_dcch_msg, buffer, sizeof(buffer)); - AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", enc_rval.failed_type->name, enc_rval.encoded); - if (LOG_DEBUGFLAG(DEBUG_ASN1)) - xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_UL_DCCH_Message, &ul_dcch_msg); - - /* disable both ciphering and integrity */ - security_mode = 0; - for (int i = 1; i < NR_NUM_SRB; i++) { - if (ue_rrc->Srb[i] == RB_ESTABLISHED) - nr_pdcp_config_set_security(ue_rrc->ue_id, i, security_mode, NULL, NULL, NULL); - } - - srb_id = 1; // SecurityModeFailure in SRB1 - nr_pdcp_data_req_srb(ue_rrc->ue_id, srb_id, 0, (enc_rval.encoded + 7) / 8, buffer, deliver_pdu_srb_rlc, NULL); - - return; - } - - /* integrity passed, send SecurityModeComplete */ - c1->present = NR_UL_DCCH_MessageType__c1_PR_securityModeComplete; - - asn1cCalloc(c1->choice.securityModeComplete, modeComplete); - modeComplete->rrc_TransactionIdentifier = securityModeCommand->rrc_TransactionIdentifier; - modeComplete->criticalExtensions.present = NR_SecurityModeComplete__criticalExtensions_PR_securityModeComplete; - asn1cCalloc(modeComplete->criticalExtensions.choice.securityModeComplete, ext); - ext->nonCriticalExtension = NULL; - LOG_I(NR_RRC, - "Receiving from SRB1 (DL-DCCH), encoding securityModeComplete, rrc_TransactionIdentifier: %ld\n", - securityModeCommand->rrc_TransactionIdentifier); - uint8_t buffer[200]; - asn_enc_rval_t enc_rval = - uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, NULL, (void *)&ul_dcch_msg, buffer, sizeof(buffer)); + asn1cCalloc(c1->choice.securityModeComplete, modeComplete); + modeComplete->rrc_TransactionIdentifier = securityModeCommand->rrc_TransactionIdentifier; + modeComplete->criticalExtensions.present = NR_SecurityModeComplete__criticalExtensions_PR_securityModeComplete; + asn1cCalloc(modeComplete->criticalExtensions.choice.securityModeComplete, ext); + ext->nonCriticalExtension = NULL; + LOG_I(NR_RRC, + "encoding securityModeComplete, rrc_TransactionIdentifier: %ld\n", + securityModeCommand->rrc_TransactionIdentifier); + ue_rrc->as_security_activated = true; + /* after encoding SecurityModeComplete we activate both ciphering and integrity */ + returned->doCyphering = true; + returned->doIntegrity = true; + } + int maxSz, *setSz; + char *buffer = getRetBuf(returned, &maxSz, &setSz); + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, NULL, (void *)&ul_dcch_msg, buffer, maxSz); AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", enc_rval.failed_type->name, enc_rval.encoded); + returned->srbID = 1; // SecurityMode answer in SRB1 + *setSz = (enc_rval.encoded + 7) / 8; - if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + if (LOG_DEBUGFLAG(DEBUG_ASN1)) xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg); - } - log_dump(NR_RRC, buffer, 16, LOG_DUMP_CHAR, "securityModeComplete payload: "); - LOG_D(NR_RRC, "securityModeComplete Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded + 7) / 8); ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_UL_DCCH_Message, &ul_dcch_msg); - for (int i = 0; i < (enc_rval.encoded + 7) / 8; i++) { + log_dump(NR_RRC, buffer, 16, LOG_DUMP_CHAR, "securityModeComplete payload: "); + + for (int i = 0; i < *setSz; i++) { LOG_T(NR_RRC, "%02x.", buffer[i]); } LOG_T(NR_RRC, "\n"); - - ue_rrc->as_security_activated = true; - srb_id = 1; // SecurityModeComplete in SRB1 - nr_pdcp_data_req_srb(ue_rrc->ue_id, srb_id, 0, (enc_rval.encoded + 7) / 8, buffer, deliver_pdu_srb_rlc, NULL); - - /* after encoding SecurityModeComplete we activate both ciphering and integrity */ - security_mode = ue_rrc->cipheringAlgorithm | (ue_rrc->integrityProtAlgorithm << 4); - // configure lower layers to apply SRB integrity protection and ciphering - for (int i = 1; i < NR_NUM_SRB; i++) { - if (ue_rrc->Srb[i] == RB_ESTABLISHED) - /* pass NULL to keep current keys */ - nr_pdcp_config_set_security(ue_rrc->ue_id, i, security_mode, NULL, NULL, NULL); - } } static void handle_meas_reporting_remove(rrcPerNB_t *rrc, int id, NR_UE_Timers_Constants_t *timers) @@ -1452,7 +1435,8 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, ue_rrc->cipheringAlgorithm, ue_rrc->integrityProtAlgorithm, kRRCenc, - kRRCint); + kRRCint, + true); } else { AssertFatal(srb->discardOnPDCP == NULL, "discardOnPDCP not yet implemented\n"); @@ -1510,7 +1494,8 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, ue_rrc->cipheringAlgorithm, ue_rrc->integrityProtAlgorithm, kUPenc, - kUPint); + kUPint, + true); } } } // drb_ToAddModList // @@ -1519,23 +1504,28 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, LOG_I(NR_RRC, "State = NR_RRC_CONNECTED\n"); } -static void nr_rrc_ue_generate_RRCReconfigurationComplete(NR_UE_RRC_INST_t *rrc, const int srb_id, const uint8_t Transaction_id) +static void nr_rrc_ue_generate_RRCReconfigurationComplete(NR_UE_RRC_INST_t *rrc, + const int srb_id, + const uint8_t Transaction_id, + RrcDcchDataResp *returned) { - uint8_t buffer[32]; - int size = do_NR_RRCReconfigurationComplete(buffer, sizeof(buffer), Transaction_id); - LOG_I(NR_RRC, " Logical Channel UL-DCCH (SRB1), Generating RRCReconfigurationComplete (bytes %d)\n", size); + int maxSz, *setSz; + char *buffer = getRetBuf(returned, &maxSz, &setSz); + *setSz = do_NR_RRCReconfigurationComplete((uint8_t *)buffer, maxSz, Transaction_id); + LOG_I(NR_RRC, " Logical Channel UL-DCCH (SRB1), Generating RRCReconfigurationComplete (bytes %d)\n", *setSz); AssertFatal(srb_id == 1 || srb_id == 3, "Invalid SRB ID %d\n", srb_id); LOG_D(RLC, "PDCP_DATA_REQ/%d Bytes (RRCReconfigurationComplete) " "--->][PDCP][RB %02d]\n", - size, + *setSz, srb_id); - nr_pdcp_data_req_srb(rrc->ue_id, srb_id, 0, size, buffer, deliver_pdu_srb_rlc, NULL); + returned->srbID = srb_id; } static void nr_rrc_ue_process_rrcReestablishment(NR_UE_RRC_INST_t *rrc, const int gNB_index, - const NR_RRCReestablishment_t *rrcReestablishment) + const NR_RRCReestablishment_t *rrcReestablishment, + RrcDcchDataResp *returned) { // implementign procedues as described in 38.331 section 5.3.7.5 // stop timer T301 @@ -1580,17 +1570,21 @@ static void nr_rrc_ue_process_rrcReestablishment(NR_UE_RRC_INST_t *rrc, rrc->ra_trigger = RA_NOT_RUNNING; // submit the RRCReestablishmentComplete message to lower layers for transmission - nr_rrc_ue_generate_rrcReestablishmentComplete(rrc, rrcReestablishment); + nr_rrc_ue_generate_rrcReestablishmentComplete(rrc, rrcReestablishment, returned); } -static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc, - const srb_id_t Srb_id, - const uint8_t *const Buffer, - size_t Buffer_size, - const uint8_t gNB_indexP, - const nr_pdcp_integrity_data_t *msg_integrity) +static MessageDef *nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc, + const srb_id_t Srb_id, + const uint8_t *const Buffer, + size_t Buffer_size, + const uint8_t gNB_indexP, + const nr_pdcp_integrity_data_t *msg_integrity, + const bool integrity_pass) { NR_DL_DCCH_Message_t *dl_dcch_msg = NULL; + MessageDef *returnMsg = itti_alloc_new_message(TASK_PDCP_UE, 0, NR_RRC_DCCH_DATA_RESP); + RrcDcchDataResp *returned = &returnMsg->ittiMsg.nr_rrc_dcch_data_resp; + *returned = (RrcDcchDataResp){.doCyphering = false}; if (Srb_id != 1 && Srb_id != 2) { LOG_E(NR_RRC, "Received message on DL-DCCH (SRB%ld), should not have ...\n", Srb_id); } @@ -1601,7 +1595,7 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc, if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { LOG_E(NR_RRC, "Failed to decode DL-DCCH (%zu bytes)\n", dec_rval.consumed); ASN_STRUCT_FREE(asn_DEF_NR_DL_DCCH_Message, dl_dcch_msg); - return -1; + return returnMsg; } if (LOG_DEBUGFLAG(DEBUG_ASN1)) { @@ -1618,7 +1612,10 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc, case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration: { nr_rrc_ue_process_rrcReconfiguration(rrc, gNB_indexP, c1->choice.rrcReconfiguration); - nr_rrc_ue_generate_RRCReconfigurationComplete(rrc, Srb_id, c1->choice.rrcReconfiguration->rrc_TransactionIdentifier); + nr_rrc_ue_generate_RRCReconfigurationComplete(rrc, + Srb_id, + c1->choice.rrcReconfiguration->rrc_TransactionIdentifier, + returned); } break; case NR_DL_DCCH_MessageType__c1_PR_rrcResume: @@ -1634,12 +1631,12 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc, case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry: LOG_I(NR_RRC, "Received Capability Enquiry (gNB %d)\n", gNB_indexP); - nr_rrc_ue_process_ueCapabilityEnquiry(rrc, c1->choice.ueCapabilityEnquiry); + nr_rrc_ue_process_ueCapabilityEnquiry(rrc, c1->choice.ueCapabilityEnquiry, returned); break; case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment: LOG_I(NR_RRC, "Logical Channel DL-DCCH (SRB1), Received RRCReestablishment\n"); - nr_rrc_ue_process_rrcReestablishment(rrc, gNB_indexP, c1->choice.rrcReestablishment); + nr_rrc_ue_process_rrcReestablishment(rrc, gNB_indexP, c1->choice.rrcReestablishment, returned); break; case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer: { @@ -1672,8 +1669,14 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc, break; case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand: LOG_I(NR_RRC, "Received securityModeCommand (gNB %d)\n", gNB_indexP); - nr_rrc_ue_process_securityModeCommand(rrc, c1->choice.securityModeCommand, - Srb_id, Buffer, Buffer_size, msg_integrity); + nr_rrc_ue_process_securityModeCommand(rrc, + c1->choice.securityModeCommand, + Srb_id, + Buffer, + Buffer_size, + msg_integrity, + integrity_pass, + returned); break; } } break; @@ -1682,7 +1685,7 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc, } // release memory allocation SEQUENCE_free(&asn_DEF_NR_DL_DCCH_Message, (void *)dl_dcch_msg, 1); - return 0; + return returnMsg; } void nr_rrc_handle_ra_indication(NR_UE_RRC_INST_t *rrc, bool ra_succeeded) @@ -1773,14 +1776,17 @@ void *rrc_nrue(void *notUsed) nr_rrc_ue_decode_ccch(rrc, ind); } break; - case NR_RRC_DCCH_DATA_IND: - nr_rrc_ue_decode_dcch(rrc, - NR_RRC_DCCH_DATA_IND(msg_p).dcch_index, - NR_RRC_DCCH_DATA_IND(msg_p).sdu_p, - NR_RRC_DCCH_DATA_IND(msg_p).sdu_size, - NR_RRC_DCCH_DATA_IND(msg_p).gNB_index, - &NR_RRC_DCCH_DATA_IND(msg_p).msg_integrity); - break; + case NR_RRC_DCCH_DATA_IND: { + NRRrcDcchDataInd *tmp = &NR_RRC_DCCH_DATA_IND(msg_p); + MessageDef *msg = nr_rrc_ue_decode_dcch(rrc, + tmp->dcch_index, + tmp->sdu_p, + tmp->sdu_size, + tmp->gNB_index, + &tmp->msg_integrity, + tmp->integrityResult); + itti_send_msg_to_task(TASK_PDCP_UE, rrc->ue_id, msg); + } break; case NAS_KENB_REFRESH_REQ: memcpy(rrc->kgnb, NAS_KENB_REFRESH_REQ(msg_p).kenb, sizeof(rrc->kgnb)); @@ -1838,7 +1844,9 @@ void nr_rrc_ue_process_sidelink_radioResourceConfig(NR_SetupRelease_SL_ConfigDed } } -static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECapabilityEnquiry_t *UECapabilityEnquiry) +static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, + NR_UECapabilityEnquiry_t *UECapabilityEnquiry, + RrcDcchDataResp *returned) { NR_UL_DCCH_Message_t ul_dcch_msg = {0}; // @@ -1890,17 +1898,19 @@ static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECa for (int i = 0; i < ueCapabilityEnquiry_ie->ue_CapabilityRAT_RequestList.list.count; i++) { if (ueCapabilityEnquiry_ie->ue_CapabilityRAT_RequestList.list.array[i]->rat_Type == NR_RAT_Type_nr) { asn1cSeqAdd(&UEcapList->list, &ue_CapabilityRAT_Container); - uint8_t buffer[500]; - asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, NULL, (void *)&ul_dcch_msg, buffer, 500); + int maxSz, *setSz; + char *buffer = getRetBuf(returned, &maxSz, &setSz); + + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, NULL, (void *)&ul_dcch_msg, buffer, maxSz); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", enc_rval.failed_type->name, enc_rval.encoded); if (LOG_DEBUGFLAG(DEBUG_ASN1)) { xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg); } - LOG_I(NR_RRC, "UECapabilityInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); - int srb_id = 1; // UECapabilityInformation on SRB1 - nr_pdcp_data_req_srb(rrc->ue_id, srb_id, 0, (enc_rval.encoded + 7) / 8, buffer, deliver_pdu_srb_rlc, NULL); + LOG_I(NR_RRC, "UECapabilityInformation Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded + 7) / 8); + returned->srbID = 1; // UECapabilityInformation on SRB1 + *setSz = (enc_rval.encoded + 7) / 8; } } } @@ -1945,14 +1955,15 @@ void nr_rrc_initiate_rrcReestablishment(NR_UE_RRC_INST_t *rrc, } static void nr_rrc_ue_generate_rrcReestablishmentComplete(const NR_UE_RRC_INST_t *rrc, - const NR_RRCReestablishment_t *rrcReestablishment) + const NR_RRCReestablishment_t *rrcReestablishment, + RrcDcchDataResp *returned) { - uint8_t buffer[RRC_BUFFER_SIZE] = {0}; - int size = do_RRCReestablishmentComplete(buffer, RRC_BUFFER_SIZE, - rrcReestablishment->rrc_TransactionIdentifier); - LOG_I(NR_RRC, "[RAPROC] Logical Channel UL-DCCH (SRB1), Generating RRCReestablishmentComplete (bytes %d)\n", size); - int srb_id = 1; // RRC re-establishment complete on SRB1 - nr_pdcp_data_req_srb(rrc->ue_id, srb_id, 0, size, buffer, deliver_pdu_srb_rlc, NULL); + int maxSz, *setSz; + char *buffer = getRetBuf(returned, &maxSz, &setSz); + + *setSz = do_RRCReestablishmentComplete((uint8_t *)buffer, maxSz, rrcReestablishment->rrc_TransactionIdentifier); + LOG_I(NR_RRC, "[RAPROC] Logical Channel UL-DCCH (SRB1), Generating RRCReestablishmentComplete (bytes %d)\n", *setSz); + returned->srbID = 1; // RRC re-establishment complete on SRB1 } void *recv_msgs_from_lte_ue(void *args_p) -- GitLab