Commit e471d8b8 authored by Raymond Knopp's avatar Raymond Knopp

Merge remote-tracking branch 'origin/NR_RRC_PDCP' into NR_UL_scheduling

parents 2f654535 e0e0ed0c
......@@ -1745,8 +1745,14 @@ set(NR_RLC_SRC
${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_ue_manager.c
)
set(NR_PDCP_SRC
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c
)
set(L2_SRC
${OPENAIR2_DIR}/LAYER2/openair2_proc.c
${PDCP_DIR}/pdcp.c
${PDCP_DIR}/pdcp_fifo.c
${PDCP_DIR}/pdcp_sequence_manager.c
......@@ -1754,6 +1760,7 @@ set(L2_SRC
${PDCP_DIR}/pdcp_util.c
${PDCP_DIR}/pdcp_security.c
${PDCP_DIR}/pdcp_netlink.c
${OPENAIR2_DIR}/LAYER2/openair2_proc.c
# ${RRC_DIR}/rrc_UE.c
${RRC_DIR}/rrc_eNB.c
${RRC_DIR}/rrc_eNB_endc.c
......@@ -1766,12 +1773,27 @@ set(L2_SRC
${RRC_DIR}/L2_interface_ue.c
)
set(L2_RRC_SRC
${OPENAIR2_DIR}/LAYER2/openair2_proc.c
# ${RRC_DIR}/rrc_UE.c
${RRC_DIR}/rrc_eNB.c
${RRC_DIR}/rrc_eNB_endc.c
${RRC_DIR}/rrc_eNB_S1AP.c
${RRC_DIR}/rrc_eNB_M2AP.c
${RRC_DIR}/rrc_eNB_UE_context.c
${RRC_DIR}/rrc_common.c
${RRC_DIR}/L2_interface.c
${RRC_DIR}/L2_interface_common.c
${RRC_DIR}/L2_interface_ue.c
)
set(L2_LTE_SRC
${RLC_V2}
)
set(L2_NR_SRC
${NR_RLC_SRC}
${NR_PDCP_SRC}
${NR_RRC_DIR}/rrc_gNB.c
${NR_RRC_DIR}/nr_rrc_common.c
${NR_RRC_DIR}/L2_nr_interface.c
......@@ -1796,19 +1818,16 @@ set(L2_SRC_UE
${RRC_DIR}/L2_interface_ue.c
)
set(LTE_NR_L2_SRC_UE
${PDCP_DIR}/pdcp.c
${PDCP_DIR}/pdcp_fifo.c
${PDCP_DIR}/pdcp_sequence_manager.c
${PDCP_DIR}/pdcp_primitives.c
${PDCP_DIR}/pdcp_util.c
${PDCP_DIR}/pdcp_security.c
${PDCP_DIR}/pdcp_netlink.c
${RLC_V2}
set(L2_RRC_SRC_UE
${RRC_DIR}/rrc_UE.c
${RRC_DIR}/rrc_common.c
${RRC_DIR}/L2_interface_common.c
${RRC_DIR}/L2_interface_ue.c
)
set(NR_L2_SRC_UE
${NR_RLC_SRC}
${NR_PDCP_SRC}
${NR_UE_RRC_DIR}/L2_interface_ue.c
${NR_UE_RRC_DIR}/main_ue.c
${NR_UE_RRC_DIR}/rrc_UE.c
......@@ -1918,6 +1937,14 @@ add_library(L2_NR
${MAC_NR_SRC}
${GNB_APP_SRC}
)
add_library(L2_LTE_NR
${L2_RRC_SRC}
${MAC_SRC}
${ENB_APP_SRC}
${MCE_APP_SRC}
)
add_dependencies(L2_NR rrc_flag nr_rrc_flag s1ap_flag x2_flag)
add_library(L2_UE
......@@ -1925,6 +1952,11 @@ add_library(L2_UE
${MAC_SRC_UE}
)
add_library(L2_UE_LTE_NR
${L2_RRC_SRC_UE}
${MAC_SRC_UE}
)
if (NOT ${NOS1})
target_compile_definitions(L2_UE PUBLIC -DPDCP_USE_NETLINK)
endif()
......@@ -2745,7 +2777,7 @@ target_link_libraries (nr-softmodem
-Wl,--start-group
UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS NR_GTPV1U SECU_CN SECU_OSA
${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB
S1AP_LIB S1AP_ENB L2 L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${PROTO_AGENT_LIB} ${FSPT_MSG_LIB}
-Wl,--end-group z dl)
......@@ -2787,7 +2819,7 @@ add_executable(nr-uesoftmodem
target_link_libraries (nr-uesoftmodem
-Wl,--start-group
RRC_LIB NR_RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB
PHY_COMMON PHY_NR_COMMON PHY_UE PHY_NR_UE PHY_RU LFDS NR_L2_UE L2_UE MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB
PHY_COMMON PHY_NR_COMMON PHY_UE PHY_NR_UE PHY_RU LFDS NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB
NFAPI_USER_LIB S1AP_LIB S1AP_ENB
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES}
-Wl,--end-group z dl)
......
......@@ -364,8 +364,6 @@ static void UE_synch(void *arg) {
}
void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
fapi_nr_config_request_t *cfg = &UE->nrUE_config;
int tx_slot_type = nr_ue_slot_select(cfg, proc->frame_tx, proc->nr_tti_tx);
uint8_t gNB_id = 0;
......
......@@ -585,7 +585,7 @@ void init_pdcp(void) {
LOG_I(RLC, "Problem at RLC initiation \n");
}
pdcp_layer_init();
nr_ip_over_LTE_DRB_preconfiguration();*/
nr_DRB_preconfiguration();*/
pdcp_module_init(pdcp_initmask);
pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req);
pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind);
......
......@@ -711,8 +711,8 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
}
#ifdef DEBUG_ULSCH_DECODING
LOG_I(PHY, "Decoder output (payload): \n");
for (i = 0; i < harq_process->TBS ; i++) {
LOG_I(PHY, "Decoder output (payload, TBS: %d): \n", harq_process->TBS);
for (i = 0; i < harq_process->TBS; i++) {
//harq_process_ul_ue->a[i] = (unsigned char) rand();
//printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
printf("%02x",harq_process->b[i]);
......
......@@ -123,7 +123,7 @@ int generate_dlsch_header(unsigned char *mac_header,
unsigned char *ue_cont_res_id,
unsigned char short_padding,
unsigned short post_padding){return 0;}
void nr_ip_over_LTE_DRB_preconfiguration(void){}
void nr_DRB_preconfiguration(void){}
// needed for some functions
openair0_config_t openair0_cfg[MAX_CARDS];
......
......@@ -76,7 +76,7 @@ boolean_t pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP,
const sdu_size_t sdu_buffer_sizeP,
mem_block_t *const sdu_buffer_pP) {return(false);}
void nr_ip_over_LTE_DRB_preconfiguration(void){}
void nr_DRB_preconfiguration(void){}
void pdcp_layer_init(void) {}
int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) {return 0;}
......
......@@ -97,7 +97,7 @@ boolean_t pdcp_data_ind(
) { return(false);}
void pdcp_run (const protocol_ctxt_t *const ctxt_pP) { return;}
void nr_ip_over_LTE_DRB_preconfiguration(void){}
void nr_DRB_preconfiguration(void){}
int rrc_init_nr_global_param(void){return(0);}
......
......@@ -39,6 +39,7 @@
#include "PHY/defs_UE.h"
#include "openair2/LAYER2/RLC/rlc.h"
#include "openair2/LAYER2/PDCP_v10.1.0/pdcp.h"
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h"
#include "executables/softmodem-common.h"
static NR_UE_MAC_INST_t *nr_ue_mac_inst;
......@@ -59,7 +60,7 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst)
LOG_I(RLC, "Problem at RLC initiation \n");
}
pdcp_layer_init();
nr_ip_over_LTE_DRB_preconfiguration();
nr_DRB_preconfiguration();
}
}
else LOG_I(MAC,"Running without RRC instance\n");
......
......@@ -261,6 +261,7 @@ int configure_fapi_dl_pdu(int Mod_idP,
uint16_t *rbStart) {
LOG_I(MAC, "Inside configure_fapi_dl_pdu() \n");
gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP];
NR_COMMON_channels_t *cc = nr_mac->common_channels;
......@@ -596,7 +597,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
LOG_D(MAC, "In nr_schedule_uss_dlsch_phytest frame %d slot %d\n",frameP,slotP);
int post_padding = 0, ta_len = 0, header_length_total = 0, sdu_length_total = 0, num_sdus = 0;
int lcid, offset, i, header_length_last, TBS_bytes;
int lcid, offset, i, header_length_last, TBS_bytes = 0;
int UE_id = 0, CC_id = 0;
gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP];
......@@ -631,18 +632,16 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
if (TBS_bytes == 0)
return;
//The --NOS1 use case currently schedules DLSCH transmissions only when there is IP traffic arriving
//through the LTE stack
if (IS_SOFTMODEM_NOS1){
lcid = DL_SCH_LCID_DTCH;
for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) {
//for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) {
// TODO: check if the lcid is active
LOG_D(MAC, "[gNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (TBS %d bytes, len %d)\n",
module_idP, frameP, lcid, TBS_bytes, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3);
if (TBS_bytes - ta_len - header_length_total - sdu_length_total - 3 > 0) {
//if (TBS_bytes - ta_len - header_length_total - sdu_length_total - 3 > 0) {
rlc_status = mac_rlc_status_ind(module_idP,
rnti,
module_idP,
......@@ -656,7 +655,9 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
if (rlc_status.bytes_in_buffer > 0) {
LOG_D(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d), TBS_bytes: %d \n \n",
LOG_I(MAC, "configure fapi due to data availability \n");
LOG_I(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d), TBS_bytes: %d \n \n",
module_idP, frameP, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3,
lcid, header_length_total, TBS_bytes);
......@@ -672,7 +673,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
0,
0);
LOG_D(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", module_idP, sdu_lengths[num_sdus], lcid);
LOG_W(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", module_idP, sdu_lengths[num_sdus], lcid);
sdu_lcids[num_sdus] = lcid;
sdu_length_total += sdu_lengths[num_sdus];
......@@ -683,17 +684,9 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
//ue_sched_ctl->uplane_inactivity_timer = 0;
}
} else { // no TBS_bytes left
break;
}
}
} //if (IS_SOFTMODEM_NOS1)
else {
//When the --NOS1 option is not enabled, DLSCH transmissions with random data
//occur every time that the current function is called (dlsch phytest mode)
LOG_D(MAC,"Configuring DL_TX in %d.%d\n", frameP, slotP);
// fill dlsch_buffer with random data
......@@ -718,7 +711,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
}
#endif
} // else IS_SOFTMODEM_NOS1
}
// there is at least one SDU or TA command
// if (num_sdus > 0 ){
......
......@@ -36,6 +36,7 @@
void nr_process_mac_pdu(
module_id_t module_idP,
rnti_t rnti,
uint8_t CC_id,
frame_t frameP,
uint8_t *pduP,
......@@ -219,10 +220,7 @@ void nr_process_mac_pdu(
LOG_T(MAC, "\n");
#endif
if (IS_SOFTMODEM_NOS1){
if (rx_lcid < NB_RB_MAX && rx_lcid >= UL_SCH_LCID_DTCH) {
if(IS_SOFTMODEM_NOS1){
mac_rlc_data_ind(module_idP,
0x1234,
module_idP,
......@@ -234,11 +232,22 @@ void nr_process_mac_pdu(
mac_sdu_len,
1,
NULL);
} else {
LOG_E(MAC, "[UE %d] Frame %d : unknown LCID %d (gNB %d)\n", module_idP, frameP, rx_lcid, module_idP);
}
else{
mac_rlc_data_ind(module_idP,
rnti,
module_idP,
frameP,
ENB_FLAG_YES,
MBMS_FLAG_NO,
rx_lcid,
(char *) (pdu_ptr + mac_subheader_len),
mac_sdu_len,
1,
NULL);
}
break;
default:
......@@ -306,7 +315,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
UE_scheduling_control->ta_update = timing_advance;
LOG_I(MAC, "[UE %d] PUSCH TPC %d and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update);
LOG_D(MAC, "Received PDU at MAC gNB \n");
nr_process_mac_pdu(gnb_mod_idP, CC_idP, frameP, sduP, sdu_lenP);
nr_process_mac_pdu(gnb_mod_idP, current_rnti, CC_idP, frameP, sduP, sdu_lenP);
}
}
else {
......
......@@ -301,6 +301,7 @@ void schedule_fapi_ul_pdu(int Mod_idP,
void nr_process_mac_pdu(
module_id_t module_idP,
rnti_t rnti,
uint8_t CC_id,
frame_t frameP,
uint8_t *pduP,
......
......@@ -35,6 +35,7 @@
#include "assertions.h"
#include "LAYER2/PDCP_v10.1.0/pdcp.h"
#include "LAYER2/nr_pdcp/nr_pdcp_entity.h"
#include "RRC/NR/nr_rrc_defs.h"
#include "common/utils/LOG/log.h"
//#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
......@@ -89,7 +90,7 @@ void mac_top_init_gNB(void)
pdcp_layer_init();
if(IS_SOFTMODEM_NOS1)
nr_ip_over_LTE_DRB_preconfiguration();
nr_DRB_preconfiguration();
rrc_init_nr_global_param();
......
......@@ -2353,101 +2353,6 @@ void pdcp_module_cleanup (void)
{
}
void nr_ip_over_LTE_DRB_preconfiguration(void){
// Addition for the use-case of 4G stack on top of 5G-NR.
// We need to configure pdcp and rlc instances without having an actual
// UE RRC Connection. In order to be able to test the NR PHY with some injected traffic
// on top of the LTE stack.
protocol_ctxt_t ctxt;
LTE_DRB_ToAddModList_t* DRB_configList=NULL;
DRB_configList = CALLOC(1, sizeof(LTE_DRB_ToAddModList_t));
struct LTE_LogicalChannelConfig *DRB_lchan_config = NULL;
struct LTE_RLC_Config *DRB_rlc_config = NULL;
struct LTE_PDCP_Config *DRB_pdcp_config = NULL;
struct LTE_PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL;
struct LTE_DRB_ToAddMod *DRB_config = NULL;
struct LTE_LogicalChannelConfig__ul_SpecificParameters *DRB_ul_SpecificParameters = NULL;
long *logicalchannelgroup_drb;
//Static preconfiguration of DRB
DRB_config = CALLOC(1, sizeof(*DRB_config));
DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long));
// allowed value 5..15, value : x+4
*(DRB_config->eps_BearerIdentity) = 1; //ue_context_pP->ue_context.e_rab[i].param.e_rab_id;//+ 4; // especial case generation
// DRB_config->drb_Identity = 1 + drb_identity_index + e_rab_done;// + i ;// (DRB_Identity_t) ue_context_pP->ue_context.e_rab[i].param.e_rab_id;
// 1 + drb_identiy_index;
DRB_config->drb_Identity = 1;
DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long));
*(DRB_config->logicalChannelIdentity) = DRB_config->drb_Identity + 3; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2
DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config));
DRB_config->rlc_Config = DRB_rlc_config;
DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config));
DRB_config->pdcp_Config = DRB_pdcp_config;
DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long));
*DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity;
DRB_pdcp_config->rlc_AM = NULL;
DRB_pdcp_config->rlc_UM = NULL;
DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional;
DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10;
DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10;
DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35;
// PDCP
PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM));
DRB_pdcp_config->rlc_UM = PDCP_rlc_UM;
PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits;
DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed;
DRB_lchan_config = CALLOC(1, sizeof(*DRB_lchan_config));
DRB_config->logicalChannelConfig = DRB_lchan_config;
DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters));
DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters;
DRB_ul_SpecificParameters->priority= 4;
DRB_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8;
//LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
DRB_ul_SpecificParameters->bucketSizeDuration =
LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
logicalchannelgroup_drb = CALLOC(1, sizeof(long));
*logicalchannelgroup_drb = 1;//(i+1) % 3;
DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb;
ASN_SEQUENCE_ADD(&DRB_configList->list,DRB_config);
if (ENB_NAS_USE_TUN){
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_YES, 0x1234, 0, 0,0);
}
else{
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0);
}
rrc_pdcp_config_asn1_req(&ctxt,
(LTE_SRB_ToAddModList_t *) NULL,
DRB_configList,
(LTE_DRB_ToReleaseList_t *) NULL,
0xff, NULL, NULL, NULL
, (LTE_PMCH_InfoList_r9_t *) NULL,
&DRB_config->drb_Identity);
rrc_rlc_config_asn1_req(&ctxt,
(LTE_SRB_ToAddModList_t*)NULL,
DRB_configList,
(LTE_DRB_ToReleaseList_t*)NULL
//#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
,(LTE_PMCH_InfoList_r9_t *)NULL
, 0, 0
//#endif
);
}
//-----------------------------------------------------------------------------
void pdcp_layer_init(void)
//-----------------------------------------------------------------------------
......
/*
* 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
*/
#include "nr_pdcp_entity.h"
#include "nr_pdcp_entity_drb_am.h"
#include "LOG/log.h"
nr_pdcp_entity_t *new_nr_pdcp_entity_srb(
int rb_id,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size),
void *deliver_sdu_data,
void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size, int sdu_id),
void *deliver_pdu_data)
{
abort();
}
nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
int rb_id,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size),
void *deliver_sdu_data,
void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size, int sdu_id),
void *deliver_pdu_data)
{
nr_pdcp_entity_drb_am_t *ret;
ret = calloc(1, sizeof(nr_pdcp_entity_drb_am_t));
if (ret == NULL) {
LOG_E(PDCP, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
ret->common.recv_pdu = nr_pdcp_entity_drb_am_recv_pdu;
ret->common.recv_sdu = nr_pdcp_entity_drb_am_recv_sdu;
ret->common.set_integrity_key = nr_pdcp_entity_drb_am_set_integrity_key;
ret->common.delete = nr_pdcp_entity_drb_am_delete;
ret->common.deliver_sdu = deliver_sdu;
ret->common.deliver_sdu_data = deliver_sdu_data;
ret->common.deliver_pdu = deliver_pdu;
ret->common.deliver_pdu_data = deliver_pdu_data;
ret->rb_id = rb_id;
ret->common.maximum_nr_pdcp_sn = 4095;
return (nr_pdcp_entity_t *)ret;
}
/*
* 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
*/
#ifndef _NR_PDCP_ENTITY_H_
#define _NR_PDCP_ENTITY_H_
typedef struct nr_pdcp_entity_t {
/* functions provided by the PDCP module */
void (*recv_pdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size);
void (*recv_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size,
int sdu_id);
void (*delete)(struct nr_pdcp_entity_t *entity);
void (*set_integrity_key)(struct nr_pdcp_entity_t *entity, char *key);
/* callbacks provided to the PDCP module */
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size);
void *deliver_sdu_data;
void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size, int sdu_id);
void *deliver_pdu_data;
int tx_hfn;
int next_nr_pdcp_tx_sn;
int maximum_nr_pdcp_sn;
} nr_pdcp_entity_t;
nr_pdcp_entity_t *new_nr_pdcp_entity_srb(
int rb_id,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size),
void *deliver_sdu_data,
void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size, int sdu_id),
void *deliver_pdu_data);
nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
int rb_id,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size),
void *deliver_sdu_data,
void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size, int sdu_id),
void *deliver_pdu_data);
void nr_DRB_preconfiguration(void);
#endif /* _NR_PDCP_ENTITY_H_ */
/*
* 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
*/
#include "nr_pdcp_entity_drb_am.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *_entity, char *buffer, int size)
{
nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity;
if (size < 3) abort();
if (!(buffer[0] & 0x80)) { printf("%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1); }
entity->common.deliver_sdu(entity->common.deliver_sdu_data,
(nr_pdcp_entity_t *)entity, buffer+3, size-3);
}
void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *_entity, char *buffer, int size,
int sdu_id)
{
nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity;
int sn;
char buf[size+2];
sn = entity->common.next_nr_pdcp_tx_sn;
entity->common.next_nr_pdcp_tx_sn++;
if (entity->common.next_nr_pdcp_tx_sn > entity->common.maximum_nr_pdcp_sn) {
entity->common.next_nr_pdcp_tx_sn = 0;
entity->common.tx_hfn++;
}
buf[0] = 0x80 | ((sn >> 16) & 0x3);
buf[1] = (sn >> 8) & 0xff;
buf[2] = sn & 0xff;
memcpy(buf+3, buffer, size);
entity->common.deliver_pdu(entity->common.deliver_pdu_data,
(nr_pdcp_entity_t *)entity, buf, size+3, sdu_id);
}
void nr_pdcp_entity_drb_am_set_integrity_key(nr_pdcp_entity_t *_entity, char *key)
{
/* nothing to do */
}
void nr_pdcp_entity_drb_am_delete(nr_pdcp_entity_t *_entity)
{
nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity;
free(entity);
}
/*
* 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
*/
#ifndef _NR_PDCP_ENTITY_DRB_AM_H_
#define _NR_PDCP_ENTITY_DRB_AM_H_
#include "nr_pdcp_entity.h"
typedef struct {
nr_pdcp_entity_t common;
int rb_id;
} nr_pdcp_entity_drb_am_t;
void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *entity, char *buffer, int size);
void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *entity, char *buffer, int size,
int sdu_id);
void nr_pdcp_entity_drb_am_set_integrity_key(nr_pdcp_entity_t *entity, char *key);
void nr_pdcp_entity_drb_am_delete(nr_pdcp_entity_t *entity);
#endif /* _NR_PDCP_ENTITY_DRB_AM_H_ */
/*
* 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
*/
#include "nr_pdcp_ue_manager.h"
#include "NR_RadioBearerConfig.h"
#include "NR_RLC-BearerConfig.h"
#include "NR_CellGroupConfig.h"
#include "openair2/RRC/NR/nr_rrc_proto.h"
/* from OAI */
#include "pdcp.h"
#define TODO do { \
printf("%s:%d:%s: todo\n", __FILE__, __LINE__, __FUNCTION__); \
exit(1); \
} while (0)
static nr_pdcp_ue_manager_t *nr_pdcp_ue_manager;
/* necessary globals for OAI, not used internally */
hash_table_t *pdcp_coll_p;
static uint64_t pdcp_optmask;
/****************************************************************************/
/* rlc_data_req queue - begin */
/****************************************************************************/
#include <pthread.h>
/* NR PDCP and RLC both use "big locks". In some cases a thread may do
* lock(rlc) followed by lock(pdcp) (typically when running 'rx_sdu').
* Another thread may first do lock(pdcp) and then lock(rlc) (typically
* the GTP module calls 'pdcp_data_req' that, in a previous implementation
* was indirectly calling 'rlc_data_req' which does lock(rlc)).
* To avoid the resulting deadlock it is enough to ensure that a call
* to lock(pdcp) will never be followed by a call to lock(rlc). So,
* here we chose to have a separate thread that deals with rlc_data_req,
* out of the PDCP lock. Other solutions may be possible.
* So instead of calling 'rlc_data_req' directly we have a queue and a
* separate thread emptying it.
*/
typedef struct {
protocol_ctxt_t ctxt_pP;
srb_flag_t srb_flagP;
MBMS_flag_t MBMS_flagP;
rb_id_t rb_idP;
mui_t muiP;
confirm_t confirmP;
sdu_size_t sdu_sizeP;
mem_block_t *sdu_pP;
} rlc_data_req_queue_item;
#define RLC_DATA_REQ_QUEUE_SIZE 10000
typedef struct {
rlc_data_req_queue_item q[RLC_DATA_REQ_QUEUE_SIZE];
volatile int start;
volatile int length;
pthread_mutex_t m;
pthread_cond_t c;
} rlc_data_req_queue;
static rlc_data_req_queue q;
extern rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP,
const NR_SRB_ToAddModList_t * const srb2add_listP,
const NR_DRB_ToAddModList_t * const drb2add_listP,
const NR_DRB_ToReleaseList_t * const drb2release_listP,
const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP,
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
static void *rlc_data_req_thread(void *_)
{
int i;
while (1) {
if (pthread_mutex_lock(&q.m) != 0) abort();
while (q.length == 0)
if (pthread_cond_wait(&q.c, &q.m) != 0) abort();
i = q.start;
if (pthread_mutex_unlock(&q.m) != 0) abort();
rlc_data_req(&q.q[i].ctxt_pP,
q.q[i].srb_flagP,
q.q[i].MBMS_flagP,
q.q[i].rb_idP,
q.q[i].muiP,
q.q[i].confirmP,
q.q[i].sdu_sizeP,
q.q[i].sdu_pP,
NULL,
NULL);
if (pthread_mutex_lock(&q.m) != 0) abort();
q.length--;
q.start = (q.start + 1) % RLC_DATA_REQ_QUEUE_SIZE;
if (pthread_cond_signal(&q.c) != 0) abort();
if (pthread_mutex_unlock(&q.m) != 0) abort();
}
}
static void init_nr_rlc_data_req_queue(void)
{
pthread_t t;
pthread_mutex_init(&q.m, NULL);
pthread_cond_init(&q.c, NULL);
if (pthread_create(&t, NULL, rlc_data_req_thread, NULL) != 0) {
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
}
static void enqueue_rlc_data_req(const protocol_ctxt_t *const ctxt_pP,
const srb_flag_t srb_flagP,
const MBMS_flag_t MBMS_flagP,
const rb_id_t rb_idP,
const mui_t muiP,
confirm_t confirmP,
sdu_size_t sdu_sizeP,
mem_block_t *sdu_pP,
void *_unused1, void *_unused2)
{
int i;
int logged = 0;
if (pthread_mutex_lock(&q.m) != 0) abort();
while (q.length == RLC_DATA_REQ_QUEUE_SIZE) {
if (!logged) {
logged = 1;
LOG_W(PDCP, "%s: rlc_data_req queue is full\n", __FUNCTION__);
}
if (pthread_cond_wait(&q.c, &q.m) != 0) abort();
}
i = (q.start + q.length) % RLC_DATA_REQ_QUEUE_SIZE;
q.length++;
q.q[i].ctxt_pP = *ctxt_pP;
q.q[i].srb_flagP = srb_flagP;
q.q[i].MBMS_flagP = MBMS_flagP;
q.q[i].rb_idP = rb_idP;
q.q[i].muiP = muiP;
q.q[i].confirmP = confirmP;
q.q[i].sdu_sizeP = sdu_sizeP;
q.q[i].sdu_pP = sdu_pP;
if (pthread_cond_signal(&q.c) != 0) abort();
if (pthread_mutex_unlock(&q.m) != 0) abort();
}
/****************************************************************************/
/* rlc_data_req queue - end */
/****************************************************************************/
/****************************************************************************/
/* hacks to be cleaned up at some point - begin */
/****************************************************************************/
#include "LAYER2/MAC/mac_extern.h"
static void reblock_tun_socket(void)
{
extern int nas_sock_fd[];
int f;
f = fcntl(nas_sock_fd[0], F_GETFL, 0);
f &= ~(O_NONBLOCK);
if (fcntl(nas_sock_fd[0], F_SETFL, f) == -1) {
LOG_E(PDCP, "reblock_tun_socket failed\n");
exit(1);
}
}
static void *enb_tun_read_thread(void *_)
{
extern int nas_sock_fd[];
char rx_buf[NL_MAX_PAYLOAD];
int len;
int rnti;
protocol_ctxt_t ctxt;
int rb_id = 1;
while (1) {
len = read(nas_sock_fd[0], &rx_buf, NL_MAX_PAYLOAD);
if (len == -1) {
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
printf("\n\n\n########## nas_sock_fd read returns len %d\n", len);
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
rnti = nr_pdcp_get_first_rnti(nr_pdcp_ue_manager);
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
if (rnti == -1) continue;
ctxt.module_id = 0;
ctxt.enb_flag = 1;
ctxt.instance = 0;
ctxt.frame = 0;
ctxt.subframe = 0;
ctxt.eNB_index = 0;
ctxt.configured = 1;
ctxt.brOption = 0;
ctxt.rnti = rnti;
pdcp_data_req(&ctxt, SRB_FLAG_NO, rb_id, RLC_MUI_UNDEFINED,
RLC_SDU_CONFIRM_NO, len, (unsigned char *)rx_buf,
PDCP_TRANSMISSION_MODE_DATA, NULL, NULL);
}
return NULL;
}
static void *ue_tun_read_thread(void *_)
{
extern int nas_sock_fd[];
char rx_buf[NL_MAX_PAYLOAD];
int len;
int rnti;
protocol_ctxt_t ctxt;
int rb_id = 1;
while (1) {
len = read(nas_sock_fd[0], &rx_buf, NL_MAX_PAYLOAD);
if (len == -1) {
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
printf("\n\n\n########## nas_sock_fd read returns len %d\n", len);
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
rnti = nr_pdcp_get_first_rnti(nr_pdcp_ue_manager);
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
if (rnti == -1) continue;
ctxt.module_id = 0;
ctxt.enb_flag = 0;
ctxt.instance = 0;
ctxt.frame = 0;
ctxt.subframe = 0;
ctxt.eNB_index = 0;
ctxt.configured = 1;
ctxt.brOption = 0;
ctxt.rnti = rnti;
pdcp_data_req(&ctxt, SRB_FLAG_NO, rb_id, RLC_MUI_UNDEFINED,
RLC_SDU_CONFIRM_NO, len, (unsigned char *)rx_buf,
PDCP_TRANSMISSION_MODE_DATA, NULL, NULL);
}
return NULL;
}
static void start_pdcp_tun_enb(void)
{
pthread_t t;
reblock_tun_socket();
if (pthread_create(&t, NULL, enb_tun_read_thread, NULL) != 0) {
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
}
static void start_pdcp_tun_ue(void)
{
pthread_t t;
reblock_tun_socket();
if (pthread_create(&t, NULL, ue_tun_read_thread, NULL) != 0) {
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
}
/****************************************************************************/
/* hacks to be cleaned up at some point - end */
/****************************************************************************/
int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP)
{
return 0;
}
void pdcp_layer_init(void)
{
/* hack: be sure to initialize only once */
static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
static int initialized = 0;
if (pthread_mutex_lock(&m) != 0) abort();
if (initialized) {
if (pthread_mutex_unlock(&m) != 0) abort();
return;
}
initialized = 1;
if (pthread_mutex_unlock(&m) != 0) abort();
nr_pdcp_ue_manager = new_nr_pdcp_ue_manager(1);
init_nr_rlc_data_req_queue();
}
#include "nfapi/oai_integration/vendor_ext.h"
#include "targets/RT/USER/lte-softmodem.h"
#include "openair2/RRC/NAS/nas_config.h"
uint64_t pdcp_module_init(uint64_t _pdcp_optmask)
{
/* hack: be sure to initialize only once */
static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
static int initialized = 0;
if (pthread_mutex_lock(&m) != 0) abort();
if (initialized) {
abort();
}
initialized = 1;
if (pthread_mutex_unlock(&m) != 0) abort();
#if 0
pdcp_optmask = _pdcp_optmask;
return pdcp_optmask;
#endif
/* temporary enforce netlink when UE_NAS_USE_TUN is set,
this is while switching from noS1 as build option
to noS1 as config option */
if ( _pdcp_optmask & UE_NAS_USE_TUN_BIT) {
pdcp_optmask = pdcp_optmask | PDCP_USE_NETLINK_BIT ;
}
pdcp_optmask = pdcp_optmask | _pdcp_optmask ;
LOG_I(PDCP, "pdcp init,%s %s\n",
((LINK_ENB_PDCP_TO_GTPV1U)?"usegtp":""),
((PDCP_USE_NETLINK)?"usenetlink":""));
if (PDCP_USE_NETLINK) {
nas_getparams();
if(UE_NAS_USE_TUN) {
int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )?MAX_NUMBER_NETIF:1;
netlink_init_tun("ue",num_if);
//Add --nr-ip-over-lte option check for next line
if (IS_SOFTMODEM_NOS1)
nas_config(1, 1, 2, "ue");
LOG_I(PDCP, "UE pdcp will use tun interface\n");
start_pdcp_tun_ue();
} else if(ENB_NAS_USE_TUN) {
netlink_init_tun("enb",1);
nas_config(1, 1, 1, "enb");
LOG_I(PDCP, "ENB pdcp will use tun interface\n");
start_pdcp_tun_enb();
} else {
LOG_I(PDCP, "pdcp will use kernel modules\n");
abort();
netlink_init();
}
}
return pdcp_optmask ;
}
static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
char *buf, int size)
{
extern int nas_sock_fd[];
int len;
nr_pdcp_ue_t *ue = _ue;
MessageDef *message_p;
uint8_t *gtpu_buffer_p;
int rb_id;
int i;
if(IS_SOFTMODEM_NOS1){
len = write(nas_sock_fd[0], buf, size);
if (len != size) {
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
}
else{
for (i = 0; i < 5; i++) {
if (entity == ue->drb[i]) {
rb_id = i+1;
goto rb_found;
}
}
LOG_E(PDCP, "%s:%d:%s: fatal, no RB found for ue %d\n",
__FILE__, __LINE__, __FUNCTION__, ue->rnti);
exit(1);
rb_found:
gtpu_buffer_p = itti_malloc(TASK_PDCP_ENB, TASK_GTPV1_U,
size + GTPU_HEADER_OVERHEAD_MAX);
AssertFatal(gtpu_buffer_p != NULL, "OUT OF MEMORY");
memcpy(&gtpu_buffer_p[GTPU_HEADER_OVERHEAD_MAX], buf, size);
message_p = itti_alloc_new_message(TASK_PDCP_ENB, GTPV1U_ENB_TUNNEL_DATA_REQ);
AssertFatal(message_p != NULL, "OUT OF MEMORY");
GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).buffer = gtpu_buffer_p;
GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).length = size;
GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).offset = GTPU_HEADER_OVERHEAD_MAX;
GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rnti = ue->rnti;
GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rab_id = rb_id + 4;
printf("!!!!!!! deliver_sdu_drb (drb %d) sending message to gtp size %d: ", rb_id, size);
//for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)buf[i]);
printf("\n");
itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p);
}
}
static void deliver_pdu_drb(void *_ue, nr_pdcp_entity_t *entity,
char *buf, int size, int sdu_id)
{
nr_pdcp_ue_t *ue = _ue;
int rb_id;
protocol_ctxt_t ctxt;
int i;
mem_block_t *memblock;
for (i = 0; i < 5; i++) {
if (entity == ue->drb[i]) {
rb_id = i+1;
goto rb_found;
}
}
LOG_E(PDCP, "%s:%d:%s: fatal, no RB found for ue %d\n",
__FILE__, __LINE__, __FUNCTION__, ue->rnti);
exit(1);
rb_found:
ctxt.module_id = 0;
ctxt.enb_flag = 1;
ctxt.instance = 0;
ctxt.frame = 0;
ctxt.subframe = 0;
ctxt.eNB_index = 0;
ctxt.configured = 1;
ctxt.brOption = 0;
ctxt.rnti = ue->rnti;
memblock = get_free_mem_block(size, __FUNCTION__);
memcpy(memblock->data, buf, size);
printf("!!!!!!! deliver_pdu_drb (srb %d) calling rlc_data_req size %d: ", rb_id, size);
//for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)memblock->data[i]);
printf("\n");
enqueue_rlc_data_req(&ctxt, 0, MBMS_FLAG_NO, rb_id, sdu_id, 0, size, memblock, NULL, NULL);
}
boolean_t pdcp_data_ind(
const protocol_ctxt_t *const ctxt_pP,
const srb_flag_t srb_flagP,
const MBMS_flag_t MBMS_flagP,
const rb_id_t rb_id,
const sdu_size_t sdu_buffer_size,
mem_block_t *const sdu_buffer)
{
nr_pdcp_ue_t *ue;
nr_pdcp_entity_t *rb;
int rnti = ctxt_pP->rnti;
if (ctxt_pP->module_id != 0 ||
//ctxt_pP->enb_flag != 1 ||
ctxt_pP->instance != 0 ||
ctxt_pP->eNB_index != 0 ||
ctxt_pP->configured != 1 ||
ctxt_pP->brOption != 0) {
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
if (ctxt_pP->enb_flag)
T(T_ENB_PDCP_UL, T_INT(ctxt_pP->module_id), T_INT(rnti),
T_INT(rb_id), T_INT(sdu_buffer_size));
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rnti);
if (srb_flagP == 1) {
if (rb_id < 1 || rb_id > 2)
rb = NULL;
else
rb = ue->srb[rb_id - 1];
} else {
if (rb_id < 1 || rb_id > 5)
rb = NULL;
else
rb = ue->drb[rb_id - 1];
}
if (rb != NULL) {
rb->recv_pdu(rb, (char *)sdu_buffer->data, sdu_buffer_size);
} else {
LOG_E(PDCP, "%s:%d:%s: fatal: no RB found (rb_id %ld, srb_flag %d)\n",
__FILE__, __LINE__, __FUNCTION__, rb_id, srb_flagP);
exit(1);
}
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
free_mem_block(sdu_buffer, __FUNCTION__);
return 1;
}
void pdcp_run(const protocol_ctxt_t *const ctxt_pP)
{
MessageDef *msg_p;
int result;
protocol_ctxt_t ctxt;
while (1) {
itti_poll_msg(ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, &msg_p);
if (msg_p == NULL)
break;
switch (ITTI_MSG_ID(msg_p)) {
case RRC_DCCH_DATA_REQ:
PROTOCOL_CTXT_SET_BY_MODULE_ID(
&ctxt,
RRC_DCCH_DATA_REQ(msg_p).module_id,
RRC_DCCH_DATA_REQ(msg_p).enb_flag,
RRC_DCCH_DATA_REQ(msg_p).rnti,
RRC_DCCH_DATA_REQ(msg_p).frame,
0,
RRC_DCCH_DATA_REQ(msg_p).eNB_index);
result = pdcp_data_req(&ctxt,
SRB_FLAG_YES,
RRC_DCCH_DATA_REQ(msg_p).rb_id,
RRC_DCCH_DATA_REQ(msg_p).muip,
RRC_DCCH_DATA_REQ(msg_p).confirmp,
RRC_DCCH_DATA_REQ(msg_p).sdu_size,
RRC_DCCH_DATA_REQ(msg_p).sdu_p,
RRC_DCCH_DATA_REQ(msg_p).mode,
NULL, NULL);
if (result != TRUE)
LOG_E(PDCP, "PDCP data request failed!\n");
result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), RRC_DCCH_DATA_REQ(msg_p).sdu_p);
AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
break;
default:
LOG_E(PDCP, "Received unexpected message %s\n", ITTI_MSG_NAME(msg_p));
break;
}
}
}
static void add_srb(int rnti, struct NR_SRB_ToAddMod *s)
{
TODO;
}
static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s)
{
nr_pdcp_entity_t *pdcp_drb;
nr_pdcp_ue_t *ue;
int drb_id = s->drb_Identity;
printf("\n\n################# rnti %d add drb %d\n\n\n", rnti, drb_id);
if (drb_id != 1) {
LOG_E(PDCP, "%s:%d:%s: fatal, bad drb id %d\n",
__FILE__, __LINE__, __FUNCTION__, drb_id);
exit(1);
}
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rnti);
if (ue->drb[drb_id-1] != NULL) {
LOG_D(PDCP, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n",
__FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
} else {
pdcp_drb = new_nr_pdcp_entity_drb_am(drb_id, deliver_sdu_drb, ue, deliver_pdu_drb, ue);
nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb);
LOG_D(PDCP, "%s:%d:%s: added drb %d to ue %d\n",
__FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
}
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
}
static void add_drb(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_Config_t *rlc_Config)
{
switch (rlc_Config->present) {
case NR_RLC_Config_PR_am:
add_drb_am(rnti, s);
break;
case NR_RLC_Config_PR_um_Bi_Directional:
//add_drb_um(rnti, s);
/* hack */
add_drb_am(rnti, s);
break;
default:
LOG_E(PDCP, "%s:%d:%s: fatal: unhandled DRB type\n",
__FILE__, __LINE__, __FUNCTION__);
exit(1);
}
}
boolean_t nr_rrc_pdcp_config_asn1_req(
const protocol_ctxt_t *const ctxt_pP,
NR_SRB_ToAddModList_t *const srb2add_list,
NR_DRB_ToAddModList_t *const drb2add_list,
NR_DRB_ToReleaseList_t *const drb2release_list,
const uint8_t security_modeP,
uint8_t *const kRRCenc,
uint8_t *const kRRCint,
uint8_t *const kUPenc
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
#endif
,rb_id_t *const defaultDRB,
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list)
//struct NR_RLC_Config *rlc_Config)
{
int rnti = ctxt_pP->rnti;
int i;
if (//ctxt_pP->enb_flag != 1 ||
ctxt_pP->module_id != 0 ||
ctxt_pP->instance != 0 ||
ctxt_pP->eNB_index != 0 ||
//ctxt_pP->configured != 2 ||
//srb2add_list == NULL ||
//drb2add_list != NULL ||
drb2release_list != NULL ||
security_modeP != 255 ||
//kRRCenc != NULL ||
//kRRCint != NULL ||
//kUPenc != NULL ||
pmch_InfoList_r9 != NULL /*||
defaultDRB != NULL */) {
TODO;
}
if (srb2add_list != NULL) {
for (i = 0; i < srb2add_list->list.count; i++) {
add_srb(rnti, srb2add_list->list.array[i]);
}
}
if (drb2add_list != NULL) {
for (i = 0; i < drb2add_list->list.count; i++) {
LOG_I(PDCP, "Before calling add_drb \n");
add_drb(rnti, drb2add_list->list.array[i], rlc_bearer2add_list->list.array[i]->rlc_Config);
}
}
/* update security */
if (kRRCint != NULL) {
/* todo */
}
free(kRRCenc);
free(kRRCint);
free(kUPenc);
return 0;
}
/* Dummy function due to dependency from LTE libraries */
boolean_t rrc_pdcp_config_asn1_req(
const protocol_ctxt_t *const ctxt_pP,
LTE_SRB_ToAddModList_t *const srb2add_list,
LTE_DRB_ToAddModList_t *const drb2add_list,
LTE_DRB_ToReleaseList_t *const drb2release_list,
const uint8_t security_modeP,
uint8_t *const kRRCenc,
uint8_t *const kRRCint,
uint8_t *const kUPenc
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
#endif
,rb_id_t *const defaultDRB)
{
return 0;
}
void nr_DRB_preconfiguration(void)
{
NR_RadioBearerConfig_t *rbconfig = NULL;
struct NR_CellGroupConfig__rlc_BearerToAddModList *Rlc_Bearer_ToAdd_list = NULL;
protocol_ctxt_t ctxt;
//fill_default_rbconfig(rb_config, 5, 1);
rbconfig = calloc(1, sizeof(*rbconfig));
rbconfig->srb_ToAddModList = NULL;
rbconfig->srb3_ToRelease = NULL;
rbconfig->drb_ToAddModList = calloc(1,sizeof(*rbconfig->drb_ToAddModList));
NR_DRB_ToAddMod_t *drb_ToAddMod = calloc(1,sizeof(*drb_ToAddMod));
drb_ToAddMod->cnAssociation = calloc(1,sizeof(*drb_ToAddMod->cnAssociation));
drb_ToAddMod->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity;
drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= 5;
drb_ToAddMod->drb_Identity = 1;
drb_ToAddMod->reestablishPDCP = NULL;
drb_ToAddMod->recoverPDCP = NULL;
drb_ToAddMod->pdcp_Config = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config));
drb_ToAddMod->pdcp_Config->drb = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb));
drb_ToAddMod->pdcp_Config->drb->discardTimer = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->discardTimer));
*drb_ToAddMod->pdcp_Config->drb->discardTimer=NR_PDCP_Config__drb__discardTimer_ms30;
drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL));
*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len12bits;
drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL));
*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len12bits;
drb_ToAddMod->pdcp_Config->drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
drb_ToAddMod->pdcp_Config->drb->headerCompression.choice.notUsed = 0;
drb_ToAddMod->pdcp_Config->drb->integrityProtection=NULL;
drb_ToAddMod->pdcp_Config->drb->statusReportRequired=NULL;
drb_ToAddMod->pdcp_Config->drb->outOfOrderDelivery=NULL;
drb_ToAddMod->pdcp_Config->moreThanOneRLC = NULL;
drb_ToAddMod->pdcp_Config->t_Reordering = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->t_Reordering));
*drb_ToAddMod->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms0;
drb_ToAddMod->pdcp_Config->ext1 = NULL;
ASN_SEQUENCE_ADD(&rbconfig->drb_ToAddModList->list,drb_ToAddMod);
rbconfig->drb_ToReleaseList = NULL;
rbconfig->securityConfig = calloc(1,sizeof(*rbconfig->securityConfig));
rbconfig->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(*rbconfig->securityConfig->securityAlgorithmConfig));
rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0;
rbconfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm=NULL;
rbconfig->securityConfig->keyToUse = calloc(1,sizeof(*rbconfig->securityConfig->keyToUse));
*rbconfig->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master;
xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig);
NR_RLC_BearerConfig_t *RLC_BearerConfig = calloc(1,sizeof(*RLC_BearerConfig));
RLC_BearerConfig->logicalChannelIdentity = 3;
RLC_BearerConfig->servedRadioBearer = calloc(1,sizeof(*RLC_BearerConfig->servedRadioBearer));
RLC_BearerConfig->servedRadioBearer->present = NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity;
RLC_BearerConfig->servedRadioBearer->choice.drb_Identity=1;
RLC_BearerConfig->reestablishRLC=calloc(1,sizeof(*RLC_BearerConfig->reestablishRLC));
*RLC_BearerConfig->reestablishRLC=NR_RLC_BearerConfig__reestablishRLC_true;
RLC_BearerConfig->rlc_Config=calloc(1,sizeof(*RLC_BearerConfig->rlc_Config));
// RLC UM Bi-directional Bearer configuration
RLC_BearerConfig->rlc_Config->present = NR_RLC_Config_PR_um_Bi_Directional;
RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional));
RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength));
*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12;
RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength));
*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12;
RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.t_Reassembly = NR_T_Reassembly_ms15;
// RLC AM Bearer configuration
/*RLC_BearerConfig->rlc_Config->present = NR_RLC_Config_PR_am;
RLC_BearerConfig->rlc_Config->choice.am = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am));
RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength));
*RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size18;
RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.t_PollRetransmit = NR_T_PollRetransmit_ms45;
RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.pollPDU = NR_PollPDU_p64;
RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.pollByte = NR_PollByte_kB500;
RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.maxRetxThreshold = NR_UL_AM_RLC__maxRetxThreshold_t32;
RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength));
*RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size18;
RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.t_Reassembly = NR_T_Reassembly_ms15;
RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.t_StatusProhibit = NR_T_StatusProhibit_ms15;*/
RLC_BearerConfig->mac_LogicalChannelConfig = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig));
RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters));
RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->priority = 1;
RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->bucketSizeDuration = NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->allowedServingCells = NULL;
RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->allowedSCS_List = NULL;
RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->maxPUSCH_Duration = NULL;
RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->configuredGrantType1Allowed = NULL;
RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup));
*RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = 1;
RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->schedulingRequestID = NULL;
RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelSR_Mask = false;
RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = false;
RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->bitRateQueryProhibitTimer = NULL;
Rlc_Bearer_ToAdd_list = calloc(1,sizeof(*Rlc_Bearer_ToAdd_list));
ASN_SEQUENCE_ADD(&Rlc_Bearer_ToAdd_list->list, RLC_BearerConfig);
if (ENB_NAS_USE_TUN){
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_YES, 0x1234, 0, 0,0);
}
else{
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0);
}
nr_rrc_pdcp_config_asn1_req(
&ctxt,
(NR_SRB_ToAddModList_t *) NULL,
rbconfig->drb_ToAddModList ,
rbconfig->drb_ToReleaseList,
0xff,
NULL,
NULL,
NULL,
NULL,
NULL,
Rlc_Bearer_ToAdd_list);
nr_rrc_rlc_config_asn1_req (&ctxt,
(NR_SRB_ToAddModList_t *) NULL,
rbconfig->drb_ToAddModList,
rbconfig->drb_ToReleaseList,
(LTE_PMCH_InfoList_r9_t *) NULL,
Rlc_Bearer_ToAdd_list);
}
uint64_t get_pdcp_optmask(void)
{
return pdcp_optmask;
}
boolean_t pdcp_remove_UE(
const protocol_ctxt_t *const ctxt_pP)
{
TODO;
return 1;
}
void pdcp_config_set_security(const protocol_ctxt_t* const ctxt_pP, pdcp_t *pdcp_pP, rb_id_t rb_id,
uint16_t lc_idP, uint8_t security_modeP, uint8_t *kRRCenc_pP, uint8_t *kRRCint_pP, uint8_t *kUPenc_pP)
{
TODO;
}
static boolean_t pdcp_data_req_drb(
protocol_ctxt_t *ctxt_pP,
const rb_id_t rb_id,
const mui_t muiP,
const confirm_t confirmP,
const sdu_size_t sdu_buffer_size,
unsigned char *const sdu_buffer)
{
printf("pdcp_data_req called size %d\n", sdu_buffer_size);
nr_pdcp_ue_t *ue;
nr_pdcp_entity_t *rb;
int rnti = ctxt_pP->rnti;
if (ctxt_pP->module_id != 0 ||
//ctxt_pP->enb_flag != 1 ||
ctxt_pP->instance != 0 ||
ctxt_pP->eNB_index != 0 /*||
ctxt_pP->configured != 1 ||
ctxt_pP->brOption != 0*/) {
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rnti);
if (rb_id < 1 || rb_id > 5)
rb = NULL;
else
rb = ue->drb[rb_id - 1];
if (rb == NULL) {
LOG_E(PDCP, "%s:%d:%s: fatal: no DRB found (rnti %d, rb_id %ld)\n",
__FILE__, __LINE__, __FUNCTION__, rnti, rb_id);
exit(1);
}
rb->recv_sdu(rb, (char *)sdu_buffer, sdu_buffer_size, muiP);
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
return 1;
}
boolean_t pdcp_data_req(
protocol_ctxt_t *ctxt_pP,
const srb_flag_t srb_flagP,
const rb_id_t rb_id,
const mui_t muiP,
const confirm_t confirmP,
const sdu_size_t sdu_buffer_size,
unsigned char *const sdu_buffer,
const pdcp_transmission_mode_t mode
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
,const uint32_t *const sourceL2Id
,const uint32_t *const destinationL2Id
#endif
)
{
if (srb_flagP) { TODO; }
return pdcp_data_req_drb(ctxt_pP, rb_id, muiP, confirmP, sdu_buffer_size,
sdu_buffer);
}
void pdcp_set_pdcp_data_ind_func(pdcp_data_ind_func_t pdcp_data_ind)
{
/* nothing to do */
}
void pdcp_set_rlc_data_req_func(send_rlc_data_req_func_t send_rlc_data_req)
{
/* nothing to do */
}
//Dummy function needed due to LTE dependencies
void
pdcp_mbms_run ( const protocol_ctxt_t *const ctxt_pP){
/* nothing to do */
}
/*
* 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
*/
#include "nr_pdcp_ue_manager.h"
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include "LOG/log.h"
typedef struct {
pthread_mutex_t lock;
nr_pdcp_ue_t **ue_list;
int ue_count;
int enb_flag;
} nr_pdcp_ue_manager_internal_t;
nr_pdcp_ue_manager_t *new_nr_pdcp_ue_manager(int enb_flag)
{
nr_pdcp_ue_manager_internal_t *ret;
ret = calloc(1, sizeof(nr_pdcp_ue_manager_internal_t));
if (ret == NULL) {
LOG_E(PDCP, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
if (pthread_mutex_init(&ret->lock, NULL)) abort();
ret->enb_flag = enb_flag;
return ret;
}
int nr_pdcp_manager_get_enb_flag(nr_pdcp_ue_manager_t *_m)
{
nr_pdcp_ue_manager_internal_t *m = _m;
return m->enb_flag;
}
void nr_pdcp_manager_lock(nr_pdcp_ue_manager_t *_m)
{
nr_pdcp_ue_manager_internal_t *m = _m;
if (pthread_mutex_lock(&m->lock)) {
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
}
void nr_pdcp_manager_unlock(nr_pdcp_ue_manager_t *_m)
{
nr_pdcp_ue_manager_internal_t *m = _m;
if (pthread_mutex_unlock(&m->lock)) {
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
}
/* must be called with lock acquired */
nr_pdcp_ue_t *nr_pdcp_manager_get_ue(nr_pdcp_ue_manager_t *_m, int rnti)
{
/* TODO: optimze */
nr_pdcp_ue_manager_internal_t *m = _m;
int i;
for (i = 0; i < m->ue_count; i++)
if (m->ue_list[i]->rnti == rnti)
return m->ue_list[i];
LOG_D(PDCP, "%s:%d:%s: new UE %d\n", __FILE__, __LINE__, __FUNCTION__, rnti);
m->ue_count++;
m->ue_list = realloc(m->ue_list, sizeof(nr_pdcp_ue_t *) * m->ue_count);
if (m->ue_list == NULL) {
LOG_E(PDCP, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
m->ue_list[m->ue_count-1] = calloc(1, sizeof(nr_pdcp_ue_t));
if (m->ue_list[m->ue_count-1] == NULL) {
LOG_E(PDCP, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
m->ue_list[m->ue_count-1]->rnti = rnti;
return m->ue_list[m->ue_count-1];
}
/* must be called with lock acquired */
void nr_pdcp_manager_remove_ue(nr_pdcp_ue_manager_t *_m, int rnti)
{
nr_pdcp_ue_manager_internal_t *m = _m;
nr_pdcp_ue_t *ue;
int i;
int j;
for (i = 0; i < m->ue_count; i++)
if (m->ue_list[i]->rnti == rnti)
break;
if (i == m->ue_count) {
LOG_D(PDCP, "%s:%d:%s: warning: ue %d not found\n",
__FILE__, __LINE__, __FUNCTION__,
rnti);
return;
}
ue = m->ue_list[i];
for (j = 0; j < 2; j++)
if (ue->srb[j] != NULL)
ue->srb[j]->delete(ue->srb[j]);
for (j = 0; j < 5; j++)
if (ue->drb[j] != NULL)
ue->drb[j]->delete(ue->drb[j]);
free(ue);
m->ue_count--;
if (m->ue_count == 0) {
free(m->ue_list);
m->ue_list = NULL;
return;
}
memmove(&m->ue_list[i], &m->ue_list[i+1],
(m->ue_count - i) * sizeof(nr_pdcp_ue_t *));
m->ue_list = realloc(m->ue_list, m->ue_count * sizeof(nr_pdcp_ue_t *));
if (m->ue_list == NULL) {
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
}
/* must be called with lock acquired */
void nr_pdcp_ue_add_srb_pdcp_entity(nr_pdcp_ue_t *ue, int srb_id, nr_pdcp_entity_t *entity)
{
if (srb_id < 1 || srb_id > 2) {
LOG_E(PDCP, "%s:%d:%s: fatal, bad srb id\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
srb_id--;
if (ue->srb[srb_id] != NULL) {
LOG_E(PDCP, "%s:%d:%s: fatal, srb already present\n",
__FILE__, __LINE__, __FUNCTION__);
exit(1);
}
ue->srb[srb_id] = entity;
}
/* must be called with lock acquired */
void nr_pdcp_ue_add_drb_pdcp_entity(nr_pdcp_ue_t *ue, int drb_id, nr_pdcp_entity_t *entity)
{
if (drb_id < 1 || drb_id > 5) {
LOG_E(PDCP, "%s:%d:%s: fatal, bad drb id\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
drb_id--;
if (ue->drb[drb_id] != NULL) {
LOG_E(PDCP, "%s:%d:%s: fatal, drb already present\n",
__FILE__, __LINE__, __FUNCTION__);
exit(1);
}
ue->drb[drb_id] = entity;
}
int nr_pdcp_get_first_rnti(nr_pdcp_ue_manager_t *_m)
{
nr_pdcp_ue_manager_internal_t *m = _m;
if (m->ue_count == 0)
return -1;
return m->ue_list[0]->rnti;
}
/*
* 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
*/
#ifndef _NR_PDCP_UE_MANAGER_H_
#define _NR_PDCP_UE_MANAGER_H_
#include "nr_pdcp_entity.h"
typedef void nr_pdcp_ue_manager_t;
typedef struct nr_pdcp_ue_t {
int rnti;
nr_pdcp_entity_t *srb[2];
nr_pdcp_entity_t *drb[5];
} nr_pdcp_ue_t;
/***********************************************************************/
/* manager functions */
/***********************************************************************/
nr_pdcp_ue_manager_t *new_nr_pdcp_ue_manager(int enb_flag);
int nr_pdcp_manager_get_enb_flag(nr_pdcp_ue_manager_t *m);
void nr_pdcp_manager_lock(nr_pdcp_ue_manager_t *m);
void nr_pdcp_manager_unlock(nr_pdcp_ue_manager_t *m);
nr_pdcp_ue_t *nr_pdcp_manager_get_ue(nr_pdcp_ue_manager_t *m, int rnti);
void nr_pdcp_manager_remove_ue(nr_pdcp_ue_manager_t *m, int rnti);
/***********************************************************************/
/* ue functions */
/***********************************************************************/
void nr_pdcp_ue_add_srb_pdcp_entity(nr_pdcp_ue_t *ue, int srb_id,
nr_pdcp_entity_t *entity);
void nr_pdcp_ue_add_drb_pdcp_entity(nr_pdcp_ue_t *ue, int drb_id,
nr_pdcp_entity_t *entity);
/***********************************************************************/
/* hacks */
/***********************************************************************/
/* returns -1 if no UE */
int nr_pdcp_get_first_rnti(nr_pdcp_ue_manager_t *m);
#endif /* _NR_PDCP_UE_MANAGER_H_ */
......@@ -21,14 +21,14 @@
#include "rlc.h"
int decode_t_reordering(int v)
int decode_t_reassembly(int v)
{
static int tab[32] = {
0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85,
90, 95, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 1600
static int tab[31] = {
0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90,
95, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200
};
if (v < 0 || v > 31) {
if (v < 0 || v > 30) {
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
......@@ -72,11 +72,13 @@ int decode_t_poll_retransmit(int v)
int decode_poll_pdu(int v)
{
static int tab[8] = {
4, 8, 16, 32, 64, 128, 256, -1 /* -1 means infinity */
static int tab[24] = {
4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 6144, 8192, 12288,
16384, 20480, 24576, 28672, 32768, 40960, 49152, 57344, 65536
-1 /* -1 means infinity */
};
if (v < 0 || v > 7) {
if (v < 0 || v > 23) {
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
......@@ -86,12 +88,23 @@ int decode_poll_pdu(int v)
int decode_poll_byte(int v)
{
static int tab[15] = {
25, 50, 75, 100, 125, 250, 375, 500, 750, 1000, 1250, 1500, 2000, 3000,
static int tab[44] = {
/* KB */
1024 * 1, 1024 * 2, 1024 * 5, 1024 * 8, 1024 * 10,
1024 * 15, 1024 * 25, 1024 * 50, 1024 * 75, 1024 * 100,
1024 * 125, 1024 * 250, 1024 * 375, 1024 * 500, 1024 * 750,
1024 * 1000, 1024 * 1250, 1024 * 1500, 1024 * 2000, 1024 * 3000,
1024 * 4000, 1024 * 4500, 1024 * 5000, 1024 * 5500, 1024 * 6000,
1024 * 6500, 1024 * 7000, 1024 * 7500,
/* MB */
1024 * 1024 * 8, 1024 * 1024 * 9, 1024 * 1024 * 10, 1024 * 1024 * 11,
1024 * 1024 * 12, 1024 * 1024 * 13, 1024 * 1024 * 14, 1024 * 1024 * 15,
1024 * 1024 * 16, 1024 * 1024 * 17, 1024 * 1024 * 18, 1024 * 1024 * 20,
1024 * 1024 * 25, 1024 * 1024 * 30, 1024 * 1024 * 40,
-1 /* -1 means infinity */
};
if (v < 0 || v > 14) {
if (v < 0 || v > 43) {
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
......@@ -114,10 +127,24 @@ int decode_max_retx_threshold(int v)
return tab[v];
}
int decode_sn_field_length(int v)
int decode_sn_field_length_um(int v)
{
static int tab[2] = {
6, 12
};
if (v < 0 || v > 1) {
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
return tab[v];
}
int decode_sn_field_length_am(int v)
{
static int tab[2] = {
5, 10
12, 18
};
if (v < 0 || v > 1) {
......
......@@ -22,12 +22,13 @@
#ifndef _ASN1_UTILS_H_
#define _ASN1_UTILS_H_
int decode_t_reordering(int v);
int decode_t_reassembly(int v);
int decode_t_status_prohibit(int v);
int decode_t_poll_retransmit(int v);
int decode_poll_pdu(int v);
int decode_poll_byte(int v);
int decode_max_retx_threshold(int v);
int decode_sn_field_length(int v);
int decode_sn_field_length_um(int v);
int decode_sn_field_length_am(int v);
#endif /* _ASN1_UTILS_H_ */
......@@ -110,6 +110,7 @@ static void consider_retransmission(nr_rlc_entity_am_t *entity,
* for the RLC code to keep going with this segment (we only remove
* a segment that was ACKed)
*/
LOG_D(RLC, "RLC segment to be added at the ReTx list \n");
nr_rlc_sdu_segment_list_append(&entity->retransmit_list,
&entity->retransmit_end,
cur);
......@@ -1588,6 +1589,8 @@ void nr_rlc_entity_am_recv_sdu(nr_rlc_entity_t *_entity,
sdu = nr_rlc_new_sdu(buffer, size, sdu_id);
LOG_I(RLC, "Created new RLC SDU and append it to the RLC list \n");
nr_rlc_sdu_segment_list_append(&entity->tx_list, &entity->tx_end, sdu);
}
......
......@@ -27,19 +27,23 @@
#include "asn1_utils.h"
#include "nr_rlc_ue_manager.h"
#include "nr_rlc_entity.h"
#include "NR_RLC-BearerConfig.h"
#include "NR_DRB-ToAddMod.h"
#include "NR_DRB-ToAddModList.h"
#include "NR_SRB-ToAddModList.h"
#include "NR_DRB-ToReleaseList.h"
#include "NR_CellGroupConfig.h"
#include "NR_RLC-Config.h"
#include <stdint.h>
static nr_rlc_ue_manager_t *nr_rlc_ue_manager;
/* TODO: handle time a bit more properly */
//#if 0
static uint64_t nr_rlc_current_time;
static int nr_rlc_current_time_last_frame;
static int nr_rlc_current_time_last_subframe;
//#endif
//#if 0
void mac_rlc_data_ind (
const module_id_t module_idP,
const rnti_t rntiP,
......@@ -195,7 +199,6 @@ mac_rlc_status_resp_t mac_rlc_status_ind(
ret.head_sdu_is_segmented = 0;
return ret;
}
//#endif
rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(
const module_id_t module_idP,
......@@ -254,7 +257,6 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(
int oai_emulation;
//#if 0
rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP,
const srb_flag_t srb_flagP,
const MBMS_flag_t MBMS_flagP,
......@@ -306,9 +308,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP,
return RLC_OP_STATUS_OK;
}
//#endif
//#if 0
int rlc_module_init(int enb_flag)
{
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
......@@ -329,13 +329,10 @@ int rlc_module_init(int enb_flag)
return 0;
}
//#endif
//#if 0
void rlc_util_print_hex_octets(comp_name_t componentP, unsigned char *dataP, const signed long sizeP)
{
}
//#endif
static void deliver_sdu(void *_ue, nr_rlc_entity_t *entity, char *buf, int size)
{
......@@ -522,7 +519,7 @@ rb_found:
#endif
}
__attribute__ ((unused)) static void add_srb(int rnti, struct LTE_SRB_ToAddMod *s)
static void add_srb(int rnti, struct LTE_SRB_ToAddMod *s)
{
nr_rlc_entity_t *nr_rlc_am;
nr_rlc_ue_t *ue;
......@@ -532,7 +529,6 @@ __attribute__ ((unused)) static void add_srb(int rnti, struct LTE_SRB_ToAddMod *
int srb_id = s->srb_Identity;
int logical_channel_group;
//int t_reordering;
int t_status_prohibit;
int t_poll_retransmit;
int poll_pdu;
......@@ -575,7 +571,6 @@ __attribute__ ((unused)) static void add_srb(int rnti, struct LTE_SRB_ToAddMod *
exit(1);
}
am = &r->choice.explicitValue.choice.am;
//t_reordering = decode_t_reordering(am->dl_AM_RLC.t_Reordering);
t_status_prohibit = decode_t_status_prohibit(am->dl_AM_RLC.t_StatusProhibit);
t_poll_retransmit = decode_t_poll_retransmit(am->ul_AM_RLC.t_PollRetransmit);
poll_pdu = decode_poll_pdu(am->ul_AM_RLC.pollPDU);
......@@ -585,7 +580,6 @@ __attribute__ ((unused)) static void add_srb(int rnti, struct LTE_SRB_ToAddMod *
}
case LTE_SRB_ToAddMod__rlc_Config_PR_defaultValue:
/* default values from 36.331 9.2.1 */
//t_reordering = 35;
t_status_prohibit = 0;
t_poll_retransmit = 45;
poll_pdu = -1;
......@@ -628,18 +622,17 @@ __attribute__ ((unused)) static void add_srb(int rnti, struct LTE_SRB_ToAddMod *
nr_rlc_manager_unlock(nr_rlc_ue_manager);
}
static void add_drb_am(int rnti, struct LTE_DRB_ToAddMod *s)
static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_t *rlc_BearerConfig)
{
nr_rlc_entity_t *nr_rlc_am;
nr_rlc_ue_t *ue;
struct LTE_RLC_Config *r = s->rlc_Config;
struct LTE_LogicalChannelConfig *l = s->logicalChannelConfig;
struct NR_RLC_Config *r = rlc_BearerConfig->rlc_Config;
struct NR_LogicalChannelConfig *l = rlc_BearerConfig->mac_LogicalChannelConfig;
int drb_id = s->drb_Identity;
int channel_id = *s->logicalChannelIdentity;
int channel_id = rlc_BearerConfig->logicalChannelIdentity;
int logical_channel_group;
//int t_reordering;
int t_status_prohibit;
int t_poll_retransmit;
int poll_pdu;
......@@ -669,10 +662,9 @@ static void add_drb_am(int rnti, struct LTE_DRB_ToAddMod *s)
}
switch (r->present) {
case LTE_RLC_Config_PR_am: {
struct LTE_RLC_Config__am *am;
am = &r->choice.am;
//t_reordering = decode_t_reordering(am->dl_AM_RLC.t_Reordering);
case NR_RLC_Config_PR_am: {
struct NR_RLC_Config__am *am;
am = r->choice.am;
t_status_prohibit = decode_t_status_prohibit(am->dl_AM_RLC.t_StatusProhibit);
t_poll_retransmit = decode_t_poll_retransmit(am->ul_AM_RLC.t_PollRetransmit);
poll_pdu = decode_poll_pdu(am->ul_AM_RLC.pollPDU);
......@@ -716,18 +708,17 @@ static void add_drb_am(int rnti, struct LTE_DRB_ToAddMod *s)
nr_rlc_manager_unlock(nr_rlc_ue_manager);
}
static void add_drb_um(int rnti, struct LTE_DRB_ToAddMod *s)
static void add_drb_um(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_t *rlc_BearerConfig)
{
nr_rlc_entity_t *nr_rlc_um;
nr_rlc_ue_t *ue;
struct LTE_RLC_Config *r = s->rlc_Config;
struct LTE_LogicalChannelConfig *l = s->logicalChannelConfig;
struct NR_RLC_Config *r = rlc_BearerConfig->rlc_Config;
struct NR_LogicalChannelConfig *l = rlc_BearerConfig->mac_LogicalChannelConfig;
int drb_id = s->drb_Identity;
int channel_id = *s->logicalChannelIdentity;
int channel_id = rlc_BearerConfig->logicalChannelIdentity;
int logical_channel_group;
//int t_reordering;
int sn_field_length;
int t_reassembly;
......@@ -752,15 +743,15 @@ static void add_drb_um(int rnti, struct LTE_DRB_ToAddMod *s)
}
switch (r->present) {
case LTE_RLC_Config_PR_um_Bi_Directional: {
struct LTE_RLC_Config__um_Bi_Directional *um;
um = &r->choice.um_Bi_Directional;
//t_reordering = decode_t_reordering(um->dl_UM_RLC.t_Reordering);
if (um->dl_UM_RLC.sn_FieldLength != um->ul_UM_RLC.sn_FieldLength) {
case NR_RLC_Config_PR_um_Bi_Directional: {
struct NR_RLC_Config__um_Bi_Directional *um;
um = r->choice.um_Bi_Directional;
t_reassembly = decode_t_reassembly(um->dl_UM_RLC.t_Reassembly);
if (*um->dl_UM_RLC.sn_FieldLength != *um->ul_UM_RLC.sn_FieldLength) {
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
sn_field_length = decode_sn_field_length(um->dl_UM_RLC.sn_FieldLength);
sn_field_length = decode_sn_field_length_um(*um->dl_UM_RLC.sn_FieldLength);
break;
}
default:
......@@ -774,9 +765,6 @@ static void add_drb_um(int rnti, struct LTE_DRB_ToAddMod *s)
LOG_D(RLC, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n",
__FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
} else {
/* hack: hardcode values for NR */
t_reassembly = 35;
sn_field_length = 6;
nr_rlc_um = new_nr_rlc_entity_um(1000000,
1000000,
deliver_sdu, ue,
......@@ -790,14 +778,14 @@ static void add_drb_um(int rnti, struct LTE_DRB_ToAddMod *s)
nr_rlc_manager_unlock(nr_rlc_ue_manager);
}
__attribute__ ((unused)) static void add_drb(int rnti, struct LTE_DRB_ToAddMod *s)
static void add_drb(int rnti, struct NR_DRB_ToAddMod *s, struct NR_RLC_BearerConfig *rlc_BearerConfig)
{
switch (s->rlc_Config->present) {
case LTE_RLC_Config_PR_am:
add_drb_am(rnti, s);
switch (rlc_BearerConfig->rlc_Config->present) {
case NR_RLC_Config_PR_am:
add_drb_am(rnti, s, rlc_BearerConfig);
break;
case LTE_RLC_Config_PR_um_Bi_Directional:
add_drb_um(rnti, s);
case NR_RLC_Config_PR_um_Bi_Directional:
add_drb_um(rnti, s, rlc_BearerConfig);
break;
default:
LOG_E(RLC, "%s:%d:%s: fatal: unhandled DRB type\n",
......@@ -806,7 +794,7 @@ __attribute__ ((unused)) static void add_drb(int rnti, struct LTE_DRB_ToAddMod *
}
}
//#if 0
/* Dummy function due to dependency from LTE libraries */
rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP,
const LTE_SRB_ToAddModList_t * const srb2add_listP,
const LTE_DRB_ToAddModList_t * const drb2add_listP,
......@@ -814,6 +802,16 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP
const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP,
const uint32_t sourceL2Id,
const uint32_t destinationL2Id)
{
return 0;
}
rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP,
const LTE_SRB_ToAddModList_t * const srb2add_listP,
const NR_DRB_ToAddModList_t * const drb2add_listP,
const NR_DRB_ToReleaseList_t * const drb2release_listP,
const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP,
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list)
{
int rnti = ctxt_pP->rnti;
int i;
......@@ -845,15 +843,13 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP
if (drb2add_listP != NULL) {
for (i = 0; i < drb2add_listP->list.count; i++) {
add_drb(rnti, drb2add_listP->list.array[i]);
add_drb(rnti, drb2add_listP->list.array[i], rlc_bearer2add_list->list.array[i]);
}
}
return RLC_OP_STATUS_OK;
}
//#endif
//#if 0
rlc_op_status_t rrc_rlc_config_req (
const protocol_ctxt_t* const ctxt_pP,
const srb_flag_t srb_flagP,
......@@ -912,16 +908,12 @@ rlc_op_status_t rrc_rlc_config_req (
nr_rlc_manager_unlock(nr_rlc_ue_manager);
return RLC_OP_STATUS_OK;
}
//#endif
//#if 0
void rrc_rlc_register_rrc (rrc_data_ind_cb_t rrc_data_indP, rrc_data_conf_cb_t rrc_data_confP)
{
/* nothing to do */
}
//#endif
//#if 0
rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x)
{
LOG_D(RLC, "%s:%d:%s: remove UE %d\n", __FILE__, __LINE__, __FUNCTION__, x->rnti);
......@@ -931,4 +923,3 @@ rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x)
return RLC_OP_STATUS_OK;
}
//#endif
......@@ -36,11 +36,34 @@
//#include "NR_UE-CapabilityRAT-ContainerList.h"
#include "LTE_UE-CapabilityRAT-ContainerList.h"
#include "NR_CG-Config.h"
//#include "NR_SRB-ToAddModList.h"
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
#include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h"
#include "executables/softmodem-common.h"
#include <openair2/RRC/NR/rrc_gNB_UE_context.h>
extern boolean_t nr_rrc_pdcp_config_asn1_req(
const protocol_ctxt_t *const ctxt_pP,
NR_SRB_ToAddModList_t *const srb2add_list,
NR_DRB_ToAddModList_t *const drb2add_list,
NR_DRB_ToReleaseList_t *const drb2release_list,
const uint8_t security_modeP,
uint8_t *const kRRCenc,
uint8_t *const kRRCint,
uint8_t *const kUPenc
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
#endif
,rb_id_t *const defaultDRB,
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
extern rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP,
const NR_SRB_ToAddModList_t * const srb2add_listP,
const NR_DRB_ToAddModList_t * const drb2add_listP,
const NR_DRB_ToReleaseList_t * const drb2release_listP,
const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP,
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, LTE_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList, x2ap_ENDC_sgnb_addition_req_t *m, NR_CG_ConfigInfo_IEs_t *cg_config_info) {
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
......@@ -244,6 +267,27 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
1, // add_ue flag
ue_context_p->ue_id_rnti,
ue_context_p->ue_context.secondaryCellGroup);
nr_rrc_pdcp_config_asn1_req(
&ctxt,
(NR_SRB_ToAddModList_t *) NULL,
ue_context_p->ue_context.rb_config->drb_ToAddModList ,
ue_context_p->ue_context.rb_config->drb_ToReleaseList,
0xff,
NULL,
NULL,
NULL,
NULL,
NULL,
ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList);
nr_rrc_rlc_config_asn1_req (&ctxt,
(NR_SRB_ToAddModList_t *) NULL,
ue_context_p->ue_context.rb_config->drb_ToAddModList,
ue_context_p->ue_context.rb_config->drb_ToReleaseList,
(LTE_PMCH_InfoList_r9_t *) NULL,
ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList);
}
......
......@@ -66,7 +66,19 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
RLC_BearerConfig->reestablishRLC=calloc(1,sizeof(*RLC_BearerConfig->reestablishRLC));
*RLC_BearerConfig->reestablishRLC=NR_RLC_BearerConfig__reestablishRLC_true;
RLC_BearerConfig->rlc_Config=calloc(1,sizeof(*RLC_BearerConfig->rlc_Config));
RLC_BearerConfig->rlc_Config->present = NR_RLC_Config_PR_am;
// RLC UM Bi-directional Bearer configuration
RLC_BearerConfig->rlc_Config->present = NR_RLC_Config_PR_um_Bi_Directional;
RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional));
RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength));
*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12;
RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength));
*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12;
RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.t_Reassembly = NR_T_Reassembly_ms15;
// RLC AM Bearer configuration
/*RLC_BearerConfig->rlc_Config->present = NR_RLC_Config_PR_am;
RLC_BearerConfig->rlc_Config->choice.am = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am));
RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength));
*RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size18;
......@@ -77,7 +89,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength));
*RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size18;
RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.t_Reassembly = NR_T_Reassembly_ms15;
RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.t_StatusProhibit = NR_T_StatusProhibit_ms15;
RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.t_StatusProhibit = NR_T_StatusProhibit_ms15;*/
RLC_BearerConfig->mac_LogicalChannelConfig = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig));
RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters));
RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->priority = 1;
......@@ -150,9 +162,8 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions= calloc(1,sizeof(struct NR_CFRA__occasions));
memcpy(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->rach_ConfigGeneric,
&servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric, sizeof(NR_RACH_ConfigGeneric_t));
//secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion= calloc(1,sizeof(long));
//*secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion = NR_CFRA__occasions__ssb_perRACH_Occasion_one;
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion= NULL;
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion= calloc(1,sizeof(long));
*secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion = NR_CFRA__occasions__ssb_perRACH_Occasion_one;
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.present = NR_CFRA__resources_PR_ssb;
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb = calloc(1,sizeof(struct NR_CFRA__resources__ssb));
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ra_ssb_OccasionMaskIndex = 0;
......@@ -2047,7 +2058,7 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) {
NR_DRB_ToAddMod_t *drb_ToAddMod = calloc(1,sizeof(*drb_ToAddMod));
drb_ToAddMod->cnAssociation = calloc(1,sizeof(*drb_ToAddMod->cnAssociation));
drb_ToAddMod->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity;
drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity=5;
drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= 5;
drb_ToAddMod->drb_Identity = 1;
drb_ToAddMod->reestablishPDCP = NULL;
drb_ToAddMod->recoverPDCP = NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment