From 53d741f20dbf619a93a678976dfa51fc217071a2 Mon Sep 17 00:00:00 2001 From: Bing-Kai Hong <Bing-Kai.Hong@eurecom.fr> Date: Thu, 20 Sep 2018 18:56:40 +0200 Subject: [PATCH] Generate the DCCH and send from pdcp --- openair2/F1AP/f1ap_cu_rrc_message_transfer.c | 14 +- openair2/F1AP/f1ap_du_rrc_message_transfer.c | 313 +++++----- openair2/F1AP/f1ap_du_task.c | 5 +- openair2/F1AP/f1ap_handlers.c | 2 +- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 111 ++-- .../LAYER2/RLC/AM_v9.3.0/#rlc_am_receiver.c# | 534 ++++++++++++++++++ openair2/LAYER2/RLC/rlc_mac.c | 4 +- openair2/RRC/LTE/L2_interface_common.c | 6 + openair2/RRC/LTE/rrc_eNB.c | 6 +- openair2/RRC/LTE/rrc_eNB_S1AP.c | 1 - targets/COMMON/create_tasks.c | 4 + targets/RT/USER/lte-softmodem.c | 10 + 12 files changed, 824 insertions(+), 186 deletions(-) create mode 100644 openair2/LAYER2/RLC/AM_v9.3.0/#rlc_am_receiver.c# diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c index 1b30602cdf..5ddb6fb187 100644 --- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c @@ -264,7 +264,7 @@ int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t instance, //ie->value.choice.RAT_FrequencyPriorityInformation.choice.rAT_FrequencySelectionPriority = 123L; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); } - + /* encode */ if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { LOG_E(CU_F1AP, "Failed to encode F1 setup request\n"); @@ -365,15 +365,17 @@ int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t instance, */ protocol_ctxt_t ctxt; ctxt.module_id = instance; + ctxt.instance = instance; ctxt.rnti = f1ap_get_rnti_by_cu_id(&f1ap_cu_ue[instance],cu_ue_f1ap_id); ctxt.enb_flag = 1; mem_block_t *mb = get_free_mem_block(ie->value.choice.RRCContainer.size,__func__); memcpy((void*)mb->data,(void*)ie->value.choice.RRCContainer.buf,ie->value.choice.RRCContainer.size); + LOG_I(CU_F1AP, "Calling pdcp_data_ind for UE RNTI %x srb_id %lu with size %d (DCCH) \n", ctxt.rnti, srb_id, ie->value.choice.RRCContainer.size); pdcp_data_ind (&ctxt, - 1, - 0, - srb_id, - ie->value.choice.RRCContainer.size, - mb); + 1, // srb_flag + 0, // embms_flag + srb_id, + ie->value.choice.RRCContainer.size, + mb); return 0; } diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 63066a4b8d..12d599bc39 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -175,153 +175,208 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, // decode RRC Container and act on the message type AssertFatal(srb_id<3,"illegal srb_id\n"); + protocol_ctxt_t ctxt; + ctxt.rnti = f1ap_get_rnti_by_du_id(&f1ap_du_ue[instance],du_ue_f1ap_id); + ctxt.module_id = instance; + ctxt.instance = instance; + ctxt.enb_flag = 1; + if (srb_id == 0) { DL_CCCH_Message_t* dl_ccch_msg=NULL; asn_dec_rval_t dec_rval; dec_rval = uper_decode(NULL, - &asn_DEF_DL_CCCH_Message, - (void**)&dl_ccch_msg, - ie->value.choice.RRCContainer.buf, - rrc_dl_sdu_len,0,0); + &asn_DEF_DL_CCCH_Message, + (void**)&dl_ccch_msg, + ie->value.choice.RRCContainer.buf, + rrc_dl_sdu_len,0,0); switch (dl_ccch_msg->message.choice.c1.present) { - - case DL_CCCH_MessageType__c1_PR_NOTHING: - LOG_I(RRC, "Received PR_NOTHING on DL-CCCH-Message\n"); - break; - - case DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishment: - LOG_I(RRC, - "Logical Channel DL-CCCH (SRB0), Received RRCConnectionReestablishment\n"); - break; - - case DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishmentReject: - LOG_I(RRC, - "Logical Channel DL-CCCH (SRB0), Received RRCConnectionReestablishmentReject\n"); - break; - - case DL_CCCH_MessageType__c1_PR_rrcConnectionReject: - LOG_I(RRC, - "Logical Channel DL-CCCH (SRB0), Received RRCConnectionReject \n"); - break; - - case DL_CCCH_MessageType__c1_PR_rrcConnectionSetup: + + case DL_CCCH_MessageType__c1_PR_NOTHING: + LOG_I(RRC, "Received PR_NOTHING on DL-CCCH-Message\n"); + break; + + case DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishment: + LOG_I(RRC, + "Logical Channel DL-CCCH (SRB0), Received RRCConnectionReestablishment\n"); + break; + + case DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishmentReject: + LOG_I(RRC, + "Logical Channel DL-CCCH (SRB0), Received RRCConnectionReestablishmentReject\n"); + break; + + case DL_CCCH_MessageType__c1_PR_rrcConnectionReject: + LOG_I(RRC, + "Logical Channel DL-CCCH (SRB0), Received RRCConnectionReject \n"); + break; + + case DL_CCCH_MessageType__c1_PR_rrcConnectionSetup: { - LOG_I(RRC, - "Logical Channel DL-CCCH (SRB0), Received RRCConnectionSetup DU_ID %x/RNTI %x\n", - du_ue_f1ap_id, - f1ap_get_rnti_by_du_id(&f1ap_du_ue[instance],du_ue_f1ap_id)); - // Get configuration - - RRCConnectionSetup_t* rrcConnectionSetup = &dl_ccch_msg->message.choice.c1.choice.rrcConnectionSetup; - // eNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - AssertFatal(rrcConnectionSetup!=NULL,"rrcConnectionSetup is null\n"); - RadioResourceConfigDedicated_t* radioResourceConfigDedicated = &rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated; - - // get SRB logical channel information - SRB_ToAddModList_t *SRB_configList; - SRB_ToAddMod_t *SRB1_config; - LogicalChannelConfig_t *SRB1_logicalChannelConfig; //,*SRB2_logicalChannelConfig; - SRB_configList = radioResourceConfigDedicated->srb_ToAddModList; - - AssertFatal(SRB_configList!=NULL,"SRB_configList is null\n"); - 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]; - - if (SRB1_config->logicalChannelConfig) { - if (SRB1_config->logicalChannelConfig->present == - SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { - SRB1_logicalChannelConfig = &SRB1_config->logicalChannelConfig->choice.explicitValue; - } else { - SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; - } - } else { - SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; - } - - - } - } - - protocol_ctxt_t ctxt; - ctxt.rnti = f1ap_get_rnti_by_du_id(&f1ap_du_ue[instance],du_ue_f1ap_id); - ctxt.module_id = instance; - ctxt.enb_flag = 1; - rrc_rlc_config_asn1_req(&ctxt, - SRB_configList, - (DRB_ToAddModList_t*) NULL, - (DRB_ToReleaseList_t*) NULL + LOG_I(RRC, + "Logical Channel DL-CCCH (SRB0), Received RRCConnectionSetup DU_ID %x/RNTI %x\n", + du_ue_f1ap_id, + f1ap_get_rnti_by_du_id(&f1ap_du_ue[instance],du_ue_f1ap_id)); + // Get configuration + + RRCConnectionSetup_t* rrcConnectionSetup = &dl_ccch_msg->message.choice.c1.choice.rrcConnectionSetup; + // eNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; + AssertFatal(rrcConnectionSetup!=NULL,"rrcConnectionSetup is null\n"); + RadioResourceConfigDedicated_t* radioResourceConfigDedicated = &rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated; + + // get SRB logical channel information + SRB_ToAddModList_t *SRB_configList; + SRB_ToAddMod_t *SRB1_config; + LogicalChannelConfig_t *SRB1_logicalChannelConfig; //,*SRB2_logicalChannelConfig; + SRB_configList = radioResourceConfigDedicated->srb_ToAddModList; + + AssertFatal(SRB_configList!=NULL,"SRB_configList is null\n"); + 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]; + + if (SRB1_config->logicalChannelConfig) { + if (SRB1_config->logicalChannelConfig->present == + SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { + SRB1_logicalChannelConfig = &SRB1_config->logicalChannelConfig->choice.explicitValue; + } else { + SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; + } + } else { + SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; + } + } + } // for + rrc_rlc_config_asn1_req(&ctxt, + SRB_configList, + (DRB_ToAddModList_t*) NULL, + (DRB_ToReleaseList_t*) NULL #if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , (PMCH_InfoList_r9_t *) NULL, - 0,0 + , (PMCH_InfoList_r9_t *) NULL, + 0,0 # endif - ); - - // This should be somewhere in the f1ap_cudu_ue_inst_t - int macrlc_instance = 0; - - rnti_t rnti = f1ap_get_rnti_by_du_id(&f1ap_du_ue[0],du_ue_f1ap_id); - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[macrlc_instance],rnti); - - eNB_RRC_UE_t *ue_p = &ue_context_p->ue_context; - AssertFatal(ue_p->Srb0.Active == 1,"SRB0 is not active\n"); - - memcpy((void*)ue_p->Srb0.Tx_buffer.Payload, - (void*)ie->value.choice.RRCContainer.buf, - rrc_dl_sdu_len); - - ue_p->Srb0.Tx_buffer.payload_size = rrc_dl_sdu_len; - - rrc_mac_config_req_eNB( - macrlc_instance, - 0, //primaryCC_id, - 0,0,0,0,0, + ); + + // This should be somewhere in the f1ap_cudu_ue_inst_t + int macrlc_instance = 0; + + rnti_t rnti = f1ap_get_rnti_by_du_id(&f1ap_du_ue[0],du_ue_f1ap_id); + struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[macrlc_instance],rnti); + + eNB_RRC_UE_t *ue_p = &ue_context_p->ue_context; + AssertFatal(ue_p->Srb0.Active == 1,"SRB0 is not active\n"); + + memcpy((void*)ue_p->Srb0.Tx_buffer.Payload, + (void*)ie->value.choice.RRCContainer.buf, + rrc_dl_sdu_len); + + ue_p->Srb0.Tx_buffer.payload_size = rrc_dl_sdu_len; + + rrc_mac_config_req_eNB( + macrlc_instance, + 0, //primaryCC_id, + 0,0,0,0,0, #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - 0, + 0, #endif - rnti, - (BCCH_BCH_Message_t *) NULL, - (RadioResourceConfigCommonSIB_t *) NULL, + rnti, + (BCCH_BCH_Message_t *) NULL, + (RadioResourceConfigCommonSIB_t *) NULL, #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (RadioResourceConfigCommonSIB_t *) NULL, + (RadioResourceConfigCommonSIB_t *) NULL, #endif - radioResourceConfigDedicated->physicalConfigDedicated, + radioResourceConfigDedicated->physicalConfigDedicated, #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (SCellToAddMod_r10_t *)NULL, - //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, + (SCellToAddMod_r10_t *)NULL, + //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif - (MeasObjectToAddMod_t **) NULL, - radioResourceConfigDedicated->mac_MainConfig, - 1, - SRB1_logicalChannelConfig, - NULL, // measGapConfig, - (TDD_Config_t *) NULL, - NULL, - (SchedulingInfoList_t *) NULL, - 0, NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL + (MeasObjectToAddMod_t **) NULL, + radioResourceConfigDedicated->mac_MainConfig, + 1, + SRB1_logicalChannelConfig, + NULL, // measGapConfig, + (TDD_Config_t *) NULL, + NULL, + (SchedulingInfoList_t *) NULL, + 0, NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL #if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , 0, (MBSFN_AreaInfoList_r9_t *) NULL, (PMCH_InfoList_r9_t *) NULL + , 0, (MBSFN_AreaInfoList_r9_t *) NULL, (PMCH_InfoList_r9_t *) NULL #endif #if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - , - (SystemInformationBlockType1_v1310_IEs_t *)NULL + , + (SystemInformationBlockType1_v1310_IEs_t *)NULL #endif - ); - break; - - default: - AssertFatal(1==0, - "Unknown message\n"); - break; - } - - } - } - else if (srb_id == 1){ + ); + break; + } // case - } - - else if (srb_id == 2){ + default: + AssertFatal(1==0, + "Unknown message\n"); + break; + }// switch case + } else if (srb_id == 1) { +// rrc_rlc_config_asn1_req(&ctxt, +// SRB_configList, +// (DRB_ToAddModList_t*) NULL, +// (DRB_ToReleaseList_t*) NULL +// #if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +// , (PMCH_InfoList_r9_t *) NULL, +// 0,0 +// # endif +// ); + + LOG_I(DU_F1AP, "Received DL RRC Transfer on srb_id 1\n"); + rlc_op_status_t rlc_status; + boolean_t ret = TRUE; + mem_block_t *pdcp_pdu_p = NULL; + pdcp_pdu_p = get_free_mem_block(rrc_dl_sdu_len, __func__); + memset(&pdcp_pdu_p->data[0], 0, rrc_dl_sdu_len); + memcpy(&pdcp_pdu_p->data[0], ie->value.choice.RRCContainer.buf, rrc_dl_sdu_len); + + if (pdcp_pdu_p != NULL) { + rlc_status = rlc_data_req(&ctxt + , 1 + , MBMS_FLAG_NO + , srb_id + , 0 + , 0 + , rrc_dl_sdu_len + , pdcp_pdu_p +#ifdef Rel14 + ,NULL + ,NULL +#endif + ); + switch (rlc_status) { + case RLC_OP_STATUS_OK: + LOG_D(PDCP, "Data sending request over RLC succeeded!\n"); + ret=TRUE; + break; + + case RLC_OP_STATUS_BAD_PARAMETER: + LOG_W(PDCP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n"); + ret= FALSE; + break; + + case RLC_OP_STATUS_INTERNAL_ERROR: + LOG_W(PDCP, "Data sending request over RLC failed with 'Internal Error' reason!\n"); + ret= FALSE; + break; + + case RLC_OP_STATUS_OUT_OF_RESSOURCES: + LOG_W(PDCP, "Data sending request over RLC failed with 'Out of Resources' reason!\n"); + ret= FALSE; + break; + + default: + LOG_W(PDCP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status); + ret= FALSE; + break; + } // switch case + return ret; + } // if pdcp_pdu_p + + } else if (srb_id == 2) { } #endif @@ -336,7 +391,6 @@ int DU_send_UL_RRC_MESSAGE_TRANSFER(const protocol_ctxt_t* const ctxt_pP, ) { - rnti_t rnti = ctxt_pP->rnti; F1AP_F1AP_PDU_t pdu; @@ -402,6 +456,7 @@ int DU_send_UL_RRC_MESSAGE_TRANSFER(const protocol_ctxt_t* const ctxt_pP, LOG_E(DU_F1AP, "Failed to encode F1 setup request\n"); return -1; } + LOG_W(DU_F1AP, "DU_send_UL_RRC_MESSAGE_TRANSFER on SRB %d for UE %x \n", rb_idP, rnti); du_f1ap_itti_send_sctp_data_req(instance, f1ap_du_data->assoc_id, buffer, len, f1ap_du_data->default_sctp_stream_id); return 0; diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index bcd14cfa36..64450a1ae7 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -175,8 +175,9 @@ void *F1AP_DU_task(void *arg) { case F1AP_UL_RRC_MESSAGE: // from rrc LOG_I(DU_F1AP, "DU Task Received F1AP_UL_RRC_MESSAGE\n"); - DU_send_UL_RRC_MESSAGE_TRANSFER(ITTI_MESSAGE_GET_INSTANCE(received_msg), - &F1AP_UL_RRC_MESSAGE(received_msg)); + AssertFatal (1 == 0, "Should not be here!\n" ); + //DU_send_UL_RRC_MESSAGE_TRANSFER(ITTI_MESSAGE_GET_INSTANCE(received_msg), + // &F1AP_UL_RRC_MESSAGE(received_msg)); break; case TERMINATE_MESSAGE: diff --git a/openair2/F1AP/f1ap_handlers.c b/openair2/F1AP/f1ap_handlers.c index 6d957e4ad6..b192cde0de 100644 --- a/openair2/F1AP/f1ap_handlers.c +++ b/openair2/F1AP/f1ap_handlers.c @@ -119,7 +119,7 @@ int f1ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, } /* Calling the right handler */ - LOG_I(DU_F1AP, "Calling handler with instance %d\n",instance); + LOG_I(F1AP, "Calling handler with instance %d\n",instance); ret = (*f1ap_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1]) (instance, assoc_id, stream, &pdu); ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_F1AP_F1AP_PDU, &pdu); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 3b4983a59d..bec37e1a29 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -49,9 +49,7 @@ #include "platform_constants.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "msc.h" - - - +#include "common/ngran_types.h" #if defined(ENABLE_SECURITY) # include "UTIL/OSA/osa_defs.h" @@ -411,53 +409,75 @@ boolean_t pdcp_data_req( free_mem_block(pdcp_pdu_p, __FUNCTION__); rlc_status = ack_result; } - - else + else // SRB #endif /*UETARGET*/ { - //It should never get here - rlc_status = rlc_data_req(ctxt_pP - , srb_flagP - , MBMS_FLAG_NO - , rb_idP - , muiP - , confirmP - , pdcp_pdu_size - , pdcp_pdu_p - #ifdef Rel14 - ,NULL - ,NULL - #endif - ); - } - - } + LOG_I(PDCP, "Sending F1AP_DL_RRC_MESSAGE with ITTI\n"); - switch (rlc_status) { - case RLC_OP_STATUS_OK: - LOG_D(PDCP, "Data sending request over RLC succeeded!\n"); - ret=TRUE; - break; + //It should never get here + if ((RC.rrc[ctxt_pP->module_id]->node_type == ngran_eNB_CU) || + (RC.rrc[ctxt_pP->module_id]->node_type == ngran_ng_eNB_CU)|| + (RC.rrc[ctxt_pP->module_id]->node_type == ngran_gNB_CU) ) { + // DL transfer + MessageDef *message_p; + // Note: the acyual task must be TASK_PDCP_ENB, but this task is not created + message_p = itti_alloc_new_message (TASK_PDCP_ENB, F1AP_DL_RRC_MESSAGE); + F1AP_DL_RRC_MESSAGE (message_p).rrc_container = &pdcp_pdu_p->data[0] ; + F1AP_DL_RRC_MESSAGE (message_p).rrc_container_length = pdcp_pdu_size; + F1AP_DL_RRC_MESSAGE (message_p).gNB_CU_ue_id = 0; + F1AP_DL_RRC_MESSAGE (message_p).gNB_DU_ue_id = 0; + F1AP_DL_RRC_MESSAGE (message_p).old_gNB_DU_ue_id = 0xFFFFFFFF; // unknown + F1AP_DL_RRC_MESSAGE (message_p).rnti = ctxt_pP->rnti; + F1AP_DL_RRC_MESSAGE (message_p).srb_id = rb_idP; + F1AP_DL_RRC_MESSAGE (message_p).execute_duplication = 1; + F1AP_DL_RRC_MESSAGE (message_p).RAT_frequency_priority_information.en_dc = 0; + itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_p); + //CU_send_DL_RRC_MESSAGE_TRANSFER(ctxt_pP->module_id, message_p); + LOG_I(PDCP, "Send F1AP_DL_RRC_MESSAGE with ITTI\n"); + ret=TRUE; + + } else{ + rlc_status = rlc_data_req(ctxt_pP + , srb_flagP + , MBMS_FLAG_NO + , rb_idP + , muiP + , confirmP + , pdcp_pdu_size + , pdcp_pdu_p +#ifdef Rel14 + ,NULL + ,NULL +#endif + ); + switch (rlc_status) { + case RLC_OP_STATUS_OK: + LOG_D(PDCP, "Data sending request over RLC succeeded!\n"); + ret=TRUE; + break; - case RLC_OP_STATUS_BAD_PARAMETER: - LOG_W(PDCP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n"); - ret= FALSE; - break; + case RLC_OP_STATUS_BAD_PARAMETER: + LOG_W(PDCP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n"); + ret= FALSE; + break; - case RLC_OP_STATUS_INTERNAL_ERROR: - LOG_W(PDCP, "Data sending request over RLC failed with 'Internal Error' reason!\n"); - ret= FALSE; - break; + case RLC_OP_STATUS_INTERNAL_ERROR: + LOG_W(PDCP, "Data sending request over RLC failed with 'Internal Error' reason!\n"); + ret= FALSE; + break; - case RLC_OP_STATUS_OUT_OF_RESSOURCES: - LOG_W(PDCP, "Data sending request over RLC failed with 'Out of Resources' reason!\n"); - ret= FALSE; - break; + case RLC_OP_STATUS_OUT_OF_RESSOURCES: + LOG_W(PDCP, "Data sending request over RLC failed with 'Out of Resources' reason!\n"); + ret= FALSE; + break; - default: - LOG_W(PDCP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status); - ret= FALSE; - break; + default: + LOG_W(PDCP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status); + ret= FALSE; + break; + } // switch case + } + } } if (ctxt_pP->enb_flag == ENB_FLAG_YES) { @@ -978,6 +998,8 @@ void pdcp_update_stats(const protocol_ctxt_t* const ctxt_pP){ } } + + //----------------------------------------------------------------------------- void pdcp_run ( @@ -1020,6 +1042,7 @@ pdcp_run ( RRC_DCCH_DATA_REQ (msg_p).frame, 0, RRC_DCCH_DATA_REQ (msg_p).eNB_index); + LOG_I(PDCP, PROTOCOL_CTXT_FMT"Received %s from %s: instance %d, rb_id %d, muiP %d, confirmP %d, mode %d\n", PROTOCOL_CTXT_ARGS(&ctxt), ITTI_MSG_NAME (msg_p), @@ -1030,6 +1053,8 @@ pdcp_run ( RRC_DCCH_DATA_REQ (msg_p).confirmp, RRC_DCCH_DATA_REQ (msg_p).mode); + log_dump(PDCP, RRC_DCCH_DATA_REQ (msg_p).sdu_p, RRC_DCCH_DATA_REQ (msg_p).sdu_size, LOG_DUMP_CHAR,"[MSG] pdcp run\n"); + result = pdcp_data_req (&ctxt, SRB_FLAG_YES, RRC_DCCH_DATA_REQ (msg_p).rb_id, diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/#rlc_am_receiver.c# b/openair2/LAYER2/RLC/AM_v9.3.0/#rlc_am_receiver.c# new file mode 100644 index 0000000000..e6a7929024 --- /dev/null +++ b/openair2/LAYER2/RLC/AM_v9.3.0/#rlc_am_receiver.c# @@ -0,0 +1,534 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#define RLC_AM_MODULE 1 +#define RLC_AM_RECEIVER_C 1 +#include "platform_types.h" +//----------------------------------------------------------------------------- +#include "assertions.h" +#include "msc.h" +#include "rlc.h" +#include "rlc_am.h" +#include "list.h" +#include "LAYER2/MAC/mac_extern.h" +#include "common/utils/LOG/log.h" + + +//----------------------------------------------------------------------------- +signed int +rlc_am_get_data_pdu_infos( + const protocol_ctxt_t* const ctxt_pP, + const rlc_am_entity_t* const rlc_pP, + rlc_am_pdu_sn_10_t* header_pP, + int16_t total_sizeP, + rlc_am_pdu_info_t* pdu_info_pP) +{ + memset(pdu_info_pP, 0, sizeof (rlc_am_pdu_info_t)); + + int16_t sum_li = 0; + pdu_info_pP->d_c = header_pP->b1 >> 7; + pdu_info_pP->num_li = 0; + +//Assertion(eNB)_PRAN_DesignDocument_annex No.766 + if(pdu_info_pP->d_c == 0) + { + LOG_E(RLC, "RLC AM Rx PDU Data D/C Header Error LcId=%d\n", rlc_pP->channel_id); + return -2; + } +/* + AssertFatal (pdu_info_pP->d_c != 0, "RLC AM Rx PDU Data D/C Header Error LcId=%d\n", rlc_pP->channel_id); +*/ + pdu_info_pP->rf = (header_pP->b1 >> 6) & 0x01; + pdu_info_pP->p = (header_pP->b1 >> 5) & 0x01; + pdu_info_pP->fi = (header_pP->b1 >> 3) & 0x03; + pdu_info_pP->e = (header_pP->b1 >> 2) & 0x01; + pdu_info_pP->sn = header_pP->b2 + (((uint16_t)(header_pP->b1 & 0x03)) << 8); + + pdu_info_pP->header_size = 2; + + if (pdu_info_pP->rf) { + pdu_info_pP->lsf = (header_pP->data[0] >> 7) & 0x01; + pdu_info_pP->so = header_pP->data[1] + (((uint16_t)(header_pP->data[0] & 0x7F)) << 8); + pdu_info_pP->payload = &header_pP->data[2]; + pdu_info_pP->header_size += 2; + } else { + pdu_info_pP->payload = &header_pP->data[0]; + } + + if (pdu_info_pP->e) { + rlc_am_e_li_t *e_li; + unsigned int li_length_in_bytes = 1; + unsigned int li_to_read = 1; + + if (pdu_info_pP->rf) { + e_li = (rlc_am_e_li_t*)(&header_pP->data[2]); + } else { + e_li = (rlc_am_e_li_t*)(header_pP->data); + } + + while (li_to_read) { + li_length_in_bytes = li_length_in_bytes ^ 3; + + if (li_length_in_bytes == 2) { + pdu_info_pP->li_list[pdu_info_pP->num_li] = ((uint16_t)(e_li->b1 << 4)) & 0x07F0; + pdu_info_pP->li_list[pdu_info_pP->num_li] |= (((uint8_t)(e_li->b2 >> 4)) & 0x000F); + li_to_read = e_li->b1 & 0x80; + pdu_info_pP->header_size += 2; + } else { + pdu_info_pP->li_list[pdu_info_pP->num_li] = ((uint16_t)(e_li->b2 << 8)) & 0x0700; + pdu_info_pP->li_list[pdu_info_pP->num_li] |= e_li->b3; + li_to_read = e_li->b2 & 0x08; + e_li++; + pdu_info_pP->header_size += 1; + } + + sum_li += pdu_info_pP->li_list[pdu_info_pP->num_li]; + pdu_info_pP->num_li = pdu_info_pP->num_li + 1; + + if (pdu_info_pP->num_li > RLC_AM_MAX_SDU_IN_PDU) { + LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[GET PDU INFO] SN %04d TOO MANY LIs ", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + pdu_info_pP->sn); + return -2; + } + } + + if (li_length_in_bytes == 2) { + pdu_info_pP->payload = &e_li->b3; + } else { + pdu_info_pP->payload = &e_li->b1; + } + } + + pdu_info_pP->payload_size = total_sizeP - pdu_info_pP->header_size; + + if (pdu_info_pP->payload_size > sum_li) { + pdu_info_pP->hidden_size = pdu_info_pP->payload_size - sum_li; + } + + return 0; +} +//----------------------------------------------------------------------------- +void +rlc_am_display_data_pdu_infos( + const protocol_ctxt_t* const ctxt_pP, + rlc_am_entity_t * const rlc_pP, + rlc_am_pdu_info_t* pdu_info_pP) +{ + int num_li; + + if (pdu_info_pP->d_c) { + if (pdu_info_pP->rf) { + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[DISPLAY DATA PDU] RX DATA PDU SN %04d FI %1d SO %05d LSF %01d POLL %1d ", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + pdu_info_pP->sn, + pdu_info_pP->fi, + pdu_info_pP->so, + pdu_info_pP->lsf, pdu_info_pP->p); + } else { + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[DISPLAY DATA PDU] RX DATA PDU SN %04d FI %1d POLL %1d ", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + pdu_info_pP->sn, + pdu_info_pP->fi, + pdu_info_pP->p); + } + + for (num_li = 0; num_li < pdu_info_pP->num_li; num_li++) { + LOG_D(RLC, "LI %05d ", pdu_info_pP->li_list[num_li]); + } + + if (pdu_info_pP->hidden_size > 0) { + LOG_D(RLC, "hidden size %05d ", pdu_info_pP->hidden_size); + } + + LOG_D(RLC, "\n"); + } else { + LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[DISPLAY DATA PDU] ERROR RX CONTROL PDU\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); + } +} +// assumed the sn of the tb_p is equal to VR(MS) +//----------------------------------------------------------------------------- +void +rlc_am_rx_update_vr_ms( + const protocol_ctxt_t* const ctxt_pP, + rlc_am_entity_t * const rlc_pP, + mem_block_t* tb_pP) +{ + //rlc_am_pdu_info_t* pdu_info_p = &((rlc_am_rx_pdu_management_t*)(tb_pP->data))->pdu_info; + rlc_am_pdu_info_t* pdu_info_cursor_p = NULL; + mem_block_t* cursor_p; + + cursor_p = tb_pP; + + if (cursor_p) { + do { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + + if ((((rlc_am_rx_pdu_management_t*)(cursor_p->data))->all_segments_received == 0) || + (rlc_pP->vr_ms != pdu_info_cursor_p->sn)) { + +#if TRACE_RLC_AM_RX + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[UPDATE VR(MS)] UPDATED VR(MS) %04d -> %04d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + rlc_pP->vr_ms, pdu_info_cursor_p->sn); +#endif + + return; + } + + rlc_pP->vr_ms = RLC_AM_NEXT_SN(pdu_info_cursor_p->sn); + cursor_p = cursor_p->next; + } while ((cursor_p != NULL) && (rlc_pP->vr_ms != rlc_pP->vr_h)); + + } +} +// assumed the sn of the tb_p is equal to VR(R) +//----------------------------------------------------------------------------- +void +rlc_am_rx_update_vr_r( + const protocol_ctxt_t* const ctxt_pP, + rlc_am_entity_t * const rlc_pP, + mem_block_t* tb_pP) +{ + rlc_am_pdu_info_t* pdu_info_cursor_p = NULL; + mem_block_t* cursor_p; + + cursor_p = tb_pP; + + if (cursor_p) { + do { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + + if ((((rlc_am_rx_pdu_management_t*)(cursor_p->data))->all_segments_received == 0) || + (rlc_pP->vr_r != pdu_info_cursor_p->sn)) { + return; + } + +#if TRACE_RLC_AM_RX + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[UPDATE VR(R)] UPDATED VR(R) %04d -> %04d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + rlc_pP->vr_r, + (pdu_info_cursor_p->sn + 1) & RLC_AM_SN_MASK); +#endif + + if (((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info.rf == 1) { + if (((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info.lsf == 1) { + rlc_pP->vr_r = (rlc_pP->vr_r + 1) & RLC_AM_SN_MASK; + } + } else { + rlc_pP->vr_r = (rlc_pP->vr_r + 1) & RLC_AM_SN_MASK; + } + + cursor_p = cursor_p->next; + } while (cursor_p != NULL); + + //rlc_pP->vr_r = (pdu_info_cursor_p->sn + 1) & RLC_AM_SN_MASK; + } +} +//----------------------------------------------------------------------------- +void +rlc_am_receive_routing ( + const protocol_ctxt_t* const ctxt_pP, + rlc_am_entity_t * const rlc_pP, + struct mac_data_ind data_indP) +{ + mem_block_t *tb_p = NULL; + uint8_t *first_byte_p = NULL; + sdu_size_t tb_size_in_bytes; + RLC_AM_MUTEX_LOCK(&rlc_pP->lock_input_sdus, ctxt_pP, rlc_pP); + + while ((tb_p = list_remove_head (&data_indP.data))) { + first_byte_p = ((struct mac_tb_ind *) (tb_p->data))->data_ptr; + tb_size_in_bytes = ((struct mac_tb_ind *) (tb_p->data))->size; + + if (tb_size_in_bytes > 0) { + if ((*first_byte_p & 0x80) == 0x80) { + rlc_pP->stat_rx_data_bytes += tb_size_in_bytes; + rlc_pP->stat_rx_data_pdu += 1; + rlc_am_receive_process_data_pdu (ctxt_pP, rlc_pP, tb_p, first_byte_p, tb_size_in_bytes); + } else { + rlc_pP->stat_rx_control_bytes += tb_size_in_bytes; + rlc_pP->stat_rx_control_pdu += 1; + rlc_am_receive_process_control_pdu (ctxt_pP, rlc_pP, tb_p, &first_byte_p, &tb_size_in_bytes); + // Test if remaining bytes not processed (up to know, highest probability is bug in MAC) +//Assertion(eNB)_PRAN_DesignDocument_annex No.767 + if(tb_size_in_bytes != 0) + { + LOG_E(RLC, "Remaining %d bytes following a control PDU\n", + tb_size_in_bytes); + } +/* + AssertFatal( tb_size_in_bytes == 0, + "Remaining %d bytes following a control PDU", + tb_size_in_bytes); +*/ + } + + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[RX ROUTING] VR(R)=%03d VR(MR)=%03d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + rlc_pP->vr_r, + rlc_pP->vr_mr); + } + } // end while + RLC_AM_MUTEX_UNLOCK(&rlc_pP->lock_input_sdus); +} +//----------------------------------------------------------------------------- +void +rlc_am_receive_process_data_pdu ( + const protocol_ctxt_t* const ctxt_pP, + rlc_am_entity_t * const rlc_pP, + mem_block_t* tb_pP, + uint8_t* first_byte_pP, + uint16_t tb_size_in_bytesP) +{ + // 5.1.3.2 Receive operations + // 5.1.3.2.1 General + // The receiving side of an AM RLC entity shall maintain a receiving window according to state variables VR(R) and + // VR(MR) as follows: + // - a SN falls within the receiving window if VR(R) <= SN < VR(MR); + // - a SN falls outside of the receiving window otherwise. + // + // When receiving a RLC data PDU from lower layer, the receiving side of an AM RLC entity shall: + // - either discard the received RLC data PDU or place it in the reception buffer (see sub clause 5.1.3.2.2); + // - if the received RLC data PDU was placed in the reception buffer: + // - update state variables, reassemble and deliver RLC SDUs to upper layer and start/stop t-Reordering as + // needed (see sub clause 5.1.3.2.3). + // When t-Reordering expires, the receiving side of an AM RLC entity shall: + // - update state variables and start t-Reordering as needed (see sub clause 5.1.3.2.4). + + + // 5.1.3.2.2 Actions when a RLC data PDU is received from lower layer + // When a RLC data PDU is received from lower layer, where the RLC data PDU contains byte segment numbers y to z of + // an AMD PDU with SN = x, the receiving side of an AM RLC entity shall: + // - if x falls outside of the receiving window; or + // - if byte segment numbers y to z of the AMD PDU with SN = x have been received before: + // - discard the received RLC data PDU; + // - else: + // - place the received RLC data PDU in the reception buffer; + // - if some byte segments of the AMD PDU contained in the RLC data PDU have been received before: + // - discard the duplicate byte segments. + rlc_am_pdu_info_t* pdu_info_p = &((rlc_am_rx_pdu_management_t*)(tb_pP->data))->pdu_info; + rlc_am_pdu_sn_10_t* rlc_am_pdu_sn_10_p = (rlc_am_pdu_sn_10_t*)first_byte_pP; + rlc_am_rx_pdu_status_t pdu_status = RLC_AM_DATA_PDU_STATUS_OK; + boolean_t reassemble = false; + + if (rlc_am_get_data_pdu_infos(ctxt_pP,rlc_pP, rlc_am_pdu_sn_10_p, tb_size_in_bytesP, pdu_info_p) >= 0) { + + ((rlc_am_rx_pdu_management_t*)(tb_pP->data))->all_segments_received = 0; + + if (RLC_AM_SN_IN_WINDOW(pdu_info_p->sn, rlc_pP->vr_r)) { + + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SN=%04d] VR(R) %04d VR(H) %04d VR(MR) %04d VR(MS) %04d VR(X) %04d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + pdu_info_p->sn, + rlc_pP->vr_r, + rlc_pP->vr_h, + rlc_pP->vr_mr, + rlc_pP->vr_ms, + rlc_pP->vr_x); + + pdu_status = rlc_am_rx_list_check_duplicate_insert_pdu(ctxt_pP, rlc_pP,tb_pP); + if (pdu_status != RLC_AM_DATA_PDU_STATUS_OK) { + rlc_pP->stat_rx_data_pdu_dropped += 1; + rlc_pP->stat_rx_data_bytes_dropped += tb_size_in_bytesP; + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] PDU DISCARDED CAUSE=%d SN=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_status,pdu_info_p->sn); +#if RLC_STOP_ON_LOST_PDU + AssertFatal( 0 == 1, + PROTOCOL_RLC_AM_CTXT_FMT" LOST PDU DETECTED\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); +#endif + } else { + // 5.1.3.2.3 + // Actions when a RLC data PDU is placed in the reception buffer + // + // When a RLC data PDU with SN = x is placed in the reception buffer, the receiving side of an AM RLC entity shall: + // - if x >= VR(H) + // - update VR(H) to x+ 1; + // + // - if all byte segments of the AMD PDU with SN = VR(MS) are received: + // - update VR(MS) to the SN of the first AMD PDU with SN > current VR(MS) for which not all byte segments + // have been received; + // + // - if x = VR(R): + // - if all byte segments of the AMD PDU with SN = VR(R) are received: + // - update VR(R) to the SN of the first AMD PDU with SN > current VR(R) for which not all byte segments + // have been received; + // - update VR(MR) to the updated VR(R) + AM_Window_Size; + // + // - reassemble RLC SDUs from any byte segments of AMD PDUs with SN that falls outside of the receiving + // window and in-sequence byte segments of the AMD PDU with SN = VR(R), remove RLC headers when + // doing so and deliver the reassembled RLC SDUs to upper layer in sequence if not delivered before; + // + // - if t-Reordering is running: + // - if VR(X) = VR(R); or + // - if VR(X) falls outside of the receiving window and VR(X) is not equal to VR(MR): + // - stop and reset t-Reordering; + // + // - if t-Reordering is not running (includes the case t-Reordering is stopped due to actions above): + // - if VR (H) > VR(R): + // - start t-Reordering; + // - set VR(X) to VR(H). + + +#if TRACE_RLC_AM_RX + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] RX LIST AFTER INSERTION:\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); + rlc_am_rx_list_display(rlc_pP, "rlc_am_receive_process_data_pdu AFTER INSERTION "); +#endif + + /* 1) Update vrH if sn >= vrH */ + if (RLC_AM_DIFF_SN(pdu_info_p->sn,rlc_pP->vr_r) >= RLC_AM_DIFF_SN(rlc_pP->vr_h,rlc_pP->vr_r)) + { + rlc_pP->vr_h = RLC_AM_NEXT_SN(pdu_info_p->sn); + } + + rlc_am_rx_check_all_byte_segments(ctxt_pP, rlc_pP, tb_pP); + + /* 2) Reordering Window Processing: Update vr_ms if sn = vr_ms and all bytes received for sn */ + if ((pdu_info_p->sn == rlc_pP->vr_ms) && (((rlc_am_rx_pdu_management_t*)(tb_pP->data))->all_segments_received)) { + rlc_am_rx_update_vr_ms(ctxt_pP, rlc_pP, tb_pP); + } + + if (pdu_info_p->sn == rlc_pP->vr_r) { +mem_block_t* cursor_p = rlc_pP->receiver_buffer.head; +rlc_am_rx_pdu_management_t * pdu_cursor_mgnt_p = (rlc_am_rx_pdu_management_t *) (cursor_p->data); +if( (((rlc_am_rx_pdu_management_t*)(tb_pP->data))->all_segments_received) == (pdu_cursor_mgnt_p->all_segments_received)){ + if (((rlc_am_rx_pdu_management_t*)(tb_pP->data))->all_segments_received) { + rlc_am_rx_update_vr_r(ctxt_pP, rlc_pP, tb_pP); + rlc_pP->vr_mr = (rlc_pP->vr_r + RLC_AM_WINDOW_SIZE) & RLC_AM_SN_MASK; + } + reassemble = rlc_am_rx_check_vr_reassemble(ctxt_pP, rlc_pP); + //TODO : optimization : check whether a reassembly is needed by looking at LI, FI, SO, etc... +}else{ + LOG_E(RLC, "BAD all_segments_received!!! discard buffer!!!\n"); + /* Discard received block if out of window, duplicate or header error */ + free_mem_block (tb_pP, __func__); +} + } + + //FNA: fix check VrX out of receiving window + if ((rlc_pP->t_reordering.running) || ((rlc_pP->t_reordering.ms_duration == 0) && (rlc_pP->vr_x != RLC_SN_UNDEFINED))) { + if ((rlc_pP->vr_x == rlc_pP->vr_r) || (!(RLC_AM_SN_IN_WINDOW(rlc_pP->vr_x, rlc_pP->vr_r)) && (rlc_pP->vr_x != rlc_pP->vr_mr))) { + rlc_am_stop_and_reset_timer_reordering(ctxt_pP, rlc_pP); + rlc_pP->vr_x = RLC_SN_UNDEFINED; + } + } + + if (!(rlc_pP->t_reordering.running)) { + if (rlc_pP->vr_h != rlc_pP->vr_r) { // - if VR (H) > VR(R) translated to - if VR (H) != VR(R) + rlc_pP->vr_x = rlc_pP->vr_h; + if (rlc_pP->t_reordering.ms_duration != 0) { + rlc_am_start_timer_reordering(ctxt_pP, rlc_pP); + } + else { + /* specific case for no timer reordering configured */ + /* reordering window directly advances with vrH */ + rlc_pP->vr_ms = rlc_pP->vr_h; + + /* Trigger a Status and clear any existing Delay Flag */ + RLC_AM_SET_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_T_REORDERING); + RLC_AM_CLEAR_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_DELAYED); + rlc_pP->sn_status_triggered_delayed = RLC_SN_UNDEFINED; + } + } + } + } + + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SN=%04d] NEW VR(R) %04d VR(H) %04d VR(MS) %04d VR(MR) %04d VR(X) %04d reassemble=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + pdu_info_p->sn, + rlc_pP->vr_r, + rlc_pP->vr_h, + rlc_pP->vr_ms, + rlc_pP->vr_mr, + rlc_pP->vr_x, + reassemble); + } else { + rlc_pP->stat_rx_data_pdu_out_of_window += 1; + rlc_pP->stat_rx_data_bytes_out_of_window += tb_size_in_bytesP; + pdu_status = RLC_AM_DATA_PDU_STATUS_SN_OUTSIDE_WINDOW; + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] PDU OUT OF RX WINDOW, DISCARDED, SN=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_info_p->sn); + } + + /* 3) Check for triggering a Tx Status PDU if a poll is received or if a pending status was delayed */ + if ((pdu_info_p->p) && (pdu_status < RLC_AM_DATA_PDU_STATUS_BUFFER_FULL)) { + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] POLL BIT SET, STATUS REQUESTED:\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); + + /* Polling Info Saving for In and Out of Window PDU */ + /* avoid multi status trigger */ + if ((RLC_AM_GET_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_DELAYED)) || + !(RLC_AM_GET_STATUS(rlc_pP->status_requested,(RLC_AM_STATUS_TRIGGERED_POLL | RLC_AM_STATUS_TRIGGERED_T_REORDERING)))) + { + RLC_AM_SET_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_POLL); + + if ((pdu_status != RLC_AM_DATA_PDU_STATUS_OK) || ((pdu_status == RLC_AM_DATA_PDU_STATUS_OK) && + (!(RLC_AM_SN_IN_WINDOW(pdu_info_p->sn,rlc_pP->vr_r)) || + (RLC_AM_DIFF_SN(pdu_info_p->sn,rlc_pP->vr_r) < RLC_AM_DIFF_SN(rlc_pP->vr_ms,rlc_pP->vr_r))) + ) + ) + { + /* Conditions are met for sending a Status Report */ + /* Then clear Delay Flag and reset its corresponding sn */ + RLC_AM_CLEAR_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_DELAYED); + rlc_pP->sn_status_triggered_delayed = RLC_SN_UNDEFINED; + } + else if (rlc_pP->sn_status_triggered_delayed == RLC_SN_UNDEFINED) + { + /* Delay status trigger if pdustatus OK and sn>= vr_ms */ + /* Note: vr_r and vr_ms have been updated */ + RLC_AM_SET_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_DELAYED); + rlc_pP->sn_status_triggered_delayed = pdu_info_p->sn; + } + } + } + + /* ReEnable a previously delayed Status Trigger if PDU discarded or */ + /* sn no more in RxWindow due to RxWindow advance or sn < vr_ms */ + if ((RLC_AM_GET_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_DELAYED)) && + (pdu_status == RLC_AM_DATA_PDU_STATUS_OK) && + (!(RLC_AM_SN_IN_WINDOW(rlc_pP->sn_status_triggered_delayed,rlc_pP->vr_r)) || + (RLC_AM_DIFF_SN(rlc_pP->sn_status_triggered_delayed,rlc_pP->vr_r) < RLC_AM_DIFF_SN(rlc_pP->vr_ms,rlc_pP->vr_r))) + ) + { + RLC_AM_CLEAR_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_DELAYED); + rlc_pP->sn_status_triggered_delayed = RLC_SN_UNDEFINED; + } + + + } else { + pdu_status = RLC_AM_DATA_PDU_STATUS_HEADER_ERROR; + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] PDU DISCARDED BAD HEADER FORMAT SN=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_info_p->sn); + } + + if (pdu_status != RLC_AM_DATA_PDU_STATUS_OK) { + /* Discard received block if out of window, duplicate or header error */ + free_mem_block (tb_pP, __func__); + } + else if (reassemble) { + /* Reassemble SDUs */ + rlc_am_rx_list_reassemble_rlc_sdus(ctxt_pP, rlc_pP); + } +} diff --git a/openair2/LAYER2/RLC/rlc_mac.c b/openair2/LAYER2/RLC/rlc_mac.c index b3d8d36dc5..ac53afa40b 100644 --- a/openair2/LAYER2/RLC/rlc_mac.c +++ b/openair2/LAYER2/RLC/rlc_mac.c @@ -260,12 +260,12 @@ void mac_rlc_data_ind ( #ifdef DEBUG_MAC_INTERFACE if (num_tbP) { - LOG_I(RLC, PROTOCOL_CTXT_FMT" MAC_RLC_DATA_IND on channel %d (%d), rb max %d, Num_tb %d\n", + LOG_I(RLC, PROTOCOL_CTXT_FMT" MAC_RLC_DATA_IND on channel %d (%d), rb max %d, tb_sizeP %d\n", PROTOCOL_CTXT_ARGS(&ctxt), channel_idP, RLC_MAX_LC, NB_RB_MAX, - num_tbP); + tb_sizeP); } #endif // DEBUG_MAC_INTERFACE diff --git a/openair2/RRC/LTE/L2_interface_common.c b/openair2/RRC/LTE/L2_interface_common.c index b03b36a557..e8aece9f29 100644 --- a/openair2/RRC/LTE/L2_interface_common.c +++ b/openair2/RRC/LTE/L2_interface_common.c @@ -94,6 +94,8 @@ rrc_data_req( RRC_DCCH_DATA_REQ (message_p).confirmp = confirmP; RRC_DCCH_DATA_REQ (message_p).sdu_size = sdu_sizeP; RRC_DCCH_DATA_REQ (message_p).sdu_p = message_buffer; + //memcpy (RRC_DCCH_DATA_REQ (message_p).sdu_p, buffer_pP, sdu_sizeP); + RRC_DCCH_DATA_REQ (message_p).mode = modeP; RRC_DCCH_DATA_REQ (message_p).module_id = ctxt_pP->module_id; RRC_DCCH_DATA_REQ (message_p).rnti = ctxt_pP->rnti; @@ -103,6 +105,10 @@ rrc_data_req( ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, ctxt_pP->instance, message_p); + LOG_I(RRC,"sent RRC_DCCH_DATA_REQ to TASK_PDCP_ENB\n"); + // RS/BK: Fix ME + pdcp_run(ctxt_pP); + return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. } diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 4c54f75d29..0dbbd7d747 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -1167,8 +1167,10 @@ rrc_eNB_generate_SecurityModeCommand( rrc_eNB_mui, size); - if ((RC.rrc[ctxt_pP->module_id]->node_type == ngran_eNB) || - (RC.rrc[ctxt_pP->module_id]->node_type == ngran_ng_eNB)) { + if ((RC.rrc[ctxt_pP->module_id]->node_type != ngran_eNB_DU) || + (RC.rrc[ctxt_pP->module_id]->node_type != ngran_gNB_DU)) { + LOG_I(RRC,"calling rrc_data_req :securityModeCommand\n"); + rrc_data_req( ctxt_pP, DCCH, diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 15ea141301..1f5a8772d4 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -923,7 +923,6 @@ rrc_eNB_process_S1AP_DOWNLINK_NAS( S1AP_DOWNLINK_NAS (msg_p).nas_pdu.buffer); LOG_DUMPMSG(RRC,DEBUG_RRC,buffer,length,"[MSG] RRC DL Information Transfer\n"); - /* * switch UL or DL NAS message without RRC piggybacked to SRB2 if active. */ diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c index aea5a5ab99..793eb90740 100644 --- a/targets/COMMON/create_tasks.c +++ b/targets/COMMON/create_tasks.c @@ -85,6 +85,10 @@ int create_tasks(uint32_t enb_nb) if (enb_nb > 0) { rc = itti_create_task(TASK_CU_F1, F1AP_CU_task, NULL); AssertFatal(rc >= 0, "Create task for CU F1AP failed\n"); + //RS/BK: Fix me! + rc = itti_create_task (TASK_L2L1, l2l1_task, NULL); + AssertFatal(rc >= 0, "Create task for L2L1 failed\n"); + } /* fall through */ case ngran_eNB: diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 2145e5d98c..34ac829f5c 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1082,6 +1082,16 @@ int main( int argc, char **argv ) RCconfig_L1(); } + + if (RC.rrc[0]->node_type == ngran_eNB_CU || RC.rrc[0]->node_type == ngran_ng_eNB_CU) { + protocol_ctxt_t ctxt; + ctxt.module_id = 0 ; + ctxt.instance = 0; + ctxt.rnti = 0; + ctxt.enb_flag = 1; + pdcp_run(&ctxt); + } + /* start threads if only L1 or not a CU */ if (RC.nb_inst == 0 || !(RC.rrc[0]->node_type == ngran_eNB_CU || RC.rrc[0]->node_type == ngran_ng_eNB_CU)) { -- GitLab