forked from acouzens/open5gs
mme: s1ap: Split rx HandoverRequired handling based on HandoverType
This is a preparation towards adding other handover types in the future.
This commit is contained in:
parent
154bff2764
commit
11d10fb009
|
@ -2331,6 +2331,74 @@ void s1ap_handle_enb_configuration_transfer(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void s1ap_handle_handover_required_intralte(enb_ue_t *source_ue,
|
||||||
|
S1AP_Cause_t *Cause, S1AP_TargetID_t *TargetID,
|
||||||
|
S1AP_Source_ToTarget_TransparentContainer_t *Source_ToTarget_TransparentContainer)
|
||||||
|
{
|
||||||
|
mme_enb_t *target_enb = NULL;
|
||||||
|
uint32_t target_enb_id = 0;
|
||||||
|
mme_ue_t *mme_ue = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
ogs_assert(source_ue);
|
||||||
|
ogs_assert(Cause);
|
||||||
|
ogs_assert(TargetID);
|
||||||
|
ogs_assert(Source_ToTarget_TransparentContainer);
|
||||||
|
|
||||||
|
switch (TargetID->present) {
|
||||||
|
case S1AP_TargetID_PR_targeteNB_ID:
|
||||||
|
ogs_s1ap_ENB_ID_to_uint32(
|
||||||
|
&TargetID->choice.targeteNB_ID->global_ENB_ID.eNB_ID,
|
||||||
|
&target_enb_id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ogs_error("Not implemented(%d)", TargetID->present);
|
||||||
|
r = s1ap_send_handover_preparation_failure(source_ue,
|
||||||
|
S1AP_Cause_PR_protocol, S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
target_enb = mme_enb_find_by_enb_id(target_enb_id);
|
||||||
|
if (target_enb == NULL) {
|
||||||
|
ogs_error("Handover required : cannot find target eNB-id[0x%x]",
|
||||||
|
target_enb_id);
|
||||||
|
r = s1ap_send_handover_preparation_failure(source_ue,
|
||||||
|
S1AP_Cause_PR_radioNetwork,
|
||||||
|
S1AP_CauseRadioNetwork_unknown_targetID);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mme_ue = source_ue->mme_ue;
|
||||||
|
if (!mme_ue) {
|
||||||
|
ogs_error("No UE(mme-ue) context");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SECURITY_CONTEXT_IS_VALID(mme_ue)) {
|
||||||
|
ogs_error("No Security Context");
|
||||||
|
r = s1ap_send_handover_preparation_failure(source_ue,
|
||||||
|
S1AP_Cause_PR_nas, S1AP_CauseNas_authentication_failure);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
source_ue->handover_type = S1AP_HandoverType_intralte;
|
||||||
|
|
||||||
|
mme_ue->nhcc++;
|
||||||
|
ogs_kdf_nh_enb(mme_ue->kasme, mme_ue->nh, mme_ue->nh);
|
||||||
|
|
||||||
|
r = s1ap_send_handover_request(
|
||||||
|
source_ue, target_enb, &source_ue->handover_type, Cause,
|
||||||
|
Source_ToTarget_TransparentContainer);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
void s1ap_handle_handover_required(mme_enb_t *enb, ogs_s1ap_message_t *message)
|
void s1ap_handle_handover_required(mme_enb_t *enb, ogs_s1ap_message_t *message)
|
||||||
{
|
{
|
||||||
char buf[OGS_ADDRSTRLEN];
|
char buf[OGS_ADDRSTRLEN];
|
||||||
|
@ -2358,9 +2426,6 @@ void s1ap_handle_handover_required(mme_enb_t *enb, ogs_s1ap_message_t *message)
|
||||||
ogs_assert(HandoverRequired);
|
ogs_assert(HandoverRequired);
|
||||||
|
|
||||||
enb_ue_t *source_ue = NULL;
|
enb_ue_t *source_ue = NULL;
|
||||||
mme_ue_t *mme_ue = NULL;
|
|
||||||
mme_enb_t *target_enb = NULL;
|
|
||||||
uint32_t target_enb_id = 0;
|
|
||||||
|
|
||||||
ogs_debug("HandoverRequired");
|
ogs_debug("HandoverRequired");
|
||||||
for (i = 0; i < HandoverRequired->protocolIEs.list.count; i++) {
|
for (i = 0; i < HandoverRequired->protocolIEs.list.count; i++) {
|
||||||
|
@ -2462,58 +2527,24 @@ void s1ap_handle_handover_required(mme_enb_t *enb, ogs_s1ap_message_t *message)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (TargetID->present) {
|
switch (*HandoverType) {
|
||||||
case S1AP_TargetID_PR_targeteNB_ID:
|
case S1AP_HandoverType_intralte:
|
||||||
ogs_s1ap_ENB_ID_to_uint32(
|
s1ap_handle_handover_required_intralte(source_ue, Cause, TargetID, Source_ToTarget_TransparentContainer);
|
||||||
&TargetID->choice.targeteNB_ID->global_ENB_ID.eNB_ID,
|
|
||||||
&target_enb_id);
|
|
||||||
break;
|
break;
|
||||||
default:
|
case S1AP_HandoverType_ltetoutran:
|
||||||
ogs_error("Not implemented(%d)", TargetID->present);
|
case S1AP_HandoverType_ltetogeran:
|
||||||
|
case S1AP_HandoverType_utrantolte:
|
||||||
|
case S1AP_HandoverType_gerantolte:
|
||||||
|
case S1AP_HandoverType_eps_to_5gs:
|
||||||
|
case S1AP_HandoverType_fivegs_to_eps:
|
||||||
|
default: /* Enumeration is extensible */
|
||||||
|
ogs_error("Rx Handover Required HandoverType=%ld not implemented!", *HandoverType);
|
||||||
r = s1ap_send_handover_preparation_failure(source_ue,
|
r = s1ap_send_handover_preparation_failure(source_ue,
|
||||||
S1AP_Cause_PR_protocol, S1AP_CauseProtocol_semantic_error);
|
S1AP_Cause_PR_protocol, S1AP_CauseProtocol_semantic_error);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
target_enb = mme_enb_find_by_enb_id(target_enb_id);
|
|
||||||
if (target_enb == NULL) {
|
|
||||||
ogs_error("Handover required : cannot find target eNB-id[0x%x]",
|
|
||||||
target_enb_id);
|
|
||||||
r = s1ap_send_handover_preparation_failure(source_ue,
|
|
||||||
S1AP_Cause_PR_radioNetwork,
|
|
||||||
S1AP_CauseRadioNetwork_unknown_targetID);
|
|
||||||
ogs_expect(r == OGS_OK);
|
|
||||||
ogs_assert(r != OGS_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mme_ue = source_ue->mme_ue;
|
|
||||||
if (!mme_ue) {
|
|
||||||
ogs_error("No UE(mme-ue) context");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SECURITY_CONTEXT_IS_VALID(mme_ue)) {
|
|
||||||
ogs_error("No Security Context");
|
|
||||||
r = s1ap_send_handover_preparation_failure(source_ue,
|
|
||||||
S1AP_Cause_PR_nas, S1AP_CauseNas_authentication_failure);
|
|
||||||
ogs_expect(r == OGS_OK);
|
|
||||||
ogs_assert(r != OGS_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
source_ue->handover_type = *HandoverType;
|
|
||||||
|
|
||||||
mme_ue->nhcc++;
|
|
||||||
ogs_kdf_nh_enb(mme_ue->kasme, mme_ue->nh, mme_ue->nh);
|
|
||||||
|
|
||||||
r = s1ap_send_handover_request(
|
|
||||||
source_ue, target_enb, HandoverType, Cause,
|
|
||||||
Source_ToTarget_TransparentContainer);
|
|
||||||
ogs_expect(r == OGS_OK);
|
|
||||||
ogs_assert(r != OGS_ERROR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void s1ap_handle_handover_request_ack(
|
void s1ap_handle_handover_request_ack(
|
||||||
|
|
Loading…
Reference in New Issue