Merge remote-tracking branch 'origin/refactor-lcid-gnb-mac' into integration_2024_w21c
This commit is contained in:
@@ -1457,6 +1457,7 @@ add_library(L2_NR
|
|||||||
${MAC_NR_SRC}
|
${MAC_NR_SRC}
|
||||||
${GNB_APP_SRC}
|
${GNB_APP_SRC}
|
||||||
)
|
)
|
||||||
|
target_link_libraries(L2_NR PRIVATE ds alg)
|
||||||
|
|
||||||
add_library(e1_if
|
add_library(e1_if
|
||||||
${NR_RRC_DIR}/cucp_cuup_direct.c
|
${NR_RRC_DIR}/cucp_cuup_direct.c
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ elm_arr_t find_if_arr_it(seq_arr_t* arr, void* start_it, void* end_it, void* val
|
|||||||
return (elm_arr_t){.found = false, .it = NULL};
|
return (elm_arr_t){.found = false, .it = NULL};
|
||||||
}
|
}
|
||||||
|
|
||||||
elm_arr_t find_if_arr(seq_arr_t* arr, void* value, bool (*f)(const void*, const void*))
|
elm_arr_t find_if(seq_arr_t* arr, void* value, bool (*f)(const void*, const void*))
|
||||||
{
|
{
|
||||||
assert(arr != NULL);
|
assert(arr != NULL);
|
||||||
void* start_it = seq_arr_front(arr);
|
void* start_it = seq_arr_front(arr);
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ typedef struct {
|
|||||||
* @param f Function representing the predicate
|
* @param f Function representing the predicate
|
||||||
* @return Whether the predicate was fullfilled and the iterator to the element if true
|
* @return Whether the predicate was fullfilled and the iterator to the element if true
|
||||||
*/
|
*/
|
||||||
elm_arr_t find_if_arr(seq_arr_t* arr, void* value, bool (*f)(const void* value, const void* it));
|
elm_arr_t find_if(seq_arr_t* arr, void* value, bool (*f)(const void* value, const void* it));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Find elements in an array in the semi-open range [start_it, end_it)
|
* @brief Find elements in an array in the semi-open range [start_it, end_it)
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ int main()
|
|||||||
|
|
||||||
// Find element in the array
|
// Find element in the array
|
||||||
int value = 50;
|
int value = 50;
|
||||||
elm_arr_t elm = find_if_arr(&arr, &value, eq_int);
|
elm_arr_t elm = find_if(&arr, &value, eq_int);
|
||||||
assert(elm.found == true);
|
assert(elm.found == true);
|
||||||
// Check
|
// Check
|
||||||
assert(*(int*)elm.it == 50);
|
assert(*(int*)elm.it == 50);
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ typedef struct {
|
|||||||
|
|
||||||
// Optional
|
// Optional
|
||||||
// only used to retreive MAC/RLC stats
|
// only used to retreive MAC/RLC stats
|
||||||
NR_UE_info_t* ue_info_list;
|
NR_UE_info_t** ue_info_list;
|
||||||
}arr_ue_id_t;
|
}arr_ue_id_t;
|
||||||
|
|
||||||
static meas_data_lst_t fill_kpm_meas_data_item(const meas_info_format_1_lst_t* meas_info_lst, const size_t len, const uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx)
|
static meas_data_lst_t fill_kpm_meas_data_item(const meas_info_format_1_lst_t* meas_info_lst, const size_t len, const uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx)
|
||||||
@@ -114,14 +114,14 @@ static cudu_ue_info_pair_t fill_ue_related_info(arr_ue_id_t* arr_ue_id, const si
|
|||||||
|
|
||||||
if (arr_ue_id->ue_id[ue_idx].type == GNB_UE_ID_E2SM) {
|
if (arr_ue_id->ue_id[ue_idx].type == GNB_UE_ID_E2SM) {
|
||||||
ue_info.rrc_ue_id = *arr_ue_id->ue_id[ue_idx].gnb.ran_ue_id; // rrc_ue_id
|
ue_info.rrc_ue_id = *arr_ue_id->ue_id[ue_idx].gnb.ran_ue_id; // rrc_ue_id
|
||||||
ue_info.ue = &arr_ue_id->ue_info_list[ue_idx];
|
ue_info.ue = arr_ue_id->ue_info_list[ue_idx];
|
||||||
} else if (arr_ue_id->ue_id[ue_idx].type == GNB_CU_UP_UE_ID_E2SM) {
|
} else if (arr_ue_id->ue_id[ue_idx].type == GNB_CU_UP_UE_ID_E2SM) {
|
||||||
/* in OAI implementation, CU-UP ue id = CU-CP ue id
|
/* in OAI implementation, CU-UP ue id = CU-CP ue id
|
||||||
=> CU-UP ue id = rrc_ue_id, but it should not be the case by the spec */
|
=> CU-UP ue id = rrc_ue_id, but it should not be the case by the spec */
|
||||||
ue_info.rrc_ue_id = *arr_ue_id->ue_id[ue_idx].gnb_cu_up.ran_ue_id; // cucp_ue_id = rrc_ue_id
|
ue_info.rrc_ue_id = *arr_ue_id->ue_id[ue_idx].gnb_cu_up.ran_ue_id; // cucp_ue_id = rrc_ue_id
|
||||||
} else if (arr_ue_id->ue_id[ue_idx].type == GNB_DU_UE_ID_E2SM) {
|
} else if (arr_ue_id->ue_id[ue_idx].type == GNB_DU_UE_ID_E2SM) {
|
||||||
ue_info.rrc_ue_id = *arr_ue_id->ue_id[ue_idx].gnb_du.ran_ue_id; // rrc_ue_id
|
ue_info.rrc_ue_id = *arr_ue_id->ue_id[ue_idx].gnb_du.ran_ue_id; // rrc_ue_id
|
||||||
ue_info.ue = &arr_ue_id->ue_info_list[ue_idx];
|
ue_info.ue = arr_ue_id->ue_info_list[ue_idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
return ue_info;
|
return ue_info;
|
||||||
@@ -275,7 +275,7 @@ static arr_ue_id_t filter_ues_by_s_nssai_in_du_or_monolithic(const test_info_lst
|
|||||||
arr_ue_id.ue_id = calloc(MAX_MOBILES_PER_GNB, sizeof(ue_id_e2sm_t));
|
arr_ue_id.ue_id = calloc(MAX_MOBILES_PER_GNB, sizeof(ue_id_e2sm_t));
|
||||||
assert(arr_ue_id.ue_id != NULL);
|
assert(arr_ue_id.ue_id != NULL);
|
||||||
|
|
||||||
arr_ue_id.ue_info_list = calloc(MAX_MOBILES_PER_GNB, sizeof(NR_UE_info_t));
|
arr_ue_id.ue_info_list = calloc(MAX_MOBILES_PER_GNB, sizeof(*arr_ue_id.ue_info_list));
|
||||||
assert(arr_ue_id.ue_info_list != NULL);
|
assert(arr_ue_id.ue_info_list != NULL);
|
||||||
|
|
||||||
const ngran_node_t node_type = get_e2_node_type();
|
const ngran_node_t node_type = get_e2_node_type();
|
||||||
@@ -284,9 +284,9 @@ static arr_ue_id_t filter_ues_by_s_nssai_in_du_or_monolithic(const test_info_lst
|
|||||||
UE_iterator (RC.nrmac[0]->UE_info.list, ue) {
|
UE_iterator (RC.nrmac[0]->UE_info.list, ue) {
|
||||||
NR_UE_sched_ctrl_t *sched_ctrl = &ue->UE_sched_ctrl;
|
NR_UE_sched_ctrl_t *sched_ctrl = &ue->UE_sched_ctrl;
|
||||||
// UE matches if any of its DRBs matches
|
// UE matches if any of its DRBs matches
|
||||||
for (int l = 0; l < sched_ctrl->dl_lc_num; ++l) {
|
for (size_t l = 0; l < seq_arr_size(&sched_ctrl->lc_config); ++l) {
|
||||||
long lcid = sched_ctrl->dl_lc_ids[l];
|
const nr_lc_config_t *c = seq_arr_at(&sched_ctrl->lc_config, l);
|
||||||
if (nssai_matches(sched_ctrl->dl_lc_nssai[lcid], sst, sd)) {
|
if (nssai_matches(c->nssai, sst, sd)) {
|
||||||
if (node_type == ngran_gNB_DU) {
|
if (node_type == ngran_gNB_DU) {
|
||||||
f1_ue_data_t rrc_ue_id = du_get_f1_ue_data(ue->rnti); // gNB CU UE ID = rrc_ue_id
|
f1_ue_data_t rrc_ue_id = du_get_f1_ue_data(ue->rnti); // gNB CU UE ID = rrc_ue_id
|
||||||
arr_ue_id.ue_id[arr_ue_id.sz] = fill_ue_id_data[ngran_gNB_DU](NULL, rrc_ue_id.secondary_ue, 0);
|
arr_ue_id.ue_id[arr_ue_id.sz] = fill_ue_id_data[ngran_gNB_DU](NULL, rrc_ue_id.secondary_ue, 0);
|
||||||
@@ -296,7 +296,7 @@ static arr_ue_id_t filter_ues_by_s_nssai_in_du_or_monolithic(const test_info_lst
|
|||||||
}
|
}
|
||||||
|
|
||||||
// store NR_UE_info_t
|
// store NR_UE_info_t
|
||||||
arr_ue_id.ue_info_list[arr_ue_id.sz] = *ue;
|
arr_ue_id.ue_info_list[arr_ue_id.sz] = ue;
|
||||||
|
|
||||||
arr_ue_id.sz++;
|
arr_ue_id.sz++;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -266,73 +266,6 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort
|
|||||||
return mat;
|
return mat;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_rlcBearerConfig(struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list,
|
|
||||||
struct NR_CellGroupConfig__rlc_BearerToReleaseList *rlc_bearer2release_list,
|
|
||||||
NR_UE_sched_ctrl_t *sched_ctrl)
|
|
||||||
{
|
|
||||||
if (rlc_bearer2release_list) {
|
|
||||||
for (int i = 0; i < rlc_bearer2release_list->list.count; i++) {
|
|
||||||
for (int idx = 0; idx < sched_ctrl->dl_lc_num; idx++) {
|
|
||||||
if (sched_ctrl->dl_lc_ids[idx] == *rlc_bearer2release_list->list.array[i]) {
|
|
||||||
const int remaining_lcs = sched_ctrl->dl_lc_num - idx - 1;
|
|
||||||
memmove(&sched_ctrl->dl_lc_ids[idx], &sched_ctrl->dl_lc_ids[idx + 1], sizeof(sched_ctrl->dl_lc_ids[idx]) * remaining_lcs);
|
|
||||||
sched_ctrl->dl_lc_num--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rlc_bearer2add_list) {
|
|
||||||
// keep lcids
|
|
||||||
for (int i = 0; i < rlc_bearer2add_list->list.count; i++) {
|
|
||||||
const int lcid = rlc_bearer2add_list->list.array[i]->logicalChannelIdentity;
|
|
||||||
bool found = false;
|
|
||||||
for (int idx = 0; idx < sched_ctrl->dl_lc_num; idx++) {
|
|
||||||
if (sched_ctrl->dl_lc_ids[idx] == lcid) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found) {
|
|
||||||
sched_ctrl->dl_lc_num++;
|
|
||||||
sched_ctrl->dl_lc_ids[sched_ctrl->dl_lc_num - 1] = lcid;
|
|
||||||
LOG_D(NR_MAC, "Adding LCID %d (%s %d)\n", lcid, lcid < 4 ? "SRB" : "DRB", lcid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_D(NR_MAC, "In %s: total num of active bearers %d) \n",
|
|
||||||
__FUNCTION__,
|
|
||||||
sched_ctrl->dl_lc_num);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_info_t *UE)
|
|
||||||
{
|
|
||||||
/* we assume that this function is mutex-protected from outside */
|
|
||||||
NR_SCHED_ENSURE_LOCKED(&RC.nrmac[0]->sched_lock);
|
|
||||||
|
|
||||||
AssertFatal(CellGroup, "CellGroup is null\n");
|
|
||||||
NR_MAC_CellGroupConfig_t *mac_CellGroupConfig = CellGroup->mac_CellGroupConfig;
|
|
||||||
|
|
||||||
if (mac_CellGroupConfig) {
|
|
||||||
//process_drx_Config(sched_ctrl,mac_CellGroupConfig->drx_Config);
|
|
||||||
//process_schedulingRequestConfig(sched_ctrl,mac_CellGroupConfig->schedulingRequestConfig);
|
|
||||||
//process_bsrConfig(sched_ctrl,mac_CellGroupConfig->bsr_Config);
|
|
||||||
//process_tag_Config(sched_ctrl,mac_CellGroupConfig->tag_Config);
|
|
||||||
//process_phr_Config(sched_ctrl,mac_CellGroupConfig->phr_Config);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CellGroup->spCellConfig && CellGroup->spCellConfig->reconfigurationWithSync
|
|
||||||
&& CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated
|
|
||||||
&& CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra) {
|
|
||||||
nr_mac_prepare_ra_ue(RC.nrmac[0], UE->rnti, CellGroup);
|
|
||||||
}
|
|
||||||
process_rlcBearerConfig(CellGroup->rlc_BearerToAddModList, CellGroup->rlc_BearerToReleaseList, &UE->UE_sched_ctrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc)
|
static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc)
|
||||||
{
|
{
|
||||||
nfapi_nr_config_request_scf_t *cfg = &nrmac->config[0];
|
nfapi_nr_config_request_scf_t *cfg = &nrmac->config[0];
|
||||||
@@ -752,20 +685,30 @@ void nr_mac_configure_sib1(gNB_MAC_INST *nrmac, const f1ap_plmn_t *plmn, uint64_
|
|||||||
|
|
||||||
bool nr_mac_add_test_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup)
|
bool nr_mac_add_test_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup)
|
||||||
{
|
{
|
||||||
|
/* ideally, instead of this function, "users" of this function should call
|
||||||
|
* the ue context setup request function in mac_rrc_dl_handler.c */
|
||||||
DevAssert(nrmac != NULL);
|
DevAssert(nrmac != NULL);
|
||||||
DevAssert(CellGroup != NULL);
|
DevAssert(CellGroup != NULL);
|
||||||
DevAssert(get_softmodem_params()->phy_test);
|
DevAssert(get_softmodem_params()->phy_test);
|
||||||
NR_SCHED_LOCK(&nrmac->sched_lock);
|
NR_SCHED_LOCK(&nrmac->sched_lock);
|
||||||
|
|
||||||
NR_UE_info_t* UE = add_new_nr_ue(nrmac, rnti, CellGroup);
|
NR_UE_info_t *UE = add_new_nr_ue(nrmac, rnti, CellGroup);
|
||||||
if (UE) {
|
if (!UE) {
|
||||||
LOG_I(NR_MAC,"Force-added new UE %x with initial CellGroup\n", rnti);
|
LOG_E(NR_MAC, "Error adding UE %04x\n", rnti);
|
||||||
process_CellGroup(CellGroup, UE);
|
NR_SCHED_UNLOCK(&nrmac->sched_lock);
|
||||||
} else {
|
return false;
|
||||||
LOG_E(NR_MAC,"Error adding UE %04x\n", rnti);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CellGroup->spCellConfig && CellGroup->spCellConfig->reconfigurationWithSync
|
||||||
|
&& CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated
|
||||||
|
&& CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra) {
|
||||||
|
nr_mac_prepare_ra_ue(RC.nrmac[0], UE->rnti, CellGroup);
|
||||||
|
}
|
||||||
|
process_addmod_bearers_cellGroupConfig(&UE->UE_sched_ctrl, CellGroup->rlc_BearerToAddModList);
|
||||||
|
AssertFatal(CellGroup->rlc_BearerToReleaseList == NULL, "cannot release bearers while adding new UEs\n");
|
||||||
NR_SCHED_UNLOCK(&nrmac->sched_lock);
|
NR_SCHED_UNLOCK(&nrmac->sched_lock);
|
||||||
return UE != NULL;
|
LOG_I(NR_MAC, "Added new UE %x with initial CellGroup\n", rnti);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nr_mac_prepare_ra_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup)
|
bool nr_mac_prepare_ra_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup)
|
||||||
@@ -823,7 +766,6 @@ bool nr_mac_prepare_cellgroup_update(gNB_MAC_INST *nrmac, NR_UE_info_t *UE, NR_C
|
|||||||
/* we assume that this function is mutex-protected from outside */
|
/* we assume that this function is mutex-protected from outside */
|
||||||
NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
|
NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
|
||||||
|
|
||||||
process_CellGroup(CellGroup, UE);
|
|
||||||
UE->reconfigCellGroup = CellGroup;
|
UE->reconfigCellGroup = CellGroup;
|
||||||
UE->expect_reconfiguration = true;
|
UE->expect_reconfiguration = true;
|
||||||
|
|
||||||
|
|||||||
@@ -329,8 +329,9 @@ static void nr_store_dlsch_buffer(module_id_t module_id, frame_t frame, sub_fram
|
|||||||
|
|
||||||
/* loop over all activated logical channels */
|
/* loop over all activated logical channels */
|
||||||
// Note: DL_SCH_LCID_DCCH, DL_SCH_LCID_DCCH1, DL_SCH_LCID_DTCH
|
// Note: DL_SCH_LCID_DCCH, DL_SCH_LCID_DCCH1, DL_SCH_LCID_DTCH
|
||||||
for (int i = 0; i < sched_ctrl->dl_lc_num; ++i) {
|
for (int i = 0; i < seq_arr_size(&sched_ctrl->lc_config); ++i) {
|
||||||
const int lcid = sched_ctrl->dl_lc_ids[i];
|
const nr_lc_config_t *c = seq_arr_at(&sched_ctrl->lc_config, i);
|
||||||
|
const int lcid = c->lcid;
|
||||||
const uint16_t rnti = UE->rnti;
|
const uint16_t rnti = UE->rnti;
|
||||||
LOG_D(NR_MAC, "In %s: UE %x: LCID %d\n", __FUNCTION__, rnti, lcid);
|
LOG_D(NR_MAC, "In %s: UE %x: LCID %d\n", __FUNCTION__, rnti, lcid);
|
||||||
if (lcid == DL_SCH_LCID_DTCH && sched_ctrl->rrc_processing_timer > 0) {
|
if (lcid == DL_SCH_LCID_DTCH && sched_ctrl->rrc_processing_timer > 0) {
|
||||||
@@ -1275,8 +1276,9 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
|
|
||||||
if (sched_ctrl->num_total_bytes > 0) {
|
if (sched_ctrl->num_total_bytes > 0) {
|
||||||
/* loop over all activated logical channels */
|
/* loop over all activated logical channels */
|
||||||
for (int i = 0; i < sched_ctrl->dl_lc_num; ++i) {
|
for (int i = 0; i < seq_arr_size(&sched_ctrl->lc_config); ++i) {
|
||||||
const int lcid = sched_ctrl->dl_lc_ids[i];
|
const nr_lc_config_t *c = seq_arr_at(&sched_ctrl->lc_config, i);
|
||||||
|
const int lcid = c->lcid;
|
||||||
|
|
||||||
if (sched_ctrl->rlc_status[lcid].bytes_in_buffer == 0)
|
if (sched_ctrl->rlc_status[lcid].bytes_in_buffer == 0)
|
||||||
continue; // no data for this LC tbs_size_t len = 0;
|
continue; // no data for this LC tbs_size_t len = 0;
|
||||||
|
|||||||
@@ -104,9 +104,9 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
sched_ctrl->num_total_bytes = 0;
|
sched_ctrl->num_total_bytes = 0;
|
||||||
sched_ctrl->dl_lc_num = 1;
|
DevAssert(seq_arr_size(&sched_ctrl->lc_config) == 1);
|
||||||
const int lcid = DL_SCH_LCID_DTCH;
|
const nr_lc_config_t *c = seq_arr_at(&sched_ctrl->lc_config, 0);
|
||||||
sched_ctrl->dl_lc_ids[sched_ctrl->dl_lc_num - 1] = lcid;
|
const int lcid = c->lcid;
|
||||||
const uint16_t rnti = UE->rnti;
|
const uint16_t rnti = UE->rnti;
|
||||||
/* update sched_ctrl->num_total_bytes so that postprocessor schedules data,
|
/* update sched_ctrl->num_total_bytes so that postprocessor schedules data,
|
||||||
* if available */
|
* if available */
|
||||||
|
|||||||
@@ -59,6 +59,8 @@
|
|||||||
#include "common/ran_context.h"
|
#include "common/ran_context.h"
|
||||||
#include "nfapi/oai_integration/vendor_ext.h"
|
#include "nfapi/oai_integration/vendor_ext.h"
|
||||||
|
|
||||||
|
#include "common/utils/alg/find.h"
|
||||||
|
|
||||||
//#define DEBUG_DCI
|
//#define DEBUG_DCI
|
||||||
|
|
||||||
extern RAN_CONTEXT_t RC;
|
extern RAN_CONTEXT_t RC;
|
||||||
@@ -2097,6 +2099,7 @@ void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_alloca
|
|||||||
ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->reconfigCellGroup);
|
ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->reconfigCellGroup);
|
||||||
ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->capability);
|
ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->capability);
|
||||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||||
|
seq_arr_free(&sched_ctrl->lc_config, NULL);
|
||||||
destroy_nr_list(&sched_ctrl->available_dl_harq);
|
destroy_nr_list(&sched_ctrl->available_dl_harq);
|
||||||
destroy_nr_list(&sched_ctrl->feedback_dl_harq);
|
destroy_nr_list(&sched_ctrl->feedback_dl_harq);
|
||||||
destroy_nr_list(&sched_ctrl->retrans_dl_harq);
|
destroy_nr_list(&sched_ctrl->retrans_dl_harq);
|
||||||
@@ -2490,6 +2493,9 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf
|
|||||||
sched_ctrl->sched_srs.frame = -1;
|
sched_ctrl->sched_srs.frame = -1;
|
||||||
sched_ctrl->sched_srs.slot = -1;
|
sched_ctrl->sched_srs.slot = -1;
|
||||||
|
|
||||||
|
// initialize LCID structure
|
||||||
|
seq_arr_init(&sched_ctrl->lc_config, sizeof(nr_lc_config_t));
|
||||||
|
|
||||||
// initialize UE BWP information
|
// initialize UE BWP information
|
||||||
NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP;
|
NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP;
|
||||||
memset(dl_bwp, 0, sizeof(*dl_bwp));
|
memset(dl_bwp, 0, sizeof(*dl_bwp));
|
||||||
@@ -2964,7 +2970,6 @@ static void nr_mac_apply_cellgroup(gNB_MAC_INST *mac, NR_UE_info_t *UE, frame_t
|
|||||||
|
|
||||||
NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon;
|
NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon;
|
||||||
|
|
||||||
/* Note! we already did process_CellGroup(), so no need to do this again */
|
|
||||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||||
configure_UE_BWP(mac, scc, sched_ctrl, NULL, UE, -1, -1);
|
configure_UE_BWP(mac, scc, sched_ctrl, NULL, UE, -1, -1);
|
||||||
|
|
||||||
@@ -3123,12 +3128,12 @@ void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE)
|
|||||||
NR_SCHED_ENSURE_LOCKED(&mac->sched_lock);
|
NR_SCHED_ENSURE_LOCKED(&mac->sched_lock);
|
||||||
/* create this UE's initial CellGroup */
|
/* create this UE's initial CellGroup */
|
||||||
int CC_id = 0;
|
int CC_id = 0;
|
||||||
|
int srb_id = 1;
|
||||||
const NR_ServingCellConfigCommon_t *scc = mac->common_channels[CC_id].ServingCellConfigCommon;
|
const NR_ServingCellConfigCommon_t *scc = mac->common_channels[CC_id].ServingCellConfigCommon;
|
||||||
const NR_ServingCellConfig_t *sccd = mac->common_channels[CC_id].pre_ServingCellConfig;
|
const NR_ServingCellConfig_t *sccd = mac->common_channels[CC_id].pre_ServingCellConfig;
|
||||||
NR_CellGroupConfig_t *cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, sccd, &mac->radio_config);
|
NR_CellGroupConfig_t *cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, sccd, &mac->radio_config);
|
||||||
|
|
||||||
UE->CellGroup = cellGroupConfig;
|
UE->CellGroup = cellGroupConfig;
|
||||||
process_CellGroup(cellGroupConfig, UE);
|
|
||||||
|
|
||||||
/* activate SRB0 */
|
/* activate SRB0 */
|
||||||
nr_rlc_activate_srb0(UE->rnti, UE, send_initial_ul_rrc_message);
|
nr_rlc_activate_srb0(UE->rnti, UE, send_initial_ul_rrc_message);
|
||||||
@@ -3136,8 +3141,12 @@ void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE)
|
|||||||
/* the cellGroup sent to CU specifies there is SRB1, so create it */
|
/* the cellGroup sent to CU specifies there is SRB1, so create it */
|
||||||
DevAssert(cellGroupConfig->rlc_BearerToAddModList->list.count == 1);
|
DevAssert(cellGroupConfig->rlc_BearerToAddModList->list.count == 1);
|
||||||
const NR_RLC_BearerConfig_t *bearer = cellGroupConfig->rlc_BearerToAddModList->list.array[0];
|
const NR_RLC_BearerConfig_t *bearer = cellGroupConfig->rlc_BearerToAddModList->list.array[0];
|
||||||
DevAssert(bearer->servedRadioBearer->choice.srb_Identity == 1);
|
DevAssert(bearer->servedRadioBearer->choice.srb_Identity == srb_id);
|
||||||
nr_rlc_add_srb(UE->rnti, bearer->servedRadioBearer->choice.srb_Identity, bearer);
|
nr_rlc_add_srb(UE->rnti, bearer->servedRadioBearer->choice.srb_Identity, bearer);
|
||||||
|
|
||||||
|
int priority = bearer->mac_LogicalChannelConfig->ul_SpecificParameters->priority;
|
||||||
|
nr_lc_config_t c = {.lcid = bearer->logicalChannelIdentity, .priority = priority};
|
||||||
|
nr_mac_add_lcid(&UE->UE_sched_ctrl, &c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nr_mac_trigger_release_timer(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing)
|
void nr_mac_trigger_release_timer(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing)
|
||||||
@@ -3213,3 +3222,80 @@ void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_
|
|||||||
};
|
};
|
||||||
nrmac->mac_rrc.ue_context_modification_required(&required);
|
nrmac->mac_rrc.ue_context_modification_required(&required);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* \brief add bearers from CellGroupConfig.
|
||||||
|
*
|
||||||
|
* This is a kind of hack, as this should be processed through a F1 UE Context
|
||||||
|
* setup request, but some modes do not use that (NSA/do-ra/phy_test). */
|
||||||
|
void process_addmod_bearers_cellGroupConfig(NR_UE_sched_ctrl_t *sched_ctrl, const struct NR_CellGroupConfig__rlc_BearerToAddModList *addmod)
|
||||||
|
{
|
||||||
|
if (addmod == NULL)
|
||||||
|
return; /* nothing to do */
|
||||||
|
|
||||||
|
for (int i = 0; i < addmod->list.count; ++i) {
|
||||||
|
const NR_RLC_BearerConfig_t *conf = addmod->list.array[i];
|
||||||
|
int lcid = conf->logicalChannelIdentity;
|
||||||
|
nr_lc_config_t c = {.lcid = lcid};
|
||||||
|
nr_mac_add_lcid(sched_ctrl, &c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long get_lcid_from_drbid(int drb_id)
|
||||||
|
{
|
||||||
|
return drb_id + 3; /* LCID is DRB + 3 */
|
||||||
|
}
|
||||||
|
|
||||||
|
long get_lcid_from_srbid(int srb_id)
|
||||||
|
{
|
||||||
|
return srb_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool eq_lcid_config(const void *vval, const void *vit)
|
||||||
|
{
|
||||||
|
const nr_lc_config_t *val = (const nr_lc_config_t *)vval;
|
||||||
|
const nr_lc_config_t *it = (const nr_lc_config_t *)vit;
|
||||||
|
return it->lcid == val->lcid;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmp_lc_config(const void *va, const void *vb)
|
||||||
|
{
|
||||||
|
const nr_lc_config_t *a = (const nr_lc_config_t *)va;
|
||||||
|
const nr_lc_config_t *b = (const nr_lc_config_t *)vb;
|
||||||
|
|
||||||
|
if (a->priority < b->priority)
|
||||||
|
return -1;
|
||||||
|
if (a->priority == b->priority)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nr_mac_add_lcid(NR_UE_sched_ctrl_t* sched_ctrl, const nr_lc_config_t *c)
|
||||||
|
{
|
||||||
|
elm_arr_t elm = find_if(&sched_ctrl->lc_config, (void *) c, eq_lcid_config);
|
||||||
|
if (elm.found) {
|
||||||
|
LOG_I(NR_MAC, "cannot add LCID %d: already present, updating configuration\n", c->lcid);
|
||||||
|
nr_lc_config_t *exist = (nr_lc_config_t *)elm.it;
|
||||||
|
*exist = *c;
|
||||||
|
} else {
|
||||||
|
LOG_D(NR_MAC, "Add LCID %d\n", c->lcid);
|
||||||
|
seq_arr_push_back(&sched_ctrl->lc_config, (void*) c, sizeof(*c));
|
||||||
|
}
|
||||||
|
void *base = seq_arr_front(&sched_ctrl->lc_config);
|
||||||
|
size_t nmemb = seq_arr_size(&sched_ctrl->lc_config);
|
||||||
|
size_t size = sizeof(*c);
|
||||||
|
qsort(base, nmemb, size, cmp_lc_config);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nr_mac_remove_lcid(NR_UE_sched_ctrl_t *sched_ctrl, long lcid)
|
||||||
|
{
|
||||||
|
nr_lc_config_t c = {.lcid = lcid};
|
||||||
|
elm_arr_t elm = find_if(&sched_ctrl->lc_config, &c, eq_lcid_config);
|
||||||
|
if (!elm.found) {
|
||||||
|
LOG_E(NR_MAC, "can not remove LC: no such LC with ID %ld\n", lcid);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
seq_arr_erase(&sched_ctrl->lc_config, elm.it);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -811,7 +811,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
|
|||||||
reset_dl_harq_list(UE_scheduling_control);
|
reset_dl_harq_list(UE_scheduling_control);
|
||||||
reset_ul_harq_list(UE_scheduling_control);
|
reset_ul_harq_list(UE_scheduling_control);
|
||||||
nr_clear_ra_proc(ra);
|
nr_clear_ra_proc(ra);
|
||||||
process_CellGroup(ra->CellGroup, UE);
|
process_addmod_bearers_cellGroupConfig(&UE->UE_sched_ctrl, ra->CellGroup->rlc_BearerToAddModList);
|
||||||
} else {
|
} else {
|
||||||
LOG_A(NR_MAC, "[RAPROC] RA-Msg3 received (sdu_lenP %d)\n", sdu_lenP);
|
LOG_A(NR_MAC, "[RAPROC] RA-Msg3 received (sdu_lenP %d)\n", sdu_lenP);
|
||||||
LOG_D(NR_MAC, "[RAPROC] Received Msg3:\n");
|
LOG_D(NR_MAC, "[RAPROC] Received Msg3:\n");
|
||||||
|
|||||||
@@ -424,7 +424,8 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t frameP, sub_frame_t slotP);
|
|||||||
|
|
||||||
size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset_rsrp);
|
size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset_rsrp);
|
||||||
|
|
||||||
void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_info_t *UE);
|
long get_lcid_from_drbid(int drb_id);
|
||||||
|
long get_lcid_from_srbid(int srb_id);
|
||||||
|
|
||||||
void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE);
|
void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE);
|
||||||
void send_initial_ul_rrc_message(int rnti, const uint8_t *sdu, sdu_size_t sdu_len, void *data);
|
void send_initial_ul_rrc_message(int rnti, const uint8_t *sdu, sdu_size_t sdu_len, void *data);
|
||||||
@@ -441,4 +442,10 @@ void nr_mac_check_ul_failure(const gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ct
|
|||||||
|
|
||||||
void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_t *UE);
|
void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_t *UE);
|
||||||
|
|
||||||
|
void process_addmod_bearers_cellGroupConfig(NR_UE_sched_ctrl_t *sched_ctrl,
|
||||||
|
const struct NR_CellGroupConfig__rlc_BearerToAddModList *addmod);
|
||||||
|
|
||||||
|
bool nr_mac_add_lcid(NR_UE_sched_ctrl_t *sched_ctrl, const nr_lc_config_t *c);
|
||||||
|
bool nr_mac_remove_lcid(NR_UE_sched_ctrl_t *sched_ctrl, long lcid);
|
||||||
|
|
||||||
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
|
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
|
||||||
|
|||||||
@@ -90,16 +90,6 @@ bool DURecvCb(protocol_ctxt_t *ctxt_pP,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long get_lcid_from_drbid(int drb_id)
|
|
||||||
{
|
|
||||||
return drb_id + 3; /* LCID is DRB + 3 */
|
|
||||||
}
|
|
||||||
|
|
||||||
static long get_lcid_from_srbid(int srb_id)
|
|
||||||
{
|
|
||||||
return srb_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool check_plmn_identity(const f1ap_plmn_t *check_plmn, const f1ap_plmn_t *plmn)
|
static bool check_plmn_identity(const f1ap_plmn_t *check_plmn, const f1ap_plmn_t *plmn)
|
||||||
{
|
{
|
||||||
return plmn->mcc == check_plmn->mcc && plmn->mnc_digit_length == check_plmn->mnc_digit_length && plmn->mnc == check_plmn->mnc;
|
return plmn->mcc == check_plmn->mcc && plmn->mnc_digit_length == check_plmn->mnc_digit_length && plmn->mnc == check_plmn->mnc;
|
||||||
@@ -152,13 +142,13 @@ void gnb_du_configuration_update_acknowledge(const f1ap_gnb_du_configuration_upd
|
|||||||
|
|
||||||
static NR_RLC_BearerConfig_t *get_bearerconfig_from_srb(const f1ap_srb_to_be_setup_t *srb)
|
static NR_RLC_BearerConfig_t *get_bearerconfig_from_srb(const f1ap_srb_to_be_setup_t *srb)
|
||||||
{
|
{
|
||||||
long priority = srb->srb_id; // high priority for SRB
|
long priority = srb->srb_id == 2 ? 3 : 1; // see 38.331 sec 9.2.1
|
||||||
e_NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration bucket =
|
e_NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration bucket =
|
||||||
NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms5;
|
NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms5;
|
||||||
return get_SRB_RLC_BearerConfig(get_lcid_from_srbid(srb->srb_id), priority, bucket);
|
return get_SRB_RLC_BearerConfig(get_lcid_from_srbid(srb->srb_id), priority, bucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_ue_context_srbs_setup(int rnti,
|
static int handle_ue_context_srbs_setup(NR_UE_info_t *UE,
|
||||||
int srbs_len,
|
int srbs_len,
|
||||||
const f1ap_srb_to_be_setup_t *req_srbs,
|
const f1ap_srb_to_be_setup_t *req_srbs,
|
||||||
f1ap_srb_to_be_setup_t **resp_srbs,
|
f1ap_srb_to_be_setup_t **resp_srbs,
|
||||||
@@ -171,7 +161,11 @@ static int handle_ue_context_srbs_setup(int rnti,
|
|||||||
for (int i = 0; i < srbs_len; i++) {
|
for (int i = 0; i < srbs_len; i++) {
|
||||||
const f1ap_srb_to_be_setup_t *srb = &req_srbs[i];
|
const f1ap_srb_to_be_setup_t *srb = &req_srbs[i];
|
||||||
NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_srb(srb);
|
NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_srb(srb);
|
||||||
nr_rlc_add_srb(rnti, srb->srb_id, rlc_BearerConfig);
|
nr_rlc_add_srb(UE->rnti, srb->srb_id, rlc_BearerConfig);
|
||||||
|
|
||||||
|
int priority = rlc_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->priority;
|
||||||
|
nr_lc_config_t c = {.lcid = rlc_BearerConfig->logicalChannelIdentity, .priority = priority};
|
||||||
|
nr_mac_add_lcid(&UE->UE_sched_ctrl, &c);
|
||||||
|
|
||||||
(*resp_srbs)[i] = *srb;
|
(*resp_srbs)[i] = *srb;
|
||||||
|
|
||||||
@@ -188,7 +182,35 @@ static NR_RLC_BearerConfig_t *get_bearerconfig_from_drb(const f1ap_drb_to_be_set
|
|||||||
return get_DRB_RLC_BearerConfig(get_lcid_from_drbid(drb->drb_id), drb->drb_id, rlc_conf, priority);
|
return get_DRB_RLC_BearerConfig(get_lcid_from_drbid(drb->drb_id), drb->drb_id, rlc_conf, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_ue_context_drbs_setup(int rnti,
|
static int get_non_dynamic_priority(int fiveqi)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < sizeofArray(qos_fiveqi); ++i)
|
||||||
|
if (qos_fiveqi[i] == fiveqi)
|
||||||
|
return qos_priority[i];
|
||||||
|
AssertFatal(false, "illegal 5QI value %d\n", fiveqi);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NR_QoS_config_t get_qos_config(const f1ap_qos_characteristics_t *qos_char)
|
||||||
|
{
|
||||||
|
NR_QoS_config_t qos_c = {0};
|
||||||
|
switch (qos_char->qos_type) {
|
||||||
|
case dynamic:
|
||||||
|
qos_c.priority = qos_char->dynamic.qos_priority_level;
|
||||||
|
qos_c.fiveQI = qos_char->dynamic.fiveqi > 0 ? qos_char->dynamic.fiveqi : 0;
|
||||||
|
break;
|
||||||
|
case non_dynamic:
|
||||||
|
qos_c.fiveQI = qos_char->non_dynamic.fiveqi;
|
||||||
|
qos_c.priority = get_non_dynamic_priority(qos_char->non_dynamic.fiveqi);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AssertFatal(false, "illegal QoS type %d\n", qos_char->qos_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return qos_c;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int handle_ue_context_drbs_setup(NR_UE_info_t *UE,
|
||||||
int drbs_len,
|
int drbs_len,
|
||||||
const f1ap_drb_to_be_setup_t *req_drbs,
|
const f1ap_drb_to_be_setup_t *req_drbs,
|
||||||
f1ap_drb_to_be_setup_t **resp_drbs,
|
f1ap_drb_to_be_setup_t **resp_drbs,
|
||||||
@@ -205,7 +227,16 @@ static int handle_ue_context_drbs_setup(int rnti,
|
|||||||
const f1ap_drb_to_be_setup_t *drb = &req_drbs[i];
|
const f1ap_drb_to_be_setup_t *drb = &req_drbs[i];
|
||||||
f1ap_drb_to_be_setup_t *resp_drb = &(*resp_drbs)[i];
|
f1ap_drb_to_be_setup_t *resp_drb = &(*resp_drbs)[i];
|
||||||
NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_drb(drb);
|
NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_drb(drb);
|
||||||
nr_rlc_add_drb(rnti, drb->drb_id, rlc_BearerConfig);
|
nr_rlc_add_drb(UE->rnti, drb->drb_id, rlc_BearerConfig);
|
||||||
|
|
||||||
|
nr_lc_config_t c = {.lcid = rlc_BearerConfig->logicalChannelIdentity, .nssai = drb->nssai};
|
||||||
|
int prio = 100;
|
||||||
|
for (int q = 0; q < drb->drb_info.flows_to_be_setup_length; ++q) {
|
||||||
|
c.qos_config[q] = get_qos_config(&drb->drb_info.flows_mapped_to_drb[q].qos_params.qos_characteristics);
|
||||||
|
prio = min(prio, c.qos_config[q].priority);
|
||||||
|
}
|
||||||
|
c.priority = prio;
|
||||||
|
nr_mac_add_lcid(&UE->UE_sched_ctrl, &c);
|
||||||
|
|
||||||
*resp_drb = *drb;
|
*resp_drb = *drb;
|
||||||
// just put same number of tunnels in DL as in UL
|
// just put same number of tunnels in DL as in UL
|
||||||
@@ -216,7 +247,7 @@ static int handle_ue_context_drbs_setup(int rnti,
|
|||||||
int qfi = -1; // don't put PDU session marker in GTP
|
int qfi = -1; // don't put PDU session marker in GTP
|
||||||
gtpv1u_gnb_create_tunnel_resp_t resp_f1 = {0};
|
gtpv1u_gnb_create_tunnel_resp_t resp_f1 = {0};
|
||||||
int ret = drb_gtpu_create(f1inst,
|
int ret = drb_gtpu_create(f1inst,
|
||||||
rnti,
|
UE->rnti,
|
||||||
drb->drb_id,
|
drb->drb_id,
|
||||||
drb->drb_id,
|
drb->drb_id,
|
||||||
qfi,
|
qfi,
|
||||||
@@ -236,7 +267,7 @@ static int handle_ue_context_drbs_setup(int rnti,
|
|||||||
return drbs_len;
|
return drbs_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_ue_context_drbs_release(int rnti,
|
static int handle_ue_context_drbs_release(NR_UE_info_t *UE,
|
||||||
int drbs_len,
|
int drbs_len,
|
||||||
const f1ap_drb_to_be_released_t *req_drbs,
|
const f1ap_drb_to_be_released_t *req_drbs,
|
||||||
NR_CellGroupConfig_t *cellGroupConfig)
|
NR_CellGroupConfig_t *cellGroupConfig)
|
||||||
@@ -261,9 +292,10 @@ static int handle_ue_context_drbs_release(int rnti,
|
|||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
if (idx < cellGroupConfig->rlc_BearerToAddModList->list.count) {
|
if (idx < cellGroupConfig->rlc_BearerToAddModList->list.count) {
|
||||||
nr_rlc_release_entity(rnti, lcid);
|
nr_mac_remove_lcid(&UE->UE_sched_ctrl, lcid);
|
||||||
|
nr_rlc_release_entity(UE->rnti, lcid);
|
||||||
if (f1inst >= 0)
|
if (f1inst >= 0)
|
||||||
newGtpuDeleteOneTunnel(f1inst, rnti, drb->rb_id);
|
newGtpuDeleteOneTunnel(f1inst, UE->rnti, drb->rb_id);
|
||||||
asn_sequence_del(&cellGroupConfig->rlc_BearerToAddModList->list, idx, 1);
|
asn_sequence_del(&cellGroupConfig->rlc_BearerToAddModList->list, idx, 1);
|
||||||
long *plcid = malloc(sizeof(*plcid));
|
long *plcid = malloc(sizeof(*plcid));
|
||||||
AssertFatal(plcid, "out of memory\n");
|
AssertFatal(plcid, "out of memory\n");
|
||||||
@@ -323,60 +355,6 @@ NR_CellGroupConfig_t *clone_CellGroupConfig(const NR_CellGroupConfig_t *orig)
|
|||||||
return cloned;
|
return cloned;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_nssaiConfig(const int drb_len, const f1ap_drb_to_be_setup_t *req_drbs, NR_UE_sched_ctrl_t *sched_ctrl)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < drb_len; i++) {
|
|
||||||
const f1ap_drb_to_be_setup_t *drb = &req_drbs[i];
|
|
||||||
|
|
||||||
long lcid = get_lcid_from_drbid(drb->drb_id);
|
|
||||||
sched_ctrl->dl_lc_nssai[lcid] = drb->nssai;
|
|
||||||
LOG_I(NR_MAC, "Setting NSSAI sst: %d, sd: %d for DRB: %ld\n", drb->nssai.sst, drb->nssai.sd, drb->drb_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_QoSConfig(const f1ap_ue_context_modif_req_t *req, NR_UE_sched_ctrl_t *sched_ctrl)
|
|
||||||
{
|
|
||||||
AssertFatal(req != NULL, "f1ap_ue_context_modif_req is NULL\n");
|
|
||||||
uint8_t drb_count = req->drbs_to_be_setup_length;
|
|
||||||
uint8_t srb_count = req->srbs_to_be_setup_length;
|
|
||||||
LOG_I(NR_MAC, "Number of DRBs = %d and SRBs = %d\n", drb_count, srb_count);
|
|
||||||
|
|
||||||
/* DRBs*/
|
|
||||||
for (int i = 0; i < drb_count; i++) {
|
|
||||||
f1ap_drb_to_be_setup_t *drb_p = &req->drbs_to_be_setup[i];
|
|
||||||
uint8_t nb_qos_flows = drb_p->drb_info.flows_to_be_setup_length;
|
|
||||||
long drb_id = drb_p->drb_id;
|
|
||||||
LOG_I(NR_MAC, "number of QOS flows mapped to DRB_id %ld: %d\n", drb_id, nb_qos_flows);
|
|
||||||
|
|
||||||
for (int q = 0; q < nb_qos_flows; q++) {
|
|
||||||
f1ap_flows_mapped_to_drb_t *qos_flow = &drb_p->drb_info.flows_mapped_to_drb[q];
|
|
||||||
|
|
||||||
f1ap_qos_characteristics_t *qos_char = &qos_flow->qos_params.qos_characteristics;
|
|
||||||
uint64_t priority = qos_char->non_dynamic.qos_priority_level;
|
|
||||||
int64_t fiveqi = qos_char->non_dynamic.fiveqi;
|
|
||||||
if (qos_char->qos_type == dynamic) {
|
|
||||||
priority = qos_char->dynamic.qos_priority_level;
|
|
||||||
fiveqi = qos_char->dynamic.fiveqi > 0 ? qos_char->dynamic.fiveqi : 0;
|
|
||||||
}
|
|
||||||
if (qos_char->qos_type == non_dynamic) {
|
|
||||||
LOG_D(NR_MAC, "Qos Priority level is considered from the standarsdized 5QI to QoS mapping table\n");
|
|
||||||
for (int id = 0; id < 26; id++) {
|
|
||||||
if (qos_fiveqi[id] == fiveqi)
|
|
||||||
priority = qos_priority[id];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sched_ctrl->qos_config[drb_id - 1][q].fiveQI = fiveqi;
|
|
||||||
sched_ctrl->qos_config[drb_id - 1][q].priority = priority;
|
|
||||||
LOG_D(NR_MAC,
|
|
||||||
"In %s: drb_id %ld: 5QI %lu priority %lu\n",
|
|
||||||
__func__,
|
|
||||||
drb_id,
|
|
||||||
sched_ctrl->qos_config[drb_id - 1][q].fiveQI,
|
|
||||||
sched_ctrl->qos_config[drb_id - 1][q].priority);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ue_context_setup_request(const f1ap_ue_context_setup_t *req)
|
void ue_context_setup_request(const f1ap_ue_context_setup_t *req)
|
||||||
{
|
{
|
||||||
gNB_MAC_INST *mac = RC.nrmac[0];
|
gNB_MAC_INST *mac = RC.nrmac[0];
|
||||||
@@ -403,7 +381,7 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req)
|
|||||||
NR_CellGroupConfig_t *new_CellGroup = clone_CellGroupConfig(UE->CellGroup);
|
NR_CellGroupConfig_t *new_CellGroup = clone_CellGroupConfig(UE->CellGroup);
|
||||||
|
|
||||||
if (req->srbs_to_be_setup_length > 0) {
|
if (req->srbs_to_be_setup_length > 0) {
|
||||||
resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(req->gNB_DU_ue_id,
|
resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(UE,
|
||||||
req->srbs_to_be_setup_length,
|
req->srbs_to_be_setup_length,
|
||||||
req->srbs_to_be_setup,
|
req->srbs_to_be_setup,
|
||||||
&resp.srbs_to_be_setup,
|
&resp.srbs_to_be_setup,
|
||||||
@@ -411,7 +389,7 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (req->drbs_to_be_setup_length > 0) {
|
if (req->drbs_to_be_setup_length > 0) {
|
||||||
resp.drbs_to_be_setup_length = handle_ue_context_drbs_setup(req->gNB_DU_ue_id,
|
resp.drbs_to_be_setup_length = handle_ue_context_drbs_setup(UE,
|
||||||
req->drbs_to_be_setup_length,
|
req->drbs_to_be_setup_length,
|
||||||
req->drbs_to_be_setup,
|
req->drbs_to_be_setup,
|
||||||
&resp.drbs_to_be_setup,
|
&resp.drbs_to_be_setup,
|
||||||
@@ -439,15 +417,8 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req)
|
|||||||
AssertFatal(enc_rval.encoded > 0, "Could not encode CellGroup, failed element %s\n", enc_rval.failed_type->name);
|
AssertFatal(enc_rval.encoded > 0, "Could not encode CellGroup, failed element %s\n", enc_rval.failed_type->name);
|
||||||
resp.du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded + 7) >> 3;
|
resp.du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded + 7) >> 3;
|
||||||
|
|
||||||
/* TODO: need to apply after UE context reconfiguration confirmed? */
|
|
||||||
nr_mac_prepare_cellgroup_update(mac, UE, new_CellGroup);
|
nr_mac_prepare_cellgroup_update(mac, UE, new_CellGroup);
|
||||||
|
|
||||||
/* Fill the QoS config in MAC for each active DRB */
|
|
||||||
set_QoSConfig(req, &UE->UE_sched_ctrl);
|
|
||||||
|
|
||||||
/* Set NSSAI config in MAC for each active DRB */
|
|
||||||
set_nssaiConfig(req->drbs_to_be_setup_length, req->drbs_to_be_setup, &UE->UE_sched_ctrl);
|
|
||||||
|
|
||||||
NR_SCHED_UNLOCK(&mac->sched_lock);
|
NR_SCHED_UNLOCK(&mac->sched_lock);
|
||||||
|
|
||||||
/* some sanity checks, since we use the same type for request and response */
|
/* some sanity checks, since we use the same type for request and response */
|
||||||
@@ -492,7 +463,7 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req)
|
|||||||
NR_CellGroupConfig_t *new_CellGroup = clone_CellGroupConfig(UE->CellGroup);
|
NR_CellGroupConfig_t *new_CellGroup = clone_CellGroupConfig(UE->CellGroup);
|
||||||
|
|
||||||
if (req->srbs_to_be_setup_length > 0) {
|
if (req->srbs_to_be_setup_length > 0) {
|
||||||
resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(req->gNB_DU_ue_id,
|
resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(UE,
|
||||||
req->srbs_to_be_setup_length,
|
req->srbs_to_be_setup_length,
|
||||||
req->srbs_to_be_setup,
|
req->srbs_to_be_setup,
|
||||||
&resp.srbs_to_be_setup,
|
&resp.srbs_to_be_setup,
|
||||||
@@ -500,7 +471,7 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (req->drbs_to_be_setup_length > 0) {
|
if (req->drbs_to_be_setup_length > 0) {
|
||||||
resp.drbs_to_be_setup_length = handle_ue_context_drbs_setup(req->gNB_DU_ue_id,
|
resp.drbs_to_be_setup_length = handle_ue_context_drbs_setup(UE,
|
||||||
req->drbs_to_be_setup_length,
|
req->drbs_to_be_setup_length,
|
||||||
req->drbs_to_be_setup,
|
req->drbs_to_be_setup,
|
||||||
&resp.drbs_to_be_setup,
|
&resp.drbs_to_be_setup,
|
||||||
@@ -509,7 +480,7 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req)
|
|||||||
|
|
||||||
if (req->drbs_to_be_released_length > 0) {
|
if (req->drbs_to_be_released_length > 0) {
|
||||||
resp.drbs_to_be_released_length =
|
resp.drbs_to_be_released_length =
|
||||||
handle_ue_context_drbs_release(req->gNB_DU_ue_id, req->drbs_to_be_released_length, req->drbs_to_be_released, new_CellGroup);
|
handle_ue_context_drbs_release(UE, req->drbs_to_be_released_length, req->drbs_to_be_released, new_CellGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->rrc_container != NULL) {
|
if (req->rrc_container != NULL) {
|
||||||
@@ -546,12 +517,6 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req)
|
|||||||
resp.du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded + 7) >> 3;
|
resp.du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded + 7) >> 3;
|
||||||
|
|
||||||
nr_mac_prepare_cellgroup_update(mac, UE, new_CellGroup);
|
nr_mac_prepare_cellgroup_update(mac, UE, new_CellGroup);
|
||||||
|
|
||||||
/* Fill the QoS config in MAC for each active DRB */
|
|
||||||
set_QoSConfig(req, &UE->UE_sched_ctrl);
|
|
||||||
|
|
||||||
/* Set NSSAI config in MAC for each active DRB */
|
|
||||||
set_nssaiConfig(req->drbs_to_be_setup_length, req->drbs_to_be_setup, &UE->UE_sched_ctrl);
|
|
||||||
} else {
|
} else {
|
||||||
ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, new_CellGroup); // we actually don't need it
|
ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, new_CellGroup); // we actually don't need it
|
||||||
}
|
}
|
||||||
@@ -695,8 +660,10 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc)
|
|||||||
UE->expect_reconfiguration = false;
|
UE->expect_reconfiguration = false;
|
||||||
/* Re-establish RLC for all remaining bearers */
|
/* Re-establish RLC for all remaining bearers */
|
||||||
if (UE->reestablish_rlc) {
|
if (UE->reestablish_rlc) {
|
||||||
for (int i = 1; i < UE->UE_sched_ctrl.dl_lc_num; ++i)
|
for (int i = 1; i < seq_arr_size(&UE->UE_sched_ctrl.lc_config); ++i) {
|
||||||
nr_rlc_reestablish_entity(dl_rrc->gNB_DU_ue_id, UE->UE_sched_ctrl.dl_lc_ids[i]);
|
nr_lc_config_t *lc_config = seq_arr_at(&UE->UE_sched_ctrl.lc_config, i);
|
||||||
|
nr_rlc_reestablish_entity(dl_rrc->gNB_DU_ue_id, lc_config->lcid);
|
||||||
|
}
|
||||||
UE->reestablish_rlc = false;
|
UE->reestablish_rlc = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -721,6 +688,10 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc)
|
|||||||
UE->uid = oldUE->uid;
|
UE->uid = oldUE->uid;
|
||||||
oldUE->uid = temp_uid;
|
oldUE->uid = temp_uid;
|
||||||
configure_UE_BWP(mac, scc, sched_ctrl, NULL, UE, -1, -1);
|
configure_UE_BWP(mac, scc, sched_ctrl, NULL, UE, -1, -1);
|
||||||
|
for (int i = 1; i < seq_arr_size(&oldUE->UE_sched_ctrl.lc_config); ++i) {
|
||||||
|
const nr_lc_config_t *c = seq_arr_at(&oldUE->UE_sched_ctrl.lc_config, i);
|
||||||
|
nr_mac_add_lcid(&UE->UE_sched_ctrl, c);
|
||||||
|
}
|
||||||
|
|
||||||
nr_mac_prepare_cellgroup_update(mac, UE, oldUE->CellGroup);
|
nr_mac_prepare_cellgroup_update(mac, UE, oldUE->CellGroup);
|
||||||
oldUE->CellGroup = NULL;
|
oldUE->CellGroup = NULL;
|
||||||
|
|||||||
@@ -179,15 +179,15 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset
|
|||||||
"UE %04x: MAC: TX %14"PRIu64" RX %14"PRIu64" bytes\n",
|
"UE %04x: MAC: TX %14"PRIu64" RX %14"PRIu64" bytes\n",
|
||||||
UE->rnti, stats->dl.total_bytes, stats->ul.total_bytes);
|
UE->rnti, stats->dl.total_bytes, stats->ul.total_bytes);
|
||||||
|
|
||||||
for (int i = 0; i < sched_ctrl->dl_lc_num; i++) {
|
for (int i = 0; i < seq_arr_size(&sched_ctrl->lc_config); i++) {
|
||||||
int lc_id = sched_ctrl->dl_lc_ids[i];
|
const nr_lc_config_t *c = seq_arr_at(&sched_ctrl->lc_config, i);
|
||||||
output += snprintf(output,
|
output += snprintf(output,
|
||||||
end - output,
|
end - output,
|
||||||
"UE %04x: LCID %d: TX %14"PRIu64" RX %14"PRIu64" bytes\n",
|
"UE %04x: LCID %d: TX %14"PRIu64" RX %14"PRIu64" bytes\n",
|
||||||
UE->rnti,
|
UE->rnti,
|
||||||
lc_id,
|
c->lcid,
|
||||||
stats->dl.lc_bytes[lc_id],
|
stats->dl.lc_bytes[c->lcid],
|
||||||
stats->ul.lc_bytes[lc_id]);
|
stats->ul.lc_bytes[c->lcid]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NR_SCHED_UNLOCK(&gNB->UE_info.mutex);
|
NR_SCHED_UNLOCK(&gNB->UE_info.mutex);
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include "common/utils/ds/seq_arr.h"
|
||||||
|
|
||||||
#define NR_SCHED_LOCK(lock) \
|
#define NR_SCHED_LOCK(lock) \
|
||||||
do { \
|
do { \
|
||||||
@@ -518,10 +519,20 @@ typedef struct NR_UE_ul_harq {
|
|||||||
} NR_UE_ul_harq_t;
|
} NR_UE_ul_harq_t;
|
||||||
|
|
||||||
typedef struct NR_QoS_config_s {
|
typedef struct NR_QoS_config_s {
|
||||||
uint64_t fiveQI;
|
int fiveQI;
|
||||||
uint64_t priority;
|
int priority;
|
||||||
} NR_QoS_config_t;
|
} NR_QoS_config_t;
|
||||||
|
|
||||||
|
typedef struct nr_lc_config {
|
||||||
|
uint8_t lcid;
|
||||||
|
/// priority as specified in 38.321
|
||||||
|
int priority;
|
||||||
|
/// associated NSSAI for DRB
|
||||||
|
nssai_t nssai;
|
||||||
|
/// QoS config for DRB
|
||||||
|
NR_QoS_config_t qos_config[NR_MAX_NUM_QFI];
|
||||||
|
} nr_lc_config_t;
|
||||||
|
|
||||||
/*! \brief scheduling control information set through an API */
|
/*! \brief scheduling control information set through an API */
|
||||||
#define MAX_CSI_REPORTS 48
|
#define MAX_CSI_REPORTS 48
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -613,20 +624,15 @@ typedef struct {
|
|||||||
/// UL HARQ processes that await retransmission
|
/// UL HARQ processes that await retransmission
|
||||||
NR_list_t retrans_ul_harq;
|
NR_list_t retrans_ul_harq;
|
||||||
NR_UE_mac_ce_ctrl_t UE_mac_ce_ctrl; // MAC CE related information
|
NR_UE_mac_ce_ctrl_t UE_mac_ce_ctrl; // MAC CE related information
|
||||||
/// number of active DL LCs
|
|
||||||
uint8_t dl_lc_num;
|
|
||||||
/// order in which DLSCH scheduler should allocate LCs
|
|
||||||
uint8_t dl_lc_ids[NR_MAX_NUM_LCID];
|
|
||||||
|
|
||||||
/// Timer for RRC processing procedures
|
/// Timer for RRC processing procedures
|
||||||
uint32_t rrc_processing_timer;
|
uint32_t rrc_processing_timer;
|
||||||
|
|
||||||
/// sri, ul_ri and tpmi based on SRS
|
/// sri, ul_ri and tpmi based on SRS
|
||||||
nr_srs_feedback_t srs_feedback;
|
nr_srs_feedback_t srs_feedback;
|
||||||
nssai_t dl_lc_nssai[NR_MAX_NUM_LCID];
|
|
||||||
|
|
||||||
// Information about the QoS configuration for each LCID/DRB
|
/// per-LC configuration
|
||||||
NR_QoS_config_t qos_config[NR_MAX_NUM_LCID - 4][NR_MAX_NUM_QFI]; // 0 -CCCH and 1- 3 SRBs(0,1,2)
|
seq_arr_t lc_config;
|
||||||
} NR_UE_sched_ctrl_t;
|
} NR_UE_sched_ctrl_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user