Merge remote-tracking branch 'origin/int-f1-ue-ctxt-modif-req' into integration_2023_w34
This commit is contained in:
+3
-6
@@ -1403,9 +1403,6 @@ if(E2_AGENT)
|
||||
endif()
|
||||
|
||||
|
||||
add_library(MAC_NR ${MAC_NR_SRC})
|
||||
target_link_libraries(MAC_NR PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
|
||||
|
||||
add_library(MAC_UE_NR ${MAC_NR_SRC_UE})
|
||||
target_link_libraries(MAC_UE_NR PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
|
||||
|
||||
@@ -2233,7 +2230,7 @@ add_executable(nr_dlsim
|
||||
${PHY_INTERFACE_DIR}/queue_t.c
|
||||
)
|
||||
target_link_libraries(nr_dlsim PRIVATE
|
||||
-Wl,--start-group UTIL SIMU SIMU_ETH PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON nr_rrc CONFIG_LIB L2_NR HASHTABLE x2ap SECURITY ngap -lz -Wl,--end-group
|
||||
-Wl,--start-group UTIL SIMU SIMU_ETH PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON nr_rrc CONFIG_LIB L2_NR HASHTABLE x2ap SECURITY ngap -lz -Wl,--end-group
|
||||
m pthread ${T_LIB} ITTI dl shlib_loader
|
||||
)
|
||||
target_link_libraries(nr_dlsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
|
||||
@@ -2277,7 +2274,7 @@ if (ENABLE_LDPC_T1)
|
||||
endif()
|
||||
|
||||
target_link_libraries(nr_ulsim PRIVATE
|
||||
-Wl,--start-group UTIL SIMU SIMU_ETH PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON nr_rrc CONFIG_LIB L2_NR HASHTABLE x2ap SECURITY ngap -lz -Wl,--end-group
|
||||
-Wl,--start-group UTIL SIMU SIMU_ETH PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON nr_rrc CONFIG_LIB L2_NR HASHTABLE x2ap SECURITY ngap -lz -Wl,--end-group
|
||||
m pthread ${T_LIB} ITTI dl shlib_loader
|
||||
)
|
||||
target_link_libraries(nr_ulsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
|
||||
@@ -2339,7 +2336,7 @@ if (${T_TRACER})
|
||||
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB
|
||||
MISC_NFAPI_LTE_LIB MISC_NFAPI_NR_LIB
|
||||
PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU PHY_MEX
|
||||
L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON MAC_NR MAC_UE_NR ngap
|
||||
L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON MAC_UE_NR ngap
|
||||
CN_UTILS GTPV1U SCTP_CLIENT MME_APP LIB_NAS_UE NB_IoT SIMU SIMU_ETH OPENAIR0_LIB
|
||||
ldpc_orig ldpc_optim ldpc_optim8seg ldpc dfts)
|
||||
if (TARGET ${i})
|
||||
|
||||
@@ -43,7 +43,7 @@ services:
|
||||
container_name: sa-du-b200-gnb
|
||||
environment:
|
||||
USE_B2XX: 'yes'
|
||||
USE_ADDITIONAL_OPTIONS: --sa --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx -E --log_config.global_log_options level,nocolor,time,line_num,function --gNBs.[0].min_rxtxtime 2 --gNBs.[0].do_CSIRS 1 --gNBs.[0].do_SRS 1 --RUs.[0].att_rx 14 --RUs.[0].att_tx 14
|
||||
USE_ADDITIONAL_OPTIONS: --sa --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx -E --log_config.global_log_options level,nocolor,time,line_num,function --gNBs.[0].min_rxtxtime 2 --gNBs.[0].do_CSIRS 1 --gNBs.[0].do_SRS 1 --RUs.[0].att_rx 18 --RUs.[0].att_tx 18
|
||||
volumes:
|
||||
- ../../conf_files/gnb-du.sa.band78.106prb.usrpb200.conf:/opt/oai-gnb/etc/gnb.conf
|
||||
- /dev:/dev
|
||||
|
||||
@@ -26,7 +26,7 @@ services:
|
||||
container_name: sa-du-b200-gnb
|
||||
environment:
|
||||
USE_B2XX: 'yes'
|
||||
USE_ADDITIONAL_OPTIONS: --sa --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx -E --telnetsrv --telnetsrv.shrmod ci --log_config.global_log_options level,nocolor,time,line_num,function --gNBs.[0].min_rxtxtime 2 --gNBs.[0].do_CSIRS 1 --gNBs.[0].do_SRS 1 --RUs.[0].att_rx 14 --RUs.[0].att_tx 14
|
||||
USE_ADDITIONAL_OPTIONS: --sa --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx -E --telnetsrv --telnetsrv.shrmod ci --log_config.global_log_options level,nocolor,time,line_num,function --gNBs.[0].min_rxtxtime 2 --gNBs.[0].do_CSIRS 1 --gNBs.[0].do_SRS 1 --RUs.[0].att_rx 18 --RUs.[0].att_tx 18
|
||||
volumes:
|
||||
- ../../conf_files/gnb-du.sa.band78.106prb.usrpb200.conf:/opt/oai-gnb/etc/gnb.conf
|
||||
- /dev:/dev
|
||||
|
||||
@@ -40,6 +40,7 @@ MESSAGE_DEF(F1AP_UL_RRC_MESSAGE , MESSAGE_PRIORITY_MED, f1ap_ul_r
|
||||
MESSAGE_DEF(F1AP_UE_CONTEXT_RELEASE_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_release_req_t, f1ap_ue_context_release_req)
|
||||
MESSAGE_DEF(F1AP_UE_CONTEXT_RELEASE_CMD, MESSAGE_PRIORITY_MED, f1ap_ue_context_release_cmd_t, f1ap_ue_context_release_cmd)
|
||||
MESSAGE_DEF(F1AP_UE_CONTEXT_RELEASE_COMPLETE, MESSAGE_PRIORITY_MED, f1ap_ue_context_release_complete_t, f1ap_ue_context_release_complete)
|
||||
MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_REQUIRED, MESSAGE_PRIORITY_MED, f1ap_ue_context_modif_required_t, f1ap_ue_context_modification_required)
|
||||
|
||||
/* RRC -> F1AP messages */
|
||||
MESSAGE_DEF(F1AP_DL_RRC_MESSAGE , MESSAGE_PRIORITY_MED, f1ap_dl_rrc_message_t , f1ap_dl_rrc_message )
|
||||
@@ -48,6 +49,8 @@ MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_se
|
||||
MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_setup_resp)
|
||||
MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_modif_req_t, f1ap_ue_context_modification_req)
|
||||
MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_modif_resp_t, f1ap_ue_context_modification_resp)
|
||||
MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_CONFIRM, MESSAGE_PRIORITY_MED, f1ap_ue_context_modif_confirm_t, f1ap_ue_context_modification_confirm)
|
||||
MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_REFUSE, MESSAGE_PRIORITY_MED, f1ap_ue_context_modif_refuse_t, f1ap_ue_context_modification_refuse)
|
||||
|
||||
/* CU -> DU*/
|
||||
MESSAGE_DEF(F1AP_PAGING_IND, MESSAGE_PRIORITY_MED, f1ap_paging_ind_t, f1ap_paging_ind)
|
||||
|
||||
@@ -44,6 +44,9 @@
|
||||
#define F1AP_UE_CONTEXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_req
|
||||
#define F1AP_UE_CONTEXT_MODIFICATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_resp
|
||||
#define F1AP_UE_CONTEXT_MODIFICATION_FAIL(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_fail
|
||||
#define F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_required
|
||||
#define F1AP_UE_CONTEXT_MODIFICATION_CONFIRM(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_confirm
|
||||
#define F1AP_UE_CONTEXT_MODIFICATION_REFUSE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_refuse
|
||||
|
||||
#define F1AP_DL_RRC_MESSAGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_dl_rrc_message
|
||||
#define F1AP_UE_CONTEXT_RELEASE_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_req
|
||||
@@ -417,6 +420,28 @@ typedef enum F1ap_Cause_e {
|
||||
F1AP_CAUSE_MISC,
|
||||
} f1ap_Cause_t;
|
||||
|
||||
typedef struct f1ap_ue_context_modif_required_t {
|
||||
uint32_t gNB_CU_ue_id;
|
||||
uint32_t gNB_DU_ue_id;
|
||||
du_to_cu_rrc_information_t *du_to_cu_rrc_information;
|
||||
f1ap_Cause_t cause;
|
||||
long cause_value;
|
||||
} f1ap_ue_context_modif_required_t;
|
||||
|
||||
typedef struct f1ap_ue_context_modif_confirm_t {
|
||||
uint32_t gNB_CU_ue_id;
|
||||
uint32_t gNB_DU_ue_id;
|
||||
uint8_t *rrc_container;
|
||||
int rrc_container_length;
|
||||
} f1ap_ue_context_modif_confirm_t;
|
||||
|
||||
typedef struct f1ap_ue_context_modif_refuse_t {
|
||||
uint32_t gNB_CU_ue_id;
|
||||
uint32_t gNB_DU_ue_id;
|
||||
f1ap_Cause_t cause;
|
||||
long cause_value;
|
||||
} f1ap_ue_context_modif_refuse_t;
|
||||
|
||||
typedef struct f1ap_ue_context_release_s {
|
||||
uint32_t gNB_CU_ue_id;
|
||||
uint32_t gNB_DU_ue_id;
|
||||
|
||||
@@ -184,6 +184,16 @@ void *F1AP_CU_task(void *arg) {
|
||||
&F1AP_PAGING_IND(received_msg));
|
||||
break;
|
||||
|
||||
case F1AP_UE_CONTEXT_MODIFICATION_CONFIRM:
|
||||
CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&F1AP_UE_CONTEXT_MODIFICATION_CONFIRM(received_msg));
|
||||
break;
|
||||
|
||||
case F1AP_UE_CONTEXT_MODIFICATION_REFUSE:
|
||||
CU_send_UE_CONTEXT_MODIFICATION_REFUSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&F1AP_UE_CONTEXT_MODIFICATION_REFUSE(received_msg));
|
||||
break;
|
||||
|
||||
// case F1AP_SETUP_RESPONSE: // This is from RRC
|
||||
// CU_send_F1_SETUP_RESPONSE(instance, *f1ap_setup_ind, &(F1AP_SETUP_RESP) f1ap_setup_resp)
|
||||
// break;
|
||||
|
||||
@@ -1701,14 +1701,264 @@ int CU_handle_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance,
|
||||
AssertFatal(1==0,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu) {
|
||||
AssertFatal(1==0,"Not implemented yet\n");
|
||||
int CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
|
||||
{
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
MessageDef *msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_MODIFICATION_REQUIRED);
|
||||
f1ap_ue_context_modif_required_t *required = &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg_p);
|
||||
|
||||
F1AP_UEContextModificationRequired_t *container = &pdu->choice.initiatingMessage->value.choice.UEContextModificationRequired;
|
||||
F1AP_UEContextModificationRequiredIEs_t *ie = NULL;
|
||||
|
||||
/* required: GNB_CU_UE_F1AP_ID */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
|
||||
required->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
|
||||
|
||||
/* required: GNB_DU_UE_F1AP_ID */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
|
||||
required->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
|
||||
|
||||
/* optional: Resource Coordination Transfer Container */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t,
|
||||
ie,
|
||||
container,
|
||||
F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferContainer,
|
||||
false);
|
||||
AssertFatal(ie == NULL, "handling of Resource Coordination Transfer Container not implemented\n");
|
||||
|
||||
/* optional: DU to CU RRC Information */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t,
|
||||
ie,
|
||||
container,
|
||||
F1AP_ProtocolIE_ID_id_DUtoCURRCInformation,
|
||||
false);
|
||||
if (ie != NULL) {
|
||||
F1AP_DUtoCURRCInformation_t *du2cu = &ie->value.choice.DUtoCURRCInformation;
|
||||
required->du_to_cu_rrc_information = malloc(sizeof(*required->du_to_cu_rrc_information));
|
||||
AssertFatal(required->du_to_cu_rrc_information != NULL, "memory allocation failed\n");
|
||||
|
||||
required->du_to_cu_rrc_information->cellGroupConfig = malloc(du2cu->cellGroupConfig.size);
|
||||
AssertFatal(required->du_to_cu_rrc_information->cellGroupConfig != NULL, "memory allocation failed\n");
|
||||
memcpy(required->du_to_cu_rrc_information->cellGroupConfig, du2cu->cellGroupConfig.buf, du2cu->cellGroupConfig.size);
|
||||
required->du_to_cu_rrc_information->cellGroupConfig_length = du2cu->cellGroupConfig.size;
|
||||
|
||||
AssertFatal(du2cu->measGapConfig == NULL, "handling of measGapConfig not implemented\n");
|
||||
AssertFatal(du2cu->requestedP_MaxFR1 == NULL, "handling of requestedP_MaxFR1 not implemented\n");
|
||||
}
|
||||
|
||||
/* optional: DRB Required to Be Modified List */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t,
|
||||
ie,
|
||||
container,
|
||||
F1AP_ProtocolIE_ID_id_DRBs_Required_ToBeModified_List,
|
||||
false);
|
||||
AssertFatal(ie == NULL, "handling of DRBs Required to be modified list not implemented\n");
|
||||
|
||||
/* optional: SRB Required to be Released List */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t,
|
||||
ie,
|
||||
container,
|
||||
F1AP_ProtocolIE_ID_id_SRBs_Required_ToBeReleased_List,
|
||||
false);
|
||||
AssertFatal(ie == NULL, "handling of SRBs Required to be released list not implemented\n");
|
||||
|
||||
/* optional: DRB Required to be Released List */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t,
|
||||
ie,
|
||||
container,
|
||||
F1AP_ProtocolIE_ID_id_DRBs_Required_ToBeReleased_List,
|
||||
false);
|
||||
AssertFatal(ie == NULL, "handling of DRBs Required to be released list not implemented\n");
|
||||
|
||||
/* mandatory: Cause */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t, ie, container, F1AP_ProtocolIE_ID_id_Cause, true);
|
||||
switch (ie->value.choice.Cause.present) {
|
||||
case F1AP_Cause_PR_radioNetwork:
|
||||
required->cause = F1AP_CAUSE_RADIO_NETWORK;
|
||||
required->cause_value = ie->value.choice.Cause.choice.radioNetwork;
|
||||
break;
|
||||
case F1AP_Cause_PR_transport:
|
||||
required->cause = F1AP_CAUSE_TRANSPORT;
|
||||
required->cause_value = ie->value.choice.Cause.choice.transport;
|
||||
break;
|
||||
case F1AP_Cause_PR_protocol:
|
||||
required->cause = F1AP_CAUSE_PROTOCOL;
|
||||
required->cause_value = ie->value.choice.Cause.choice.protocol;
|
||||
break;
|
||||
case F1AP_Cause_PR_misc:
|
||||
required->cause = F1AP_CAUSE_MISC;
|
||||
required->cause_value = ie->value.choice.Cause.choice.misc;
|
||||
break;
|
||||
default:
|
||||
LOG_W(F1AP, "Unknown cause for UE Context Modification required message\n");
|
||||
/* fall through */
|
||||
case F1AP_Cause_PR_NOTHING:
|
||||
required->cause = F1AP_CAUSE_NOTHING;
|
||||
break;
|
||||
}
|
||||
|
||||
/* optional: BH RLC Channel Required to be Released List */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t,
|
||||
ie,
|
||||
container,
|
||||
F1AP_ProtocolIE_ID_id_BHChannels_Required_ToBeReleased_List,
|
||||
false);
|
||||
AssertFatal(ie == NULL, "handling of BH RLC Channel Required to be Released list not implemented\n");
|
||||
|
||||
/* optional: SL DRB Required to Be Modified List */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t,
|
||||
ie,
|
||||
container,
|
||||
F1AP_ProtocolIE_ID_id_SLDRBs_Required_ToBeModified_List,
|
||||
false);
|
||||
AssertFatal(ie == NULL, "handling of SL DRB Required to be modified list not implemented\n");
|
||||
|
||||
/* optional: SL DRB Required to be Released List */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t,
|
||||
ie,
|
||||
container,
|
||||
F1AP_ProtocolIE_ID_id_SLDRBs_Required_ToBeReleased_List,
|
||||
false);
|
||||
AssertFatal(ie == NULL, "handling of SL DRBs Required to be released list not implemented\n");
|
||||
|
||||
/* optional: Candidate Cells To Be Cancelled List */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequiredIEs_t,
|
||||
ie,
|
||||
container,
|
||||
F1AP_ProtocolIE_ID_id_Candidate_SpCell_List,
|
||||
false);
|
||||
AssertFatal(ie == NULL, "handling of candidate cells to be cancelled list not implemented\n");
|
||||
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance,
|
||||
F1AP_UEContextModificationConfirm_t UEContextModificationConfirm_t) {
|
||||
AssertFatal(1==0,"Not implemented yet\n");
|
||||
int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, f1ap_ue_context_modif_confirm_t *confirm)
|
||||
{
|
||||
F1AP_F1AP_PDU_t pdu = {0};
|
||||
pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome;
|
||||
asn1cCalloc(pdu.choice.successfulOutcome, tmp);
|
||||
tmp->procedureCode = F1AP_ProcedureCode_id_UEContextModificationRequired;
|
||||
tmp->criticality = F1AP_Criticality_reject;
|
||||
tmp->value.present = F1AP_SuccessfulOutcome__value_PR_UEContextModificationConfirm;
|
||||
F1AP_UEContextModificationConfirm_t *out = &tmp->value.choice.UEContextModificationConfirm;
|
||||
|
||||
/* mandatory: GNB_CU_UE_F1AP_ID */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationConfirmIEs_t, ie1);
|
||||
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
|
||||
ie1->criticality = F1AP_Criticality_reject;
|
||||
ie1->value.present = F1AP_UEContextModificationConfirmIEs__value_PR_GNB_CU_UE_F1AP_ID;
|
||||
ie1->value.choice.GNB_CU_UE_F1AP_ID = confirm->gNB_CU_ue_id;
|
||||
|
||||
/* mandatory: GNB_DU_UE_F1AP_ID */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationConfirmIEs_t, ie2);
|
||||
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
|
||||
ie2->criticality = F1AP_Criticality_reject;
|
||||
ie2->value.present = F1AP_UEContextModificationConfirmIEs__value_PR_GNB_DU_UE_F1AP_ID;
|
||||
ie2->value.choice.GNB_DU_UE_F1AP_ID = confirm->gNB_DU_ue_id;
|
||||
|
||||
/* optional: Resource Coordination Transfer Container */
|
||||
/* not implemented*/
|
||||
|
||||
/* optional: DRB Modified List */
|
||||
/* not implemented*/
|
||||
|
||||
/* optional: RRC Container */
|
||||
if (confirm->rrc_container != NULL) {
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationConfirmIEs_t, ie);
|
||||
ie->id = F1AP_ProtocolIE_ID_id_RRCContainer;
|
||||
ie->criticality = F1AP_Criticality_ignore;
|
||||
ie->value.present = F1AP_UEContextModificationConfirmIEs__value_PR_RRCContainer;
|
||||
OCTET_STRING_fromBuf(&ie->value.choice.RRCContainer, (const char *)confirm->rrc_container, confirm->rrc_container_length);
|
||||
}
|
||||
|
||||
/* optional: CriticalityDiagnostics */
|
||||
/* not implemented*/
|
||||
|
||||
/* optional: Execute Duplication */
|
||||
/* not implemented*/
|
||||
|
||||
/* optional: Resource Coordination Transfer Information */
|
||||
/* not implemented*/
|
||||
|
||||
/* optional: SL DRB Modified List */
|
||||
/* not implemented*/
|
||||
|
||||
/* encode */
|
||||
uint8_t *buffer = NULL;
|
||||
uint32_t len = 0;
|
||||
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
LOG_E(F1AP, "Failed to encode F1 UE Context Modification Confirm\n");
|
||||
return -1;
|
||||
}
|
||||
f1ap_itti_send_sctp_data_req(true, instance, buffer, len, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CU_send_UE_CONTEXT_MODIFICATION_REFUSE(instance_t instance, f1ap_ue_context_modif_refuse_t *refuse)
|
||||
{
|
||||
F1AP_F1AP_PDU_t pdu = {0};
|
||||
pdu.present = F1AP_F1AP_PDU_PR_unsuccessfulOutcome;
|
||||
asn1cCalloc(pdu.choice.unsuccessfulOutcome, tmp);
|
||||
tmp->procedureCode = F1AP_ProcedureCode_id_UEContextModificationRequired;
|
||||
tmp->criticality = F1AP_Criticality_reject;
|
||||
tmp->value.present = F1AP_UnsuccessfulOutcome__value_PR_UEContextModificationRefuse;
|
||||
F1AP_UEContextModificationRefuse_t *out = &tmp->value.choice.UEContextModificationRefuse;
|
||||
|
||||
/* mandatory: GNB_CU_UE_F1AP_ID */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRefuseIEs_t, ie1);
|
||||
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
|
||||
ie1->criticality = F1AP_Criticality_reject;
|
||||
ie1->value.present = F1AP_UEContextModificationRefuseIEs__value_PR_GNB_CU_UE_F1AP_ID;
|
||||
ie1->value.choice.GNB_CU_UE_F1AP_ID = refuse->gNB_CU_ue_id;
|
||||
|
||||
/* mandatory: GNB_DU_UE_F1AP_ID */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRefuseIEs_t, ie2);
|
||||
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
|
||||
ie2->criticality = F1AP_Criticality_reject;
|
||||
ie2->value.present = F1AP_UEContextModificationRefuseIEs__value_PR_GNB_DU_UE_F1AP_ID;
|
||||
ie2->value.choice.GNB_DU_UE_F1AP_ID = refuse->gNB_DU_ue_id;
|
||||
|
||||
/* optional: Cause */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRefuseIEs_t, ie3);
|
||||
ie3->id = F1AP_ProtocolIE_ID_id_Cause;
|
||||
ie3->criticality = F1AP_Criticality_reject;
|
||||
ie3->value.present = F1AP_UEContextModificationRefuseIEs__value_PR_Cause;
|
||||
F1AP_Cause_t *cause = &ie3->value.choice.Cause;
|
||||
switch (refuse->cause) {
|
||||
case F1AP_CAUSE_RADIO_NETWORK:
|
||||
cause->present = F1AP_Cause_PR_radioNetwork;
|
||||
cause->choice.radioNetwork = refuse->cause_value;
|
||||
break;
|
||||
case F1AP_CAUSE_TRANSPORT:
|
||||
cause->present = F1AP_Cause_PR_transport;
|
||||
cause->choice.transport = refuse->cause_value;
|
||||
break;
|
||||
case F1AP_CAUSE_PROTOCOL:
|
||||
cause->present = F1AP_Cause_PR_protocol;
|
||||
cause->choice.protocol = refuse->cause_value;
|
||||
break;
|
||||
case F1AP_CAUSE_MISC:
|
||||
cause->present = F1AP_Cause_PR_misc;
|
||||
cause->choice.misc = refuse->cause_value;
|
||||
break;
|
||||
case F1AP_CAUSE_NOTHING:
|
||||
default:
|
||||
cause->present = F1AP_Cause_PR_NOTHING;
|
||||
break;
|
||||
} // switch
|
||||
|
||||
/* optional: CriticalityDiagnostics */
|
||||
/* not implemented*/
|
||||
|
||||
/* encode */
|
||||
uint8_t *buffer = NULL;
|
||||
uint32_t len = 0;
|
||||
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
LOG_E(F1AP, "Failed to encode F1 UE Context Modification Refuse\n");
|
||||
return -1;
|
||||
}
|
||||
f1ap_itti_send_sctp_data_req(true, instance, buffer, len, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -85,12 +85,11 @@ int CU_handle_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance,
|
||||
/*
|
||||
* UE Context Modification Required (gNB-DU initiated)
|
||||
*/
|
||||
int CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance,
|
||||
F1AP_UEContextModificationConfirm_t UEContextModificationConfirm_t);
|
||||
int CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, f1ap_ue_context_modif_confirm_t *confirm);
|
||||
|
||||
int CU_send_UE_CONTEXT_MODIFICATION_REFUSE(instance_t instance, f1ap_ue_context_modif_refuse_t *refuse);
|
||||
|
||||
/*
|
||||
* UE Inactivity Notification
|
||||
|
||||
@@ -169,6 +169,10 @@ void *F1AP_DU_task(void *arg) {
|
||||
DU_send_UE_CONTEXT_RELEASE_COMPLETE(myInstance, &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg));
|
||||
break;
|
||||
|
||||
case F1AP_UE_CONTEXT_MODIFICATION_REQUIRED:
|
||||
DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(myInstance, &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg));
|
||||
break;
|
||||
|
||||
case TERMINATE_MESSAGE:
|
||||
LOG_W(F1AP, " *** Exiting F1AP thread\n");
|
||||
itti_exit_task();
|
||||
|
||||
@@ -1285,12 +1285,252 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex
|
||||
int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance) {
|
||||
AssertFatal(1==0,"Not implemented yet\n");
|
||||
}
|
||||
int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance) {
|
||||
AssertFatal(1==0,"Not implemented yet\n");
|
||||
|
||||
int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, f1ap_ue_context_modif_required_t *required)
|
||||
{
|
||||
/* 0. Message Type */
|
||||
F1AP_F1AP_PDU_t pdu = {0};
|
||||
pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
|
||||
asn1cCalloc(pdu.choice.initiatingMessage, tmp);
|
||||
tmp->procedureCode = F1AP_ProcedureCode_id_UEContextModificationRequired;
|
||||
tmp->criticality = F1AP_Criticality_reject;
|
||||
tmp->value.present = F1AP_InitiatingMessage__value_PR_UEContextModificationRequired;
|
||||
F1AP_UEContextModificationRequired_t *out = &tmp->value.choice.UEContextModificationRequired;
|
||||
|
||||
/* mandatory GNB_CU_UE_F1AP_ID */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequiredIEs_t, ie1);
|
||||
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
|
||||
ie1->criticality = F1AP_Criticality_reject;
|
||||
ie1->value.present = F1AP_UEContextModificationRequiredIEs__value_PR_GNB_CU_UE_F1AP_ID;
|
||||
ie1->value.choice.GNB_CU_UE_F1AP_ID = required->gNB_CU_ue_id;
|
||||
|
||||
/* mandatory: GNB_DU_UE_F1AP_ID */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequiredIEs_t, ie2);
|
||||
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
|
||||
ie2->criticality = F1AP_Criticality_reject;
|
||||
ie2->value.present = F1AP_UEContextModificationRequiredIEs__value_PR_GNB_DU_UE_F1AP_ID;
|
||||
ie2->value.choice.GNB_DU_UE_F1AP_ID = required->gNB_DU_ue_id;
|
||||
|
||||
/* optional: Resource Coordination Transfer Container */
|
||||
/* not implemented!*/
|
||||
|
||||
/* optional: DU-to-CU RRC Container */
|
||||
if (required->du_to_cu_rrc_information) {
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequiredIEs_t, ie3);
|
||||
ie3->id = F1AP_ProtocolIE_ID_id_DUtoCURRCInformation;
|
||||
ie3->criticality = F1AP_Criticality_reject;
|
||||
ie3->value.present = F1AP_UEContextModificationRequiredIEs__value_PR_DUtoCURRCInformation;
|
||||
|
||||
const du_to_cu_rrc_information_t *du2cu = required->du_to_cu_rrc_information;
|
||||
AssertFatal(du2cu->cellGroupConfig != NULL, "du2cu cellGroupConfig is mandatory!\n");
|
||||
|
||||
/* mandatorycellGroupConfig */
|
||||
OCTET_STRING_fromBuf(&ie3->value.choice.DUtoCURRCInformation.cellGroupConfig,
|
||||
(const char *)du2cu->cellGroupConfig,
|
||||
du2cu->cellGroupConfig_length);
|
||||
|
||||
/* optional: measGapConfig */
|
||||
if (du2cu->measGapConfig != NULL) {
|
||||
OCTET_STRING_fromBuf(ie3->value.choice.DUtoCURRCInformation.measGapConfig,
|
||||
(const char *)du2cu->measGapConfig,
|
||||
du2cu->measGapConfig_length);
|
||||
}
|
||||
|
||||
/* optional: requestedP_MaxFR1 */
|
||||
if (du2cu->requestedP_MaxFR1 != NULL) {
|
||||
OCTET_STRING_fromBuf(ie3->value.choice.DUtoCURRCInformation.requestedP_MaxFR1,
|
||||
(const char *)du2cu->requestedP_MaxFR1,
|
||||
du2cu->requestedP_MaxFR1_length);
|
||||
}
|
||||
}
|
||||
|
||||
/* optional: DRB required to be modified */
|
||||
/* not implemented */
|
||||
|
||||
/* optional: SRB required to be released */
|
||||
/* not implemented */
|
||||
|
||||
/* optional: DRB required to be released */
|
||||
/* not implemented */
|
||||
|
||||
/* mandatory: cause */
|
||||
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequiredIEs_t, ie4);
|
||||
ie4->id = F1AP_ProtocolIE_ID_id_Cause;
|
||||
ie4->criticality = F1AP_Criticality_reject;
|
||||
ie4->value.present = F1AP_UEContextModificationRequiredIEs__value_PR_Cause;
|
||||
F1AP_Cause_t *cause = &ie4->value.choice.Cause;
|
||||
switch (required->cause) {
|
||||
case F1AP_CAUSE_RADIO_NETWORK:
|
||||
cause->present = F1AP_Cause_PR_radioNetwork;
|
||||
cause->choice.radioNetwork = required->cause_value;
|
||||
break;
|
||||
case F1AP_CAUSE_TRANSPORT:
|
||||
cause->present = F1AP_Cause_PR_transport;
|
||||
cause->choice.transport = required->cause_value;
|
||||
break;
|
||||
case F1AP_CAUSE_PROTOCOL:
|
||||
cause->present = F1AP_Cause_PR_protocol;
|
||||
cause->choice.protocol = required->cause_value;
|
||||
break;
|
||||
case F1AP_CAUSE_MISC:
|
||||
cause->present = F1AP_Cause_PR_misc;
|
||||
cause->choice.misc = required->cause_value;
|
||||
break;
|
||||
case F1AP_CAUSE_NOTHING:
|
||||
default:
|
||||
cause->present = F1AP_Cause_PR_NOTHING;
|
||||
break;
|
||||
} // switch
|
||||
|
||||
/* optional: BH RLC Channel Required to be Released List */
|
||||
/* not implemented */
|
||||
|
||||
/* optional: SL DRB Required to Be Modified List */
|
||||
/* not implemented */
|
||||
|
||||
/* optional: SL DRB Required to be Released List */
|
||||
/* not implemented */
|
||||
|
||||
/* optional: Candidate Cells To Be Cancelled List */
|
||||
/* not implemented */
|
||||
|
||||
/* encode */
|
||||
uint8_t *buffer = NULL;
|
||||
uint32_t len = 0;
|
||||
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
LOG_E(F1AP, "Failed to encode F1 context release request\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
f1ap_itti_send_sctp_data_req(false, instance, buffer, len, getCxt(false, instance)->default_sctp_stream_id);
|
||||
return 0;
|
||||
}
|
||||
int DU_handle_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu) {
|
||||
AssertFatal(1==0,"Not implemented yet\n");
|
||||
|
||||
int DU_handle_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
|
||||
{
|
||||
F1AP_UEContextModificationConfirm_t *container = &pdu->choice.successfulOutcome->value.choice.UEContextModificationConfirm;
|
||||
f1ap_ue_context_modif_confirm_t confirm = {0};
|
||||
F1AP_UEContextModificationConfirmIEs_t *ie = NULL;
|
||||
|
||||
/* mandatory: GNB_CU_UE_F1AP_ID */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
|
||||
confirm.gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
|
||||
|
||||
/* mandatory: GNB_DU_UE_F1AP_ID */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
|
||||
confirm.gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
|
||||
|
||||
/* optional: Resource Coordination Transfer Container */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t,
|
||||
ie,
|
||||
container,
|
||||
F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferContainer,
|
||||
false);
|
||||
AssertFatal(ie == NULL, "handling of Resource Coordination Transfer Container not implemented\n");
|
||||
|
||||
/* optional: DRBS Modified List */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t,
|
||||
ie,
|
||||
container,
|
||||
F1AP_ProtocolIE_ID_id_DRBs_Modified_List,
|
||||
false);
|
||||
AssertFatal(ie == NULL, "handling of DRBs Modified List not implemented\n");
|
||||
|
||||
/* optional: RRC Container */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t, ie, container, F1AP_ProtocolIE_ID_id_RRCContainer, false);
|
||||
if (ie != NULL) {
|
||||
F1AP_RRCContainer_t *rrc_container = &ie->value.choice.RRCContainer;
|
||||
confirm.rrc_container = malloc(rrc_container->size);
|
||||
AssertFatal(confirm.rrc_container != NULL, "memory allocation failed\n");
|
||||
memcpy(confirm.rrc_container, rrc_container->buf, rrc_container->size);
|
||||
confirm.rrc_container_length = rrc_container->size;
|
||||
}
|
||||
|
||||
/* optional: Criticality Diagnostics */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t,
|
||||
ie,
|
||||
container,
|
||||
F1AP_ProtocolIE_ID_id_CriticalityDiagnostics,
|
||||
false);
|
||||
AssertFatal(ie == NULL, "handling of DRBs Modified List not implemented\n");
|
||||
|
||||
/* optional: Execute Duplication */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t,
|
||||
ie,
|
||||
container,
|
||||
F1AP_ProtocolIE_ID_id_ExecuteDuplication,
|
||||
false);
|
||||
AssertFatal(ie == NULL, "handling of DRBs Modified List not implemented\n");
|
||||
|
||||
/* optional: Resource Coordination Transfer Information */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t,
|
||||
ie,
|
||||
container,
|
||||
F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferInformation,
|
||||
false);
|
||||
AssertFatal(ie == NULL, "handling of DRBs Modified List not implemented\n");
|
||||
|
||||
/* optional: SL DRB Modified List */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t,
|
||||
ie,
|
||||
container,
|
||||
F1AP_ProtocolIE_ID_id_SLDRBs_Modified_List,
|
||||
false);
|
||||
AssertFatal(ie == NULL, "handling of DRBs Modified List not implemented\n");
|
||||
|
||||
ue_context_modification_confirm(&confirm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DU_handle_UE_CONTEXT_MODIFICATION_REFUSE(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
|
||||
{
|
||||
F1AP_UEContextModificationRefuse_t *container = &pdu->choice.unsuccessfulOutcome->value.choice.UEContextModificationRefuse;
|
||||
f1ap_ue_context_modif_refuse_t refuse = {0};
|
||||
F1AP_UEContextModificationRefuseIEs_t *ie = NULL;
|
||||
|
||||
/* mandatory: GNB_CU_UE_F1AP_ID */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRefuseIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
|
||||
refuse.gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
|
||||
|
||||
/* mandatory: GNB_DU_UE_F1AP_ID */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRefuseIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
|
||||
refuse.gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
|
||||
|
||||
/* mandatory: Cause */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRefuseIEs_t, ie, container, F1AP_ProtocolIE_ID_id_Cause, true);
|
||||
switch (ie->value.choice.Cause.present) {
|
||||
case F1AP_Cause_PR_radioNetwork:
|
||||
refuse.cause = F1AP_CAUSE_RADIO_NETWORK;
|
||||
refuse.cause_value = ie->value.choice.Cause.choice.radioNetwork;
|
||||
break;
|
||||
case F1AP_Cause_PR_transport:
|
||||
refuse.cause = F1AP_CAUSE_TRANSPORT;
|
||||
refuse.cause_value = ie->value.choice.Cause.choice.transport;
|
||||
break;
|
||||
case F1AP_Cause_PR_protocol:
|
||||
refuse.cause = F1AP_CAUSE_PROTOCOL;
|
||||
refuse.cause_value = ie->value.choice.Cause.choice.protocol;
|
||||
break;
|
||||
case F1AP_Cause_PR_misc:
|
||||
refuse.cause = F1AP_CAUSE_MISC;
|
||||
refuse.cause_value = ie->value.choice.Cause.choice.misc;
|
||||
break;
|
||||
default:
|
||||
LOG_W(F1AP, "Unknown cause for UE Context Modification Refuse message\n");
|
||||
/* fall through */
|
||||
case F1AP_Cause_PR_NOTHING:
|
||||
refuse.cause = F1AP_CAUSE_NOTHING;
|
||||
break;
|
||||
}
|
||||
|
||||
/* optional: Criticality Diagnostics */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRefuseIEs_t,
|
||||
ie,
|
||||
container,
|
||||
F1AP_ProtocolIE_ID_id_CriticalityDiagnostics,
|
||||
false);
|
||||
AssertFatal(ie == NULL, "handling of DRBs Modified List not implemented\n");
|
||||
|
||||
ue_context_modification_refuse(&refuse);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -79,13 +79,11 @@ int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance);
|
||||
/*
|
||||
* UE Context Modification Required (gNB-DU initiated)
|
||||
*/
|
||||
int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance);
|
||||
int DU_handle_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
F1AP_F1AP_PDU_t *pdu);
|
||||
int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, f1ap_ue_context_modif_required_t *required);
|
||||
|
||||
int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *req);
|
||||
int DU_handle_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
int DU_handle_UE_CONTEXT_MODIFICATION_REFUSE(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
/*
|
||||
* UE Inactivity Notification
|
||||
|
||||
@@ -52,7 +52,7 @@ static const f1ap_message_processing_t f1ap_messages_processing[][3] = {
|
||||
{DU_handle_UE_CONTEXT_SETUP_REQUEST, CU_handle_UE_CONTEXT_SETUP_RESPONSE, 0}, /* UEContextSetup */
|
||||
{DU_handle_UE_CONTEXT_RELEASE_COMMAND, CU_handle_UE_CONTEXT_RELEASE_COMPLETE, 0}, /* UEContextRelease */
|
||||
{DU_handle_UE_CONTEXT_MODIFICATION_REQUEST, CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE, 0}, /* UEContextModification */
|
||||
{0, 0, 0}, /* UEContextModificationRequired */
|
||||
{CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED, DU_handle_UE_CONTEXT_MODIFICATION_CONFIRM, DU_handle_UE_CONTEXT_MODIFICATION_REFUSE}, /* UEContextModificationRequired */
|
||||
{0, 0, 0}, /* UEMobilityCommand */
|
||||
{CU_handle_UE_CONTEXT_RELEASE_REQUEST, 0, 0}, /* UEContextReleaseRequest */
|
||||
{CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER, 0, 0}, /* InitialULRRCMessageTransfer */
|
||||
|
||||
@@ -1615,192 +1615,6 @@ static void prepare_dl_pdus(gNB_MAC_INST *nr_mac,
|
||||
LOG_D(NR_MAC,"numDlDci: %i\n", pdcch_pdu_rel15->numDlDci);
|
||||
}
|
||||
|
||||
static void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP,
|
||||
int CC_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
NR_RA_t *ra,
|
||||
nfapi_nr_dl_tti_request_t *DL_req,
|
||||
nfapi_nr_tx_data_request_t *TX_req)
|
||||
{
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
|
||||
|
||||
// proceed only if it is a DL slot
|
||||
if (!is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[slotP / 64], slotP))
|
||||
return;
|
||||
|
||||
// UE is known by the network, C-RNTI to be used instead of TC-RNTI
|
||||
int rnti = ra->crnti;
|
||||
|
||||
NR_UE_info_t *UE = find_nr_UE(&nr_mac->UE_info, rnti);
|
||||
if (!UE) {
|
||||
LOG_E(NR_MAC, "Received Msg3 with C-RNTI but rnti %04x not in the table\n", rnti);
|
||||
return;
|
||||
}
|
||||
|
||||
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
NR_SearchSpace_t *ss = ra->ra_ss;
|
||||
|
||||
NR_ControlResourceSet_t *coreset = ra->coreset;
|
||||
AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg4\n");
|
||||
|
||||
// Only need to schedule DCI with and empty DL
|
||||
NR_UE_DL_BWP_t *dl_bwp = &ra->DL_BWP;
|
||||
long BWPStart = 0;
|
||||
long BWPSize = 0;
|
||||
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = NULL;
|
||||
if(*ss->controlResourceSetId!=0) {
|
||||
BWPStart = dl_bwp->BWPStart;
|
||||
BWPSize = dl_bwp->BWPSize;
|
||||
} else {
|
||||
type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[ra->beam_id];
|
||||
BWPStart = type0_PDCCH_CSS_config->cset_start_rb;
|
||||
BWPSize = type0_PDCCH_CSS_config->num_rbs;
|
||||
}
|
||||
|
||||
// get CCEindex, needed also for PUCCH and then later for PDCCH
|
||||
uint8_t aggregation_level;
|
||||
int CCEIndex = get_cce_index(nr_mac,
|
||||
CC_id, slotP, 0,
|
||||
&aggregation_level,
|
||||
ss,
|
||||
coreset,
|
||||
&ra->sched_pdcch,
|
||||
true);
|
||||
|
||||
if (CCEIndex < 0) {
|
||||
LOG_E(NR_MAC, "%s(): cannot find free CCE for RA RNTI 0x%04x!\n", __func__, rnti);
|
||||
return;
|
||||
}
|
||||
|
||||
// Checking if the DCI allocation is feasible in current subframe
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
|
||||
if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) {
|
||||
LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, rnti);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t time_domain_assignment = get_dl_tda(nr_mac, scc, slotP);
|
||||
int mux_pattern = type0_PDCCH_CSS_config ? type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern : 1;
|
||||
NR_tda_info_t tda = get_dl_tda_info(dl_bwp, ss->searchSpaceType->present, time_domain_assignment,
|
||||
scc->dmrs_TypeA_Position, mux_pattern, NR_RNTI_C, coreset->controlResourceSetId, false);
|
||||
|
||||
NR_pdsch_dmrs_t dmrs_info = get_dl_dmrs_params(scc,
|
||||
dl_bwp,
|
||||
&tda,
|
||||
1);
|
||||
|
||||
int subheader_len = sizeof(NR_MAC_SUBHEADER_SHORT);
|
||||
int pdu_length = subheader_len + 7; // 7 is contetion resolution length
|
||||
|
||||
int mcsTableIdx = dl_bwp->mcsTableIdx;
|
||||
int mcsIndex = 0;
|
||||
int rbStart = 0;
|
||||
int rbSize = 0;
|
||||
int tb_scaling = 0;
|
||||
uint32_t tb_size = 0;
|
||||
|
||||
// increase PRBs until we get to BWPSize or TBS is bigger than MAC PDU size
|
||||
do {
|
||||
if(rbSize < BWPSize)
|
||||
rbSize++;
|
||||
else
|
||||
mcsIndex++;
|
||||
LOG_D(NR_MAC,"Calling nr_compute_tbs with N_PRB_DMRS %d, N_DMRS_SLOT %d\n",dmrs_info.N_PRB_DMRS,dmrs_info.N_DMRS_SLOT);
|
||||
tb_size = nr_compute_tbs(nr_get_Qm_dl(mcsIndex, mcsTableIdx),
|
||||
nr_get_code_rate_dl(mcsIndex, mcsTableIdx),
|
||||
rbSize, tda.nrOfSymbols, dmrs_info.N_PRB_DMRS * dmrs_info.N_DMRS_SLOT, 0, tb_scaling,1) >> 3;
|
||||
} while (tb_size < pdu_length && mcsIndex<=28);
|
||||
|
||||
AssertFatal(tb_size >= pdu_length,"Cannot allocate response to MSG3 with DCCH\n");
|
||||
|
||||
int i = 0;
|
||||
uint16_t *vrb_map = cc[CC_id].vrb_map;
|
||||
while ((i < rbSize) && (rbStart + rbSize <= BWPSize)) {
|
||||
if (vrb_map[BWPStart + rbStart + i]&SL_to_bitmap(tda.startSymbolIndex, tda.nrOfSymbols)) {
|
||||
rbStart += i+1;
|
||||
i = 0;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (rbStart > (BWPSize - rbSize)) {
|
||||
LOG_E(NR_MAC, "%s(): cannot find free vrb_map for RNTI %04x!\n", __func__, rnti);
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove UE associated to TC-RNTI
|
||||
mac_remove_nr_ue(nr_mac, ra->rnti);
|
||||
|
||||
|
||||
// If the UE used MSG3 to transfer a DCCH or DTCH message, then contention resolution is successful if the UE receives a PDCCH transmission which has its CRC bits scrambled by the C-RNTI
|
||||
// Just send padding LCID
|
||||
uint8_t buf[tb_size];
|
||||
NR_MAC_SUBHEADER_FIXED *padding = (NR_MAC_SUBHEADER_FIXED *) &buf[0];
|
||||
padding->R = 0;
|
||||
padding->LCID = DL_SCH_LCID_PADDING;
|
||||
for(int k = 1; k < tb_size; k++)
|
||||
buf[k] = 0;
|
||||
|
||||
T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(ra->rnti),
|
||||
T_INT(frameP), T_INT(slotP), T_INT(0), T_BUFFER(buf, tb_size));
|
||||
|
||||
// SCF222: PDU index incremented for each PDSCH PDU sent in TX control message. This is used to associate control
|
||||
// information to data and is reset every slot.
|
||||
const int pduindex = nr_mac->pdu_index[CC_id]++;
|
||||
|
||||
prepare_dl_pdus(nr_mac, ra, dl_bwp, dl_req, NULL, dmrs_info, tda, aggregation_level, CCEIndex, tb_size, 0, 0, 0,
|
||||
0, time_domain_assignment, CC_id, rnti, 0, mcsIndex, tb_scaling, pduindex, rbStart, rbSize);
|
||||
|
||||
// DL TX request
|
||||
nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[TX_req->Number_of_PDUs];
|
||||
memcpy(tx_req->TLVs[0].value.direct, buf, sizeof(uint8_t) * tb_size);
|
||||
tx_req->PDU_length = tb_size;
|
||||
tx_req->PDU_index = pduindex;
|
||||
tx_req->num_TLV = 1;
|
||||
tx_req->TLVs[0].length = tb_size + 2;
|
||||
TX_req->SFN = frameP;
|
||||
TX_req->Number_of_PDUs++;
|
||||
TX_req->Slot = slotP;
|
||||
|
||||
// Mark the corresponding symbols and RBs as used
|
||||
fill_pdcch_vrb_map(nr_mac,
|
||||
CC_id,
|
||||
&ra->sched_pdcch,
|
||||
CCEIndex,
|
||||
aggregation_level);
|
||||
for (int rb = 0; rb < rbSize; rb++)
|
||||
vrb_map[BWPStart + rb + rbStart] |= SL_to_bitmap(tda.startSymbolIndex, tda.nrOfSymbols);
|
||||
|
||||
|
||||
// If the UE used MSG3 to transfer a DCCH or DTCH message, then contention resolution is successful upon transmission of PDCCH
|
||||
LOG_A(NR_MAC, "(ue rnti 0x%04x) CBRA procedure succeeded!\n", ra->rnti);
|
||||
nr_clear_ra_proc(module_idP, CC_id, frameP, ra);
|
||||
UE->Msg4_ACKed = true;
|
||||
UE->ra_timer = 0;
|
||||
|
||||
if(!UE->CellGroup) {
|
||||
// In the specific scenario where UE correctly received MSG4 (assuming it decoded RRCsetup with CellGroup) and gNB didn't correctly received an ACK,
|
||||
// the UE would already have CG but the UE-dedicated gNB structure wouldn't (because RA didn't complete on gNB side).
|
||||
uper_decode(NULL,
|
||||
&asn_DEF_NR_CellGroupConfig, //might be added prefix later
|
||||
(void **)&UE->CellGroup,
|
||||
(uint8_t *)UE->cg_buf,
|
||||
(UE->enc_rval.encoded+7)/8, 0, 0);
|
||||
}
|
||||
|
||||
process_CellGroup(UE->CellGroup, UE);
|
||||
|
||||
// switching to initial BWP
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
configure_UE_BWP(nr_mac, scc, sched_ctrl, NULL, UE, 0, 0);
|
||||
|
||||
// Reset uplink failure flags/counters/timers at MAC so gNB will resume again scheduling resources for this UE
|
||||
nr_mac_reset_ul_failure(sched_ctrl);
|
||||
}
|
||||
|
||||
static void nr_generate_Msg4(module_id_t module_idP,
|
||||
int CC_id,
|
||||
frame_t frameP,
|
||||
@@ -1814,8 +1628,7 @@ static void nr_generate_Msg4(module_id_t module_idP,
|
||||
NR_UE_DL_BWP_t *dl_bwp = &ra->DL_BWP;
|
||||
|
||||
// if it is a DL slot, if the RA is in MSG4 state
|
||||
if (is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[slotP / 64], slotP) &&
|
||||
ra->state == Msg4) {
|
||||
if (is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[slotP / 64], slotP)) {
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
NR_SearchSpace_t *ss = ra->ra_ss;
|
||||
@@ -1842,7 +1655,7 @@ static void nr_generate_Msg4(module_id_t module_idP,
|
||||
|
||||
if (srb_status.bytes_in_buffer == 0) {
|
||||
lcid = DL_SCH_LCID_DCCH;
|
||||
// Check for data on SRB1 (RRCReestablishment)
|
||||
// Check for data on SRB1 (RRCReestablishment, RRCReconfiguration)
|
||||
srb_status = mac_rlc_status_ind(module_idP, ra->rnti, module_idP, frameP, slotP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, 0, 0);
|
||||
}
|
||||
|
||||
@@ -1955,8 +1768,6 @@ static void nr_generate_Msg4(module_id_t module_idP,
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_I(NR_MAC,"Generate msg4, rnti: %04x\n", ra->rnti);
|
||||
|
||||
// HARQ management
|
||||
if (current_harq_pid < 0) {
|
||||
AssertFatal(sched_ctrl->available_dl_harq.head >= 0,
|
||||
@@ -2011,7 +1822,6 @@ static void nr_generate_Msg4(module_id_t module_idP,
|
||||
((NR_MAC_SUBHEADER_LONG *)&buf[mac_pdu_length])->L = htons(mac_sdu_length);
|
||||
ra->mac_pdu_length = mac_pdu_length + mac_sdu_length + sizeof(NR_MAC_SUBHEADER_LONG);
|
||||
}
|
||||
LOG_I(NR_MAC,"Encoded RRCSetup Piggyback (%d + %d bytes), mac_pdu_length %d\n", mac_sdu_length, mac_subheader_len, ra->mac_pdu_length);
|
||||
memcpy(&buf[mac_pdu_length + mac_subheader_len], buffer, mac_sdu_length);
|
||||
}
|
||||
|
||||
@@ -2054,7 +1864,7 @@ static void nr_generate_Msg4(module_id_t module_idP,
|
||||
}
|
||||
|
||||
ra->state = WAIT_Msg4_ACK;
|
||||
LOG_D(NR_MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state);
|
||||
LOG_I(NR_MAC,"UE %04x Generate msg4: feedback at %4d.%2d, payload %d bytes, next state WAIT_Msg4_ACK\n", ra->rnti, pucch->frame, pucch->ul_slot, harq->tb_size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2113,7 +1923,6 @@ void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, NR_RA_t
|
||||
ra->timing_offset = 0;
|
||||
ra->RRC_timer = 20;
|
||||
ra->msg3_round = 0;
|
||||
ra->crnti = 0;
|
||||
if(ra->cfra == false) {
|
||||
ra->rnti = 0;
|
||||
}
|
||||
@@ -2271,7 +2080,7 @@ void nr_schedule_RA(module_id_t module_idP,
|
||||
nr_generate_Msg3_retransmission(module_idP, CC_id, frameP, slotP, ra, ul_dci_req);
|
||||
break;
|
||||
case Msg3_dcch_dtch:
|
||||
nr_generate_Msg3_dcch_dtch_response(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req);
|
||||
/* fallthrough */
|
||||
case Msg4:
|
||||
nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req);
|
||||
break;
|
||||
|
||||
@@ -43,11 +43,13 @@
|
||||
#include "UTIL/OPT/opt.h"
|
||||
|
||||
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
|
||||
#include "F1AP_CauseRadioNetwork.h"
|
||||
|
||||
#include "RRC/NR/MESSAGES/asn1_msg.h"
|
||||
|
||||
#include "intertask_interface.h"
|
||||
#include "openair2/F1AP/f1ap_ids.h"
|
||||
#include "F1AP_CauseRadioNetwork.h"
|
||||
|
||||
#include "T.h"
|
||||
|
||||
@@ -2945,12 +2947,33 @@ void nr_mac_check_ul_failure(const gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ct
|
||||
* stop at 0 and we wait for a UE release command from upper layers */
|
||||
if (sched_ctrl->ul_failure_timer == 1) {
|
||||
f1_ue_data_t ue_data = du_get_f1_ue_data(rnti);
|
||||
f1ap_ue_context_release_complete_t complete = {
|
||||
f1ap_ue_context_release_req_t request = {
|
||||
.gNB_CU_ue_id = ue_data.secondary_ue,
|
||||
.gNB_DU_ue_id = rnti,
|
||||
.cause = F1AP_CAUSE_RADIO_NETWORK,
|
||||
.cause_value = 12, // F1AP_CauseRadioNetwork_rl_failure_others
|
||||
.cause_value = F1AP_CauseRadioNetwork_rl_failure_others,
|
||||
};
|
||||
nrmac->mac_rrc.ue_context_release_request(&complete);
|
||||
nrmac->mac_rrc.ue_context_release_request(&request);
|
||||
}
|
||||
}
|
||||
|
||||
void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_t *UE)
|
||||
{
|
||||
DevAssert(UE->CellGroup != NULL);
|
||||
uint8_t buf[2048];
|
||||
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, NULL, UE->CellGroup, buf, sizeof(buf));
|
||||
AssertFatal(enc_rval.encoded > 0, "ASN1 encoding of CellGroupConfig failed, failed type %s\n", enc_rval.failed_type->name);
|
||||
du_to_cu_rrc_information_t du2cu = {
|
||||
.cellGroupConfig = buf,
|
||||
.cellGroupConfig_length = (enc_rval.encoded + 7) >> 3,
|
||||
};
|
||||
f1_ue_data_t ue_data = du_get_f1_ue_data(UE->rnti);
|
||||
f1ap_ue_context_modif_required_t required = {
|
||||
.gNB_CU_ue_id = ue_data.secondary_ue,
|
||||
.gNB_DU_ue_id = UE->rnti,
|
||||
.du_to_cu_rrc_information = &du2cu,
|
||||
.cause = F1AP_CAUSE_RADIO_NETWORK,
|
||||
.cause_value = F1AP_CauseRadioNetwork_action_desirable_for_radio_reasons,
|
||||
};
|
||||
nrmac->mac_rrc.ue_context_modification_required(&required);
|
||||
}
|
||||
|
||||
@@ -952,7 +952,8 @@ static NR_UE_harq_t *find_harq(frame_t frame, sub_frame_t slot, NR_UE_info_t * U
|
||||
while (harq->feedback_frame != frame
|
||||
|| (harq->feedback_frame == frame && harq->feedback_slot < slot)) {
|
||||
LOG_W(NR_MAC,
|
||||
"expected HARQ pid %d feedback at %4d.%2d, but is at %4d.%2d instead (HARQ feedback is in the past)\n",
|
||||
"UE %04x expected HARQ pid %d feedback at %4d.%2d, but is at %4d.%2d instead (HARQ feedback is in the past)\n",
|
||||
UE->rnti,
|
||||
pid,
|
||||
harq->feedback_frame,
|
||||
harq->feedback_slot,
|
||||
@@ -968,7 +969,8 @@ static NR_UE_harq_t *find_harq(frame_t frame, sub_frame_t slot, NR_UE_info_t * U
|
||||
/* feedbacks that we wait for in the future: don't do anything */
|
||||
if (harq->feedback_slot > slot) {
|
||||
LOG_W(NR_MAC,
|
||||
"expected HARQ pid %d feedback at %4d.%2d, but is at %4d.%2d instead (HARQ feedback is in the future)\n",
|
||||
"UE %04x expected HARQ pid %d feedback at %4d.%2d, but is at %4d.%2d instead (HARQ feedback is in the future)\n",
|
||||
UE->rnti,
|
||||
pid,
|
||||
harq->feedback_frame,
|
||||
harq->feedback_slot,
|
||||
@@ -1001,7 +1003,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
|
||||
const uint8_t harq_confidence = uci_01->harq->harq_confidence_level;
|
||||
NR_UE_harq_t *harq = find_harq(frame, slot, UE, nrmac->dl_bler.harq_round_max);
|
||||
if (!harq) {
|
||||
LOG_E(NR_MAC, "Oh no! Could not find a harq in %s!\n", __FUNCTION__);
|
||||
LOG_E(NR_MAC, "UE %04x: Could not find a HARQ process at %4d.%2d!\n", UE->rnti, frame, slot);
|
||||
break;
|
||||
}
|
||||
DevAssert(harq->is_waiting);
|
||||
|
||||
@@ -223,9 +223,14 @@ static int nr_process_mac_pdu(instance_t module_idP,
|
||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
||||
NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i];
|
||||
if (ra->state >= WAIT_Msg3 && ra->rnti == UE->rnti) {
|
||||
ra->crnti = ((pduP[1]&0xFF)<<8)|(pduP[2]&0xFF);
|
||||
// remove UE context just created after Msg.3 in some milliseconds
|
||||
// as the UE is one already known (not now, as the UE context is
|
||||
// still needed for the moment)
|
||||
nr_mac_trigger_release_timer(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs);
|
||||
//mac_remove_nr_ue(RC.nrmac[module_idP], ra->rnti);
|
||||
// this UE is the one identified by the RNTI in pduP
|
||||
ra->rnti = ((pduP[1]&0xFF)<<8)|(pduP[2]&0xFF);
|
||||
ra->state = Msg3_dcch_dtch;
|
||||
LOG_I(NR_MAC, "Received UL_SCH_LCID_C_RNTI with C-RNTI 0x%04x\n", ra->crnti);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -780,12 +785,13 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
|
||||
if (ra->state == Msg3_dcch_dtch) {
|
||||
// Check if the UE identified by C-RNTI still exists at the gNB
|
||||
NR_UE_info_t * UE_C = find_nr_UE(&gNB_mac->UE_info, ra->crnti);
|
||||
NR_UE_info_t * UE_C = find_nr_UE(&gNB_mac->UE_info, ra->rnti);
|
||||
if (!UE_C) {
|
||||
// The UE identified by C-RNTI no longer exists at the gNB
|
||||
// Let's abort the current RA, so the UE will trigger a new RA later but using RRCSetupRequest instead. A better solution may be implemented
|
||||
mac_remove_nr_ue(gNB_mac, ra->rnti);
|
||||
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
|
||||
LOG_W(NR_MAC, "No UE found with C-RNTI %04x, ignoring Msg.3 to have UE come back with new RA attempt\n", ra->rnti);
|
||||
return;
|
||||
} else {
|
||||
// The UE identified by C-RNTI still exists at the gNB
|
||||
@@ -794,9 +800,11 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
// Reset HARQ processes
|
||||
reset_dl_harq_list(&UE_C->UE_sched_ctrl);
|
||||
reset_ul_harq_list(&UE_C->UE_sched_ctrl);
|
||||
|
||||
// Trigger RRC Reconfiguration
|
||||
LOG_I(NR_MAC, "Received UL_SCH_LCID_C_RNTI with C-RNTI 0x%04x, triggering RRC Reconfiguration\n", UE_C->rnti);
|
||||
nr_mac_trigger_reconfiguration(RC.nrmac[gnb_mod_idP], UE_C);
|
||||
}
|
||||
LOG_I(NR_MAC, "Activating scheduling response to MSG3 with DCCH/DTCCH and RNTI 0x%04x (state %d)\n",
|
||||
ra->crnti, ra->state);
|
||||
}
|
||||
else {
|
||||
LOG_I(NR_MAC, "Activating scheduling RA-Msg4 for TC_RNTI 0x%04x (state %d)\n",
|
||||
|
||||
@@ -449,4 +449,6 @@ void nr_mac_trigger_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpac
|
||||
void nr_mac_reset_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl);
|
||||
void nr_mac_check_ul_failure(const gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ctrl_t *sched_ctrl);
|
||||
|
||||
void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_t *UE);
|
||||
|
||||
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "openair2/F1AP/f1ap_ids.h"
|
||||
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
|
||||
#include "openair2/RRC/NR/MESSAGES/asn1_msg.h"
|
||||
#include "F1AP_CauseRadioNetwork.h"
|
||||
|
||||
#include "uper_decoder.h"
|
||||
#include "uper_encoder.h"
|
||||
@@ -243,6 +244,63 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req)
|
||||
}
|
||||
}
|
||||
|
||||
void ue_context_modification_confirm(const f1ap_ue_context_modif_confirm_t *confirm)
|
||||
{
|
||||
LOG_I(MAC, "Received UE Context Modification Confirm for UE %04x\n", confirm->gNB_DU_ue_id);
|
||||
|
||||
gNB_MAC_INST *mac = RC.nrmac[0];
|
||||
NR_SCHED_LOCK(&mac->sched_lock);
|
||||
/* check first that the scheduler knows such UE */
|
||||
NR_UE_info_t *UE = find_nr_UE(&mac->UE_info, confirm->gNB_DU_ue_id);
|
||||
if (UE == NULL) {
|
||||
LOG_E(MAC, "ERROR: unknown UE with RNTI %04x, ignoring UE Context Modification Confirm\n", confirm->gNB_DU_ue_id);
|
||||
NR_SCHED_UNLOCK(&mac->sched_lock);
|
||||
return;
|
||||
}
|
||||
NR_SCHED_UNLOCK(&mac->sched_lock);
|
||||
|
||||
if (confirm->rrc_container_length > 0)
|
||||
nr_rlc_srb_recv_sdu(confirm->gNB_DU_ue_id, DCCH, confirm->rrc_container, confirm->rrc_container_length);
|
||||
|
||||
/* nothing else to be done? */
|
||||
}
|
||||
|
||||
void ue_context_modification_refuse(const f1ap_ue_context_modif_refuse_t *refuse)
|
||||
{
|
||||
/* Currently, we only use the UE Context Modification Required procedure to
|
||||
* trigger a RRC reconfigurtion after Msg.3 with C-RNTI MAC CE. If the CU
|
||||
* refuses, it cannot do this reconfiguration, leaving the UE in an
|
||||
* unconfigured state. Therefore, we just free all RA-related info, and
|
||||
* request the release of the UE. */
|
||||
LOG_W(MAC, "Received UE Context Modification Refuse for %04x, requesting release\n", refuse->gNB_DU_ue_id);
|
||||
|
||||
gNB_MAC_INST *mac = RC.nrmac[0];
|
||||
NR_SCHED_LOCK(&mac->sched_lock);
|
||||
NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, refuse->gNB_DU_ue_id);
|
||||
if (UE == NULL) {
|
||||
LOG_E(MAC, "ERROR: unknown UE with RNTI %04x, ignoring UE Context Modification Refuse\n", refuse->gNB_DU_ue_id);
|
||||
NR_SCHED_UNLOCK(&mac->sched_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
const int CC_id = 0;
|
||||
NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
|
||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
||||
NR_RA_t *ra = &cc->ra[i];
|
||||
if (ra->rnti == UE->rnti)
|
||||
nr_clear_ra_proc(0, CC_id, 0 /* frame */, ra);
|
||||
}
|
||||
NR_SCHED_UNLOCK(&mac->sched_lock);
|
||||
|
||||
f1ap_ue_context_release_req_t request = {
|
||||
.gNB_CU_ue_id = refuse->gNB_CU_ue_id,
|
||||
.gNB_DU_ue_id = refuse->gNB_DU_ue_id,
|
||||
.cause = F1AP_CAUSE_RADIO_NETWORK,
|
||||
.cause_value = F1AP_CauseRadioNetwork_procedure_cancelled,
|
||||
};
|
||||
mac->mac_rrc.ue_context_release_request(&request);
|
||||
}
|
||||
|
||||
void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd)
|
||||
{
|
||||
/* mark UE as to be deleted after PUSCH failure */
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
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);
|
||||
void ue_context_modification_confirm(const f1ap_ue_context_modif_confirm_t *confirm);
|
||||
void ue_context_modification_refuse(const f1ap_ue_context_modif_refuse_t *refuse);
|
||||
void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd);
|
||||
|
||||
void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc);
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
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,
|
||||
const f1ap_ue_context_modif_resp_t *resp);
|
||||
typedef void (*ue_context_modification_required_func_t)(const f1ap_ue_context_modif_required_t *t);
|
||||
typedef void (*ue_context_release_request_func_t)(const f1ap_ue_context_release_req_t* req);
|
||||
typedef void (*ue_context_release_complete_func_t)(const f1ap_ue_context_release_complete_t *complete);
|
||||
|
||||
|
||||
@@ -111,6 +111,31 @@ static void ue_context_modification_response_direct(const f1ap_ue_context_modif_
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, 0, msg);
|
||||
}
|
||||
|
||||
static void ue_context_modification_required_direct(const f1ap_ue_context_modif_required_t *required)
|
||||
{
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQUIRED);
|
||||
f1ap_ue_context_modif_required_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg);
|
||||
f1ap_msg->gNB_CU_ue_id = required->gNB_CU_ue_id;
|
||||
f1ap_msg->gNB_DU_ue_id = required->gNB_DU_ue_id;
|
||||
f1ap_msg->du_to_cu_rrc_information = NULL;
|
||||
if (required->du_to_cu_rrc_information != NULL) {
|
||||
f1ap_msg->du_to_cu_rrc_information = calloc(1, sizeof(*f1ap_msg->du_to_cu_rrc_information));
|
||||
AssertFatal(f1ap_msg->du_to_cu_rrc_information != NULL, "out of memory\n");
|
||||
du_to_cu_rrc_information_t *du2cu = f1ap_msg->du_to_cu_rrc_information;
|
||||
AssertFatal(required->du_to_cu_rrc_information->cellGroupConfig != NULL && required->du_to_cu_rrc_information->cellGroupConfig_length > 0,
|
||||
"cellGroupConfig is mandatory\n");
|
||||
du2cu->cellGroupConfig_length = required->du_to_cu_rrc_information->cellGroupConfig_length;
|
||||
du2cu->cellGroupConfig = malloc(du2cu->cellGroupConfig_length * sizeof(*du2cu->cellGroupConfig));
|
||||
AssertFatal(du2cu->cellGroupConfig != NULL, "out of memory\n");
|
||||
memcpy(du2cu->cellGroupConfig, required->du_to_cu_rrc_information->cellGroupConfig, du2cu->cellGroupConfig_length);
|
||||
AssertFatal(required->du_to_cu_rrc_information->measGapConfig == NULL && required->du_to_cu_rrc_information->measGapConfig_length == 0, "not handled yet\n");
|
||||
AssertFatal(required->du_to_cu_rrc_information->requestedP_MaxFR1 == NULL && required->du_to_cu_rrc_information->requestedP_MaxFR1_length == 0, "not handled yet\n");
|
||||
}
|
||||
f1ap_msg->cause = required->cause;
|
||||
f1ap_msg->cause_value = required->cause_value;
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, 0, msg);
|
||||
}
|
||||
|
||||
static void ue_context_release_request_direct(const f1ap_ue_context_release_req_t* req)
|
||||
{
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_REQ);
|
||||
@@ -151,6 +176,7 @@ void mac_rrc_ul_direct_init(struct nr_mac_rrc_ul_if_s *mac_rrc)
|
||||
{
|
||||
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;
|
||||
mac_rrc->ue_context_release_request = ue_context_release_request_direct;
|
||||
mac_rrc->ue_context_release_complete = ue_context_release_complete_direct;
|
||||
mac_rrc->initial_ul_rrc_message_transfer = initial_ul_rrc_message_transfer_direct;
|
||||
|
||||
@@ -96,6 +96,31 @@ static void ue_context_modification_response_f1ap(const f1ap_ue_context_modif_re
|
||||
itti_send_msg_to_task(TASK_DU_F1, 0, msg);
|
||||
}
|
||||
|
||||
static void ue_context_modification_required_f1ap(const f1ap_ue_context_modif_required_t *required)
|
||||
{
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQUIRED);
|
||||
f1ap_ue_context_modif_required_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg);
|
||||
f1ap_msg->gNB_CU_ue_id = required->gNB_CU_ue_id;
|
||||
f1ap_msg->gNB_DU_ue_id = required->gNB_DU_ue_id;
|
||||
f1ap_msg->du_to_cu_rrc_information = NULL;
|
||||
if (required->du_to_cu_rrc_information != NULL) {
|
||||
f1ap_msg->du_to_cu_rrc_information = calloc(1, sizeof(*f1ap_msg->du_to_cu_rrc_information));
|
||||
AssertFatal(f1ap_msg->du_to_cu_rrc_information != NULL, "out of memory\n");
|
||||
du_to_cu_rrc_information_t *du2cu = f1ap_msg->du_to_cu_rrc_information;
|
||||
AssertFatal(required->du_to_cu_rrc_information->cellGroupConfig != NULL && required->du_to_cu_rrc_information->cellGroupConfig_length > 0,
|
||||
"cellGroupConfig is mandatory\n");
|
||||
du2cu->cellGroupConfig_length = required->du_to_cu_rrc_information->cellGroupConfig_length;
|
||||
du2cu->cellGroupConfig = malloc(du2cu->cellGroupConfig_length * sizeof(*du2cu->cellGroupConfig));
|
||||
AssertFatal(du2cu->cellGroupConfig != NULL, "out of memory\n");
|
||||
memcpy(du2cu->cellGroupConfig, required->du_to_cu_rrc_information->cellGroupConfig, du2cu->cellGroupConfig_length);
|
||||
AssertFatal(required->du_to_cu_rrc_information->measGapConfig == NULL && required->du_to_cu_rrc_information->measGapConfig_length == 0, "not handled yet\n");
|
||||
AssertFatal(required->du_to_cu_rrc_information->requestedP_MaxFR1 == NULL && required->du_to_cu_rrc_information->requestedP_MaxFR1_length == 0, "not handled yet\n");
|
||||
}
|
||||
f1ap_msg->cause = required->cause;
|
||||
f1ap_msg->cause_value = required->cause_value;
|
||||
itti_send_msg_to_task(TASK_DU_F1, 0, msg);
|
||||
}
|
||||
|
||||
static void ue_context_release_request_f1ap(const f1ap_ue_context_release_req_t* req)
|
||||
{
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_REQ);
|
||||
@@ -138,6 +163,7 @@ void mac_rrc_ul_f1ap_init(struct nr_mac_rrc_ul_if_s *mac_rrc)
|
||||
{
|
||||
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;
|
||||
mac_rrc->ue_context_release_request = ue_context_release_request_f1ap;
|
||||
mac_rrc->ue_context_release_complete = ue_context_release_complete_f1ap;
|
||||
mac_rrc->initial_ul_rrc_message_transfer = initial_ul_rrc_message_transfer_f1ap;
|
||||
|
||||
@@ -204,8 +204,6 @@ typedef struct {
|
||||
NR_CellGroupConfig_t *CellGroup;
|
||||
/// Preambles for contention-free access
|
||||
NR_preamble_ue_t preambles;
|
||||
/// NSA: the UEs C-RNTI to use
|
||||
rnti_t crnti;
|
||||
/// CFRA flag
|
||||
bool cfra;
|
||||
// BWP for RA
|
||||
@@ -660,6 +658,7 @@ typedef struct NR_bler_options {
|
||||
typedef struct nr_mac_rrc_ul_if_s {
|
||||
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;
|
||||
ue_context_release_request_func_t ue_context_release_request;
|
||||
ue_context_release_complete_func_t ue_context_release_complete;
|
||||
initial_ul_rrc_message_transfer_func_t initial_ul_rrc_message_transfer;
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
typedef void (*ue_context_setup_request_func_t)(const f1ap_ue_context_setup_t *req);
|
||||
typedef void (*ue_context_modification_request_func_t)(const f1ap_ue_context_modif_req_t *req);
|
||||
typedef void (*ue_context_modification_confirm_func_t)(const f1ap_ue_context_modif_confirm_t *confirm);
|
||||
typedef void (*ue_context_modification_refuse_func_t)(const f1ap_ue_context_modif_refuse_t *refuse);
|
||||
typedef void (*ue_context_release_command_func_t)(const f1ap_ue_context_release_cmd_t *cmd);
|
||||
|
||||
typedef void (*dl_rrc_message_transfer_func_t)(const f1ap_dl_rrc_message_t *dl_rrc);
|
||||
|
||||
@@ -28,6 +28,8 @@ void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc)
|
||||
{
|
||||
mac_rrc->ue_context_setup_request = ue_context_setup_request;
|
||||
mac_rrc->ue_context_modification_request = ue_context_modification_request;
|
||||
mac_rrc->ue_context_modification_confirm = ue_context_modification_confirm;
|
||||
mac_rrc->ue_context_modification_refuse = ue_context_modification_refuse;
|
||||
mac_rrc->ue_context_release_command = ue_context_release_command;
|
||||
mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer;
|
||||
}
|
||||
|
||||
@@ -71,6 +71,31 @@ static void ue_context_modification_request_f1ap(const f1ap_ue_context_modif_req
|
||||
itti_send_msg_to_task(TASK_CU_F1, 0, msg);
|
||||
}
|
||||
|
||||
static void ue_context_modification_confirm_f1ap(const f1ap_ue_context_modif_confirm_t *confirm)
|
||||
{
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_CONFIRM);
|
||||
f1ap_ue_context_modif_confirm_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_CONFIRM(msg);
|
||||
f1ap_msg->gNB_CU_ue_id = confirm->gNB_CU_ue_id;
|
||||
f1ap_msg->gNB_DU_ue_id = confirm->gNB_DU_ue_id;
|
||||
f1ap_msg->rrc_container = NULL;
|
||||
f1ap_msg->rrc_container_length = 0;
|
||||
if (confirm->rrc_container != NULL) {
|
||||
f1ap_msg->rrc_container = calloc(1, sizeof(*f1ap_msg->rrc_container));
|
||||
AssertFatal(f1ap_msg->rrc_container != NULL, "out of memory\n");
|
||||
memcpy(f1ap_msg->rrc_container, confirm->rrc_container, confirm->rrc_container_length);
|
||||
f1ap_msg->rrc_container_length = confirm->rrc_container_length;
|
||||
}
|
||||
itti_send_msg_to_task(TASK_CU_F1, 0, msg);
|
||||
}
|
||||
|
||||
static void ue_context_modification_refuse_f1ap(const f1ap_ue_context_modif_refuse_t *refuse)
|
||||
{
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REFUSE);
|
||||
f1ap_ue_context_modif_refuse_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_REFUSE(msg);
|
||||
*f1ap_msg = *refuse;
|
||||
itti_send_msg_to_task(TASK_CU_F1, 0, msg);
|
||||
}
|
||||
|
||||
static void ue_context_release_command_f1ap(const f1ap_ue_context_release_cmd_t *cmd)
|
||||
{
|
||||
MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD);
|
||||
@@ -110,6 +135,8 @@ void mac_rrc_dl_f1ap_init(nr_mac_rrc_dl_if_t *mac_rrc)
|
||||
{
|
||||
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;
|
||||
mac_rrc->ue_context_modification_refuse = ue_context_modification_refuse_f1ap;
|
||||
mac_rrc->ue_context_release_command = ue_context_release_command_f1ap;
|
||||
mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_f1ap;
|
||||
}
|
||||
|
||||
@@ -365,6 +365,8 @@ typedef struct {
|
||||
typedef struct nr_mac_rrc_dl_if_s {
|
||||
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;
|
||||
ue_context_modification_refuse_func_t ue_context_modification_refuse;
|
||||
ue_context_release_command_func_t ue_context_release_command;
|
||||
dl_rrc_message_transfer_func_t dl_rrc_message_transfer;
|
||||
} nr_mac_rrc_dl_if_t;
|
||||
|
||||
+77
-34
@@ -43,7 +43,6 @@
|
||||
#include "rrc_gNB_radio_bearers.h"
|
||||
|
||||
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
|
||||
#include "LAYER2/RLC/rlc.h"
|
||||
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "COMMON/mac_rrc_primitives.h"
|
||||
@@ -68,7 +67,6 @@
|
||||
#include "uper_encoder.h"
|
||||
#include "uper_decoder.h"
|
||||
|
||||
#include "rlc.h"
|
||||
#include "platform_types.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
|
||||
@@ -188,26 +186,6 @@ static void freeDRBlist(NR_DRB_ToAddModList_t *list)
|
||||
return;
|
||||
}
|
||||
|
||||
static void nr_rrc_addmod_drbs(int rnti,
|
||||
const NR_DRB_ToAddModList_t *drb_list,
|
||||
const struct NR_CellGroupConfig__rlc_BearerToAddModList *bearer_list)
|
||||
{
|
||||
if (drb_list == NULL || bearer_list == NULL)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < drb_list->list.count; i++) {
|
||||
const NR_DRB_ToAddMod_t *drb = drb_list->list.array[i];
|
||||
for (int j = 0; j < bearer_list->list.count; j++) {
|
||||
const NR_RLC_BearerConfig_t *bearer = bearer_list->list.array[j];
|
||||
if (bearer->servedRadioBearer != NULL
|
||||
&& bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity
|
||||
&& drb->drb_Identity == bearer->servedRadioBearer->choice.drb_Identity) {
|
||||
nr_rlc_add_drb(rnti, drb->drb_Identity, bearer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct deliver_dl_rrc_message_data_s {
|
||||
const gNB_RRC_INST *rrc;
|
||||
f1ap_dl_rrc_message_t *dl_rrc;
|
||||
@@ -994,14 +972,6 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co
|
||||
kUPint,
|
||||
get_softmodem_params()->sa ? ue_p->masterCellGroup->rlc_BearerToAddModList : NULL);
|
||||
|
||||
/* Refresh DRBs */
|
||||
if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
|
||||
LOG_D(NR_RRC,"Configuring RLC DRBs/SRBs for UE %04x\n",ue_context_pP->ue_context.rnti);
|
||||
const struct NR_CellGroupConfig__rlc_BearerToAddModList *bearer_list =
|
||||
ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList;
|
||||
nr_rrc_addmod_drbs(ctxt_pP->rntiMaybeUEid, DRB_configList, bearer_list);
|
||||
}
|
||||
|
||||
/* Loop through DRBs and establish if necessary */
|
||||
if (DRB_configList != NULL) {
|
||||
for (int i = 0; i < DRB_configList->list.count; i++) {
|
||||
@@ -1219,6 +1189,7 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP
|
||||
|
||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
|
||||
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
||||
ue_p->xids[xid] = RRC_DEDICATED_RECONF;
|
||||
|
||||
NR_CellGroupConfig_t *masterCellGroup = ue_p->masterCellGroup;
|
||||
if (dl_bwp_id > 0) {
|
||||
@@ -1247,18 +1218,22 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP
|
||||
NULL,
|
||||
masterCellGroup);
|
||||
|
||||
nr_rrc_mac_update_cellgroup(ue_context_pP->ue_context.rnti, masterCellGroup);
|
||||
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size);
|
||||
|
||||
if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) {
|
||||
uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated
|
||||
nr_rrc_mac_update_cellgroup(ue_context_pP->ue_context.rnti, masterCellGroup);
|
||||
|
||||
uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig
|
||||
&& ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated
|
||||
&& ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList
|
||||
? NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS
|
||||
: NR_RRC_RECONFIGURATION_DELAY_MS;
|
||||
|
||||
nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, ue_p->rnti, *rrc->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, delay_ms);
|
||||
nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id,
|
||||
ue_p->rnti,
|
||||
*rrc->carrier.servingcellconfigcommon->ssbSubcarrierSpacing,
|
||||
delay_ms);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1711,6 +1686,7 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_
|
||||
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p);
|
||||
break;
|
||||
case RRC_REESTABLISH_COMPLETE:
|
||||
case RRC_DEDICATED_RECONF:
|
||||
/* do nothing */
|
||||
break;
|
||||
default:
|
||||
@@ -2131,6 +2107,69 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, i
|
||||
}
|
||||
}
|
||||
|
||||
static void rrc_CU_process_ue_modification_required(MessageDef *msg_p)
|
||||
{
|
||||
f1ap_ue_context_modif_required_t *required = &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg_p);
|
||||
protocol_ctxt_t ctxt = {.rntiMaybeUEid = required->gNB_CU_ue_id, .module_id = 0, .instance = 0, .enb_flag = 1, .eNB_index = 0};
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, required->gNB_CU_ue_id);
|
||||
if (ue_context_p == NULL) {
|
||||
LOG_E(RRC, "Could not find UE context for CU UE ID %d, cannot handle UE context modification request\n", required->gNB_CU_ue_id);
|
||||
f1ap_ue_context_modif_refuse_t refuse = {
|
||||
.gNB_CU_ue_id = required->gNB_CU_ue_id,
|
||||
.gNB_DU_ue_id = required->gNB_DU_ue_id,
|
||||
.cause = F1AP_CAUSE_RADIO_NETWORK,
|
||||
.cause_value = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_cu_ue_f1ap_id,
|
||||
};
|
||||
rrc->mac_rrc.ue_context_modification_refuse(&refuse);
|
||||
return;
|
||||
}
|
||||
|
||||
if (required->du_to_cu_rrc_information && required->du_to_cu_rrc_information->cellGroupConfig) {
|
||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||
LOG_I(RRC,
|
||||
"UE Context Modification Required: new CellGroupConfig for UE ID %d/RNTI %04x, triggering reconfiguration\n",
|
||||
UE->rrc_ue_id,
|
||||
UE->rnti);
|
||||
|
||||
NR_CellGroupConfig_t *cellGroupConfig = NULL;
|
||||
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
|
||||
&asn_DEF_NR_CellGroupConfig,
|
||||
(void **)&cellGroupConfig,
|
||||
(uint8_t *)required->du_to_cu_rrc_information->cellGroupConfig,
|
||||
required->du_to_cu_rrc_information->cellGroupConfig_length);
|
||||
if (dec_rval.code != RC_OK && dec_rval.consumed == 0) {
|
||||
LOG_E(RRC, "Cell group config decode error, refusing reconfiguration\n");
|
||||
f1ap_ue_context_modif_refuse_t refuse = {
|
||||
.gNB_CU_ue_id = required->gNB_CU_ue_id,
|
||||
.gNB_DU_ue_id = required->gNB_DU_ue_id,
|
||||
.cause = F1AP_CAUSE_PROTOCOL,
|
||||
.cause_value = F1AP_CauseProtocol_transfer_syntax_error,
|
||||
};
|
||||
rrc->mac_rrc.ue_context_modification_refuse(&refuse);
|
||||
return;
|
||||
}
|
||||
|
||||
if (UE->masterCellGroup) {
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->masterCellGroup);
|
||||
LOG_I(RRC, "UE %d/RNTI %04x replacing existing CellGroupConfig with new one received from DU\n", UE->rrc_ue_id, UE->rnti);
|
||||
}
|
||||
UE->masterCellGroup = cellGroupConfig;
|
||||
if (LOG_DEBUGFLAG(DEBUG_ASN1))
|
||||
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, UE->masterCellGroup);
|
||||
|
||||
/* trigger reconfiguration */
|
||||
nr_rrc_reconfiguration_req(ue_context_p, &ctxt, 0, 0);
|
||||
//rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p);
|
||||
//rrc_gNB_generate_defaultRRCReconfiguration(&ctxt, ue_context_p);
|
||||
return;
|
||||
}
|
||||
LOG_W(RRC,
|
||||
"nothing to be done after UE Context Modification Required for UE ID %d/RNTI %04x\n",
|
||||
required->gNB_CU_ue_id,
|
||||
required->gNB_DU_ue_id);
|
||||
}
|
||||
|
||||
unsigned int mask_flip(unsigned int x) {
|
||||
return((((x>>8) + (x<<8))&0xffff)>>6);
|
||||
}
|
||||
@@ -2598,6 +2637,10 @@ void *rrc_gnb_task(void *args_p) {
|
||||
rrc_CU_process_ue_context_modification_response(msg_p, instance);
|
||||
break;
|
||||
|
||||
case F1AP_UE_CONTEXT_MODIFICATION_REQUIRED:
|
||||
rrc_CU_process_ue_modification_required(msg_p);
|
||||
break;
|
||||
|
||||
case F1AP_UE_CONTEXT_RELEASE_REQ:
|
||||
rrc_CU_process_ue_context_release_request(msg_p);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user