Skip to content
Snippets Groups Projects
Commit 2f232889 authored by Thomas Laurent's avatar Thomas Laurent
Browse files

synchronous work between PDCP and RRC for DCCCH messages

parent 514537e6
No related tags found
No related merge requests found
......@@ -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 #
......
......@@ -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)
......@@ -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 {
......
......@@ -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;
......
......@@ -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,
......
......@@ -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,
......
......@@ -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
......
......@@ -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)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment