Commit aaae82d7 authored by Robert Schmidt's avatar Robert Schmidt

Implement F1 Setup Request/Response to be used internally

- send F1 Setup using callback
- store f1 setup req locally for reference
- check F1 Setup Req against RRC data structures:
  * if matches: send F1 Setup Response using callback
  * if not matching: send F1 Setup Failure using callback
- don't send CU config update by default, we don't need this
- if the Setup Response does not contain a cell, don't activate. It is
  possible the CU sends a gNB-CU configuration update, which will
  initialize the structures
parent 925c2d0f
......@@ -160,12 +160,9 @@ void *gNB_app_task(void *args_p)
LOG_E(F1AP, "Create task for F1AP DU failed\n");
AssertFatal(1==0,"exiting");
}
// configure F1AP here for F1C
LOG_I(GNB_APP,"ngran_gNB_DU: Allocating ITTI message for F1AP_SETUP_REQ\n");
msg_p = itti_alloc_new_message (TASK_GNB_APP, 0, F1AP_DU_REGISTER_REQ);
RCconfig_NR_DU_F1(msg_p, 0);
itti_send_msg_to_task (TASK_DU_F1, GNB_MODULE_ID_TO_INSTANCE(0), msg_p);
}
if (NODE_IS_DU(node_type) || NODE_IS_MONOLITHIC(node_type)) {
RC_config_trigger_F1Setup();
}
}
do {
......@@ -230,15 +227,9 @@ void *gNB_app_task(void *args_p)
break;
case F1AP_SETUP_RESP:
AssertFatal(NODE_IS_DU(node_type), "Should not have received F1AP_SETUP_RESP in CU/gNB\n");
LOG_I(GNB_APP, "Received %s: associated ngran_gNB_CU %s with %d cells to activate\n", ITTI_MSG_NAME (msg_p),
F1AP_SETUP_RESP(msg_p).gNB_CU_name,F1AP_SETUP_RESP(msg_p).num_cells_to_activate);
cell_to_activate = F1AP_SETUP_RESP(msg_p).num_cells_to_activate;
gNB_app_handle_f1ap_setup_resp(&F1AP_SETUP_RESP(msg_p));
AssertFatal(false, "Should not received this, logic bug\n");
break;
case F1AP_GNB_CU_CONFIGURATION_UPDATE:
AssertFatal(NODE_IS_DU(node_type), "Should not have received F1AP_GNB_CU_CONFIGURATION_UPDATE in CU/gNB\n");
......
This diff is collapsed.
......@@ -103,8 +103,7 @@ extern void NRRCConfig(void);
void RCconfig_NRRRC(gNB_RRC_INST *rrc);
int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i);
int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i);
int RCconfig_NR_DU_F1(MessageDef *msg_p, uint32_t i);
int gNB_app_handle_f1ap_setup_resp(f1ap_setup_resp_t *resp);
int RC_config_trigger_F1Setup(void);
int gNB_app_handle_f1ap_gnb_cu_configuration_update(f1ap_gnb_cu_configuration_update_t *gnb_cu_cfg_update);
MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process);
ngran_node_t get_node_type(void);
......
......@@ -30,9 +30,37 @@
#include "uper_decoder.h"
#include "uper_encoder.h"
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;
}
void f1_setup_response(const f1ap_setup_resp_t *resp)
{
AssertFatal(false, "not implemented\n");
LOG_I(MAC, "received F1 Setup Response from CU %s\n", resp->gNB_CU_name);
if (resp->num_cells_to_activate == 0) {
LOG_W(NR_MAC, "no cell to activate: cell remains blocked\n");
return;
}
gNB_MAC_INST *mac = RC.nrmac[0];
NR_SCHED_LOCK(&mac->sched_lock);
const f1ap_setup_req_t *setup_req = mac->f1_config.setup_req;
const f1ap_served_cell_info_t *du_cell = &setup_req->cell[0].info;
AssertFatal(resp->num_cells_to_activate == 1, "can only handle one cell, but %d activated\n", resp->num_cells_to_activate);
const served_cells_to_activate_t *cu_cell = &resp->cells_to_activate[0];
AssertFatal(du_cell->nr_cellid == cu_cell->nr_cellid, "CellID mismatch: DU %ld vs CU %ld\n", du_cell->nr_cellid, cu_cell->nr_cellid);
AssertFatal(check_plmn_identity(&du_cell->plmn, &cu_cell->plmn), "PLMN mismatch\n");
AssertFatal(du_cell->nr_pci == cu_cell->nrpci, "PCI mismatch: DU %d vs CU %d\n", du_cell->nr_pci, cu_cell->nrpci);
AssertFatal(cu_cell->num_SI == 0, "handling of CU-provided SIBs: not implemented\n");
NR_SCHED_UNLOCK(&mac->sched_lock);
/* TODO: handling of pre-operational state? */
}
void f1_setup_failure(const f1ap_setup_failure_t *failure)
......
......@@ -26,7 +26,42 @@
static void f1_setup_request_direct(const f1ap_setup_req_t *req)
{
AssertFatal(false, "not implemented\n");
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_SETUP_REQ);
f1ap_setup_req_t *f1ap_msg = &F1AP_SETUP_REQ(msg);
f1ap_msg->gNB_DU_id = req->gNB_DU_id;
f1ap_msg->gNB_DU_name = strdup(req->gNB_DU_name);
f1ap_msg->num_cells_available = req->num_cells_available;
for (int n = 0; n < req->num_cells_available; ++n) {
f1ap_msg->cell[n].info = req->cell[n].info; // copy most fields
if (req->cell[n].info.tac) {
f1ap_msg->cell[n].info.tac = malloc(sizeof(*f1ap_msg->cell[n].info.tac));
AssertFatal(f1ap_msg->cell[n].info.tac != NULL, "out of memory\n");
*f1ap_msg->cell[n].info.tac = *req->cell[n].info.tac;
}
if (req->cell[n].info.measurement_timing_information)
f1ap_msg->cell[n].info.measurement_timing_information = strdup(req->cell[n].info.measurement_timing_information);
if (req->cell[n].sys_info) {
f1ap_gnb_du_system_info_t *orig_sys_info = req->cell[n].sys_info;
f1ap_gnb_du_system_info_t *copy_sys_info = calloc(1, sizeof(*copy_sys_info));
AssertFatal(copy_sys_info != NULL, "out of memory\n");
f1ap_msg->cell[n].sys_info = copy_sys_info;
copy_sys_info->mib = calloc(orig_sys_info->mib_length, sizeof(uint8_t));
AssertFatal(copy_sys_info->mib != NULL, "out of memory\n");
memcpy(copy_sys_info->mib, orig_sys_info->mib, orig_sys_info->mib_length);
copy_sys_info->mib_length = orig_sys_info->mib_length;
if (orig_sys_info->sib1_length > 0) {
copy_sys_info->sib1 = calloc(orig_sys_info->sib1_length, sizeof(uint8_t));
AssertFatal(copy_sys_info->sib1 != NULL, "out of memory\n");
memcpy(copy_sys_info->sib1, orig_sys_info->sib1, orig_sys_info->sib1_length);
copy_sys_info->sib1_length = orig_sys_info->sib1_length;
}
}
}
itti_send_msg_to_task(TASK_RRC_GNB, 0, msg);
}
static void ue_context_setup_response_direct(const f1ap_ue_context_setup_t *req, const f1ap_ue_context_setup_t *resp)
......
......@@ -709,6 +709,11 @@ typedef bool (*nr_pp_impl_ul)(module_id_t mod_id,
frame_t frame,
sub_frame_t slot);
typedef struct f1_config_t {
f1ap_setup_req_t *setup_req;
f1ap_setup_resp_t *setup_resp;
} f1_config_t;
/*! \brief top level eNB MAC structure */
typedef struct gNB_MAC_INST_s {
/// Ethernet parameters for northbound midhaul interface
......@@ -816,7 +821,9 @@ typedef struct gNB_MAC_INST_s {
uint8_t min_grant_prb;
uint8_t min_grant_mcs;
bool identity_pm;
nr_mac_rrc_ul_if_t mac_rrc;
f1_config_t f1_config;
int16_t frame;
int16_t slot;
......
......@@ -377,6 +377,10 @@ typedef struct cucp_cuup_if_s {
cucp_cuup_bearer_context_setup_func_t bearer_context_mod;
} cucp_cuup_if_t;
typedef struct nr_rrc_du_container_t {
f1ap_setup_req_t *setup_req;
} nr_rrc_du_container_t;
//---NR---(completely change)---------------------
typedef struct gNB_RRC_INST_s {
......@@ -416,8 +420,6 @@ typedef struct gNB_RRC_INST_s {
int srs_enable[MAX_NUM_CCs];
uint16_t sctp_in_streams;
uint16_t sctp_out_streams;
int cell_info_configured;
pthread_mutex_t cell_info_mutex;
char *uecap_file;
......@@ -427,6 +429,8 @@ typedef struct gNB_RRC_INST_s {
nr_mac_rrc_dl_if_t mac_rrc;
cucp_cuup_if_t cucp_cuup;
nr_rrc_du_container_t *du;
} gNB_RRC_INST;
#include "nr_rrc_proto.h" //should be put here otherwise compilation error
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment