Merge remote-tracking branch 'origin/liteon_du_integration' into integration_2024_w03
This commit is contained in:
@@ -132,3 +132,21 @@ void set_priority(int priority)
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a version string x.y.z into numbers.
|
||||
*
|
||||
* The function takes a version string of format "x.y.z" where x is the major
|
||||
* version number, y minor, z patch. It tries to match version, and outputs the
|
||||
* numbers in the correspondingly named variables.
|
||||
*
|
||||
* @return The number of version parts matched (should be three on x.y.z).
|
||||
*/
|
||||
int read_version(const char *version, uint8_t *major, uint8_t *minor, uint8_t *patch)
|
||||
{
|
||||
int ret = sscanf(version, "%hhu.%hhu.%hhu", major, minor, patch);
|
||||
// EOF means "end of input reached or matching failure"
|
||||
if (ret == EOF)
|
||||
return 3;
|
||||
return ret; // ret has number of items matched
|
||||
}
|
||||
|
||||
@@ -107,6 +107,10 @@ void set_priority(int priority);
|
||||
|
||||
char *itoa(int i);
|
||||
|
||||
#define STRINGIFY(S) #S
|
||||
#define TO_STRING(S) STRINGIFY(S)
|
||||
int read_version(const char *version, uint8_t *major, uint8_t *minor, uint8_t *patch);
|
||||
|
||||
#define findInList(keY, result, list, element_type) {\
|
||||
int i;\
|
||||
for (i=0; i<sizeof(list)/sizeof(element_type) ; i++)\
|
||||
|
||||
@@ -146,11 +146,16 @@ typedef struct f1ap_gnb_du_system_info_t {
|
||||
} f1ap_gnb_du_system_info_t;
|
||||
|
||||
typedef struct f1ap_setup_req_s {
|
||||
/// ulong transaction id
|
||||
uint64_t transaction_id;
|
||||
|
||||
// F1_Setup_Req payload
|
||||
uint64_t gNB_DU_id;
|
||||
char *gNB_DU_name;
|
||||
|
||||
|
||||
/// rrc version
|
||||
uint8_t rrc_ver[3];
|
||||
|
||||
/// number of DU cells available
|
||||
uint16_t num_cells_available; //0< num_cells_available <= 512;
|
||||
struct {
|
||||
@@ -179,11 +184,17 @@ typedef struct served_cells_to_activate_s {
|
||||
} served_cells_to_activate_t;
|
||||
|
||||
typedef struct f1ap_setup_resp_s {
|
||||
/// ulong transaction id
|
||||
uint64_t transaction_id;
|
||||
/// string holding gNB_CU_name
|
||||
char *gNB_CU_name;
|
||||
/// number of DU cells to activate
|
||||
uint16_t num_cells_to_activate; //0< num_cells_to_activate <= 512;
|
||||
served_cells_to_activate_t cells_to_activate[F1AP_MAX_NB_CELLS];
|
||||
|
||||
/// rrc version
|
||||
uint8_t rrc_ver[3];
|
||||
|
||||
} f1ap_setup_resp_t;
|
||||
|
||||
typedef struct f1ap_gnb_cu_configuration_update_s {
|
||||
|
||||
@@ -89,6 +89,12 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint3
|
||||
MessageDef *message_p = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_SETUP_REQ);
|
||||
message_p->ittiMsgHeader.originInstance = assoc_id;
|
||||
f1ap_setup_req_t *req = &F1AP_SETUP_REQ(message_p);
|
||||
|
||||
/* Transaction ID*/
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupRequestIEs_t, ie, container, F1AP_ProtocolIE_ID_id_TransactionID, true);
|
||||
req->transaction_id = ie->value.choice.TransactionID;
|
||||
LOG_D(F1AP, "req->transaction_id %lu \n", req->transaction_id);
|
||||
|
||||
/* gNB_DU_id */
|
||||
// this function exits if the ie is mandatory
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupRequestIEs_t, ie, container,
|
||||
@@ -180,22 +186,40 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint3
|
||||
} else {
|
||||
AssertFatal(false, "unknown NR Mode info %d\n", servedCellInformation->nR_Mode_Info.present);
|
||||
}
|
||||
|
||||
|
||||
struct F1AP_GNB_DU_System_Information * DUsi=served_cells_item->gNB_DU_System_Information;
|
||||
// System Information
|
||||
req->cell[i].sys_info = calloc(1, sizeof(*req->cell[i].sys_info));
|
||||
AssertFatal(req->cell[i].sys_info != NULL, "out of memory\n");
|
||||
f1ap_gnb_du_system_info_t *sys_info = req->cell[i].sys_info;
|
||||
/* mib */
|
||||
sys_info->mib = calloc(DUsi->mIB_message.size, sizeof(char));
|
||||
memcpy(sys_info->mib, DUsi->mIB_message.buf, DUsi->mIB_message.size);
|
||||
sys_info->mib_length = DUsi->mIB_message.size;
|
||||
/* sib1 */
|
||||
sys_info->sib1 = calloc(DUsi->sIB1_message.size, sizeof(char));
|
||||
memcpy(sys_info->sib1, DUsi->sIB1_message.buf, DUsi->sIB1_message.size);
|
||||
sys_info->sib1_length = DUsi->sIB1_message.size;
|
||||
if (DUsi != NULL) {
|
||||
// System Information
|
||||
req->cell[i].sys_info = calloc(1, sizeof(*req->cell[i].sys_info));
|
||||
AssertFatal(req->cell[i].sys_info != NULL, "out of memory\n");
|
||||
f1ap_gnb_du_system_info_t *sys_info = req->cell[i].sys_info;
|
||||
/* mib */
|
||||
sys_info->mib = calloc(DUsi->mIB_message.size, sizeof(char));
|
||||
memcpy(sys_info->mib, DUsi->mIB_message.buf, DUsi->mIB_message.size);
|
||||
sys_info->mib_length = DUsi->mIB_message.size;
|
||||
/* sib1 */
|
||||
sys_info->sib1 = calloc(DUsi->sIB1_message.size, sizeof(char));
|
||||
memcpy(sys_info->sib1, DUsi->sIB1_message.buf, DUsi->sIB1_message.size);
|
||||
sys_info->sib1_length = DUsi->sIB1_message.size;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle RRC Version */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupRequestIEs_t, ie, container,
|
||||
F1AP_ProtocolIE_ID_id_GNB_DU_RRC_Version, true);
|
||||
// Latest RRC Version: "This IE is not used in this release."
|
||||
// BIT_STRING_to_uint8(&ie->value.choice.RRC_Version.latest_RRC_Version);
|
||||
if (ie->value.choice.RRC_Version.iE_Extensions) {
|
||||
F1AP_ProtocolExtensionContainer_10696P228_t *ext =
|
||||
(F1AP_ProtocolExtensionContainer_10696P228_t *)ie->value.choice.RRC_Version.iE_Extensions;
|
||||
if (ext->list.count > 0) {
|
||||
F1AP_RRC_Version_ExtIEs_t *rrcext = ext->list.array[0];
|
||||
OCTET_STRING_t *os = &rrcext->extensionValue.choice.OCTET_STRING_SIZE_3_;
|
||||
DevAssert(os->size == 3);
|
||||
for (int i = 0; i < 3; ++i)
|
||||
req->rrc_ver[i] = os->buf[i];
|
||||
}
|
||||
}
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, GNB_MODULE_ID_TO_INSTANCE(instance), message_p);
|
||||
|
||||
return 0;
|
||||
@@ -220,7 +244,7 @@ int CU_send_F1_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_setup_resp_t *f1ap_set
|
||||
ie1->id = F1AP_ProtocolIE_ID_id_TransactionID;
|
||||
ie1->criticality = F1AP_Criticality_reject;
|
||||
ie1->value.present = F1AP_F1SetupResponseIEs__value_PR_TransactionID;
|
||||
ie1->value.choice.TransactionID = F1AP_get_next_transaction_identifier(0, 0);
|
||||
ie1->value.choice.TransactionID = f1ap_setup_resp->transaction_id;
|
||||
|
||||
/* optional */
|
||||
/* c2. GNB_CU_Name */
|
||||
@@ -292,6 +316,36 @@ int CU_send_F1_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_setup_resp_t *f1ap_set
|
||||
}
|
||||
}
|
||||
|
||||
/* c5. RRC VERSION */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_F1SetupResponseIEs_t, ie4);
|
||||
ie4->id = F1AP_ProtocolIE_ID_id_GNB_CU_RRC_Version;
|
||||
ie4->criticality = F1AP_Criticality_reject;
|
||||
ie4->value.present = F1AP_F1SetupResponseIEs__value_PR_RRC_Version;
|
||||
// RRC Version: "This IE is not used in this release."
|
||||
// we put one bit for each byte in rrc_ver that is != 0
|
||||
uint8_t bits = 0;
|
||||
for (int i = 0; i < 3; ++i)
|
||||
bits |= (f1ap_setup_resp->rrc_ver[i] != 0) << i;
|
||||
BIT_STRING_t *bs = &ie4->value.choice.RRC_Version.latest_RRC_Version;
|
||||
bs->buf = calloc(1, sizeof(char));
|
||||
AssertFatal(bs->buf != NULL, "out of memory\n");
|
||||
bs->buf[0] = bits;
|
||||
bs->size = 1;
|
||||
bs->bits_unused = 5;
|
||||
|
||||
F1AP_ProtocolExtensionContainer_10696P228_t *p = (F1AP_ProtocolExtensionContainer_10696P228_t*)calloc(1, sizeof(F1AP_ProtocolExtensionContainer_10696P228_t));
|
||||
asn1cSequenceAdd(p->list, F1AP_RRC_Version_ExtIEs_t, rrcv_ext);
|
||||
rrcv_ext->id = F1AP_ProtocolIE_ID_id_latest_RRC_Version_Enhanced;
|
||||
rrcv_ext->criticality = F1AP_Criticality_ignore;
|
||||
rrcv_ext->extensionValue.present = F1AP_RRC_Version_ExtIEs__extensionValue_PR_OCTET_STRING_SIZE_3_;
|
||||
OCTET_STRING_t *os = &rrcv_ext->extensionValue.choice.OCTET_STRING_SIZE_3_;
|
||||
os->size = 3;
|
||||
os->buf = malloc(3 * sizeof(*os->buf));
|
||||
AssertFatal(os->buf != NULL, "out of memory\n");
|
||||
for (int i = 0; i < 3; ++i)
|
||||
os->buf[i] = f1ap_setup_resp->rrc_ver[i];
|
||||
ie4->value.choice.RRC_Version.iE_Extensions = (struct F1AP_ProtocolExtensionContainer *)p;
|
||||
|
||||
/* encode */
|
||||
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
LOG_E(F1AP, "Failed to encode F1 setup response\n");
|
||||
|
||||
@@ -274,25 +274,49 @@ int DU_send_F1_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_setup_req_t *setup_req)
|
||||
OCTET_STRING_fromBuf(&served_cell_information->measurementTimingConfiguration,
|
||||
measurementTimingConfiguration,
|
||||
strlen(measurementTimingConfiguration));
|
||||
asn1cCalloc(gnb_du_served_cells_item->gNB_DU_System_Information, gNB_DU_System_Information);
|
||||
|
||||
/* 4.1.2 gNB-DU System Information */
|
||||
AssertFatal(setup_req->cell[i].sys_info != NULL, "assume that sys_info is present, which is not the case\n");
|
||||
const f1ap_gnb_du_system_info_t *sys_info = setup_req->cell[i].sys_info;
|
||||
OCTET_STRING_fromBuf(&gNB_DU_System_Information->mIB_message, (const char *)sys_info->mib, sys_info->mib_length);
|
||||
OCTET_STRING_fromBuf(&gNB_DU_System_Information->sIB1_message, (const char *)sys_info->sib1, sys_info->sib1_length);
|
||||
if (setup_req->cell[i].sys_info != NULL) {
|
||||
asn1cCalloc(gnb_du_served_cells_item->gNB_DU_System_Information, gNB_DU_System_Information);
|
||||
const f1ap_gnb_du_system_info_t *sys_info = setup_req->cell[i].sys_info;
|
||||
AssertFatal(sys_info->mib != NULL, "MIB must be present in DU sys info\n");
|
||||
OCTET_STRING_fromBuf(&gNB_DU_System_Information->mIB_message, (const char *)sys_info->mib, sys_info->mib_length);
|
||||
AssertFatal(sys_info->sib1 != NULL, "SIB1 must be present in DU sys info\n");
|
||||
OCTET_STRING_fromBuf(&gNB_DU_System_Information->sIB1_message, (const char *)sys_info->sib1, sys_info->sib1_length);
|
||||
}
|
||||
}
|
||||
|
||||
/* mandatory */
|
||||
/* c5. RRC VERSION */
|
||||
asn1cSequenceAdd(f1Setup->protocolIEs.list, F1AP_F1SetupRequestIEs_t, ie2);
|
||||
ie2->id = F1AP_ProtocolIE_ID_id_GNB_DU_RRC_Version;
|
||||
ie2->criticality = F1AP_Criticality_reject;
|
||||
ie2->value.present = F1AP_F1SetupRequestIEs__value_PR_RRC_Version;
|
||||
ie2->value.choice.RRC_Version.latest_RRC_Version.buf=calloc(1,sizeof(char));
|
||||
ie2->value.choice.RRC_Version.latest_RRC_Version.buf[0] = 0xe0;
|
||||
ie2->value.choice.RRC_Version.latest_RRC_Version.size = 1;
|
||||
ie2->value.choice.RRC_Version.latest_RRC_Version.bits_unused = 5;
|
||||
ie2->id = F1AP_ProtocolIE_ID_id_GNB_DU_RRC_Version;
|
||||
ie2->criticality = F1AP_Criticality_reject;
|
||||
ie2->value.present = F1AP_F1SetupRequestIEs__value_PR_RRC_Version;
|
||||
// RRC Version: "This IE is not used in this release."
|
||||
// we put one bit for each byte in rrc_ver that is != 0
|
||||
uint8_t bits = 0;
|
||||
for (int i = 0; i < 3; ++i)
|
||||
bits |= (setup_req->rrc_ver[i] != 0) << i;
|
||||
BIT_STRING_t *bs = &ie2->value.choice.RRC_Version.latest_RRC_Version;
|
||||
bs->buf = calloc(1, sizeof(char));
|
||||
AssertFatal(bs->buf != NULL, "out of memory\n");
|
||||
bs->buf[0] = bits;
|
||||
bs->size = 1;
|
||||
bs->bits_unused = 5;
|
||||
|
||||
F1AP_ProtocolExtensionContainer_10696P228_t *p = calloc(1, sizeof(F1AP_ProtocolExtensionContainer_10696P228_t));
|
||||
asn1cSequenceAdd(p->list, F1AP_RRC_Version_ExtIEs_t, rrcv_ext);
|
||||
rrcv_ext->id = F1AP_ProtocolIE_ID_id_latest_RRC_Version_Enhanced;
|
||||
rrcv_ext->criticality = F1AP_Criticality_ignore;
|
||||
rrcv_ext->extensionValue.present = F1AP_RRC_Version_ExtIEs__extensionValue_PR_OCTET_STRING_SIZE_3_;
|
||||
OCTET_STRING_t *os = &rrcv_ext->extensionValue.choice.OCTET_STRING_SIZE_3_;
|
||||
os->size = 3;
|
||||
os->buf = malloc(3 * sizeof(*os->buf));
|
||||
AssertFatal(os->buf != NULL, "out of memory\n");
|
||||
for (int i = 0; i < 3; ++i)
|
||||
os->buf[i] = setup_req->rrc_ver[i];
|
||||
ie2->value.choice.RRC_Version.iE_Extensions = (struct F1AP_ProtocolExtensionContainer*)p;
|
||||
|
||||
/* encode */
|
||||
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
LOG_E(F1AP, "Failed to encode F1 setup request\n");
|
||||
@@ -339,7 +363,7 @@ int DU_handle_F1_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint
|
||||
AssertFatal(ie->criticality == F1AP_Criticality_ignore,
|
||||
"ie->criticality != F1AP_Criticality_ignore\n");
|
||||
AssertFatal(ie->value.present == F1AP_F1SetupResponseIEs__value_PR_GNB_CU_Name,
|
||||
"ie->value.present != F1AP_F1SetupResponseIEs__value_PR_TransactionID\n");
|
||||
"ie->value.present != F1AP_F1SetupResponseIEs__value_PR_GNB_CU_Name\n");
|
||||
resp.gNB_CU_name = malloc(ie->value.choice.GNB_CU_Name.size+1);
|
||||
memcpy(resp.gNB_CU_name, ie->value.choice.GNB_CU_Name.buf, ie->value.choice.GNB_CU_Name.size);
|
||||
resp.gNB_CU_name[ie->value.choice.GNB_CU_Name.size] = '\0';
|
||||
@@ -347,7 +371,21 @@ int DU_handle_F1_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint
|
||||
break;
|
||||
|
||||
case F1AP_ProtocolIE_ID_id_GNB_CU_RRC_Version:
|
||||
LOG_D(F1AP, "F1AP: Received GNB-CU-RRC-Version, ignoring\n");
|
||||
AssertFatal(ie->criticality == F1AP_Criticality_reject,
|
||||
"ie->criticality != F1AP_Criticality_reject\n");
|
||||
AssertFatal(ie->value.present == F1AP_F1SetupResponseIEs__value_PR_RRC_Version,
|
||||
"ie->value.present != F1AP_F1SetupResponseIEs__value_PR_RRC_Version\n");
|
||||
// RRC Version: "This IE is not used in this release."
|
||||
if(ie->value.choice.RRC_Version.iE_Extensions) {
|
||||
F1AP_ProtocolExtensionContainer_10696P228_t *ext =
|
||||
(F1AP_ProtocolExtensionContainer_10696P228_t *)ie->value.choice.RRC_Version.iE_Extensions;
|
||||
if(ext->list.count > 0){
|
||||
F1AP_RRC_Version_ExtIEs_t *rrcext = ext->list.array[0];
|
||||
OCTET_STRING_t *os = &rrcext->extensionValue.choice.OCTET_STRING_SIZE_3_;
|
||||
for (int i = 0; i < 3; i++)
|
||||
resp.rrc_ver[i] = os->buf[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List: {
|
||||
|
||||
@@ -1153,18 +1153,20 @@ static f1ap_setup_req_t *RC_read_F1Setup(uint64_t id,
|
||||
|
||||
req->cell[0].info.measurement_timing_information = "0";
|
||||
|
||||
int buf_len = 3; // this is what we assume in monolithic
|
||||
req->cell[0].sys_info = calloc(1, sizeof(*req->cell[0].sys_info));
|
||||
AssertFatal(req->cell[0].sys_info != NULL, "out of memory\n");
|
||||
f1ap_gnb_du_system_info_t *sys_info = req->cell[0].sys_info;
|
||||
sys_info->mib = calloc(buf_len, sizeof(*sys_info->mib));
|
||||
DevAssert(sys_info->mib != NULL);
|
||||
DevAssert(mib != NULL);
|
||||
sys_info->mib_length = encode_MIB_NR(mib, 0, sys_info->mib, buf_len);
|
||||
DevAssert(sys_info->mib_length == buf_len);
|
||||
|
||||
if (get_softmodem_params()->sa) {
|
||||
// in NSA we don't transmit SIB1
|
||||
// in NSA we don't transmit SIB1, so cannot fill DU system information
|
||||
// so cannot send MIB either
|
||||
|
||||
int buf_len = 3; // this is what we assume in monolithic
|
||||
req->cell[0].sys_info = calloc(1, sizeof(*req->cell[0].sys_info));
|
||||
AssertFatal(req->cell[0].sys_info != NULL, "out of memory\n");
|
||||
f1ap_gnb_du_system_info_t *sys_info = req->cell[0].sys_info;
|
||||
sys_info->mib = calloc(buf_len, sizeof(*sys_info->mib));
|
||||
DevAssert(sys_info->mib != NULL);
|
||||
DevAssert(mib != NULL);
|
||||
sys_info->mib_length = encode_MIB_NR(mib, 0, sys_info->mib, buf_len);
|
||||
DevAssert(sys_info->mib_length == buf_len);
|
||||
|
||||
DevAssert(sib1 != NULL);
|
||||
NR_SIB1_t *bcch_SIB1 = sib1->message.choice.c1->choice.systemInformationBlockType1;
|
||||
sys_info->sib1 = calloc(NR_MAX_SIB_LENGTH / 8, sizeof(*sys_info->sib1));
|
||||
@@ -1173,6 +1175,9 @@ static f1ap_setup_req_t *RC_read_F1Setup(uint64_t id,
|
||||
sys_info->sib1_length = (enc_rval.encoded + 7) / 8;
|
||||
}
|
||||
|
||||
int num = read_version(TO_STRING(NR_RRC_VERSION), &req->rrc_ver[0], &req->rrc_ver[1], &req->rrc_ver[2]);
|
||||
AssertFatal(num == 3, "could not read RRC version string %s\n", TO_STRING(NR_RRC_VERSION));
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ static bool check_plmn_identity(const f1ap_plmn_t *check_plmn, const f1ap_plmn_t
|
||||
void f1_setup_response(const f1ap_setup_resp_t *resp)
|
||||
{
|
||||
LOG_I(MAC, "received F1 Setup Response from CU %s\n", resp->gNB_CU_name);
|
||||
LOG_I(MAC, "CU uses RRC version %d.%d.%d\n", resp->rrc_ver[0], resp->rrc_ver[1], resp->rrc_ver[2]);
|
||||
|
||||
if (resp->num_cells_to_activate == 0) {
|
||||
LOG_W(NR_MAC, "no cell to activate: cell remains blocked\n");
|
||||
|
||||
@@ -61,6 +61,7 @@ static void f1_setup_request_direct(const f1ap_setup_req_t *req)
|
||||
}
|
||||
}
|
||||
}
|
||||
memcpy(f1ap_msg->rrc_ver, req->rrc_ver, sizeof(req->rrc_ver));
|
||||
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, 0, msg);
|
||||
}
|
||||
|
||||
@@ -93,6 +93,7 @@ static void f1_setup_request_f1ap(const f1ap_setup_req_t *req)
|
||||
}
|
||||
}
|
||||
}
|
||||
memcpy(f1ap_setup->rrc_ver, req->rrc_ver, sizeof(req->rrc_ver));
|
||||
|
||||
F1AP_DU_REGISTER_REQ(msg).net_config = read_DU_IP_config(&RC.nrmac[0]->eth_params_n);
|
||||
|
||||
|
||||
@@ -576,8 +576,13 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co
|
||||
f1ap_served_cell_info_t *cell_info = &du->setup_req->cell[0].info;
|
||||
int scs = get_ssb_scs(cell_info);
|
||||
int band = get_dl_band(cell_info);
|
||||
uint32_t ssb_arfcn = get_ssb_arfcn(cell_info, du->mib, du->sib1);
|
||||
NR_MeasConfig_t *measconfig = get_defaultMeasConfig(ssb_arfcn, band, scs);
|
||||
NR_MeasConfig_t *measconfig = NULL;
|
||||
if (du->mib != NULL && du->sib1 != NULL) {
|
||||
/* we cannot calculate the default measurement config without MIB&SIB1, as
|
||||
* we don't know the DU's SSB ARFCN */
|
||||
uint32_t ssb_arfcn = get_ssb_arfcn(cell_info, du->mib, du->sib1);
|
||||
measconfig = get_defaultMeasConfig(ssb_arfcn, band, scs);
|
||||
}
|
||||
|
||||
uint8_t buffer[RRC_BUF_SIZE] = {0};
|
||||
int size = do_RRCReconfiguration(ue_p,
|
||||
@@ -1288,12 +1293,22 @@ static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc, sctp_assoc_t
|
||||
return;
|
||||
}
|
||||
|
||||
rnti_t old_rnti = req->ue_Identity.c_RNTI;
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, assoc_id, old_rnti);
|
||||
/* in case we need to do RRC Setup, give the UE a new random identity */
|
||||
uint64_t random_value;
|
||||
fill_random(&random_value, sizeof(random_value));
|
||||
random_value = random_value & 0x7fffffffff; /* random value is 39 bits */
|
||||
if (du->mib == NULL || du->sib1 == NULL) {
|
||||
/* we don't have MIB/SIB1 of the DU, and therefore cannot generate the
|
||||
* Reestablishment (as we would need the SSB's ARFCN, which we cannot
|
||||
* compute). So generate RRC Setup instead */
|
||||
LOG_E(NR_RRC, "Reestablishment request: no MIB/SIB1 of DU present, cannot do reestablishment, force setup request\n");
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_create_ue_context(assoc_id, msg->crnti, rrc, random_value, msg->gNB_DU_ue_id);
|
||||
ue_context_p->ue_context.Srb[1].Active = 1;
|
||||
rrc_gNB_generate_RRCSetup(0, msg->crnti, ue_context_p, msg->du2cu_rrc_container, msg->du2cu_rrc_container_length);
|
||||
}
|
||||
|
||||
rnti_t old_rnti = req->ue_Identity.c_RNTI;
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, assoc_id, old_rnti);
|
||||
if (ue_context_p == NULL) {
|
||||
LOG_E(NR_RRC, "NR_RRCReestablishmentRequest without UE context, fallback to RRC setup\n");
|
||||
ue_context_p = rrc_gNB_create_ue_context(assoc_id, msg->crnti, rrc, random_value, msg->gNB_DU_ue_id);
|
||||
|
||||
@@ -112,41 +112,36 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
|
||||
|
||||
// if there is no system info or no SIB1 and we run in SA mode, we cannot handle it
|
||||
const f1ap_gnb_du_system_info_t *sys_info = req->cell[0].sys_info;
|
||||
if (sys_info == NULL || sys_info->mib == NULL || (sys_info->sib1 == NULL && get_softmodem_params()->sa)) {
|
||||
LOG_E(NR_RRC, "no system information provided by DU, rejecting\n");
|
||||
f1ap_setup_failure_t fail = {.cause = F1AP_CauseProtocol_semantic_error};
|
||||
rrc->mac_rrc.f1_setup_failure(assoc_id, &fail);
|
||||
return;
|
||||
}
|
||||
|
||||
/* do we need the MIB? for the moment, just check it is valid, then drop it */
|
||||
NR_BCCH_BCH_Message_t *mib = NULL;
|
||||
asn_dec_rval_t dec_rval =
|
||||
uper_decode_complete(NULL, &asn_DEF_NR_BCCH_BCH_Message, (void **)&mib, sys_info->mib, sys_info->mib_length);
|
||||
if (dec_rval.code != RC_OK || mib->message.present != NR_BCCH_BCH_MessageType_PR_mib
|
||||
|| mib->message.choice.messageClassExtension == NULL) {
|
||||
LOG_E(RRC, "Failed to decode NR_BCCH_BCH_MESSAGE (%zu bits) of DU, rejecting DU\n", dec_rval.consumed);
|
||||
f1ap_setup_failure_t fail = {.cause = F1AP_CauseProtocol_semantic_error};
|
||||
rrc->mac_rrc.f1_setup_failure(assoc_id, &fail);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, mib);
|
||||
return;
|
||||
}
|
||||
|
||||
NR_SIB1_t *sib1 = NULL;
|
||||
if (sys_info->sib1) {
|
||||
dec_rval = uper_decode_complete(NULL, &asn_DEF_NR_SIB1, (void **)&sib1, sys_info->sib1, sys_info->sib1_length);
|
||||
if (dec_rval.code != RC_OK) {
|
||||
LOG_E(RRC, "Failed to decode NR_SIB1 (%zu bits) of DU, rejecting DU\n", dec_rval.consumed);
|
||||
|
||||
if (sys_info != NULL && sys_info->mib != NULL && !(sys_info->sib1 == NULL && get_softmodem_params()->sa)) {
|
||||
asn_dec_rval_t dec_rval =
|
||||
uper_decode_complete(NULL, &asn_DEF_NR_BCCH_BCH_Message, (void **)&mib, sys_info->mib, sys_info->mib_length);
|
||||
if (dec_rval.code != RC_OK || mib->message.present != NR_BCCH_BCH_MessageType_PR_mib
|
||||
|| mib->message.choice.messageClassExtension == NULL) {
|
||||
LOG_E(RRC, "Failed to decode NR_BCCH_BCH_MESSAGE (%zu bits) of DU, rejecting DU\n", dec_rval.consumed);
|
||||
f1ap_setup_failure_t fail = {.cause = F1AP_CauseProtocol_semantic_error};
|
||||
rrc->mac_rrc.f1_setup_failure(assoc_id, &fail);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_SIB1, sib1);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, mib);
|
||||
return;
|
||||
}
|
||||
if (LOG_DEBUGFLAG(DEBUG_ASN1))
|
||||
xer_fprint(stdout, &asn_DEF_NR_SIB1, sib1);
|
||||
}
|
||||
|
||||
if (sys_info->sib1) {
|
||||
dec_rval = uper_decode_complete(NULL, &asn_DEF_NR_SIB1, (void **)&sib1, sys_info->sib1, sys_info->sib1_length);
|
||||
if (dec_rval.code != RC_OK) {
|
||||
LOG_E(RRC, "Failed to decode NR_SIB1 (%zu bits) of DU, rejecting DU\n", dec_rval.consumed);
|
||||
f1ap_setup_failure_t fail = {.cause = F1AP_CauseProtocol_semantic_error};
|
||||
rrc->mac_rrc.f1_setup_failure(assoc_id, &fail);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_SIB1, sib1);
|
||||
return;
|
||||
}
|
||||
if (LOG_DEBUGFLAG(DEBUG_ASN1))
|
||||
xer_fprint(stdout, &asn_DEF_NR_SIB1, sib1);
|
||||
}
|
||||
}
|
||||
LOG_I(RRC, "Accepting DU %ld (%s), sending F1 Setup Response\n", req->gNB_DU_id, req->gNB_DU_name);
|
||||
LOG_I(RRC, "DU uses RRC version %u.%u.%u\n", req->rrc_ver[0], req->rrc_ver[1], req->rrc_ver[2]);
|
||||
|
||||
// we accept the DU
|
||||
nr_rrc_du_container_t *du = calloc(1, sizeof(*du));
|
||||
@@ -156,13 +151,15 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
|
||||
/* ITTI will free the setup request message via free(). So the memory
|
||||
* "inside" of the message will remain, but the "outside" container no, so
|
||||
* allocate memory and copy it in */
|
||||
du->setup_req = malloc(sizeof(*du->setup_req));
|
||||
du->setup_req = calloc(1,sizeof(*du->setup_req));
|
||||
AssertFatal(du->setup_req != NULL, "out of memory\n");
|
||||
*du->setup_req = *req;
|
||||
du->mib = mib->message.choice.mib;
|
||||
mib->message.choice.mib = NULL;
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_MessageType, mib);
|
||||
du->sib1 = sib1;
|
||||
if (mib != NULL && sib1 != NULL) {
|
||||
du->mib = mib->message.choice.mib;
|
||||
mib->message.choice.mib = NULL;
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_MessageType, mib);
|
||||
du->sib1 = sib1;
|
||||
}
|
||||
RB_INSERT(rrc_du_tree, &rrc->dus, du);
|
||||
rrc->num_dus++;
|
||||
|
||||
@@ -171,8 +168,13 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
|
||||
.nr_cellid = cell_info->nr_cellid,
|
||||
.nrpci = cell_info->nr_pci,
|
||||
.num_SI = 0,
|
||||
};
|
||||
f1ap_setup_resp_t resp = {.num_cells_to_activate = 1, .cells_to_activate[0] = cell};
|
||||
};
|
||||
|
||||
f1ap_setup_resp_t resp = {.transaction_id = req->transaction_id,
|
||||
.num_cells_to_activate = 1,
|
||||
.cells_to_activate[0] = cell};
|
||||
int num = read_version(TO_STRING(NR_RRC_VERSION), &resp.rrc_ver[0], &resp.rrc_ver[1], &resp.rrc_ver[2]);
|
||||
AssertFatal(num == 3, "could not read RRC version string %s\n", TO_STRING(NR_RRC_VERSION));
|
||||
if (rrc->node_name != NULL)
|
||||
resp.gNB_CU_name = strdup(rrc->node_name);
|
||||
rrc->mac_rrc.f1_setup_response(assoc_id, &resp);
|
||||
|
||||
Reference in New Issue
Block a user