Merge remote-tracking branch 'origin/develop' into threading-rk
This commit is contained in:
@@ -327,6 +327,13 @@ typedef struct nas_establish_req_s {
|
||||
as_nas_info_t initialNasMsg; /* Initial NAS message to transfer */
|
||||
} nas_establish_req_t;
|
||||
|
||||
/*
|
||||
* fill me
|
||||
*/
|
||||
typedef struct nas_deregistration_req_s {
|
||||
// fill me
|
||||
} nas_deregistration_req_t;
|
||||
|
||||
/*
|
||||
* AS->NAS - NAS signalling connection establishment indication
|
||||
* AS transfers the initial NAS message to the NAS.
|
||||
|
||||
@@ -62,6 +62,7 @@ MESSAGE_DEF(NAS_KENB_REFRESH_REQ, MESSAGE_PRIORITY_MED, NasKenbRefre
|
||||
MESSAGE_DEF(NAS_CELL_SELECTION_REQ, MESSAGE_PRIORITY_MED, NasCellSelectionReq, nas_cell_selection_req)
|
||||
MESSAGE_DEF(NAS_CONN_ESTABLI_REQ, MESSAGE_PRIORITY_MED, NasConnEstabliReq, nas_conn_establi_req)
|
||||
MESSAGE_DEF(NAS_UPLINK_DATA_REQ, MESSAGE_PRIORITY_MED, NasUlDataReq, nas_ul_data_req)
|
||||
MESSAGE_DEF(NAS_DEREGISTRATION_REQ, MESSAGE_PRIORITY_MED, NasDeregistrationReq, nas_deregistration_req)
|
||||
|
||||
MESSAGE_DEF(NAS_RAB_ESTABLI_RSP, MESSAGE_PRIORITY_MED, NasRabEstRsp, nas_rab_est_rsp)
|
||||
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
#define NAS_CELL_SELECTION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_cell_selection_req
|
||||
#define NAS_CONN_ESTABLI_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_conn_establi_req
|
||||
#define NAS_UPLINK_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_data_req
|
||||
#define NAS_DEREGISTRATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_deregistration_req
|
||||
|
||||
#define NAS_RAB_ESTABLI_RSP(mSGpTR) (mSGpTR)->ittiMsg.nas_rab_est_rsp
|
||||
|
||||
@@ -441,6 +442,7 @@ typedef kenb_refresh_req_t NasKenbRefreshReq;
|
||||
typedef cell_info_req_t NasCellSelectionReq;
|
||||
typedef nas_establish_req_t NasConnEstabliReq;
|
||||
typedef ul_info_transfer_req_t NasUlDataReq;
|
||||
typedef nas_deregistration_req_t NasDeregistrationReq;
|
||||
|
||||
typedef rab_establish_rsp_t NasRabEstRsp;
|
||||
|
||||
|
||||
@@ -112,9 +112,7 @@ static int drb_config_N3gtpu_create(e1ap_bearer_setup_req_t * const req,
|
||||
create_tunnel_req.ue_id = (req->gNB_cu_cp_ue_id & 0xFFFF);
|
||||
|
||||
// Create N3 tunnel
|
||||
int ret = gtpv1u_create_ngu_tunnel(instance,
|
||||
&create_tunnel_req,
|
||||
create_tunnel_resp);
|
||||
int ret = gtpv1u_create_ngu_tunnel(instance, &create_tunnel_req, create_tunnel_resp, nr_pdcp_data_req_drb, sdap_data_req);
|
||||
if (ret != 0) {
|
||||
LOG_E(NR_RRC,"rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE id %ld\n",
|
||||
create_tunnel_req.ue_id);
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include "f1ap_cu_rrc_message_transfer.h"
|
||||
#include "common/ran_context.h"
|
||||
#include "openair3/UTILS/conversions.h"
|
||||
#include "pdcp.h"
|
||||
#include "LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
|
||||
|
||||
/*
|
||||
Initial UL RRC Message Transfer
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#include "rrc_extern.h"
|
||||
#include "openair2/RRC/NR/rrc_gNB_NGAP.h"
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
#include "pdcp.h"
|
||||
#include "LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
|
||||
|
||||
static void setQos(F1AP_NonDynamic5QIDescriptor_t *toFill) {
|
||||
asn1cCalloc(toFill, tmp);
|
||||
@@ -958,7 +958,7 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
|
||||
LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti);
|
||||
}
|
||||
|
||||
pdcp_remove_UE(&ctxt);
|
||||
nr_pdcp_remove_UE(ctxt.rntiMaybeUEid);
|
||||
|
||||
LOG_I(F1AP, "Received UE CONTEXT RELEASE COMPLETE: Removing CU UE entry for RNTI %x\n", rnti);
|
||||
f1ap_remove_ue(CUtype, instance, rnti);
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
#include "f1ap_du_task.h"
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include <openair2/LAYER2/nr_pdcp/nr_pdcp.h>
|
||||
#include "openair2/LAYER2/PDCP_v10.1.0/pdcp.h"
|
||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
|
||||
#include "openair2/E1AP/e1ap.h"
|
||||
#include "gnb_config.h"
|
||||
extern unsigned char NB_gNB_INST;
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
#include "radio/ETHERNET/USERSPACE/LIB/ethernet_lib.h"
|
||||
#include "nfapi_vnf.h"
|
||||
#include "nfapi_pnf.h"
|
||||
#include "pdcp.h"
|
||||
#include "nr_pdcp/nr_pdcp_oai_api.h"
|
||||
|
||||
//#include "L1_paramdef.h"
|
||||
#include "prs_nr_paramdef.h"
|
||||
@@ -2247,6 +2247,6 @@ void nr_read_config_and_init(void) {
|
||||
}
|
||||
|
||||
if (NODE_IS_CU(RC.nrrrc[0]->node_type) && RC.nrrrc[0]->node_type != ngran_gNB_CUCP) {
|
||||
pdcp_layer_init();
|
||||
nr_pdcp_layer_init();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -701,6 +701,9 @@ int nr_rrc_mac_config_req_ue(module_id_t module_id,
|
||||
RA_config_t *ra = &mac->ra;
|
||||
fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
|
||||
|
||||
if (mac->dl_config_request == NULL) // for SIB1 reception
|
||||
mac->dl_config_request = calloc(NR_MAX_SLOTS_PER_FRAME, sizeof(*mac->dl_config_request));
|
||||
|
||||
// TODO do something FAPI-like P5 L1/L2 config interface in config_si, config_mib, etc.
|
||||
|
||||
if(mibP != NULL){
|
||||
@@ -726,9 +729,21 @@ int nr_rrc_mac_config_req_ue(module_id_t module_id,
|
||||
}
|
||||
}
|
||||
LOG_I(NR_MAC, "Initializing ul_config_request. num_slots_ul = %d\n", num_slots_ul);
|
||||
mac->ul_config_request = (fapi_nr_ul_config_request_t *)calloc(num_slots_ul, sizeof(fapi_nr_ul_config_request_t));
|
||||
mac->ul_config_request = calloc(num_slots_ul, sizeof(*mac->ul_config_request));
|
||||
for (int i=0; i<num_slots_ul; i++)
|
||||
pthread_mutex_init(&(mac->ul_config_request[i].mutex_ul_config), NULL);
|
||||
|
||||
int num_slots_dl = nr_slots_per_frame[mac->mib->subCarrierSpacingCommon];
|
||||
if (cfg->cell_config.frame_duplex_type == TDD) {
|
||||
num_slots_dl = mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots;
|
||||
if (mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols > 0) {
|
||||
num_slots_dl++;
|
||||
}
|
||||
}
|
||||
LOG_I(NR_MAC, "Initializing dl_config_request. num_slots_dl = %d\n", num_slots_dl);
|
||||
mac->dl_config_request = realloc(mac->dl_config_request, num_slots_dl*sizeof(*mac->dl_config_request));
|
||||
memset(mac->dl_config_request, 0, num_slots_dl*sizeof(fapi_nr_dl_config_request_t));
|
||||
|
||||
// Setup the SSB to Rach Occasionsif (cell_group_config->spCellConfig) { mapping according to the config
|
||||
build_ssb_to_ro_map(mac);//->scc, mac->phy_config.config_req.cell_config.frame_duplex_type);
|
||||
if (!get_softmodem_params()->emulate_l1)
|
||||
@@ -752,8 +767,8 @@ int nr_rrc_mac_config_req_ue(module_id_t module_id,
|
||||
config_control_ue(mac);
|
||||
// Setup the SSB to Rach Occasions mapping according to the config
|
||||
build_ssb_to_ro_map(mac);
|
||||
}
|
||||
else if (cell_group_config != NULL ){
|
||||
|
||||
} else if (cell_group_config != NULL) {
|
||||
LOG_I(MAC,"Applying CellGroupConfig from gNodeB\n");
|
||||
mac->cg = cell_group_config;
|
||||
if (cell_group_config->spCellConfig)
|
||||
@@ -772,20 +787,38 @@ int nr_rrc_mac_config_req_ue(module_id_t module_id,
|
||||
configure_current_BWP(mac, NULL, cell_group_config);
|
||||
config_control_ue(mac);
|
||||
|
||||
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);
|
||||
if (cell_group_config->spCellConfig && cell_group_config->spCellConfig->reconfigurationWithSync) {
|
||||
LOG_A(NR_MAC, "Received the reconfigurationWithSync in %s\n", __FUNCTION__);
|
||||
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;
|
||||
if (mac->scc_SIB) {
|
||||
free(mac->scc_SIB);
|
||||
mac->scc_SIB = NULL;
|
||||
}
|
||||
int num_slots = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
|
||||
if (mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols > 0) {
|
||||
num_slots++;
|
||||
}
|
||||
mac->state = UE_NOT_SYNC;
|
||||
mac->ra.ra_state = RA_UE_IDLE;
|
||||
mac->physCellId = *mac->scc->physCellId;
|
||||
if (!get_softmodem_params()->emulate_l1) {
|
||||
mac->synch_request.Mod_id = module_id;
|
||||
mac->synch_request.CC_id = cc_idP;
|
||||
mac->synch_request.synch_req.target_Nid_cell = mac->physCellId;
|
||||
mac->if_module->synch_request(&mac->synch_request);
|
||||
}
|
||||
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);
|
||||
|
||||
nr_ue_init_mac(module_id);
|
||||
if (!get_softmodem_params()->emulate_l1) {
|
||||
mac->if_module->phy_config_request(&mac->phy_config);
|
||||
mac->phy_config_request_sent = true;
|
||||
}
|
||||
|
||||
// Setup the SSB to Rach Occasions mapping according to the config
|
||||
|
||||
@@ -376,8 +376,9 @@ typedef struct {
|
||||
uint32_t ssb_index;
|
||||
/// SSB RSRP in dBm
|
||||
short ssb_rsrp_dBm;
|
||||
int consecutive_bch_failures;
|
||||
|
||||
} NR_PHY_meas_t;
|
||||
} NR_SSB_meas_t;
|
||||
|
||||
/*!\brief Top level UE MAC structure */
|
||||
typedef struct {
|
||||
@@ -441,11 +442,12 @@ typedef struct {
|
||||
int first_ul_tx[NR_MAX_HARQ_PROCESSES];
|
||||
//// FAPI-like interface message
|
||||
fapi_nr_ul_config_request_t *ul_config_request;
|
||||
fapi_nr_dl_config_request_t dl_config_request;
|
||||
fapi_nr_dl_config_request_t *dl_config_request;
|
||||
|
||||
/// Interface module instances
|
||||
nr_ue_if_module_t *if_module;
|
||||
nr_phy_config_t phy_config;
|
||||
nr_synch_request_t synch_request;
|
||||
|
||||
/// BSR report flag management
|
||||
uint8_t BSR_reporting_active;
|
||||
@@ -464,9 +466,9 @@ typedef struct {
|
||||
uint16_t nr_band;
|
||||
uint8_t ssb_subcarrier_offset;
|
||||
|
||||
NR_PHY_meas_t phy_measurements;
|
||||
NR_SSB_meas_t ssb_measurements;
|
||||
|
||||
dci_pdu_rel15_t def_dci_pdu_rel15[8];
|
||||
dci_pdu_rel15_t def_dci_pdu_rel15[NR_MAX_SLOTS_PER_FRAME][8];
|
||||
|
||||
// Defined for abstracted mode
|
||||
nr_downlink_indication_t dl_info;
|
||||
|
||||
@@ -190,6 +190,8 @@ int8_t nr_ue_process_csirs_measurements(module_id_t module_id, frame_t frame, in
|
||||
|
||||
uint32_t get_ssb_frame(uint32_t test);
|
||||
|
||||
void nr_ue_aperiodic_srs_scheduling(NR_UE_MAC_INST_t *mac, long resource_trigger, int frame, int slot);
|
||||
|
||||
bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac,
|
||||
PUCCH_sched_t *pucch,
|
||||
frame_t frame,
|
||||
@@ -371,7 +373,7 @@ void nr_ue_contention_resolution(module_id_t module_id, int cc_id, frame_t frame
|
||||
|
||||
void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_resources, frame_t frame, int slot);
|
||||
|
||||
void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot);
|
||||
void nr_ra_succeeded(const module_id_t mod_id, const uint8_t gNB_index, const frame_t frame, const int slot);
|
||||
|
||||
void nr_get_RA_window(NR_UE_MAC_INST_t *mac);
|
||||
|
||||
@@ -441,9 +443,11 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
|
||||
uint16_t rnti,
|
||||
int ss_type,
|
||||
uint64_t *dci_pdu,
|
||||
dci_pdu_rel15_t *dci_pdu_rel15);
|
||||
dci_pdu_rel15_t *dci_pdu_rel15,
|
||||
int slot);
|
||||
|
||||
fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot);
|
||||
fapi_nr_dl_config_request_t *get_dl_config_request(NR_UE_MAC_INST_t *mac, int slot);
|
||||
|
||||
void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type);
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp.h"
|
||||
#include "openair2/LAYER2/PDCP_v10.1.0/pdcp.h"
|
||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
|
||||
#include <pthread.h>
|
||||
|
||||
static NR_UE_MAC_INST_t *nr_ue_mac_inst;
|
||||
@@ -55,6 +55,7 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) {
|
||||
nr_ue_mac_inst->sib1_decoded = false;
|
||||
nr_ue_mac_inst->phy_config_request_sent = false;
|
||||
nr_ue_mac_inst->state = UE_NOT_SYNC;
|
||||
memset(&nr_ue_mac_inst->ssb_measurements, 0, sizeof(nr_ue_mac_inst->ssb_measurements));
|
||||
|
||||
for (int j=0;j<NB_NR_UE_MAC_INST;j++) {
|
||||
nr_ue_init_mac(j);
|
||||
@@ -65,7 +66,7 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) {
|
||||
nr_rrc_mac_config_req_ue(0,0,0,NULL,NULL,NULL,rrc_inst->scell_group_config);
|
||||
AssertFatal(rlc_module_init(0) == 0, "%s: Could not initialize RLC layer\n", __FUNCTION__);
|
||||
if (IS_SOFTMODEM_NOS1){
|
||||
pdcp_layer_init();
|
||||
nr_pdcp_layer_init();
|
||||
nr_DRB_preconfiguration(nr_ue_mac_inst->crnti);
|
||||
nr_ue_mac_inst->logicalChannelBearer_exist[0] = true;
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ int16_t get_prach_tx_power(module_id_t mod_id) {
|
||||
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
|
||||
RA_config_t *ra = &mac->ra;
|
||||
int16_t pathloss = compute_nr_SSB_PL(mac, mac->phy_measurements.ssb_rsrp_dBm);
|
||||
int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm);
|
||||
int16_t ra_preamble_rx_power = (int16_t)(ra->prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER - pathloss + 30);
|
||||
return min(nr_get_Pcmax(mod_id), ra_preamble_rx_power);
|
||||
|
||||
@@ -674,7 +674,7 @@ void nr_get_prach_resources(module_id_t mod_id,
|
||||
} else {
|
||||
/* 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 ? compute_nr_SSB_PL(mac, mac->phy_measurements.ssb_rsrp_dBm) : 0;
|
||||
int16_t dl_pathloss = !get_softmodem_params()->emulate_l1 ? compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm) : 0;
|
||||
ssb_rach_config(ra, prach_resources, nr_rach_ConfigCommon);
|
||||
ra_preambles_config(prach_resources, mac, dl_pathloss);
|
||||
LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-based random access procedure... \n", ra->ra_PreambleIndex);
|
||||
@@ -886,7 +886,7 @@ uint8_t nr_ue_get_rach(module_id_t mod_id,
|
||||
|
||||
if(ra->cfra) {
|
||||
// Reset RA_active flag: it disables Msg3 retransmission (8.3 of TS 38.213)
|
||||
nr_ra_succeeded(mod_id, frame, nr_slot_tx);
|
||||
nr_ra_succeeded(mod_id, gNB_id, frame, nr_slot_tx);
|
||||
}
|
||||
|
||||
} else if (ra->RA_window_cnt == 0 && !ra->RA_RAPID_found) {
|
||||
@@ -1001,13 +1001,14 @@ void nr_ue_contention_resolution(module_id_t module_id, int cc_id, frame_t frame
|
||||
// according to section 5 of 3GPP TS 38.321 version 16.2.1 Release 16
|
||||
// todo:
|
||||
// - complete handling of received contention-based RA preamble
|
||||
void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot){
|
||||
|
||||
void nr_ra_succeeded(const module_id_t mod_id, const uint8_t gNB_index, const frame_t frame, const int slot)
|
||||
{
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
|
||||
RA_config_t *ra = &mac->ra;
|
||||
|
||||
if (ra->cfra) {
|
||||
LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CF-RA: RAR successfully received.\n", mod_id, frame, slot);
|
||||
nr_rrc_RA_succeeded(mod_id, gNB_index);
|
||||
mac->state = UE_CONNECTED;
|
||||
ra->RA_window_cnt = -1;
|
||||
} else {
|
||||
|
||||
@@ -172,7 +172,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
|
||||
rel15->dci_length_options[i] = nr_dci_size(current_DL_BWP,
|
||||
current_UL_BWP,
|
||||
mac->cg,
|
||||
&mac->def_dci_pdu_rel15[dci_format],
|
||||
&mac->def_dci_pdu_rel15[dl_config->slot][dci_format],
|
||||
dci_format,
|
||||
NR_RNTI_TC,
|
||||
coreset,
|
||||
@@ -269,7 +269,7 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
|
||||
uint8_t bwp_id = mac->current_DL_BWP.bwp_id;
|
||||
//NR_ServingCellConfig_t *scd = mac->scg->spCellConfig->spCellConfigDedicated;
|
||||
NR_BWP_DownlinkDedicated_t *bwpd = (bwp_id>0) ? mac->DLbwp[bwp_id-1]->bwp_Dedicated : (mac->cg ? mac->cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL);
|
||||
NR_BWP_DownlinkCommon_t *bwp_Common = (bwp_id>0) ? mac->DLbwp[bwp_id-1]->bwp_Common : &mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP;
|
||||
NR_BWP_DownlinkCommon_t *bwp_Common = get_bwp_downlink_common(mac, bwp_id);
|
||||
|
||||
LOG_D(NR_MAC, "[DCI_CONFIG] ra_rnti %p (%x) crnti %p (%x) t_crnti %p (%x)\n", &ra->ra_rnti, ra->ra_rnti, &mac->crnti, mac->crnti, &ra->t_crnti, ra->t_crnti);
|
||||
|
||||
|
||||
@@ -238,6 +238,8 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
|
||||
|
||||
AssertFatal(mac->mib != NULL, "nr_ue_decode_mib() mac->mib == NULL\n");
|
||||
|
||||
mac->ssb_measurements.consecutive_bch_failures = 0; // resetting decoding failures
|
||||
|
||||
uint16_t frame = (mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused);
|
||||
uint16_t frame_number_4lsb = 0;
|
||||
|
||||
@@ -316,9 +318,6 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
|
||||
mac->first_sync_frame = frame;
|
||||
}
|
||||
|
||||
mac->dl_config_request.sfn = frame;
|
||||
mac->dl_config_request.slot = ssb_start_symbol/14;
|
||||
|
||||
if(get_softmodem_params()->phy_test)
|
||||
mac->state = UE_CONNECTED;
|
||||
else if(mac->state == UE_NOT_SYNC)
|
||||
@@ -419,15 +418,15 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *p
|
||||
int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci) {
|
||||
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
||||
dci_pdu_rel15_t *def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[dci->dci_format];
|
||||
dci_pdu_rel15_t *def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[slot][dci->dci_format];
|
||||
|
||||
LOG_D(MAC,"Received dci indication (rnti %x,dci format %d,n_CCE %d,payloadSize %d,payload %llx)\n",
|
||||
dci->rnti,dci->dci_format,dci->n_CCE,dci->payloadSize,*(unsigned long long*)dci->payloadBits);
|
||||
int8_t ret = nr_extract_dci_info(mac, dci->dci_format, dci->payloadSize, dci->rnti, dci->ss_type, (uint64_t *)dci->payloadBits, def_dci_pdu_rel15);
|
||||
int8_t ret = nr_extract_dci_info(mac, dci->dci_format, dci->payloadSize, dci->rnti, dci->ss_type, (uint64_t *)dci->payloadBits, def_dci_pdu_rel15, slot);
|
||||
if ((ret&1) == 1) return -1;
|
||||
else if (ret == 2) {
|
||||
dci->dci_format = NR_UL_DCI_FORMAT_0_0;
|
||||
def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[dci->dci_format];
|
||||
def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[slot][dci->dci_format];
|
||||
}
|
||||
int8_t ret_proc = nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, def_dci_pdu_rel15, dci);
|
||||
return ret_proc;
|
||||
@@ -445,7 +444,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
|
||||
bool valid_ptrs_setup = 0;
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
||||
RA_config_t *ra = &mac->ra;
|
||||
fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request;
|
||||
fapi_nr_dl_config_request_t *dl_config = get_dl_config_request(mac, slot);
|
||||
uint8_t is_Msg3 = 0;
|
||||
NR_UE_DL_BWP_t *current_DL_BWP = &mac->current_DL_BWP;
|
||||
NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP;
|
||||
@@ -541,6 +540,11 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
|
||||
// - SECOND_DAI
|
||||
// - SRS_RESOURCE_IND
|
||||
|
||||
/* SRS_REQUEST */
|
||||
AssertFatal(dci->srs_request.nbits == 2, "If SUL is supported in the cell, there is an additional bit in SRS request field\n");
|
||||
if(dci->srs_request.val > 0)
|
||||
nr_ue_aperiodic_srs_scheduling(mac, dci->srs_request.val, frame, slot);
|
||||
|
||||
// Schedule PUSCH
|
||||
tda_info = get_ul_tda_info(current_UL_BWP, coreset_type, dci_ind->ss_type, get_rnti_type(mac, rnti), dci->time_domain_assignment.val);
|
||||
if (tda_info.nrOfSymbols == 0)
|
||||
@@ -686,7 +690,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,
|
||||
NR_DL_DCI_FORMAT_1_0,
|
||||
(get_softmodem_params()->nsa) ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position,
|
||||
mac->scc ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position,
|
||||
dlsch_config_pdu_1_0->number_symbols,
|
||||
dlsch_config_pdu_1_0->start_symbol,
|
||||
tda_info.mapping_type,
|
||||
@@ -809,6 +813,8 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
|
||||
dlsch_config_pdu_1_0->accumulated_delta_PUCCH,
|
||||
dci->pucch_resource_indicator,
|
||||
1+dci->pdsch_to_harq_feedback_timing_indicator.val);
|
||||
|
||||
dlsch_config_pdu_1_0->k1_feedback = 1+dci->pdsch_to_harq_feedback_timing_indicator.val;
|
||||
|
||||
LOG_D(MAC,"(nr_ue_procedures.c) pdu_type=%d\n\n",dl_config->dl_config_list[dl_config->number_pdus].pdu_type);
|
||||
|
||||
@@ -1071,14 +1077,15 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
|
||||
dlsch_config_pdu_1_1->n_front_load_symb);
|
||||
|
||||
/* TCI */
|
||||
if (mac->dl_config_request.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.tci_present_in_dci == 1){
|
||||
if (dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.coreset.tci_present_in_dci == 1){
|
||||
// 0 bit if higher layer parameter tci-PresentInDCI is not enabled
|
||||
// otherwise 3 bits as defined in Subclause 5.1.5 of [6, TS38.214]
|
||||
dlsch_config_pdu_1_1->tci_state = dci->transmission_configuration_indication.val;
|
||||
}
|
||||
/* SRS_REQUEST */
|
||||
// if SUL is supported in the cell, there is an additional bit in this field and the value of this bit represents table 7.1.1.1-1 TS 38.212 FIXME!!!
|
||||
dlsch_config_pdu_1_1->srs_config.aperiodicSRS_ResourceTrigger = (dci->srs_request.val & 0x11); // as per Table 7.3.1.1.2-24 TS 38.212
|
||||
AssertFatal(dci->srs_request.nbits == 2, "If SUL is supported in the cell, there is an additional bit in SRS request field\n");
|
||||
if(dci->srs_request.val > 0 )
|
||||
nr_ue_aperiodic_srs_scheduling(mac, dci->srs_request.val, frame, slot);
|
||||
/* CBGTI */
|
||||
dlsch_config_pdu_1_1->cbgti = dci->cbgti.val;
|
||||
/* CBGFI */
|
||||
@@ -1106,6 +1113,10 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
|
||||
LOG_D(MAC,"(nr_ue_procedures.c) pdu_type=%d\n\n",dl_config->dl_config_list[dl_config->number_pdus].pdu_type);
|
||||
|
||||
dl_config->number_pdus = dl_config->number_pdus + 1;
|
||||
|
||||
// send the ack/nack slot number to phy to indicate tx thread to wait for DLSCH decoding
|
||||
dlsch_config_pdu_1_1->k1_feedback = feedback_ti;
|
||||
|
||||
/* 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;
|
||||
dlsch_config_pdu_1_1->qamModOrder = nr_get_Qm_dl(dlsch_config_pdu_1_1->mcs, dlsch_config_pdu_1_1->mcs_table);
|
||||
@@ -1208,14 +1219,12 @@ 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;
|
||||
if (get_softmodem_params()->emulate_l1) {
|
||||
int scs = get_softmodem_params()->numerology;
|
||||
int slots_per_frame = nr_slots_per_frame[scs];
|
||||
slot += data_toul_fb;
|
||||
if (slot >= slots_per_frame) {
|
||||
frame = (frame + 1) % 1024;
|
||||
slot %= slots_per_frame;
|
||||
}
|
||||
int scs = get_softmodem_params()->numerology;
|
||||
int slots_per_frame = nr_slots_per_frame[scs];
|
||||
slot += data_toul_fb;
|
||||
if (slot >= slots_per_frame) {
|
||||
frame = (frame + 1) % 1024;
|
||||
slot %= slots_per_frame;
|
||||
}
|
||||
|
||||
LOG_D(NR_PHY,"Setting harq_status for harq_id %d, dl %d.%d, sched ul %d.%d\n",
|
||||
@@ -1564,7 +1573,7 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
|
||||
return (PUCCH_POWER_DEFAULT);
|
||||
}
|
||||
|
||||
int16_t pathloss = compute_nr_SSB_PL(mac, mac->phy_measurements.ssb_rsrp_dBm);
|
||||
int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm);
|
||||
int M_pucch_component = (10 * log10((double)(pow(2,scs) * nb_of_prbs)));
|
||||
|
||||
int16_t pucch_power = P_O_PUCCH + M_pucch_component + pathloss + delta_F_PUCCH + DELTA_TF + G_b_f_c;
|
||||
@@ -1820,10 +1829,14 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac,
|
||||
}
|
||||
|
||||
number_harq_feedback++;
|
||||
if (current_harq->ack_received)
|
||||
if (current_harq->ack_received) {
|
||||
ack_data[code_word][dai_current - 1] = current_harq->ack;
|
||||
else
|
||||
current_harq->active = false;
|
||||
current_harq->ack_received = false;
|
||||
} else {
|
||||
LOG_W(NR_MAC, "DLSCH ACK/NACK reporting initiated for harq pid %d before DLSCH decoding completed\n", dl_harq_pid);
|
||||
ack_data[code_word][dai_current - 1] = 0;
|
||||
}
|
||||
dai[code_word][dai_current - 1] = dai_current;
|
||||
|
||||
pucch->resource_indicator = current_harq->pucch_resource_indicator;
|
||||
@@ -1831,9 +1844,7 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac,
|
||||
pucch->N_CCE = current_harq->N_CCE;
|
||||
pucch->delta_pucch = current_harq->delta_pucch;
|
||||
pucch->is_common = current_harq->is_common;
|
||||
current_harq->active = false;
|
||||
current_harq->ack_received = false;
|
||||
LOG_D(PHY,"%4d.%2d Sent %d ack on harq pid %d\n", frame, slot, current_harq->ack, dl_harq_pid);
|
||||
LOG_D(PHY,"%4d.%2d Sent %d ack on harq pid %d\n", frame, slot, current_harq->ack, dl_harq_pid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2179,7 +2190,7 @@ uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
|
||||
}
|
||||
}
|
||||
AssertFatal(*SSB_resource.list.array[ssb_rsrp[0][0]] == mac->mib_ssb, "Couldn't find corresponding SSB in csi_SSB_ResourceList\n");
|
||||
ssb_rsrp[1][0] = mac->phy_measurements.ssb_rsrp_dBm;
|
||||
ssb_rsrp[1][0] = mac->ssb_measurements.ssb_rsrp_dBm;
|
||||
|
||||
uint8_t ssbi;
|
||||
|
||||
@@ -2398,7 +2409,8 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
|
||||
uint16_t rnti,
|
||||
int ss_type,
|
||||
uint64_t *dci_pdu,
|
||||
dci_pdu_rel15_t *dci_pdu_rel15)
|
||||
dci_pdu_rel15_t *dci_pdu_rel15,
|
||||
int slot)
|
||||
{
|
||||
|
||||
int pos = 0;
|
||||
@@ -2421,6 +2433,7 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
|
||||
switch(dci_format) {
|
||||
|
||||
case NR_DL_DCI_FORMAT_1_0:
|
||||
|
||||
switch(rnti_type) {
|
||||
case NR_RNTI_RA:
|
||||
// Freq domain assignment
|
||||
@@ -2465,8 +2478,8 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
|
||||
|
||||
//switch to DCI_0_0
|
||||
if (dci_pdu_rel15->format_indicator == 0) {
|
||||
dci_pdu_rel15 = &mac->def_dci_pdu_rel15[NR_UL_DCI_FORMAT_0_0];
|
||||
return 2+nr_extract_dci_info(mac, NR_UL_DCI_FORMAT_0_0, dci_size, rnti, ss_type, dci_pdu, dci_pdu_rel15);
|
||||
dci_pdu_rel15 = &mac->def_dci_pdu_rel15[slot][NR_UL_DCI_FORMAT_0_0];
|
||||
return 2+nr_extract_dci_info(mac, NR_UL_DCI_FORMAT_0_0, dci_size, rnti, ss_type, dci_pdu, dci_pdu_rel15, slot);
|
||||
}
|
||||
#ifdef DEBUG_EXTRACT_DCI
|
||||
LOG_D(MAC,"Format indicator %d (%d bits) N_RB_BWP %d => %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,N_RB,dci_size-pos,*dci_pdu);
|
||||
@@ -2656,13 +2669,10 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
|
||||
|
||||
//switch to DCI_0_0
|
||||
if (dci_pdu_rel15->format_indicator == 0) {
|
||||
dci_pdu_rel15 = &mac->def_dci_pdu_rel15[NR_UL_DCI_FORMAT_0_0];
|
||||
return 2+nr_extract_dci_info(mac, NR_UL_DCI_FORMAT_0_0, dci_size, rnti, ss_type, dci_pdu, dci_pdu_rel15);
|
||||
dci_pdu_rel15 = &mac->def_dci_pdu_rel15[slot][NR_UL_DCI_FORMAT_0_0];
|
||||
return 2+nr_extract_dci_info(mac, NR_UL_DCI_FORMAT_0_0, dci_size, rnti, ss_type, dci_pdu, dci_pdu_rel15, slot);
|
||||
}
|
||||
|
||||
if (dci_pdu_rel15->format_indicator == 0)
|
||||
return 1; // discard dci, format indicator not corresponding to dci_format
|
||||
|
||||
// Freq domain assignment 0-16 bit
|
||||
fsize = (int)ceil(log2((N_RB * (N_RB + 1)) >> 1));
|
||||
pos+=fsize;
|
||||
@@ -3256,7 +3266,7 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
||||
}
|
||||
|
||||
if ( (ra->RA_active == 1) && ra_success) {
|
||||
nr_ra_succeeded(module_idP, frameP, slot);
|
||||
nr_ra_succeeded(module_idP, gNB_index, frameP, slot);
|
||||
} else if (!ra_success){
|
||||
// TODO: Handle failure of RA procedure @ MAC layer
|
||||
// nr_ra_failed(module_idP, CC_id, prach_resources, frameP, slot); // prach_resources is a PHY structure
|
||||
@@ -3274,41 +3284,26 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
||||
// check if LCID is valid at current time.
|
||||
case DL_SCH_LCID_DCCH1:
|
||||
// check if LCID is valid at current time.
|
||||
case DL_SCH_LCID_DTCH ... (DL_SCH_LCID_DTCH + 28):
|
||||
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
||||
return;
|
||||
LOG_D(NR_MAC, "%4d.%2d : DLSCH -> LCID %d %d bytes\n", frameP, slot, rx_lcid, mac_len);
|
||||
|
||||
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_len,
|
||||
1,
|
||||
NULL);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
||||
return;
|
||||
LOG_D(NR_MAC, "[UE %d] %4d.%2d : DLSCH -> DL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, slot, rx_lcid, gNB_index, mac_len);
|
||||
|
||||
#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]);
|
||||
|
||||
LOG_T(MAC, "\n");
|
||||
#endif
|
||||
|
||||
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_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;
|
||||
}
|
||||
LOG_W(MAC, "unknown lcid %02x\n", rx_lcid);
|
||||
break;
|
||||
}
|
||||
pduP += ( mac_subheader_len + mac_len );
|
||||
pdu_len -= ( mac_subheader_len + mac_len );
|
||||
|
||||
@@ -112,11 +112,8 @@ fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int sl
|
||||
|
||||
NR_TDD_UL_DL_ConfigCommon_t *tdd_config = mac->scc==NULL ? mac->scc_SIB->tdd_UL_DL_ConfigurationCommon : mac->scc->tdd_UL_DL_ConfigurationCommon;
|
||||
|
||||
//Check if request to access ul_config is for a UL slot
|
||||
if (is_nr_UL_slot(tdd_config, slot, mac->frame_type) == 0) {
|
||||
LOG_W(NR_MAC, "Slot %d is not a UL slot. %s called for wrong slot!!!\n", slot, __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
//Check if requested on the right slot
|
||||
AssertFatal(is_nr_UL_slot(tdd_config, slot, mac->frame_type) != 0, "%s called at wrong slot %d\n", __func__, slot);
|
||||
|
||||
// Calculate the index of the UL slot in mac->ul_config_request list. This is
|
||||
// based on the TDD pattern (slot configuration period) and number of UL+mixed
|
||||
@@ -127,16 +124,57 @@ fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int sl
|
||||
const int num_slots_ul = tdd_config ? (tdd_config->pattern1.nrofUplinkSlots + (tdd_config->pattern1.nrofUplinkSymbols != 0)) : n;
|
||||
int index = slot % num_slots_ul;
|
||||
|
||||
LOG_D(NR_MAC, "In %s slots per %s: %d, num_slots_ul %d, index %d\n",
|
||||
LOG_D(NR_MAC, "In %s slots per %s: %d, num_slots %d, index %d\n",
|
||||
__FUNCTION__,
|
||||
tdd_config ? "TDD" : "FDD",
|
||||
num_slots_per_tdd,
|
||||
num_slots_ul,
|
||||
index);
|
||||
|
||||
if(!mac->ul_config_request)
|
||||
if (mac->ul_config_request) return &mac->ul_config_request[index];
|
||||
else {
|
||||
LOG_E(NR_MAC, "mac->ul_config_request not set\n");
|
||||
return NULL;
|
||||
return &mac->ul_config_request[index];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function returns the DL config corresponding to a given DL slot
|
||||
* from MAC instance .
|
||||
*/
|
||||
fapi_nr_dl_config_request_t *get_dl_config_request(NR_UE_MAC_INST_t *mac, int slot)
|
||||
{
|
||||
int index;
|
||||
if (!mac->scc && !mac->scc_SIB)
|
||||
index = 0;
|
||||
else {
|
||||
NR_TDD_UL_DL_ConfigCommon_t *tdd_config = mac->scc==NULL ? mac->scc_SIB->tdd_UL_DL_ConfigurationCommon : mac->scc->tdd_UL_DL_ConfigurationCommon;
|
||||
|
||||
//Check if requested on the right slot
|
||||
AssertFatal(is_nr_DL_slot(tdd_config, slot) != 0, "%s called at wrong slot %d\n", __func__, slot);
|
||||
|
||||
// Calculate the index of the DL slot in mac->ul_config_request list. This is
|
||||
// based on the TDD pattern (slot configuration period) and number of DL+mixed
|
||||
// slots in the period. TS 38.213 Sec 11.1
|
||||
int mu = mac->current_UL_BWP.scs;
|
||||
const int n = nr_slots_per_frame[mu];
|
||||
const int num_slots_per_tdd = tdd_config ? (n >> (7 - tdd_config->pattern1.dl_UL_TransmissionPeriodicity)) : n;
|
||||
const int num_slots_dl = tdd_config ? (tdd_config->pattern1.nrofDownlinkSlots + (tdd_config->pattern1.nrofDownlinkSymbols != 0)) : n;
|
||||
|
||||
index = slot % num_slots_dl;
|
||||
LOG_D(NR_MAC, "In %s slots per %s: %d, num_slots %d, index %d\n",
|
||||
__FUNCTION__,
|
||||
tdd_config ? "TDD" : "FDD",
|
||||
num_slots_per_tdd,
|
||||
num_slots_dl,
|
||||
index);
|
||||
}
|
||||
|
||||
if (mac->dl_config_request) return &mac->dl_config_request[index];
|
||||
else {
|
||||
LOG_E(NR_MAC, "mac->dl_config_request not set\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void ul_layers_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, dci_pdu_rel15_t *dci, nr_dci_format_t dci_format)
|
||||
@@ -495,7 +533,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
|
||||
|
||||
#ifdef DEBUG_MSG3
|
||||
LOG_D(NR_MAC, "In %s BWP assignment (BWP (start %d, size %d) \n", __FUNCTION__, pusch_config_pdu->bwp_start, pusch_config_pdu->bwp_size);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// MCS
|
||||
pusch_config_pdu->mcs_index = rar_grant->mcs;
|
||||
@@ -763,6 +801,140 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
|
||||
|
||||
}
|
||||
|
||||
void configure_srs_pdu(NR_UE_MAC_INST_t *mac,
|
||||
NR_SRS_Resource_t *srs_resource,
|
||||
fapi_nr_ul_config_srs_pdu *srs_config_pdu,
|
||||
int period, int offset)
|
||||
{
|
||||
NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP;
|
||||
|
||||
srs_config_pdu->rnti = mac->crnti;
|
||||
srs_config_pdu->handle = 0;
|
||||
srs_config_pdu->bwp_size = current_UL_BWP->BWPSize;
|
||||
srs_config_pdu->bwp_start = current_UL_BWP->BWPStart;
|
||||
srs_config_pdu->subcarrier_spacing = current_UL_BWP->scs;
|
||||
srs_config_pdu->cyclic_prefix = 0;
|
||||
srs_config_pdu->num_ant_ports = srs_resource->nrofSRS_Ports;
|
||||
srs_config_pdu->num_symbols = srs_resource->resourceMapping.nrofSymbols;
|
||||
srs_config_pdu->num_repetitions = srs_resource->resourceMapping.repetitionFactor;
|
||||
srs_config_pdu->time_start_position = srs_resource->resourceMapping.startPosition;
|
||||
srs_config_pdu->config_index = srs_resource->freqHopping.c_SRS;
|
||||
srs_config_pdu->sequence_id = srs_resource->sequenceId;
|
||||
srs_config_pdu->bandwidth_index = srs_resource->freqHopping.b_SRS;
|
||||
srs_config_pdu->comb_size = srs_resource->transmissionComb.present - 1;
|
||||
|
||||
switch(srs_resource->transmissionComb.present) {
|
||||
case NR_SRS_Resource__transmissionComb_PR_n2:
|
||||
srs_config_pdu->comb_offset = srs_resource->transmissionComb.choice.n2->combOffset_n2;
|
||||
srs_config_pdu->cyclic_shift = srs_resource->transmissionComb.choice.n2->cyclicShift_n2;
|
||||
break;
|
||||
case NR_SRS_Resource__transmissionComb_PR_n4:
|
||||
srs_config_pdu->comb_offset = srs_resource->transmissionComb.choice.n4->combOffset_n4;
|
||||
srs_config_pdu->cyclic_shift = srs_resource->transmissionComb.choice.n4->cyclicShift_n4;
|
||||
break;
|
||||
default:
|
||||
LOG_W(NR_MAC, "Invalid or not implemented comb_size!\n");
|
||||
}
|
||||
|
||||
srs_config_pdu->frequency_position = srs_resource->freqDomainPosition;
|
||||
srs_config_pdu->frequency_shift = srs_resource->freqDomainShift;
|
||||
srs_config_pdu->frequency_hopping = srs_resource->freqHopping.b_hop;
|
||||
srs_config_pdu->group_or_sequence_hopping = srs_resource->groupOrSequenceHopping;
|
||||
srs_config_pdu->resource_type = srs_resource->resourceType.present - 1;
|
||||
if(srs_config_pdu->resource_type > 0) { // not aperiodic
|
||||
srs_config_pdu->t_srs = period;
|
||||
srs_config_pdu->t_offset = offset;
|
||||
}
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
LOG_I(NR_MAC,"Frame = %i, slot = %i\n", frame, slot);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->rnti = 0x%04x\n", srs_config_pdu->rnti);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->handle = %u\n", srs_config_pdu->handle);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->bwp_size = %u\n", srs_config_pdu->bwp_size);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->bwp_start = %u\n", srs_config_pdu->bwp_start);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->subcarrier_spacing = %u\n", srs_config_pdu->subcarrier_spacing);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->cyclic_prefix = %u (0: Normal; 1: Extended)\n", srs_config_pdu->cyclic_prefix);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->num_ant_ports = %u (0 = 1 port, 1 = 2 ports, 2 = 4 ports)\n", srs_config_pdu->num_ant_ports);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->num_symbols = %u (0 = 1 symbol, 1 = 2 symbols, 2 = 4 symbols)\n", srs_config_pdu->num_symbols);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->num_repetitions = %u (0 = 1, 1 = 2, 2 = 4)\n", srs_config_pdu->num_repetitions);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->time_start_position = %u\n", srs_config_pdu->time_start_position);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->config_index = %u\n", srs_config_pdu->config_index);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->sequence_id = %u\n", srs_config_pdu->sequence_id);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->bandwidth_index = %u\n", srs_config_pdu->bandwidth_index);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->comb_size = %u (0 = comb size 2, 1 = comb size 4, 2 = comb size 8)\n", srs_config_pdu->comb_size);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->comb_offset = %u\n", srs_config_pdu->comb_offset);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->cyclic_shift = %u\n", srs_config_pdu->cyclic_shift);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->frequency_position = %u\n", srs_config_pdu->frequency_position);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->frequency_shift = %u\n", srs_config_pdu->frequency_shift);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->frequency_hopping = %u\n", srs_config_pdu->frequency_hopping);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->group_or_sequence_hopping = %u (0 = No hopping, 1 = Group hopping groupOrSequenceHopping, 2 = Sequence hopping)\n", srs_config_pdu->group_or_sequence_hopping);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->resource_type = %u (0: aperiodic, 1: semi-persistent, 2: periodic)\n", srs_config_pdu->resource_type);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->t_srs = %u\n", srs_config_pdu->t_srs);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->t_offset = %u\n", srs_config_pdu->t_offset);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Aperiodic SRS scheduling
|
||||
void nr_ue_aperiodic_srs_scheduling(NR_UE_MAC_INST_t *mac, long resource_trigger, int frame, int slot)
|
||||
{
|
||||
NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP;
|
||||
NR_SRS_Config_t *srs_config = current_UL_BWP->srs_Config;
|
||||
|
||||
if (!srs_config) {
|
||||
LOG_E(NR_MAC, "DCI is triggering aperiodic SRS but there is no SRS configuration\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int slot_offset = 0;
|
||||
NR_SRS_Resource_t *srs_resource = NULL;
|
||||
for(int rs = 0; rs < srs_config->srs_ResourceSetToAddModList->list.count; rs++) {
|
||||
|
||||
// Find aperiodic resource set
|
||||
NR_SRS_ResourceSet_t *srs_resource_set = srs_config->srs_ResourceSetToAddModList->list.array[rs];
|
||||
if(srs_resource_set->resourceType.present != NR_SRS_ResourceSet__resourceType_PR_aperiodic)
|
||||
continue;
|
||||
// the resource trigger need to match the DCI one
|
||||
if(srs_resource_set->resourceType.choice.aperiodic->aperiodicSRS_ResourceTrigger != resource_trigger)
|
||||
continue;
|
||||
// if slotOffset is null -> offset = 0
|
||||
if(srs_resource_set->resourceType.choice.aperiodic->slotOffset)
|
||||
slot_offset = *srs_resource_set->resourceType.choice.aperiodic->slotOffset;
|
||||
|
||||
// Find the corresponding srs resource
|
||||
for(int r1 = 0; r1 < srs_resource_set->srs_ResourceIdList->list.count; r1++) {
|
||||
for (int r2 = 0; r2 < srs_config->srs_ResourceToAddModList->list.count; r2++) {
|
||||
if ((*srs_resource_set->srs_ResourceIdList->list.array[r1] == srs_config->srs_ResourceToAddModList->list.array[r2]->srs_ResourceId) &&
|
||||
(srs_config->srs_ResourceToAddModList->list.array[r2]->resourceType.present == NR_SRS_Resource__resourceType_PR_aperiodic)) {
|
||||
srs_resource = srs_config->srs_ResourceToAddModList->list.array[r2];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(srs_resource == NULL) {
|
||||
LOG_E(NR_MAC, "Couldn't find SRS aperiodic resource with trigger %ld\n", resource_trigger);
|
||||
return;
|
||||
}
|
||||
|
||||
AssertFatal(slot_offset >= DURATION_RX_TO_TX,"Slot offset between DCI and aperiodic SRS (%d) cannot be less than DURATION_RX_TO_TX (%d)\n",
|
||||
slot_offset, DURATION_RX_TO_TX);
|
||||
int n_slots_frame = nr_slots_per_frame[current_UL_BWP->scs];
|
||||
int sched_slot = (slot + slot_offset) % n_slots_frame;
|
||||
NR_TDD_UL_DL_ConfigCommon_t *tdd_config = mac->scc==NULL ? mac->scc_SIB->tdd_UL_DL_ConfigurationCommon : mac->scc->tdd_UL_DL_ConfigurationCommon;
|
||||
if (!is_nr_UL_slot(tdd_config, sched_slot, mac->frame_type)) {
|
||||
LOG_E(NR_MAC, "Slot for scheduling aperiodic SRS %d is not an UL slot\n", sched_slot);
|
||||
return;
|
||||
}
|
||||
int sched_frame = frame + (slot + slot_offset >= n_slots_frame) % 1024;
|
||||
|
||||
fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, sched_slot);
|
||||
fapi_nr_ul_config_srs_pdu *srs_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].srs_config_pdu;
|
||||
configure_srs_pdu(mac, srs_resource, srs_config_pdu, 0, 0);
|
||||
fill_ul_config(ul_config, sched_frame, sched_slot, FAPI_NR_UL_CONFIG_TYPE_SRS);
|
||||
}
|
||||
|
||||
|
||||
// Periodic SRS scheduling
|
||||
bool nr_ue_periodic_srs_scheduling(module_id_t mod_id, frame_t frame, slot_t slot)
|
||||
{
|
||||
@@ -812,68 +984,7 @@ bool nr_ue_periodic_srs_scheduling(module_id_t mod_id, frame_t frame, slot_t slo
|
||||
fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot);
|
||||
fapi_nr_ul_config_srs_pdu *srs_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].srs_config_pdu;
|
||||
|
||||
srs_config_pdu->rnti = mac->crnti;
|
||||
srs_config_pdu->handle = 0;
|
||||
srs_config_pdu->bwp_size = current_UL_BWP->BWPSize;
|
||||
srs_config_pdu->bwp_start = current_UL_BWP->BWPStart;
|
||||
srs_config_pdu->subcarrier_spacing = current_UL_BWP->scs;
|
||||
srs_config_pdu->cyclic_prefix = 0;
|
||||
srs_config_pdu->num_ant_ports = srs_resource->nrofSRS_Ports;
|
||||
srs_config_pdu->num_symbols = srs_resource->resourceMapping.nrofSymbols;
|
||||
srs_config_pdu->num_repetitions = srs_resource->resourceMapping.repetitionFactor;
|
||||
srs_config_pdu->time_start_position = srs_resource->resourceMapping.startPosition;
|
||||
srs_config_pdu->config_index = srs_resource->freqHopping.c_SRS;
|
||||
srs_config_pdu->sequence_id = srs_resource->sequenceId;
|
||||
srs_config_pdu->bandwidth_index = srs_resource->freqHopping.b_SRS;
|
||||
srs_config_pdu->comb_size = srs_resource->transmissionComb.present - 1;
|
||||
|
||||
switch(srs_resource->transmissionComb.present) {
|
||||
case NR_SRS_Resource__transmissionComb_PR_n2:
|
||||
srs_config_pdu->comb_offset = srs_resource->transmissionComb.choice.n2->combOffset_n2;
|
||||
srs_config_pdu->cyclic_shift = srs_resource->transmissionComb.choice.n2->cyclicShift_n2;
|
||||
break;
|
||||
case NR_SRS_Resource__transmissionComb_PR_n4:
|
||||
srs_config_pdu->comb_offset = srs_resource->transmissionComb.choice.n4->combOffset_n4;
|
||||
srs_config_pdu->cyclic_shift = srs_resource->transmissionComb.choice.n4->cyclicShift_n4;
|
||||
break;
|
||||
default:
|
||||
LOG_W(NR_MAC, "Invalid or not implemented comb_size!\n");
|
||||
}
|
||||
|
||||
srs_config_pdu->frequency_position = srs_resource->freqDomainPosition;
|
||||
srs_config_pdu->frequency_shift = srs_resource->freqDomainShift;
|
||||
srs_config_pdu->frequency_hopping = srs_resource->freqHopping.b_hop;
|
||||
srs_config_pdu->group_or_sequence_hopping = srs_resource->groupOrSequenceHopping;
|
||||
srs_config_pdu->resource_type = srs_resource->resourceType.present - 1;
|
||||
srs_config_pdu->t_srs = period;
|
||||
srs_config_pdu->t_offset = offset;
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
LOG_I(NR_MAC,"Frame = %i, slot = %i\n", frame, slot);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->rnti = 0x%04x\n", srs_config_pdu->rnti);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->handle = %u\n", srs_config_pdu->handle);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->bwp_size = %u\n", srs_config_pdu->bwp_size);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->bwp_start = %u\n", srs_config_pdu->bwp_start);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->subcarrier_spacing = %u\n", srs_config_pdu->subcarrier_spacing);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->cyclic_prefix = %u (0: Normal; 1: Extended)\n", srs_config_pdu->cyclic_prefix);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->num_ant_ports = %u (0 = 1 port, 1 = 2 ports, 2 = 4 ports)\n", srs_config_pdu->num_ant_ports);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->num_symbols = %u (0 = 1 symbol, 1 = 2 symbols, 2 = 4 symbols)\n", srs_config_pdu->num_symbols);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->num_repetitions = %u (0 = 1, 1 = 2, 2 = 4)\n", srs_config_pdu->num_repetitions);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->time_start_position = %u\n", srs_config_pdu->time_start_position);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->config_index = %u\n", srs_config_pdu->config_index);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->sequence_id = %u\n", srs_config_pdu->sequence_id);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->bandwidth_index = %u\n", srs_config_pdu->bandwidth_index);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->comb_size = %u (0 = comb size 2, 1 = comb size 4, 2 = comb size 8)\n", srs_config_pdu->comb_size);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->comb_offset = %u\n", srs_config_pdu->comb_offset);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->cyclic_shift = %u\n", srs_config_pdu->cyclic_shift);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->frequency_position = %u\n", srs_config_pdu->frequency_position);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->frequency_shift = %u\n", srs_config_pdu->frequency_shift);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->frequency_hopping = %u\n", srs_config_pdu->frequency_hopping);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->group_or_sequence_hopping = %u (0 = No hopping, 1 = Group hopping groupOrSequenceHopping, 2 = Sequence hopping)\n", srs_config_pdu->group_or_sequence_hopping);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->resource_type = %u (0: aperiodic, 1: semi-persistent, 2: periodic)\n", srs_config_pdu->resource_type);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->t_srs = %u\n", srs_config_pdu->t_srs);
|
||||
LOG_I(NR_MAC,"srs_config_pdu->t_offset = %u\n", srs_config_pdu->t_offset);
|
||||
#endif
|
||||
configure_srs_pdu(mac, srs_resource, srs_config_pdu, period, offset);
|
||||
|
||||
fill_ul_config(ul_config, frame, slot, FAPI_NR_UL_CONFIG_TYPE_SRS);
|
||||
srs_scheduled = true;
|
||||
@@ -895,7 +1006,9 @@ void nr_ue_dl_scheduler(nr_downlink_indication_t *dl_info)
|
||||
slot_t rx_slot = dl_info->slot;
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
|
||||
|
||||
fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request;
|
||||
fapi_nr_dl_config_request_t *dl_config = get_dl_config_request(mac, rx_slot);
|
||||
dl_config->sfn = rx_frame;
|
||||
dl_config->slot = rx_slot;
|
||||
|
||||
nr_scheduled_response_t scheduled_response;
|
||||
nr_dcireq_t dcireq;
|
||||
@@ -909,11 +1022,11 @@ void nr_ue_dl_scheduler(nr_downlink_indication_t *dl_info)
|
||||
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;
|
||||
*dl_config = dcireq.dl_config_req;
|
||||
|
||||
nr_schedule_csirs_reception(mac, rx_frame, rx_slot);
|
||||
nr_schedule_csi_for_im(mac, rx_frame, rx_slot);
|
||||
dcireq.dl_config_req = mac->dl_config_request;
|
||||
dcireq.dl_config_req = *dl_config;
|
||||
|
||||
fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->phy_data);
|
||||
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) {
|
||||
@@ -1399,6 +1512,8 @@ int nr_ue_pusch_scheduler(NR_UE_MAC_INST_t *mac, uint8_t is_Msg3, frame_t curren
|
||||
case 3:
|
||||
delta = 6;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1 == 0, "Invalid numerology %i\n", mu);
|
||||
}
|
||||
|
||||
AssertFatal((k2 + delta) >= DURATION_RX_TO_TX,
|
||||
@@ -2175,7 +2290,7 @@ void nr_schedule_csi_for_im(NR_UE_MAC_INST_t *mac, int frame, int slot) {
|
||||
if (csi_measconfig->csi_IM_ResourceToAddModList == NULL)
|
||||
return;
|
||||
|
||||
fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request;
|
||||
fapi_nr_dl_config_request_t *dl_config = get_dl_config_request(mac, slot);
|
||||
NR_CSI_IM_Resource_t *imcsi;
|
||||
int period, offset;
|
||||
|
||||
@@ -2229,7 +2344,7 @@ void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot) {
|
||||
if (csi_measconfig->nzp_CSI_RS_ResourceToAddModList == NULL)
|
||||
return;
|
||||
|
||||
fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request;
|
||||
fapi_nr_dl_config_request_t *dl_config = get_dl_config_request(mac, slot);
|
||||
NR_NZP_CSI_RS_Resource_t *nzpcsi;
|
||||
int period, offset;
|
||||
NR_UE_DL_BWP_t *current_DL_BWP = &mac->current_DL_BWP;
|
||||
@@ -2551,9 +2666,6 @@ void nr_ue_sib1_scheduler(module_id_t module_idP,
|
||||
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
|
||||
nr_scheduled_response_t scheduled_response;
|
||||
int frame_s,slot_s;
|
||||
fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request;
|
||||
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15;
|
||||
|
||||
uint8_t scs_ssb = get_softmodem_params()->numerology;
|
||||
uint16_t ssb_offset_point_a = (ssb_start_subcarrier - ssb_subcarrier_offset)/12;
|
||||
@@ -2571,17 +2683,7 @@ void nr_ue_sib1_scheduler(module_id_t module_idP,
|
||||
1, // If the UE is not configured with a periodicity, the UE assumes a periodicity of a half frame
|
||||
ssb_offset_point_a);
|
||||
|
||||
if(mac->search_space_zero == NULL) mac->search_space_zero=calloc(1,sizeof(*mac->search_space_zero));
|
||||
if(mac->coreset0 == NULL) mac->coreset0 = calloc(1,sizeof(*mac->coreset0));
|
||||
|
||||
fill_coresetZero(mac->coreset0, &mac->type0_PDCCH_CSS_config);
|
||||
fill_searchSpaceZero(mac->search_space_zero, &mac->type0_PDCCH_CSS_config);
|
||||
rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15;
|
||||
rel15->num_dci_options = 1;
|
||||
rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0;
|
||||
config_dci_pdu(mac, rel15, dl_config, NR_RNTI_SI, -1);
|
||||
fill_dci_search_candidates(mac->search_space_zero, rel15, -1, -1);
|
||||
|
||||
int frame_s,slot_s;
|
||||
if(mac->type0_PDCCH_CSS_config.type0_pdcch_ss_mux_pattern == 1){
|
||||
// same frame as ssb
|
||||
if ((mac->type0_PDCCH_CSS_config.frame & 0x1) == mac->type0_PDCCH_CSS_config.sfn_c)
|
||||
@@ -2594,6 +2696,20 @@ void nr_ue_sib1_scheduler(module_id_t module_idP,
|
||||
frame_s = 0; // same frame as ssb
|
||||
slot_s = mac->type0_PDCCH_CSS_config.n_c;
|
||||
}
|
||||
fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request[0]; // Take the first dl_config_request for SIB1
|
||||
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15;
|
||||
|
||||
if(mac->search_space_zero == NULL) mac->search_space_zero=calloc(1,sizeof(*mac->search_space_zero));
|
||||
if(mac->coreset0 == NULL) mac->coreset0 = calloc(1,sizeof(*mac->coreset0));
|
||||
|
||||
fill_coresetZero(mac->coreset0, &mac->type0_PDCCH_CSS_config);
|
||||
fill_searchSpaceZero(mac->search_space_zero, &mac->type0_PDCCH_CSS_config);
|
||||
rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15;
|
||||
rel15->num_dci_options = 1;
|
||||
rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0;
|
||||
config_dci_pdu(mac, rel15, dl_config, NR_RNTI_SI, -1);
|
||||
fill_dci_search_candidates(mac->search_space_zero, rel15, -1, -1);
|
||||
|
||||
LOG_D(MAC,"Calling fill_scheduled_response, type0_pdcch, num_pdus %d\n",dl_config->number_pdus);
|
||||
fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, module_idP, cc_id, frame_s, slot_s, phy_data);
|
||||
|
||||
|
||||
@@ -455,6 +455,12 @@ int nr_mac_enable_ue_rrc_processing_timer(module_id_t Mod_idP, rnti_t rnti, NR_S
|
||||
sched_ctrl->rrc_processing_timer = (rrc_reconfiguration_delay<<subcarrierSpacing) + sl_ahead;
|
||||
LOG_I(NR_MAC, "Activating RRC processing timer for UE %04x with %d ms\n", UE_info->rnti, rrc_reconfiguration_delay);
|
||||
|
||||
// it might happen that timing advance command should be sent during the RRC
|
||||
// processing timer. To prevent this, set a variable as if we would have just
|
||||
// sent it. This way, another TA command will for sure be sent in some
|
||||
// frames, after RRC processing timer.
|
||||
sched_ctrl->ta_frame = (RC.nrmac[Mod_idP]->frame - 1 + 1024) % 1024;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -650,7 +656,58 @@ bool nr_mac_update_cellgroup(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupCon
|
||||
exit(1);
|
||||
}
|
||||
|
||||
nr_mac_update_RA(nrmac, rnti, CellGroup);
|
||||
process_CellGroup(CellGroup, &UE->UE_sched_ctrl);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nr_mac_update_RA(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup)
|
||||
{
|
||||
// Checking for free RA process
|
||||
NR_COMMON_channels_t *cc = &nrmac->common_channels[0];
|
||||
uint8_t ra_index = 0;
|
||||
for (; ra_index < NR_NB_RA_PROC_MAX; ra_index++) {
|
||||
if ((cc->ra[ra_index].state == RA_IDLE) && (!cc->ra[ra_index].cfra))
|
||||
break;
|
||||
}
|
||||
if (ra_index == NR_NB_RA_PROC_MAX) {
|
||||
LOG_E(NR_MAC, "%s() %s:%d RA processes are not available for CFRA RNTI :%x\n", __FUNCTION__, __FILE__, __LINE__, rnti);
|
||||
return -1;
|
||||
}
|
||||
|
||||
NR_RA_t *ra = &cc->ra[ra_index];
|
||||
if (CellGroup->spCellConfig && CellGroup->spCellConfig->reconfigurationWithSync
|
||||
&& CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated != NULL) {
|
||||
if (CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra != NULL) {
|
||||
ra->cfra = true;
|
||||
ra->rnti = rnti;
|
||||
ra->CellGroup = CellGroup;
|
||||
struct NR_CFRA *cfra = CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra;
|
||||
uint8_t num_preamble = cfra->resources.choice.ssb->ssb_ResourceList.list.count;
|
||||
ra->preambles.num_preambles = num_preamble;
|
||||
ra->preambles.preamble_list = (uint8_t *)malloc(num_preamble * sizeof(uint8_t));
|
||||
for (int i = 0; i < cc->num_active_ssb; i++) {
|
||||
for (int j = 0; j < num_preamble; j++) {
|
||||
if (cc->ssb_index[i] == cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ssb) {
|
||||
// One dedicated preamble for each beam
|
||||
ra->preambles.preamble_list[i] = cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ra_PreambleIndex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ra->cfra = false;
|
||||
ra->rnti = 0;
|
||||
if (ra->preambles.preamble_list == NULL) {
|
||||
ra->preambles.num_preambles = MAX_NUM_NR_PRACH_PREAMBLES;
|
||||
ra->preambles.preamble_list = (uint8_t *)malloc(MAX_NUM_NR_PRACH_PREAMBLES * sizeof(uint8_t));
|
||||
for (int i = 0; i < MAX_NUM_NR_PRACH_PREAMBLES; i++)
|
||||
ra->preambles.preamble_list[i] = i;
|
||||
}
|
||||
}
|
||||
LOG_I(NR_MAC, "Added new %s process for UE RNTI %04x with initial CellGroup\n", ra->cfra ? "CFRA" : "CBRA", rnti);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -42,8 +42,7 @@
|
||||
|
||||
#include "RRC/NR/nr_rrc_extern.h"
|
||||
|
||||
//#include "LAYER2/MAC/pre_processor.c"
|
||||
#include "pdcp.h"
|
||||
#include "nr_pdcp/nr_pdcp_oai_api.h"
|
||||
|
||||
#include "intertask_interface.h"
|
||||
|
||||
@@ -57,10 +56,13 @@
|
||||
const uint8_t nr_rv_round_map[4] = { 0, 2, 3, 1 };
|
||||
uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 };
|
||||
|
||||
void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
|
||||
void clear_nr_nfapi_information(gNB_MAC_INST *gNB,
|
||||
int CC_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP)
|
||||
sub_frame_t slotP,
|
||||
nfapi_nr_dl_tti_request_t *DL_req,
|
||||
nfapi_nr_tx_data_request_t *TX_req,
|
||||
nfapi_nr_ul_dci_request_t *UL_dci_req)
|
||||
{
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc = gNB->common_channels->ServingCellConfigCommon;
|
||||
@@ -68,10 +70,7 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
|
||||
|
||||
UL_tti_req_ahead_initialization(gNB, scc, num_slots, CC_idP, frameP, slotP, *scc->ssbSubcarrierSpacing);
|
||||
|
||||
nfapi_nr_dl_tti_request_t *DL_req = &gNB->DL_req[0];
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t **pdcch = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t **)gNB->pdcch_pdu_idx[CC_idP];
|
||||
nfapi_nr_ul_dci_request_t *UL_dci_req = &gNB->UL_dci_req[0];
|
||||
nfapi_nr_tx_data_request_t *TX_req = &gNB->TX_req[0];
|
||||
|
||||
gNB->pdu_index[CC_idP] = 0;
|
||||
|
||||
@@ -97,23 +96,53 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
|
||||
future_ul_tti_req->n_ulcch = 0;
|
||||
future_ul_tti_req->n_group = 0;
|
||||
|
||||
/* UL_tti_req is a simple pointer into the current UL_tti_req_ahead, i.e.,
|
||||
* it walks over UL_tti_req_ahead in a circular fashion */
|
||||
const int current_index = ul_buffer_index(frameP, slotP, *scc->ssbSubcarrierSpacing, gNB->UL_tti_req_ahead_size);
|
||||
gNB->UL_tti_req[CC_idP] = &gNB->UL_tti_req_ahead[CC_idP][current_index];
|
||||
TX_req[CC_idP].Number_of_PDUs = 0;
|
||||
|
||||
}
|
||||
|
||||
bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot) {
|
||||
return (bitmap >> (slot % 64)) & 0x01;
|
||||
}
|
||||
|
||||
void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
frame_t frame,
|
||||
sub_frame_t slot)
|
||||
/* the structure nfapi_nr_ul_tti_request_t is very big, let's copy only what is necessary */
|
||||
static void copy_ul_tti_req(nfapi_nr_ul_tti_request_t *to, nfapi_nr_ul_tti_request_t *from)
|
||||
{
|
||||
int i;
|
||||
|
||||
to->header = from->header;
|
||||
to->SFN = from->SFN;
|
||||
to->Slot = from->Slot;
|
||||
to->n_pdus = from->n_pdus;
|
||||
to->rach_present = from->rach_present;
|
||||
to->n_ulsch = from->n_ulsch;
|
||||
to->n_ulcch = from->n_ulcch;
|
||||
to->n_group = from->n_group;
|
||||
|
||||
for (i = 0; i < from->n_pdus; i++) {
|
||||
to->pdus_list[i].pdu_type = from->pdus_list[i].pdu_type;
|
||||
to->pdus_list[i].pdu_size = from->pdus_list[i].pdu_size;
|
||||
|
||||
switch (from->pdus_list[i].pdu_type) {
|
||||
case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE:
|
||||
to->pdus_list[i].prach_pdu = from->pdus_list[i].prach_pdu;
|
||||
break;
|
||||
case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:
|
||||
to->pdus_list[i].pusch_pdu = from->pdus_list[i].pusch_pdu;
|
||||
break;
|
||||
case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE:
|
||||
to->pdus_list[i].pucch_pdu = from->pdus_list[i].pucch_pdu;
|
||||
break;
|
||||
case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE:
|
||||
to->pdus_list[i].srs_pdu = from->pdus_list[i].srs_pdu;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < from->n_group; i++)
|
||||
to->groups_list[i] = from->groups_list[i];
|
||||
}
|
||||
|
||||
void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_t slot, NR_Sched_Rsp_t *sched_info)
|
||||
{
|
||||
protocol_ctxt_t ctxt = {0};
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frame, slot,module_idP);
|
||||
|
||||
@@ -137,7 +166,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
start_meas(&gNB->eNB_scheduler);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN);
|
||||
|
||||
pdcp_run(&ctxt);
|
||||
/* send tick to RLC and RRC every ms */
|
||||
if ((slot & ((1 << *scc->ssbSubcarrierSpacing) - 1)) == 0) {
|
||||
void nr_rlc_tick(int frame, int subframe);
|
||||
@@ -159,8 +187,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
uint16_t *vrb_map_UL = cc[CC_id].vrb_map_UL;
|
||||
memcpy(&vrb_map_UL[prev_slot % size * MAX_BWP_SIZE], &gNB->ulprbbl, sizeof(uint16_t) * MAX_BWP_SIZE);
|
||||
|
||||
clear_nr_nfapi_information(gNB, CC_id, frame, slot);
|
||||
|
||||
clear_nr_nfapi_information(gNB, CC_id, frame, slot, &sched_info->DL_req, &sched_info->TX_req, &sched_info->UL_dci_req);
|
||||
}
|
||||
|
||||
if ((slot == 0) && (frame & 127) == 0) {
|
||||
@@ -174,12 +201,11 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
schedule_nr_bwp_switch(module_idP, frame, slot);
|
||||
|
||||
// This schedules MIB
|
||||
schedule_nr_mib(module_idP, frame, slot);
|
||||
schedule_nr_mib(module_idP, frame, slot, &sched_info->DL_req);
|
||||
|
||||
// This schedules SIB1
|
||||
if (get_softmodem_params()->sa == 1)
|
||||
schedule_nr_sib1(module_idP, frame, slot);
|
||||
|
||||
schedule_nr_sib1(module_idP, frame, slot, &sched_info->DL_req, &sched_info->TX_req);
|
||||
|
||||
// This schedule PRACH if we are not in phy_test mode
|
||||
if (get_softmodem_params()->phy_test == 0) {
|
||||
@@ -196,7 +222,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
}
|
||||
|
||||
// Schedule CSI-RS transmission
|
||||
nr_csirs_scheduling(module_idP, frame, slot, nr_slots_per_frame[*scc->ssbSubcarrierSpacing]);
|
||||
nr_csirs_scheduling(module_idP, frame, slot, nr_slots_per_frame[*scc->ssbSubcarrierSpacing], &sched_info->DL_req);
|
||||
|
||||
// Schedule CSI measurement reporting
|
||||
nr_csi_meas_reporting(module_idP, frame, slot);
|
||||
@@ -206,22 +232,29 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
// This schedule RA procedure if not in phy_test mode
|
||||
// Otherwise consider 5G already connected
|
||||
if (get_softmodem_params()->phy_test == 0) {
|
||||
nr_schedule_RA(module_idP, frame, slot);
|
||||
nr_schedule_RA(module_idP, frame, slot, &sched_info->UL_dci_req, &sched_info->DL_req, &sched_info->TX_req);
|
||||
}
|
||||
|
||||
// This schedules the DCI for Uplink and subsequently PUSCH
|
||||
nr_schedule_ulsch(module_idP, frame, slot);
|
||||
nr_schedule_ulsch(module_idP, frame, slot, &sched_info->UL_dci_req);
|
||||
|
||||
// This schedules the DCI for Downlink and PDSCH
|
||||
start_meas(&gNB->schedule_dlsch);
|
||||
nr_schedule_ue_spec(module_idP, frame, slot);
|
||||
nr_schedule_ue_spec(module_idP, frame, slot, &sched_info->DL_req, &sched_info->TX_req);
|
||||
stop_meas(&gNB->schedule_dlsch);
|
||||
|
||||
nr_sr_reporting(gNB, frame, slot);
|
||||
|
||||
nr_schedule_pucch(gNB, frame, slot);
|
||||
|
||||
/* TODO: we copy from gNB->UL_tti_req_ahead[0][current_index], ie. CC_id == 0,
|
||||
* is more than 1 CC supported?
|
||||
*/
|
||||
AssertFatal(MAX_NUM_CCs == 1, "only 1 CC supported\n");
|
||||
const int current_index = ul_buffer_index(frame, slot, *scc->ssbSubcarrierSpacing, gNB->UL_tti_req_ahead_size);
|
||||
copy_ul_tti_req(&sched_info->UL_tti_req, &gNB->UL_tti_req_ahead[0][current_index]);
|
||||
|
||||
stop_meas(&gNB->eNB_scheduler);
|
||||
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT);
|
||||
}
|
||||
|
||||
@@ -662,8 +662,13 @@ void nr_initiate_ra_proc(module_id_t module_idP,
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0);
|
||||
}
|
||||
|
||||
void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
|
||||
|
||||
void nr_schedule_RA(module_id_t module_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
nfapi_nr_ul_dci_request_t *ul_dci_req,
|
||||
nfapi_nr_dl_tti_request_t *DL_req,
|
||||
nfapi_nr_tx_data_request_t *TX_req)
|
||||
{
|
||||
gNB_MAC_INST *mac = RC.nrmac[module_idP];
|
||||
|
||||
start_meas(&mac->schedule_ra);
|
||||
@@ -674,15 +679,15 @@ void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
|
||||
LOG_D(NR_MAC, "RA[state:%d]\n", ra->state);
|
||||
switch (ra->state) {
|
||||
case Msg2:
|
||||
nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra);
|
||||
nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req);
|
||||
break;
|
||||
case Msg3_retransmission:
|
||||
nr_generate_Msg3_retransmission(module_idP, CC_id, frameP, slotP, ra);
|
||||
nr_generate_Msg3_retransmission(module_idP, CC_id, frameP, slotP, ra, ul_dci_req);
|
||||
break;
|
||||
case Msg3_dcch_dtch:
|
||||
nr_generate_Msg3_dcch_dtch_response(module_idP, CC_id, frameP, slotP, ra);
|
||||
nr_generate_Msg3_dcch_dtch_response(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req);
|
||||
case Msg4:
|
||||
nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra);
|
||||
nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req);
|
||||
break;
|
||||
case WAIT_Msg4_ACK:
|
||||
nr_check_Msg4_Ack(module_idP, CC_id, frameP, slotP, ra);
|
||||
@@ -695,9 +700,13 @@ void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
|
||||
stop_meas(&mac->schedule_ra);
|
||||
}
|
||||
|
||||
|
||||
void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra) {
|
||||
|
||||
void nr_generate_Msg3_retransmission(module_id_t module_idP,
|
||||
int CC_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
NR_RA_t *ra,
|
||||
nfapi_nr_ul_dci_request_t *ul_dci_req)
|
||||
{
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
|
||||
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
@@ -784,8 +793,6 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t
|
||||
NR_ControlResourceSet_t *coreset = ra->coreset;
|
||||
AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg3 retransmission\n");
|
||||
|
||||
nfapi_nr_ul_dci_request_t *ul_dci_req = &nr_mac->UL_dci_req[CC_id];
|
||||
|
||||
const int coresetid = coreset->controlResourceSetId;
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][coresetid];
|
||||
if (!pdcch_pdu_rel15) {
|
||||
@@ -1148,8 +1155,14 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
|
||||
nr_fill_rar(module_idP, ra, RAR_pdu, pusch_pdu);
|
||||
}
|
||||
|
||||
void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra) {
|
||||
|
||||
void nr_generate_Msg2(module_id_t module_idP,
|
||||
int CC_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
NR_RA_t *ra,
|
||||
nfapi_nr_dl_tti_request_t *DL_req,
|
||||
nfapi_nr_tx_data_request_t *TX_req)
|
||||
{
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
|
||||
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
|
||||
NR_UE_DL_BWP_t *dl_bwp = &ra->DL_BWP;
|
||||
@@ -1198,7 +1211,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
}
|
||||
|
||||
// Checking if the DCI allocation is feasible in current subframe
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body;
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
|
||||
if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) {
|
||||
LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, ra->RA_rnti);
|
||||
return;
|
||||
@@ -1369,16 +1382,24 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
nr_mac->cset0_bwp_size);
|
||||
|
||||
// DL TX request
|
||||
nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs];
|
||||
nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[TX_req->Number_of_PDUs];
|
||||
|
||||
// Program UL processing for Msg3
|
||||
nr_get_Msg3alloc(module_idP, CC_id, scc, slotP, frameP, ra, nr_mac->tdd_beam_association);
|
||||
nr_add_msg3(module_idP, CC_id, frameP, slotP, ra, (uint8_t *) &tx_req->TLVs[0].value.direct[0]);
|
||||
|
||||
if(ra->cfra) {
|
||||
if (ra->cfra) {
|
||||
NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[module_idP]->UE_info, ra->rnti);
|
||||
if (UE) {
|
||||
const NR_ServingCellConfig_t *servingCellConfig = UE->CellGroup ? UE->CellGroup->spCellConfig->spCellConfigDedicated : NULL;
|
||||
uint32_t delay_ms = servingCellConfig && servingCellConfig->downlinkBWP_ToAddModList ? NR_RRC_SETUP_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_SETUP_DELAY_MS;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
sched_ctrl->rrc_processing_timer = (delay_ms << ra->DL_BWP.scs);
|
||||
}
|
||||
LOG_D(NR_MAC, "Frame %d, Subframe %d: Setting RA-Msg3 reception (CFRA) for SFN.Slot %d.%d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot);
|
||||
} else {
|
||||
LOG_D(NR_MAC, "Frame %d, Subframe %d: Setting RA-Msg3 reception (CBRA) for SFN.Slot %d.%d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot);
|
||||
}
|
||||
else LOG_D(NR_MAC, "Frame %d, Subframe %d: Setting RA-Msg3 reception (CBRA) for SFN.Slot %d.%d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot);
|
||||
|
||||
T(T_GNB_MAC_DL_RAR_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(ra->RA_rnti), T_INT(frameP),
|
||||
T_INT(slotP), T_INT(0), T_BUFFER(&tx_req->TLVs[0].value.direct[0], tx_req->TLVs[0].length));
|
||||
@@ -1387,9 +1408,9 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
tx_req->PDU_index = pduindex;
|
||||
tx_req->num_TLV = 1;
|
||||
tx_req->TLVs[0].length = tx_req->PDU_length + 2;
|
||||
nr_mac->TX_req[CC_id].SFN = frameP;
|
||||
nr_mac->TX_req[CC_id].Number_of_PDUs++;
|
||||
nr_mac->TX_req[CC_id].Slot = slotP;
|
||||
TX_req->SFN = frameP;
|
||||
TX_req->Number_of_PDUs++;
|
||||
TX_req->Slot = slotP;
|
||||
|
||||
// Mark the corresponding symbols RBs as used
|
||||
fill_pdcch_vrb_map(nr_mac,
|
||||
@@ -1592,7 +1613,13 @@ void prepare_dl_pdus(gNB_MAC_INST *nr_mac,
|
||||
LOG_D(NR_MAC,"numDlDci: %i\n", pdcch_pdu_rel15->numDlDci);
|
||||
}
|
||||
|
||||
void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra)
|
||||
void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP,
|
||||
int CC_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
NR_RA_t *ra,
|
||||
nfapi_nr_dl_tti_request_t *DL_req,
|
||||
nfapi_nr_tx_data_request_t *TX_req)
|
||||
{
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
|
||||
|
||||
@@ -1646,7 +1673,7 @@ void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, int CC_id, fram
|
||||
}
|
||||
|
||||
// Checking if the DCI allocation is feasible in current subframe
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body;
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
|
||||
if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) {
|
||||
LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, rnti);
|
||||
return;
|
||||
@@ -1726,15 +1753,15 @@ void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, int CC_id, fram
|
||||
0, time_domain_assignment, CC_id, rnti, 0, mcsIndex, tb_scaling, pduindex, rbStart, rbSize);
|
||||
|
||||
// DL TX request
|
||||
nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs];
|
||||
nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[TX_req->Number_of_PDUs];
|
||||
memcpy(tx_req->TLVs[0].value.direct, buf, sizeof(uint8_t) * tb_size);
|
||||
tx_req->PDU_length = tb_size;
|
||||
tx_req->PDU_index = pduindex;
|
||||
tx_req->num_TLV = 1;
|
||||
tx_req->TLVs[0].length = tb_size + 2;
|
||||
nr_mac->TX_req[CC_id].SFN = frameP;
|
||||
nr_mac->TX_req[CC_id].Number_of_PDUs++;
|
||||
nr_mac->TX_req[CC_id].Slot = slotP;
|
||||
TX_req->SFN = frameP;
|
||||
TX_req->Number_of_PDUs++;
|
||||
TX_req->Slot = slotP;
|
||||
|
||||
// Mark the corresponding symbols and RBs as used
|
||||
fill_pdcch_vrb_map(nr_mac,
|
||||
@@ -1772,7 +1799,13 @@ void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, int CC_id, fram
|
||||
sched_ctrl->ul_failure = 0;
|
||||
}
|
||||
|
||||
void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra)
|
||||
void nr_generate_Msg4(module_id_t module_idP,
|
||||
int CC_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
NR_RA_t *ra,
|
||||
nfapi_nr_dl_tti_request_t *DL_req,
|
||||
nfapi_nr_tx_data_request_t *TX_req)
|
||||
{
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
|
||||
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
|
||||
@@ -1846,7 +1879,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
}
|
||||
|
||||
// Checking if the DCI allocation is feasible in current subframe
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body;
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
|
||||
if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) {
|
||||
LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, ra->rnti);
|
||||
return;
|
||||
@@ -1998,15 +2031,15 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
T_INT(frameP), T_INT(slotP), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock, harq->tb_size));
|
||||
|
||||
// DL TX request
|
||||
nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs];
|
||||
nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[TX_req->Number_of_PDUs];
|
||||
memcpy(tx_req->TLVs[0].value.direct, harq->transportBlock, sizeof(uint8_t) * harq->tb_size);
|
||||
tx_req->PDU_length = harq->tb_size;
|
||||
tx_req->PDU_index = pduindex;
|
||||
tx_req->num_TLV = 1;
|
||||
tx_req->TLVs[0].length = harq->tb_size + 2;
|
||||
nr_mac->TX_req[CC_id].SFN = frameP;
|
||||
nr_mac->TX_req[CC_id].Number_of_PDUs++;
|
||||
nr_mac->TX_req[CC_id].Slot = slotP;
|
||||
TX_req->SFN = frameP;
|
||||
TX_req->Number_of_PDUs++;
|
||||
TX_req->Slot = slotP;
|
||||
|
||||
// Mark the corresponding symbols and RBs as used
|
||||
fill_pdcch_vrb_map(nr_mac,
|
||||
|
||||
@@ -42,8 +42,6 @@
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
|
||||
|
||||
#include "pdcp.h"
|
||||
|
||||
#define ENABLE_MAC_PAYLOAD_DEBUG
|
||||
#define DEBUG_eNB_SCHEDULER 1
|
||||
|
||||
@@ -91,10 +89,10 @@ void schedule_ssb(frame_t frame, sub_frame_t slot,
|
||||
|
||||
}
|
||||
|
||||
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
|
||||
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, nfapi_nr_dl_tti_request_t *DL_req)
|
||||
{
|
||||
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
|
||||
NR_COMMON_channels_t *cc;
|
||||
nfapi_nr_dl_tti_request_t *dl_tti_request;
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req;
|
||||
NR_MIB_t *mib = RC.nrrrc[module_idP]->carrier.mib.message.choice.mib;
|
||||
uint8_t num_tdd_period,num_ssb;
|
||||
@@ -105,8 +103,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
|
||||
cc = &gNB->common_channels[CC_id];
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
const int slots_per_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
dl_tti_request = &gNB->DL_req[CC_id];
|
||||
dl_req = &dl_tti_request->dl_tti_request_body;
|
||||
dl_req = &DL_req->dl_tti_request_body;
|
||||
|
||||
// get MIB every 8 frames
|
||||
if(((slotP == 0) && (frameP & 7) == 0) ||
|
||||
@@ -257,7 +254,6 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void schedule_nr_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) {
|
||||
//----------------------------------------
|
||||
}
|
||||
@@ -522,8 +518,12 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
|
||||
|
||||
}
|
||||
|
||||
void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
|
||||
|
||||
void schedule_nr_sib1(module_id_t module_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
nfapi_nr_dl_tti_request_t *DL_req,
|
||||
nfapi_nr_tx_data_request_t *TX_req)
|
||||
{
|
||||
// TODO: Get these values from RRC
|
||||
const int CC_id = 0;
|
||||
uint8_t candidate_idx = 0;
|
||||
@@ -588,12 +588,12 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
|
||||
candidate_idx,
|
||||
sib1_sdu_length);
|
||||
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
|
||||
int pdu_index = gNB_mac->pdu_index[0]++;
|
||||
nr_fill_nfapi_dl_sib1_pdu(module_idP, dl_req, pdu_index, type0_PDCCH_CSS_config, TBS, tda_info.startSymbolIndex, tda_info.nrOfSymbols);
|
||||
|
||||
const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs;
|
||||
nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req];
|
||||
const int ntx_req = TX_req->Number_of_PDUs;
|
||||
nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[ntx_req];
|
||||
|
||||
// Data to be transmitted
|
||||
memcpy(tx_req->TLVs[0].value.direct, sib1_payload, TBS);
|
||||
@@ -602,9 +602,9 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
|
||||
tx_req->PDU_index = pdu_index;
|
||||
tx_req->num_TLV = 1;
|
||||
tx_req->TLVs[0].length = TBS + 2;
|
||||
gNB_mac->TX_req[CC_id].Number_of_PDUs++;
|
||||
gNB_mac->TX_req[CC_id].SFN = frameP;
|
||||
gNB_mac->TX_req[CC_id].Slot = slotP;
|
||||
TX_req->Number_of_PDUs++;
|
||||
TX_req->SFN = frameP;
|
||||
TX_req->Slot = slotP;
|
||||
|
||||
type0_PDCCH_CSS_config->active = false;
|
||||
}
|
||||
|
||||
@@ -873,8 +873,10 @@ nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(int CC_id) {
|
||||
|
||||
void nr_schedule_ue_spec(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot) {
|
||||
|
||||
sub_frame_t slot,
|
||||
nfapi_nr_dl_tti_request_t *DL_req,
|
||||
nfapi_nr_tx_data_request_t *TX_req)
|
||||
{
|
||||
gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
|
||||
|
||||
if (!is_xlsch_in_slot(gNB_mac->dlsch_slot_bitmap[slot / 64], slot))
|
||||
@@ -885,7 +887,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
const int CC_id = 0;
|
||||
NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon;
|
||||
NR_UEs_t *UE_info = &gNB_mac->UE_info;
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
|
||||
|
||||
UE_iterator(UE_info->list, UE) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
@@ -1326,16 +1328,16 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock, TBS));
|
||||
}
|
||||
|
||||
const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs;
|
||||
nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req];
|
||||
const int ntx_req = TX_req->Number_of_PDUs;
|
||||
nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[ntx_req];
|
||||
tx_req->PDU_length = TBS;
|
||||
tx_req->PDU_index = pduindex;
|
||||
tx_req->num_TLV = 1;
|
||||
tx_req->TLVs[0].length = TBS + 2;
|
||||
memcpy(tx_req->TLVs[0].value.direct, harq->transportBlock, TBS);
|
||||
gNB_mac->TX_req[CC_id].Number_of_PDUs++;
|
||||
gNB_mac->TX_req[CC_id].SFN = frame;
|
||||
gNB_mac->TX_req[CC_id].Slot = slot;
|
||||
TX_req->Number_of_PDUs++;
|
||||
TX_req->SFN = frame;
|
||||
TX_req->Slot = slot;
|
||||
/* mark UE as scheduled */
|
||||
sched_pdsch->rbSize = 0;
|
||||
}
|
||||
|
||||
@@ -1979,11 +1979,6 @@ int get_nrofHARQ_ProcessesForPDSCH(e_NR_PDSCH_ServingCellConfig__nrofHARQ_Proces
|
||||
}
|
||||
}
|
||||
|
||||
/* hack data to remove UE in the phy */
|
||||
int rnti_to_remove[10];
|
||||
volatile int rnti_to_remove_count;
|
||||
pthread_mutex_t rnti_to_remove_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_allocator_t *uia)
|
||||
{
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
@@ -1997,16 +1992,6 @@ void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_alloca
|
||||
LOG_I(NR_MAC, "Remove NR rnti 0x%04x\n", UE->rnti);
|
||||
const rnti_t rnti = UE->rnti;
|
||||
free(UE);
|
||||
/* hack to remove UE in the phy */
|
||||
if (pthread_mutex_lock(&rnti_to_remove_mutex))
|
||||
exit(1);
|
||||
if (rnti_to_remove_count == 10)
|
||||
exit(1);
|
||||
rnti_to_remove[rnti_to_remove_count] = rnti;
|
||||
LOG_W(NR_MAC, "to remove in mac rnti_to_remove[%d] = 0x%04x\n", rnti_to_remove_count, rnti);
|
||||
rnti_to_remove_count++;
|
||||
if (pthread_mutex_unlock(&rnti_to_remove_mutex))
|
||||
exit(1);
|
||||
|
||||
/* clear RA process(es?) associated to the UE */
|
||||
for (int cc_id = 0; cc_id < NFAPI_CC_MAX; cc_id++) {
|
||||
@@ -2015,8 +2000,8 @@ void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_alloca
|
||||
if (cc->ra[i].rnti == rnti) {
|
||||
LOG_D(NR_MAC, "free RA process %d for rnti %04x\n", i, rnti);
|
||||
/* is it enough? */
|
||||
cc->ra[i].cfra = false;
|
||||
cc->ra[i].rnti = 0;
|
||||
cc->ra[i].cfra = false;
|
||||
cc->ra[i].rnti = 0;
|
||||
cc->ra[i].crnti = 0;
|
||||
}
|
||||
}
|
||||
@@ -2524,16 +2509,6 @@ void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti)
|
||||
delete_nr_ue_data(UE, nr_mac->common_channels, &UE_info->uid_allocator);
|
||||
}
|
||||
|
||||
void nr_mac_remove_ra_rnti(module_id_t mod_id, rnti_t rnti) {
|
||||
// Hack to remove UE in the phy (following the same procedure as in function mac_remove_nr_ue)
|
||||
if (pthread_mutex_lock(&rnti_to_remove_mutex)) exit(1);
|
||||
if (rnti_to_remove_count == 10) exit(1);
|
||||
rnti_to_remove[rnti_to_remove_count] = rnti;
|
||||
LOG_W(NR_MAC, "to remove in mac rnti_to_remove[%d] = 0x%04x\n", rnti_to_remove_count, rnti);
|
||||
rnti_to_remove_count++;
|
||||
if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1);
|
||||
}
|
||||
|
||||
uint8_t nr_get_tpc(int target, uint8_t cqi, int incr) {
|
||||
// al values passed to this function are x10
|
||||
int snrx10 = (cqi*5) - 640;
|
||||
@@ -2563,11 +2538,8 @@ int get_pdsch_to_harq_feedback(NR_PUCCH_Config_t *pucch_Config,
|
||||
}
|
||||
}
|
||||
|
||||
void nr_csirs_scheduling(int Mod_idP,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int n_slots_frame){
|
||||
|
||||
void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slots_frame, nfapi_nr_dl_tti_request_t *DL_req)
|
||||
{
|
||||
int CC_id = 0;
|
||||
NR_UEs_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
gNB_MAC_INST *gNB_mac = RC.nrmac[Mod_idP];
|
||||
@@ -2606,7 +2578,7 @@ void nr_csirs_scheduling(int Mod_idP,
|
||||
NR_NZP_CSI_RS_Resource_t *nzpcsi;
|
||||
int period, offset;
|
||||
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
|
||||
|
||||
for (int id = 0; id < csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.count; id++){
|
||||
nzpcsi = csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.array[id];
|
||||
|
||||
@@ -478,14 +478,29 @@ void abort_nr_ul_harq(NR_UE_info_t *UE, int8_t harq_pid)
|
||||
sched_ctrl->sched_ul_bytes = 0;
|
||||
}
|
||||
|
||||
bool get_UE_waiting_CFRA_msg3(const gNB_MAC_INST *gNB_mac, const int CC_id, const frame_t frame, const sub_frame_t slot)
|
||||
{
|
||||
bool UE_waiting_CFRA_msg3 = false;
|
||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
||||
const NR_RA_t *ra = &gNB_mac->common_channels[CC_id].ra[i];
|
||||
if (ra->cfra == true && ra->state == WAIT_Msg3 && frame == ra->Msg3_frame && slot == ra->Msg3_slot) {
|
||||
UE_waiting_CFRA_msg3 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return UE_waiting_CFRA_msg3;
|
||||
}
|
||||
|
||||
void handle_nr_ul_harq(const int CC_idP,
|
||||
module_id_t mod_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
const nfapi_nr_crc_t *crc_pdu)
|
||||
{
|
||||
NR_UE_info_t* UE = find_nr_UE(&RC.nrmac[mod_id]->UE_info, crc_pdu->rnti);
|
||||
if (!UE) {
|
||||
NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[mod_id]->UE_info, crc_pdu->rnti);
|
||||
bool UE_waiting_CFRA_msg3 = get_UE_waiting_CFRA_msg3(RC.nrmac[mod_id], CC_idP, frame, slot);
|
||||
|
||||
if (!UE || UE_waiting_CFRA_msg3 == true) {
|
||||
LOG_W(NR_MAC, "handle harq for rnti %04x, in RA process\n", crc_pdu->rnti);
|
||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) {
|
||||
NR_RA_t *ra = &RC.nrmac[mod_id]->common_channels[CC_idP].ra[i];
|
||||
@@ -568,9 +583,12 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
LOG_D(NR_MAC, "rx_sdu for rnti %04x\n", current_rnti);
|
||||
const int target_snrx10 = gNB_mac->pusch_target_snrx10;
|
||||
const int pusch_failure_thres = gNB_mac->pusch_failure_thres;
|
||||
|
||||
NR_UE_info_t* UE = find_nr_UE(&gNB_mac->UE_info, current_rnti);
|
||||
if (UE) {
|
||||
|
||||
NR_UE_info_t *UE = find_nr_UE(&gNB_mac->UE_info, current_rnti);
|
||||
bool UE_waiting_CFRA_msg3 = get_UE_waiting_CFRA_msg3(gNB_mac, CC_idP, frameP, slotP);
|
||||
|
||||
if (UE && UE_waiting_CFRA_msg3 == false) {
|
||||
|
||||
NR_UE_sched_ctrl_t *UE_scheduling_control = &UE->UE_sched_ctrl;
|
||||
const int8_t harq_pid = UE_scheduling_control->feedback_ul_harq.head;
|
||||
|
||||
@@ -680,7 +698,6 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
|
||||
if(no_sig) {
|
||||
LOG_D(NR_MAC, "Random Access %i failed at state %i (no signal)\n", i, ra->state);
|
||||
nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
|
||||
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
|
||||
} else {
|
||||
|
||||
@@ -693,25 +710,24 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
|
||||
if( (frameP==ra->Msg3_frame) && (slotP==ra->Msg3_slot) ) {
|
||||
LOG_D(NR_MAC, "Random Access %i failed at state %i (TC_RNTI %04x RNTI %04x)\n", i, ra->state,ra->rnti,current_rnti);
|
||||
nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
|
||||
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
NR_UE_info_t *UE = add_new_nr_ue(gNB_mac, ra->rnti, ra->CellGroup);
|
||||
if (!UE) {
|
||||
LOG_W(NR_MAC, "Random Access %i discarded at state %i (TC_RNTI %04x RNTI %04x): max number of users achieved!\n", i, ra->state,ra->rnti,current_rnti);
|
||||
nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
|
||||
NR_UE_info_t *UE_msg3_stage = UE ? UE : add_new_nr_ue(gNB_mac, ra->rnti, ra->CellGroup);
|
||||
if (!UE_msg3_stage) {
|
||||
LOG_W(NR_MAC, "Random Access %i discarded at state %i (TC_RNTI %04x RNTI %04x): max number of users achieved!\n", i, ra->state, ra->rnti, current_rnti);
|
||||
|
||||
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
|
||||
return;
|
||||
}
|
||||
|
||||
UE->UE_beam_index = ra->beam_id;
|
||||
UE_msg3_stage->UE_beam_index = ra->beam_id;
|
||||
|
||||
// re-initialize ta update variables after RA procedure completion
|
||||
UE->UE_sched_ctrl.ta_frame = frameP;
|
||||
UE_msg3_stage->UE_sched_ctrl.ta_frame = frameP;
|
||||
|
||||
LOG_D(NR_MAC,
|
||||
"reset RA state information for RA-RNTI 0x%04x/index %d\n",
|
||||
@@ -725,19 +741,22 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
current_rnti,
|
||||
ra->rnti);
|
||||
|
||||
NR_UE_sched_ctrl_t *UE_scheduling_control = &UE->UE_sched_ctrl;
|
||||
NR_UE_sched_ctrl_t *UE_scheduling_control = &UE_msg3_stage->UE_sched_ctrl;
|
||||
|
||||
UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10,ul_cqi,30);
|
||||
UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10, ul_cqi, 30);
|
||||
if (timing_advance != 0xffff)
|
||||
UE_scheduling_control->ta_update = timing_advance;
|
||||
UE_scheduling_control->raw_rssi = rssi;
|
||||
UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640;
|
||||
LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n",UE->rnti,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update);
|
||||
if(ra->cfra) {
|
||||
|
||||
LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n", UE_msg3_stage->rnti, UE_scheduling_control->tpc0, UE_scheduling_control->ta_update);
|
||||
if (ra->cfra) {
|
||||
LOG_A(NR_MAC, "(rnti 0x%04x) CFRA procedure succeeded!\n", ra->rnti);
|
||||
UE->ra_timer = 0;
|
||||
nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
|
||||
nr_mac_gNB_rrc_ul_failure_reset(gnb_mod_idP, frameP, slotP, ra->rnti);
|
||||
reset_dl_harq_list(UE_scheduling_control);
|
||||
reset_ul_harq_list(UE_scheduling_control);
|
||||
UE_scheduling_control->pusch_consecutive_dtx_cnt = 0;
|
||||
UE_scheduling_control->ul_failure = 0;
|
||||
UE_msg3_stage->ra_timer = 0;
|
||||
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
|
||||
process_CellGroup(ra->CellGroup, UE_scheduling_control);
|
||||
|
||||
@@ -755,7 +774,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
memcpy(ra->cont_res_id, &sduP[1], sizeof(uint8_t) * 6);
|
||||
// harq_pid set a non valid value because it is not used in this call
|
||||
// the function is only called to decode the contention resolution sub-header
|
||||
if (nr_process_mac_pdu(gnb_mod_idP, UE, CC_idP, frameP, slotP, sduP, sdu_lenP, -1) == 0) {
|
||||
if (nr_process_mac_pdu(gnb_mod_idP, UE_msg3_stage, CC_idP, frameP, slotP, sduP, sdu_lenP, -1) == 0) {
|
||||
|
||||
if (ra->state == Msg3_dcch_dtch) {
|
||||
// Check if the UE identified by C-RNTI still exists at the gNB
|
||||
@@ -785,7 +804,6 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
}
|
||||
}
|
||||
else {
|
||||
nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
|
||||
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
|
||||
}
|
||||
}
|
||||
@@ -804,14 +822,12 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
// for CFRA (NSA) do not schedule retransmission of msg3
|
||||
if (ra->cfra) {
|
||||
LOG_D(NR_MAC, "Random Access %i failed at state %i (NSA msg3 reception failed)\n", i, ra->state);
|
||||
nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
|
||||
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ra->msg3_round >= gNB_mac->ul_bler.harq_round_max - 1) {
|
||||
LOG_W(NR_MAC, "Random Access %i failed at state %i (Reached msg3 max harq rounds)\n", i, ra->state);
|
||||
nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
|
||||
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
|
||||
return;
|
||||
}
|
||||
@@ -1981,7 +1997,7 @@ nr_pp_impl_ul nr_init_fr1_ulsch_preprocessor(int CC_id)
|
||||
return nr_fr1_ulsch_preprocessor;
|
||||
}
|
||||
|
||||
void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, nfapi_nr_ul_dci_request_t *ul_dci_req)
|
||||
{
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
|
||||
/* Uplink data ONLY can be scheduled when the current slot is downlink slot,
|
||||
@@ -1994,8 +2010,6 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
if (!do_sched)
|
||||
return;
|
||||
|
||||
const int CC_id = 0;
|
||||
nfapi_nr_ul_dci_request_t *ul_dci_req = &nr_mac->UL_dci_req[CC_id];
|
||||
ul_dci_req->SFN = frame;
|
||||
ul_dci_req->Slot = slot;
|
||||
/* a PDCCH PDU groups DCIs per BWP and CORESET. Save a pointer to each
|
||||
|
||||
@@ -58,18 +58,21 @@ void nr_mac_config_sib1(gNB_MAC_INST *nrmac, NR_BCCH_DL_SCH_Message_t *sib1);
|
||||
bool nr_mac_add_test_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup);
|
||||
bool nr_mac_prepare_ra_nsa_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup);
|
||||
bool nr_mac_update_cellgroup(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup);
|
||||
bool nr_mac_update_RA(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup);
|
||||
|
||||
void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
|
||||
void clear_nr_nfapi_information(gNB_MAC_INST *gNB,
|
||||
int CC_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t subframeP);
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
nfapi_nr_dl_tti_request_t *DL_req,
|
||||
nfapi_nr_tx_data_request_t *TX_req,
|
||||
nfapi_nr_ul_dci_request_t *UL_dci_req);
|
||||
|
||||
void nr_mac_update_timers(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot);
|
||||
|
||||
void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
frame_t frame_rxP, sub_frame_t slot_rxP);
|
||||
void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame_rxP, sub_frame_t slot_rxP, NR_Sched_Rsp_t *sched_info);
|
||||
|
||||
void schedule_nr_bwp_switch(module_id_t module_id,
|
||||
frame_t frame,
|
||||
@@ -80,7 +83,9 @@ void schedule_nr_bwp_switch(module_id_t module_id,
|
||||
* messages, statistics, HARQ handling, CEs, ... */
|
||||
void nr_schedule_ue_spec(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot);
|
||||
sub_frame_t slot,
|
||||
nfapi_nr_dl_tti_request_t *DL_req,
|
||||
nfapi_nr_tx_data_request_t *TX_req);
|
||||
|
||||
uint32_t schedule_control_sib1(module_id_t module_id,
|
||||
int CC_id,
|
||||
@@ -94,21 +99,30 @@ uint32_t schedule_control_sib1(module_id_t module_id,
|
||||
/* \brief default FR1 DL preprocessor init routine, returns preprocessor to call */
|
||||
nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(int CC_id);
|
||||
|
||||
void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP);
|
||||
void schedule_nr_sib1(module_id_t module_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
nfapi_nr_dl_tti_request_t *DL_req,
|
||||
nfapi_nr_tx_data_request_t *TX_req);
|
||||
|
||||
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
|
||||
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, nfapi_nr_dl_tti_request_t *DL_req);
|
||||
|
||||
/* \brief main UL scheduler function. Calls a preprocessor to decide on
|
||||
* resource allocation, then "post-processes" resource allocation (nFAPI
|
||||
* messages, statistics, HARQ handling, ... */
|
||||
void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot);
|
||||
void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, nfapi_nr_ul_dci_request_t *ul_dci_req);
|
||||
|
||||
/* \brief default FR1 UL preprocessor init routine, returns preprocessor to call */
|
||||
nr_pp_impl_ul nr_init_fr1_ulsch_preprocessor(int CC_id);
|
||||
|
||||
/////// Random Access MAC-PHY interface functions and primitives ///////
|
||||
|
||||
void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
|
||||
void nr_schedule_RA(module_id_t module_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
nfapi_nr_ul_dci_request_t *ul_dci_req,
|
||||
nfapi_nr_dl_tti_request_t *DL_req,
|
||||
nfapi_nr_tx_data_request_t *TX_req);
|
||||
|
||||
/* \brief Function to indicate a received preamble on PRACH. It initiates the RA procedure.
|
||||
@param module_idP Instance ID of gNB
|
||||
@@ -133,7 +147,12 @@ void nr_get_Msg3alloc(module_id_t module_id,
|
||||
NR_RA_t *ra,
|
||||
int16_t *tdd_beam_association);
|
||||
|
||||
void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra);
|
||||
void nr_generate_Msg3_retransmission(module_id_t module_idP,
|
||||
int CC_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
NR_RA_t *ra,
|
||||
nfapi_nr_ul_dci_request_t *ul_dci_req);
|
||||
|
||||
/* \brief Function in gNB to fill RAR pdu when requested by PHY.
|
||||
@param ra Instance of RA resources of gNB
|
||||
@@ -200,10 +219,7 @@ void nr_srs_ri_computation(const nfapi_nr_srs_normalized_channel_iq_matrix_t *nr
|
||||
|
||||
void nr_schedule_srs(int module_id, frame_t frame, int slot);
|
||||
|
||||
void nr_csirs_scheduling(int Mod_idP,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int n_slots_frame);
|
||||
void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slots_frame, nfapi_nr_dl_tti_request_t *DL_req);
|
||||
|
||||
void nr_csi_meas_reporting(int Mod_idP,
|
||||
frame_t frameP,
|
||||
@@ -350,8 +366,6 @@ NR_UE_info_t* add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf
|
||||
|
||||
void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti);
|
||||
|
||||
void nr_mac_remove_ra_rnti(module_id_t mod_id, rnti_t rnti);
|
||||
|
||||
int nr_get_default_pucch_res(int pucch_ResourceCommon);
|
||||
|
||||
int get_dlscs(nfapi_nr_config_request_t *cfg);
|
||||
@@ -366,13 +380,31 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
|
||||
unsigned char drx_cmd,
|
||||
unsigned char *ue_cont_res_id);
|
||||
|
||||
void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra);
|
||||
void nr_generate_Msg2(module_id_t module_idP,
|
||||
int CC_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
NR_RA_t *ra,
|
||||
nfapi_nr_dl_tti_request_t *dl_req,
|
||||
nfapi_nr_tx_data_request_t *TX_req);
|
||||
|
||||
void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra);
|
||||
void nr_generate_Msg4(module_id_t module_idP,
|
||||
int CC_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
NR_RA_t *ra,
|
||||
nfapi_nr_dl_tti_request_t *DL_req,
|
||||
nfapi_nr_tx_data_request_t *TX_req);
|
||||
|
||||
void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra);
|
||||
|
||||
void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra);
|
||||
void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP,
|
||||
int CC_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
NR_RA_t *ra,
|
||||
nfapi_nr_dl_tti_request_t *DL_req,
|
||||
nfapi_nr_tx_data_request_t *TX_req);
|
||||
|
||||
int binomial(int n, int k);
|
||||
|
||||
|
||||
@@ -33,9 +33,8 @@
|
||||
#include "NR_MAC_gNB/mac_proto.h"
|
||||
#include "NR_MAC_COMMON/nr_mac_extern.h"
|
||||
#include "assertions.h"
|
||||
#include "pdcp.h"
|
||||
#include "nr_pdcp/nr_pdcp_oai_api.h"
|
||||
|
||||
#include "LAYER2/nr_pdcp/nr_pdcp_entity.h"
|
||||
#include "RRC/NR/nr_rrc_defs.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
//#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
|
||||
@@ -250,7 +249,7 @@ void mac_top_init_gNB(ngran_node_t node_type)
|
||||
AssertFatal(rlc_module_init(1) == 0,"Could not initialize RLC layer\n");
|
||||
|
||||
// These should be out of here later
|
||||
if (get_softmodem_params()->usim_test == 0 ) pdcp_layer_init();
|
||||
if (get_softmodem_params()->usim_test == 0 ) nr_pdcp_layer_init();
|
||||
|
||||
if(IS_SOFTMODEM_NOS1 && get_softmodem_params()->phy_test)
|
||||
nr_DRB_preconfiguration(0x1234);
|
||||
|
||||
@@ -719,24 +719,15 @@ typedef struct gNB_MAC_INST_s {
|
||||
uint16_t ulprbbl[MAX_BWP_SIZE];
|
||||
/// NFAPI Config Request Structure
|
||||
nfapi_nr_config_request_scf_t config[NFAPI_CC_MAX];
|
||||
/// NFAPI DL Config Request Structure
|
||||
nfapi_nr_dl_tti_request_t DL_req[NFAPI_CC_MAX];
|
||||
/// a PDCCH PDU groups DCIs per BWP and CORESET. The following structure
|
||||
/// keeps pointers to PDCCH PDUs within DL_req so that we can easily track
|
||||
/// PDCCH PDUs per CC/BWP/CORESET
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_idx[NFAPI_CC_MAX][MAX_NUM_CORESET];
|
||||
/// NFAPI UL TTI Request Structure, simple pointer into structure
|
||||
/// UL_tti_req_ahead for current frame/slot
|
||||
nfapi_nr_ul_tti_request_t *UL_tti_req[NFAPI_CC_MAX];
|
||||
/// NFAPI UL TTI Request Structure for future TTIs, dynamically allocated
|
||||
/// because length depends on number of slots
|
||||
nfapi_nr_ul_tti_request_t *UL_tti_req_ahead[NFAPI_CC_MAX];
|
||||
int UL_tti_req_ahead_size;
|
||||
int vrb_map_UL_size;
|
||||
/// NFAPI HI/DCI0 Config Request Structure
|
||||
nfapi_nr_ul_dci_request_t UL_dci_req[NFAPI_CC_MAX];
|
||||
/// NFAPI DL PDU structure
|
||||
nfapi_nr_tx_data_request_t TX_req[NFAPI_CC_MAX];
|
||||
|
||||
NR_UEs_t UE_info;
|
||||
|
||||
|
||||
@@ -402,9 +402,7 @@ void pdcp_mbms_run (
|
||||
void pdcp_run (
|
||||
const protocol_ctxt_t *const ctxt_pP);
|
||||
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);
|
||||
void pdcp_layer_cleanup (void);
|
||||
#define PDCP2NW_DRIVER_FIFO 21
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "pdcp.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
|
||||
int decode_t_reordering(int v)
|
||||
{
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "common/utils/oai_asn1.h"
|
||||
#include "NR_RadioBearerConfig.h"
|
||||
|
||||
#include "pdcp.h"
|
||||
#include "nr_pdcp_oai_api.h"
|
||||
#include "LAYER2/nr_rlc/nr_rlc_oai_api.h"
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
#include "openair2/SDAP/nr_sdap/nr_sdap.h"
|
||||
|
||||
@@ -176,14 +176,19 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
|
||||
}
|
||||
}
|
||||
|
||||
static void nr_pdcp_entity_recv_sdu(nr_pdcp_entity_t *entity,
|
||||
char *buffer, int size, int sdu_id)
|
||||
static int nr_pdcp_entity_process_sdu(nr_pdcp_entity_t *entity,
|
||||
char *buffer,
|
||||
int size,
|
||||
int sdu_id,
|
||||
char *pdu_buffer,
|
||||
int pdu_max_size)
|
||||
{
|
||||
uint32_t count;
|
||||
int sn;
|
||||
int header_size;
|
||||
int integrity_size;
|
||||
char buf[size + 3 + 4];
|
||||
char *buf = pdu_buffer;
|
||||
DevAssert(size + 3 + 4 <= pdu_max_size);
|
||||
int dc_bit;
|
||||
entity->stats.rxsdu_pkts++;
|
||||
entity->stats.rxsdu_bytes += size;
|
||||
@@ -243,13 +248,11 @@ static void nr_pdcp_entity_recv_sdu(nr_pdcp_entity_t *entity,
|
||||
|
||||
entity->tx_next++;
|
||||
|
||||
entity->deliver_pdu(entity->deliver_pdu_data, entity, buf,
|
||||
header_size + size + integrity_size, sdu_id);
|
||||
entity->stats.txpdu_pkts++;
|
||||
entity->stats.txpdu_bytes += header_size + size + integrity_size;
|
||||
entity->stats.txpdu_sn = sn;
|
||||
|
||||
|
||||
return header_size + size + integrity_size;
|
||||
}
|
||||
|
||||
/* may be called several times, take care to clean previous settings */
|
||||
@@ -398,7 +401,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
|
||||
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
|
||||
char *buf, int size),
|
||||
void *deliver_sdu_data,
|
||||
void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
|
||||
void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id,
|
||||
char *buf, int size, int sdu_id),
|
||||
void *deliver_pdu_data,
|
||||
int sn_size,
|
||||
@@ -420,7 +423,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
|
||||
ret->type = type;
|
||||
|
||||
ret->recv_pdu = nr_pdcp_entity_recv_pdu;
|
||||
ret->recv_sdu = nr_pdcp_entity_recv_sdu;
|
||||
ret->process_sdu = nr_pdcp_entity_process_sdu;
|
||||
ret->set_security = nr_pdcp_entity_set_security;
|
||||
ret->set_time = nr_pdcp_entity_set_time;
|
||||
|
||||
|
||||
@@ -73,8 +73,8 @@ typedef struct nr_pdcp_entity_t {
|
||||
|
||||
/* functions provided by the PDCP module */
|
||||
void (*recv_pdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size);
|
||||
void (*recv_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size,
|
||||
int sdu_id);
|
||||
int (*process_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size,
|
||||
int sdu_id, char *pdu_buffer, int pdu_max_size);
|
||||
void (*delete_entity)(struct nr_pdcp_entity_t *entity);
|
||||
void (*get_stats)(struct nr_pdcp_entity_t *entity, nr_pdcp_statistics_t *out);
|
||||
|
||||
@@ -95,7 +95,7 @@ typedef struct nr_pdcp_entity_t {
|
||||
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
|
||||
char *buf, int size);
|
||||
void *deliver_sdu_data;
|
||||
void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
|
||||
void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id,
|
||||
char *buf, int size, int sdu_id);
|
||||
void *deliver_pdu_data;
|
||||
|
||||
@@ -176,7 +176,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
|
||||
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
|
||||
char *buf, int size),
|
||||
void *deliver_sdu_data,
|
||||
void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
|
||||
void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id,
|
||||
char *buf, int size, int sdu_id),
|
||||
void *deliver_pdu_data,
|
||||
int sn_size,
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
/* from OAI */
|
||||
#include "oai_asn1.h"
|
||||
#include "pdcp.h"
|
||||
#include "nr_pdcp_oai_api.h"
|
||||
#include "LAYER2/nr_rlc/nr_rlc_oai_api.h"
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
#include "openair2/SDAP/nr_sdap/nr_sdap.h"
|
||||
@@ -73,7 +73,7 @@ static ngran_node_t node_type;
|
||||
/* NR PDCP and RLC both use "big locks". In some cases a thread may do
|
||||
* lock(rlc) followed by lock(pdcp) (typically when running 'rx_sdu').
|
||||
* Another thread may first do lock(pdcp) and then lock(rlc) (typically
|
||||
* the GTP module calls 'pdcp_data_req' that, in a previous implementation
|
||||
* the GTP module calls 'nr_pdcp_data_req' that, in a previous implementation
|
||||
* was indirectly calling 'rlc_data_req' which does lock(rlc)).
|
||||
* To avoid the resulting deadlock it is enough to ensure that a call
|
||||
* to lock(pdcp) will never be followed by a call to lock(rlc). So,
|
||||
@@ -531,7 +531,13 @@ static void set_node_type() {
|
||||
node_type = get_node_type();
|
||||
}
|
||||
|
||||
/* hack: dummy function needed due to LTE dependencies */
|
||||
void pdcp_layer_init(void)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
void nr_pdcp_layer_init(void)
|
||||
{
|
||||
/* hack: be sure to initialize only once */
|
||||
static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
|
||||
@@ -647,35 +653,12 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
|
||||
}
|
||||
}
|
||||
|
||||
static void deliver_pdu_drb(void *_ue, nr_pdcp_entity_t *entity,
|
||||
static void deliver_pdu_drb(void *deliver_pdu_data, ue_id_t ue_id, int rb_id,
|
||||
char *buf, int size, int sdu_id)
|
||||
{
|
||||
nr_pdcp_ue_t *ue = _ue;
|
||||
int rb_id;
|
||||
protocol_ctxt_t ctxt;
|
||||
int i;
|
||||
mem_block_t *memblock;
|
||||
DevAssert(deliver_pdu_data == NULL);
|
||||
protocol_ctxt_t ctxt = { .enb_flag = 1, .rntiMaybeUEid = ue_id };
|
||||
|
||||
for (i = 0; i < MAX_DRBS_PER_UE; i++) {
|
||||
if (entity == ue->drb[i]) {
|
||||
rb_id = i+1;
|
||||
goto rb_found;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_E(PDCP, "%s:%d:%s: fatal, no RB found for UE ID/RNTI %ld\n", __FILE__, __LINE__, __FUNCTION__, ue->rntiMaybeUEid);
|
||||
exit(1);
|
||||
|
||||
rb_found:
|
||||
ctxt.module_id = 0;
|
||||
ctxt.enb_flag = 1;
|
||||
ctxt.instance = 0;
|
||||
ctxt.frame = 0;
|
||||
ctxt.subframe = 0;
|
||||
ctxt.eNB_index = 0;
|
||||
ctxt.brOption = 0;
|
||||
|
||||
ctxt.rntiMaybeUEid = ue->rntiMaybeUEid;
|
||||
if (NODE_IS_CU(node_type)) {
|
||||
MessageDef *message_p = itti_alloc_new_message_sized(TASK_PDCP_ENB, 0,
|
||||
GTPV1U_TUNNEL_DATA_REQ,
|
||||
@@ -690,14 +673,14 @@ rb_found:
|
||||
req->buffer = gtpu_buffer_p;
|
||||
req->length = size;
|
||||
req->offset = GTPU_HEADER_OVERHEAD_MAX;
|
||||
req->ue_id = ue->rntiMaybeUEid;
|
||||
req->ue_id = ue_id;
|
||||
req->bearer_id = rb_id;
|
||||
LOG_I(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_GTPV1_U, CUuniqInstance, message_p);
|
||||
} else {
|
||||
memblock = get_free_mem_block(size, __FUNCTION__);
|
||||
mem_block_t *memblock = get_free_mem_block(size, __FUNCTION__);
|
||||
memcpy(memblock->data, buf, size);
|
||||
LOG_D(PDCP, "%s(): (drb %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]);
|
||||
@@ -749,101 +732,26 @@ srb_found:
|
||||
}
|
||||
}
|
||||
|
||||
static void deliver_pdu_srb(void *_ue, nr_pdcp_entity_t *entity,
|
||||
char *buf, int size, int sdu_id)
|
||||
void deliver_pdu_srb_rlc(void *deliver_pdu_data, ue_id_t ue_id, int srb_id,
|
||||
char *buf, int size, int sdu_id)
|
||||
{
|
||||
nr_pdcp_ue_t *ue = _ue;
|
||||
int srb_id;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeofArray(ue->srb) ; i++) {
|
||||
if (entity == ue->srb[i]) {
|
||||
srb_id = i+1;
|
||||
goto srb_found;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_E(PDCP, "%s:%d:%s: fatal, no SRB found for UE ID/RNTI %ld\n", __FILE__, __LINE__, __FUNCTION__, ue->rntiMaybeUEid);
|
||||
exit(1);
|
||||
|
||||
srb_found:
|
||||
|
||||
|
||||
LOG_D(PDCP, "%s(): (srb %d) calling rlc_data_req size %d\n", __func__, srb_id, size);
|
||||
//for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)memblock->data[i]);
|
||||
//printf("\n");
|
||||
if ((RC.nrrrc == NULL) || (!NODE_IS_CU(node_type))) {
|
||||
if (entity->is_gnb) {
|
||||
f1ap_dl_rrc_message_t dl_rrc = {.old_gNB_DU_ue_id = 0xFFFFFF, .rrc_container = (uint8_t *)buf, .rrc_container_length = size, .rnti = ue->rntiMaybeUEid, .srb_id = DCCH};
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[0];
|
||||
rrc->mac_rrc.dl_rrc_message_transfer(0, &dl_rrc);
|
||||
} else { // UE
|
||||
mem_block_t *memblock;
|
||||
protocol_ctxt_t ctxt = {.module_id = 0, .enb_flag = 1, .instance = 0, .frame = 0, .subframe = 0, .eNB_index = 0, .brOption = 0, .rntiMaybeUEid = ue->rntiMaybeUEid};
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_DL_RRC_MESSAGE);
|
||||
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;
|
||||
F1AP_DL_RRC_MESSAGE (message_p).old_gNB_DU_ue_id = 0xFFFFFFFF; // unknown
|
||||
F1AP_DL_RRC_MESSAGE(message_p).rnti = ue->rntiMaybeUEid;
|
||||
F1AP_DL_RRC_MESSAGE (message_p).srb_id = srb_id;
|
||||
F1AP_DL_RRC_MESSAGE (message_p).execute_duplication = 1;
|
||||
F1AP_DL_RRC_MESSAGE (message_p).RAT_frequency_priority_information.en_dc = 0;
|
||||
itti_send_msg_to_task (TASK_CU_F1, 0, message_p);
|
||||
LOG_D(PDCP, "Send F1AP_DL_RRC_MESSAGE with ITTI\n");
|
||||
}
|
||||
protocol_ctxt_t ctxt = { .enb_flag = 1, .rntiMaybeUEid = ue_id };
|
||||
mem_block_t *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);
|
||||
}
|
||||
|
||||
void pdcp_run(const protocol_ctxt_t *const ctxt_pP)
|
||||
void deliver_pdu_srb_f1(void *deliver_pdu_data, ue_id_t ue_id, int srb_id,
|
||||
char *buf, int size, int sdu_id)
|
||||
{
|
||||
MessageDef *msg_p;
|
||||
int result;
|
||||
protocol_ctxt_t ctxt = {.module_id = 0, .enb_flag = 1, .instance = 0, .rntiMaybeUEid = 0, .frame = -1, .subframe = -1, .eNB_index = 0, .brOption = false};
|
||||
|
||||
while (1) {
|
||||
itti_poll_msg(ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, &msg_p);
|
||||
if (msg_p == NULL){
|
||||
break;
|
||||
}
|
||||
switch (ITTI_MSG_ID(msg_p)) {
|
||||
case RRC_DCCH_DATA_REQ:
|
||||
LOG_D(PDCP, "Received RRC_DCCH_DATA_REQ type at PDCP task \n");
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(
|
||||
&ctxt,
|
||||
RRC_DCCH_DATA_REQ(msg_p).module_id,
|
||||
RRC_DCCH_DATA_REQ(msg_p).enb_flag,
|
||||
RRC_DCCH_DATA_REQ(msg_p).rnti,
|
||||
RRC_DCCH_DATA_REQ(msg_p).frame,
|
||||
0,
|
||||
RRC_DCCH_DATA_REQ(msg_p).eNB_index);
|
||||
result = pdcp_data_req(&ctxt,
|
||||
SRB_FLAG_YES,
|
||||
RRC_DCCH_DATA_REQ(msg_p).rb_id,
|
||||
RRC_DCCH_DATA_REQ(msg_p).muip,
|
||||
RRC_DCCH_DATA_REQ(msg_p).confirmp,
|
||||
RRC_DCCH_DATA_REQ(msg_p).sdu_size,
|
||||
RRC_DCCH_DATA_REQ(msg_p).sdu_p,
|
||||
RRC_DCCH_DATA_REQ(msg_p).mode,
|
||||
NULL, NULL);
|
||||
|
||||
if (result != true)
|
||||
LOG_E(PDCP, "PDCP data request failed!\n");
|
||||
result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), RRC_DCCH_DATA_REQ(msg_p).sdu_p);
|
||||
AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
break;
|
||||
default:
|
||||
LOG_E(PDCP, "Received unexpected message %s\n", ITTI_MSG_NAME(msg_p));
|
||||
break;
|
||||
}
|
||||
}
|
||||
DevAssert(deliver_pdu_data != NULL);
|
||||
gNB_RRC_INST *rrc = deliver_pdu_data;
|
||||
f1ap_dl_rrc_message_t dl_rrc = {.old_gNB_DU_ue_id = 0xFFFFFF,
|
||||
.rrc_container = (uint8_t *)buf,
|
||||
.rrc_container_length = size,
|
||||
.rnti = ue_id,
|
||||
.srb_id = srb_id};
|
||||
rrc->mac_rrc.dl_rrc_message_transfer(0, &dl_rrc);
|
||||
}
|
||||
|
||||
static void add_srb(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_SRB_ToAddMod *s, int ciphering_algorithm, int integrity_algorithm, unsigned char *ciphering_key, unsigned char *integrity_key)
|
||||
@@ -864,7 +772,7 @@ static void add_srb(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_SRB_ToAddMod *s
|
||||
} else {
|
||||
pdcp_srb = new_nr_pdcp_entity(NR_PDCP_SRB, is_gnb, srb_id,
|
||||
0, false, false, // sdap parameters
|
||||
deliver_sdu_srb, ue, deliver_pdu_srb, ue,
|
||||
deliver_sdu_srb, ue, NULL, ue,
|
||||
12, t_Reordering, -1,
|
||||
ciphering_algorithm,
|
||||
integrity_algorithm,
|
||||
@@ -1131,30 +1039,43 @@ uint64_t get_pdcp_optmask(void)
|
||||
return pdcp_optmask;
|
||||
}
|
||||
|
||||
/* hack: dummy function needed due to LTE dependencies */
|
||||
bool pdcp_remove_UE(const protocol_ctxt_t *const ctxt_pP)
|
||||
{
|
||||
ue_id_t rntiMaybeUEid = ctxt_pP->rntiMaybeUEid;
|
||||
abort();
|
||||
}
|
||||
|
||||
bool nr_pdcp_remove_UE(ue_id_t ue_id)
|
||||
{
|
||||
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
|
||||
nr_pdcp_manager_remove_ue(nr_pdcp_ue_manager, rntiMaybeUEid);
|
||||
nr_pdcp_manager_remove_ue(nr_pdcp_ue_manager, ue_id);
|
||||
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void pdcp_config_set_security(
|
||||
const protocol_ctxt_t* const ctxt_pP,
|
||||
pdcp_t *const pdcp_pP,
|
||||
const rb_id_t rb_id,
|
||||
const uint16_t lc_idP,
|
||||
const uint8_t security_modeP,
|
||||
uint8_t *const kRRCenc_pP,
|
||||
uint8_t *const kRRCint_pP,
|
||||
uint8_t *const kUPenc_pP)
|
||||
/* hack: dummy function needed due to LTE dependencies */
|
||||
void pdcp_config_set_security(const protocol_ctxt_t *const ctxt_pP,
|
||||
pdcp_t *const pdcp_pP,
|
||||
const rb_id_t rb_id,
|
||||
const uint16_t lc_idP,
|
||||
const uint8_t security_modeP,
|
||||
uint8_t *const kRRCenc_pP,
|
||||
uint8_t *const kRRCint_pP,
|
||||
uint8_t *const kUPenc_pP)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
void nr_pdcp_config_set_security(ue_id_t ue_id,
|
||||
const rb_id_t rb_id,
|
||||
const uint8_t security_modeP,
|
||||
uint8_t *const kRRCenc_pP,
|
||||
uint8_t *const kRRCint_pP,
|
||||
uint8_t *const kUPenc_pP)
|
||||
{
|
||||
nr_pdcp_ue_t *ue;
|
||||
nr_pdcp_entity_t *rb;
|
||||
ue_id_t ue_id = ctxt_pP->rntiMaybeUEid;
|
||||
int integrity_algorithm;
|
||||
int ciphering_algorithm;
|
||||
|
||||
@@ -1186,27 +1107,17 @@ void pdcp_config_set_security(
|
||||
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
|
||||
}
|
||||
|
||||
static bool pdcp_data_req_srb(protocol_ctxt_t *ctxt_pP,
|
||||
const rb_id_t rb_id,
|
||||
const mui_t muiP,
|
||||
const confirm_t confirmP,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer)
|
||||
bool nr_pdcp_data_req_srb(ue_id_t ue_id,
|
||||
const rb_id_t rb_id,
|
||||
const mui_t muiP,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer,
|
||||
deliver_pdu deliver_pdu_cb,
|
||||
void *data)
|
||||
{
|
||||
LOG_D(PDCP, "%s() called, size %d\n", __func__, sdu_buffer_size);
|
||||
nr_pdcp_ue_t *ue;
|
||||
nr_pdcp_entity_t *rb;
|
||||
ue_id_t ue_id = ctxt_pP->rntiMaybeUEid;
|
||||
|
||||
if (ctxt_pP->module_id != 0 ||
|
||||
//ctxt_pP->enb_flag != 1 ||
|
||||
ctxt_pP->instance != 0 ||
|
||||
ctxt_pP->eNB_index != 0 /*||
|
||||
ctxt_pP->configured != 1 ||
|
||||
ctxt_pP->brOption != 0*/) {
|
||||
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
|
||||
|
||||
@@ -1223,21 +1134,31 @@ static bool pdcp_data_req_srb(protocol_ctxt_t *ctxt_pP,
|
||||
return 0;
|
||||
}
|
||||
|
||||
rb->recv_sdu(rb, (char *)sdu_buffer, sdu_buffer_size, muiP);
|
||||
int max_size = sdu_buffer_size + 3 + 4; // 3: max header, 4: max integrity
|
||||
char pdu_buf[max_size];
|
||||
int pdu_size = rb->process_sdu(rb, (char *)sdu_buffer, sdu_buffer_size, muiP, pdu_buf, max_size);
|
||||
AssertFatal(rb->deliver_pdu == NULL, "SRB callback should be NULL, to be provided on every invocation\n");
|
||||
|
||||
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
|
||||
|
||||
deliver_pdu_cb(data, ue_id, rb_id, pdu_buf, pdu_size, muiP);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static bool pdcp_data_req_drb(protocol_ctxt_t *ctxt_pP,
|
||||
const rb_id_t rb_id,
|
||||
const mui_t muiP,
|
||||
const confirm_t confirmP,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer)
|
||||
bool nr_pdcp_data_req_drb(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)
|
||||
{
|
||||
DevAssert(srb_flagP == SRB_FLAG_NO);
|
||||
|
||||
LOG_D(PDCP, "%s() called, size %d\n", __func__, sdu_buffer_size);
|
||||
nr_pdcp_ue_t *ue;
|
||||
nr_pdcp_entity_t *rb;
|
||||
@@ -1268,10 +1189,15 @@ static bool pdcp_data_req_drb(protocol_ctxt_t *ctxt_pP,
|
||||
return 0;
|
||||
}
|
||||
|
||||
rb->recv_sdu(rb, (char *)sdu_buffer, sdu_buffer_size, muiP);
|
||||
int max_size = sdu_buffer_size + 3 + 4; // 3: max header, 4: max integrity
|
||||
char pdu_buf[max_size];
|
||||
int pdu_size = rb->process_sdu(rb, (char *)sdu_buffer, sdu_buffer_size, muiP, pdu_buf, max_size);
|
||||
deliver_pdu deliver_pdu_cb = rb->deliver_pdu;
|
||||
|
||||
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
|
||||
|
||||
deliver_pdu_cb(NULL, ue_id, rb_id, pdu_buf, pdu_size, muiP);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1301,23 +1227,20 @@ bool cu_f1u_data_req(protocol_ctxt_t *ctxt_pP,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* hack: dummy function needed due to LTE dependencies */
|
||||
bool pdcp_data_req(protocol_ctxt_t *ctxt_pP,
|
||||
const srb_flag_t srb_flagP,
|
||||
const rb_id_t rb_id,
|
||||
const mui_t muiP,
|
||||
const confirm_t confirmP,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer,
|
||||
const pdcp_transmission_mode_t mode,
|
||||
const srb_flag_t srb_flagP,
|
||||
const rb_id_t rb_idP,
|
||||
const mui_t muiP,
|
||||
const confirm_t confirmP,
|
||||
const sdu_size_t sdu_buffer_sizeP,
|
||||
unsigned char *const sdu_buffer_pP,
|
||||
const pdcp_transmission_mode_t modeP,
|
||||
const uint32_t *const sourceL2Id,
|
||||
const uint32_t *const destinationL2Id)
|
||||
{
|
||||
if (srb_flagP) {
|
||||
return pdcp_data_req_srb(ctxt_pP, rb_id, muiP, confirmP, sdu_buffer_size, sdu_buffer);
|
||||
}
|
||||
else{
|
||||
return pdcp_data_req_drb(ctxt_pP, rb_id, muiP, confirmP, sdu_buffer_size, sdu_buffer);
|
||||
}
|
||||
abort();
|
||||
return false;
|
||||
}
|
||||
|
||||
void pdcp_set_pdcp_data_ind_func(pdcp_data_ind_func_t pdcp_data_ind)
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef NR_PDCP_OAI_API_H
|
||||
#define NR_PDCP_OAI_API_H
|
||||
|
||||
#include "pdcp.h"
|
||||
#include "nr_pdcp_ue_manager.h"
|
||||
|
||||
void nr_pdcp_layer_init(void);
|
||||
uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id);
|
||||
|
||||
void du_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);
|
||||
|
||||
bool 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,
|
||||
const uint32_t *const srcID,
|
||||
const uint32_t *const dstID);
|
||||
|
||||
void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
|
||||
ue_id_t rntiMaybeUEid,
|
||||
ue_id_t reestablish_ue_id,
|
||||
NR_DRB_ToAddModList_t *const drb2add_list,
|
||||
const uint8_t security_modeP,
|
||||
uint8_t *const kUPenc,
|
||||
uint8_t *const kUPint,
|
||||
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
|
||||
|
||||
void nr_DRB_preconfiguration(ue_id_t crntiMaybeUEid);
|
||||
|
||||
bool nr_pdcp_remove_UE(ue_id_t ue_id);
|
||||
|
||||
void nr_pdcp_config_set_security(ue_id_t ue_id,
|
||||
const rb_id_t rb_id,
|
||||
const uint8_t security_modeP,
|
||||
uint8_t *const kRRCenc_pP,
|
||||
uint8_t *const kRRCint_pP,
|
||||
uint8_t *const kUPenc_pP);
|
||||
|
||||
bool 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);
|
||||
|
||||
typedef void (*deliver_pdu)(void *data, ue_id_t ue_id, int srb_id,
|
||||
char *buf, int size, int sdu_id);
|
||||
/* default implementation of deliver_pdu */
|
||||
void deliver_pdu_srb_rlc(void *data, ue_id_t ue_id, int srb_id, char *buf,
|
||||
int size, int sdu_id);
|
||||
void deliver_pdu_srb_f1(void *data, ue_id_t ue_id, int srb_id, char *buf,
|
||||
int size, int sdu_id);
|
||||
bool nr_pdcp_data_req_srb(ue_id_t ue_id,
|
||||
const rb_id_t rb_id,
|
||||
const mui_t muiP,
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer,
|
||||
deliver_pdu deliver_cb,
|
||||
void *data);
|
||||
bool nr_pdcp_data_req_drb(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);
|
||||
|
||||
void nr_pdcp_tick(int frame, int subframe);
|
||||
|
||||
nr_pdcp_ue_manager_t *nr_pdcp_sdap_get_ue_manager();
|
||||
|
||||
const bool nr_pdcp_get_statistics(ue_id_t ue_id, int srb_flag, int rb_id, nr_pdcp_statistics_t *out);
|
||||
|
||||
#endif /* NR_PDCP_OAI_API_H */
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
/* from openair */
|
||||
#include "rlc.h"
|
||||
#include "pdcp.h"
|
||||
#include "LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
|
||||
|
||||
/* from nr rlc module */
|
||||
#include "nr_rlc_asn1_utils.h"
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include "LAYER2/RLC/rlc.h"
|
||||
#include "LAYER2/MAC/mac.h"
|
||||
#include "LAYER2/MAC/mac_extern.h"
|
||||
#include "LAYER2/PDCP_v10.1.0/pdcp.h"
|
||||
#include "LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "common/ran_context.h"
|
||||
|
||||
|
||||
@@ -39,12 +39,12 @@
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include "nfapi/oai_integration/gnb_ind_vars.h"
|
||||
#include "openair2/PHY_INTERFACE/queue_t.h"
|
||||
#include "openair2/NR_PHY_INTERFACE/nr_sched_response.h"
|
||||
|
||||
#define MAX_IF_MODULES 100
|
||||
//#define UL_HARQ_PRINT
|
||||
|
||||
static NR_IF_Module_t *nr_if_inst[MAX_IF_MODULES];
|
||||
static NR_Sched_Rsp_t NR_Sched_INFO[MAX_IF_MODULES][MAX_NUM_CCs];
|
||||
extern int oai_nfapi_harq_indication(nfapi_harq_indication_t *harq_ind);
|
||||
extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind);
|
||||
extern int oai_nfapi_cqi_indication(nfapi_cqi_indication_t *cqi_ind);
|
||||
@@ -389,7 +389,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
|
||||
AssertFatal(UL_info!=NULL,"UL_info is null\n");
|
||||
module_id_t module_id = UL_info->module_id;
|
||||
int CC_id = UL_info->CC_id;
|
||||
NR_Sched_Rsp_t *sched_info = &NR_Sched_INFO[module_id][CC_id];
|
||||
NR_Sched_Rsp_t *sched_info;
|
||||
NR_IF_Module_t *ifi = nr_if_inst[module_id];
|
||||
|
||||
LOG_D(NR_PHY,"SFN/SLOT:%d.%d module_id:%d CC_id:%d UL_info[rach_pdus:%zu rx_ind:%zu crcs:%zu]\n",
|
||||
@@ -451,8 +451,6 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
|
||||
}
|
||||
if (NFAPI_MODE != NFAPI_MODE_PNF) {
|
||||
gNB_MAC_INST *mac = RC.nrmac[module_id];
|
||||
// clear UL DCI prior to handling ULSCH
|
||||
mac->UL_dci_req[CC_id].numPdus = 0;
|
||||
if (ifi->CC_mask==0) {
|
||||
ifi->current_frame = UL_info->frame;
|
||||
ifi->current_slot = UL_info->slot;
|
||||
@@ -471,21 +469,20 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
|
||||
*/
|
||||
nfapi_nr_config_request_scf_t *cfg = &mac->config[CC_id];
|
||||
int spf = get_spf(cfg);
|
||||
sched_info = allocate_sched_response();
|
||||
// clear UL DCI prior to handling ULSCH
|
||||
sched_info->UL_dci_req.numPdus = 0;
|
||||
gNB_dlsch_ulsch_scheduler(module_id,
|
||||
(UL_info->frame+((UL_info->slot>(spf-1-ifi->sl_ahead))?1:0)) % 1024,
|
||||
(UL_info->slot+ifi->sl_ahead)%spf);
|
||||
(UL_info->frame + ((UL_info->slot > (spf - 1 - ifi->sl_ahead)) ? 1 : 0)) % 1024,
|
||||
(UL_info->slot + ifi->sl_ahead) % spf,
|
||||
sched_info);
|
||||
|
||||
ifi->CC_mask = 0;
|
||||
sched_info->module_id = module_id;
|
||||
sched_info->CC_id = CC_id;
|
||||
sched_info->frame = (UL_info->frame + ((UL_info->slot>(spf-1-ifi->sl_ahead)) ? 1 : 0)) % 1024;
|
||||
sched_info->slot = (UL_info->slot+ifi->sl_ahead)%spf;
|
||||
sched_info->DL_req = &mac->DL_req[CC_id];
|
||||
sched_info->UL_dci_req = &mac->UL_dci_req[CC_id];
|
||||
|
||||
sched_info->UL_tti_req = mac->UL_tti_req[CC_id];
|
||||
|
||||
sched_info->TX_req = &mac->TX_req[CC_id];
|
||||
#ifdef DUMP_FAPI
|
||||
dump_dl(sched_info);
|
||||
#endif
|
||||
@@ -496,10 +493,11 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
|
||||
CC_id);
|
||||
ifi->NR_Schedule_response(sched_info);
|
||||
|
||||
LOG_D(NR_PHY,"NR_Schedule_response: SFN SLOT:%d %d dl_pdus:%d\n",
|
||||
sched_info->frame,
|
||||
sched_info->slot,
|
||||
sched_info->DL_req->dl_tti_request_body.nPDUs);
|
||||
LOG_D(NR_PHY,
|
||||
"NR_Schedule_response: SFN SLOT:%d %d dl_pdus:%d\n",
|
||||
sched_info->frame,
|
||||
sched_info->slot,
|
||||
sched_info->DL_req.dl_tti_request_body.nPDUs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -520,5 +518,7 @@ NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {
|
||||
"allocation of nr_if_inst[%d]->if_mutex fails\n",Mod_id);
|
||||
}
|
||||
|
||||
init_sched_response();
|
||||
|
||||
return nr_if_inst[Mod_id];
|
||||
}
|
||||
|
||||
@@ -83,6 +83,8 @@ typedef struct {
|
||||
|
||||
|
||||
typedef struct {
|
||||
/// the ID of this sched_response - used by sched_reponse memory management
|
||||
int sched_response_id;
|
||||
/// Module ID
|
||||
module_id_t module_id;
|
||||
/// CC ID
|
||||
@@ -92,13 +94,13 @@ typedef struct {
|
||||
/// slot
|
||||
slot_t slot;
|
||||
/// nFAPI DL Config Request
|
||||
nfapi_nr_dl_tti_request_t *DL_req;
|
||||
nfapi_nr_dl_tti_request_t DL_req;
|
||||
/// nFAPI UL Config Request
|
||||
nfapi_nr_ul_tti_request_t *UL_tti_req;
|
||||
nfapi_nr_ul_tti_request_t UL_tti_req;
|
||||
/// nFAPI UL_DCI Request
|
||||
nfapi_nr_ul_dci_request_t *UL_dci_req;
|
||||
nfapi_nr_ul_dci_request_t UL_dci_req;
|
||||
/// Pointers to DL SDUs
|
||||
nfapi_nr_tx_data_request_t *TX_req;
|
||||
nfapi_nr_tx_data_request_t TX_req;
|
||||
} NR_Sched_Rsp_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* sched response memory management */
|
||||
|
||||
/* A system with reference counting is implemented.
|
||||
* It is needed because several threads will access the structure,
|
||||
* which has to be released only when all the threads are done with it.
|
||||
* So the main thread allocates a sched_response with allocate_sched_response()
|
||||
* which allocates a sched_response with a reference counter == 1
|
||||
* and then for each other thread that will access sched_response, a
|
||||
* call to inc_ref_sched_response() is done. When a thread has finished
|
||||
* using the sched_response, it calls deref_sched_response() which will
|
||||
* in turn call release_sched_response() when the reference counter becomes 0.
|
||||
*
|
||||
* The several threads in question are accessing the _same_ sched_response,
|
||||
* it has not to be confused with the various TX processes that may run in
|
||||
* parallel and which are accessing _different_ sched_response (the maximum
|
||||
* number of parallel processes is N_RESP).
|
||||
*/
|
||||
|
||||
#include "nr_sched_response.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "common/utils/assertions.h"
|
||||
|
||||
#define N_RESP 3
|
||||
static NR_Sched_Rsp_t resp[N_RESP];
|
||||
static int resp_refcount[N_RESP];
|
||||
static int resp_freelist_next[N_RESP];
|
||||
static int resp_freelist_head;
|
||||
static pthread_mutex_t resp_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static bool resp_freelist_inited = false;
|
||||
|
||||
void init_sched_response(void)
|
||||
{
|
||||
/* init only once */
|
||||
if (pthread_mutex_lock(&resp_mutex))
|
||||
AssertFatal(0, "pthread_mutex_lock failed\n");
|
||||
if (resp_freelist_inited) {
|
||||
if (pthread_mutex_unlock(&resp_mutex))
|
||||
AssertFatal(0, "pthread_mutex_unlock failed\n");
|
||||
return;
|
||||
}
|
||||
resp_freelist_inited = true;
|
||||
if (pthread_mutex_unlock(&resp_mutex))
|
||||
AssertFatal(0, "pthread_mutex_unlock failed\n");
|
||||
|
||||
int i;
|
||||
for (i = 0; i < N_RESP - 1; i++)
|
||||
resp_freelist_next[i] = i + 1;
|
||||
resp_freelist_next[N_RESP - 1] = -1;
|
||||
resp_freelist_head = 0;
|
||||
}
|
||||
|
||||
NR_Sched_Rsp_t *allocate_sched_response(void)
|
||||
{
|
||||
NR_Sched_Rsp_t *ret;
|
||||
int new_head;
|
||||
|
||||
if (pthread_mutex_lock(&resp_mutex))
|
||||
AssertFatal(0, "pthread_mutex_lock failed\n");
|
||||
|
||||
AssertFatal(resp_freelist_inited, "sched_response used before init\n");
|
||||
|
||||
if (resp_freelist_head == -1) {
|
||||
LOG_E(PHY, "fatal: sched_response cannot be allocated, increase N_RESP\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret = &resp[resp_freelist_head];
|
||||
ret->sched_response_id = resp_freelist_head;
|
||||
resp_refcount[resp_freelist_head] = 1;
|
||||
|
||||
new_head = resp_freelist_next[resp_freelist_head];
|
||||
resp_freelist_next[resp_freelist_head] = -1;
|
||||
resp_freelist_head = new_head;
|
||||
|
||||
if (pthread_mutex_unlock(&resp_mutex))
|
||||
AssertFatal(0, "pthread_mutex_unlock failed\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void release_sched_response(int sched_response_id)
|
||||
{
|
||||
resp_freelist_next[sched_response_id] = resp_freelist_head;
|
||||
resp_freelist_head = sched_response_id;
|
||||
}
|
||||
|
||||
void deref_sched_response(int sched_response_id)
|
||||
{
|
||||
/* simulators (ulsim/dlsim) deal with their own sched_response but call
|
||||
* functions that call this one, let's handle this case with a special
|
||||
* value -1 where we do nothing (yes it's a hack)
|
||||
*/
|
||||
if (sched_response_id == -1)
|
||||
return;
|
||||
|
||||
if (pthread_mutex_lock(&resp_mutex))
|
||||
AssertFatal(0, "pthread_mutex_lock failed\n");
|
||||
|
||||
AssertFatal(resp_freelist_inited, "sched_response used before init\n");
|
||||
AssertFatal(resp_refcount[sched_response_id] > 0, "sched_reponse decreased too much\n");
|
||||
|
||||
resp_refcount[sched_response_id]--;
|
||||
if (resp_refcount[sched_response_id] == 0)
|
||||
release_sched_response(sched_response_id);
|
||||
|
||||
if (pthread_mutex_unlock(&resp_mutex))
|
||||
AssertFatal(0, "pthread_mutex_unlock failed\n");
|
||||
}
|
||||
|
||||
void inc_ref_sched_response(int sched_response_id)
|
||||
{
|
||||
/* simulators (ulsim/dlsim) deal with their own sched_response but call
|
||||
* functions that call this one, let's handle this case with a special
|
||||
* value -1 where we do nothing (yes it's a hack)
|
||||
*/
|
||||
if (sched_response_id == -1)
|
||||
return;
|
||||
|
||||
if (pthread_mutex_lock(&resp_mutex))
|
||||
AssertFatal(0, "pthread_mutex_lock failed\n");
|
||||
|
||||
AssertFatal(resp_freelist_inited, "sched_response used before init\n");
|
||||
|
||||
resp_refcount[sched_response_id]++;
|
||||
|
||||
if (pthread_mutex_unlock(&resp_mutex))
|
||||
AssertFatal(0, "pthread_mutex_unlock failed\n");
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef OPENAIR2_NR_PHY_INTERFACE_NR_SCHED_RESPONSE_H
|
||||
#define OPENAIR2_NR_PHY_INTERFACE_NR_SCHED_RESPONSE_H
|
||||
|
||||
#include "NR_IF_Module.h"
|
||||
|
||||
void init_sched_response(void);
|
||||
NR_Sched_Rsp_t *allocate_sched_response(void);
|
||||
void deref_sched_response(int sched_response_id);
|
||||
void inc_ref_sched_response(int sched_response_id);
|
||||
|
||||
#endif /* OPENAIR2_NR_PHY_INTERFACE_NR_SCHED_RESPONSE_H */
|
||||
@@ -66,6 +66,7 @@ queue_t nr_dl_tti_req_queue;
|
||||
queue_t nr_tx_req_queue;
|
||||
queue_t nr_ul_dci_req_queue;
|
||||
queue_t nr_ul_tti_req_queue;
|
||||
pthread_mutex_t mac_IF_mutex;
|
||||
|
||||
void nrue_init_standalone_socket(int tx_port, int rx_port)
|
||||
{
|
||||
@@ -304,25 +305,24 @@ static void fill_dl_info_with_pdcch(fapi_nr_dci_indication_t *dci, nfapi_nr_dl_d
|
||||
|
||||
static void fill_mib_in_rx_ind(nfapi_nr_dl_tti_request_pdu_t *pdu_list, fapi_nr_rx_indication_t *rx_ind, int pdu_idx, int pdu_type)
|
||||
{
|
||||
AssertFatal(pdu_idx < sizeof(rx_ind->rx_indication_body) / sizeof(rx_ind->rx_indication_body[0]),
|
||||
"pdu_index (%d) is greater than rx_indication_body size!\n", pdu_idx);
|
||||
AssertFatal(pdu_idx == rx_ind->number_pdus, "Invalid pdu_idx %d!\n", pdu_idx);
|
||||
AssertFatal(pdu_idx < sizeof(rx_ind->rx_indication_body) / sizeof(rx_ind->rx_indication_body[0]),
|
||||
"pdu_index (%d) is greater than rx_indication_body size!\n", pdu_idx);
|
||||
AssertFatal(pdu_idx == rx_ind->number_pdus, "Invalid pdu_idx %d!\n", pdu_idx);
|
||||
|
||||
LOG_T(NR_MAC, "Recevied an SSB and are filling rx_ind with the MIB!\n");
|
||||
|
||||
nfapi_nr_dl_tti_ssb_pdu_rel15_t *ssb_pdu = &pdu_list->ssb_pdu.ssb_pdu_rel15;
|
||||
rx_ind->rx_indication_body[pdu_idx].ssb_pdu.cell_id = ssb_pdu->PhysCellId;
|
||||
rx_ind->rx_indication_body[pdu_idx].ssb_pdu.pdu = MALLOC(3 * sizeof(*rx_ind->rx_indication_body[pdu_idx].ssb_pdu.pdu));
|
||||
rx_ind->rx_indication_body[pdu_idx].ssb_pdu.pdu[0] = (ssb_pdu->bchPayload) & 0xff;
|
||||
rx_ind->rx_indication_body[pdu_idx].ssb_pdu.pdu[1] = (ssb_pdu->bchPayload >> 8) & 0xff;
|
||||
rx_ind->rx_indication_body[pdu_idx].ssb_pdu.pdu[2] = (ssb_pdu->bchPayload >> 16) & 0xff;
|
||||
rx_ind->rx_indication_body[pdu_idx].ssb_pdu.rsrp_dBm = ssb_pdu->ssbRsrp;
|
||||
rx_ind->rx_indication_body[pdu_idx].ssb_pdu.ssb_index = ssb_pdu->SsbBlockIndex;
|
||||
rx_ind->rx_indication_body[pdu_idx].ssb_pdu.ssb_length = pdu_list->PDUSize;
|
||||
rx_ind->rx_indication_body[pdu_idx].ssb_pdu.ssb_start_subcarrier = ssb_pdu->SsbSubcarrierOffset;
|
||||
rx_ind->rx_indication_body[pdu_idx].pdu_type = pdu_type;
|
||||
rx_ind->number_pdus = pdu_idx + 1;
|
||||
LOG_T(NR_MAC, "Recevied an SSB and are filling rx_ind with the MIB!\n");
|
||||
|
||||
nfapi_nr_dl_tti_ssb_pdu_rel15_t *ssb_pdu = &pdu_list->ssb_pdu.ssb_pdu_rel15;
|
||||
rx_ind->rx_indication_body[pdu_idx].ssb_pdu.cell_id = ssb_pdu->PhysCellId;
|
||||
rx_ind->rx_indication_body[pdu_idx].ssb_pdu.pdu[0] = (ssb_pdu->bchPayload) & 0xff;
|
||||
rx_ind->rx_indication_body[pdu_idx].ssb_pdu.pdu[1] = (ssb_pdu->bchPayload >> 8) & 0xff;
|
||||
rx_ind->rx_indication_body[pdu_idx].ssb_pdu.pdu[2] = (ssb_pdu->bchPayload >> 16) & 0xff;
|
||||
rx_ind->rx_indication_body[pdu_idx].ssb_pdu.rsrp_dBm = ssb_pdu->ssbRsrp;
|
||||
rx_ind->rx_indication_body[pdu_idx].ssb_pdu.ssb_index = ssb_pdu->SsbBlockIndex;
|
||||
rx_ind->rx_indication_body[pdu_idx].ssb_pdu.ssb_length = pdu_list->PDUSize;
|
||||
rx_ind->rx_indication_body[pdu_idx].ssb_pdu.ssb_start_subcarrier = ssb_pdu->SsbSubcarrierOffset;
|
||||
rx_ind->rx_indication_body[pdu_idx].ssb_pdu.decoded_pdu = true;
|
||||
rx_ind->rx_indication_body[pdu_idx].pdu_type = pdu_type;
|
||||
rx_ind->number_pdus = pdu_idx + 1;
|
||||
}
|
||||
|
||||
static bool is_my_dci(NR_UE_MAC_INST_t *mac, nfapi_nr_dl_dci_pdu_t *received_pdu)
|
||||
@@ -692,7 +692,6 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request,
|
||||
slot = dl_tti_request->Slot;
|
||||
LOG_D(NR_PHY, "[%d, %d] dl_tti_request\n", frame, slot);
|
||||
copy_dl_tti_req_to_dl_info(&mac->dl_info, dl_tti_request);
|
||||
free_and_zero(dl_tti_request);
|
||||
}
|
||||
/* This checks if the previously recevied DCI matches our current RNTI
|
||||
value. The assumption is that if the DCI matches our RNTI, then the
|
||||
@@ -711,14 +710,12 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request,
|
||||
else {
|
||||
LOG_D(NR_MAC, "Unexpected tx_data_req\n");
|
||||
}
|
||||
free_and_zero(tx_data_request);
|
||||
}
|
||||
else if (ul_dci_request) {
|
||||
frame = ul_dci_request->SFN;
|
||||
slot = ul_dci_request->Slot;
|
||||
LOG_D(NR_PHY, "[%d, %d] ul_dci_request\n", frame, slot);
|
||||
copy_ul_dci_data_req_to_dl_info(&mac->dl_info, ul_dci_request);
|
||||
free_and_zero(ul_dci_request);
|
||||
}
|
||||
else if (ul_tti_request) {
|
||||
frame = ul_tti_request->SFN;
|
||||
@@ -735,7 +732,10 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request,
|
||||
|
||||
NR_UL_TIME_ALIGNMENT_t ul_time_alignment;
|
||||
memset(&ul_time_alignment, 0, sizeof(ul_time_alignment));
|
||||
fill_dci_from_dl_config(&mac->dl_info, &mac->dl_config_request);
|
||||
if (dl_tti_request || tx_data_request || ul_dci_request) {
|
||||
fapi_nr_dl_config_request_t *dl_config = get_dl_config_request(mac, slot);
|
||||
fill_dci_from_dl_config(&mac->dl_info, dl_config);
|
||||
}
|
||||
nr_ue_dl_scheduler(&mac->dl_info);
|
||||
nr_ue_dl_indication(&mac->dl_info, &ul_time_alignment);
|
||||
|
||||
@@ -1045,18 +1045,26 @@ int handle_bcch_bch(module_id_t module_id, int cc_id,
|
||||
uint16_t ssb_start_subcarrier, uint16_t cell_id){
|
||||
|
||||
return nr_ue_decode_mib(module_id,
|
||||
cc_id,
|
||||
gNB_index,
|
||||
phy_data,
|
||||
additional_bits,
|
||||
ssb_length, // Lssb = 64 is not support
|
||||
ssb_index,
|
||||
pduP,
|
||||
ssb_start_subcarrier,
|
||||
cell_id);
|
||||
cc_id,
|
||||
gNB_index,
|
||||
phy_data,
|
||||
additional_bits,
|
||||
ssb_length, // Lssb = 64 is not support
|
||||
ssb_index,
|
||||
pduP,
|
||||
ssb_start_subcarrier,
|
||||
cell_id);
|
||||
|
||||
}
|
||||
|
||||
void handle_bch_failure(NR_UE_MAC_INST_t *mac)
|
||||
{
|
||||
mac->ssb_measurements.consecutive_bch_failures++;
|
||||
//TODO handle this properly by scheduling re-synchronization
|
||||
AssertFatal(mac->ssb_measurements.consecutive_bch_failures < 100,
|
||||
"Radio link failure caused by 100 consecutive PBCH detection failures.\n");
|
||||
}
|
||||
|
||||
// L2 Abstraction Layer
|
||||
int handle_bcch_dlsch(module_id_t module_id, int cc_id, unsigned int gNB_index, uint8_t ack_nack, uint8_t *pduP, uint32_t pdu_len){
|
||||
return nr_ue_decode_BCCH_DL_SCH(module_id, cc_id, gNB_index, ack_nack, pduP, pdu_len);
|
||||
@@ -1069,10 +1077,10 @@ int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, frame_t
|
||||
|
||||
}
|
||||
|
||||
void handle_ssb_meas(NR_UE_MAC_INST_t *mac, uint8_t ssb_index, int16_t rsrp_dbm)
|
||||
void handle_ssb_meas(NR_UE_MAC_INST_t *mac, uint8_t ssb_index, int16_t rsrp_dbm)
|
||||
{
|
||||
mac->phy_measurements.ssb_index = ssb_index;
|
||||
mac->phy_measurements.ssb_rsrp_dBm = rsrp_dbm;
|
||||
mac->ssb_measurements.ssb_index = ssb_index;
|
||||
mac->ssb_measurements.ssb_rsrp_dBm = rsrp_dbm;
|
||||
}
|
||||
|
||||
// L2 Abstraction Layer
|
||||
@@ -1116,6 +1124,9 @@ void update_harq_status(module_id_t module_id, uint8_t harq_pid, uint8_t ack_nac
|
||||
|
||||
int nr_ue_ul_indication(nr_uplink_indication_t *ul_info)
|
||||
{
|
||||
|
||||
pthread_mutex_lock(&mac_IF_mutex);
|
||||
|
||||
module_id_t module_id = ul_info->module_id;
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
||||
|
||||
@@ -1125,15 +1136,19 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info)
|
||||
NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon = mac->scc != NULL ? mac->scc->tdd_UL_DL_ConfigurationCommon : mac->scc_SIB->tdd_UL_DL_ConfigurationCommon;
|
||||
if (mac->phy_config_request_sent && is_nr_UL_slot(tdd_UL_DL_ConfigurationCommon, ul_info->slot_tx, mac->frame_type))
|
||||
nr_ue_ul_scheduler(ul_info);
|
||||
|
||||
pthread_mutex_unlock(&mac_IF_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment){
|
||||
|
||||
pthread_mutex_lock(&mac_IF_mutex);
|
||||
uint32_t ret_mask = 0x0;
|
||||
module_id_t module_id = dl_info->module_id;
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
||||
fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request;
|
||||
fapi_nr_dl_config_request_t *dl_config = get_dl_config_request(mac, dl_info->slot);
|
||||
|
||||
if ((!dl_info->dci_ind && !dl_info->rx_ind)) {
|
||||
// UL indication to schedule DCI reception
|
||||
@@ -1160,7 +1175,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
|
||||
LOG_D(NR_MAC, "We are filtering a UL_DCI to prevent it from being treated like a DL_DCI\n");
|
||||
continue;
|
||||
}
|
||||
dci_pdu_rel15_t *def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[dci_index->dci_format];
|
||||
dci_pdu_rel15_t *def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[dl_info->slot][dci_index->dci_format];
|
||||
g_harq_pid = def_dci_pdu_rel15->harq_pid;
|
||||
LOG_T(NR_MAC, "Setting harq_pid = %d and dci_index = %d (based on format)\n", g_harq_pid, dci_index->dci_format);
|
||||
|
||||
@@ -1180,31 +1195,35 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
|
||||
|
||||
for (int i=0; i<dl_info->rx_ind->number_pdus; ++i) {
|
||||
|
||||
fapi_nr_rx_indication_body_t rx_indication_body = dl_info->rx_ind->rx_indication_body[i];
|
||||
LOG_D(NR_MAC, "In %s sending DL indication to MAC. 1 PDU type %d of %d total number of PDUs \n",
|
||||
__FUNCTION__,
|
||||
dl_info->rx_ind->rx_indication_body[i].pdu_type,
|
||||
rx_indication_body.pdu_type,
|
||||
dl_info->rx_ind->number_pdus);
|
||||
|
||||
switch(dl_info->rx_ind->rx_indication_body[i].pdu_type){
|
||||
switch(rx_indication_body.pdu_type){
|
||||
case FAPI_NR_RX_PDU_TYPE_SSB:
|
||||
handle_ssb_meas(mac,
|
||||
(dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_index,
|
||||
(dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.rsrp_dBm);
|
||||
ret_mask |= (handle_bcch_bch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, dl_info->phy_data,
|
||||
(dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.pdu,
|
||||
(dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.additional_bits,
|
||||
(dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_index,
|
||||
(dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_length,
|
||||
(dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_start_subcarrier,
|
||||
(dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.cell_id)) << FAPI_NR_RX_PDU_TYPE_SSB;
|
||||
free((dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.pdu);
|
||||
if(rx_indication_body.ssb_pdu.decoded_pdu) {
|
||||
handle_ssb_meas(mac,
|
||||
rx_indication_body.ssb_pdu.ssb_index,
|
||||
rx_indication_body.ssb_pdu.rsrp_dBm);
|
||||
ret_mask |= (handle_bcch_bch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, dl_info->phy_data,
|
||||
rx_indication_body.ssb_pdu.pdu,
|
||||
rx_indication_body.ssb_pdu.additional_bits,
|
||||
rx_indication_body.ssb_pdu.ssb_index,
|
||||
rx_indication_body.ssb_pdu.ssb_length,
|
||||
rx_indication_body.ssb_pdu.ssb_start_subcarrier,
|
||||
rx_indication_body.ssb_pdu.cell_id)) << FAPI_NR_RX_PDU_TYPE_SSB;
|
||||
}
|
||||
else
|
||||
handle_bch_failure(mac);
|
||||
break;
|
||||
case FAPI_NR_RX_PDU_TYPE_SIB:
|
||||
ret_mask |= (handle_bcch_dlsch(dl_info->module_id,
|
||||
dl_info->cc_id, dl_info->gNB_index,
|
||||
(dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.ack_nack,
|
||||
(dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu,
|
||||
(dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu_length)) << FAPI_NR_RX_PDU_TYPE_SIB;
|
||||
rx_indication_body.pdsch_pdu.ack_nack,
|
||||
rx_indication_body.pdsch_pdu.pdu,
|
||||
rx_indication_body.pdsch_pdu.pdu_length)) << FAPI_NR_RX_PDU_TYPE_SIB;
|
||||
break;
|
||||
case FAPI_NR_RX_PDU_TYPE_DLSCH:
|
||||
ret_mask |= (handle_dlsch(dl_info, ul_time_alignment, i)) << FAPI_NR_RX_PDU_TYPE_DLSCH;
|
||||
@@ -1216,16 +1235,16 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
|
||||
ret_mask |= (handle_csirs_measurements(dl_info->module_id,
|
||||
dl_info->frame,
|
||||
dl_info->slot,
|
||||
&(dl_info->rx_ind->rx_indication_body+i)->csirs_measurements)) << FAPI_NR_CSIRS_IND;
|
||||
&rx_indication_body.csirs_measurements)) << FAPI_NR_CSIRS_IND;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(dl_info->rx_ind);
|
||||
dl_info->rx_ind = NULL;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&mac_IF_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1239,6 +1258,7 @@ nr_ue_if_module_t *nr_ue_if_module_init(uint32_t module_id){
|
||||
nr_ue_if_module_inst[module_id]->current_frame = 0;
|
||||
nr_ue_if_module_inst[module_id]->current_slot = 0;
|
||||
nr_ue_if_module_inst[module_id]->phy_config_request = nr_ue_phy_config_request;
|
||||
nr_ue_if_module_inst[module_id]->synch_request = nr_ue_synch_request;
|
||||
if (get_softmodem_params()->emulate_l1)
|
||||
nr_ue_if_module_inst[module_id]->scheduled_response = nr_ue_scheduled_response_stub;
|
||||
else
|
||||
@@ -1246,6 +1266,7 @@ nr_ue_if_module_t *nr_ue_if_module_init(uint32_t module_id){
|
||||
nr_ue_if_module_inst[module_id]->dl_indication = nr_ue_dl_indication;
|
||||
nr_ue_if_module_inst[module_id]->ul_indication = nr_ue_ul_indication;
|
||||
}
|
||||
pthread_mutex_init(&mac_IF_mutex, NULL);
|
||||
|
||||
return nr_ue_if_module_inst[module_id];
|
||||
}
|
||||
@@ -1262,8 +1283,8 @@ int nr_ue_dcireq(nr_dcireq_t *dcireq) {
|
||||
|
||||
fapi_nr_dl_config_request_t *dl_config = &dcireq->dl_config_req;
|
||||
NR_UE_MAC_INST_t *UE_mac = get_mac_inst(0);
|
||||
dl_config->sfn = UE_mac->dl_config_request.sfn;
|
||||
dl_config->slot = UE_mac->dl_config_request.slot;
|
||||
dl_config->sfn = dcireq->frame;
|
||||
dl_config->slot = dcireq->slot;
|
||||
|
||||
LOG_T(PHY, "Entering UE DCI configuration frame %d slot %d \n", dcireq->frame, dcireq->slot);
|
||||
|
||||
|
||||
@@ -151,6 +151,16 @@ typedef struct {
|
||||
|
||||
} nr_phy_config_t;
|
||||
|
||||
typedef struct {
|
||||
/// module id
|
||||
uint8_t Mod_id;
|
||||
/// component carrier id
|
||||
uint8_t CC_id;
|
||||
/// Flag signaling that synch_request was received
|
||||
uint8_t received_synch_request;
|
||||
/// NR UE FAPI message
|
||||
fapi_nr_synch_request_t synch_req;
|
||||
} nr_synch_request_t;
|
||||
|
||||
/*
|
||||
* Generic type of an application-defined callback to return various
|
||||
@@ -171,6 +181,12 @@ typedef int8_t (nr_ue_scheduled_response_f)(nr_scheduled_response_t *scheduled_r
|
||||
*/
|
||||
typedef int8_t (nr_ue_phy_config_request_f)(nr_phy_config_t *phy_config);
|
||||
|
||||
/*
|
||||
* Generic type of an application-defined callback to return various
|
||||
* types of data to the application.
|
||||
*/
|
||||
typedef void (nr_ue_synch_request_f)(nr_synch_request_t *synch_request);
|
||||
|
||||
|
||||
/*
|
||||
* Generic type of an application-defined callback to return various
|
||||
@@ -196,6 +212,7 @@ typedef int (nr_ue_dcireq_f)(nr_dcireq_t *ul_info);
|
||||
typedef struct nr_ue_if_module_s {
|
||||
nr_ue_scheduled_response_f *scheduled_response;
|
||||
nr_ue_phy_config_request_f *phy_config_request;
|
||||
nr_ue_synch_request_f *synch_request;
|
||||
nr_ue_dl_indication_f *dl_indication;
|
||||
nr_ue_ul_indication_f *ul_indication;
|
||||
//nr_ue_dcireq_f *dcireq;
|
||||
|
||||
@@ -921,10 +921,7 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char
|
||||
|
||||
create_tunnel_req.rnti = ue_context_p->ue_context.rnti; // warning put zero above
|
||||
// create_tunnel_req.num_tunnels = i;
|
||||
ret = gtpv1u_create_s1u_tunnel(
|
||||
instance,
|
||||
&create_tunnel_req,
|
||||
&create_tunnel_resp);
|
||||
ret = gtpv1u_create_s1u_tunnel(instance, &create_tunnel_req, &create_tunnel_resp, pdcp_data_req);
|
||||
|
||||
if ( ret != 0 ) {
|
||||
LOG_E(RRC,"rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ : gtpv1u_create_s1u_tunnel failed,start to release UE %x\n",ue_context_p->ue_context.rnti);
|
||||
@@ -1234,10 +1231,7 @@ int rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(MessageDef *msg_p, const char *msg_name
|
||||
create_tunnel_req.rnti = ue_context_p->ue_context.rnti; // warning put zero above
|
||||
create_tunnel_req.num_tunnels = e_rab_done;
|
||||
// NN: not sure if we should create a new tunnel: need to check teid, etc.
|
||||
ret = gtpv1u_create_s1u_tunnel(
|
||||
instance,
|
||||
&create_tunnel_req,
|
||||
&create_tunnel_resp);
|
||||
ret = gtpv1u_create_s1u_tunnel(instance, &create_tunnel_req, &create_tunnel_resp, pdcp_data_req);
|
||||
|
||||
if ( ret != 0 ) {
|
||||
LOG_E(RRC,"rrc_eNB_process_S1AP_E_RAB_SETUP_REQ : gtpv1u_create_s1u_tunnel failed,start to release UE %x\n",ue_context_p->ue_context.rnti);
|
||||
@@ -1908,14 +1902,8 @@ int rrc_eNB_send_PATH_SWITCH_REQ(const protocol_ctxt_t *const ctxt_pP,
|
||||
S1AP_PATH_SWITCH_REQ (msg_p).nb_of_e_rabs = e_rabs_done;
|
||||
create_tunnel_req.rnti = ue_context_pP->ue_context.rnti;
|
||||
create_tunnel_req.num_tunnels = e_rabs_done;
|
||||
gtpv1u_create_s1u_tunnel(
|
||||
ctxt_pP->instance,
|
||||
&create_tunnel_req,
|
||||
&create_tunnel_resp);
|
||||
rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
ctxt_pP,
|
||||
&create_tunnel_resp,
|
||||
&inde_list[0]);
|
||||
gtpv1u_create_s1u_tunnel(ctxt_pP->instance, &create_tunnel_req, &create_tunnel_resp, pdcp_data_req);
|
||||
rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(ctxt_pP, &create_tunnel_resp, &inde_list[0]);
|
||||
|
||||
for (e_rab = 0; e_rab < e_rabs_done; e_rab++) {
|
||||
S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].e_rab_id = create_tunnel_resp.eps_bearer_id[e_rab];
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#include "nr_rrc_defs.h"
|
||||
#include "nr_rrc_extern.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "pdcp.h"
|
||||
#include "common/ran_context.h"
|
||||
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
|
||||
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
|
||||
@@ -43,6 +42,7 @@
|
||||
#include "NR_BCCH-BCH-Message.h"
|
||||
#include "rrc_gNB_UE_context.h"
|
||||
#include <openair2/RRC/NR/MESSAGES/asn1_msg.h>
|
||||
#include "nr_pdcp/nr_pdcp_oai_api.h"
|
||||
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
@@ -55,56 +55,6 @@ nr_rrc_mac_remove_ue(module_id_t mod_idP,
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
uint8_t
|
||||
nr_rrc_data_req(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const rb_id_t rb_idP,
|
||||
const mui_t muiP,
|
||||
const confirm_t confirmP,
|
||||
const sdu_size_t sdu_sizeP,
|
||||
uint8_t *const buffer_pP,
|
||||
const pdcp_transmission_mode_t modeP
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
|
||||
MessageDef *message_p;
|
||||
// Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling).
|
||||
uint8_t *message_buffer;
|
||||
message_buffer = itti_malloc (
|
||||
ctxt_pP->enb_flag ? TASK_RRC_GNB : TASK_RRC_UE,
|
||||
ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE,
|
||||
sdu_sizeP);
|
||||
memcpy (message_buffer, buffer_pP, sdu_sizeP);
|
||||
message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_RRC_GNB : TASK_RRC_UE, 0, RRC_DCCH_DATA_REQ);
|
||||
RRC_DCCH_DATA_REQ (message_p).frame = ctxt_pP->frame;
|
||||
RRC_DCCH_DATA_REQ (message_p).enb_flag = ctxt_pP->enb_flag;
|
||||
RRC_DCCH_DATA_REQ (message_p).rb_id = rb_idP;
|
||||
RRC_DCCH_DATA_REQ (message_p).muip = muiP;
|
||||
RRC_DCCH_DATA_REQ (message_p).confirmp = confirmP;
|
||||
RRC_DCCH_DATA_REQ (message_p).sdu_size = sdu_sizeP;
|
||||
RRC_DCCH_DATA_REQ (message_p).sdu_p = message_buffer;
|
||||
//memcpy (NR_RRC_DCCH_DATA_REQ (message_p).sdu_p, buffer_pP, sdu_sizeP);
|
||||
RRC_DCCH_DATA_REQ (message_p).mode = modeP;
|
||||
RRC_DCCH_DATA_REQ (message_p).module_id = ctxt_pP->module_id;
|
||||
RRC_DCCH_DATA_REQ(message_p).rnti = ctxt_pP->rntiMaybeUEid;
|
||||
RRC_DCCH_DATA_REQ (message_p).eNB_index = ctxt_pP->eNB_index;
|
||||
itti_send_msg_to_task (
|
||||
ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE,
|
||||
ctxt_pP->instance,
|
||||
message_p);
|
||||
LOG_I(NR_RRC,"send RRC_DCCH_DATA_REQ to PDCP\n");
|
||||
|
||||
/* Hack: only trigger PDCP if in CU, otherwise it is triggered by RU threads
|
||||
* Ideally, PDCP would not neet to be triggered like this but react to ITTI
|
||||
* messages automatically */
|
||||
if (ctxt_pP->enb_flag)
|
||||
pdcp_run(ctxt_pP);
|
||||
|
||||
return true; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway.
|
||||
}
|
||||
|
||||
uint16_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
|
||||
const int CC_id,
|
||||
const frame_t frameP,
|
||||
|
||||
@@ -120,7 +120,11 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p,
|
||||
}
|
||||
create_tunnel_req.num_tunnels = UE->nb_of_pdusessions;
|
||||
create_tunnel_req.ue_id = UE->rnti;
|
||||
int ret = gtpv1u_create_ngu_tunnel(getCxtE1(instance)->gtpInstN3, &create_tunnel_req, &create_tunnel_resp);
|
||||
int ret = gtpv1u_create_ngu_tunnel(getCxtE1(instance)->gtpInstN3,
|
||||
&create_tunnel_req,
|
||||
&create_tunnel_resp,
|
||||
nr_pdcp_data_req_drb,
|
||||
sdap_data_req);
|
||||
|
||||
if (ret != 0) {
|
||||
LOG_E(NR_RRC,"rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE rnti %ld\n",
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#include "COMMON/mac_rrc_primitives.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "asn1_msg.h"
|
||||
#include "pdcp.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include "common/ran_context.h"
|
||||
|
||||
|
||||
@@ -271,6 +271,40 @@ typedef struct pdu_session_param_s {
|
||||
uint8_t cause_value;
|
||||
} rrc_pdu_session_param_t;
|
||||
|
||||
typedef struct drb_s {
|
||||
int status;
|
||||
int defaultDRBid;
|
||||
int drb_id;
|
||||
int reestablishPDCP;
|
||||
int recoverPDCP;
|
||||
int daps_Config_r16;
|
||||
struct cnAssociation_s {
|
||||
int present;
|
||||
int eps_BearerIdentity;
|
||||
struct sdap_config_s {
|
||||
bool defaultDRB;
|
||||
int pdusession_id;
|
||||
int sdap_HeaderDL;
|
||||
int sdap_HeaderUL;
|
||||
int mappedQoS_FlowsToAdd[QOSFLOW_MAX_VALUE];
|
||||
} sdap_config;
|
||||
} cnAssociation;
|
||||
struct pdcp_config_s {
|
||||
int discardTimer;
|
||||
int pdcp_SN_SizeUL;
|
||||
int pdcp_SN_SizeDL;
|
||||
int t_Reordering;
|
||||
int integrityProtection;
|
||||
struct headerCompression_s {
|
||||
int NotUsed;
|
||||
int present;
|
||||
} headerCompression;
|
||||
struct ext1_s {
|
||||
int cipheringDisabled;
|
||||
} ext1;
|
||||
} pdcp_config;
|
||||
} drb_t;
|
||||
|
||||
typedef struct gNB_RRC_UE_s {
|
||||
uint8_t primaryCC_id;
|
||||
NR_SRB_ToAddModList_t *SRB_configList;
|
||||
@@ -278,6 +312,7 @@ typedef struct gNB_RRC_UE_s {
|
||||
NR_DRB_ToAddModList_t *DRB_configList;
|
||||
NR_DRB_ToAddModList_t *DRB_configList2[NR_RRC_TRANSACTION_IDENTIFIER_NUMBER];
|
||||
NR_DRB_ToReleaseList_t *DRB_Release_configList2[NR_RRC_TRANSACTION_IDENTIFIER_NUMBER];
|
||||
drb_t established_drbs[NGAP_MAX_DRBS_PER_UE];
|
||||
uint8_t DRB_active[NGAP_MAX_DRBS_PER_UE];
|
||||
|
||||
NR_SRB_INFO_TABLE_ENTRY Srb[maxSRBs]; // 3gpp max is 3 SRBs, number 1..3, we waste the entry 0 for code simplicity
|
||||
|
||||
@@ -136,17 +136,6 @@ void nr_rrc_trigger(protocol_ctxt_t *ctxt, int CC_id, int frame, int subframe);
|
||||
\ *reOffset Pointer to RE Offset Value */
|
||||
void rrc_config_dl_ptrs_params(NR_BWP_Downlink_t *bwp, int *ptrsNrb, int *ptrsMcs, int *epre_Ratio, int * reOffset);
|
||||
|
||||
uint8_t
|
||||
nr_rrc_data_req(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const rb_id_t rb_idP,
|
||||
const mui_t muiP,
|
||||
const confirm_t confirmP,
|
||||
const sdu_size_t sdu_size,
|
||||
uint8_t *const buffer_pP,
|
||||
const pdcp_transmission_mode_t modeP
|
||||
);
|
||||
|
||||
int
|
||||
nr_rrc_mac_remove_ue(module_id_t mod_idP,
|
||||
rnti_t rntiP);
|
||||
|
||||
+239
-182
@@ -82,7 +82,7 @@
|
||||
#include "rrc_gNB_GTPV1U.h"
|
||||
|
||||
#include "nr_pdcp/nr_pdcp_entity.h"
|
||||
#include "pdcp.h"
|
||||
#include "nr_pdcp/nr_pdcp_oai_api.h"
|
||||
|
||||
#include "intertask_interface.h"
|
||||
#include "SIMULATION/TOOLS/sim.h" // for taus
|
||||
@@ -105,15 +105,6 @@
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
extern void pdcp_config_set_security(const protocol_ctxt_t *const ctxt_pP,
|
||||
pdcp_t *const pdcp_pP,
|
||||
const rb_id_t rb_idP,
|
||||
const uint16_t lc_idP,
|
||||
const uint8_t security_modeP,
|
||||
uint8_t *const kRRCenc,
|
||||
uint8_t *const kRRCint,
|
||||
uint8_t *const kUPenc);
|
||||
|
||||
static inline uint64_t bitStr_to_uint64(BIT_STRING_t *asn);
|
||||
|
||||
mui_t rrc_gNB_mui = 0;
|
||||
@@ -582,7 +573,7 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co
|
||||
ue_context_pP->ue_context.rnti);
|
||||
AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n");
|
||||
|
||||
nr_rrc_data_req(ctxt_pP, DCCH, rrc_gNB_mui++, SDU_CONFIRM_NO, size, buffer, PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc);
|
||||
|
||||
if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) {
|
||||
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
||||
@@ -652,7 +643,8 @@ void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP,
|
||||
if(drb_is_active(ue_p, drb_id)){ /* Non-GBR flow using the same DRB or a GBR flow with no available DRBs*/
|
||||
nb_drb_to_setup--;
|
||||
} else {
|
||||
NR_DRB_ToAddMod_t *DRB_config = generateDRB(ue_p, drb_id, &ue_p->pduSession[i], rrc->configuration.enable_sdap, rrc->security.do_drb_integrity, rrc->security.do_drb_ciphering);
|
||||
generateDRB(ue_p, drb_id, &ue_p->pduSession[i], rrc->configuration.enable_sdap, rrc->security.do_drb_integrity, rrc->security.do_drb_ciphering);
|
||||
NR_DRB_ToAddMod_t *DRB_config = generateDRB_ASN1(&ue_p->established_drbs[drb_id-1]);
|
||||
if (drb_id_to_setup_start == 0)
|
||||
drb_id_to_setup_start = DRB_config->drb_Identity;
|
||||
asn1cSeqAdd(&ue_p->DRB_configList->list, DRB_config);
|
||||
@@ -771,14 +763,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
|
||||
ctxt_pP->module_id,
|
||||
DCCH);
|
||||
|
||||
nr_rrc_data_req(
|
||||
ctxt_pP,
|
||||
DCCH,
|
||||
rrc_gNB_mui++,
|
||||
SDU_CONFIRM_NO,
|
||||
size,
|
||||
buffer,
|
||||
PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc);
|
||||
|
||||
if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) {
|
||||
nr_mac_update_cellgroup(RC.nrmac[rrc->module_id], ue_context_pP->ue_context.rnti, ue_context_pP->ue_context.masterCellGroup);
|
||||
@@ -945,22 +930,16 @@ rrc_gNB_modify_dedicatedRRCReconfiguration(
|
||||
ctxt_pP->module_id,
|
||||
DCCH);
|
||||
|
||||
nr_rrc_data_req(
|
||||
ctxt_pP,
|
||||
DCCH,
|
||||
rrc_gNB_mui++,
|
||||
SDU_CONFIRM_NO,
|
||||
size,
|
||||
buffer,
|
||||
PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc);
|
||||
|
||||
if (NODE_IS_DU(RC.nrrrc[ctxt_pP->module_id]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
|
||||
if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) {
|
||||
uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated
|
||||
&& ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList
|
||||
? NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS
|
||||
: NR_RRC_RECONFIGURATION_DELAY_MS;
|
||||
|
||||
nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, ue_p->rnti, *RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, delay_ms);
|
||||
nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, ue_p->rnti, *rrc->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, delay_ms);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1035,22 +1014,17 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release(
|
||||
rrc_gNB_mui,
|
||||
ctxt_pP->module_id,
|
||||
DCCH);
|
||||
nr_rrc_data_req(
|
||||
ctxt_pP,
|
||||
DCCH,
|
||||
rrc_gNB_mui++,
|
||||
SDU_CONFIRM_NO,
|
||||
size,
|
||||
buffer,
|
||||
PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
|
||||
if (NODE_IS_DU(RC.nrrrc[ctxt_pP->module_id]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc);
|
||||
|
||||
if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) {
|
||||
uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated
|
||||
&& ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList
|
||||
? NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS
|
||||
: NR_RRC_RECONFIGURATION_DELAY_MS;
|
||||
|
||||
nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, ue_p->rnti, *RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, delay_ms);
|
||||
nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, ue_p->rnti, *rrc->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, delay_ms);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1289,55 +1263,55 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP,
|
||||
} // if (*SRB_configList != NULL)
|
||||
|
||||
LOG_I(NR_RRC, "Set PDCP security RNTI %04lx nca %ld nia %d in RRCReestablishment\n", ctxt_pP->rntiMaybeUEid, ue_p->ciphering_algorithm, ue_p->integrity_algorithm);
|
||||
pdcp_config_set_security(ctxt_pP,
|
||||
NULL, /* pdcp_pP not used anymore in NR */
|
||||
DCCH,
|
||||
DCCH + 2,
|
||||
enable_ciphering ? ue_p->ciphering_algorithm | (ue_p->integrity_algorithm << 4) : 0 | (ue_p->integrity_algorithm << 4),
|
||||
kRRCenc,
|
||||
kRRCint,
|
||||
kUPenc);
|
||||
uint8_t security_mode =
|
||||
enable_ciphering ? ue_p->ciphering_algorithm | (ue_p->integrity_algorithm << 4) : 0 | (ue_p->integrity_algorithm << 4);
|
||||
|
||||
nr_pdcp_config_set_security(ctxt_pP->rntiMaybeUEid,
|
||||
DCCH,
|
||||
security_mode,
|
||||
kRRCenc,
|
||||
kRRCint,
|
||||
kUPenc);
|
||||
|
||||
if (!NODE_IS_CU(rrc->node_type)) {
|
||||
apply_macrlc_config_reest(rrc, ue_context_pP, ctxt_pP, ctxt_pP->rntiMaybeUEid);
|
||||
}
|
||||
|
||||
nr_rrc_data_req(ctxt_pP, DCCH, rrc_gNB_mui++, SDU_CONFIRM_NO, size, buffer, PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP, const rnti_t reestablish_rnti, rrc_gNB_ue_context_t *ue_context_pP, const uint8_t xid)
|
||||
//-----------------------------------------------------------------------------
|
||||
/*
|
||||
* Handle RRC Reestablishment Complete Functions
|
||||
*/
|
||||
|
||||
/// @brief Function used in RRCReestablishmentComplete procedure to reestablish the SRB2.
|
||||
/// @param old_xid The old RRC transaction id.
|
||||
/// @param new_xid The new RRC transaction id.
|
||||
void RRCReestablishmentComplete_fill_SRB2_configList(const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *ue_context_pP,
|
||||
const uint8_t old_xid,
|
||||
const uint8_t new_xid)
|
||||
{
|
||||
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
||||
LOG_I(NR_RRC, "[RAPROC] UE %04x Logical Channel UL-DCCH, processing NR_RRCReestablishmentComplete from UE (SRB1 Active)\n", ue_p->rnti);
|
||||
|
||||
NR_DRB_ToAddModList_t *DRB_configList = ue_p->DRB_configList;
|
||||
NR_SRB_ToAddMod_t *SRB2_config = NULL;
|
||||
NR_SRB_ToAddModList_t *SRB_configList = ue_p->SRB_configList;
|
||||
NR_SRB_ToAddModList_t **SRB_configList2 = NULL;
|
||||
NR_DRB_ToAddModList_t **DRB_configList2 = NULL;
|
||||
NR_SRB_ToAddMod_t *SRB2_config = NULL;
|
||||
NR_DRB_ToAddMod_t *DRB_config = NULL;
|
||||
//NR_SDAP_Config_t *sdap_config = NULL;
|
||||
int i = 0;
|
||||
NR_SRB_ToAddModList_t **SRB_configList2 = NULL;
|
||||
|
||||
uint8_t new_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
|
||||
int ret = 0;
|
||||
ue_p->StatusRrc = NR_RRC_CONNECTED;
|
||||
ue_p->ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED
|
||||
ue_p->reestablishment_xid = new_xid;
|
||||
SRB_configList2 = &ue_p->SRB_configList2[xid];
|
||||
SRB_configList2 = &ue_p->SRB_configList2[old_xid];
|
||||
|
||||
// get old configuration of SRB2
|
||||
if (*SRB_configList2 != NULL) {
|
||||
if((*SRB_configList2)->list.count!=0) {
|
||||
LOG_D(NR_RRC, "SRB_configList2(%p) count is %d\n SRB_configList2->list.array[0] addr is %p",
|
||||
SRB_configList2, (*SRB_configList2)->list.count, (*SRB_configList2)->list.array[0]);
|
||||
if ((*SRB_configList2)->list.count != 0) {
|
||||
LOG_D(NR_RRC,
|
||||
"RRC Reestablishment - SRB_configList2(%p) count is %d\n SRB_configList2->list.array[0] addr is %p\n",
|
||||
SRB_configList2,
|
||||
(*SRB_configList2)->list.count,
|
||||
(*SRB_configList2)->list.array[0]);
|
||||
}
|
||||
|
||||
for (i = 0; (i < (*SRB_configList2)->list.count) && (i < 3); i++) {
|
||||
if ((*SRB_configList2)->list.array[i]->srb_Identity == 2 ) {
|
||||
LOG_D(NR_RRC, "get SRB2_config from (ue_p->SRB_configList2[%d])\n", xid);
|
||||
for (int i = 0; (i < (*SRB_configList2)->list.count) && (i < 3); i++) {
|
||||
if ((*SRB_configList2)->list.array[i]->srb_Identity == 2) {
|
||||
LOG_D(NR_RRC, "RRC Reestablishment - get SRB2_config from (ue_p->SRB_configList2[%d])\n", old_xid);
|
||||
SRB2_config = (*SRB_configList2)->list.array[i];
|
||||
SRB2_config->reestablishPDCP = CALLOC(1, sizeof(*SRB2_config->reestablishPDCP));
|
||||
*SRB2_config->reestablishPDCP = NR_SRB_ToAddMod__reestablishPDCP_true;
|
||||
@@ -1346,15 +1320,11 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx
|
||||
}
|
||||
}
|
||||
|
||||
// SRB2_config = CALLOC(1, sizeof(*SRB2_config));
|
||||
// SRB2_config->srb_Identity = 2;
|
||||
|
||||
SRB_configList2 = &(ue_p->SRB_configList2[new_xid]);
|
||||
DRB_configList2 = &(ue_p->DRB_configList2[new_xid]);
|
||||
|
||||
if (*SRB_configList2) {
|
||||
free(*SRB_configList2);
|
||||
LOG_D(NR_RRC, "free(ue_p->SRB_configList2[%d])\n", new_xid);
|
||||
LOG_D(NR_RRC, "RRC Reestablishment - free(ue_p->SRB_configList2[%d])\n", new_xid);
|
||||
}
|
||||
|
||||
*SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
|
||||
@@ -1363,42 +1333,74 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx
|
||||
// Add SRB2 to SRB configuration list
|
||||
asn1cSeqAdd(&SRB_configList->list, SRB2_config);
|
||||
asn1cSeqAdd(&(*SRB_configList2)->list, SRB2_config);
|
||||
LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_p->SRB_configList\n", SRB2_config->srb_Identity);
|
||||
LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_p->SRB_configList2[%d]\n", SRB2_config->srb_Identity, new_xid);
|
||||
LOG_D(NR_RRC, "RRC Reestablishment - Add SRB2_config (srb_Identity:%ld) to ue_p->SRB_configList\n", SRB2_config->srb_Identity);
|
||||
LOG_D(NR_RRC,
|
||||
"RRC Reestablishment - Add SRB2_config (srb_Identity:%ld) to ue_p->SRB_configList2[%d]\n",
|
||||
SRB2_config->srb_Identity,
|
||||
new_xid);
|
||||
} else {
|
||||
// SRB configuration list only contains SRB1.
|
||||
LOG_W(NR_RRC,"SRB2 configuration does not exist in SRB configuration list\n");
|
||||
}
|
||||
|
||||
if (*DRB_configList2) {
|
||||
free(*DRB_configList2);
|
||||
LOG_D(NR_RRC, "free(ue_p->DRB_configList2[%d])\n", new_xid);
|
||||
}
|
||||
|
||||
*DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2));
|
||||
|
||||
if (DRB_configList != NULL) {
|
||||
LOG_D(NR_RRC, "get DRB_config from (ue_p->DRB_configList)\n");
|
||||
|
||||
for (i = 0; (i < DRB_configList->list.count) && (i < 3); i++) {
|
||||
DRB_config = DRB_configList->list.array[i];
|
||||
asn1cCallocOne(DRB_config->reestablishPDCP, NR_DRB_ToAddMod__reestablishPDCP_true);
|
||||
// Add DRB to DRB configuration list, for LTE_RRCConnectionReconfigurationComplete
|
||||
asn1cSeqAdd(&(*DRB_configList2)->list, DRB_config);
|
||||
}
|
||||
LOG_W(NR_RRC, "RRC Reestablishment - SRB2 configuration does not exist in SRB configuration list\n");
|
||||
}
|
||||
|
||||
ue_p->Srb[1].Active = 1;
|
||||
|
||||
if (get_softmodem_params()->sa) {
|
||||
LOG_W(NR_RRC, "Rework identity mapping need to be done properly!\n");
|
||||
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0};
|
||||
uint8_t send_security_mode_command = false;
|
||||
nr_rrc_pdcp_config_security(ctxt_pP, ue_context_pP, send_security_mode_command);
|
||||
LOG_D(NR_RRC, "RRC Reestablishment - set security successfully \n");
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Function used in RRCReestablishmentComplete procedure to reestablish the DRBs
|
||||
/// that the UE previously had, it gets the information from the established_drbs
|
||||
/// struct.
|
||||
/// @param new_xid The new RRC transaction id.
|
||||
void RRCReestablishmentComplete_fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *ue_context_pP,
|
||||
const uint8_t new_xid)
|
||||
{
|
||||
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
||||
NR_DRB_ToAddMod_t *DRB_config = NULL;
|
||||
NR_DRB_ToAddModList_t **DRB_configList2 = &(ue_p->DRB_configList2[new_xid]);
|
||||
|
||||
if (*DRB_configList2) {
|
||||
free(*DRB_configList2);
|
||||
LOG_D(NR_RRC, "RRC Reestablishment - free(ue_p->DRB_configList2[%d])\n", new_xid);
|
||||
}
|
||||
|
||||
*DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2));
|
||||
|
||||
for (int i = 0; i < NGAP_MAX_DRBS_PER_UE; i++) {
|
||||
if (ue_p->established_drbs[i].status != DRB_INACTIVE) {
|
||||
ue_p->established_drbs[i].reestablishPDCP = NR_DRB_ToAddMod__reestablishPDCP_true;
|
||||
DRB_config = generateDRB_ASN1(&ue_p->established_drbs[i]);
|
||||
asn1cCallocOne(DRB_config->reestablishPDCP, NR_DRB_ToAddMod__reestablishPDCP_true);
|
||||
asn1cSeqAdd(&(*DRB_configList2)->list, DRB_config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Function used in RRCReestablishmentComplete procedure to update the NGU Tunnels.
|
||||
/// @param reestablish_rnti is the old C-RNTI
|
||||
void RRCReestablishmentComplete_update_ngu_tunnel(const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *ue_context_pP,
|
||||
const rnti_t reestablish_rnti)
|
||||
{
|
||||
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (get_softmodem_params()->sa) {
|
||||
LOG_W(NR_RRC, "RRC Reestablishment - Rework identity mapping need to be done properly!\n");
|
||||
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req = {0};
|
||||
/* Save e RAB information for later */
|
||||
int j;
|
||||
|
||||
for (j = 0, i = 0; i < NB_RB_MAX; i++) {
|
||||
if (ue_p->pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_p->pduSession[i].status == PDU_SESSION_STATUS_DONE) {
|
||||
create_tunnel_req.pdusession_id[j] = ue_p->pduSession[i].param.pdusession_id;
|
||||
create_tunnel_req.incoming_rb_id[j] = i+1;
|
||||
create_tunnel_req.incoming_rb_id[j] = i + 1;
|
||||
create_tunnel_req.outgoing_teid[j] = ue_p->pduSession[i].param.gtp_teid;
|
||||
// to be developped, use the first QFI only
|
||||
create_tunnel_req.outgoing_qfi[j] = ue_p->pduSession[i].param.qos[0].qfi;
|
||||
@@ -1409,14 +1411,11 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx
|
||||
}
|
||||
|
||||
create_tunnel_req.ue_id = ctxt_pP->rntiMaybeUEid; // warning put zero above
|
||||
create_tunnel_req.num_tunnels = j;
|
||||
ret = gtpv1u_update_ngu_tunnel(
|
||||
ctxt_pP->instance,
|
||||
&create_tunnel_req,
|
||||
reestablish_rnti);
|
||||
create_tunnel_req.num_tunnels = j;
|
||||
ret = gtpv1u_update_ngu_tunnel(ctxt_pP->instance, &create_tunnel_req, reestablish_rnti);
|
||||
|
||||
if ( ret != 0 ) {
|
||||
LOG_E(NR_RRC, "gtpv1u_update_ngu_tunnel failed,start to release UE %x\n", reestablish_rnti);
|
||||
if (ret != 0) {
|
||||
LOG_E(NR_RRC, "RRC Reestablishment - gtpv1u_update_ngu_tunnel failed,start to release UE %x\n", reestablish_rnti);
|
||||
ue_p->ue_release_timer_s1 = 1;
|
||||
ue_p->ue_release_timer_thres_s1 = 100;
|
||||
ue_p->ue_release_timer = 0;
|
||||
@@ -1426,34 +1425,72 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Function used in RRCReestablishmentComplete procedure to update the NAS PDUSessions and the xid.
|
||||
/// @param old_xid Refers to the old transaction identifier passed to rrc_gNB_process_RRCReestablishmentComplete as xid.
|
||||
/// @todo parameters yet to process inside the for loop.
|
||||
/// @todo should test if pdu session are Ok before! inside the for loop.
|
||||
void RRCReestablishmentComplete_nas_pdu_update(rrc_gNB_ue_context_t *ue_context_pP, const uint8_t old_xid)
|
||||
{
|
||||
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
||||
/* Add all NAS PDUs to the list */
|
||||
for (int i = 0; i < ue_p->nb_of_pdusessions; i++) {
|
||||
ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE;
|
||||
ue_p->pduSession[i].xid = old_xid;
|
||||
LOG_D(NR_RRC,
|
||||
"RRC Reestablishment - setting the status for the default DRB (index %d) to (%d,%s)\n",
|
||||
i,
|
||||
ue_p->pduSession[i].status,
|
||||
"PDU_SESSION_STATUS_DONE");
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Function used in RRCReestablishmentComplete procedure to Free all the NAS PDU buffers.
|
||||
void RRCReestablishmentComplete_nas_pdu_free(rrc_gNB_ue_context_t *ue_context_pP)
|
||||
{
|
||||
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
||||
/* Free all NAS PDUs */
|
||||
for (int i = 0; i < ue_p->nb_of_pdusessions; i++) {
|
||||
if (ue_p->pduSession[i].param.nas_pdu.buffer != NULL) {
|
||||
/* Free the NAS PDU buffer and invalidate it */
|
||||
free(ue_p->pduSession[i].param.nas_pdu.buffer);
|
||||
ue_p->pduSession[i].param.nas_pdu.buffer = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Function tha processes RRCReestablishmentComplete message sent by the UE, after RRCReestasblishment request.
|
||||
/// @param ctxt_pP Protocol context containing information regarding the UE and gNB
|
||||
/// @param reestablish_rnti is the old C-RNTI
|
||||
/// @param ue_context_pP UE context container information regarding the UE
|
||||
/// @param xid Transaction Identifier used in RRC messages
|
||||
void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP,
|
||||
const rnti_t reestablish_rnti,
|
||||
rrc_gNB_ue_context_t *ue_context_pP,
|
||||
const uint8_t xid)
|
||||
{
|
||||
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
||||
LOG_I(NR_RRC,
|
||||
"[RAPROC] UE %04x Logical Channel UL-DCCH, processing NR_RRCReestablishmentComplete from UE (SRB1 Active)\n",
|
||||
ue_p->rnti);
|
||||
|
||||
int i = 0;
|
||||
|
||||
uint8_t new_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
|
||||
ue_p->StatusRrc = NR_RRC_CONNECTED;
|
||||
ue_p->ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED
|
||||
ue_p->reestablishment_xid = new_xid;
|
||||
|
||||
RRCReestablishmentComplete_fill_SRB2_configList(ctxt_pP, ue_context_pP, xid, new_xid);
|
||||
RRCReestablishmentComplete_fill_DRB_configList(ctxt_pP, ue_context_pP, new_xid);
|
||||
RRCReestablishmentComplete_update_ngu_tunnel(ctxt_pP, ue_context_pP, reestablish_rnti);
|
||||
RRCReestablishmentComplete_nas_pdu_update(ue_context_pP, xid);
|
||||
|
||||
/* Update RNTI in ue_context */
|
||||
LOG_I(NR_RRC, "Updating UEid from %04x to %lx\n", ue_p->rnti, ctxt_pP->rntiMaybeUEid);
|
||||
LOG_I(NR_RRC, "RRC Reestablishment - Updating UEid from %04x to %lx\n", ue_p->rnti, ctxt_pP->rntiMaybeUEid);
|
||||
rrc_gNB_update_ue_context_rnti(ctxt_pP->rntiMaybeUEid, RC.nrrrc[ctxt_pP->module_id], ue_p->gNB_ue_ngap_id);
|
||||
|
||||
if (get_softmodem_params()->sa) {
|
||||
uint8_t send_security_mode_command = false;
|
||||
nr_rrc_pdcp_config_security(
|
||||
ctxt_pP,
|
||||
ue_context_pP,
|
||||
send_security_mode_command ? 0 : 1);
|
||||
LOG_D(NR_RRC, "set security successfully \n");
|
||||
}
|
||||
|
||||
uint8_t drb_id_to_setup_start = DRB_configList ? DRB_configList->list.array[0]->drb_Identity : 1;
|
||||
uint8_t nb_drb_to_setup = DRB_configList ? DRB_configList->list.count : ue_p->nb_of_pdusessions;
|
||||
/* TODO: hardcoded to 13 for the time being, to be changed? */
|
||||
long drb_priority[NGAP_MAX_DRBS_PER_UE] = {13};
|
||||
|
||||
/* Add all NAS PDUs to the list */
|
||||
for (i = 0; i < ue_p->nb_of_pdusessions; i++) {
|
||||
/* TODO parameters yet to process ... */
|
||||
/* TODO should test if pdu session are Ok before! */
|
||||
ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE;
|
||||
ue_p->pduSession[i].xid = xid;
|
||||
LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", i, ue_p->pduSession[i].status, "PDU_SESSION_STATUS_DONE");
|
||||
}
|
||||
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t));
|
||||
|
||||
@@ -1461,51 +1498,62 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx
|
||||
ue_p->masterCellGroup->spCellConfig = ue_p->spCellConfigReestablishment;
|
||||
ue_p->spCellConfigReestablishment = NULL;
|
||||
cellGroupConfig->spCellConfig = ue_p->masterCellGroup->spCellConfig;
|
||||
cellGroupConfig->physicalCellGroupConfig = ue_p->masterCellGroup->physicalCellGroupConfig;
|
||||
cellGroupConfig->physicalCellGroupConfig = ue_p->masterCellGroup->physicalCellGroupConfig;
|
||||
|
||||
fill_mastercellGroupConfig(cellGroupConfig, ue_p->masterCellGroup, rrc->um_on_default_drb, (drb_id_to_setup_start < 2) ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority);
|
||||
uint8_t drb_id_to_setup_start = ue_p->DRB_configList ? ue_p->DRB_configList->list.array[0]->drb_Identity : 1;
|
||||
uint8_t nb_drb_to_setup = ue_p->DRB_configList ? ue_p->DRB_configList->list.count : ue_p->nb_of_pdusessions;
|
||||
/* TODO: hardcoded to 13 for the time being, to be changed? */
|
||||
long drb_priority[NGAP_MAX_DRBS_PER_UE] = {13};
|
||||
|
||||
for(i = 0; i < cellGroupConfig->rlc_BearerToAddModList->list.count; i++) {
|
||||
cellGroupConfig->rlc_BearerToAddModList->list.array[i]->reestablishRLC = CALLOC(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList->list.array[i]->reestablishRLC));
|
||||
fill_mastercellGroupConfig(cellGroupConfig,
|
||||
ue_p->masterCellGroup,
|
||||
rrc->um_on_default_drb,
|
||||
(drb_id_to_setup_start < 2) ? 1 : 0,
|
||||
drb_id_to_setup_start,
|
||||
nb_drb_to_setup,
|
||||
drb_priority);
|
||||
|
||||
for (i = 0; i < cellGroupConfig->rlc_BearerToAddModList->list.count; i++) {
|
||||
cellGroupConfig->rlc_BearerToAddModList->list.array[i]->reestablishRLC =
|
||||
CALLOC(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList->list.array[i]->reestablishRLC));
|
||||
*cellGroupConfig->rlc_BearerToAddModList->list.array[i]->reestablishRLC = NR_RLC_BearerConfig__reestablishRLC_true;
|
||||
}
|
||||
|
||||
uint8_t buffer[RRC_BUF_SIZE] = {0};
|
||||
int size = do_RRCReconfiguration(ctxt_pP,
|
||||
buffer,
|
||||
RRC_BUF_SIZE,
|
||||
new_xid,
|
||||
*SRB_configList2,
|
||||
DRB_configList,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, // MeasObj_list,
|
||||
NULL,
|
||||
ue_context_pP,
|
||||
&rrc->carrier,
|
||||
NULL,
|
||||
NULL,
|
||||
cellGroupConfig);
|
||||
buffer,
|
||||
RRC_BUF_SIZE,
|
||||
new_xid,
|
||||
ue_p->SRB_configList2[new_xid],
|
||||
ue_p->DRB_configList2[new_xid],
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, // MeasObj_list,
|
||||
NULL,
|
||||
ue_context_pP,
|
||||
&rrc->carrier,
|
||||
NULL,
|
||||
NULL,
|
||||
cellGroupConfig);
|
||||
|
||||
LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Reconfiguration\n");
|
||||
LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buffer, size, "[MSG] RRC Reconfiguration\n");
|
||||
|
||||
/* Free all NAS PDUs */
|
||||
for (i = 0; i < ue_p->nb_of_pdusessions; i++) {
|
||||
if (ue_p->pduSession[i].param.nas_pdu.buffer != NULL) {
|
||||
/* Free the NAS PDU buffer and invalidate it */
|
||||
free(ue_p->pduSession[i].param.nas_pdu.buffer);
|
||||
ue_p->pduSession[i].param.nas_pdu.buffer = NULL;
|
||||
}
|
||||
}
|
||||
RRCReestablishmentComplete_nas_pdu_free(ue_context_pP);
|
||||
|
||||
if (size < 0) {
|
||||
LOG_E(NR_RRC, "RRC decode err!!! do_RRCReconfiguration\n");
|
||||
return;
|
||||
} else {
|
||||
LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE id %04x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_p->rnti);
|
||||
LOG_I(NR_RRC,
|
||||
"[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE id %04x)\n",
|
||||
ctxt_pP->module_id,
|
||||
ctxt_pP->frame,
|
||||
size,
|
||||
ue_p->rnti);
|
||||
LOG_D(NR_RRC,
|
||||
"[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (RRCReconfiguration to UE %04x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
|
||||
"[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (RRCReconfiguration to UE %04x MUI %d) --->][PDCP][MOD "
|
||||
"%u][RB %u]\n",
|
||||
ctxt_pP->frame,
|
||||
ctxt_pP->module_id,
|
||||
size,
|
||||
@@ -1515,16 +1563,20 @@ cellGroupConfig->physicalCellGroupConfig = ue_p->masterCellGroup->physicalCellGr
|
||||
DCCH);
|
||||
|
||||
nr_mac_update_cellgroup(RC.nrmac[rrc->module_id], ue_context_pP->ue_context.rnti, cellGroupConfig);
|
||||
nr_rrc_data_req(ctxt_pP, DCCH, rrc_gNB_mui++, SDU_CONFIRM_NO, size, buffer, PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc);
|
||||
}
|
||||
|
||||
if (NODE_IS_DU(RC.nrrrc[ctxt_pP->module_id]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
|
||||
uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated
|
||||
uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig
|
||||
&& ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated
|
||||
&& ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList
|
||||
? NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS
|
||||
: NR_RRC_RECONFIGURATION_DELAY_MS;
|
||||
|
||||
nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, ue_p->rnti, *RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, delay_ms);
|
||||
nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id,
|
||||
ue_p->rnti,
|
||||
*RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing,
|
||||
delay_ms);
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -1566,21 +1618,16 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP
|
||||
|
||||
nr_mac_update_cellgroup(RC.nrmac[ctxt_pP->module_id], ue_context_pP->ue_context.rnti, masterCellGroup);
|
||||
|
||||
nr_rrc_data_req(ctxt_pP,
|
||||
DCCH,
|
||||
rrc_gNB_mui++,
|
||||
SDU_CONFIRM_NO,
|
||||
size,
|
||||
buffer,
|
||||
PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc);
|
||||
|
||||
if (NODE_IS_DU(RC.nrrrc[ctxt_pP->module_id]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
|
||||
if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) {
|
||||
uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated
|
||||
&& ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList
|
||||
? NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS
|
||||
: NR_RRC_RECONFIGURATION_DELAY_MS;
|
||||
|
||||
nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, ue_p->rnti, *RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, delay_ms);
|
||||
nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, ue_p->rnti, *rrc->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, delay_ms);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -3225,7 +3272,7 @@ void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
|
||||
gNB_MAC_INST *nrmac = RC.nrmac[ctxt_pP->module_id]; // WHAT A BEAUTIFULL RACE CONDITION !!!
|
||||
mac_remove_nr_ue(nrmac, UE->rnti);
|
||||
rrc_rlc_remove_ue(ctxt_pP);
|
||||
pdcp_remove_UE(ctxt_pP);
|
||||
nr_pdcp_remove_UE(ctxt_pP->rntiMaybeUEid);
|
||||
|
||||
/* remove RRC UE Context */
|
||||
ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, UE->rnti);
|
||||
@@ -3262,7 +3309,7 @@ void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
|
||||
mac_remove_nr_ue(nrmac, UE->rnti);
|
||||
}
|
||||
rrc_rlc_remove_ue(ctxt_pP);
|
||||
pdcp_remove_UE(ctxt_pP);
|
||||
nr_pdcp_remove_UE(ctxt_pP->rntiMaybeUEid);
|
||||
newGtpuDeleteAllTunnels(ctxt_pP->instance, UE->rnti);
|
||||
|
||||
/* remove RRC UE Context */
|
||||
@@ -3623,7 +3670,7 @@ rrc_gNB_generate_SecurityModeCommand(
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n");
|
||||
|
||||
nr_rrc_data_req(ctxt_pP, DCCH, rrc_gNB_mui++, SDU_CONFIRM_NO, size, buffer, PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -3649,7 +3696,7 @@ rrc_gNB_generate_UECapabilityEnquiry(
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n");
|
||||
|
||||
nr_rrc_data_req(ctxt_pP, DCCH, rrc_gNB_mui++, SDU_CONFIRM_NO, size, buffer, PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -3683,12 +3730,22 @@ rrc_gNB_generate_RRCRelease(
|
||||
rrc_gNB_mui,
|
||||
DCCH);
|
||||
|
||||
nr_rrc_data_req(ctxt_pP, DCCH, rrc_gNB_mui++, SDU_CONFIRM_NO, size, buffer, PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc);
|
||||
|
||||
rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(ctxt_pP->instance, ue_context_pP->ue_context.gNB_ue_ngap_id);
|
||||
ue_context_pP->ue_context.ue_release_timer_rrc = 1;
|
||||
/* TODO: 38.331 says for RRC Release that the UE should release everything
|
||||
* after 60ms or if lower layers acked receipt of release. Hence, from the
|
||||
* gNB POV, we can free the UE's RRC context as soon as we sent the msg.
|
||||
* Currently, without the F1 interface, the ue_release timer expiration also
|
||||
* triggers MAC, so we give it some time. If we send an F1 UE Context release
|
||||
* message, we can free it immediately. The MAC should release it after these
|
||||
* 60ms, or the ack of the DLSCH transmission. */
|
||||
ue_context_pP->ue_context.ue_release_timer_thres_rrc = 5;
|
||||
LOG_I(RRC, "delaying UE %ld context removal by 5ms\n", ctxt_pP->rntiMaybeUEid);
|
||||
|
||||
if (NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
|
||||
if (NODE_IS_CU(rrc->node_type)) {
|
||||
uint8_t *message_buffer = itti_malloc (TASK_RRC_GNB, TASK_CU_F1, size);
|
||||
memcpy (message_buffer, buffer, size);
|
||||
MessageDef *m = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD);
|
||||
|
||||
@@ -36,8 +36,9 @@
|
||||
|
||||
#include "oai_asn1.h"
|
||||
#include "intertask_interface.h"
|
||||
#include "pdcp.h"
|
||||
#include "nr_pdcp/nr_pdcp_oai_api.h"
|
||||
#include "pdcp_primitives.h"
|
||||
#include "SDAP/nr_sdap/nr_sdap.h"
|
||||
|
||||
#include "openair3/ocp-gtpu/gtp_itf.h"
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
@@ -153,14 +154,9 @@ nr_rrc_pdcp_config_security(
|
||||
}
|
||||
}
|
||||
|
||||
pdcp_config_set_security(ctxt_pP,
|
||||
NULL, /* pdcp_pP not used anymore in NR */
|
||||
DCCH,
|
||||
DCCH + 2,
|
||||
enable_ciphering ? UE->ciphering_algorithm | (UE->integrity_algorithm << 4) : 0 | (UE->integrity_algorithm << 4),
|
||||
kRRCenc,
|
||||
kRRCint,
|
||||
kUPenc);
|
||||
uint8_t security_mode =
|
||||
enable_ciphering ? UE->ciphering_algorithm | (UE->integrity_algorithm << 4) : 0 | (UE->integrity_algorithm << 4);
|
||||
nr_pdcp_config_set_security(ctxt_pP->rntiMaybeUEid, DCCH, security_mode, kRRCenc, kRRCint, kUPenc);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -396,7 +392,7 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t
|
||||
}
|
||||
create_tunnel_req.ue_id = UE->rnti;
|
||||
gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp = {0};
|
||||
int ret = gtpv1u_create_ngu_tunnel(instance, &create_tunnel_req, &create_tunnel_resp);
|
||||
int ret = gtpv1u_create_ngu_tunnel(instance, &create_tunnel_req, &create_tunnel_resp, nr_pdcp_data_req_drb, sdap_data_req);
|
||||
if (ret != 0) {
|
||||
LOG_E(NR_RRC, "rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE %x\n", UE->rnti);
|
||||
UE->ue_release_timer_ng = 1;
|
||||
@@ -625,7 +621,7 @@ int rrc_gNB_process_NGAP_DOWNLINK_NAS(MessageDef *msg_p, instance_t instance, mu
|
||||
AssertFatal(!NODE_IS_DU(RC.nrrrc[ctxt.module_id]->node_type), "illegal node type DU: receiving NGAP messages at this node\n");
|
||||
/* Transfer data to PDCP */
|
||||
rb_id_t srb_id = UE->Srb[2].Active ? DCCH1 : DCCH;
|
||||
nr_rrc_data_req(&ctxt, srb_id, (*rrc_gNB_mui)++, SDU_CONFIRM_NO, length, buffer, PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
nr_pdcp_data_req_srb(ctxt.rntiMaybeUEid, srb_id, (*rrc_gNB_mui)++, length, buffer, deliver_pdu_srb_f1, RC.nrrrc[instance]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
#include "UTIL/OSA/osa_defs.h"
|
||||
#include <openair2/RRC/NR/nr_rrc_proto.h>
|
||||
#include "pdcp.h"
|
||||
#include "nr_pdcp/nr_pdcp_oai_api.h"
|
||||
|
||||
void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList, x2ap_ENDC_sgnb_addition_req_t *m, NR_CG_ConfigInfo_IEs_t *cg_config_info)
|
||||
{
|
||||
@@ -282,10 +282,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a
|
||||
memset(&create_tunnel_resp, 0, sizeof(create_tunnel_resp));
|
||||
if (!IS_SOFTMODEM_NOS1) {
|
||||
LOG_D(RRC, "Calling gtpv1u_create_s1u_tunnel()\n");
|
||||
gtpv1u_create_s1u_tunnel(
|
||||
ctxt.instance,
|
||||
&create_tunnel_req,
|
||||
&create_tunnel_resp);
|
||||
gtpv1u_create_s1u_tunnel(ctxt.instance, &create_tunnel_req, &create_tunnel_resp, nr_pdcp_data_req_drb);
|
||||
rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
&ctxt,
|
||||
&create_tunnel_resp,
|
||||
@@ -391,7 +388,7 @@ void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) {
|
||||
return;
|
||||
}
|
||||
|
||||
pdcp_remove_UE(&ctxt);
|
||||
nr_pdcp_remove_UE(ctxt.rntiMaybeUEid);
|
||||
|
||||
rrc_rlc_remove_ue(&ctxt);
|
||||
|
||||
|
||||
@@ -36,65 +36,109 @@ rrc_pdu_session_param_t *find_pduSession(gNB_RRC_UE_t *ue, int id, bool create)
|
||||
return ue->pduSession + j;
|
||||
}
|
||||
|
||||
NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *ue, uint8_t drb_id, rrc_pdu_session_param_t *pduSession, bool enable_sdap, int do_drb_integrity, int do_drb_ciphering)
|
||||
void generateDRB(gNB_RRC_UE_t *ue,
|
||||
uint8_t drb_id,
|
||||
rrc_pdu_session_param_t *pduSession,
|
||||
bool enable_sdap,
|
||||
int do_drb_integrity,
|
||||
int do_drb_ciphering)
|
||||
{
|
||||
int i;
|
||||
int qos_flow_index;
|
||||
drb_t *est_drb = &ue->established_drbs[drb_id - 1];
|
||||
if (est_drb->status == DRB_INACTIVE) {
|
||||
/* DRB Management */
|
||||
est_drb->drb_id = drb_id;
|
||||
est_drb->reestablishPDCP = -1;
|
||||
est_drb->recoverPDCP = -1;
|
||||
for (i = 0; i < NGAP_MAX_DRBS_PER_UE; i++) {
|
||||
if ((est_drb->cnAssociation.sdap_config.pdusession_id == 0
|
||||
|| est_drb->cnAssociation.sdap_config.pdusession_id == pduSession->param.pdusession_id)
|
||||
&& est_drb->defaultDRBid == 0) {
|
||||
est_drb->cnAssociation.sdap_config.defaultDRB = true;
|
||||
est_drb->defaultDRBid = drb_id;
|
||||
}
|
||||
}
|
||||
/* SDAP Configuration */
|
||||
est_drb->cnAssociation.present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config;
|
||||
est_drb->cnAssociation.sdap_config.pdusession_id = pduSession->param.pdusession_id;
|
||||
if (enable_sdap) {
|
||||
est_drb->cnAssociation.sdap_config.sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present;
|
||||
est_drb->cnAssociation.sdap_config.sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_present;
|
||||
} else {
|
||||
est_drb->cnAssociation.sdap_config.sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent;
|
||||
est_drb->cnAssociation.sdap_config.sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent;
|
||||
}
|
||||
for (qos_flow_index = 0; qos_flow_index < pduSession->param.nb_qos; qos_flow_index++) {
|
||||
est_drb->cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] = pduSession->param.qos[qos_flow_index].qfi;
|
||||
if (pduSession->param.qos[qos_flow_index].fiveQI > 5)
|
||||
est_drb->status = DRB_ACTIVE_NONGBR;
|
||||
else
|
||||
est_drb->status = DRB_ACTIVE;
|
||||
}
|
||||
/* PDCP Configuration */
|
||||
est_drb->pdcp_config.discardTimer = NR_PDCP_Config__drb__discardTimer_infinity;
|
||||
est_drb->pdcp_config.pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits;
|
||||
est_drb->pdcp_config.pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
|
||||
est_drb->pdcp_config.t_Reordering = NR_PDCP_Config__t_Reordering_ms100;
|
||||
est_drb->pdcp_config.headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
|
||||
est_drb->pdcp_config.headerCompression.NotUsed = 0;
|
||||
if (do_drb_integrity)
|
||||
est_drb->pdcp_config.integrityProtection = NR_PDCP_Config__drb__integrityProtection_enabled;
|
||||
else
|
||||
est_drb->pdcp_config.integrityProtection = 1;
|
||||
if (do_drb_ciphering)
|
||||
est_drb->pdcp_config.ext1.cipheringDisabled = 1;
|
||||
else
|
||||
est_drb->pdcp_config.ext1.cipheringDisabled = NR_PDCP_Config__ext1__cipheringDisabled_true;
|
||||
}
|
||||
}
|
||||
|
||||
NR_DRB_ToAddMod_t *generateDRB_ASN1(const drb_t *drb_asn1)
|
||||
{
|
||||
NR_DRB_ToAddMod_t *DRB_config = CALLOC(1, sizeof(*DRB_config));
|
||||
DRB_config->drb_Identity = drb_id;
|
||||
NR_SDAP_Config_t *SDAP_config = CALLOC(1, sizeof(NR_SDAP_Config_t));
|
||||
|
||||
asn1cCalloc(DRB_config->cnAssociation, association);
|
||||
association->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config;
|
||||
asn1cCalloc(SDAP_config->mappedQoS_FlowsToAdd, sdapFlows);
|
||||
asn1cCalloc(DRB_config->pdcp_Config, pdcpConfig);
|
||||
asn1cCalloc(pdcpConfig->drb, drb);
|
||||
|
||||
DRB_config->drb_Identity = drb_asn1->drb_id;
|
||||
association->present = drb_asn1->cnAssociation.present;
|
||||
|
||||
/* SDAP Configuration */
|
||||
NR_SDAP_Config_t *SDAP_config = CALLOC(1, sizeof(NR_SDAP_Config_t));
|
||||
asn1cCalloc(SDAP_config->mappedQoS_FlowsToAdd, sdapFlows);
|
||||
SDAP_config->pdu_Session = drb_asn1->cnAssociation.sdap_config.pdusession_id;
|
||||
SDAP_config->sdap_HeaderDL = drb_asn1->cnAssociation.sdap_config.sdap_HeaderDL;
|
||||
SDAP_config->sdap_HeaderUL = drb_asn1->cnAssociation.sdap_config.sdap_HeaderUL;
|
||||
SDAP_config->defaultDRB = drb_asn1->cnAssociation.sdap_config.defaultDRB;
|
||||
|
||||
SDAP_config->pdu_Session = pduSession->param.pdusession_id;
|
||||
|
||||
if (enable_sdap) {
|
||||
SDAP_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present;
|
||||
SDAP_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_present;
|
||||
} else {
|
||||
SDAP_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent;
|
||||
SDAP_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent;
|
||||
}
|
||||
|
||||
SDAP_config->defaultDRB = true;
|
||||
|
||||
for (int qos_flow_index = 0; qos_flow_index < pduSession->param.nb_qos; qos_flow_index++)
|
||||
{
|
||||
asn1cSequenceAdd(sdapFlows->list, NR_QFI_t, qfi);
|
||||
*qfi = pduSession->param.qos[qos_flow_index].qfi;
|
||||
if(pduSession->param.qos[qos_flow_index].fiveQI > 5)
|
||||
pduSession->param.used_drbs[drb_id - 1] = DRB_ACTIVE_NONGBR;
|
||||
else
|
||||
pduSession->param.used_drbs[drb_id - 1] = DRB_ACTIVE;
|
||||
for (int qos_flow_index = 0; qos_flow_index < QOSFLOW_MAX_VALUE; qos_flow_index++) {
|
||||
if (drb_asn1->cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] != 0) {
|
||||
asn1cSequenceAdd(sdapFlows->list, NR_QFI_t, qfi);
|
||||
*qfi = drb_asn1->cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index];
|
||||
}
|
||||
}
|
||||
|
||||
association->choice.sdap_Config = SDAP_config;
|
||||
|
||||
/* PDCP Configuration */
|
||||
asn1cCalloc(DRB_config->pdcp_Config, pdcpConfig);
|
||||
asn1cCalloc(pdcpConfig->drb, drb);
|
||||
asn1cCallocOne(drb->discardTimer, drb_asn1->pdcp_config.discardTimer);
|
||||
asn1cCallocOne(drb->pdcp_SN_SizeUL, drb_asn1->pdcp_config.pdcp_SN_SizeUL);
|
||||
asn1cCallocOne(drb->pdcp_SN_SizeDL, drb_asn1->pdcp_config.pdcp_SN_SizeDL);
|
||||
asn1cCallocOne(pdcpConfig->t_Reordering, drb_asn1->pdcp_config.t_Reordering);
|
||||
|
||||
asn1cCallocOne(drb->discardTimer, NR_PDCP_Config__drb__discardTimer_infinity);
|
||||
drb->headerCompression.present = drb_asn1->pdcp_config.headerCompression.present;
|
||||
drb->headerCompression.choice.notUsed = drb_asn1->pdcp_config.headerCompression.NotUsed;
|
||||
|
||||
asn1cCallocOne(drb->pdcp_SN_SizeUL, NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits);
|
||||
asn1cCallocOne(drb->pdcp_SN_SizeDL, NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits);
|
||||
|
||||
drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
|
||||
drb->headerCompression.choice.notUsed = 0;
|
||||
|
||||
asn1cCallocOne(pdcpConfig->t_Reordering, NR_PDCP_Config__t_Reordering_ms100);
|
||||
|
||||
if (do_drb_integrity) {
|
||||
asn1cCallocOne(drb->integrityProtection, NR_PDCP_Config__drb__integrityProtection_enabled);
|
||||
if (!drb_asn1->pdcp_config.integrityProtection) {
|
||||
asn1cCallocOne(drb->integrityProtection, drb_asn1->pdcp_config.integrityProtection);
|
||||
}
|
||||
if (!do_drb_ciphering) {
|
||||
if (!drb_asn1->pdcp_config.ext1.cipheringDisabled) {
|
||||
asn1cCalloc(pdcpConfig->ext1, ext1);
|
||||
asn1cCallocOne(ext1->cipheringDisabled, NR_PDCP_Config__ext1__cipheringDisabled_true);
|
||||
asn1cCallocOne(ext1->cipheringDisabled, drb_asn1->pdcp_config.ext1.cipheringDisabled);
|
||||
}
|
||||
|
||||
ue->DRB_active[drb_id-1] = DRB_ACTIVE;
|
||||
|
||||
return DRB_config;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,24 @@
|
||||
#define GBR_FLOW (1)
|
||||
#define NONGBR_FLOW (0)
|
||||
|
||||
NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *rrc_ue, uint8_t drb_id, rrc_pdu_session_param_t *pduSession, bool enable_sdap, int do_drb_integrity, int do_drb_ciphering);
|
||||
/// @brief Generates an ASN1 DRB-ToAddMod, from the established_drbs in gNB_RRC_UE_t.
|
||||
/// @param drb_t drb_asn1
|
||||
/// @return Returns the ASN1 DRB-ToAddMod structs.
|
||||
NR_DRB_ToAddMod_t *generateDRB_ASN1(const drb_t *drb_asn1);
|
||||
/// @brief Creates and stores a DRB in the gNB_RRC_UE_t struct, it doesn't create the actual entity,
|
||||
/// to create the actual entity use the generateDRB_ASN1.
|
||||
/// @param ue The gNB_RRC_UE_t struct that holds information for the UEs
|
||||
/// @param drb_id The Data Radio Bearer Identity to be created for the established DRB.
|
||||
/// @param pduSession The PDU Session that the DRB is created for.
|
||||
/// @param enable_sdap If true the SDAP header will be added to the packet, else it will not add or search for SDAP header.
|
||||
/// @param do_drb_integrity
|
||||
/// @param do_drb_ciphering
|
||||
void generateDRB(gNB_RRC_UE_t *ue,
|
||||
uint8_t drb_id,
|
||||
rrc_pdu_session_param_t *pduSession,
|
||||
bool enable_sdap,
|
||||
int do_drb_integrity,
|
||||
int do_drb_ciphering);
|
||||
uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession, bool is_gbr);
|
||||
bool drb_is_active(gNB_RRC_UE_t *ue, uint8_t drb_id);
|
||||
|
||||
|
||||
@@ -149,39 +149,12 @@ int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
rrc_data_req_nr_ue(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const rb_id_t rb_idP,
|
||||
const mui_t muiP,
|
||||
const confirm_t confirmP,
|
||||
const sdu_size_t sdu_sizeP,
|
||||
uint8_t *const buffer_pP,
|
||||
const pdcp_transmission_mode_t modeP
|
||||
)
|
||||
int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index)
|
||||
{
|
||||
MessageDef *message_p;
|
||||
// Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling).
|
||||
uint8_t *message_buffer;
|
||||
message_buffer = itti_malloc (TASK_RRC_UE, TASK_PDCP_UE, sdu_sizeP);
|
||||
LOG_D(RRC,"Sending RRC message for SRB %ld, sdu_size %d\n",rb_idP, sdu_sizeP);
|
||||
memcpy (message_buffer, buffer_pP, sdu_sizeP);
|
||||
message_p = itti_alloc_new_message ( TASK_RRC_UE, 0, RRC_DCCH_DATA_REQ);
|
||||
RRC_DCCH_DATA_REQ (message_p).frame = ctxt_pP->frame;
|
||||
RRC_DCCH_DATA_REQ (message_p).enb_flag = ctxt_pP->enb_flag;
|
||||
RRC_DCCH_DATA_REQ (message_p).rb_id = rb_idP;
|
||||
RRC_DCCH_DATA_REQ (message_p).muip = muiP;
|
||||
RRC_DCCH_DATA_REQ (message_p).confirmp = confirmP;
|
||||
RRC_DCCH_DATA_REQ (message_p).sdu_size = sdu_sizeP;
|
||||
RRC_DCCH_DATA_REQ (message_p).sdu_p = message_buffer;
|
||||
RRC_DCCH_DATA_REQ (message_p).mode = modeP;
|
||||
RRC_DCCH_DATA_REQ (message_p).module_id = ctxt_pP->module_id;
|
||||
RRC_DCCH_DATA_REQ(message_p).rnti = ctxt_pP->rntiMaybeUEid;
|
||||
RRC_DCCH_DATA_REQ (message_p).eNB_index = ctxt_pP->eNB_index;
|
||||
itti_send_msg_to_task (
|
||||
TASK_PDCP_UE,
|
||||
ctxt_pP->instance,
|
||||
message_p);
|
||||
return true; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway.
|
||||
|
||||
if (NR_UE_rrc_inst[mod_id].Info[gNB_index].T304_active == 1) {
|
||||
LOG_W(NR_RRC, "T304 was stoped with value %i\n", NR_UE_rrc_inst[mod_id].Info[gNB_index].T304_cnt);
|
||||
NR_UE_rrc_inst[mod_id].Info[gNB_index].T304_active = 0;
|
||||
NR_UE_rrc_inst[mod_id].Info[gNB_index].T304_cnt = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
+72
-71
@@ -58,7 +58,7 @@
|
||||
#include "nr-uesoftmodem.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "plmn_data.h"
|
||||
#include "pdcp.h"
|
||||
#include "nr_pdcp/nr_pdcp_oai_api.h"
|
||||
#include "UTIL/OSA/osa_defs.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
@@ -90,17 +90,6 @@ static const char nr_nas_attach_req_imsi[] = {
|
||||
0x01, 0x27, 0x11,
|
||||
};
|
||||
|
||||
extern void pdcp_config_set_security(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
pdcp_t *const pdcp_pP,
|
||||
const rb_id_t rb_idP,
|
||||
const uint16_t lc_idP,
|
||||
const uint8_t security_modeP,
|
||||
uint8_t *const kRRCenc,
|
||||
uint8_t *const kRRCint,
|
||||
uint8_t *const kUPenc
|
||||
);
|
||||
|
||||
void
|
||||
nr_rrc_ue_process_ueCapabilityEnquiry(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
@@ -1286,10 +1275,38 @@ nr_rrc_ue_process_masterCellGroup(
|
||||
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig);
|
||||
}
|
||||
|
||||
if( cellGroupConfig->spCellConfig != NULL && cellGroupConfig->spCellConfig->reconfigurationWithSync != NULL){
|
||||
//TODO (perform Reconfiguration with sync according to 5.3.5.5.2)
|
||||
//TODO (resume all suspended radio bearers and resume SCG transmission for all radio bearers, if suspended)
|
||||
// NSA procedures
|
||||
// TS 38.331 - Section 5.3.5.5.2 Reconfiguration with sync
|
||||
if (cellGroupConfig->spCellConfig != NULL && cellGroupConfig->spCellConfig->reconfigurationWithSync != NULL) {
|
||||
|
||||
LOG_A(NR_RRC, "Received the reconfigurationWithSync in %s\n", __FUNCTION__);
|
||||
|
||||
NR_ReconfigurationWithSync_t *reconfigurationWithSync = cellGroupConfig->spCellConfig->reconfigurationWithSync;
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T304_active = 1;
|
||||
switch (reconfigurationWithSync->t304) {
|
||||
case NR_ReconfigurationWithSync__t304_ms100:
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T304_cnt = 100;
|
||||
break;
|
||||
case NR_ReconfigurationWithSync__t304_ms150:
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T304_cnt = 150;
|
||||
break;
|
||||
case NR_ReconfigurationWithSync__t304_ms200:
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T304_cnt = 200;
|
||||
break;
|
||||
case NR_ReconfigurationWithSync__t304_ms500:
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T304_cnt = 500;
|
||||
break;
|
||||
case NR_ReconfigurationWithSync__t304_ms1000:
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T304_cnt = 1000;
|
||||
break;
|
||||
case NR_ReconfigurationWithSync__t304_ms2000:
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T304_cnt = 2000;
|
||||
break;
|
||||
case NR_ReconfigurationWithSync__t304_ms10000:
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T304_cnt = 10000;
|
||||
break;
|
||||
default:
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T304_cnt = 50;
|
||||
}
|
||||
}
|
||||
|
||||
if(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config == NULL){
|
||||
@@ -1372,7 +1389,8 @@ static void rrc_ue_generate_RRCSetupComplete(
|
||||
|
||||
if (get_softmodem_params()->sa) {
|
||||
as_nas_info_t initialNasMsg;
|
||||
generateRegistrationRequest(&initialNasMsg, ctxt_pP->module_id);
|
||||
nr_ue_nas_t *nas = get_ue_nas_info(ctxt_pP->module_id);
|
||||
generateRegistrationRequest(&initialNasMsg, nas);
|
||||
nas_msg = (char*)initialNasMsg.data;
|
||||
nas_msg_length = initialNasMsg.length;
|
||||
} else {
|
||||
@@ -1397,14 +1415,7 @@ static void rrc_ue_generate_RRCSetupComplete(
|
||||
//for (int i=0;i<size;i++) printf("%02x ",buffer[i]);
|
||||
//printf("\n");
|
||||
|
||||
// ctxt_pP_local.rnti = ctxt_pP->rnti;
|
||||
rrc_data_req_nr_ue(ctxt_pP,
|
||||
DCCH,
|
||||
nr_rrc_mui++,
|
||||
SDU_CONFIRM_NO,
|
||||
size,
|
||||
buffer,
|
||||
PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, nr_rrc_mui++, size, buffer, deliver_pdu_srb_rlc, NULL);
|
||||
}
|
||||
|
||||
int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB_INFO *const Srb_info, const uint8_t gNB_index ){
|
||||
@@ -1675,10 +1686,9 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[28], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[29], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[30], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[31]);
|
||||
|
||||
if (securityMode != 0xff) {
|
||||
pdcp_config_set_security(ctxt_pP, NULL, DCCH, DCCH+2,
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm
|
||||
| (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4),
|
||||
kRRCenc, kRRCint, kUPenc);
|
||||
uint8_t security_mode =
|
||||
NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm | (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4);
|
||||
nr_pdcp_config_set_security(ctxt_pP->rntiMaybeUEid, DCCH, security_mode, kRRCenc, kRRCint, kUPenc);
|
||||
} else {
|
||||
LOG_I(NR_RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x", securityMode);
|
||||
}
|
||||
@@ -1710,13 +1720,7 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB
|
||||
}
|
||||
|
||||
LOG_T(NR_RRC, "\n");
|
||||
rrc_data_req_nr_ue (ctxt_pP,
|
||||
DCCH,
|
||||
nr_rrc_mui++,
|
||||
SDU_CONFIRM_NO,
|
||||
(enc_rval.encoded + 7) / 8,
|
||||
buffer,
|
||||
PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, nr_rrc_mui++, (enc_rval.encoded + 7) / 8, buffer, deliver_pdu_srb_rlc, NULL);
|
||||
} else
|
||||
LOG_W(NR_RRC,"securityModeCommand->criticalExtensions.present (%d) != NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand\n",
|
||||
securityModeCommand->criticalExtensions.present);
|
||||
@@ -2202,14 +2206,7 @@ nr_rrc_ue_establish_srb2(
|
||||
nr_rrc_mui,
|
||||
UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id),
|
||||
DCCH);
|
||||
rrc_data_req_nr_ue (
|
||||
ctxt_pP,
|
||||
DCCH,
|
||||
nr_rrc_mui++,
|
||||
SDU_CONFIRM_NO,
|
||||
size,
|
||||
buffer,
|
||||
PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, nr_rrc_mui++, size, buffer, deliver_pdu_srb_rlc, NULL);
|
||||
}
|
||||
|
||||
// from NR SRB1
|
||||
@@ -2228,11 +2225,9 @@ nr_rrc_ue_establish_srb2(
|
||||
NR_DL_DCCH_Message_t *dl_dcch_msg = NULL;
|
||||
MessageDef *msg_p;
|
||||
|
||||
if (Srb_id != 1) {
|
||||
if (Srb_id != 1 && Srb_id != 2) {
|
||||
LOG_E(NR_RRC,"[UE %d] Frame %d: Received message on DL-DCCH (SRB%ld), should not have ...\n",
|
||||
ctxt_pP->module_id, ctxt_pP->frame, Srb_id);
|
||||
} else {
|
||||
LOG_D(NR_RRC, "Received message on SRB%ld\n", Srb_id);
|
||||
}
|
||||
|
||||
LOG_D(NR_RRC, "Decoding DL-DCCH Message\n");
|
||||
@@ -2287,7 +2282,7 @@ nr_rrc_ue_establish_srb2(
|
||||
NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_frequency;
|
||||
}
|
||||
|
||||
itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p);
|
||||
itti_send_msg_to_task(TASK_NAS_NRUE, ctxt_pP->instance, msg_p);
|
||||
break;
|
||||
case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry:
|
||||
LOG_I(NR_RRC, "[UE %d] Received Capability Enquiry (gNB %d)\n", ctxt_pP->module_id,gNB_indexP);
|
||||
@@ -2458,21 +2453,8 @@ nr_rrc_ue_establish_srb2(
|
||||
/* Transfer data to PDCP */
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_UE_rrc_inst[ue_mod_id].Info[0].rnti, 0, 0,0);
|
||||
// check if SRB2 is created, if yes request data_req on DCCH1 (SRB2)
|
||||
if(NR_UE_rrc_inst[ue_mod_id].SRB2_config[0] == NULL) {
|
||||
rrc_data_req_nr_ue (&ctxt,
|
||||
DCCH,
|
||||
nr_rrc_mui++,
|
||||
SDU_CONFIRM_NO,
|
||||
length, buffer,
|
||||
PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
} else {
|
||||
rrc_data_req_nr_ue (&ctxt,
|
||||
DCCH1,
|
||||
nr_rrc_mui++,
|
||||
SDU_CONFIRM_NO,
|
||||
length, buffer,
|
||||
PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
}
|
||||
rb_id_t srb_id = NR_UE_rrc_inst[ue_mod_id].SRB2_config[0] == NULL ? DCCH : DCCH1;
|
||||
nr_pdcp_data_req_srb(ctxt.rntiMaybeUEid, srb_id, nr_rrc_mui++, length, buffer, deliver_pdu_srb_rlc, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2616,14 +2598,7 @@ nr_rrc_ue_process_ueCapabilityEnquiry(
|
||||
}
|
||||
|
||||
LOG_I(NR_RRC, "UECapabilityInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
|
||||
rrc_data_req_nr_ue (
|
||||
ctxt_pP,
|
||||
DCCH,
|
||||
nr_rrc_mui++,
|
||||
SDU_CONFIRM_NO,
|
||||
(enc_rval.encoded + 7) / 8,
|
||||
buffer,
|
||||
PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, nr_rrc_mui++, (enc_rval.encoded + 7) / 8, buffer, deliver_pdu_srb_rlc, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2862,3 +2837,29 @@ void process_lte_nsa_msg(nsa_msg_t *msg, int msg_len)
|
||||
LOG_E(NR_RRC, "No NSA Message Found\n");
|
||||
}
|
||||
}
|
||||
|
||||
void *nr_rrc_timers_update() {
|
||||
|
||||
while (1) {
|
||||
|
||||
for (int mod_id = 0; mod_id < NB_NR_UE_INST; mod_id++) {
|
||||
for (int i = 0; i < NB_SIG_CNX_UE; i++) {
|
||||
NR_UE_RRC_INFO *timers = &NR_UE_rrc_inst[mod_id].Info[i];
|
||||
|
||||
// T304
|
||||
if (timers->T304_active == 1) {
|
||||
if ((timers->T304_cnt % 100) == 0) {
|
||||
LOG_W(NR_RRC, "T304: %u\n", timers->T304_cnt);
|
||||
}
|
||||
if (timers->T304_cnt == 1) {
|
||||
timers->T304_active = 0;
|
||||
}
|
||||
timers->T304_cnt--;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
usleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,21 +145,15 @@ int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
|
||||
const rb_id_t Srb_id,
|
||||
uint8_t *buffer_pP);
|
||||
|
||||
uint8_t
|
||||
rrc_data_req_nr_ue(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const rb_id_t rb_idP,
|
||||
const mui_t muiP,
|
||||
const confirm_t confirmP,
|
||||
const sdu_size_t sdu_sizeP,
|
||||
uint8_t *const buffer_pP,
|
||||
const pdcp_transmission_mode_t modeP
|
||||
);
|
||||
int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index);
|
||||
|
||||
/**\brief RRC UE task.
|
||||
\param void *args_p Pointer on arguments to start the task. */
|
||||
void *rrc_nrue_task(void *args_p);
|
||||
|
||||
/**\brief RRC timers update at UE. */
|
||||
void *nr_rrc_timers_update();
|
||||
|
||||
/**\brief RRC NSA UE task.
|
||||
\param void *args_p Pointer on arguments to start the task. */
|
||||
void *recv_msgs_from_lte_ue(void *args_p);
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "nr_sdap_entity.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include <openair2/LAYER2/PDCP_v10.1.0/pdcp.h>
|
||||
#include <openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h>
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h"
|
||||
|
||||
@@ -37,15 +37,20 @@ static nr_sdap_entity_info sdap_info;
|
||||
|
||||
instance_t *N3GTPUInst = NULL;
|
||||
|
||||
nr_pdcp_ue_manager_t *nr_pdcp_sdap_get_ue_manager(void);
|
||||
|
||||
void nr_pdcp_submit_sdap_ctrl_pdu(ue_id_t ue_id, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu)
|
||||
{
|
||||
nr_pdcp_ue_t *ue;
|
||||
nr_pdcp_ue_manager_t *nr_pdcp_ue_manager;
|
||||
nr_pdcp_ue_manager = nr_pdcp_sdap_get_ue_manager();
|
||||
ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id);
|
||||
ue->drb[sdap_ctrl_pdu_drb-1]->recv_sdu(ue->drb[sdap_ctrl_pdu_drb-1], (char*)&ctrl_pdu, SDAP_HDR_LENGTH, RLC_MUI_UNDEFINED);
|
||||
|
||||
protocol_ctxt_t ctxt = { .rntiMaybeUEid = ue_id };
|
||||
nr_pdcp_data_req_drb(&ctxt,
|
||||
SRB_FLAG_NO,
|
||||
sdap_ctrl_pdu_drb,
|
||||
RLC_MUI_UNDEFINED,
|
||||
SDU_CONFIRM_NO,
|
||||
SDAP_HDR_LENGTH,
|
||||
(unsigned char *)&ctrl_pdu,
|
||||
PDCP_TRANSMISSION_MODE_UNKNOWN,
|
||||
NULL,
|
||||
NULL);
|
||||
LOG_D(SDAP, "Control PDU - Submitting Control PDU to DRB ID: %ld\n", sdap_ctrl_pdu_drb);
|
||||
LOG_D(SDAP, "QFI: %u\n R: %u\n D/C: %u\n", ctrl_pdu.QFI, ctrl_pdu.R, ctrl_pdu.DC);
|
||||
return;
|
||||
@@ -87,16 +92,16 @@ static bool nr_sdap_tx_entity(nr_sdap_entity_t *entity,
|
||||
|
||||
if(!pdcp_ent_has_sdap){
|
||||
LOG_D(SDAP, "TX - DRB ID: %ld does not have SDAP\n", entity->qfi2drb_table[qfi].drb_id);
|
||||
ret = pdcp_data_req(ctxt_p,
|
||||
srb_flag,
|
||||
sdap_drb_id,
|
||||
mui,
|
||||
confirm,
|
||||
sdu_buffer_size,
|
||||
sdu_buffer,
|
||||
pt_mode,
|
||||
sourceL2Id,
|
||||
destinationL2Id);
|
||||
ret = nr_pdcp_data_req_drb(ctxt_p,
|
||||
srb_flag,
|
||||
sdap_drb_id,
|
||||
mui,
|
||||
confirm,
|
||||
sdu_buffer_size,
|
||||
sdu_buffer,
|
||||
pt_mode,
|
||||
sourceL2Id,
|
||||
destinationL2Id);
|
||||
|
||||
if(!ret)
|
||||
LOG_E(SDAP, "%s:%d:%s: PDCP refused PDU\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
@@ -155,16 +160,16 @@ static bool nr_sdap_tx_entity(nr_sdap_entity_t *entity,
|
||||
*
|
||||
* Downlink gNB side
|
||||
*/
|
||||
ret = pdcp_data_req(ctxt_p,
|
||||
srb_flag,
|
||||
sdap_drb_id,
|
||||
mui,
|
||||
confirm,
|
||||
sdu_buffer_size+offset,
|
||||
sdap_buf,
|
||||
pt_mode,
|
||||
sourceL2Id,
|
||||
destinationL2Id);
|
||||
ret = nr_pdcp_data_req_drb(ctxt_p,
|
||||
srb_flag,
|
||||
sdap_drb_id,
|
||||
mui,
|
||||
confirm,
|
||||
sdu_buffer_size + offset,
|
||||
sdap_buf,
|
||||
pt_mode,
|
||||
sourceL2Id,
|
||||
destinationL2Id);
|
||||
|
||||
if(!ret)
|
||||
LOG_E(SDAP, "%s:%d:%s: PDCP refused PDU\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
Reference in New Issue
Block a user