Merge remote-tracking branch 'origin/develop' into develop-SRS
# Conflicts: # ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf # ci-scripts/conf_files/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf # openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c # openair2/RRC/NR/L2_nr_interface.c
This commit is contained in:
@@ -799,7 +799,7 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
|
||||
RC.mac[Mod_idP]->common_channels[CC_idP].Ncp = Ncp;
|
||||
RC.mac[Mod_idP]->common_channels[CC_idP].eutra_band = eutra_band;
|
||||
RC.mac[Mod_idP]->common_channels[CC_idP].dl_CarrierFreq = dl_CarrierFreq;
|
||||
LOG_I(MAC,
|
||||
LOG_A(MAC,
|
||||
"Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d,Nid_cell %d,p %d,DL freq %u,phich_config.resource %d, phich_config.duration %d)\n",
|
||||
Mod_idP,
|
||||
CC_idP,
|
||||
@@ -1067,7 +1067,7 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
|
||||
while(RC.mac[Mod_idP]->if_inst->PHY_config_req == NULL) {
|
||||
// DJP AssertFatal(RC.mac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n");
|
||||
usleep(100 * 1000);
|
||||
printf("Waiting for PHY_config_req\n");
|
||||
LOG_I(MAC, "Waiting for PHY_config_req\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -200,7 +200,7 @@ rrc_mac_config_req_ue(module_id_t Mod_idP,
|
||||
LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5;
|
||||
}
|
||||
|
||||
if(NFAPI_MODE != NFAPI_UE_STUB_PNF)
|
||||
if(NFAPI_MODE!=NFAPI_UE_STUB_PNF && NFAPI_MODE!=NFAPI_MODE_STANDALONE_PNF)
|
||||
phy_config_harq_ue(Mod_idP, 0, eNB_index, UE_mac_inst[Mod_idP].scheduling_info.maxHARQ_Tx);
|
||||
|
||||
if (mac_MainConfig->ul_SCH_Config->retxBSR_Timer) {
|
||||
@@ -308,7 +308,7 @@ rrc_mac_config_req_ue(module_id_t Mod_idP,
|
||||
}
|
||||
|
||||
if (physicalConfigDedicated != NULL) {
|
||||
if(NFAPI_MODE != NFAPI_UE_STUB_PNF)
|
||||
if(NFAPI_MODE != NFAPI_UE_STUB_PNF && NFAPI_MODE != NFAPI_MODE_STANDALONE_PNF)
|
||||
phy_config_dedicated_ue(Mod_idP, 0, eNB_index,
|
||||
physicalConfigDedicated);
|
||||
|
||||
|
||||
@@ -313,6 +313,7 @@ schedule_SR (module_id_t module_idP,
|
||||
nfapi_ul_config_request_body_t *ul_req_body = NULL;
|
||||
LTE_SchedulingRequestConfig_t *SRconfig = NULL;
|
||||
nfapi_ul_config_sr_information sr;
|
||||
memset(&sr, 0, sizeof(sr));
|
||||
|
||||
for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
||||
eNB->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP;
|
||||
@@ -573,6 +574,27 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
UE_sched_ctrl_t *UE_scheduling_control = NULL;
|
||||
start_meas(&(eNB->eNB_scheduler));
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, VCD_FUNCTION_IN);
|
||||
// TODO: Better solution needed this is the first
|
||||
// 3 indications of this function on startup
|
||||
// 1303275.278188 [MAC] XXX 0.0 -> 0.4 = 4
|
||||
// 1303275.279443 [MAC] XXX 0.4 -> 639.5 = 6391
|
||||
// 1303275.348686 [MAC] XXX 646.3 -> 646.3 = 0
|
||||
int delta = (frameP * 10 + subframeP) - (eNB->frame * 10 + eNB->subframe);
|
||||
if (delta < 0)
|
||||
{
|
||||
delta += 10240; // sfn_sf decimal values range from 0 to 10239
|
||||
}
|
||||
// If we ever see a difference this big something is very wrong
|
||||
// This threshold is arbitrary
|
||||
if (delta > 8500 || delta == 0) // 850 frames
|
||||
{
|
||||
LOG_I(MAC, "scheduler ignoring outerspace %d.%d -> %d.%d = %d\n",
|
||||
eNB->frame, eNB->subframe, frameP, subframeP, delta);
|
||||
return;
|
||||
}
|
||||
LOG_D(MAC, "Entering dlsch_ulsch scheduler %d.%d -> %d.%d = %d\n",
|
||||
eNB->frame, eNB->subframe, frameP, subframeP, delta);
|
||||
|
||||
eNB->frame = frameP;
|
||||
eNB->subframe = subframeP;
|
||||
|
||||
|
||||
@@ -918,7 +918,7 @@ generate_Msg4(module_id_t module_idP,
|
||||
module_idP, CC_idP, frameP, subframeP, UE_id, rrc_sdu_length);
|
||||
// AssertFatal(rrc_sdu_length > 0,
|
||||
// "[MAC][eNB Scheduler] CCCH not allocated, rrc_sdu_length: %d\n", rrc_sdu_length);
|
||||
LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RNTI %x)\n",
|
||||
LOG_A(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RNTI %x)\n",
|
||||
module_idP, CC_idP, frameP, subframeP, ra->rnti);
|
||||
/// Choose first 4 RBs for Msg4, should really check that these are free!
|
||||
first_rb = 0;
|
||||
|
||||
@@ -560,7 +560,7 @@ void dlsch_scheduler_pre_ue_select_fairRR(
|
||||
return;
|
||||
}
|
||||
|
||||
void dlsch_scheduler_pre_processor_reset_fairRR(
|
||||
static void dlsch_scheduler_pre_processor_reset_fairRR(
|
||||
module_id_t module_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t subframeP,
|
||||
@@ -729,7 +729,7 @@ void dlsch_scheduler_pre_processor_reset_fairRR(
|
||||
}
|
||||
|
||||
// This function returns the estimated number of RBs required by each UE for downlink scheduling
|
||||
void assign_rbs_required_fairRR(
|
||||
static void assign_rbs_required_fairRR(
|
||||
module_id_t Mod_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t subframe,
|
||||
@@ -1018,8 +1018,8 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id,
|
||||
UE_id,
|
||||
CC_id,
|
||||
N_RBG[CC_id],
|
||||
(uint16_t(*)[NUMBER_OF_UE_MAX])nb_rbs_required,
|
||||
(uint16_t(*)[NUMBER_OF_UE_MAX])nb_rbs_required_remaining,
|
||||
nb_rbs_required,
|
||||
nb_rbs_required_remaining,
|
||||
rballoc_sub);
|
||||
temp_total_rbs_count -= ue_sched_ctl->pre_nb_available_rbs[CC_id];
|
||||
temp_total_ue_count--;
|
||||
@@ -1925,7 +1925,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
|
||||
}
|
||||
|
||||
trace_pdu(DIRECTION_DOWNLINK, (uint8_t *)UE_info->DLSCH_pdu[CC_id][0][UE_id].payload[0],
|
||||
TBS, module_idP, WS_RA_RNTI, UE_RNTI(module_idP, UE_id),
|
||||
TBS, module_idP, WS_C_RNTI, UE_RNTI(module_idP, UE_id),
|
||||
eNB->frame, eNB->subframe,0,0);
|
||||
T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP),
|
||||
T_INT(harq_pid), T_BUFFER(UE_info->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS));
|
||||
|
||||
@@ -85,21 +85,6 @@ void dlsch_scheduler_pre_ue_select_fairRR(
|
||||
uint16_t nb_rbs_required[MAX_NUM_CCs][MAX_MOBILES_PER_ENB],
|
||||
DLSCH_UE_SELECT dlsch_ue_select[MAX_NUM_CCs]);
|
||||
|
||||
void dlsch_scheduler_pre_processor_reset_fairRR(
|
||||
module_id_t module_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t subframeP,
|
||||
int min_rb_unit[NFAPI_CC_MAX],
|
||||
uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
|
||||
uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX],
|
||||
uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]);
|
||||
|
||||
void assign_rbs_required_fairRR(
|
||||
module_id_t Mod_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t subframe,
|
||||
uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]);
|
||||
|
||||
void dlsch_scheduler_pre_processor_allocate_fairRR(
|
||||
module_id_t Mod_id,
|
||||
int UE_id,
|
||||
|
||||
@@ -41,10 +41,12 @@
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
|
||||
|
||||
|
||||
#include "PHY_INTERFACE/phy_stub_UE.h"
|
||||
#include "common/ran_context.h"
|
||||
#include <openair2/RRC/LTE/rrc_proto.h>
|
||||
|
||||
extern void openair_rrc_top_init_ue( int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, uint8_t HO_active);
|
||||
|
||||
void dl_phy_sync_success(module_id_t module_idP, frame_t frameP, unsigned char eNB_index, uint8_t first_sync) { //init as MR
|
||||
LOG_D(MAC, "[UE %d] Frame %d: PHY Sync to eNB_index %d successful \n",
|
||||
module_idP, frameP, eNB_index);
|
||||
@@ -88,6 +90,16 @@ mac_top_init_ue(int eMBMS_active, char *uecap_xer,
|
||||
UE_mac_inst = NULL;
|
||||
}
|
||||
|
||||
// mutex below are used for multiple UE's L2 FAPI simulation.
|
||||
if (NFAPI_MODE == NFAPI_UE_STUB_PNF || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) {
|
||||
pthread_mutex_init(&fill_ul_mutex.rx_mutex,NULL);
|
||||
pthread_mutex_init(&fill_ul_mutex.crc_mutex,NULL);
|
||||
pthread_mutex_init(&fill_ul_mutex.sr_mutex,NULL);
|
||||
pthread_mutex_init(&fill_ul_mutex.harq_mutex,NULL);
|
||||
pthread_mutex_init(&fill_ul_mutex.cqi_mutex,NULL);
|
||||
pthread_mutex_init(&fill_ul_mutex.rach_mutex,NULL);
|
||||
}
|
||||
|
||||
LOG_I(MAC, "[MAIN] calling RRC\n");
|
||||
openair_rrc_top_init_ue(eMBMS_active, uecap_xer, cba_group_active,
|
||||
HO_active);
|
||||
|
||||
@@ -287,9 +287,12 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id,
|
||||
sub_frame_t subframeP) {
|
||||
uint8_t Size = 0;
|
||||
UE_MODE_t UE_mode;
|
||||
|
||||
protocol_ctxt_t ctxt;
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_NO,
|
||||
UE_mac_inst[module_idP].crnti, frameP,
|
||||
subframeP, eNB_indexP);
|
||||
// Modification for phy_stub_ue operation
|
||||
if(NFAPI_MODE == NFAPI_UE_STUB_PNF) { // phy_stub_ue mode
|
||||
if(NFAPI_MODE == NFAPI_UE_STUB_PNF || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) { // phy_stub_ue mode
|
||||
UE_mode = UE_mac_inst[module_idP].UE_mode[0];
|
||||
LOG_D(MAC, "ue_get_rach , UE_mode: %d", UE_mode);
|
||||
} else { // Full stack mode
|
||||
@@ -320,6 +323,18 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id,
|
||||
|
||||
if (UE_mac_inst[module_idP].RA_active == 0) {
|
||||
LOG_I(MAC, "RA not active\n");
|
||||
if (UE_rrc_inst[module_idP].Info[eNB_indexP].T300_cnt
|
||||
!= T300[UE_rrc_inst[module_idP].sib2[eNB_indexP]->ue_TimersAndConstants.t300]) {
|
||||
/* Calling rrc_ue_generate_RRCConnectionRequest here to ensure that
|
||||
every time we fill the UE_mac_inst context we generate new random
|
||||
values in msg3. When the T300 timer has expired, rrc_common.c will
|
||||
call rrc_ue_generate_RRCConnectionRequest, so we do not want to call
|
||||
when UE_rrc_inst[module_idP].Info[eNB_indexP].T300_cnt ==
|
||||
T300[UE_rrc_inst[module_idP].sib2[eNB_indexP]->ue_TimersAndConstants.t300. */
|
||||
UE_rrc_inst[module_idP].Srb0[eNB_indexP].Tx_buffer.payload_size = 0;
|
||||
rrc_ue_generate_RRCConnectionRequest(&ctxt, eNB_indexP);
|
||||
}
|
||||
|
||||
// check if RRC is ready to initiate the RA procedure
|
||||
Size = mac_rrc_data_req_ue(module_idP,
|
||||
CC_id,
|
||||
|
||||
@@ -67,6 +67,7 @@ uint16_t ue_process_rar(const module_id_t module_idP, const int CC_id, const fra
|
||||
LOG_D(PHY, "Found RAR with the intended RAPID %d\n",
|
||||
rarh->RAPID);
|
||||
rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6);
|
||||
UE_mac_inst[module_idP].UE_mode[0] = RA_RESPONSE;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -77,9 +78,10 @@ uint16_t ue_process_rar(const module_id_t module_idP, const int CC_id, const fra
|
||||
}
|
||||
|
||||
if (rarh->E == 0) {
|
||||
LOG_I(PHY,
|
||||
LOG_I(MAC,
|
||||
"No RAR found with the intended RAPID. The closest RAPID in all RARs is %d\n",
|
||||
best_rx_rapid);
|
||||
UE_mac_inst[module_idP].UE_mode[0] = PRACH;
|
||||
break;
|
||||
} else {
|
||||
rarh++;
|
||||
@@ -94,7 +96,7 @@ uint16_t ue_process_rar(const module_id_t module_idP, const int CC_id, const fra
|
||||
return (0xffff);
|
||||
}
|
||||
|
||||
LOG_I(MAC,
|
||||
LOG_A(MAC,
|
||||
"[UE %d][RAPROC] Frame %d Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n",
|
||||
module_idP, frameP, *(uint8_t *) rarh, rar[0], rar[1], rar[2],
|
||||
rar[3], rar[4], rar[5], rarh->RAPID, preamble_index);
|
||||
@@ -130,7 +132,7 @@ uint16_t ue_process_rar(const module_id_t module_idP, const int CC_id, const fra
|
||||
}
|
||||
|
||||
// move the selected RAR to the front of the RA_PDSCH buffer
|
||||
memcpy(selected_rar_buffer + 0, (uint8_t *) rarh, 1);
|
||||
memcpy(selected_rar_buffer + 1, (uint8_t *) rar, 6);
|
||||
memmove(selected_rar_buffer + 0, (uint8_t *) rarh, 1);
|
||||
memmove(selected_rar_buffer + 1, (uint8_t *) rar, 6);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -149,15 +149,13 @@ void ue_init_mac(module_id_t module_idP) {
|
||||
UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[i] = 0;
|
||||
}
|
||||
|
||||
if(NFAPI_MODE==NFAPI_UE_STUB_PNF) {
|
||||
if(NFAPI_MODE==NFAPI_UE_STUB_PNF || NFAPI_MODE==NFAPI_MODE_STANDALONE_PNF) {
|
||||
pthread_mutex_init(&UE_mac_inst[module_idP].UL_INFO_mutex,NULL);
|
||||
UE_mac_inst[module_idP].UE_mode[0] = NOT_SYNCHED; //PRACH;
|
||||
UE_mac_inst[module_idP].UE_mode[0] = PRACH; //NOT_SYNCHED;
|
||||
UE_mac_inst[module_idP].first_ULSCH_Tx =0;
|
||||
UE_mac_inst[module_idP].SI_Decoded = 0;
|
||||
next_ra_frame = 0;
|
||||
next_Mod_id = 0;
|
||||
tx_request_pdu_list = NULL;
|
||||
tx_req_num_elems = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -411,7 +409,7 @@ ue_send_sdu(module_id_t module_idP,
|
||||
|
||||
if (payload_ptr != NULL) {
|
||||
for (i = 0; i < num_ce; i++) {
|
||||
// printf("ce %d : %d\n",i,rx_ces[i]);
|
||||
LOG_I(MAC, "ce %d : %d\n",i,rx_ces[i]);
|
||||
switch (rx_ces[i]) {
|
||||
case UE_CONT_RES:
|
||||
LOG_I(MAC,
|
||||
@@ -436,7 +434,7 @@ ue_send_sdu(module_id_t module_idP,
|
||||
"[UE %d][RAPROC] Contention detected, RA failed\n",
|
||||
module_idP);
|
||||
|
||||
if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { // phy_stub mode
|
||||
if(NFAPI_MODE==NFAPI_UE_STUB_PNF || NFAPI_MODE==NFAPI_MODE_STANDALONE_PNF) { // phy_stub mode
|
||||
// Modification for phy_stub mode operation here. We only need to make sure that the ue_mode is back to
|
||||
// PRACH state.
|
||||
LOG_I(MAC, "nfapi_mode3: Setting UE_mode BACK to PRACH 1\n");
|
||||
@@ -462,7 +460,7 @@ ue_send_sdu(module_id_t module_idP,
|
||||
[module_idP].
|
||||
RA_contention_resolution_timer_active = 0;
|
||||
|
||||
if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { // phy_stub mode
|
||||
if(NFAPI_MODE==NFAPI_UE_STUB_PNF || NFAPI_MODE==NFAPI_MODE_STANDALONE_PNF) { // phy_stub mode
|
||||
// Modification for phy_stub mode operation here. We only need to change the ue_mode to PUSCH
|
||||
UE_mac_inst[module_idP].UE_mode[eNB_index] = PUSCH;
|
||||
} else { // Full stack mode
|
||||
@@ -480,7 +478,7 @@ ue_send_sdu(module_id_t module_idP,
|
||||
#endif
|
||||
|
||||
// Eliminate call to process_timing_advance for the phy_stub UE operation mode. Is this correct?
|
||||
if (NFAPI_MODE!=NFAPI_UE_STUB_PNF) {
|
||||
if (NFAPI_MODE!=NFAPI_UE_STUB_PNF && NFAPI_MODE!=NFAPI_MODE_STANDALONE_PNF) {
|
||||
process_timing_advance(module_idP,CC_id,payload_ptr[0]);
|
||||
}
|
||||
|
||||
@@ -2508,6 +2506,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
|
||||
scheduling_info.BSR_bytes[UE_mac_inst[module_idP].
|
||||
scheduling_info.LCGID
|
||||
[lcid]]);
|
||||
AssertFatal(num_sdus < sizeof(sdu_lengths) / sizeof(sdu_lengths[0]), "num_sdus %d > num sdu_length elements\n", num_sdus);
|
||||
sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
|
||||
UE_mac_inst
|
||||
[module_idP].
|
||||
@@ -2639,7 +2638,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
|
||||
|
||||
// build PHR and update the timers
|
||||
if (phr_ce_len == sizeof(POWER_HEADROOM_CMD)) {
|
||||
if(NFAPI_MODE==NFAPI_UE_STUB_PNF) {
|
||||
if(NFAPI_MODE==NFAPI_UE_STUB_PNF || NFAPI_MODE==NFAPI_MODE_STANDALONE_PNF) {
|
||||
//Substitute with a static value for the MAC layer abstraction (phy_stub mode)
|
||||
phr_p->PH = 60;
|
||||
} else {
|
||||
@@ -3090,7 +3089,7 @@ ue_scheduler(const module_id_t module_idP,
|
||||
"Module id %u Contention resolution timer expired, RA failed\n",
|
||||
module_idP);
|
||||
|
||||
if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { // phy_stub mode
|
||||
if(NFAPI_MODE==NFAPI_UE_STUB_PNF || NFAPI_MODE==NFAPI_MODE_STANDALONE_PNF) { // phy_stub mode
|
||||
// Modification for phy_stub mode operation here. We only need to make sure that the ue_mode is back to
|
||||
// PRACH state.
|
||||
LOG_I(MAC, "nfapi_mode3: Setting UE_mode to PRACH 2 \n");
|
||||
|
||||
@@ -264,6 +264,16 @@ typedef struct {
|
||||
uint8_t nbits;
|
||||
} dci_field_t;
|
||||
|
||||
typedef struct {
|
||||
bool expected_sib;
|
||||
bool index_has_sib[16];
|
||||
bool expected_rar;
|
||||
bool index_has_rar[16];
|
||||
bool expected_dci;
|
||||
bool index_has_dci[16];
|
||||
int active_harq_sfn_slot;
|
||||
} nr_emulated_l1_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
uint8_t format_indicator; //1 bit
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
|
||||
extern const uint8_t nr_slots_per_frame[5];
|
||||
|
||||
extern dci_pdu_rel15_t *def_dci_pdu_rel15;
|
||||
|
||||
/* extern const uint32_t BSR_TABLE[BSR_TABLE_SIZE];
|
||||
extern const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE];
|
||||
extern const uint8_t cqi2fmt0_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE];
|
||||
|
||||
@@ -627,7 +627,8 @@ int nr_rrc_mac_config_req_ue(
|
||||
pthread_mutex_init(&(mac->ul_config_request[i].mutex_ul_config), NULL);
|
||||
// Setup the SSB to Rach Occasions mapping according to the config
|
||||
build_ssb_to_ro_map(mac);//->scc, mac->phy_config.config_req.cell_config.frame_duplex_type);
|
||||
mac->if_module->phy_config_request(&mac->phy_config);
|
||||
if (!get_softmodem_params()->emulate_l1)
|
||||
mac->if_module->phy_config_request(&mac->phy_config);
|
||||
mac->common_configuration_complete = 1;
|
||||
}
|
||||
if(scell_group_config != NULL ){
|
||||
@@ -654,7 +655,16 @@ int nr_rrc_mac_config_req_ue(
|
||||
else if (cell_group_config != NULL ){
|
||||
LOG_I(MAC,"Applying CellGroupConfig from gNodeB\n");
|
||||
mac->cg = cell_group_config;
|
||||
mac->servCellIndex = cell_group_config->spCellConfig->servCellIndex ? *cell_group_config->spCellConfig->servCellIndex : 0;
|
||||
if (cell_group_config->spCellConfig) {
|
||||
mac->servCellIndex = cell_group_config->spCellConfig->servCellIndex ? *cell_group_config->spCellConfig->servCellIndex : 0;
|
||||
mac->DL_BWP_Id=mac->cg->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id ? *mac->cg->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id : 0;
|
||||
mac->UL_BWP_Id=mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id ? *mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id : 0;
|
||||
}
|
||||
else {
|
||||
mac->servCellIndex = 0;
|
||||
mac->DL_BWP_Id = 0;
|
||||
mac->UL_BWP_Id = 0;
|
||||
}
|
||||
|
||||
mac->scheduling_info.periodicBSR_SF =
|
||||
MAC_UE_BSR_TIMER_NOT_RUNNING;
|
||||
@@ -667,7 +677,26 @@ int nr_rrc_mac_config_req_ue(
|
||||
mac->scheduling_info.retxBSR_SF);
|
||||
|
||||
config_control_ue(mac);
|
||||
//config_common_ue(mac,module_id,cc_idP);
|
||||
if (get_softmodem_params()->nsa) {
|
||||
if (cell_group_config->spCellConfig && cell_group_config->spCellConfig->reconfigurationWithSync) {
|
||||
if (cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated) {
|
||||
ra->rach_ConfigDedicated = cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink;
|
||||
}
|
||||
mac->scc = cell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon;
|
||||
int num_slots = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
|
||||
if (mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols > 0) {
|
||||
num_slots++;
|
||||
}
|
||||
mac->ul_config_request = calloc(num_slots, sizeof(*mac->ul_config_request));
|
||||
config_common_ue(mac,module_id,cc_idP);
|
||||
mac->crnti = cell_group_config->spCellConfig->reconfigurationWithSync->newUE_Identity;
|
||||
LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti);
|
||||
}
|
||||
|
||||
// Setup the SSB to Rach Occasions mapping according to the config
|
||||
build_ssb_to_ro_map(mac);
|
||||
}
|
||||
|
||||
/*
|
||||
if(mac_cell_group_configP != NULL){
|
||||
if(mac_cell_group_configP->drx_Config != NULL ){
|
||||
|
||||
@@ -430,8 +430,14 @@ typedef struct {
|
||||
|
||||
dci_pdu_rel15_t def_dci_pdu_rel15[8];
|
||||
|
||||
// Defined for abstracted mode
|
||||
nr_downlink_indication_t dl_info;
|
||||
NR_UE_HARQ_STATUS_t dl_harq_info[16];
|
||||
|
||||
nr_emulated_l1_t nr_ue_emul_l1;
|
||||
|
||||
pthread_mutex_t mutex_dl_info;
|
||||
|
||||
} NR_UE_MAC_INST_t;
|
||||
|
||||
typedef enum seach_space_mask_e {
|
||||
|
||||
@@ -68,8 +68,6 @@ extern const uint16_t table_7_2_1[16];
|
||||
|
||||
extern dci_pdu_rel15_t *def_dci_pdu_rel15;
|
||||
|
||||
extern dci_pdu_rel15_t *def_dci_pdu_rel15;
|
||||
|
||||
extern void mac_rlc_data_ind(const module_id_t module_idP,
|
||||
const rnti_t rntiP,
|
||||
const eNB_index_t eNB_index,
|
||||
|
||||
@@ -595,7 +595,9 @@ void nr_get_prach_resources(module_id_t mod_id,
|
||||
LOG_D(MAC, "In %s: selected RA preamble index %d for contention-free random access procedure for SSB with Id %d\n", __FUNCTION__, prach_resources->ra_PreambleIndex, cfra_ssb_resource_idx);
|
||||
}
|
||||
} else {
|
||||
int16_t dl_pathloss = get_nr_PL(mod_id, CC_id, gNB_id);
|
||||
/* TODO: This controls the tx_power of UE and the ramping procedure of RA of UE. Later we
|
||||
can abstract this, perhaps in the proxy. But for the time being lets leave it as below. */
|
||||
int16_t dl_pathloss = !get_softmodem_params()->emulate_l1 ? get_nr_PL(mod_id, CC_id, gNB_id) : 0;
|
||||
ssb_rach_config(ra, prach_resources, nr_rach_ConfigCommon, prach_pdu);
|
||||
ra_preambles_config(prach_resources, mac, dl_pathloss);
|
||||
LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-based random access procedure... \n", prach_resources->ra_PreambleIndex);
|
||||
@@ -674,7 +676,8 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
|
||||
|
||||
// Delay init RA procedure to allow the convergence of the IIR filter on PRACH noise measurements at gNB side
|
||||
if (!prach_resources->init_msg1) {
|
||||
if ( (mac->common_configuration_complete>0 || get_softmodem_params()->do_ra==1) && ((MAX_FRAME_NUMBER+frame-prach_resources->sync_frame)%MAX_FRAME_NUMBER)>150 ){
|
||||
if ((mac->common_configuration_complete > 0 || get_softmodem_params()->do_ra || get_softmodem_params()->nsa) &&
|
||||
((MAX_FRAME_NUMBER + frame - prach_resources->sync_frame) % MAX_FRAME_NUMBER) > 150) {
|
||||
prach_resources->init_msg1 = 1;
|
||||
} else {
|
||||
LOG_D(NR_MAC,"PRACH Condition not met: frame %d, prach_resources->sync_frame %d\n",frame,prach_resources->sync_frame);
|
||||
@@ -738,6 +741,30 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
|
||||
pdu -= sh_size;
|
||||
}
|
||||
|
||||
} else if (get_softmodem_params()->nsa) {
|
||||
|
||||
uint8_t mac_sdus[MAX_NR_ULSCH_PAYLOAD_BYTES];
|
||||
uint16_t sdu_lengths[NB_RB_MAX] = {0};
|
||||
int TBS_bytes = 848;
|
||||
int mac_ce_len = 0;
|
||||
int header_length_total=0;
|
||||
unsigned short post_padding = 1;
|
||||
|
||||
// fill ulsch_buffer with random data
|
||||
for (int i = 0; i < TBS_bytes; i++){
|
||||
mac_sdus[i] = (unsigned char) (lrand48()&0xff);
|
||||
}
|
||||
//Sending SDUs with size 1
|
||||
//Initialize elements of sdu_lengths
|
||||
sdu_lengths[0] = TBS_bytes - 3 - post_padding - mac_ce_len;
|
||||
header_length_total += 2 + (sdu_lengths[0] >= 128);
|
||||
size_sdu += sdu_lengths[0];
|
||||
|
||||
if (size_sdu > 0) {
|
||||
memcpy(ra->cont_res_id, mac_sdus, sizeof(uint8_t) * 6);
|
||||
ra->Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
size_sdu = nr_write_ce_ulsch_pdu(pdu, mac, 0, &(mac->crnti), NULL, NULL, NULL);
|
||||
@@ -746,19 +773,20 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
|
||||
|
||||
}
|
||||
|
||||
if (size_sdu > 0 && ra->generate_nr_prach == GENERATE_PREAMBLE) {
|
||||
if (size_sdu > 0 && (ra->generate_nr_prach == GENERATE_PREAMBLE || get_softmodem_params()->nsa)) {
|
||||
|
||||
LOG_D(NR_MAC, "In %s: [UE %d][%d.%d]: starting initialisation Random Access Procedure...\n", __FUNCTION__, mod_id, frame, nr_slot_tx);
|
||||
AssertFatal(TBS_max > ra->Msg3_size, "In %s: allocated resources are not enough for Msg3!\n", __FUNCTION__);
|
||||
|
||||
// Init RA procedure
|
||||
init_RA(mod_id, prach_resources, setup, rach_ConfigGeneric, rach_ConfigDedicated);
|
||||
nr_get_RA_window(mac);
|
||||
// Fill in preamble and PRACH resources
|
||||
nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated);
|
||||
if (ra->generate_nr_prach == GENERATE_PREAMBLE)
|
||||
nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated);
|
||||
|
||||
// Padding: fill remainder with 0
|
||||
if (TBS_max - ra->Msg3_size > 0) {
|
||||
AssertFatal(TBS_max > ra->Msg3_size, "In %s: allocated resources are not enough for Msg3!\n", __FUNCTION__);
|
||||
LOG_D(NR_MAC, "In %s: remaining %d bytes, filling with padding\n", __FUNCTION__, TBS_max - ra->Msg3_size);
|
||||
((NR_MAC_SUBHEADER_FIXED *) pdu)->R = 0;
|
||||
((NR_MAC_SUBHEADER_FIXED *) pdu)->LCID = UL_SCH_LCID_PADDING;
|
||||
@@ -777,8 +805,10 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
|
||||
// Msg3 was initialized with TBS_max bytes because the RA_Msg3_size will only be known after
|
||||
// receiving Msg2 (which contains the Msg3 resource reserve).
|
||||
// Msg3 will be transmitted with RA_Msg3_size bytes, removing unnecessary 0s.
|
||||
mac->ulsch_pdu.Pdu_size = TBS_max;
|
||||
memcpy(mac->ulsch_pdu.payload, payload, TBS_max);
|
||||
if (!get_softmodem_params()->nsa) {
|
||||
mac->ulsch_pdu.Pdu_size = TBS_max;
|
||||
memcpy(mac->ulsch_pdu.payload, payload, TBS_max);
|
||||
}
|
||||
|
||||
} else {
|
||||
return 0;
|
||||
@@ -936,7 +966,7 @@ void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot){
|
||||
|
||||
} else {
|
||||
|
||||
LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CB-RA: Contention Resolution is successful.\n", mod_id, frame, slot);
|
||||
LOG_A(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CB-RA: Contention Resolution is successful.\n", mod_id, frame, slot);
|
||||
|
||||
ra->RA_contention_resolution_timer_active = 0;
|
||||
mac->crnti = ra->t_crnti;
|
||||
|
||||
@@ -428,7 +428,8 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
|
||||
NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon;
|
||||
|
||||
if (pdcch_ConfigCommon &&
|
||||
pdcch_ConfigCommon->choice.setup->searchSpaceSIB1){
|
||||
pdcch_ConfigCommon->choice.setup->searchSpaceSIB1 &&
|
||||
!get_softmodem_params()->nsa) {
|
||||
|
||||
NR_SearchSpace_t *ss0 = mac->search_space_zero;
|
||||
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15;
|
||||
@@ -442,7 +443,7 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // use coreset0/ss0
|
||||
else if (!get_softmodem_params()->nsa) { // use coreset0/ss0
|
||||
NR_SearchSpace_t *ss0 = mac->search_space_zero;
|
||||
if(ss0) {
|
||||
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15;
|
||||
|
||||
@@ -608,7 +608,6 @@ int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_in
|
||||
def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[dci->dci_format];
|
||||
}
|
||||
int8_t ret_proc = nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, def_dci_pdu_rel15, dci);
|
||||
memset(def_dci_pdu_rel15, 0, sizeof(dci_pdu_rel15_t));
|
||||
return ret_proc;
|
||||
}
|
||||
|
||||
@@ -728,6 +727,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
|
||||
LOG_W(MAC, "In %s: ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n", __FUNCTION__, frame, slot);
|
||||
return -1;
|
||||
}
|
||||
ul_config->number_pdus = 0;
|
||||
|
||||
pthread_mutex_lock(&ul_config->mutex_ul_config);
|
||||
AssertFatal(ul_config->number_pdus<FAPI_NR_UL_CONFIG_LIST_NUM, "ul_config->number_pdus %d out of bounds\n",ul_config->number_pdus);
|
||||
@@ -868,7 +868,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
|
||||
|
||||
/* dmrs symbol positions*/
|
||||
dlsch_config_pdu_1_0->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config,
|
||||
mac->mib->dmrs_TypeA_Position,
|
||||
(get_softmodem_params()->nsa) ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position,
|
||||
dlsch_config_pdu_1_0->number_symbols,
|
||||
dlsch_config_pdu_1_0->start_symbol,
|
||||
mappingtype);
|
||||
@@ -1255,6 +1255,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
|
||||
/* TODO same calculation for MCS table as done in UL */
|
||||
dlsch_config_pdu_1_1->mcs_table = (pdsch_Config->mcs_Table) ? (*pdsch_Config->mcs_Table + 1) : 0;
|
||||
/*PTRS configuration */
|
||||
dlsch_config_pdu_1_1->pduBitmap = 0;
|
||||
if(pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS != NULL) {
|
||||
valid_ptrs_setup = set_dl_ptrs_values(pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup,
|
||||
dlsch_config_pdu_1_1->number_rbs, dlsch_config_pdu_1_1->mcs, dlsch_config_pdu_1_1->mcs_table,
|
||||
@@ -1333,8 +1334,10 @@ void set_harq_status(NR_UE_MAC_INST_t *mac,
|
||||
// FIXME k0 != 0 currently not taken into consideration
|
||||
current_harq->dl_frame = frame;
|
||||
current_harq->dl_slot = slot;
|
||||
mac->nr_ue_emul_l1.active_harq_sfn_slot = NFAPI_SFNSLOT2HEX(frame, (slot + data_toul_fb));
|
||||
|
||||
LOG_D(PHY,"Setting harq_status for harq_id %d, dl %d.%d\n",harq_id,frame,slot);
|
||||
LOG_D(NR_PHY,"Setting harq_status for harq_id %d, dl %d.%d, sched ul %d.%d\n",
|
||||
harq_id, frame, slot, frame, (slot + data_toul_fb));
|
||||
}
|
||||
|
||||
|
||||
@@ -2837,7 +2840,7 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
|
||||
// check BWP id
|
||||
if (mac->DLbwp[0]) N_RB=NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
else N_RB=mac->type0_PDCCH_CSS_config.num_rbs;
|
||||
;
|
||||
|
||||
|
||||
// indicating a DL DCI format 1bit
|
||||
pos++;
|
||||
@@ -3331,6 +3334,9 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
||||
mac_subheader_len = 2;
|
||||
}
|
||||
|
||||
AssertFatal(pdu_len > mac_sdu_len, "The mac_sdu_len (%d) has an invalid size. PDU len = %d! \n",
|
||||
mac_sdu_len, pdu_len);
|
||||
|
||||
// Check if it is a valid CCCH message, we get all 00's messages very often
|
||||
int i = 0;
|
||||
for(i=0; i<(mac_subheader_len+mac_sdu_len); i++) {
|
||||
@@ -3496,47 +3502,56 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
||||
case DL_SCH_LCID_DCCH1:
|
||||
// check if LCID is valid at current time.
|
||||
default:
|
||||
// check if LCID is valid at current time.
|
||||
if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
|
||||
//mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
|
||||
mac_subheader_len = 3;
|
||||
mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pduP)->L1 & 0x7f) << 8)
|
||||
| ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pduP)->L2 & 0xff);
|
||||
{
|
||||
// check if LCID is valid at current time.
|
||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
|
||||
return;
|
||||
NR_MAC_SUBHEADER_SHORT *shs = (NR_MAC_SUBHEADER_SHORT *)pduP;
|
||||
if (shs->F) {
|
||||
//mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
|
||||
mac_subheader_len = 3;
|
||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_LONG))
|
||||
return;
|
||||
NR_MAC_SUBHEADER_LONG *shl = (NR_MAC_SUBHEADER_LONG *)pduP;
|
||||
mac_sdu_len = ((uint16_t)(shl->L1 & 0x7f) << 8) | (uint16_t)(shl->L2 & 0xff);
|
||||
} else {
|
||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
|
||||
return;
|
||||
mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
|
||||
mac_subheader_len = 2;
|
||||
}
|
||||
|
||||
} else {
|
||||
mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
|
||||
mac_subheader_len = 2;
|
||||
}
|
||||
LOG_D(NR_MAC, "[UE %d] Frame %d : DLSCH -> DL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, gNB_index, mac_sdu_len);
|
||||
|
||||
LOG_D(MAC, "[UE %d] Frame %d : DLSCH -> DL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, gNB_index, mac_sdu_len);
|
||||
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
|
||||
LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP);
|
||||
|
||||
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
|
||||
LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP);
|
||||
for (i = 0; i < 32; i++)
|
||||
LOG_T(MAC, "%x.", (pduP + mac_subheader_len)[i]);
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
LOG_T(MAC, "%x.", (pduP + mac_subheader_len)[i]);
|
||||
LOG_T(MAC, "\n");
|
||||
#endif
|
||||
|
||||
LOG_T(MAC, "\n");
|
||||
#endif
|
||||
if (rx_lcid < NB_RB_MAX && rx_lcid >= DL_SCH_LCID_DCCH) {
|
||||
|
||||
if (rx_lcid < NB_RB_MAX && rx_lcid >= DL_SCH_LCID_DCCH) {
|
||||
mac_rlc_data_ind(module_idP,
|
||||
mac->crnti,
|
||||
gNB_index,
|
||||
frameP,
|
||||
ENB_FLAG_NO,
|
||||
MBMS_FLAG_NO,
|
||||
rx_lcid,
|
||||
(char *) (pduP + mac_subheader_len),
|
||||
mac_sdu_len,
|
||||
1,
|
||||
NULL);
|
||||
} else {
|
||||
LOG_E(MAC, "[UE %d] Frame %d : unknown LCID %d (gNB %d)\n", module_idP, frameP, rx_lcid, gNB_index);
|
||||
}
|
||||
|
||||
mac_rlc_data_ind(module_idP,
|
||||
mac->crnti,
|
||||
gNB_index,
|
||||
frameP,
|
||||
ENB_FLAG_NO,
|
||||
MBMS_FLAG_NO,
|
||||
rx_lcid,
|
||||
(char *) (pduP + mac_subheader_len),
|
||||
mac_sdu_len,
|
||||
1,
|
||||
NULL);
|
||||
} else {
|
||||
LOG_E(MAC, "[UE %d] Frame %d : unknown LCID %d (gNB %d)\n", module_idP, frameP, rx_lcid, gNB_index);
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pduP += ( mac_subheader_len + mac_ce_len + mac_sdu_len );
|
||||
pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len );
|
||||
@@ -3791,7 +3806,7 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t
|
||||
}
|
||||
}
|
||||
if (rarh->RAPID == preamble_index) {
|
||||
LOG_I(NR_MAC, "[UE %d][RAPROC][%d.%d] Found RAR with the intended RAPID %d\n", mod_id, frame, slot, rarh->RAPID);
|
||||
LOG_A(NR_MAC, "[UE %d][RAPROC][%d.%d] Found RAR with the intended RAPID %d\n", mod_id, frame, slot, rarh->RAPID);
|
||||
rar = (NR_MAC_RAR *) (dlsch_buffer + n_subheaders + (n_subPDUs - 1) * sizeof(NR_MAC_RAR));
|
||||
ra->RA_RAPID_found = 1;
|
||||
break;
|
||||
@@ -3908,6 +3923,8 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t
|
||||
LOG_W(MAC, "In %s: ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n", __FUNCTION__, frame, slot);
|
||||
return -1;
|
||||
}
|
||||
AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]),
|
||||
"Number of PDUS in ul_config = %d > ul_config_list num elements", ul_config->number_pdus);
|
||||
|
||||
// Upon successful reception, set the T-CRNTI to the RAR value if the RA preamble is selected among the contention-based RA Preambles
|
||||
if (!ra->cfra) {
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "assertions.h"
|
||||
#include "asn1_conversions.h"
|
||||
#include "SIMULATION/TOOLS/sim.h" // for taus
|
||||
#include "utils.h"
|
||||
|
||||
#include <executables/softmodem-common.h>
|
||||
|
||||
@@ -62,8 +63,13 @@ static prach_association_pattern_t prach_assoc_pattern;
|
||||
static ssb_list_info_t ssb_list;
|
||||
|
||||
void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type){
|
||||
|
||||
AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]),
|
||||
"Number of PDUS in ul_config = %d > ul_config_list num elements", ul_config->number_pdus);
|
||||
// clear ul_config for new frame/slot
|
||||
if ((ul_config->slot != slot_tx || ul_config->sfn != frame_tx) && ul_config->number_pdus != 0) {
|
||||
if ((ul_config->slot != slot_tx || ul_config->sfn != frame_tx) &&
|
||||
ul_config->number_pdus != 0 &&
|
||||
!get_softmodem_params()->emulate_l1) {
|
||||
LOG_D(MAC, "%d.%d %d.%d f clear ul_config %p t %d pdu %d\n", frame_tx, slot_tx, ul_config->sfn, ul_config->slot, ul_config, pdu_type, ul_config->number_pdus);
|
||||
ul_config->number_pdus = 0;
|
||||
memset(ul_config->ul_config_list, 0, sizeof(ul_config->ul_config_list));
|
||||
@@ -168,6 +174,8 @@ fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int sl
|
||||
num_slots_ul,
|
||||
index);
|
||||
|
||||
if(!mac->ul_config_request)
|
||||
return NULL;
|
||||
return &mac->ul_config_request[index];
|
||||
}
|
||||
|
||||
@@ -1041,6 +1049,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
dcireq.slot = rx_slot;
|
||||
dcireq.dl_config_req.number_pdus = 0;
|
||||
nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
|
||||
mac->dl_config_request = dcireq.dl_config_req;
|
||||
|
||||
fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id);
|
||||
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
|
||||
@@ -1077,6 +1086,9 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
RA_config_t *ra = &mac->ra;
|
||||
|
||||
fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx);
|
||||
if (!ul_config) {
|
||||
LOG_E(NR_MAC, "mac->ul_config is null!\n");
|
||||
}
|
||||
|
||||
// Periodic SRS scheduling
|
||||
nr_ue_periodic_srs_scheduling(mod_id, frame_tx, slot_tx);
|
||||
@@ -1151,7 +1163,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->gNB_index);
|
||||
}
|
||||
if (ra->ra_state == WAIT_RAR && !ra->cfra){
|
||||
LOG_I(NR_MAC,"[RAPROC][%d.%d] RA-Msg3 transmitted\n", frame_tx, slot_tx);
|
||||
LOG_A(NR_MAC, "[RAPROC][%d.%d] RA-Msg3 transmitted\n", frame_tx, slot_tx);
|
||||
nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->gNB_index);
|
||||
}
|
||||
}
|
||||
@@ -2329,9 +2341,12 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
|
||||
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
|
||||
RA_config_t *ra = &mac->ra;
|
||||
fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP);
|
||||
if (!ul_config) {
|
||||
LOG_E(NR_MAC, "mac->ul_config is null! \n");
|
||||
return;
|
||||
}
|
||||
|
||||
//fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP);
|
||||
fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request[0];
|
||||
fapi_nr_ul_config_prach_pdu *prach_config_pdu;
|
||||
fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
|
||||
fapi_nr_prach_config_t *prach_config = &cfg->prach_config;
|
||||
@@ -2368,11 +2383,13 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
|
||||
format = prach_occasion_info_p->format;
|
||||
format0 = format & 0xff; // single PRACH format
|
||||
format1 = (format >> 8) & 0xff; // dual PRACH format
|
||||
AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]),
|
||||
"Number of PDUS in ul_config = %d > ul_config_list num elements", ul_config->number_pdus);
|
||||
|
||||
pthread_mutex_lock(&ul_config->mutex_ul_config);
|
||||
AssertFatal(ul_config->number_pdus<FAPI_NR_UL_CONFIG_LIST_NUM, "ul_config->number_pdus %d out of bounds\n",ul_config->number_pdus);
|
||||
prach_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu;
|
||||
|
||||
memset(prach_config_pdu, 0, sizeof(fapi_nr_ul_config_prach_pdu));
|
||||
fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PRACH);
|
||||
pthread_mutex_unlock(&ul_config->mutex_ul_config);
|
||||
LOG_D(PHY, "In %s: (%p) %d UL PDUs:\n", __FUNCTION__, ul_config, ul_config->number_pdus);
|
||||
|
||||
@@ -519,10 +519,16 @@ void nr_initiate_ra_proc(module_id_t module_idP,
|
||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
||||
NR_RA_t *ra = &cc->ra[i];
|
||||
pr_found = 0;
|
||||
const int UE_id = find_nr_UE_id(module_idP, ra->rnti);
|
||||
if (UE_id != -1) {
|
||||
continue;
|
||||
}
|
||||
if (ra->state == RA_IDLE) {
|
||||
for(int j = 0; j < ra->preambles.num_preambles; j++) {
|
||||
//check if the preamble received correspond to one of the listed or configured preambles
|
||||
if (preamble_index == ra->preambles.preamble_list[j]) {
|
||||
if (ra->rnti == 0 && get_softmodem_params()->nsa)
|
||||
continue;
|
||||
pr_found=1;
|
||||
break;
|
||||
}
|
||||
@@ -636,16 +642,17 @@ void nr_initiate_ra_proc(module_id_t module_idP,
|
||||
ra->preamble_index = preamble_index;
|
||||
ra->beam_id = beam_index;
|
||||
|
||||
LOG_D(NR_MAC,
|
||||
LOG_I(NR_MAC,
|
||||
"[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB "
|
||||
"index %u\n",
|
||||
"index %u RA index %d\n",
|
||||
module_idP,
|
||||
CC_id,
|
||||
frameP,
|
||||
ra->Msg2_frame,
|
||||
ra->Msg2_slot,
|
||||
ra->RA_rnti,
|
||||
cc->ssb_index[beam_index]);
|
||||
cc->ssb_index[beam_index],
|
||||
i);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1229,7 +1236,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
dl_req->nPDUs+=1;
|
||||
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
|
||||
|
||||
LOG_I(NR_MAC,"[gNB %d][RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg2 DCI, rnti 0x%04x, state %d, CoreSetType %d\n",
|
||||
LOG_A(NR_MAC,"[gNB %d][RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg2 DCI, rnti 0x%x, state %d, CoreSetType %d\n",
|
||||
module_idP, CC_id, frameP, slotP, ra->RA_rnti, ra->state,pdcch_pdu_rel15->CoreSetType);
|
||||
|
||||
// SCF222: PDU index incremented for each PDSCH PDU sent in TX control message. This is used to associate control
|
||||
@@ -1624,7 +1631,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
dl_req->nPDUs+=1;
|
||||
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
|
||||
|
||||
LOG_I(NR_MAC,"[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg4 DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state);
|
||||
LOG_A(NR_MAC, "[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg4 DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state);
|
||||
|
||||
// SCF222: PDU index incremented for each PDSCH PDU sent in TX control message. This is used to associate control
|
||||
// information to data and is reset every slot.
|
||||
@@ -1809,7 +1816,7 @@ void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_fram
|
||||
if (harq->is_waiting == 0) {
|
||||
if (harq->round == 0) {
|
||||
if (stats->dlsch_errors == 0) {
|
||||
LOG_I(NR_MAC, "(ue %i, rnti 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", UE_id, ra->rnti);
|
||||
LOG_A(NR_MAC, "(ue %i, rnti 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", UE_id, ra->rnti);
|
||||
UE_info->active[UE_id] = true;
|
||||
UE_info->Msg4_ACKed[UE_id] = true;
|
||||
}
|
||||
|
||||
@@ -741,6 +741,11 @@ void pf_dl(module_id_t module_id,
|
||||
const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth,MAX_BWP_SIZE);
|
||||
int rbStart = 0; // start wrt BWPstart
|
||||
|
||||
if (sched_ctrl->available_dl_harq.head < 0) {
|
||||
LOG_D(MAC, "UE %d RNTI %04x has no free HARQ process, skipping\n", UE_id, UE_info->rnti[UE_id]);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Find a free CCE */
|
||||
bool freeCCE = find_free_CCE(module_id, slot, UE_id);
|
||||
if (!freeCCE) {
|
||||
@@ -851,7 +856,7 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
frame,
|
||||
slot,
|
||||
&UE_info->list,
|
||||
2,
|
||||
MAX_MOBILES_PER_GNB,
|
||||
n_rb_sched,
|
||||
rballoc_mask);
|
||||
}
|
||||
@@ -997,6 +1002,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
const int coresetid = (bwp||bwpd) ? sched_ctrl->coreset->controlResourceSetId : gNB_mac->sched_ctrlCommon->coreset->controlResourceSetId;
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu = gNB_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid];
|
||||
if (!pdcch_pdu) {
|
||||
LOG_D(NR_MAC, "creating pdcch pdu, pdcch_pdu = NULL. \n");
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
|
||||
memset(dl_tti_pdcch_pdu, 0, sizeof(nfapi_nr_dl_tti_request_pdu_t));
|
||||
dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
|
||||
|
||||
@@ -292,7 +292,7 @@ uint8_t compute_ri_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
}
|
||||
return max_ri;
|
||||
}
|
||||
else
|
||||
else
|
||||
AssertFatal(1==0,"Other configurations not yet implemented\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -563,6 +563,7 @@ void nr_csi_meas_reporting(int Mod_idP,
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((unused))
|
||||
static void handle_dl_harq(module_id_t mod_id,
|
||||
int UE_id,
|
||||
int8_t harq_pid,
|
||||
@@ -1094,8 +1095,10 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
|
||||
const uint8_t harq_value = uci_01->harq->harq_list[harq_bit].harq_value;
|
||||
const uint8_t harq_confidence = uci_01->harq->harq_confidence_level;
|
||||
NR_UE_harq_t *harq = find_harq(mod_id, frame, slot, UE_id);
|
||||
if (!harq)
|
||||
if (!harq) {
|
||||
LOG_E(NR_MAC, "Oh no! Could not find a harq in %s!\n", __FUNCTION__);
|
||||
break;
|
||||
}
|
||||
DevAssert(harq->is_waiting);
|
||||
const int8_t pid = sched_ctrl->feedback_dl_harq.head;
|
||||
remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
|
||||
@@ -1416,6 +1419,7 @@ int nr_acknack_scheduling(int mod_id,
|
||||
/* verify that at that slot and symbol, resources are free. We only do this
|
||||
* for initialCyclicShift 0 (we assume it always has that one), so other
|
||||
* initialCyclicShifts can overlap with ICS 0!*/
|
||||
|
||||
if (pucch_Config) {
|
||||
const NR_PUCCH_Resource_t *resource = pucch_Config->resourceToAddModList->list.array[pucch->resource_indicator];
|
||||
DevAssert(resource->format.present == NR_PUCCH_Resource__format_PR_format0);
|
||||
@@ -1464,8 +1468,11 @@ void nr_sr_reporting(int Mod_idP, frame_t SFN, sub_frame_t slot)
|
||||
RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) {
|
||||
pucch_Config = RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup;
|
||||
}
|
||||
|
||||
else continue;
|
||||
if (!pucch_Config->schedulingRequestResourceToAddModList) continue;
|
||||
if (!pucch_Config->schedulingRequestResourceToAddModList)
|
||||
continue;
|
||||
|
||||
AssertFatal(pucch_Config->schedulingRequestResourceToAddModList->list.count>0,"NO SR configuration available");
|
||||
|
||||
for (int SR_resource_id =0; SR_resource_id < pucch_Config->schedulingRequestResourceToAddModList->list.count;SR_resource_id++) {
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include "utils.h"
|
||||
#include <openair2/UTIL/OPT/opt.h>
|
||||
|
||||
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
|
||||
@@ -565,6 +566,7 @@ void handle_nr_ul_harq(const int CC_idP,
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
int8_t harq_pid = sched_ctrl->feedback_ul_harq.head;
|
||||
LOG_D(NR_MAC, "Comparing crc_pdu->harq_id vs feedback harq_pid = %d %d\n",crc_pdu->harq_id, harq_pid);
|
||||
while (crc_pdu->harq_id != harq_pid || harq_pid < 0) {
|
||||
LOG_W(NR_MAC,
|
||||
"Unexpected ULSCH HARQ PID %d (have %d) for RNTI 0x%04x (ignore this warning for RA)\n",
|
||||
@@ -800,14 +802,14 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
LOG_D(NR_MAC, "[UE %d] PUSCH TPC %d and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update);
|
||||
if(ra->cfra) {
|
||||
|
||||
LOG_I(NR_MAC, "(ue %i, rnti 0x%04x) CFRA procedure succeeded!\n", UE_id, ra->rnti);
|
||||
LOG_A(NR_MAC, "(ue %i, rnti 0x%04x) CFRA procedure succeeded!\n", UE_id, ra->rnti);
|
||||
nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
|
||||
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
|
||||
UE_info->active[UE_id] = true;
|
||||
|
||||
} else {
|
||||
|
||||
LOG_I(NR_MAC,"[RAPROC] RA-Msg3 received (sdu_lenP %d)\n",sdu_lenP);
|
||||
LOG_A(NR_MAC,"[RAPROC] RA-Msg3 received (sdu_lenP %d)\n",sdu_lenP);
|
||||
LOG_D(NR_MAC,"[RAPROC] Received Msg3:\n");
|
||||
for (int k = 0; k < sdu_lenP; k++) {
|
||||
LOG_D(NR_MAC,"(%i): 0x%x\n",k,sduP[k]);
|
||||
@@ -1500,6 +1502,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static;
|
||||
|
||||
/* Statistics */
|
||||
AssertFatal(cur_harq->round < 8, "Indexing ulsch_rounds[%d] is out of bounds\n", cur_harq->round);
|
||||
UE_info->mac_stats[UE_id].ulsch_rounds[cur_harq->round]++;
|
||||
if (cur_harq->round == 0) {
|
||||
UE_info->mac_stats[UE_id].ulsch_total_bytes_scheduled += sched_pusch->tb_size;
|
||||
@@ -1633,6 +1636,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
pusch_pdu->nr_of_symbols = ps->nrOfSymbols;
|
||||
|
||||
/* PUSCH PDU */
|
||||
AssertFatal(cur_harq->round < 4, "Indexing nr_rv_round_map[%d] is out of bounds\n", cur_harq->round);
|
||||
pusch_pdu->pusch_data.rv_index = nr_rv_round_map[cur_harq->round];
|
||||
pusch_pdu->pusch_data.harq_process_id = harq_id;
|
||||
pusch_pdu->pusch_data.new_data_indicator = cur_harq->ndi;
|
||||
|
||||
@@ -140,6 +140,36 @@ extern volatile int oai_exit;
|
||||
|
||||
pthread_t pdcp_stats_thread_desc;
|
||||
|
||||
// will be called when 4G F1 implementation will use GTP-U instead of protobuf
|
||||
boolean_t cu_f1u_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,
|
||||
const uint32_t *const sourceL2Id,
|
||||
const uint32_t *const destinationL2Id
|
||||
) {
|
||||
mem_block_t *memblock = get_free_mem_block(sdu_buffer_size, __func__);
|
||||
if (memblock == NULL) {
|
||||
LOG_E(RLC, "%s:%d:%s: ERROR: get_free_mem_block failed\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
memcpy(memblock->data,sdu_buffer, sdu_buffer_size);
|
||||
// weird rb id management in 4G, not fully understand (looks bad design)
|
||||
// overcomplex: if i understand, on the interface DRB start at 4 because there can be SRB 0..3
|
||||
// but it would be much simpler to use absolute numbering
|
||||
// instead of this "srb flag" associated to these +/-4
|
||||
int ret=pdcp_data_ind(ctxt_pP,srb_flagP, false, rb_id-4, sdu_buffer_size, memblock, NULL, NULL);
|
||||
if (!ret) {
|
||||
LOG_E(RLC, "%s:%d:%s: ERROR: pdcp_data_ind failed\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
/* what to do in case of failure? for the moment: nothing */
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
void *pdcp_stats_thread(void *param) {
|
||||
|
||||
FILE *fd;
|
||||
@@ -176,6 +206,33 @@ void *pdcp_stats_thread(void *param) {
|
||||
uint64_t get_pdcp_optmask(void) {
|
||||
return pdcp_params.optmask;
|
||||
}
|
||||
|
||||
rlc_op_status_t cu_send_to_du(const protocol_ctxt_t *const ctxt,
|
||||
const srb_flag_t srb_flag, const MBMS_flag_t MBMS_flag,
|
||||
const rb_id_t rb_id, const mui_t mui,
|
||||
confirm_t confirm, sdu_size_t size, mem_block_t *sdu,
|
||||
const uint32_t *const sourceID, const uint32_t *const destID) {
|
||||
uint8_t *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,
|
||||
sdu->data,
|
||||
size );
|
||||
MessageDef *message_p = itti_alloc_new_message(TASK_PDCP_ENB, 0, GTPV1U_ENB_TUNNEL_DATA_REQ);
|
||||
AssertFatal(message_p != NULL, "OUT OF MEMORY");
|
||||
gtpv1u_enb_tunnel_data_req_t *req=>PV1U_ENB_TUNNEL_DATA_REQ(message_p);
|
||||
req->buffer = gtpu_buffer_p;
|
||||
req->length = size;
|
||||
req->offset = GTPU_HEADER_OVERHEAD_MAX;
|
||||
req->rnti = ctxt->rnti;
|
||||
req->rab_id = rb_id+4;
|
||||
LOG_D(PDCP, "%s() (drb %ld) sending message to gtp size %d\n",
|
||||
__func__, rb_id, size);
|
||||
extern instance_t CUuniqInstance;
|
||||
itti_send_msg_to_task(TASK_VARIABLE, CUuniqInstance, message_p);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/*
|
||||
* If PDCP_UNIT_TEST is set here then data flow between PDCP and RLC is broken
|
||||
@@ -249,12 +306,8 @@ boolean_t pdcp_data_req(
|
||||
LOG_W(PDCP, PROTOCOL_CTXT_FMT" Instance is not configured for rb_id %ld Ignoring SDU...\n",
|
||||
PROTOCOL_CTXT_ARGS(ctxt_pP),
|
||||
rb_idP);
|
||||
ctxt_pP->configured=FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
// instance for a given RB is configured
|
||||
ctxt_pP->configured=TRUE;
|
||||
}
|
||||
|
||||
if (ctxt_pP->enb_flag == ENB_FLAG_YES) {
|
||||
@@ -575,7 +628,9 @@ pdcp_data_ind(
|
||||
const MBMS_flag_t MBMS_flagP,
|
||||
const rb_id_t rb_idP,
|
||||
const sdu_size_t sdu_buffer_sizeP,
|
||||
mem_block_t *const sdu_buffer_pP
|
||||
mem_block_t *const sdu_buffer_pP,
|
||||
const uint32_t *const srcID,
|
||||
const uint32_t *const dstID
|
||||
)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
@@ -1072,7 +1127,7 @@ pdcp_data_ind(
|
||||
* for the UE compiled in noS1 mode, we need 0
|
||||
* TODO: be sure of this
|
||||
*/
|
||||
if (NFAPI_MODE == NFAPI_UE_STUB_PNF ) {
|
||||
if (NFAPI_MODE == NFAPI_UE_STUB_PNF || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) {
|
||||
pdcpHead->inst = ctxt_pP->module_id;
|
||||
} else { // nfapi_mode
|
||||
if (UE_NAS_USE_TUN) {
|
||||
@@ -1288,7 +1343,7 @@ pdcp_run (
|
||||
|
||||
// IP/NAS -> PDCP traffic : TX, read the pkt from the upper layer buffer
|
||||
// if (LINK_ENB_PDCP_TO_GTPV1U && ctxt_pP->enb_flag == ENB_FLAG_NO) {
|
||||
if (!EPC_MODE_ENABLED || ctxt_pP->enb_flag == ENB_FLAG_NO ) {
|
||||
if (!get_softmodem_params()->emulate_l1 && (!EPC_MODE_ENABLED || ctxt_pP->enb_flag == ENB_FLAG_NO)) {
|
||||
pdcp_fifo_read_input_sdus(ctxt_pP);
|
||||
}
|
||||
|
||||
@@ -1298,8 +1353,9 @@ pdcp_run (
|
||||
} else {
|
||||
start_meas(&UE_pdcp_stats[ctxt_pP->module_id].pdcp_ip);
|
||||
}
|
||||
|
||||
pdcp_fifo_flush_sdus(ctxt_pP);
|
||||
if (!get_softmodem_params()->emulate_l1) {
|
||||
pdcp_fifo_flush_sdus(ctxt_pP);
|
||||
}
|
||||
|
||||
if (ctxt_pP->enb_flag) {
|
||||
stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].pdcp_ip);
|
||||
@@ -1491,7 +1547,7 @@ void pdcp_add_UE(const protocol_ctxt_t *const ctxt_pP) {
|
||||
pdcp_enb[ctxt_pP->module_id].rnti[i]=ctxt_pP->rnti;
|
||||
pdcp_enb[ctxt_pP->module_id].uid[i]=i;
|
||||
pdcp_enb[ctxt_pP->module_id].num_ues++;
|
||||
printf("add new uid is %d %x\n\n", i, ctxt_pP->rnti);
|
||||
LOG_I(PDCP,"add new uid is %d %x\n", i, ctxt_pP->rnti);
|
||||
pdcp_init_stats_UE(ctxt_pP->module_id, i);
|
||||
// ret=1;
|
||||
break;
|
||||
@@ -2342,7 +2398,7 @@ void pdcp_set_pdcp_data_ind_func(pdcp_data_ind_func_t pdcp_data_ind) {
|
||||
pdcp_params.pdcp_data_ind_func = pdcp_data_ind;
|
||||
}
|
||||
|
||||
uint64_t pdcp_module_init( uint64_t pdcp_optmask ) {
|
||||
uint64_t pdcp_module_init( uint64_t pdcp_optmask, int id) {
|
||||
/* temporary enforce netlink when UE_NAS_USE_TUN is set,
|
||||
this is while switching from noS1 as build option
|
||||
to noS1 as config option */
|
||||
@@ -2359,18 +2415,18 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) {
|
||||
nas_getparams();
|
||||
|
||||
if(UE_NAS_USE_TUN) {
|
||||
int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )? MAX_MOBILES_PER_ENB : 1;
|
||||
netlink_init_tun("ue",num_if);
|
||||
int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF)? MAX_MOBILES_PER_ENB : 1;
|
||||
netlink_init_tun("ue",num_if, id);
|
||||
if (IS_SOFTMODEM_NOS1)
|
||||
nas_config(1, 1, 2, "ue");
|
||||
netlink_init_mbms_tun("uem");
|
||||
nas_config(1, 1, 2, "ue");
|
||||
netlink_init_mbms_tun("uem", id);
|
||||
nas_config_mbms(1, 2, 2, "uem");
|
||||
LOG_I(PDCP, "UE pdcp will use tun interface\n");
|
||||
} else if(ENB_NAS_USE_TUN) {
|
||||
netlink_init_tun("enb",1);
|
||||
netlink_init_tun("enb", 1, 0);
|
||||
nas_config(1, 1, 1, "enb");
|
||||
if(pdcp_optmask & ENB_NAS_USE_TUN_W_MBMS_BIT){
|
||||
netlink_init_mbms_tun("enm");
|
||||
netlink_init_mbms_tun("enm", 0);
|
||||
nas_config_mbms(1, 2, 1, "enm");
|
||||
LOG_I(PDCP, "ENB pdcp will use mbms tun interface\n");
|
||||
}
|
||||
@@ -2382,8 +2438,8 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) {
|
||||
}else{
|
||||
if(pdcp_optmask & ENB_NAS_USE_TUN_W_MBMS_BIT){
|
||||
LOG_W(PDCP, "ENB pdcp will use tun interface for MBMS\n");
|
||||
netlink_init_mbms_tun("enm");
|
||||
nas_config_mbms_s1(1, 2, 1, "enm");
|
||||
netlink_init_mbms_tun("enm", 0);
|
||||
nas_config_mbms_s1(1, 2, 1, "enm");
|
||||
}else
|
||||
LOG_E(PDCP, "ENB pdcp will not use tun interface\n");
|
||||
}
|
||||
@@ -2425,6 +2481,7 @@ pdcp_free (
|
||||
void pdcp_module_cleanup (void)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
netlink_cleanup();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -47,13 +47,16 @@
|
||||
|
||||
|
||||
typedef rlc_op_status_t (*send_rlc_data_req_func_t)(const protocol_ctxt_t *const,
|
||||
const srb_flag_t, const MBMS_flag_t,
|
||||
const rb_id_t, const mui_t,
|
||||
const srb_flag_t, const MBMS_flag_t,
|
||||
const rb_id_t, const mui_t,
|
||||
confirm_t, sdu_size_t, mem_block_t *,const uint32_t *const, const uint32_t *const);
|
||||
typedef boolean_t (*pdcp_data_ind_func_t)( const protocol_ctxt_t *, const srb_flag_t,
|
||||
const MBMS_flag_t, const rb_id_t, const sdu_size_t,
|
||||
mem_block_t *,const uint32_t *const, const uint32_t *const);
|
||||
|
||||
typedef boolean_t (pdcp_data_ind_t)( const protocol_ctxt_t *, const srb_flag_t,
|
||||
const MBMS_flag_t, const rb_id_t, const sdu_size_t,
|
||||
mem_block_t *,const uint32_t *const, const uint32_t *const);
|
||||
typedef pdcp_data_ind_t* pdcp_data_ind_func_t;
|
||||
|
||||
#define MAX_NUMBER_NETIF 1 //16
|
||||
#define ENB_NAS_USE_TUN_W_MBMS_BIT (1<< 10)
|
||||
#define PDCP_USE_NETLINK_BIT (1<< 11)
|
||||
#define LINK_ENB_PDCP_TO_IP_DRIVER_BIT (1<< 13)
|
||||
@@ -254,6 +257,19 @@ boolean_t pdcp_data_req(
|
||||
const uint32_t * destinationL2Id
|
||||
);
|
||||
|
||||
boolean_t cu_f1u_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,
|
||||
const uint32_t *const sourceL2Id,
|
||||
const uint32_t *const destinationL2Id
|
||||
);
|
||||
|
||||
/*! \fn boolean_t pdcp_data_ind(const protocol_ctxt_t* const, srb_flag_t, MBMS_flag_t, rb_id_t, sdu_size_t, mem_block_t*, boolean_t)
|
||||
* \brief This functions handles data transfer indications coming from RLC
|
||||
* \param[in] ctxt_pP Running context.
|
||||
@@ -267,13 +283,7 @@ boolean_t pdcp_data_req(
|
||||
* \note None
|
||||
* @ingroup _pdcp
|
||||
*/
|
||||
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);
|
||||
pdcp_data_ind_t pdcp_data_ind;
|
||||
|
||||
/*! \fn void rrc_pdcp_config_req(const protocol_ctxt_t* const ,uint32_t,rb_id_t,uint8_t)
|
||||
* \brief This functions initializes relevant PDCP entity
|
||||
@@ -401,7 +411,8 @@ void pdcp_mbms_run (
|
||||
*/
|
||||
void pdcp_run (
|
||||
const protocol_ctxt_t *const ctxt_pP);
|
||||
uint64_t pdcp_module_init (uint64_t pdcp_optmask);
|
||||
uint64_t pdcp_module_init (uint64_t pdcp_optmask, int ue_id);
|
||||
uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id);
|
||||
void pdcp_module_cleanup (void);
|
||||
void nr_ip_over_LTE_DRB_preconfiguration (void);
|
||||
void pdcp_layer_init (void);
|
||||
@@ -419,7 +430,10 @@ pdcp_data_ind_func_t get_pdcp_data_ind_func(void);
|
||||
//-----------------------------------------------------------------------------
|
||||
int pdcp_fifo_flush_mbms_sdus ( const protocol_ctxt_t *const ctxt_pP);
|
||||
int pdcp_fifo_read_input_mbms_sdus_fromtun ( const protocol_ctxt_t *const ctxt_pP);
|
||||
|
||||
rlc_op_status_t cu_send_to_du(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, const uint32_t *const, const uint32_t *const);
|
||||
|
||||
/*
|
||||
* Following two types are utilized between NAS driver and PDCP
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
pdcp_control_primitives.c
|
||||
-------------------
|
||||
begin : Mon Dec 10 2001
|
||||
email : Lionel.Gauthier@eurecom.fr
|
||||
-------------------
|
||||
description
|
||||
This file contains the functions used for configuration of pdcp
|
||||
|
||||
***************************************************************************/
|
||||
#include "rtos_header.h"
|
||||
#include "platform.h"
|
||||
#include "protocol_vars_extern.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "rlc.h"
|
||||
#include "pdcp.h"
|
||||
#include "debug_l2.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
configure_pdcp_req (struct pdcp_entity *pdcpP, void *rlcP, uint8_t rlc_sap_typeP, uint8_t header_compression_typeP)
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
mem_block *mb;
|
||||
|
||||
mb = get_free_mem_block (sizeof (struct cpdcp_primitive), __func__);
|
||||
if(mb==NULL) return;
|
||||
((struct cpdcp_primitive *) mb->data)->type = CPDCP_CONFIG_REQ;
|
||||
((struct cpdcp_primitive *) mb->data)->primitive.config_req.rlc_sap = rlcP;
|
||||
((struct cpdcp_primitive *) mb->data)->primitive.config_req.rlc_type_sap = rlc_sap_typeP;
|
||||
((struct cpdcp_primitive *) mb->data)->primitive.config_req.header_compression_type = header_compression_typeP;
|
||||
send_pdcp_control_primitive (pdcpP, mb);
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
pdcp_control_primitives_proto_extern.h
|
||||
-------------------
|
||||
begin : Mon Dec 10 2001
|
||||
email : Lionel.Gauthier@eurecom.fr
|
||||
-------------------
|
||||
description
|
||||
This file contains the prototypes of functions used for configuration of pdcp
|
||||
|
||||
***************************************************************************/
|
||||
#ifndef PDCP_CONTROL_PRIMITIVES_PROTO_EXTERN_H
|
||||
# define PDCP_CONTROL_PRIMITIVES_PROTO_EXTERN_H
|
||||
# include "pdcp.h"
|
||||
void rrc_configure_pdcp (struct pdcp_entity *pdcpP, void *rlcP, uint8_t rlc_sap_typeP, uint8_t header_compression_typeP);
|
||||
#endif
|
||||
@@ -89,7 +89,7 @@ extern struct msghdr nas_msg_rx;
|
||||
|
||||
|
||||
extern int gtpv1u_new_data_req( uint8_t enb_module_idP, rnti_t ue_rntiP, uint8_t rab_idP, uint8_t *buffer_pP, uint32_t buf_lenP, uint32_t buf_offsetP);
|
||||
|
||||
uint16_t ue_id_g; // Global variable to identify the ID for each UE. It is updated in main() of lte-uesoftmodem.c
|
||||
|
||||
void debug_pdcp_pc5s_sdu(sidelink_pc5s_element *sl_pc5s_msg, char *title) {
|
||||
LOG_I(PDCP,"%s: \nPC5S message, header traffic_type: %d)\n", title, sl_pc5s_msg->pc5s_header.traffic_type);
|
||||
@@ -210,14 +210,46 @@ int pdcp_fifo_read_input_sdus_fromtun (const protocol_ctxt_t *const ctxt_pP) {
|
||||
pdcp_t *pdcp_p = NULL;
|
||||
int len;
|
||||
rb_id_t rab_id = DEFAULT_RAB_ID;
|
||||
int sockd;
|
||||
|
||||
do {
|
||||
if (UE_NAS_USE_TUN) {
|
||||
if (ue_id_g == 0) {
|
||||
sockd = nas_sock_fd[ctxt_pP->module_id];
|
||||
}
|
||||
else {
|
||||
sockd = nas_sock_fd[ue_id_g];
|
||||
}
|
||||
}
|
||||
else {
|
||||
sockd = nas_sock_fd[0];
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 1 );
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 1 );
|
||||
len = read(UE_NAS_USE_TUN?nas_sock_fd[ctxt_pP->module_id]:nas_sock_fd[0], &nl_rx_buf, NL_MAX_PAYLOAD);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 0 );
|
||||
len = read(sockd, &nl_rx_buf, NL_MAX_PAYLOAD);
|
||||
|
||||
if (len<=0) continue;
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 0 );
|
||||
if (len == -1) {
|
||||
if (errno == EAGAIN) {
|
||||
LOG_D(PDCP, "Error reading NAS socket: %s\n", strerror(errno));
|
||||
}
|
||||
else {
|
||||
LOG_E(PDCP, "Error reading NAS socket: %s\n", strerror(errno));
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* Check for message truncation. Strictly speaking if the packet is exactly sizeof(nl_rx_buf) bytes
|
||||
that would not be an error. But we cannot distinguish that from a packet > sizeof(nl_rx_buf) */
|
||||
if (len == sizeof(nl_rx_buf))
|
||||
{
|
||||
LOG_E(PDCP, "%s(%d). Message truncated %d\n", __FUNCTION__, __LINE__, len);
|
||||
break;
|
||||
}
|
||||
if (len == 0) {
|
||||
LOG_E(PDCP, "EOF Reading NAS socket\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (UE_NAS_USE_TUN) {
|
||||
key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
|
||||
@@ -263,7 +295,7 @@ int pdcp_fifo_read_input_sdus_fromtun (const protocol_ctxt_t *const ctxt_pP) {
|
||||
ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id,
|
||||
ctxt.rnti, rab_id, key);
|
||||
}
|
||||
} while (len > 0);
|
||||
}
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 0 );
|
||||
return len;
|
||||
@@ -474,8 +506,12 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx
|
||||
// never finished code, dropped
|
||||
}
|
||||
} else { // ctxt.enb_flag => UE
|
||||
if (NFAPI_MODE == NFAPI_UE_STUB_PNF) {
|
||||
if (NFAPI_MODE == NFAPI_UE_STUB_PNF || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) {
|
||||
#ifdef UESIM_EXPANSION
|
||||
ctxt.module_id = inst_pdcp_list[pdcp_read_header_g.inst];
|
||||
#else
|
||||
ctxt.module_id = pdcp_read_header_g.inst;
|
||||
#endif
|
||||
} else {
|
||||
ctxt.module_id = 0;
|
||||
}
|
||||
@@ -526,8 +562,8 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx
|
||||
pdcp_read_header_g.data_size,
|
||||
(unsigned char *)NLMSG_DATA(nas_nlh_rx),
|
||||
PDCP_TRANSMISSION_MODE_DATA,
|
||||
(NFAPI_MODE == NFAPI_UE_STUB_PNF)?NULL:&pdcp_read_header_g.sourceL2Id,
|
||||
(NFAPI_MODE == NFAPI_UE_STUB_PNF)?NULL:&pdcp_read_header_g.destinationL2Id
|
||||
(NFAPI_MODE == NFAPI_UE_STUB_PNF || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) ? NULL : &pdcp_read_header_g.sourceL2Id,
|
||||
(NFAPI_MODE == NFAPI_UE_STUB_PNF || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) ? NULL : &pdcp_read_header_g.destinationL2Id
|
||||
);
|
||||
} else { /* else of h_rc == HASH_TABLE_OK */
|
||||
MSC_LOG_RX_DISCARDED_MESSAGE(
|
||||
@@ -571,8 +607,8 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx
|
||||
pdcp_read_header_g.data_size,
|
||||
(unsigned char *)NLMSG_DATA(nas_nlh_rx),
|
||||
PDCP_TRANSMISSION_MODE_DATA,
|
||||
(NFAPI_MODE == NFAPI_UE_STUB_PNF) ? NULL :&pdcp_read_header_g.sourceL2Id,
|
||||
(NFAPI_MODE == NFAPI_UE_STUB_PNF) ? NULL :&pdcp_read_header_g.destinationL2Id
|
||||
(NFAPI_MODE == NFAPI_UE_STUB_PNF|| NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) ? NULL : &pdcp_read_header_g.sourceL2Id,
|
||||
(NFAPI_MODE == NFAPI_UE_STUB_PNF|| NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) ? NULL : &pdcp_read_header_g.destinationL2Id
|
||||
);
|
||||
} /* rab_id == 0 */
|
||||
} /*pdcp_read_state_g != 0 */
|
||||
@@ -597,35 +633,45 @@ void pdcp_fifo_read_input_sdus_frompc5s (const protocol_ctxt_t *const ctxt_pP)
|
||||
/* avoid gcc warnings */
|
||||
(void)data_p;
|
||||
pdcp_t *pdcp_p = NULL;
|
||||
//TTN for D2D (PC5S)
|
||||
int prose_addr_len = sizeof(prose_pdcp_addr);
|
||||
char send_buf[BUFSIZE], receive_buf[BUFSIZE];
|
||||
//int optval;
|
||||
int bytes_received;
|
||||
sidelink_pc5s_element *sl_pc5s_msg_send = NULL;
|
||||
pc5s_header_t *pc5s_header = NULL;
|
||||
rb_id_t rab_id = 0;
|
||||
//TTN for D2D (PC5S)
|
||||
// receive a message from ProSe App
|
||||
memset(receive_buf, 0, BUFSIZE);
|
||||
bytes_received = recvfrom(pdcp_pc5_sockfd, receive_buf, BUFSIZE, 0,
|
||||
(struct sockaddr *) &prose_pdcp_addr, (socklen_t *)&prose_addr_len);
|
||||
|
||||
char receive_buf[MAX_MESSAGE_SIZE];
|
||||
memset(receive_buf, 0, sizeof(receive_buf));
|
||||
socklen_t prose_addr_len = sizeof(prose_pdcp_addr);
|
||||
bytes_received = recvfrom(pdcp_pc5_sockfd, receive_buf, sizeof(receive_buf), MSG_TRUNC,
|
||||
(struct sockaddr *) &prose_pdcp_addr, &prose_addr_len);
|
||||
if (bytes_received == -1) {
|
||||
LOG_E(PDCP, "%s(%d). recvfrom failed. %s\n", __FUNCTION__, __LINE__, strerror(errno));
|
||||
return;
|
||||
}
|
||||
if (bytes_received == 0) {
|
||||
LOG_E(PDCP, "%s(%d). EOF pdcp_pc5_sockfd.\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
if (bytes_received > sizeof(receive_buf)) {
|
||||
LOG_E(PDCP, "%s(%d). Message truncated. %d\n", __FUNCTION__, __LINE__, bytes_received);
|
||||
return;
|
||||
}
|
||||
if (bytes_received > 0) {
|
||||
pc5s_header = calloc(1, sizeof(pc5s_header_t));
|
||||
memcpy((void *)pc5s_header, (void *)receive_buf, sizeof(pc5s_header_t));
|
||||
|
||||
char send_buf[MAX_MESSAGE_SIZE];
|
||||
switch(pc5s_header->traffic_type) {
|
||||
case TRAFFIC_PC5S_SESSION_INIT :
|
||||
//send reply to ProSe app
|
||||
LOG_D(PDCP,"Received a request to open PDCP socket and establish a new PDCP session ... send response to ProSe App \n");
|
||||
memset(send_buf, 0, BUFSIZE);
|
||||
memset(send_buf, 0, sizeof(send_buf));
|
||||
sl_pc5s_msg_send = calloc(1, sizeof(sidelink_pc5s_element));
|
||||
sl_pc5s_msg_send->pc5s_header.traffic_type = TRAFFIC_PC5S_SESSION_INIT;
|
||||
sl_pc5s_msg_send->pc5sPrimitive.status = 1;
|
||||
memcpy((void *)send_buf, (void *)sl_pc5s_msg_send, sizeof(sidelink_pc5s_element));
|
||||
memcpy(send_buf, sl_pc5s_msg_send, sizeof(sidelink_pc5s_element));
|
||||
int prose_addr_len = sizeof(prose_pdcp_addr);
|
||||
int bytes_sent = sendto(pdcp_pc5_sockfd, (char *)send_buf, sizeof(sidelink_pc5s_element), 0, (struct sockaddr *)&prose_pdcp_addr, prose_addr_len);
|
||||
int bytes_sent = sendto(pdcp_pc5_sockfd, send_buf, sizeof(sidelink_pc5s_element), 0,
|
||||
(struct sockaddr *) &prose_pdcp_addr, prose_addr_len);
|
||||
free (sl_pc5s_msg_send);
|
||||
|
||||
if (bytes_sent < 0) {
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*! \file pdcp_thread.c
|
||||
* \brief
|
||||
* \author F. Kaltenberger
|
||||
* \date 2013
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email: florian.kaltenberger@eurecom.fr
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#include <pthread.h>
|
||||
//#include <inttypes.h>
|
||||
|
||||
#include "pdcp.h"
|
||||
#include "PHY/extern.h" //for PHY_vars
|
||||
#include "UTIL/LOG/log.h"
|
||||
#include "UTIL/LOG/vcd_signal_dumper.h"
|
||||
#include "msc.h"
|
||||
|
||||
#define OPENAIR_THREAD_STACK_SIZE 8192
|
||||
#define OPENAIR_THREAD_PRIORITY 255
|
||||
|
||||
extern int oai_exit;
|
||||
extern char UE_flag;
|
||||
|
||||
pthread_t pdcp_thread;
|
||||
pthread_mutex_t pdcp_mutex;
|
||||
pthread_cond_t pdcp_cond;
|
||||
int pdcp_instance_cnt;
|
||||
|
||||
static void *pdcp_thread_main(void* param);
|
||||
|
||||
static void *pdcp_thread_main(void* param)
|
||||
{
|
||||
uint8_t eNB_flag = !UE_flag;
|
||||
|
||||
LOG_I(PDCP,"This is pdcp_thread eNB_flag = %d\n",eNB_flag);
|
||||
MSC_START_USE();
|
||||
|
||||
while (!oai_exit) {
|
||||
|
||||
if (pthread_mutex_lock(&pdcp_mutex) != 0) {
|
||||
LOG_E(PDCP,"Error locking mutex.\n");
|
||||
} else {
|
||||
while (pdcp_instance_cnt < 0) {
|
||||
pthread_cond_wait(&pdcp_cond,&pdcp_mutex);
|
||||
}
|
||||
|
||||
if (pthread_mutex_unlock(&pdcp_mutex) != 0) {
|
||||
LOG_E(PDCP,"Error unlocking mutex.\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (oai_exit) break;
|
||||
|
||||
if (eNB_flag) {
|
||||
pdcp_run(PHY_vars_eNB_g[0]->frame, eNB_flag, PHY_vars_eNB_g[0]->Mod_id, 0);
|
||||
LOG_D(PDCP,"Calling pdcp_run (eNB) for frame %d\n",PHY_vars_eNB_g[0]->frame);
|
||||
} else {
|
||||
pdcp_run(PHY_vars_UE_g[0]->frame, eNB_flag, 0, PHY_vars_UE_g[0]->Mod_id);
|
||||
LOG_D(PDCP,"Calling pdcp_run (UE) for frame %d\n",PHY_vars_UE_g[0]->frame);
|
||||
}
|
||||
|
||||
if (pthread_mutex_lock(&pdcp_mutex) != 0) {
|
||||
LOG_E(PDCP,"Error locking mutex.\n");
|
||||
} else {
|
||||
pdcp_instance_cnt--;
|
||||
|
||||
if (pthread_mutex_unlock(&pdcp_mutex) != 0) {
|
||||
LOG_E(PDCP,"Error unlocking mutex.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
int init_pdcp_thread(void)
|
||||
{
|
||||
|
||||
pthread_mutex_init(&pdcp_mutex,NULL);
|
||||
pthread_cond_init(&pdcp_cond,NULL);
|
||||
|
||||
pdcp_instance_cnt = -1;
|
||||
LOG_I(PDCP,"Allocating PDCP thread\n");
|
||||
threadCreate(&pdcp_thread, pdcp_thread_main, (void*)NULL, "PDCP", -1, OAI_PRIORITY_RT);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
void cleanup_pdcp_thread(void)
|
||||
{
|
||||
void *status_p = NULL;
|
||||
|
||||
LOG_I(PDCP,"Scheduling PDCP thread to exit\n");
|
||||
|
||||
pdcp_instance_cnt = 0;
|
||||
|
||||
if (pthread_cond_signal(&pdcp_cond) != 0) {
|
||||
LOG_I(PDCP,"ERROR pthread_cond_signal\n");
|
||||
} else {
|
||||
LOG_I(PDCP,"Signalled PDCP thread to exit\n");
|
||||
}
|
||||
|
||||
pthread_join(pdcp_thread,&status_p);
|
||||
LOG_I(PDCP,"PDCP thread exited\n");
|
||||
pthread_cond_destroy(&pdcp_cond);
|
||||
pthread_mutex_destroy(&pdcp_mutex);
|
||||
}
|
||||
@@ -157,7 +157,7 @@ void proto_agent_stop(mod_id_t mod_id) {
|
||||
rlc_op_status_t proto_agent_send_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) {
|
||||
confirm_t confirmP, sdu_size_t sdu_sizeP, mem_block_t *sdu_pP,const uint32_t *const SrcID, const uint32_t *const DstID) {
|
||||
uint8_t *msg = NULL;
|
||||
Protocol__FlexsplitMessage *init_msg=NULL;
|
||||
int msg_flag = 0;
|
||||
@@ -191,9 +191,10 @@ error:
|
||||
}
|
||||
|
||||
|
||||
boolean_t
|
||||
proto_agent_send_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_idP, sdu_size_t sdu_sizeP, mem_block_t *sdu_pP) {
|
||||
boolean_t proto_agent_send_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_idP,
|
||||
sdu_size_t sdu_sizeP, mem_block_t *sdu_pP,
|
||||
const uint32_t *const SrcID, const uint32_t *const DstID) {
|
||||
uint8_t *msg = NULL;
|
||||
Protocol__FlexsplitMessage *init_msg = NULL;
|
||||
int msg_flag = 0;
|
||||
|
||||
@@ -42,10 +42,8 @@ void proto_agent_stop(mod_id_t mod_id);
|
||||
rlc_op_status_t proto_agent_send_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);
|
||||
sdu_size_t sdu_sizeP, mem_block_t *sdu_pP,const uint32_t *const SrcID, const uint32_t *const DstID);
|
||||
|
||||
boolean_t proto_agent_send_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_idP, sdu_size_t sdu_sizeP, mem_block_t *sdu_pP);
|
||||
pdcp_data_ind_t proto_agent_send_pdcp_data_ind;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -496,14 +496,6 @@ error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
int proto_agent_pdcp_data_ind_process(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg) {
|
||||
boolean_t result = 0;
|
||||
Protocol__FlexsplitMessage *input = (Protocol__FlexsplitMessage *)params;
|
||||
@@ -525,7 +517,6 @@ int proto_agent_pdcp_data_ind_process(mod_id_t mod_id, const void *params, Proto
|
||||
ctxt_pP.rnti = ctxt->fsp_rnti;
|
||||
ctxt_pP.frame = ctxt->fsp_frame;
|
||||
ctxt_pP.subframe = ctxt->fsp_subframe;
|
||||
ctxt_pP.configured = 1;
|
||||
ctxt_pP.brOption = 0;
|
||||
ctxt_pP.eNB_index = ctxt->fsp_enb_index;
|
||||
srb_flagP = rlc_data->fsp_srb_flag;
|
||||
@@ -546,7 +537,7 @@ int proto_agent_pdcp_data_ind_process(mod_id_t mod_id, const void *params, Proto
|
||||
flag_MBMS,
|
||||
rb_idP,
|
||||
pdcp_pdu_size,
|
||||
pdcp_pdu_p);
|
||||
pdcp_pdu_p, NULL, NULL);
|
||||
return result;
|
||||
error:
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
|
||||
|
||||
if (rcvd_count < entity->rx_deliv
|
||||
|| nr_pdcp_sdu_in_list(entity->rx_list, rcvd_count)) {
|
||||
LOG_D(PDCP, "discard NR PDU rcvd_count=%d\n", rcvd_count);
|
||||
LOG_W(PDCP, "discard NR PDU rcvd_count=%d\n", rcvd_count);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ hash_table_t *pdcp_coll_p;
|
||||
static uint64_t pdcp_optmask;
|
||||
|
||||
ngran_node_t node_type = ngran_gNB;
|
||||
uint8_t first_dcch = 0;
|
||||
uint8_t proto_agent_flag = 0;
|
||||
|
||||
/****************************************************************************/
|
||||
@@ -160,8 +161,7 @@ static void enqueue_rlc_data_req(const protocol_ctxt_t *const ctxt_pP,
|
||||
const mui_t muiP,
|
||||
confirm_t confirmP,
|
||||
sdu_size_t sdu_sizeP,
|
||||
mem_block_t *sdu_pP,
|
||||
void *_unused1, void *_unused2)
|
||||
mem_block_t *sdu_pP)
|
||||
{
|
||||
int i;
|
||||
int logged = 0;
|
||||
@@ -206,9 +206,7 @@ void du_rlc_data_req(const protocol_ctxt_t *const ctxt_pP,
|
||||
rb_idP, muiP,
|
||||
confirmP,
|
||||
sdu_sizeP,
|
||||
sdu_pP,
|
||||
NULL,
|
||||
NULL);
|
||||
sdu_pP);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
@@ -256,7 +254,6 @@ static void do_pdcp_data_ind(
|
||||
//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);
|
||||
@@ -376,7 +373,9 @@ boolean_t pdcp_data_ind(
|
||||
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)
|
||||
mem_block_t *const sdu_buffer,
|
||||
const uint32_t *const srcID,
|
||||
const uint32_t *const dstID)
|
||||
{
|
||||
enqueue_pdcp_data_ind(ctxt_pP,
|
||||
srb_flagP,
|
||||
@@ -442,7 +441,6 @@ static void *enb_tun_read_thread(void *_)
|
||||
ctxt.frame = 0;
|
||||
ctxt.subframe = 0;
|
||||
ctxt.eNB_index = 0;
|
||||
ctxt.configured = 1;
|
||||
ctxt.brOption = 0;
|
||||
|
||||
ctxt.rnti = rnti;
|
||||
@@ -486,7 +484,6 @@ static void *ue_tun_read_thread(void *_)
|
||||
ctxt.frame = 0;
|
||||
ctxt.subframe = 0;
|
||||
ctxt.eNB_index = 0;
|
||||
ctxt.configured = 1;
|
||||
ctxt.brOption = 0;
|
||||
|
||||
ctxt.rnti = rnti;
|
||||
@@ -559,7 +556,7 @@ void pdcp_layer_init(void)
|
||||
#include "targets/RT/USER/lte-softmodem.h"
|
||||
#include "openair2/RRC/NAS/nas_config.h"
|
||||
|
||||
uint64_t pdcp_module_init(uint64_t _pdcp_optmask)
|
||||
uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id)
|
||||
{
|
||||
/* hack: be sure to initialize only once */
|
||||
static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
|
||||
@@ -591,16 +588,18 @@ uint64_t pdcp_module_init(uint64_t _pdcp_optmask)
|
||||
nas_getparams();
|
||||
|
||||
if(UE_NAS_USE_TUN) {
|
||||
int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )? MAX_MOBILES_PER_ENB : 1;
|
||||
netlink_init_tun("ue",num_if);
|
||||
char *ifsuffix_ue = get_softmodem_params()->nsa ? "nrue" : "ue";
|
||||
int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF)? MAX_MOBILES_PER_ENB : 1;
|
||||
netlink_init_tun(ifsuffix_ue, num_if, id);
|
||||
//Add --nr-ip-over-lte option check for next line
|
||||
if (IS_SOFTMODEM_NOS1)
|
||||
nas_config(1, 1, 2, "ue");
|
||||
nas_config(1, 1, !get_softmodem_params()->nsa ? 2 : 3, ifsuffix_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");
|
||||
char *ifsuffix_base_s = get_softmodem_params()->nsa ? "gnb" : "enb";
|
||||
netlink_init_tun(ifsuffix_base_s, 1, id);
|
||||
nas_config(1, 1, 1, ifsuffix_base_s);
|
||||
LOG_I(PDCP, "ENB pdcp will use tun interface\n");
|
||||
start_pdcp_tun_enb();
|
||||
} else {
|
||||
@@ -623,7 +622,7 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
|
||||
int rb_id;
|
||||
int i;
|
||||
|
||||
if(IS_SOFTMODEM_NOS1 || UE_NAS_USE_TUN){
|
||||
if (IS_SOFTMODEM_NOS1 || UE_NAS_USE_TUN) {
|
||||
LOG_D(PDCP, "IP packet received, to be sent to TUN interface");
|
||||
|
||||
if(entity->has_sdapDLheader){
|
||||
@@ -634,7 +633,7 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
|
||||
}
|
||||
|
||||
if (len != size) {
|
||||
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
LOG_E(PDCP, "%s:%d:%s: fatal error %d: %s\n", __FILE__, __LINE__, __FUNCTION__, errno, strerror(errno));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -653,19 +652,23 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
|
||||
rb_found:
|
||||
{
|
||||
int offset=0;
|
||||
if (entity->has_sdap == 1 && entity->has_sdapULheader == 1) offset = 1; // this is the offset of the SDAP header in bytes
|
||||
if (entity->has_sdap == 1 && entity->has_sdapULheader == 1)
|
||||
offset = 1; // this is the offset of the SDAP header in bytes
|
||||
|
||||
gtpu_buffer_p = itti_malloc(TASK_PDCP_ENB, TASK_GTPV1_U,
|
||||
size + GTPU_HEADER_OVERHEAD_MAX - offset);
|
||||
AssertFatal(gtpu_buffer_p != NULL, "OUT OF MEMORY");
|
||||
memcpy(>pu_buffer_p[GTPU_HEADER_OVERHEAD_MAX], buf+offset, size-offset);
|
||||
message_p = itti_alloc_new_message(TASK_PDCP_ENB, 0, GTPV1U_GNB_TUNNEL_DATA_REQ);
|
||||
message_p = itti_alloc_new_message_sized(TASK_PDCP_ENB, 0,
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ,
|
||||
sizeof(gtpv1u_gnb_tunnel_data_req_t) + size
|
||||
+ GTPU_HEADER_OVERHEAD_MAX - offset);
|
||||
AssertFatal(message_p != NULL, "OUT OF MEMORY");
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).buffer = gtpu_buffer_p;
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).length = size-offset;
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).offset = GTPU_HEADER_OVERHEAD_MAX;
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).rnti = ue->rnti;
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).pdusession_id = entity->pdusession_id;
|
||||
|
||||
gtpv1u_gnb_tunnel_data_req_t *req=>PV1U_GNB_TUNNEL_DATA_REQ(message_p);
|
||||
gtpu_buffer_p = (uint8_t*)(req+1);
|
||||
memcpy(gtpu_buffer_p+GTPU_HEADER_OVERHEAD_MAX, buf+offset, size-offset);
|
||||
req->buffer = gtpu_buffer_p;
|
||||
req->length = size-offset;
|
||||
req->offset = GTPU_HEADER_OVERHEAD_MAX;
|
||||
req->rnti = ue->rnti;
|
||||
req->pdusession_id = entity->pdusession_id;
|
||||
if (offset==1) {
|
||||
LOG_I(PDCP, "%s() (drb %d) SDAP header %2x\n",__func__, rb_id, buf[0]);
|
||||
sdap_gnb_ul_header_handler(buf[0]); // Handler for the UL gNB SDAP Header
|
||||
@@ -703,18 +706,39 @@ rb_found:
|
||||
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);
|
||||
|
||||
LOG_D(PDCP, "%s(): (srb %d) calling rlc_data_req size %d\n", __func__, 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);
|
||||
if (RC.nrrrc != NULL && NODE_IS_CU(RC.nrrrc[0]->node_type)) {
|
||||
MessageDef *message_p = itti_alloc_new_message_sized(TASK_PDCP_ENB, 0,
|
||||
GTPV1U_GNB_TUNNEL_DATA_REQ,
|
||||
sizeof(gtpv1u_gnb_tunnel_data_req_t)
|
||||
+ size
|
||||
+ GTPU_HEADER_OVERHEAD_MAX);
|
||||
AssertFatal(message_p != NULL, "OUT OF MEMORY");
|
||||
gtpv1u_gnb_tunnel_data_req_t *req=>PV1U_GNB_TUNNEL_DATA_REQ(message_p);
|
||||
uint8_t *gtpu_buffer_p = (uint8_t*)(req+1);
|
||||
memcpy(gtpu_buffer_p+GTPU_HEADER_OVERHEAD_MAX,
|
||||
buf, size);
|
||||
req->buffer = gtpu_buffer_p;
|
||||
req->length = size;
|
||||
req->offset = GTPU_HEADER_OVERHEAD_MAX;
|
||||
req->rnti = ue->rnti;
|
||||
req->pdusession_id = rb_id;
|
||||
LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n",
|
||||
__func__, rb_id, size);
|
||||
extern instance_t CUuniqInstance;
|
||||
itti_send_msg_to_task(TASK_VARIABLE, CUuniqInstance, message_p);
|
||||
} else {
|
||||
|
||||
memblock = get_free_mem_block(size, __FUNCTION__);
|
||||
memcpy(memblock->data, buf, size);
|
||||
|
||||
LOG_D(PDCP, "%s(): (srb %d) calling rlc_data_req size %d\n", __func__, 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);
|
||||
}
|
||||
}
|
||||
|
||||
static void deliver_sdu_srb(void *_ue, nr_pdcp_entity_t *entity,
|
||||
@@ -791,18 +815,19 @@ srb_found:
|
||||
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);
|
||||
enqueue_rlc_data_req(&ctxt, 1, MBMS_FLAG_NO, srb_id, sdu_id, 0, size, memblock, NULL, NULL);
|
||||
enqueue_rlc_data_req(&ctxt, 1, MBMS_FLAG_NO, srb_id, sdu_id, 0, size, memblock);
|
||||
}
|
||||
else {
|
||||
MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_DL_RRC_MESSAGE);
|
||||
F1AP_DL_RRC_MESSAGE (message_p).rrc_container = (uint8_t*)buf;
|
||||
uint8_t *message_buffer = itti_malloc (TASK_RRC_GNB, TASK_CU_F1, size);
|
||||
memcpy (message_buffer, buf, size);
|
||||
F1AP_DL_RRC_MESSAGE (message_p).rrc_container = message_buffer;
|
||||
F1AP_DL_RRC_MESSAGE (message_p).rrc_container_length = size;
|
||||
F1AP_DL_RRC_MESSAGE (message_p).gNB_CU_ue_id = 0;
|
||||
F1AP_DL_RRC_MESSAGE (message_p).gNB_DU_ue_id = 0;
|
||||
@@ -827,7 +852,6 @@ void pdcp_run(const protocol_ctxt_t *const ctxt_pP)
|
||||
.frame=-1,
|
||||
.subframe=-1,
|
||||
.eNB_index=0,
|
||||
.configured=true,
|
||||
.brOption=false
|
||||
};
|
||||
|
||||
@@ -1164,7 +1188,7 @@ void nr_DRB_preconfiguration(uint16_t crnti)
|
||||
|
||||
NR_RLC_BearerConfig_t *RLC_BearerConfig = calloc(1,sizeof(*RLC_BearerConfig));
|
||||
nr_rlc_bearer_init(RLC_BearerConfig,NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity);
|
||||
nr_drb_config(RLC_BearerConfig->rlc_Config, NR_RLC_Config_PR_um_Bi_Directional);
|
||||
nr_drb_config(RLC_BearerConfig->rlc_Config, NR_RLC_Config_PR_am);
|
||||
nr_rlc_bearer_init_ul_spec(RLC_BearerConfig->mac_LogicalChannelConfig);
|
||||
|
||||
Rlc_Bearer_ToAdd_list = calloc(1,sizeof(*Rlc_Bearer_ToAdd_list));
|
||||
@@ -1356,6 +1380,35 @@ static boolean_t pdcp_data_req_drb(
|
||||
return 1;
|
||||
}
|
||||
|
||||
boolean_t cu_f1u_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
|
||||
,const uint32_t *const sourceL2Id
|
||||
,const uint32_t *const destinationL2Id
|
||||
) {
|
||||
|
||||
//Force instance id to 0, OAI incoherent instance management
|
||||
ctxt_pP->instance=0;
|
||||
mem_block_t *memblock = get_free_mem_block(sdu_buffer_size, __func__);
|
||||
if (memblock == NULL) {
|
||||
LOG_E(RLC, "%s:%d:%s: ERROR: get_free_mem_block failed\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
memcpy(memblock->data,sdu_buffer, sdu_buffer_size);
|
||||
int ret=pdcp_data_ind(ctxt_pP,srb_flagP, false, rb_id, sdu_buffer_size, memblock, NULL, NULL);
|
||||
if (!ret) {
|
||||
LOG_E(RLC, "%s:%d:%s: ERROR: pdcp_data_ind failed\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
/* what to do in case of failure? for the moment: nothing */
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
boolean_t pdcp_data_req(
|
||||
protocol_ctxt_t *ctxt_pP,
|
||||
const srb_flag_t srb_flagP,
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include "nr_pdcp_timer_thread.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -33,6 +34,7 @@ static volatile uint64_t timer_thread_curtime = 0;
|
||||
|
||||
static void *nr_pdcp_timer_thread(void *_nr_pdcp_ue_manager)
|
||||
{
|
||||
pthread_setname_np(pthread_self(),"pdcp_timer");
|
||||
nr_pdcp_ue_manager_t *nr_pdcp_ue_manager = (nr_pdcp_ue_manager_t *)_nr_pdcp_ue_manager;
|
||||
nr_pdcp_ue_t **ue_list;
|
||||
int ue_count;
|
||||
|
||||
@@ -596,20 +596,20 @@ void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *_entity,
|
||||
|
||||
/* dicard PDU if no data */
|
||||
if (data_size <= 0) {
|
||||
LOG_D(RLC, "%s:%d:%s: warning: discard PDU, no data\n",
|
||||
LOG_W(RLC, "%s:%d:%s: warning: discard PDU, no data\n",
|
||||
__FILE__, __LINE__, __FUNCTION__);
|
||||
goto discard;
|
||||
}
|
||||
|
||||
/* dicard PDU if rx buffer is full */
|
||||
if (entity->rx_size + data_size > entity->rx_maxsize) {
|
||||
LOG_D(RLC, "%s:%d:%s: warning: discard PDU, RX buffer full\n",
|
||||
LOG_W(RLC, "%s:%d:%s: warning: discard PDU, RX buffer full\n",
|
||||
__FILE__, __LINE__, __FUNCTION__);
|
||||
goto discard;
|
||||
}
|
||||
|
||||
if (!sn_in_recv_window(entity, sn)) {
|
||||
LOG_D(RLC, "%s:%d:%s: warning: discard PDU, sn out of window (sn %d rx_next %d)\n",
|
||||
LOG_W(RLC, "%s:%d:%s: warning: discard PDU, sn out of window (sn %d rx_next %d)\n",
|
||||
__FILE__, __LINE__, __FUNCTION__,
|
||||
sn, entity->rx_next);
|
||||
goto discard;
|
||||
@@ -617,7 +617,7 @@ void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *_entity,
|
||||
|
||||
/* discard segment if all the bytes of the segment are already there */
|
||||
if (segment_already_received(entity, sn, so, data_size)) {
|
||||
LOG_D(RLC, "%s:%d:%s: warning: discard PDU, already received\n",
|
||||
LOG_W(RLC, "%s:%d:%s: warning: discard PDU, already received\n",
|
||||
__FILE__, __LINE__, __FUNCTION__);
|
||||
goto discard;
|
||||
}
|
||||
@@ -653,7 +653,7 @@ void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *_entity,
|
||||
control:
|
||||
cpt = nr_rlc_pdu_decoder_get_bits(&decoder, 3); R(decoder);
|
||||
if (cpt != 0) {
|
||||
LOG_D(RLC, "%s:%d:%s: warning: discard PDU, CPT not 0 (%d)\n",
|
||||
LOG_W(RLC, "%s:%d:%s: warning: discard PDU, CPT not 0 (%d)\n",
|
||||
__FILE__, __LINE__, __FUNCTION__, cpt);
|
||||
goto discard;
|
||||
}
|
||||
@@ -1660,7 +1660,7 @@ static void check_t_poll_retransmit(nr_rlc_entity_am_t *entity)
|
||||
*/
|
||||
entity->force_poll = 1;
|
||||
|
||||
LOG_D(RLC, "%s:%d:%s: warning: t_poll_retransmit expired\n",
|
||||
LOG_W(RLC, "%s:%d:%s: warning: t_poll_retransmit expired\n",
|
||||
__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
/* do we meet conditions of 38.322 5.3.3.4? */
|
||||
|
||||
@@ -313,21 +313,21 @@ void nr_rlc_entity_um_recv_pdu(nr_rlc_entity_t *_entity,
|
||||
|
||||
/* dicard PDU if no data */
|
||||
if (data_size <= 0) {
|
||||
LOG_D(RLC, "%s:%d:%s: warning: discard PDU, no data\n",
|
||||
LOG_W(RLC, "%s:%d:%s: warning: discard PDU, no data\n",
|
||||
__FILE__, __LINE__, __FUNCTION__);
|
||||
goto discard;
|
||||
}
|
||||
|
||||
/* dicard PDU if rx buffer is full */
|
||||
if (entity->rx_size + data_size > entity->rx_maxsize) {
|
||||
LOG_D(RLC, "%s:%d:%s: warning: discard PDU, RX buffer full\n",
|
||||
LOG_W(RLC, "%s:%d:%s: warning: discard PDU, RX buffer full\n",
|
||||
__FILE__, __LINE__, __FUNCTION__);
|
||||
goto discard;
|
||||
}
|
||||
|
||||
/* discard PDU if sn < rx_next_reassembly */
|
||||
if (sn_compare_rx(entity, sn, entity->rx_next_reassembly) < 0) {
|
||||
LOG_D(RLC, "%s:%d:%s: warning: discard PDU, SN (%d) < rx_next_reassembly (%d)\n",
|
||||
LOG_W(RLC, "%s:%d:%s: warning: discard PDU, SN (%d) < rx_next_reassembly (%d)\n",
|
||||
__FILE__, __LINE__, __FUNCTION__,
|
||||
sn, entity->rx_next_reassembly);
|
||||
goto discard;
|
||||
@@ -534,7 +534,7 @@ void nr_rlc_entity_um_recv_sdu(nr_rlc_entity_t *_entity,
|
||||
}
|
||||
|
||||
if (entity->tx_size + size > entity->tx_maxsize) {
|
||||
LOG_D(RLC, "%s:%d:%s: warning: SDU rejected, SDU buffer full\n",
|
||||
LOG_W(RLC, "%s:%d:%s: warning: SDU rejected, SDU buffer full\n",
|
||||
__FILE__, __LINE__, __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -346,16 +346,16 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(
|
||||
|
||||
|
||||
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,
|
||||
const rb_id_t rb_idP,
|
||||
const mui_t muiP,
|
||||
confirm_t confirmP,
|
||||
sdu_size_t sdu_sizeP,
|
||||
mem_block_t *sdu_pP,
|
||||
const uint32_t *const sourceL2Id,
|
||||
const uint32_t *const destinationL2Id
|
||||
)
|
||||
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,
|
||||
const uint32_t *const sourceL2Id,
|
||||
const uint32_t *const destinationL2Id
|
||||
)
|
||||
{
|
||||
int rnti = ctxt_pP->rnti;
|
||||
nr_rlc_ue_t *ue;
|
||||
@@ -465,19 +465,11 @@ rb_found:
|
||||
LOG_D(RLC, "%s:%d:%s: delivering SDU (rnti %d is_srb %d rb_id %d) size %d\n",
|
||||
__FILE__, __LINE__, __FUNCTION__, ue->rnti, is_srb, rb_id, size);
|
||||
|
||||
memblock = get_free_mem_block(size, __func__);
|
||||
if (memblock == NULL) {
|
||||
LOG_E(RLC, "%s:%d:%s: ERROR: get_free_mem_block failed\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
memcpy(memblock->data, buf, size);
|
||||
|
||||
/* unused fields? */
|
||||
ctx.instance = 0;
|
||||
ctx.frame = 0;
|
||||
ctx.subframe = 0;
|
||||
ctx.eNB_index = 0;
|
||||
ctx.configured = 1;
|
||||
ctx.brOption = 0;
|
||||
|
||||
/* used fields? */
|
||||
@@ -502,19 +494,44 @@ rb_found:
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (NODE_IS_DU(type) && is_srb == 1) {
|
||||
MessageDef *msg;
|
||||
msg = itti_alloc_new_message(TASK_RLC_ENB, 0, F1AP_UL_RRC_MESSAGE);
|
||||
F1AP_UL_RRC_MESSAGE(msg).rnti = ue->rnti;
|
||||
F1AP_UL_RRC_MESSAGE(msg).srb_id = rb_id;
|
||||
F1AP_UL_RRC_MESSAGE(msg).rrc_container = (unsigned char *)buf;
|
||||
F1AP_UL_RRC_MESSAGE(msg).rrc_container_length = size;
|
||||
itti_send_msg_to_task(TASK_DU_F1, ENB_MODULE_ID_TO_INSTANCE(0 /*ctxt_pP->module_id*/), msg);
|
||||
return;
|
||||
if (NODE_IS_DU(type)) {
|
||||
if(is_srb) {
|
||||
MessageDef *msg;
|
||||
msg = itti_alloc_new_message(TASK_RLC_ENB, 0, F1AP_UL_RRC_MESSAGE);
|
||||
uint8_t *message_buffer = itti_malloc (TASK_RLC_ENB, TASK_DU_F1, size);
|
||||
memcpy (message_buffer, buf, size);
|
||||
F1AP_UL_RRC_MESSAGE(msg).rnti = ue->rnti;
|
||||
F1AP_UL_RRC_MESSAGE(msg).srb_id = rb_id;
|
||||
F1AP_UL_RRC_MESSAGE(msg).rrc_container = message_buffer;
|
||||
F1AP_UL_RRC_MESSAGE(msg).rrc_container_length = size;
|
||||
itti_send_msg_to_task(TASK_DU_F1, ENB_MODULE_ID_TO_INSTANCE(0 /*ctxt_pP->module_id*/), msg);
|
||||
return;
|
||||
} else {
|
||||
MessageDef *msg = itti_alloc_new_message_sized(TASK_RLC_ENB, 0, GTPV1U_GNB_TUNNEL_DATA_REQ,
|
||||
sizeof(gtpv1u_gnb_tunnel_data_req_t) + size);
|
||||
gtpv1u_gnb_tunnel_data_req_t *req=>PV1U_GNB_TUNNEL_DATA_REQ(msg);
|
||||
req->buffer=(uint8_t*)(req+1);
|
||||
memcpy(req->buffer,buf,size);
|
||||
req->length=size;
|
||||
req->offset=0;
|
||||
req->rnti=ue->rnti;
|
||||
req->pdusession_id=rb_id;
|
||||
LOG_D(RLC, "Received uplink user-plane traffic at RLC-DU to be sent to the CU, size %d \n", size);
|
||||
extern instance_t DUuniqInstance;
|
||||
itti_send_msg_to_task(OCP_GTPV1_U, DUuniqInstance, msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!pdcp_data_ind(&ctx, is_srb, 0, rb_id, size, memblock)) {
|
||||
memblock = get_free_mem_block(size, __func__);
|
||||
if (memblock == NULL) {
|
||||
LOG_E(RLC, "%s:%d:%s: ERROR: get_free_mem_block failed\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
memcpy(memblock->data, buf, size);
|
||||
LOG_D(PDCP, "Calling PDCP layer from RLC in %s\n", __FUNCTION__);
|
||||
if (!pdcp_data_ind(&ctx, is_srb, 0, rb_id, size, memblock, NULL, NULL)) {
|
||||
LOG_E(RLC, "%s:%d:%s: ERROR: pdcp_data_ind failed\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
/* what to do in case of failure? for the moment: nothing */
|
||||
}
|
||||
@@ -721,7 +738,7 @@ static void add_rlc_srb(int rnti, struct NR_SRB_ToAddMod *s, NR_RLC_BearerConfig
|
||||
sn_field_length);
|
||||
nr_rlc_ue_add_srb_rlc_entity(ue, srb_id, nr_rlc_am);
|
||||
|
||||
LOG_D(RLC, "%s:%d:%s: added srb %d to UE with RNTI 0x%x\n", __FILE__, __LINE__, __FUNCTION__, srb_id, rnti);
|
||||
LOG_I(RLC, "%s:%d:%s: added srb %d to UE with RNTI 0x%x\n", __FILE__, __LINE__, __FUNCTION__, srb_id, rnti);
|
||||
}
|
||||
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
||||
}
|
||||
@@ -803,7 +820,7 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_
|
||||
sn_field_length);
|
||||
nr_rlc_ue_add_drb_rlc_entity(ue, drb_id, nr_rlc_am);
|
||||
|
||||
LOG_D(RLC, "%s:%d:%s: added drb %d to UE with RNTI 0x%x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
|
||||
LOG_I(RLC, "%s:%d:%s: added drb %d to UE with RNTI 0x%x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
|
||||
}
|
||||
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
||||
}
|
||||
@@ -918,10 +935,10 @@ rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt
|
||||
|
||||
if (/*ctxt_pP->enb_flag != 1 ||*/ ctxt_pP->module_id != 0 /*||
|
||||
ctxt_pP->instance != 0 || ctxt_pP->eNB_index != 0 ||
|
||||
ctxt_pP->configured != 1 || ctxt_pP->brOption != 0 */) {
|
||||
LOG_E(RLC, "%s: ctxt_pP not handled (%d %d %ld %d %d %d)\n", __FUNCTION__,
|
||||
ctxt_pP->brOption != 0 */) {
|
||||
LOG_E(RLC, "%s: ctxt_pP not handled (%d %d %ld %d %d)\n", __FUNCTION__,
|
||||
ctxt_pP->enb_flag , ctxt_pP->module_id, ctxt_pP->instance,
|
||||
ctxt_pP->eNB_index, ctxt_pP->configured, ctxt_pP->brOption);
|
||||
ctxt_pP->eNB_index, ctxt_pP->brOption);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -394,19 +394,12 @@ rb_found:
|
||||
LOG_D(RLC, "%s:%d:%s: delivering SDU (rnti %d is_srb %d rb_id %d) size %d",
|
||||
__FILE__, __LINE__, __FUNCTION__, ue->rnti, is_srb, rb_id, size);
|
||||
|
||||
memblock = get_free_mem_block(size, __func__);
|
||||
if (memblock == NULL) {
|
||||
LOG_E(RLC, "%s:%d:%s: ERROR: get_free_mem_block failed\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
memcpy(memblock->data, buf, size);
|
||||
|
||||
/* unused fields? */
|
||||
ctx.instance = ue->module_id;
|
||||
ctx.frame = 0;
|
||||
ctx.subframe = 0;
|
||||
ctx.eNB_index = 0;
|
||||
ctx.configured = 1;
|
||||
ctx.brOption = 0;
|
||||
|
||||
/* used fields? */
|
||||
@@ -425,17 +418,40 @@ rb_found:
|
||||
AssertFatal(type != ngran_eNB_CU && type != ngran_ng_eNB_CU && type != ngran_gNB_CU,
|
||||
"Can't be CU, bad node type %d\n", type);
|
||||
|
||||
if (NODE_IS_DU(type) && is_srb == 1) {
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RLC_ENB, 0, F1AP_UL_RRC_MESSAGE);
|
||||
F1AP_UL_RRC_MESSAGE(msg).rnti = ue->rnti;
|
||||
F1AP_UL_RRC_MESSAGE(msg).srb_id = rb_id;
|
||||
F1AP_UL_RRC_MESSAGE(msg).rrc_container = (unsigned char *)buf;
|
||||
F1AP_UL_RRC_MESSAGE(msg).rrc_container_length = size;
|
||||
itti_send_msg_to_task(TASK_DU_F1, ENB_MODULE_ID_TO_INSTANCE(0 /*ctxt_pP->module_id*/), msg);
|
||||
return;
|
||||
if (NODE_IS_DU(type)) {
|
||||
if (is_srb == 1) {
|
||||
MessageDef *msg = itti_alloc_new_message_sized(TASK_RLC_ENB, 0, F1AP_UL_RRC_MESSAGE, sizeof(*msg) + size);
|
||||
F1AP_UL_RRC_MESSAGE(msg).rrc_container = (uint8_t*)(msg+1);
|
||||
memcpy(F1AP_UL_RRC_MESSAGE(msg).rrc_container, buf, size);
|
||||
F1AP_UL_RRC_MESSAGE(msg).rnti = ue->rnti;
|
||||
F1AP_UL_RRC_MESSAGE(msg).srb_id = rb_id;
|
||||
F1AP_UL_RRC_MESSAGE(msg).rrc_container_length = size;
|
||||
itti_send_msg_to_task(TASK_DU_F1, ENB_MODULE_ID_TO_INSTANCE(0 /*ctxt_pP->module_id*/), msg);
|
||||
return;
|
||||
} else {
|
||||
// Fixme: very dirty workaround of incomplete F1-U implementation
|
||||
instance_t DUuniqInstance=0;
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_RLC_ENB, 0, GTPV1U_ENB_TUNNEL_DATA_REQ);
|
||||
gtpv1u_enb_tunnel_data_req_t *req=>PV1U_ENB_TUNNEL_DATA_REQ(msg);
|
||||
req->buffer=malloc(size);
|
||||
memcpy(req->buffer,buf,size);
|
||||
req->length=size;
|
||||
req->offset=0;
|
||||
req->rnti=ue->rnti;
|
||||
req->rab_id=rb_id+4;
|
||||
LOG_D(RLC, "Received uplink user-plane traffic at RLC-DU to be sent to the CU, size %d \n", size);
|
||||
itti_send_msg_to_task(OCP_GTPV1_U, DUuniqInstance, msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
memblock = get_free_mem_block(size, __func__);
|
||||
if (memblock == NULL) {
|
||||
LOG_E(RLC, "%s:%d:%s: ERROR: get_free_mem_block failed\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
memcpy(memblock->data, buf, size);
|
||||
if (!get_pdcp_data_ind_func()(&ctx, is_srb, is_mbms, rb_id, size, memblock, NULL, NULL)) {
|
||||
LOG_E(RLC, "%s:%d:%s: ERROR: pdcp_data_ind failed (is_srb %d rb_id %d rnti %d)\n",
|
||||
__FILE__, __LINE__, __FUNCTION__,
|
||||
@@ -832,10 +848,10 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP
|
||||
|
||||
if (0 /*||
|
||||
ctxt_pP->instance != 0 || ctxt_pP->eNB_index != 0 ||
|
||||
ctxt_pP->configured != 1 || ctxt_pP->brOption != 0 */) {
|
||||
LOG_E(RLC, "%s: ctxt_pP not handled (%d %d %ld %d %d %d)\n", __FUNCTION__,
|
||||
ctxt_pP->brOption != 0 */) {
|
||||
LOG_E(RLC, "%s: ctxt_pP not handled (%d %d %ld %d %d)\n", __FUNCTION__,
|
||||
ctxt_pP->enb_flag , ctxt_pP->module_id, ctxt_pP->instance,
|
||||
ctxt_pP->eNB_index, ctxt_pP->configured, ctxt_pP->brOption);
|
||||
ctxt_pP->eNB_index, ctxt_pP->brOption);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -1040,5 +1056,12 @@ void du_rlc_data_req(const protocol_ctxt_t *const ctxt_pP,
|
||||
confirm_t confirmP,
|
||||
sdu_size_t sdu_sizeP,
|
||||
mem_block_t *sdu_pP){
|
||||
|
||||
}
|
||||
rlc_data_req (ctxt_pP,
|
||||
srb_flagP,
|
||||
MBMS_flagP,
|
||||
rb_idP,
|
||||
muiP,
|
||||
confirmP,
|
||||
sdu_sizeP,
|
||||
sdu_pP, NULL, NULL);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user