Commit 65d494fb authored by Jaroslava Fiedlerova's avatar Jaroslava Fiedlerova

Merge remote-tracking branch 'origin/f1ap_uecontext_refactoring' into integration_2024_w18

parents 944925ff 0fb0b055
......@@ -30,7 +30,7 @@ gNBs =
absoluteFrequencySSB = 620736;
dl_frequencyBand = 78;
# this is 3300.30 MHz
dl_absoluteFrequencyPointA = 620052;
dl_absoluteFrequencyPointA = 620020;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
......
......@@ -27,11 +27,14 @@ MESSAGE_DEF(F1AP_DU_REGISTER_REQ, MESSAGE_PRIORITY_MED, f1ap_du_register_req_t,
MESSAGE_DEF(F1AP_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_setup_req_t , f1ap_setup_req)
MESSAGE_DEF(F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE , MESSAGE_PRIORITY_MED, f1ap_gnb_cu_configuration_update_acknowledge_t , f1ap_gnb_cu_configuration_update_acknowledge)
MESSAGE_DEF(F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE , MESSAGE_PRIORITY_MED, f1ap_gnb_cu_configuration_update_failure_t , f1ap_gnb_cu_configuration_update_failure)
MESSAGE_DEF(F1AP_GNB_DU_CONFIGURATION_UPDATE, MESSAGE_PRIORITY_MED, f1ap_gnb_du_configuration_update_t, f1ap_gnb_du_configuration_update)
/* F1AP -> eNB_DU or eNB_CU_RRC -> F1AP application layer messages */
MESSAGE_DEF(F1AP_SETUP_RESP , MESSAGE_PRIORITY_MED, f1ap_setup_resp_t , f1ap_setup_resp)
MESSAGE_DEF(F1AP_SETUP_FAILURE , MESSAGE_PRIORITY_MED, f1ap_setup_failure_t , f1ap_setup_failure)
MESSAGE_DEF(F1AP_GNB_CU_CONFIGURATION_UPDATE , MESSAGE_PRIORITY_MED, f1ap_gnb_cu_configuration_update_t , f1ap_gnb_cu_configuration_update)
MESSAGE_DEF(F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE , MESSAGE_PRIORITY_MED, f1ap_gnb_du_configuration_update_acknowledge_t, f1ap_gnb_du_configuration_update_acknowledge)
MESSAGE_DEF(F1AP_GNB_DU_CONFIGURATION_UPDATE_FAILURE , MESSAGE_PRIORITY_MED, f1ap_gnb_du_configuration_update_failure_t, f1ap_gnb_du_configuration_update_failure)
/* F1AP -> RRC to inform about lost connection */
MESSAGE_DEF(F1AP_LOST_CONNECTION, MESSAGE_PRIORITY_MED, f1ap_lost_connection_t, f1ap_lost_connection)
......
......@@ -39,6 +39,10 @@
#define F1AP_GNB_CU_CONFIGURATION_UPDATE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_cu_configuration_update
#define F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_cu_configuration_update_acknowledge
#define F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_cu_configuration_update_failure
#define F1AP_GNB_DU_CONFIGURATION_UPDATE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_du_configuration_update
#define F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_du_configuration_update_acknowledge
#define F1AP_GNB_DU_CONFIGURATION_UPDATE_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_du_configuration_update_failure
#define F1AP_SETUP_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_setup_failure
#define F1AP_LOST_CONNECTION(mSGpTR) (mSGpTR)->ittiMsg.f1ap_lost_connection
......@@ -125,10 +129,9 @@ typedef struct f1ap_served_cell_info_t {
/* Tracking area code */
uint32_t *tac;
// Number of slide support items (max 16, could be increased to as much as 1024)
// Number of slice support items (max 16, could be increased to as much as 1024)
uint16_t num_ssi;
uint8_t sst;
uint8_t sd;
nssai_t nssai[16];
f1ap_mode_t mode;
union {
......@@ -136,7 +139,8 @@ typedef struct f1ap_served_cell_info_t {
f1ap_tdd_info_t tdd;
};
char *measurement_timing_information;
uint8_t *measurement_timing_config;
int measurement_timing_config_len;
} f1ap_served_cell_info_t;
typedef struct f1ap_gnb_du_system_info_t {
......@@ -247,6 +251,57 @@ typedef struct f1ap_gnb_cu_configuration_update_failure_s {
uint16_t criticality_diagnostics;
} f1ap_gnb_cu_configuration_update_failure_t;
/*DU configuration messages*/
typedef struct f1ap_gnb_du_configuration_update_s {
/*TODO UPDATE TO SUPPORT DU CONFIG*/
/* Transaction ID */
uint64_t transaction_id;
/// int cells_to_add
uint16_t num_cells_to_add;
struct {
f1ap_served_cell_info_t info;
f1ap_gnb_du_system_info_t *sys_info;
} cell_to_add[F1AP_MAX_NB_CELLS];
/// int cells_to_modify
uint16_t num_cells_to_modify;
struct {
f1ap_plmn_t old_plmn;
uint64_t old_nr_cellid; // NR Global Cell Id
f1ap_served_cell_info_t info;
f1ap_gnb_du_system_info_t *sys_info;
} cell_to_modify[F1AP_MAX_NB_CELLS];
/// int cells_to_delete
uint16_t num_cells_to_delete;
struct {
// NR CGI
f1ap_plmn_t plmn;
uint64_t nr_cellid; // NR Global Cell Id
} cell_to_delete[F1AP_MAX_NB_CELLS];
/// string holding gNB_CU_name
uint64_t *gNB_DU_ID;
} f1ap_gnb_du_configuration_update_t;
typedef struct f1ap_gnb_du_configuration_update_acknowledge_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];
} f1ap_gnb_du_configuration_update_acknowledge_t;
typedef struct f1ap_gnb_du_configuration_update_failure_s {
/*TODO UPDATE TO SUPPORT DU CONFIG*/
uint16_t cause;
uint16_t time_to_wait;
uint16_t criticality_diagnostics;
} f1ap_gnb_du_configuration_update_failure_t;
typedef struct f1ap_dl_rrc_message_s {
uint32_t gNB_CU_ue_id;
......
......@@ -583,6 +583,8 @@ typedef struct ngap_ue_ctxt_modification_resp_s {
typedef struct ngap_ue_release_complete_s {
uint32_t gNB_ue_ngap_id;
int num_pdu_sessions;
uint32_t pdu_session_id[256];
} ngap_ue_release_complete_t;
//-------------------------------------------------------------------------------------------//
......
......@@ -62,10 +62,11 @@ int CU_send_F1_SETUP_FAILURE(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *
int CU_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
int CU_send_gNB_DU_CONFIGURATION_FAILURE(sctp_assoc_t assoc_id,
F1AP_GNBDUConfigurationUpdateFailure_t *GNBDUConfigurationUpdateFailure);
f1ap_gnb_du_configuration_update_failure_t *GNBDUConfigurationUpdateFailure);
int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(sctp_assoc_t assoc_id,
F1AP_GNBDUConfigurationUpdateAcknowledge_t *GNBDUConfigurationUpdateAcknowledge);
int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(
sctp_assoc_t assoc_id,
f1ap_gnb_du_configuration_update_acknowledge_t *GNBDUConfigurationUpdateAcknowledge);
/*
* gNB-CU Configuration Update
......
......@@ -174,6 +174,9 @@ void *F1AP_CU_task(void *arg) {
&F1AP_GNB_CU_CONFIGURATION_UPDATE(received_msg));
break;
case F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE:
CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(assoc_id, &F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(received_msg));
break;
case F1AP_DL_RRC_MESSAGE: // from rrc
CU_send_DL_RRC_MESSAGE_TRANSFER(assoc_id,
&F1AP_DL_RRC_MESSAGE(received_msg));
......
......@@ -273,27 +273,27 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu
f1ap_ue_context_setup_req->cu_to_du_rrc_information->measConfig_length);
}
}
/* mandatory */
/* c7. Candidate_SpCell_List */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie7);
ie7->id = F1AP_ProtocolIE_ID_id_Candidate_SpCell_List; //90
ie7->criticality = F1AP_Criticality_ignore;
ie7->value.present = F1AP_UEContextSetupRequestIEs__value_PR_Candidate_SpCell_List;
for (int i=0; i<1; i++) {
asn1cSequenceAdd(ie7->value.choice.Candidate_SpCell_List.list,F1AP_Candidate_SpCell_ItemIEs_t, candidate_spCell_item_ies);
candidate_spCell_item_ies->id = F1AP_ProtocolIE_ID_id_Candidate_SpCell_Item; // 91
candidate_spCell_item_ies->criticality = F1AP_Criticality_reject;
candidate_spCell_item_ies->value.present = F1AP_Candidate_SpCell_ItemIEs__value_PR_Candidate_SpCell_Item;
/* 7.1 Candidate_SpCell_Item */
F1AP_Candidate_SpCell_Item_t *candidate_spCell_item=
&candidate_spCell_item_ies->value.choice.Candidate_SpCell_Item;
/* - candidate_SpCell_ID */
//FixMe: first cell ???
addnRCGI(candidate_spCell_item->candidate_SpCell_ID,f1ap_ue_context_setup_req);
/* TODO add correct mcc/mnc */
/* optional */
if (0) {
/* c7. Candidate_SpCell_List */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie7);
ie7->id = F1AP_ProtocolIE_ID_id_Candidate_SpCell_List; // 90
ie7->criticality = F1AP_Criticality_ignore;
ie7->value.present = F1AP_UEContextSetupRequestIEs__value_PR_Candidate_SpCell_List;
for (int i = 0; i < 1; i++) {
asn1cSequenceAdd(ie7->value.choice.Candidate_SpCell_List.list, F1AP_Candidate_SpCell_ItemIEs_t, candidate_spCell_item_ies);
candidate_spCell_item_ies->id = F1AP_ProtocolIE_ID_id_Candidate_SpCell_Item; // 91
candidate_spCell_item_ies->criticality = F1AP_Criticality_ignore;
candidate_spCell_item_ies->value.present = F1AP_Candidate_SpCell_ItemIEs__value_PR_Candidate_SpCell_Item;
/* 7.1 Candidate_SpCell_Item */
F1AP_Candidate_SpCell_Item_t *candidate_spCell_item = &candidate_spCell_item_ies->value.choice.Candidate_SpCell_Item;
/* - candidate_SpCell_ID */
// FixMe: first cell ???
addnRCGI(candidate_spCell_item->candidate_SpCell_ID, f1ap_ue_context_setup_req);
/* TODO add correct mcc/mnc */
}
}
/* optional */
......@@ -335,32 +335,33 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu
strlen("asdsa1d32sa1d31asd31as"));
}
/* mandatory */
/* c10. SCell_ToBeSetup_List */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie10);
ie10->id = F1AP_ProtocolIE_ID_id_SCell_ToBeSetup_List;
ie10->criticality = F1AP_Criticality_ignore;
ie10->value.present = F1AP_UEContextSetupRequestIEs__value_PR_SCell_ToBeSetup_List;
for (int i=0; i<1; i++) {
//
asn1cSequenceAdd(ie10->value.choice.SCell_ToBeSetup_List.list, F1AP_SCell_ToBeSetup_ItemIEs_t, scell_toBeSetup_item_ies);
scell_toBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_SCell_ToBeSetup_Item; //53
scell_toBeSetup_item_ies->criticality = F1AP_Criticality_ignore;
scell_toBeSetup_item_ies->value.present = F1AP_SCell_ToBeSetup_ItemIEs__value_PR_SCell_ToBeSetup_Item;
/* 10.1 SCell_ToBeSetup_Item */
F1AP_SCell_ToBeSetup_Item_t *scell_toBeSetup_item=&scell_toBeSetup_item_ies->value.choice.SCell_ToBeSetup_Item;
/* 10.1.1 sCell_ID */
addnRCGI(scell_toBeSetup_item->sCell_ID, f1ap_ue_context_setup_req);
/* TODO correct MCC/MNC */
/* 10.1.2 sCellIndex */
scell_toBeSetup_item->sCellIndex = 3; // issue here
/* optional */
if (0) {
/* c10. SCell_ToBeSetup_List */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie10);
ie10->id = F1AP_ProtocolIE_ID_id_SCell_ToBeSetup_List;
ie10->criticality = F1AP_Criticality_ignore;
ie10->value.present = F1AP_UEContextSetupRequestIEs__value_PR_SCell_ToBeSetup_List;
for (int i = 0; i < 1; i++) {
asn1cSequenceAdd(ie10->value.choice.SCell_ToBeSetup_List.list, F1AP_SCell_ToBeSetup_ItemIEs_t, scell_toBeSetup_item_ies);
scell_toBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_SCell_ToBeSetup_Item; // 53
scell_toBeSetup_item_ies->criticality = F1AP_Criticality_ignore;
scell_toBeSetup_item_ies->value.present = F1AP_SCell_ToBeSetup_ItemIEs__value_PR_SCell_ToBeSetup_Item;
/* 10.1 SCell_ToBeSetup_Item */
F1AP_SCell_ToBeSetup_Item_t *scell_toBeSetup_item = &scell_toBeSetup_item_ies->value.choice.SCell_ToBeSetup_Item;
/* 10.1.1 sCell_ID */
addnRCGI(scell_toBeSetup_item->sCell_ID, f1ap_ue_context_setup_req);
/* TODO correct MCC/MNC */
/* 10.1.2 sCellIndex */
scell_toBeSetup_item->sCellIndex = 3; // issue here
/* OPTIONAL */
/* 10.1.3 sCellULConfigured*/
if (0) {
asn1cCallocOne(scell_toBeSetup_item->sCellULConfigured,
F1AP_CellULConfigured_ul_and_sul); // enum
/* OPTIONAL */
/* 10.1.3 sCellULConfigured*/
if (0) {
asn1cCallocOne(scell_toBeSetup_item->sCellULConfigured,
F1AP_CellULConfigured_ul_and_sul); // enum
}
}
}
......@@ -375,7 +376,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu
for (int i=0; i<f1ap_ue_context_setup_req->srbs_to_be_setup_length; i++) {
asn1cSequenceAdd(ie11->value.choice.SRBs_ToBeSetup_List.list, F1AP_SRBs_ToBeSetup_ItemIEs_t, srbs_toBeSetup_item_ies);
srbs_toBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetup_Item; // 73
srbs_toBeSetup_item_ies->criticality = F1AP_Criticality_ignore;
srbs_toBeSetup_item_ies->criticality = F1AP_Criticality_reject;
srbs_toBeSetup_item_ies->value.present = F1AP_SRBs_ToBeSetup_ItemIEs__value_PR_SRBs_ToBeSetup_Item;
/* 11.1 SRBs_ToBeSetup_Item */
F1AP_SRBs_ToBeSetup_Item_t *srbs_toBeSetup_item=&srbs_toBeSetup_item_ies->value.choice.SRBs_ToBeSetup_Item;
......@@ -539,7 +540,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu
if(f1ap_ue_context_setup_req->rrc_container_length > 0) {
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie14);
ie14->id = F1AP_ProtocolIE_ID_id_RRCContainer;
ie14->criticality = F1AP_Criticality_reject;
ie14->criticality = F1AP_Criticality_ignore;
ie14->value.present = F1AP_UEContextSetupRequestIEs__value_PR_RRCContainer;
OCTET_STRING_fromBuf(&ie14->value.choice.RRCContainer, (const char *)f1ap_ue_context_setup_req->rrc_container,
f1ap_ue_context_setup_req->rrc_container_length);
......
......@@ -50,7 +50,7 @@ int DU_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint3
/*
* F1 Setup
*/
int DU_send_F1_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_setup_req_t *setup_req);
int DU_send_F1_SETUP_REQUEST(sctp_assoc_t assoc_id, const f1ap_setup_req_t *setup_req);
int DU_handle_F1_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
......@@ -59,8 +59,7 @@ int DU_handle_F1_SETUP_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint3
/*
* gNB-DU Configuration Update
*/
int DU_send_gNB_DU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id,
f1ap_setup_req_t *f1ap_du_data);
int DU_send_gNB_DU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, const f1ap_gnb_du_configuration_update_t *upd);
int DU_handle_gNB_DU_CONFIGURATION_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
......
......@@ -186,6 +186,10 @@ void *F1AP_DU_task(void *arg) {
DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(assoc_id, &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg));
break;
case F1AP_GNB_DU_CONFIGURATION_UPDATE:
DU_send_gNB_DU_CONFIGURATION_UPDATE(assoc_id, &F1AP_GNB_DU_CONFIGURATION_UPDATE(msg));
break;
case TERMINATE_MESSAGE:
LOG_W(F1AP, " *** Exiting F1AP thread\n");
itti_exit_task();
......
......@@ -45,7 +45,7 @@ static const f1ap_message_processing_t f1ap_messages_processing[][3] = {
{0, 0, 0}, /* Reset */
{CU_handle_F1_SETUP_REQUEST, DU_handle_F1_SETUP_RESPONSE, DU_handle_F1_SETUP_FAILURE}, /* F1Setup */
{0, 0, 0}, /* ErrorIndication */
{0, 0, 0}, /* gNBDUConfigurationUpdate */
{CU_handle_gNB_DU_CONFIGURATION_UPDATE, 0, 0}, /* gNBDUConfigurationUpdate */
{DU_handle_gNB_CU_CONFIGURATION_UPDATE,
CU_handle_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE,
CU_handle_gNB_CU_CONFIGURATION_UPDATE_FAILURE}, /* gNBCUConfigurationUpdate */
......
......@@ -82,6 +82,7 @@
#include "NR_RateMatchPatternLTE-CRS.h"
#include "NR_SearchSpace.h"
#include "NR_ControlResourceSet.h"
#include "NR_MeasurementTimingConfiguration.h"
#include "NR_EUTRA-MBSFN-SubframeConfig.h"
#include "uper_decoder.h"
#include "uper_encoder.h"
......@@ -1095,6 +1096,8 @@ static int read_du_cell_info(configmodule_interface_t *cfg,
PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]);
paramlist_def_t PLMNParamList = {GNB_CONFIG_STRING_PLMN_LIST, NULL, 0};
config_getlist(cfg, &PLMNParamList, PLMNParams, sizeof(PLMNParams) / sizeof(paramdef_t), aprefix);
AssertFatal(PLMNParamList.numelt > 0, "need to have a PLMN in PLMN section\n");
AssertFatal(PLMNParamList.numelt == 1, "cannot have more than one PLMN\n");
// if fronthaul is F1, require gNB_DU_ID, else use gNB_ID
if (separate_du) {
......@@ -1119,12 +1122,53 @@ static int read_du_cell_info(configmodule_interface_t *cfg,
info->plmn.mnc_digit_length);
info->nr_cellid = (uint64_t) * (GNBParamList.paramarray[0][GNB_NRCELLID_IDX].u64ptr);
LOG_W(GNB_APP, "no slices transported via F1 Setup Request!\n");
info->num_ssi = 0;
paramdef_t SNSSAIParams[] = GNBSNSSAIPARAMS_DESC;
paramlist_def_t SNSSAIParamList = {GNB_CONFIG_STRING_SNSSAI_LIST, NULL, 0};
checkedparam_t config_check_SNSSAIParams[] = SNSSAIPARAMS_CHECK;
for (int J = 0; J < sizeofArray(SNSSAIParams); ++J)
SNSSAIParams[J].chkPptr = &(config_check_SNSSAIParams[J]);
char snssaistr[MAX_OPTNAME_SIZE * 2 + 8];
sprintf(snssaistr, "%s.[0].%s.[0]", GNB_CONFIG_STRING_GNB_LIST, GNB_CONFIG_STRING_PLMN_LIST);
config_getlist(config_get_if(), &SNSSAIParamList, SNSSAIParams, sizeofArray(SNSSAIParams), snssaistr);
info->num_ssi = SNSSAIParamList.numelt;
for (int s = 0; s < info->num_ssi; ++s) {
info->nssai[s].sst = *SNSSAIParamList.paramarray[s][GNB_SLICE_SERVICE_TYPE_IDX].uptr;
info->nssai[s].sd = *SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr;
AssertFatal(info->nssai[s].sd <= 0xffffff, "SD cannot be bigger than 0xffffff, but is %d\n", info->nssai[s].sd);
}
return 1;
}
static f1ap_tdd_info_t read_tdd_config(const NR_ServingCellConfigCommon_t *scc)
{
const NR_FrequencyInfoDL_t *dl = scc->downlinkConfigCommon->frequencyInfoDL;
f1ap_tdd_info_t tdd = {
.freqinfo.arfcn = dl->absoluteFrequencyPointA,
.freqinfo.band = *dl->frequencyBandList.list.array[0],
.tbw.scs = dl->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
.tbw.nrb = dl->scs_SpecificCarrierList.list.array[0]->carrierBandwidth,
};
return tdd;
}
static f1ap_fdd_info_t read_fdd_config(const NR_ServingCellConfigCommon_t *scc)
{
const NR_FrequencyInfoDL_t *dl = scc->downlinkConfigCommon->frequencyInfoDL;
const NR_FrequencyInfoUL_t *ul = scc->uplinkConfigCommon->frequencyInfoUL;
f1ap_fdd_info_t fdd = {
.dl_freqinfo.arfcn = dl->absoluteFrequencyPointA,
.ul_freqinfo.arfcn = *ul->absoluteFrequencyPointA,
.dl_tbw.scs = dl->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
.ul_tbw.scs = ul->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
.dl_tbw.nrb = dl->scs_SpecificCarrierList.list.array[0]->carrierBandwidth,
.ul_tbw.nrb = ul->scs_SpecificCarrierList.list.array[0]->carrierBandwidth,
.dl_freqinfo.band = *dl->frequencyBandList.list.array[0],
.ul_freqinfo.band = *ul->frequencyBandList->list.array[0],
};
return fdd;
}
static f1ap_setup_req_t *RC_read_F1Setup(uint64_t id,
const char *name,
const f1ap_served_cell_info_t *info,
......@@ -1150,30 +1194,26 @@ static f1ap_setup_req_t *RC_read_F1Setup(uint64_t id,
req->cell[0].info.nr_cellid);
req->cell[0].info.nr_pci = *scc->physCellId;
struct NR_FrequencyInfoDL *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
if (scc->tdd_UL_DL_ConfigurationCommon) {
LOG_I(GNB_APP, "ngran_DU: Configuring Cell %d for TDD\n", 0);
req->cell[0].info.mode = F1AP_MODE_TDD;
f1ap_tdd_info_t *tdd = &req->cell[0].info.tdd;
tdd->freqinfo.arfcn = frequencyInfoDL->absoluteFrequencyPointA;
tdd->tbw.scs = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
tdd->tbw.nrb = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
tdd->freqinfo.band = *frequencyInfoDL->frequencyBandList.list.array[0];
req->cell[0].info.tdd = read_tdd_config(scc);
} else {
LOG_I(GNB_APP, "ngran_DU: Configuring Cell %d for FDD\n", 0);
req->cell[0].info.mode = F1AP_MODE_FDD;
f1ap_fdd_info_t *fdd = &req->cell[0].info.fdd;
fdd->dl_freqinfo.arfcn = frequencyInfoDL->absoluteFrequencyPointA;
fdd->ul_freqinfo.arfcn = *scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA;
fdd->dl_tbw.scs = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
fdd->ul_tbw.scs = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
fdd->dl_tbw.nrb = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
fdd->ul_tbw.nrb = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
fdd->dl_freqinfo.band = *frequencyInfoDL->frequencyBandList.list.array[0];
fdd->ul_freqinfo.band = *scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0];
req->cell[0].info.fdd = read_fdd_config(scc);
}
req->cell[0].info.measurement_timing_information = "0";
NR_MeasurementTimingConfiguration_t *mtc = get_new_MeasurementTimingConfiguration(scc);
uint8_t buf[1024];
int len = encode_MeasurementTimingConfiguration(mtc, buf, sizeof(buf));
DevAssert(len <= sizeof(buf));
free_MeasurementTimingConfiguration(mtc);
uint8_t *mtc_buf = calloc(len, sizeof(*mtc_buf));
AssertFatal(mtc_buf != NULL, "out of memory\n");
memcpy(mtc_buf, buf, len);
req->cell[0].info.measurement_timing_config = mtc_buf;
req->cell[0].info.measurement_timing_config_len = len;
if (get_softmodem_params()->sa) {
// in NSA we don't transmit SIB1, so cannot fill DU system information
......@@ -1186,7 +1226,8 @@ static f1ap_setup_req_t *RC_read_F1Setup(uint64_t id,
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);
// encode only the mib message itself
sys_info->mib_length = encode_MIB_NR_setup(mib->message.choice.mib, 0, sys_info->mib, buf_len);
DevAssert(sys_info->mib_length == buf_len);
DevAssert(sib1 != NULL);
......
......@@ -540,13 +540,6 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant
get_ssb_subcarrier_offset(*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB,
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA,
*scc->ssbSubcarrierSpacing);
AssertFatal(cfg->ssb_table.ssb_subcarrier_offset.value < 16,
"cannot handle ssb_subcarrier_offset %d resulting from Point A %ld SSB %ld: please increase dl_absoluteFrequencyPointA "
"in the config by 16\n",
cfg->ssb_table.ssb_subcarrier_offset.value,
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA,
*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB);
cfg->ssb_table.ssb_subcarrier_offset.tl.tag = NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG;
cfg->num_tlv++;
......
......@@ -144,6 +144,12 @@ void f1_setup_failure(const f1ap_setup_failure_t *failure)
exit(1);
}
void gnb_du_configuration_update_acknowledge(const f1ap_gnb_du_configuration_update_acknowledge_t *ack)
{
(void)ack;
LOG_I(MAC, "received gNB-DU configuration update acknowledge\n");
}
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
......
......@@ -28,6 +28,7 @@
void f1_setup_response(const f1ap_setup_resp_t *resp);
void f1_setup_failure(const f1ap_setup_failure_t *failure);
void gnb_du_configuration_update_acknowledge(const f1ap_gnb_du_configuration_update_acknowledge_t *ack);
NR_CellGroupConfig_t *clone_CellGroupConfig(const NR_CellGroupConfig_t *orig);
void ue_context_setup_request(const f1ap_ue_context_setup_t *req);
void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req);
......
......@@ -26,6 +26,7 @@
#include "f1ap_messages_types.h"
typedef void (*f1_setup_request_func_t)(const f1ap_setup_req_t* req);
typedef void (*gnb_du_configuration_update_t)(const f1ap_gnb_du_configuration_update_t *upd);
typedef void (*ue_context_setup_response_func_t)(const f1ap_ue_context_setup_t* req, const f1ap_ue_context_setup_t *resp);
typedef void (*ue_context_modification_response_func_t)(const f1ap_ue_context_modif_req_t *req,
......
......@@ -39,8 +39,14 @@ static void f1_setup_request_direct(const f1ap_setup_req_t *req)
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].info.measurement_timing_config_len > 0) {
f1ap_msg->cell[n].info.measurement_timing_config = calloc(req->cell[n].info.measurement_timing_config_len, sizeof(uint8_t));
AssertFatal(f1ap_msg->cell[n].info.measurement_timing_config != NULL, "out of memory\n");
memcpy(f1ap_msg->cell[n].info.measurement_timing_config,
req->cell[n].info.measurement_timing_config,
req->cell[n].info.measurement_timing_config_len);
f1ap_msg->cell[n].info.measurement_timing_config_len = req->cell[n].info.measurement_timing_config_len;
}
if (req->cell[n].sys_info) {
f1ap_gnb_du_system_info_t *orig_sys_info = req->cell[n].sys_info;
......@@ -66,6 +72,58 @@ static void f1_setup_request_direct(const f1ap_setup_req_t *req)
itti_send_msg_to_task(TASK_RRC_GNB, 0, msg);
}
static void gnb_du_configuration_update_direct(const f1ap_gnb_du_configuration_update_t *upd)
{
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_GNB_DU_CONFIGURATION_UPDATE);
msg->ittiMsgHeader.originInstance = -1; // means monolithic
f1ap_gnb_du_configuration_update_t *f1ap_msg = &F1AP_GNB_DU_CONFIGURATION_UPDATE(msg);
DevAssert(upd->gNB_DU_ID == NULL);
f1ap_msg->transaction_id = upd->transaction_id;
DevAssert(upd->num_cells_to_add == 0);
DevAssert(upd->num_cells_to_delete == 0);
f1ap_msg->num_cells_to_modify = upd->num_cells_to_modify;
for (int n = 0; n < upd->num_cells_to_modify; ++n) {
f1ap_msg->cell_to_modify[n].old_nr_cellid = upd->cell_to_modify[n].old_nr_cellid;
f1ap_msg->cell_to_modify[n].info = upd->cell_to_modify[n].info; // copy most fields
if (upd->cell_to_modify[n].info.tac) {
f1ap_msg->cell_to_modify[n].info.tac = malloc(sizeof(*f1ap_msg->cell_to_modify[n].info.tac));
AssertFatal(f1ap_msg->cell_to_modify[n].info.tac != NULL, "out of memory\n");
*f1ap_msg->cell_to_modify[n].info.tac = *upd->cell_to_modify[n].info.tac;
}
if (upd->cell_to_modify[n].info.measurement_timing_config_len > 0) {
f1ap_msg->cell_to_modify[n].info.measurement_timing_config =
calloc(upd->cell_to_modify[n].info.measurement_timing_config_len, sizeof(uint8_t));
AssertFatal(f1ap_msg->cell_to_modify[n].info.measurement_timing_config != NULL, "out of memory\n");
memcpy(f1ap_msg->cell_to_modify[n].info.measurement_timing_config,
upd->cell_to_modify[n].info.measurement_timing_config,
upd->cell_to_modify[n].info.measurement_timing_config_len);
f1ap_msg->cell_to_modify[n].info.measurement_timing_config_len = upd->cell_to_modify[n].info.measurement_timing_config_len;
}
if (upd->cell_to_modify[n].sys_info) {
f1ap_gnb_du_system_info_t *orig_sys_info = upd->cell_to_modify[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_to_modify[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)
{
DevAssert(req->drbs_to_be_setup_length == resp->drbs_to_be_setup_length);
......@@ -227,6 +285,7 @@ static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const
void mac_rrc_ul_direct_init(struct nr_mac_rrc_ul_if_s *mac_rrc)
{
mac_rrc->f1_setup_request = f1_setup_request_direct;
mac_rrc->gnb_du_configuration_update = gnb_du_configuration_update_direct;
mac_rrc->ue_context_setup_response = ue_context_setup_response_direct;
mac_rrc->ue_context_modification_response = ue_context_modification_response_direct;
mac_rrc->ue_context_modification_required = ue_context_modification_required_direct;
......
......@@ -69,8 +69,14 @@ static void f1_setup_request_f1ap(const f1ap_setup_req_t *req)
AssertFatal(f1ap_setup->cell[n].info.tac != NULL, "out of memory\n");
*f1ap_setup->cell[n].info.tac = *req->cell[n].info.tac;
}
if (req->cell[n].info.measurement_timing_information)
f1ap_setup->cell[n].info.measurement_timing_information = strdup(req->cell[n].info.measurement_timing_information);
if (req->cell[n].info.measurement_timing_config_len > 0) {
f1ap_setup->cell[n].info.measurement_timing_config = calloc(req->cell[n].info.measurement_timing_config_len, sizeof(uint8_t));
AssertFatal(f1ap_setup->cell[n].info.measurement_timing_config != NULL, "out of memory\n");
memcpy(f1ap_setup->cell[n].info.measurement_timing_config,
req->cell[n].info.measurement_timing_config,
req->cell[n].info.measurement_timing_config_len);
f1ap_setup->cell[n].info.measurement_timing_config_len = req->cell[n].info.measurement_timing_config_len;
}
if (req->cell[n].sys_info) {
f1ap_gnb_du_system_info_t *orig_sys_info = req->cell[n].sys_info;
......@@ -98,6 +104,39 @@ static void f1_setup_request_f1ap(const f1ap_setup_req_t *req)
itti_send_msg_to_task(TASK_DU_F1, 0, msg);
}
static void gnb_du_configuration_update_f1ap(const f1ap_gnb_du_configuration_update_t *upd)
{
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_GNB_DU_CONFIGURATION_UPDATE);
f1ap_gnb_du_configuration_update_t *f1_upd = &F1AP_GNB_DU_CONFIGURATION_UPDATE(msg);
f1_upd->transaction_id = upd->transaction_id;
AssertFatal(upd->num_cells_to_add == 0, "gNB-DU config update: cells to add not supported\n");
f1_upd->num_cells_to_modify = upd->num_cells_to_modify;
for (int n = 0; n < upd->num_cells_to_modify; ++n) {
f1_upd->cell_to_modify[n].old_plmn = upd->cell_to_modify[n].old_plmn;
f1_upd->cell_to_modify[n].old_nr_cellid = upd->cell_to_modify[n].old_nr_cellid;
f1_upd->cell_to_modify[n].info = upd->cell_to_modify[n].info;
if (upd->cell_to_modify[n].sys_info) {
f1ap_gnb_du_system_info_t *orig_sys_info = upd->cell_to_modify[n].sys_info;
f1ap_gnb_du_system_info_t *copy_sys_info = calloc(1, sizeof(*copy_sys_info));
f1_upd->cell_to_modify[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;
}
}
}
AssertFatal(upd->num_cells_to_delete == 0, "gNB-DU config update: cells to add not supported\n");
itti_send_msg_to_task(TASK_DU_F1, 0, msg);
}
static void ue_context_setup_response_f1ap(const f1ap_ue_context_setup_t *req, const f1ap_ue_context_setup_t *resp)
{
DevAssert(req->drbs_to_be_setup_length == resp->drbs_to_be_setup_length);
......@@ -237,6 +276,7 @@ static void initial_ul_rrc_message_transfer_f1ap(module_id_t module_id, const f1
void mac_rrc_ul_f1ap_init(struct nr_mac_rrc_ul_if_s *mac_rrc)
{
mac_rrc->f1_setup_request = f1_setup_request_f1ap;
mac_rrc->gnb_du_configuration_update = gnb_du_configuration_update_f1ap;
mac_rrc->ue_context_setup_response = ue_context_setup_response_f1ap;
mac_rrc->ue_context_modification_response = ue_context_modification_response_f1ap;
mac_rrc->ue_context_modification_required = ue_context_modification_required_f1ap;
......
......@@ -660,6 +660,7 @@ typedef struct NR_bler_options {
typedef struct nr_mac_rrc_ul_if_s {
f1_setup_request_func_t f1_setup_request;
gnb_du_configuration_update_t gnb_du_configuration_update;
ue_context_setup_response_func_t ue_context_setup_response;
ue_context_modification_response_func_t ue_context_modification_response;
ue_context_modification_required_func_t ue_context_modification_required;
......
......@@ -1093,8 +1093,12 @@ int do_RRCReestablishmentComplete(uint8_t *buffer, size_t buffer_size, int64_t r
return((enc_rval.encoded+7)/8);
}
NR_MeasConfig_t *get_defaultMeasConfig(uint32_t ssb_arfcn, int band, int scs)
NR_MeasConfig_t *get_defaultMeasConfig(const NR_MeasTiming_t *mt, int band, int scs)
{
DevAssert(mt != NULL && mt->frequencyAndTiming != NULL);
const struct NR_MeasTiming__frequencyAndTiming *ft = mt->frequencyAndTiming;
const NR_SSB_MTC_t *ssb_mtc = &ft->ssb_MeasurementTimingConfiguration;
NR_MeasConfig_t *mc = calloc(1, sizeof(*mc));
mc->measObjectToAddModList = calloc(1, sizeof(*mc->measObjectToAddModList));
mc->reportConfigToAddModList = calloc(1, sizeof(*mc->reportConfigToAddModList));
......@@ -1105,17 +1109,16 @@ NR_MeasConfig_t *get_defaultMeasConfig(uint32_t ssb_arfcn, int band, int scs)
mo1->measObjectId = 1;
mo1->measObject.present = NR_MeasObjectToAddMod__measObject_PR_measObjectNR;
NR_MeasObjectNR_t *monr1 = calloc(1, sizeof(*monr1));
asn1cCallocOne(monr1->ssbFrequency, ssb_arfcn);
asn1cCallocOne(monr1->ssbSubcarrierSpacing, scs);
asn1cCallocOne(monr1->ssbFrequency, ft->carrierFreq);
asn1cCallocOne(monr1->ssbSubcarrierSpacing, ft->ssbSubcarrierSpacing);
monr1->referenceSignalConfig.ssb_ConfigMobility = calloc(1, sizeof(*monr1->referenceSignalConfig.ssb_ConfigMobility));
monr1->referenceSignalConfig.ssb_ConfigMobility->deriveSSB_IndexFromCell = true;
monr1->absThreshSS_BlocksConsolidation = calloc(1, sizeof(*monr1->absThreshSS_BlocksConsolidation));
asn1cCallocOne(monr1->absThreshSS_BlocksConsolidation->thresholdRSRP, 36);
asn1cCallocOne(monr1->nrofSS_BlocksToAverage, 8);
monr1->smtc1 = calloc(1, sizeof(*monr1->smtc1));
monr1->smtc1->periodicityAndOffset.present = NR_SSB_MTC__periodicityAndOffset_PR_sf20;
monr1->smtc1->periodicityAndOffset.choice.sf20 = 2;
monr1->smtc1->duration = NR_SSB_MTC__duration_sf2;
monr1->smtc1->periodicityAndOffset = ssb_mtc->periodicityAndOffset;
monr1->smtc1->duration = ssb_mtc->duration;
monr1->quantityConfigIndex = 1;
monr1->ext1 = calloc(1, sizeof(*monr1->ext1));
asn1cCallocOne(monr1->ext1->freqBandIndicatorNR, band);
......
......@@ -143,7 +143,7 @@ int do_RRCReestablishment(rrc_gNB_ue_context_t *const ue_context_pP,
int do_RRCReestablishmentComplete(uint8_t *buffer, size_t buffer_size, int64_t rrc_TransactionIdentifier);
NR_MeasConfig_t *get_defaultMeasConfig(uint32_t absFreqSSB, int band, int scs);
NR_MeasConfig_t *get_defaultMeasConfig(const NR_MeasTiming_t *mt, int band, int scs);
void free_defaultMeasConfig(NR_MeasConfig_t *mc);
uint8_t do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi);
......
......@@ -27,6 +27,8 @@
typedef void (*f1_setup_response_func_t)(sctp_assoc_t assoc_id, const f1ap_setup_resp_t *resp);
typedef void (*f1_setup_failure_func_t)(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *fail);
typedef void (*gnb_du_configuration_update_ack_func_t)(sctp_assoc_t assoc_id,
const f1ap_gnb_du_configuration_update_acknowledge_t *ack);
typedef void (*ue_context_setup_request_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_setup_t *req);
typedef void (*ue_context_modification_request_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_req_t *req);
......
......@@ -36,6 +36,12 @@ static void f1_setup_failure_direct(sctp_assoc_t assoc_id, const f1ap_setup_fail
f1_setup_failure(fail);
}
static void gnb_du_configuration_update_ack_direct(sctp_assoc_t assoc_id, const f1ap_gnb_du_configuration_update_acknowledge_t *ack)
{
AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id);
gnb_du_configuration_update_acknowledge(ack);
}
static void ue_context_setup_request_direct(sctp_assoc_t assoc_id, const f1ap_ue_context_setup_t *req)
{
AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id);
......@@ -76,6 +82,7 @@ void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc)
{
mac_rrc->f1_setup_response = f1_setup_response_direct;
mac_rrc->f1_setup_failure = f1_setup_failure_direct;
mac_rrc->gnb_du_configuration_update_acknowledge = gnb_du_configuration_update_ack_direct;
mac_rrc->ue_context_setup_request = ue_context_setup_request_direct;
mac_rrc->ue_context_modification_request = ue_context_modification_request_direct;
mac_rrc->ue_context_modification_confirm = ue_context_modification_confirm_direct;
......
......@@ -44,6 +44,15 @@ static void f1_setup_failure_f1ap(sctp_assoc_t assoc_id, const f1ap_setup_failur
itti_send_msg_to_task(TASK_CU_F1, 0, msg);
}
static void gnb_du_configuration_update_ack_f1ap(sctp_assoc_t assoc_id, const f1ap_gnb_du_configuration_update_acknowledge_t *ack)
{
MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE);
msg->ittiMsgHeader.originInstance = assoc_id;
f1ap_gnb_du_configuration_update_acknowledge_t *f1ap_msg = &F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg);
*f1ap_msg = *ack;
itti_send_msg_to_task(TASK_CU_F1, 0, msg);
}
static void ue_context_setup_request_f1ap(sctp_assoc_t assoc_id, const f1ap_ue_context_setup_t *req)
{
MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_SETUP_REQ);
......@@ -208,6 +217,7 @@ void mac_rrc_dl_f1ap_init(nr_mac_rrc_dl_if_t *mac_rrc)
{
mac_rrc->f1_setup_response = f1_setup_response_f1ap;
mac_rrc->f1_setup_failure = f1_setup_failure_f1ap;
mac_rrc->gnb_du_configuration_update_acknowledge = gnb_du_configuration_update_ack_f1ap;
mac_rrc->ue_context_setup_request = ue_context_setup_request_f1ap;
mac_rrc->ue_context_modification_request = ue_context_modification_request_f1ap;
mac_rrc->ue_context_modification_confirm = ue_context_modification_confirm_f1ap;
......
......@@ -36,6 +36,8 @@
#include "oai_asn1.h"
#include "SIMULATION/TOOLS/sim.h" // for taus();
#include "NR_MeasurementTimingConfiguration.h"
#include "uper_decoder.h"
#include "uper_encoder.h"
......@@ -1875,6 +1877,95 @@ int encode_MIB_NR(NR_BCCH_BCH_Message_t *mib, int frame, uint8_t *buf, int buf_s
return (enc_rval.encoded + 7) / 8;
}
int encode_MIB_NR_setup(NR_MIB_t *mib, int frame, uint8_t *buf, int buf_size)
{
DevAssert(mib != NULL);
uint8_t sfn_msb = (uint8_t)((frame >> 4) & 0x3f);
*mib->systemFrameNumber.buf = sfn_msb << 2;
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_MIB, NULL, mib, buf, buf_size);
AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
LOG_D(NR_RRC, "Encoded MIB for frame %d sfn_msb %d, bits %lu\n", frame, sfn_msb, enc_rval.encoded);
return (enc_rval.encoded + 7) / 8;
}
static struct NR_SSB_MTC__periodicityAndOffset get_SSB_MTC_periodicityAndOffset(long ssb_periodicityServingCell)
{
struct NR_SSB_MTC__periodicityAndOffset po = {0};
switch (ssb_periodicityServingCell) {
case NR_ServingCellConfigCommon__ssb_periodicityServingCell_ms5:
po.present = NR_SSB_MTC__periodicityAndOffset_PR_sf5;
po.choice.sf5 = 0;
break;
case NR_ServingCellConfigCommon__ssb_periodicityServingCell_ms10:
po.present = NR_SSB_MTC__periodicityAndOffset_PR_sf10;
po.choice.sf10 = 0;
break;
case NR_ServingCellConfigCommon__ssb_periodicityServingCell_ms20:
po.present = NR_SSB_MTC__periodicityAndOffset_PR_sf20;
po.choice.sf20 = 0;
break;
case NR_ServingCellConfigCommon__ssb_periodicityServingCell_ms40:
po.present = NR_SSB_MTC__periodicityAndOffset_PR_sf40;
po.choice.sf40 = 0;
break;
case NR_ServingCellConfigCommon__ssb_periodicityServingCell_ms80:
po.present = NR_SSB_MTC__periodicityAndOffset_PR_sf80;
po.choice.sf80 = 0;
break;
case NR_ServingCellConfigCommon__ssb_periodicityServingCell_ms160:
po.present = NR_SSB_MTC__periodicityAndOffset_PR_sf160;
po.choice.sf160 = 0;
break;
default:
AssertFatal(false, "illegal ssb_periodicityServingCell %ld\n", ssb_periodicityServingCell);
break;
}
return po;
}
NR_MeasurementTimingConfiguration_t *get_new_MeasurementTimingConfiguration(const NR_ServingCellConfigCommon_t *scc)
{
NR_MeasurementTimingConfiguration_t *mtc = calloc(1, sizeof(*mtc));
AssertFatal(mtc != NULL, "out of memory\n");
mtc->criticalExtensions.present = NR_MeasurementTimingConfiguration__criticalExtensions_PR_c1;
mtc->criticalExtensions.choice.c1 = calloc(1, sizeof(*mtc->criticalExtensions.choice.c1));
AssertFatal(mtc->criticalExtensions.choice.c1 != NULL, "out of memory\n");
mtc->criticalExtensions.choice.c1->present = NR_MeasurementTimingConfiguration__criticalExtensions__c1_PR_measTimingConf;
NR_MeasurementTimingConfiguration_IEs_t *mtc_ie = calloc(1, sizeof(*mtc_ie));
AssertFatal(mtc_ie != NULL, "out of memory\n");
mtc->criticalExtensions.choice.c1->choice.measTimingConf = mtc_ie;
mtc_ie->measTiming = calloc(1, sizeof(*mtc_ie->measTiming));
AssertFatal(mtc_ie->measTiming != NULL, "out of memory\n");
asn1cSequenceAdd(mtc_ie->measTiming->list, NR_MeasTiming_t, mt);
AssertFatal(mt != NULL, "out of memory\n");
mt->frequencyAndTiming = calloc(1, sizeof(*mt->frequencyAndTiming));
AssertFatal(mt->frequencyAndTiming != NULL, "out of memory\n");
mt->frequencyAndTiming->carrierFreq = *scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB;
mt->frequencyAndTiming->ssbSubcarrierSpacing = *scc->ssbSubcarrierSpacing;
NR_SSB_MTC_t *ssb_mtc = &mt->frequencyAndTiming->ssb_MeasurementTimingConfiguration;
ssb_mtc->duration = NR_SSB_MTC__duration_sf1;
ssb_mtc->periodicityAndOffset = get_SSB_MTC_periodicityAndOffset(*scc->ssb_periodicityServingCell);
return mtc;
}
int encode_MeasurementTimingConfiguration(const struct NR_MeasurementTimingConfiguration *mtc, uint8_t *buf, int buf_len)
{
DevAssert(mtc != NULL);
xer_fprint(stdout, &asn_DEF_NR_MeasurementTimingConfiguration, mtc);
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_MeasurementTimingConfiguration, NULL, mtc, buf, buf_len);
AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
return (enc_rval.encoded + 7) / 8;
}
void free_MeasurementTimingConfiguration(NR_MeasurementTimingConfiguration_t *mtc)
{
ASN_STRUCT_FREE(asn_DEF_NR_MeasurementTimingConfiguration, mtc);
}
NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc, const f1ap_plmn_t *plmn, uint64_t cellID, int tac)
{
AssertFatal(cellID < (1l << 36), "cellID must fit within 36 bits, but is %lu\n", cellID);
......
......@@ -55,7 +55,12 @@ void prepare_sim_uecap(NR_UE_NR_Capability_t *cap,
NR_BCCH_BCH_Message_t *get_new_MIB_NR(const NR_ServingCellConfigCommon_t *scc);
void free_MIB_NR(NR_BCCH_BCH_Message_t *mib);
int encode_MIB_NR(NR_BCCH_BCH_Message_t *mib, int frame, uint8_t *buf, int buf_size);
int encode_MIB_NR_setup(NR_MIB_t *mib, int frame, uint8_t *buf, int buf_size);
struct NR_MeasurementTimingConfiguration;
struct NR_MeasurementTimingConfiguration *get_new_MeasurementTimingConfiguration(const NR_ServingCellConfigCommon_t *scc);
int encode_MeasurementTimingConfiguration(const struct NR_MeasurementTimingConfiguration *mtc, uint8_t *buf, int buf_len);
void free_MeasurementTimingConfiguration(struct NR_MeasurementTimingConfiguration *mtc);
#define NR_MAX_SIB_LENGTH 2976 // 3GPP TS 38.331 section 5.2.1
NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc, const f1ap_plmn_t *plmn, uint64_t cellID, int tac);
......
......@@ -62,6 +62,7 @@
#include "NR_CellGroupConfig.h"
#include "NR_ServingCellConfigCommon.h"
#include "NR_EstablishmentCause.h"
#include "NR_MeasurementTimingConfiguration.h"
//-------------------
......@@ -240,7 +241,6 @@ typedef enum {
RRC_SETUP_FOR_REESTABLISHMENT,
RRC_REESTABLISH,
RRC_REESTABLISH_COMPLETE,
RRC_DEFAULT_RECONF,
RRC_DEDICATED_RECONF,
RRC_PDUSESSION_ESTABLISH,
RRC_PDUSESSION_MODIFY,
......@@ -260,6 +260,7 @@ typedef struct gNB_RRC_UE_s {
NR_MeasResults_t *measResults;
bool as_security_active;
bool f1_ue_context_active;
byte_array_t ue_cap_buffer;
NR_UE_NR_Capability_t* UE_Capability_nr;
......@@ -318,12 +319,14 @@ typedef struct gNB_RRC_UE_s {
uint32_t ue_reconfiguration_counter;
struct NR_SpCellConfig *spCellConfig;
/* NGUEContextSetup might come with PDU sessions, but setup needs to be
* delayed after security (and capability); PDU sessions are stored here */
int n_initial_pdu;
pdusession_t *initial_pdus;
/* Nas Pdu */
ngap_pdu_t nas_pdu;
/* hack, see rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ() for more info */
int max_delays_pdu_session;
} gNB_RRC_UE_t;
typedef struct rrc_gNB_ue_context_s {
......@@ -359,6 +362,7 @@ typedef struct {
typedef struct nr_mac_rrc_dl_if_s {
f1_setup_response_func_t f1_setup_response;
f1_setup_failure_func_t f1_setup_failure;
gnb_du_configuration_update_ack_func_t gnb_du_configuration_update_acknowledge;
ue_context_setup_request_func_t ue_context_setup_request;
ue_context_modification_request_func_t ue_context_modification_request;
ue_context_modification_confirm_func_t ue_context_modification_confirm;
......@@ -381,6 +385,7 @@ typedef struct nr_rrc_du_container_t {
f1ap_setup_req_t *setup_req;
NR_MIB_t *mib;
NR_SIB1_t *sib1;
NR_MeasurementTimingConfiguration_t *mtc;
} nr_rrc_du_container_t;
typedef struct nr_rrc_cuup_container_t {
......
......@@ -80,13 +80,7 @@ int generate_CG_Config(gNB_RRC_INST *rrc,
int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2ap_ENDC_sgnb_addition_req_t *m);
void
rrc_gNB_generate_SecurityModeCommand(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
int n_drbs,
const f1ap_drb_to_be_setup_t *drbs
);
void rrc_gNB_generate_SecurityModeCommand(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP);
unsigned int rrc_gNB_get_next_transaction_identifier(module_id_t gnb_mod_idP);
......@@ -165,8 +159,25 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
uint8_t *const kUPenc,
uint8_t *const kUPint);
void trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession_t *sessions, uint64_t ueAggMaxBitRateDownlink);
int rrc_gNB_generate_pcch_msg(sctp_assoc_t assoc_id, const NR_SIB1_t *sib, uint32_t tmsi, uint8_t paging_drx);
void nr_rrc_transfer_protected_rrc_message(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue_p, uint8_t srb_id, const uint8_t* buffer, int size);
/** @}*/
/* UE Management Procedures */
void rrc_gNB_generate_UeContextSetupRequest(const gNB_RRC_INST *rrc,
rrc_gNB_ue_context_t *const ue_context_pP,
int n_drbs,
const f1ap_drb_to_be_setup_t *drbs);
void rrc_gNB_generate_UeContextModificationRequest(const gNB_RRC_INST *rrc,
rrc_gNB_ue_context_t *const ue_context_pP,
int n_drbs,
const f1ap_drb_to_be_setup_t *drbs,
int n_rel_drbs,
const f1ap_drb_to_be_released_t *rel_drbs);
#endif
This diff is collapsed.
......@@ -362,7 +362,7 @@ static int decodePDUSessionResourceSetup(pdusession_t *session)
return 0;
}
static void trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession_t *sessions, uint64_t ueAggMaxBitRateDownlink)
void trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession_t *sessions, uint64_t ueAggMaxBitRateDownlink)
{
e1ap_bearer_setup_req_t bearer_req = {0};
......@@ -493,18 +493,15 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t
/* configure only integrity, ciphering comes after receiving SecurityModeComplete */
nr_rrc_pdcp_config_security(&ctxt, ue_context_p, 0);
uint8_t nb_pdusessions_tosetup = req->nb_of_pdusessions;
/* if there are PDU sessions to setup, first send them to the CU-UP, then
* send the UE Context setup with Security commend. Else go to the security
* command directly. */
if (nb_pdusessions_tosetup > 0) {
trigger_bearer_setup(RC.nrrrc[instance],
UE,
req->nb_of_pdusessions,
req->pdusession_param,
/*req->ueAggMaxBitRateDownlink*/ 0);
} else {
rrc_gNB_generate_SecurityModeCommand(&ctxt, ue_context_p, 0, NULL);
rrc_gNB_generate_SecurityModeCommand(&ctxt, ue_context_p);
if (req->nb_of_pdusessions > 0) {
/* if there are PDU sessions to setup, store them to be created once
* security (and UE capabilities) are received */
UE->n_initial_pdu = req->nb_of_pdusessions;
UE->initial_pdus = calloc(UE->n_initial_pdu, sizeof(*UE->initial_pdus));
AssertFatal(UE->initial_pdus != NULL, "out of memory\n");
for (int i = 0; i < UE->n_initial_pdu; ++i)
UE->initial_pdus[i] = req->pdusession_param[i];
}
return 0;
......@@ -814,28 +811,6 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
return;
}
/* \brief checks if any transaction is ongoing for any xid of this UE */
static bool transaction_ongoing(const gNB_RRC_UE_t *UE)
{
for (int xid = 0; xid < 4; ++xid)
if (UE->xids[xid] != RRC_ACTION_NONE)
return true;
return false;
}
/* \brief delays the ongoing transaction (in msg_p) by setting a timer to wait
* 10ms; upon expiry, delivers to RRC, which sends the message to itself */
static void delay_transaction(MessageDef *msg_p, int wait_us)
{
MessageDef *new = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_PDUSESSION_SETUP_REQ);
ngap_pdusession_setup_req_t *n = &NGAP_PDUSESSION_SETUP_REQ(new);
*n = NGAP_PDUSESSION_SETUP_REQ(msg_p);
int instance = msg_p->ittiMsgHeader.originInstance;
long timer_id;
timer_setup(0, wait_us, TASK_RRC_GNB, instance, TIMER_ONE_SHOT, new, &timer_id);
}
//------------------------------------------------------------------------------
void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t instance)
//------------------------------------------------------------------------------
......@@ -861,24 +836,6 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins
AssertFatal(UE->rrc_ue_id == msg->gNB_ue_ngap_id, "logic bug\n");
UE->amf_ue_ngap_id = msg->amf_ue_ngap_id;
/* This is a hack. We observed that with some UEs, PDU session requests might
* come in quick succession, faster than the RRC reconfiguration for the PDU
* session requests can be carried out (UE is doing reconfig, and second PDU
* session request arrives). We don't have currently the means to "queue up"
* these transactions, which would probably involve some rework of the RRC.
* To still allow these requests to come in and succeed, we below check and delay transactions
* for 10ms. However, to not accidentally end up in infinite loops, the
* maximum number is capped on a per-UE basis as indicated in variable
* max_delays_pdu_session. */
if (UE->max_delays_pdu_session > 0 && transaction_ongoing(UE)) {
int wait_us = 10000;
LOG_D(RRC, "UE %d: delay PDU session setup by %d us, pending %d retries\n", UE->rrc_ue_id, wait_us, UE->max_delays_pdu_session);
delay_transaction(msg_p, wait_us);
UE->max_delays_pdu_session--;
return;
}
trigger_bearer_setup(rrc, UE, msg->nb_pdusessions_tosetup, msg->pdusession_setup_params, msg->ueAggMaxBitRateDownlink);
return;
}
......@@ -1207,13 +1164,10 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_
if (ue_context_p == NULL) {
/* Can not associate this message to an UE index */
MessageDef *msg_complete_p = NULL;
LOG_W(NR_RRC, "[gNB %ld] In NGAP_UE_CONTEXT_RELEASE_COMMAND: unknown UE from gNB_ue_ngap_id (%u)\n",
instance,
gNB_ue_ngap_id);
msg_complete_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_COMPLETE);
NGAP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).gNB_ue_ngap_id = gNB_ue_ngap_id;
itti_send_msg_to_task(TASK_NGAP, instance, msg_complete_p);
rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance, gNB_ue_ngap_id, 0, NULL);
return -1;
}
......@@ -1249,11 +1203,17 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_
return 0;
}
void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(
instance_t instance,
uint32_t gNB_ue_ngap_id) {
void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
uint32_t gNB_ue_ngap_id,
int num_pdu,
uint32_t pdu_session_id[256])
{
MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_COMPLETE);
NGAP_UE_CONTEXT_RELEASE_COMPLETE(msg).gNB_ue_ngap_id = gNB_ue_ngap_id;
NGAP_UE_CONTEXT_RELEASE_COMPLETE(msg).num_pdu_sessions = num_pdu;
for (int i = 0; i < num_pdu; ++i)
NGAP_UE_CONTEXT_RELEASE_COMPLETE(msg).pdu_session_id[i] = pdu_session_id[i];
LOG_W(RRC, "trigger release with %d pdu\n", num_pdu);
itti_send_msg_to_task(TASK_NGAP, instance, msg);
}
......
......@@ -94,7 +94,10 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ(MessageDef *msg_p, instance_t in
int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_t instance);
void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, uint32_t gNB_ue_ngap_id);
void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
uint32_t gNB_ue_ngap_id,
int num_pdu,
uint32_t pdu_session_id[256]);
void rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
......
......@@ -202,7 +202,6 @@ rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(sctp_assoc_t assoc_id,
"UE F1 Context for ID %d already exists, logic bug\n",
ue->rrc_ue_id);
cu_add_f1_ue_data(ue->rrc_ue_id, &ue_data);
ue->max_delays_pdu_session = 20; /* see rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ() */
RB_INSERT(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_p);
LOG_I(NR_RRC,
......
This diff is collapsed.
......@@ -31,9 +31,11 @@ struct f1ap_setup_req_s;
struct f1ap_lost_connection_t;
struct gNB_RRC_INST_s;
struct nr_rrc_du_container_t;
struct f1ap_gnb_du_configuration_update_s;
void rrc_gNB_process_f1_setup_req(struct f1ap_setup_req_s *req, sctp_assoc_t assoc_id);
void rrc_CU_process_f1_lost_connection(struct gNB_RRC_INST_s *rrc, struct f1ap_lost_connection_t *lc, sctp_assoc_t assoc_id);
void rrc_gNB_process_f1_du_configuration_update(struct f1ap_gnb_du_configuration_update_s *conf_up, sctp_assoc_t assoc_id);
struct nr_rrc_du_container_t *get_du_for_ue(struct gNB_RRC_INST_s *rrc, uint32_t ue_id);
struct nr_rrc_du_container_t *get_du_by_assoc_id(struct gNB_RRC_INST_s *rrc, sctp_assoc_t assoc_id);
......
......@@ -50,7 +50,7 @@
#include "ngap_gNB_management_procedures.h"
#include "ngap_gNB_context_management_procedures.h"
#include "NGAP_PDUSessionResourceItemCxtRelReq.h"
#include "NGAP_PDUSessionResourceItemCxtRelCpl.h"
int ngap_ue_context_release_complete(instance_t instance,
ngap_ue_release_complete_t *ue_release_complete_p)
......@@ -100,6 +100,20 @@ int ngap_ue_context_release_complete(instance_t instance,
ie->value.choice.RAN_UE_NGAP_ID = ue_release_complete_p->gNB_ue_ngap_id;
}
/* number of PDU sessions */
if (ue_release_complete_p->num_pdu_sessions > 0) {
asn1cSequenceAdd(out->protocolIEs.list, NGAP_UEContextReleaseComplete_IEs_t, ie);
ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceListCxtRelCpl;
ie->criticality = NGAP_Criticality_reject;
ie->value.present = NGAP_UEContextReleaseComplete_IEs__value_PR_PDUSessionResourceListCxtRelCpl;
NGAP_PDUSessionResourceListCxtRelCpl_t *l = &ie->value.choice.PDUSessionResourceListCxtRelCpl;
DevAssert(ue_release_complete_p->num_pdu_sessions <= 256);
for (int i = 0; i < ue_release_complete_p->num_pdu_sessions; ++i) {
asn1cSequenceAdd(l->list, NGAP_PDUSessionResourceItemCxtRelCpl_t, pdu);
pdu->pDUSessionID = ue_release_complete_p->pdu_session_id[i];
}
}
if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) {
/* Encode procedure has failed... */
NGAP_ERROR("Failed to encode UE context release complete\n");
......
......@@ -190,18 +190,22 @@ do { \
(aSN)->bits_unused = 0; \
} while(0)
#define AMF_SETID_TO_BIT_STRING(x, aSN) \
do { \
INT16_TO_OCTET_STRING(x, aSN); \
(aSN)->bits_unused = 6; \
} while(0)
#define AMF_POINTER_TO_BIT_STRING(x, aSN) \
do { \
INT8_TO_OCTET_STRING(x, aSN); \
(aSN)->bits_unused = 2; \
} while(0)
#define AMF_SETID_TO_BIT_STRING(x, aSN) \
do { \
(aSN)->buf = calloc(2, sizeof(uint8_t)); \
(aSN)->buf[0] = ((x) >> 2) & 0xff; \
(aSN)->buf[1] = ((x) & 0x03) << 6; \
(aSN)->size = 2; \
(aSN)->bits_unused = 6; \
} while (0)
#define AMF_POINTER_TO_BIT_STRING(x, aSN) \
do { \
(aSN)->buf = calloc(1, sizeof(uint8_t)); \
(aSN)->buf[0] = ((x) & 0x3f) << 2; \
(aSN)->size = 1; \
(aSN)->bits_unused = 2; \
} while (0)
#define ENCRALG_TO_BIT_STRING(encralg, bitstring) \
do { \
......
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