feat: Add N2-Handover

This commit is contained in:
Sukchan Lee 2021-01-28 14:23:54 -05:00
parent 0fc5190a09
commit 49a9e58efe
47 changed files with 5084 additions and 808 deletions

View File

@ -183,6 +183,10 @@ typedef struct ogs_pfcp_far_s {
uint32_t num_of_buffered_packet;
ogs_pkbuf_t *buffered_packet[OGS_MAX_NUM_OF_PACKET_BUFFER];
struct {
bool prepared;
} handover; /* Saved from N2-Handover Request Acknowledge */
/* Related Context */
ogs_pfcp_sess_t *sess;
void *gnode;

View File

@ -80,7 +80,8 @@ typedef struct ogs_pfcp_xact_s {
#define OGS_PFCP_MODIFY_DEACTIVATE ((uint64_t)1<<9)
#define OGS_PFCP_MODIFY_END_MARKER ((uint64_t)1<<10)
#define OGS_PFCP_MODIFY_ERROR_INDICATION ((uint64_t)1<<11)
#define OGS_PFCP_MODIFY_PATH_SWITCH ((uint64_t)1<<12)
#define OGS_PFCP_MODIFY_XN_HANDOVER ((uint64_t)1<<12)
#define OGS_PFCP_MODIFY_N2_HANDOVER ((uint64_t)1<<13)
uint64_t modify_flags;
#define OGS_PFCP_DELETE_TRIGGER_UE_REQUESTED 1

View File

@ -136,7 +136,7 @@ typedef struct ogs_sbi_xact_s {
ogs_timer_t *t_response;
ogs_sbi_stream_t *assoc_stream;
uint8_t state;
int state;
ogs_sbi_object_t *sbi_object;
} ogs_sbi_xact_t;

View File

@ -418,7 +418,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
SWITCH(sbi_message.h.resource.component[2])
CASE(OGS_SBI_RESOURCE_NAME_MODIFY)
amf_nsmf_pdu_session_handle_update_sm_context(
amf_nsmf_pdusession_handle_update_sm_context(
sess, state, &sbi_message);
break;
@ -432,11 +432,11 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
amf_ue->supi, sbi_message.res_status);
}
amf_nsmf_pdu_session_handle_release_sm_context(sess, state);
amf_nsmf_pdusession_handle_release_sm_context(sess, state);
break;
DEFAULT
amf_nsmf_pdu_session_handle_create_sm_context(
amf_nsmf_pdusession_handle_create_sm_context(
sess, &sbi_message);
END
break;

View File

@ -975,6 +975,10 @@ ran_ue_t *ran_ue_add(amf_gnb_t *gnb, uint32_t ran_ue_ngap_id)
ran_ue->gnb_ostream_id =
OGS_NEXT_ID(gnb->ostream_id, 1, gnb->max_num_of_ostreams-1);
ran_ue->t_ng_holding = ogs_timer_add(
ogs_app()->timer_mgr, amf_timer_ng_holding_timer_expire, ran_ue);
ogs_assert(ran_ue->t_ng_holding);
ran_ue->gnb = gnb;
ogs_list_add(&gnb->ran_ue_list, ran_ue);
@ -991,8 +995,8 @@ void ran_ue_remove(ran_ue_t *ran_ue)
ogs_list_remove(&ran_ue->gnb->ran_ue_list, ran_ue);
if (ran_ue->t_ng_holding)
ogs_timer_delete(ran_ue->t_ng_holding);
ogs_assert(ran_ue->t_ng_holding);
ogs_timer_delete(ran_ue->t_ng_holding);
ogs_pool_free(&ran_ue_pool, ran_ue);
@ -1177,7 +1181,7 @@ void amf_ue_remove(amf_ue_t *amf_ue)
OGS_ASN_CLEAR_DATA(&amf_ue->ueRadioCapability);
/* Clear Transparent Container */
OGS_ASN_CLEAR_DATA(&amf_ue->container);
OGS_ASN_CLEAR_DATA(&amf_ue->handover.container);
/* Clear Paging Info */
AMF_UE_CLEAR_PAGING_INFO(amf_ue);
@ -1523,17 +1527,10 @@ void amf_sess_remove(amf_sess_t *sess)
if (sess->pdu_session_establishment_accept)
ogs_pkbuf_free(sess->pdu_session_establishment_accept);
if (sess->transfer.pdu_session_resource_setup_request)
ogs_pkbuf_free(sess->transfer.pdu_session_resource_setup_request);
sess->transfer.pdu_session_resource_setup_request = NULL;
if (sess->transfer.path_switch_request_ack)
ogs_pkbuf_free(sess->transfer.path_switch_request_ack);
sess->transfer.path_switch_request_ack = NULL;
if (sess->transfer.pdu_session_resource_release_command)
ogs_pkbuf_free(sess->transfer.pdu_session_resource_release_command);
sess->transfer.pdu_session_resource_release_command = NULL;
AMF_SESS_CLEAR_N2_TRANSFER(sess, pdu_session_resource_setup_request);
AMF_SESS_CLEAR_N2_TRANSFER(sess, path_switch_request_ack);
AMF_SESS_CLEAR_N2_TRANSFER(sess, handover_request);
AMF_SESS_CLEAR_N2_TRANSFER(sess, handover_command);
if (sess->paging.client)
ogs_sbi_client_remove(sess->paging.client);

View File

@ -162,7 +162,6 @@ struct ran_ue_s {
bool initial_context_setup_request_sent;
/* Handover Info */
NGAP_HandoverType_t handover_type;
ran_ue_t *source_ue;
ran_ue_t *target_ue;
@ -184,7 +183,7 @@ struct ran_ue_s {
#define NGAP_UE_CTX_REL_NG_CONTEXT_REMOVE 1
#define NGAP_UE_CTX_REL_NG_REMOVE_AND_UNLINK 2
#define NGAP_UE_CTX_REL_UE_CONTEXT_REMOVE 3
#define NGAP_UE_CTX_REL_DELETE_INDIRECT_TUNNEL 4
#define NGAP_UE_CTX_REL_NG_HANDOVER_COMPLETE 4
uint8_t ue_ctx_rel_action;
/* Related Context */
@ -387,8 +386,13 @@ struct amf_ue_s {
/* UE Radio Capability */
OCTET_STRING_t ueRadioCapability;
/* NGAP Transparent Container */
OCTET_STRING_t container;
/* Handover Info */
struct {
NGAP_HandoverType_t type;
OCTET_STRING_t container;
NGAP_Cause_PR group;
long cause;
} handover;
ogs_list_t sess_list;
};
@ -448,7 +452,8 @@ typedef struct amf_sess_s {
struct {
ogs_pkbuf_t *pdu_session_resource_setup_request;
ogs_pkbuf_t *path_switch_request_ack;
ogs_pkbuf_t *pdu_session_resource_release_command;
ogs_pkbuf_t *handover_request;
ogs_pkbuf_t *handover_command;
} transfer;
#define AMF_SESS_STORE_N2_TRANSFER(__sESS, __n2Type, __n2Buf) \
do { \
@ -463,14 +468,18 @@ typedef struct amf_sess_s {
ogs_assert(sess->transfer.__n2Type); \
} while(0);
#define AMF_SESS_CLEAR_N2_TRANSFER(__sESS, __n2Type) \
do { \
if ((__sESS)->transfer.__n2Type) \
ogs_pkbuf_free((__sESS)->transfer.__n2Type); \
(__sESS)->transfer.__n2Type = NULL; \
} while(0);
#define AMF_UE_CLEAR_N2_TRANSFER(__aMF, __n2Type) \
do { \
amf_sess_t *sess = NULL; \
ogs_list_for_each(&((__aMF)->sess_list), sess) { \
if (sess->transfer.__n2Type) { \
ogs_pkbuf_free(sess->transfer.__n2Type); \
sess->transfer.__n2Type = NULL; \
} \
AMF_SESS_CLEAR_N2_TRANSFER(sess, __n2Type) \
} \
} while(0);

View File

@ -305,7 +305,8 @@ int gmm_handle_registration_update(amf_ue_t *amf_ue,
ogs_list_for_each(&amf_ue->sess_list, sess) {
if (psimask & (1 << sess->psi)) {
if (SESSION_CONTEXT_IN_SMF(sess))
amf_sbi_send_activating_session(sess);
amf_sbi_send_activating_session(
sess, AMF_UPDATE_SM_CONTEXT_REGISTRATION_REQUEST);
}
}
}
@ -473,7 +474,8 @@ int gmm_handle_service_update(amf_ue_t *amf_ue,
ogs_list_for_each(&amf_ue->sess_list, sess) {
if (psimask & (1 << sess->psi)) {
if (SESSION_CONTEXT_IN_SMF(sess))
amf_sbi_send_activating_session(sess);
amf_sbi_send_activating_session(
sess, AMF_UPDATE_SM_CONTEXT_SERVICE_REQUEST);
}
}
}
@ -653,7 +655,7 @@ int gmm_handle_ul_nas_transport(amf_ue_t *amf_ue,
ogs_nas_5gs_ul_nas_transport_t *ul_nas_transport)
{
amf_sess_t *sess = NULL;
amf_nsmf_pdu_session_update_sm_context_param_t param;
amf_nsmf_pdusession_update_sm_context_param_t param;
ogs_nas_payload_container_type_t *payload_container_type = NULL;
ogs_nas_payload_container_t *payload_container = NULL;
@ -796,7 +798,7 @@ int gmm_handle_ul_nas_transport(amf_ue_t *amf_ue,
amf_sess_sbi_discover_and_send(OpenAPI_nf_type_SMF,
sess, AMF_SESS_SM_CONTEXT_NO_STATE, NULL,
amf_nsmf_pdu_session_build_create_sm_context);
amf_nsmf_pdusession_build_create_sm_context);
} else {
@ -819,7 +821,7 @@ int gmm_handle_ul_nas_transport(amf_ue_t *amf_ue,
amf_sess_sbi_discover_and_send(OpenAPI_nf_type_SMF,
sess, AMF_UPDATE_SM_CONTEXT_N1_RELEASED, &param,
amf_nsmf_pdu_session_build_update_sm_context);
amf_nsmf_pdusession_build_update_sm_context);
if (gsm_header->message_type ==
OGS_NAS_5GS_PDU_SESSION_RELEASE_COMPLETE) {

View File

@ -464,7 +464,7 @@ int amf_namf_callback_handle_sm_context_status(
sess->resource_status == OpenAPI_resource_status_RELEASED) {
ogs_debug("[%s:%d] SM context remove", amf_ue->supi, sess->psi);
amf_nsmf_pdu_session_handle_release_sm_context(
amf_nsmf_pdusession_handle_release_sm_context(
sess, AMF_SESS_SM_CONTEXT_NO_STATE);
}

File diff suppressed because it is too large Load Diff

View File

@ -52,31 +52,21 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command(
ogs_pkbuf_t *ngap_build_paging(amf_ue_t *amf_ue);
ogs_pkbuf_t *ngap_build_amf_configuration_transfer(
NGAP_SONConfigurationTransfer_t *son_configuration_transfer);
ogs_pkbuf_t *ngap_build_downlink_ran_configuration_transfer(
NGAP_SONConfigurationTransfer_t *transfer);
ogs_pkbuf_t *ngap_build_path_switch_ack(amf_ue_t *amf_ue);
ogs_pkbuf_t *ngap_build_handover_command(ran_ue_t *source_ue);
ogs_pkbuf_t *ngap_build_handover_request(ran_ue_t *target_ue);
ogs_pkbuf_t *ngap_build_handover_preparation_failure(
ran_ue_t *source_ue, NGAP_Cause_t *cause);
ogs_pkbuf_t *ngap_build_handover_request(
amf_ue_t *amf_ue, ran_ue_t *target_ue,
NGAP_RAN_UE_NGAP_ID_t *ran_ue_ngap_id,
NGAP_AMF_UE_NGAP_ID_t *amf_ue_ngap_id,
NGAP_HandoverType_t *handovertype,
NGAP_Cause_t *cause,
NGAP_SourceToTarget_TransparentContainer_t
*source_totarget_transparentContainer);
ogs_pkbuf_t *ngap_build_handover_command(ran_ue_t *source_ue);
ogs_pkbuf_t *ngap_build_handover_cancel_ack(ran_ue_t *source_ue);
ogs_pkbuf_t *ngap_build_handover_cancel_ack(
ran_ue_t *source_ue);
ogs_pkbuf_t *ngap_build_amf_status_transfer(
ogs_pkbuf_t *ngap_build_uplink_ran_status_transfer(
ran_ue_t *target_ue,
NGAP_RANStatusTransfer_TransparentContainer_t
*gnb_statustransfer_transparentContainer);
NGAP_RANStatusTransfer_TransparentContainer_t *transfer);
#ifdef __cplusplus
}

File diff suppressed because it is too large Load Diff

View File

@ -57,6 +57,9 @@ void ngap_handle_ue_context_release_complete(
amf_gnb_t *gnb, ogs_ngap_message_t *message);
void ngap_handle_ue_context_release_action(ran_ue_t *ran_ue);
void ngap_handle_uplink_ran_configuration_transfer(
amf_gnb_t *gnb, ogs_ngap_message_t *message, ogs_pkbuf_t *pkbuf);
void ngap_handle_path_switch_request(
amf_gnb_t *gnb, ogs_ngap_message_t *message);
@ -68,11 +71,8 @@ void ngap_handle_handover_failure(
amf_gnb_t *gnb, ogs_ngap_message_t *message);
void ngap_handle_handover_cancel(
amf_gnb_t *gnb, ogs_ngap_message_t *message);
void ngap_handle_gnb_status_transfer(
void ngap_handle_uplink_ran_status_transfer(
amf_gnb_t *gnb, ogs_ngap_message_t *message);
void ngap_handle_gnb_configuration_transfer(
amf_gnb_t *gnb, ogs_ngap_message_t *message, ogs_pkbuf_t *pkbuf);
void ngap_handle_handover_notification(
amf_gnb_t *gnb, ogs_ngap_message_t *message);

View File

@ -269,7 +269,7 @@ void ngap_send_ue_context_modification_request(amf_ue_t *amf_ue)
void ngap_send_ran_ue_context_release_command(
ran_ue_t *ran_ue, NGAP_Cause_PR group, long cause,
uint8_t action, uint32_t delay)
uint8_t action, ogs_time_t duration)
{
int rv;
ogs_pkbuf_t *ngapbuf = NULL;
@ -283,41 +283,34 @@ void ngap_send_ran_ue_context_release_command(
ogs_assert(action != NGAP_UE_CTX_REL_INVALID_ACTION);
ran_ue->ue_ctx_rel_action = action;
ogs_debug(" Group[%d] Cause[%d] Action[%d] Delay[%d]",
group, (int)cause, action, delay);
ogs_debug(" Group[%d] Cause[%d] Action[%d] Duration[%d]",
group, (int)cause, action, (int)duration);
ngapbuf = ngap_build_ue_context_release_command(ran_ue, group, cause);
ogs_expect_or_return(ngapbuf);
rv = ngap_delayed_send_to_ran_ue(ran_ue, ngapbuf, delay);
rv = ngap_delayed_send_to_ran_ue(ran_ue, ngapbuf, duration);
ogs_expect(rv == OGS_OK);
if (ran_ue->t_ng_holding)
ogs_timer_delete(ran_ue->t_ng_holding);
ran_ue->t_ng_holding = ogs_timer_add(
ogs_app()->timer_mgr, amf_timer_ng_holding_timer_expire, ran_ue);
ogs_assert(ran_ue->t_ng_holding);
ogs_timer_start(ran_ue->t_ng_holding,
amf_timer_cfg(AMF_TIMER_NG_HOLDING)->duration);
}
void ngap_send_amf_ue_context_release_command(
amf_ue_t *amf_ue, NGAP_Cause_PR group, long cause,
uint8_t action, uint32_t delay)
uint8_t action, ogs_time_t duration)
{
ogs_assert(amf_ue);
ran_ue_t *ran_ue = ran_ue_cycle(amf_ue->ran_ue);
if (ran_ue) {
ngap_send_ran_ue_context_release_command(ran_ue,
group, cause, action, delay);
group, cause, action, duration);
ogs_debug(" SUPI[%s]", amf_ue->supi);
} else {
ogs_error("[%s] No NG Context - "
"Group[%d] Cause[%d] Action[%d] Delay[%d]",
amf_ue->supi, group, (int)cause, action, delay);
"Group[%d] Cause[%d] Action[%d] Duration[%d]",
amf_ue->supi, group, (int)cause, action, (int)duration);
}
}
@ -392,26 +385,22 @@ void ngap_send_pdu_resource_setup_request(
}
}
#if 0
void ngap_send_amf_configuration_transfer(
amf_gnb_t *target_gnb,
NGAP_SONConfigurationTransfer_t *SONConfigurationTransfer)
void ngap_send_downlink_ran_configuration_transfer(
amf_gnb_t *target_gnb, NGAP_SONConfigurationTransfer_t *transfer)
{
int rv;
ogs_pkbuf_t *ngapbuf = NULL;
ogs_assert(target_gnb);
ogs_assert(SONConfigurationTransfer);
ogs_assert(transfer);
ngapbuf = ngap_build_amf_configuration_transfer(SONConfigurationTransfer);
ngapbuf = ngap_build_downlink_ran_configuration_transfer(transfer);
ogs_expect_or_return(ngapbuf);
rv = ngap_send_to_gnb(target_gnb, ngapbuf, NGAP_NON_UE_SIGNALLING);
ogs_expect(rv == OGS_OK);
}
#endif
void ngap_send_path_switch_ack(amf_sess_t *sess)
{
int rv;
@ -430,18 +419,23 @@ void ngap_send_path_switch_ack(amf_sess_t *sess)
ogs_expect(rv == OGS_OK);
}
#if 0
void ngap_send_handover_command(ran_ue_t *source_ue)
void ngap_send_handover_request(amf_ue_t *amf_ue)
{
int rv;
ran_ue_t *source_ue = NULL, *target_ue = NULL;
ogs_pkbuf_t *ngapbuf = NULL;
ogs_assert(amf_ue);
source_ue = amf_ue->ran_ue;
ogs_assert(source_ue);
target_ue = source_ue->target_ue;
ogs_assert(target_ue);
ngapbuf = ngap_build_handover_command(source_ue);
ngapbuf = ngap_build_handover_request(target_ue);
ogs_expect_or_return(ngapbuf);
rv = ngap_send_to_ran_ue(source_ue, ngapbuf);
rv = ngap_send_to_ran_ue(target_ue, ngapbuf);
ogs_expect(rv == OGS_OK);
}
@ -461,6 +455,24 @@ void ngap_send_handover_preparation_failure(
ogs_expect(rv == OGS_OK);
}
void ngap_send_handover_command(amf_ue_t *amf_ue)
{
int rv;
ran_ue_t *source_ue = NULL;
ogs_pkbuf_t *ngapbuf = NULL;
ogs_assert(amf_ue);
source_ue = amf_ue->ran_ue;
ogs_assert(source_ue);
ngapbuf = ngap_build_handover_command(source_ue);
ogs_expect_or_return(ngapbuf);
rv = ngap_send_to_ran_ue(source_ue, ngapbuf);
ogs_expect(rv == OGS_OK);
}
void ngap_send_handover_cancel_ack(ran_ue_t *source_ue)
{
int rv;
@ -475,69 +487,22 @@ void ngap_send_handover_cancel_ack(ran_ue_t *source_ue)
ogs_expect(rv == OGS_OK);
}
void ngap_send_handover_request(
amf_ue_t *amf_ue,
amf_gnb_t *target_gnb,
NGAP_RAN_UE_NGAP_ID_t *ran_ue_ngap_id,
NGAP_AMF_UE_NGAP_ID_t *amf_ue_ngap_id,
NGAP_HandoverType_t *handovertype,
NGAP_Cause_t *cause,
NGAP_Source_ToTarget_TransparentContainer_t
*source_totarget_transparentContainer)
{
int rv;
ogs_pkbuf_t *ngapbuf = NULL;
ran_ue_t *source_ue = NULL, *target_ue = NULL;
ogs_debug("[AMF] Handover request");
ogs_assert(target_gnb);
ogs_assert(amf_ue);
source_ue = ran_ue_cycle(amf_ue->ran_ue);
ogs_assert(source_ue);
ogs_assert(source_ue->target_ue == NULL);
target_ue = ran_ue_add(target_gnb, INVALID_UE_NGAP_ID);
ogs_assert(target_ue);
ogs_debug(" Source : RAN_UE_NGAP_ID[%d] AMF_UE_NGAP_ID[%d]",
source_ue->ran_ue_ngap_id, source_ue->amf_ue_ngap_id);
ogs_debug(" Target : RAN_UE_NGAP_ID[Unknown] AMF_UE_NGAP_ID[%d]",
target_ue->amf_ue_ngap_id);
source_ue_associate_target_ue(source_ue, target_ue);
ngapbuf = ngap_build_handover_request(amf_ue, target_ue,
ran_ue_ngap_id, amf_ue_ngap_id,
handovertype, cause,
source_totarget_transparentContainer);
ogs_expect_or_return(ngapbuf);
rv = ngap_send_to_ran_ue(target_ue, ngapbuf);
ogs_expect(rv == OGS_OK);
}
void ngap_send_amf_status_transfer(
void ngap_send_downlink_ran_status_transfer(
ran_ue_t *target_ue,
NGAP_RAN_StatusTransfer_TransparentContainer_t
*gnb_statustransfer_transparentContainer)
NGAP_RANStatusTransfer_TransparentContainer_t *transfer)
{
int rv;
ogs_pkbuf_t *ngapbuf = NULL;
ogs_assert(target_ue);
ogs_assert(transfer);
ngapbuf = ngap_build_amf_status_transfer(target_ue,
gnb_statustransfer_transparentContainer);
ngapbuf = ngap_build_uplink_ran_status_transfer(target_ue, transfer);
ogs_expect_or_return(ngapbuf);
rv = ngap_send_to_ran_ue(target_ue, ngapbuf);
ogs_expect(rv == OGS_OK);
}
#endif
void ngap_send_error_indication(
amf_gnb_t *gnb,

View File

@ -55,41 +55,30 @@ void ngap_send_ue_context_modification_request(amf_ue_t *amf_ue);
void ngap_send_ran_ue_context_release_command(
ran_ue_t *ran_ue, NGAP_Cause_PR group, long cause,
uint8_t action, uint32_t delay);
uint8_t action, ogs_time_t delay);
void ngap_send_amf_ue_context_release_command(
amf_ue_t *amf_ue, NGAP_Cause_PR group, long cause,
uint8_t action, uint32_t delay);
uint8_t action, ogs_time_t delay);
void ngap_send_paging(amf_ue_t *amf_ue);
void ngap_send_pdu_resource_setup_request(
amf_sess_t *sess, ogs_pkbuf_t *n2smbuf);
void ngap_send_amf_configuration_transfer(
amf_gnb_t *target_gnb,
NGAP_SONConfigurationTransfer_t *SONConfigurationTransfer);
void ngap_send_downlink_ran_configuration_transfer(
amf_gnb_t *target_gnb, NGAP_SONConfigurationTransfer_t *transfer);
void ngap_send_path_switch_ack(amf_sess_t *sess);
void ngap_send_handover_command(ran_ue_t *source_ue);
void ngap_send_handover_request(amf_ue_t *amf_ue);
void ngap_send_handover_preparation_failure(
ran_ue_t *source_ue, NGAP_Cause_t *cause);
void ngap_send_handover_request(
amf_ue_t *amf_ue,
amf_gnb_t *target_gnb,
NGAP_RAN_UE_NGAP_ID_t *ran_ue_ngap_id,
NGAP_AMF_UE_NGAP_ID_t *amf_ue_ngap_id,
NGAP_HandoverType_t *handovertype,
NGAP_Cause_t *cause,
NGAP_SourceToTarget_TransparentContainer_t
*source_totarget_transparentContainer);
void ngap_send_handover_command(amf_ue_t *amf_ue);
void ngap_send_handover_cancel_ack(ran_ue_t *source_ue);
void ngap_send_amf_status_transfer(
void ngap_send_downlink_ran_status_transfer(
ran_ue_t *target_ue,
NGAP_RANStatusTransfer_TransparentContainer_t
*gnb_statustransfer_transparentContainer);
NGAP_RANStatusTransfer_TransparentContainer_t *transfer);
void ngap_send_error_indication(
amf_gnb_t *gnb,
uint32_t *ran_ue_ngap_id,

View File

@ -40,9 +40,7 @@ void ngap_state_final(ogs_fsm_t *s, amf_event_t *e)
void ngap_state_operational(ogs_fsm_t *s, amf_event_t *e)
{
amf_gnb_t *gnb = NULL;
#if 0
ogs_pkbuf_t *pkbuf = NULL;
#endif
NGAP_NGAP_PDU_t *pdu = NULL;
NGAP_InitiatingMessage_t *initiatingMessage = NULL;
@ -97,26 +95,24 @@ void ngap_state_operational(ogs_fsm_t *s, amf_event_t *e)
case NGAP_ProcedureCode_id_PathSwitchRequest:
ngap_handle_path_switch_request(gnb, pdu);
break;
#if 0
case NGAP_ProcedureCode_id_eNBConfigurationTransfer:
case NGAP_ProcedureCode_id_UplinkRANConfigurationTransfer:
pkbuf = e->pkbuf;
ogs_assert(pkbuf);
ngap_handle_gnb_configuration_transfer(gnb, pdu, pkbuf);
ngap_handle_uplink_ran_configuration_transfer(gnb, pdu, pkbuf);
break;
case NGAP_ProcedureCode_id_HandoverPreparation:
ngap_handle_handover_required(gnb, pdu);
break;
case NGAP_ProcedureCode_id_HandoverCancel:
ngap_handle_handover_cancel(gnb, pdu);
break;
case NGAP_ProcedureCode_id_eNBStatusTransfer:
ngap_handle_gnb_status_transfer(gnb, pdu);
case NGAP_ProcedureCode_id_UplinkRANStatusTransfer:
ngap_handle_uplink_ran_status_transfer(gnb, pdu);
break;
case NGAP_ProcedureCode_id_HandoverNotification:
ngap_handle_handover_notification(gnb, pdu);
break;
#endif
case NGAP_ProcedureCode_id_HandoverCancel:
ngap_handle_handover_cancel(gnb, pdu);
break;
case NGAP_ProcedureCode_id_NGReset:
ngap_handle_ng_reset(gnb, pdu);
break;
@ -151,11 +147,9 @@ void ngap_state_operational(ogs_fsm_t *s, amf_event_t *e)
case NGAP_ProcedureCode_id_UEContextRelease:
ngap_handle_ue_context_release_complete(gnb, pdu);
break;
#if 0
case NGAP_ProcedureCode_id_HandoverResourceAllocation:
ngap_handle_handover_request_ack(gnb, pdu);
break;
#endif
default:
ogs_error("Not implemented(choice:%d, proc:%d)",
pdu->present, (int)successfulOutcome->procedureCode);
@ -174,10 +168,10 @@ void ngap_state_operational(ogs_fsm_t *s, amf_event_t *e)
case NGAP_ProcedureCode_id_UEContextModification:
ngap_handle_ue_context_modification_failure(gnb, pdu);
break;
#endif
case NGAP_ProcedureCode_id_HandoverResourceAllocation :
ngap_handle_handover_failure(gnb, pdu);
break;
#endif
default:
ogs_error("Not implemented(choice:%d, proc:%d)",
pdu->present, (int)unsuccessfulOutcome->procedureCode);

View File

@ -19,7 +19,7 @@
#include "nsmf-build.h"
ogs_sbi_request_t *amf_nsmf_pdu_session_build_create_sm_context(
ogs_sbi_request_t *amf_nsmf_pdusession_build_create_sm_context(
amf_sess_t *sess, void *data)
{
ogs_sbi_message_t message;
@ -157,10 +157,10 @@ ogs_sbi_request_t *amf_nsmf_pdu_session_build_create_sm_context(
return request;
}
ogs_sbi_request_t *amf_nsmf_pdu_session_build_update_sm_context(
ogs_sbi_request_t *amf_nsmf_pdusession_build_update_sm_context(
amf_sess_t *sess, void *data)
{
amf_nsmf_pdu_session_update_sm_context_param_t *param = data;
amf_nsmf_pdusession_update_sm_context_param_t *param = data;
ogs_sbi_message_t message;
ogs_sbi_request_t *request = NULL;
@ -225,16 +225,28 @@ ogs_sbi_request_t *amf_nsmf_pdu_session_build_update_sm_context(
if (param->upCnxState) {
SmContextUpdateData.up_cnx_state = param->upCnxState;
if (param->ngApCause.group) {
SmContextUpdateData.ng_ap_cause = &ngApCause;
memset(&ngApCause, 0, sizeof(ngApCause));
ngApCause.group = param->ngApCause.group;
ngApCause.value = param->ngApCause.value;
message.SmContextUpdateData = &SmContextUpdateData;
}
if (param->hoState) {
SmContextUpdateData.ho_state = param->hoState;
if (param->TargetID) {
SmContextUpdateData.target_id =
amf_nsmf_pdusession_build_target_id(param->TargetID);
ogs_assert(SmContextUpdateData.target_id);
}
message.SmContextUpdateData = &SmContextUpdateData;
}
if (param->ngApCause.group) {
SmContextUpdateData.ng_ap_cause = &ngApCause;
memset(&ngApCause, 0, sizeof(ngApCause));
ngApCause.group = param->ngApCause.group;
ngApCause.value = param->ngApCause.value;
}
memset(&ueLocation, 0, sizeof(ueLocation));
if (param->ue_location) {
ueLocation.nr_location = ogs_sbi_build_nr_location(
@ -260,11 +272,14 @@ ogs_sbi_request_t *amf_nsmf_pdu_session_build_update_sm_context(
}
if (SmContextUpdateData.ue_time_zone)
ogs_free(SmContextUpdateData.ue_time_zone);
if (SmContextUpdateData.target_id)
amf_nsmf_pdusession_free_target_id(SmContextUpdateData.target_id);
return request;
}
ogs_sbi_request_t *amf_nsmf_pdu_session_build_release_sm_context(
ogs_sbi_request_t *amf_nsmf_pdusession_build_release_sm_context(
amf_sess_t *sess, void *data)
{
ogs_sbi_message_t message;
@ -361,3 +376,109 @@ ogs_sbi_request_t *amf_nsmf_callback_build_n1_n2_failure_notify(
return request;
}
OpenAPI_ng_ran_target_id_t *amf_nsmf_pdusession_build_target_id(
NGAP_TargetID_t *TargetID)
{
ogs_plmn_id_t plmn_id;
ogs_5gs_tai_t nr_tai;
NGAP_TargetRANNodeID_t *targetRANNodeID = NULL;
NGAP_GlobalRANNodeID_t *globalRANNodeID = NULL;
NGAP_GlobalGNB_ID_t *globalGNB_ID = NULL;
OpenAPI_ng_ran_target_id_t *targetId = NULL;
OpenAPI_global_ran_node_id_t *ranNodeId = NULL;
OpenAPI_g_nb_id_t *gNbId = NULL;
OpenAPI_tai_t *tai = NULL;
ogs_assert(TargetID);
if (TargetID->present != NGAP_TargetID_PR_targetRANNodeID) {
ogs_error("Not implemented TargetID[%d]", TargetID->present);
return NULL;
}
targetRANNodeID = TargetID->choice.targetRANNodeID;
if (!targetRANNodeID) {
ogs_error("No targetRANNodeID");
return NULL;
}
globalRANNodeID = &targetRANNodeID->globalRANNodeID;
if (globalRANNodeID->present != NGAP_GlobalRANNodeID_PR_globalGNB_ID) {
ogs_error("Not implemented globalRANNodeID[%d]",
globalRANNodeID->present);
return NULL;
}
globalGNB_ID = globalRANNodeID->choice.globalGNB_ID;
if (!globalGNB_ID) {
ogs_error("No globalGNB_ID");
return NULL;
}
targetId = ogs_calloc(1, sizeof(*targetId));
ogs_assert(targetId);
targetId->ran_node_id = ranNodeId = ogs_calloc(1, sizeof(*ranNodeId));;
ogs_assert(ranNodeId);
memcpy(&plmn_id, globalGNB_ID->pLMNIdentity.buf, OGS_PLMN_ID_LEN);
ranNodeId->plmn_id = ogs_sbi_build_plmn_id(&plmn_id);
ogs_assert(ranNodeId->plmn_id);
ranNodeId->g_nb_id = gNbId = ogs_calloc(1, sizeof(*gNbId));
ogs_assert(gNbId);
gNbId->g_nb_value = ogs_calloc(
1, OGS_KEYSTRLEN(globalGNB_ID->gNB_ID.choice.gNB_ID.size));
ogs_assert(gNbId->g_nb_value);
ogs_hex_to_ascii(
globalGNB_ID->gNB_ID.choice.gNB_ID.buf,
globalGNB_ID->gNB_ID.choice.gNB_ID.size,
gNbId->g_nb_value,
OGS_KEYSTRLEN(globalGNB_ID->gNB_ID.choice.gNB_ID.size));
gNbId->bit_length = 32 - globalGNB_ID->gNB_ID.choice.gNB_ID.bits_unused;
targetId->tai = tai = ogs_calloc(1, sizeof(*tai));;
ogs_assert(tai);
ogs_ngap_ASN_to_5gs_tai(&targetRANNodeID->selectedTAI, &nr_tai);
tai->plmn_id = ogs_sbi_build_plmn_id(&nr_tai.plmn_id);
ogs_assert(tai->plmn_id);
tai->tac = ogs_uint24_to_0string(nr_tai.tac);
ogs_assert(tai->tac);
return targetId;
}
void amf_nsmf_pdusession_free_target_id(OpenAPI_ng_ran_target_id_t *targetId)
{
ogs_assert(targetId);
if (targetId->ran_node_id) {
OpenAPI_global_ran_node_id_t *ranNodeId = targetId->ran_node_id;
OpenAPI_tai_t *tai = targetId->tai;
if (ranNodeId) {
if (ranNodeId->plmn_id)
OpenAPI_plmn_id_free(ranNodeId->plmn_id);
if (ranNodeId->g_nb_id) {
OpenAPI_g_nb_id_t *gNbId = ranNodeId->g_nb_id;
if (gNbId->g_nb_value)
ogs_free(gNbId->g_nb_value);
ogs_free(gNbId);
}
ogs_free(ranNodeId);
}
if (tai) {
if (tai->plmn_id)
OpenAPI_plmn_id_free(tai->plmn_id);
if (tai->tac)
ogs_free(tai->tac);
ogs_free(tai);
}
}
ogs_free(targetId);
}

View File

@ -26,7 +26,7 @@
extern "C" {
#endif
typedef struct amf_nsmf_pdu_session_update_sm_context_param_s {
typedef struct amf_nsmf_pdusession_update_sm_context_param_s {
ogs_pkbuf_t *n1smbuf;
ogs_pkbuf_t *n2smbuf;
OpenAPI_n2_sm_info_type_e n2SmInfoType;
@ -43,18 +43,27 @@ typedef struct amf_nsmf_pdu_session_update_sm_context_param_s {
};
uint8_t indications;
};
} amf_nsmf_pdu_session_update_sm_context_param_t;
ogs_sbi_request_t *amf_nsmf_pdu_session_build_create_sm_context(
OpenAPI_ho_state_e hoState;
OpenAPI_ng_ran_target_id_t *targetId;
NGAP_TargetID_t *TargetID;
} amf_nsmf_pdusession_update_sm_context_param_t;
ogs_sbi_request_t *amf_nsmf_pdusession_build_create_sm_context(
amf_sess_t *sess, void *data);
ogs_sbi_request_t *amf_nsmf_pdu_session_build_update_sm_context(
ogs_sbi_request_t *amf_nsmf_pdusession_build_update_sm_context(
amf_sess_t *sess, void *data);
ogs_sbi_request_t *amf_nsmf_pdu_session_build_release_sm_context(
ogs_sbi_request_t *amf_nsmf_pdusession_build_release_sm_context(
amf_sess_t *sess, void *data);
ogs_sbi_request_t *amf_nsmf_callback_build_n1_n2_failure_notify(
amf_sess_t *sess, OpenAPI_n1_n2_message_transfer_cause_e cause);
OpenAPI_ng_ran_target_id_t *amf_nsmf_pdusession_build_target_id(
NGAP_TargetID_t *TargetID);
void amf_nsmf_pdusession_free_target_id(OpenAPI_ng_ran_target_id_t *targetId);
#ifdef __cplusplus
}
#endif

View File

@ -24,7 +24,7 @@
#include "gmm-build.h"
int amf_nsmf_pdu_session_handle_create_sm_context(
int amf_nsmf_pdusession_handle_create_sm_context(
amf_sess_t *sess, ogs_sbi_message_t *recvmsg)
{
int rv;
@ -142,7 +142,7 @@ int amf_nsmf_pdu_session_handle_create_sm_context(
return OGS_OK;
}
int amf_nsmf_pdu_session_handle_update_sm_context(
int amf_nsmf_pdusession_handle_update_sm_context(
amf_sess_t *sess, int state, ogs_sbi_message_t *recvmsg)
{
amf_ue_t *amf_ue = NULL;
@ -189,44 +189,46 @@ int amf_nsmf_pdu_session_handle_update_sm_context(
return OGS_ERROR;
}
/*
* To Deliver N2 SM Content to gNB Temporarily,
* Store N2 SM Context in Session Context
*/
AMF_SESS_STORE_N2_TRANSFER(
sess, pdu_session_resource_setup_request,
ogs_pkbuf_copy(n2smbuf));
if (state == AMF_UPDATE_SM_CONTEXT_REGISTRATION_REQUEST) {
AMF_SESS_STORE_N2_TRANSFER(
sess, pdu_session_resource_setup_request,
ogs_pkbuf_copy(n2smbuf));
switch(amf_ue->nas.message_type) {
case OGS_NAS_5GS_REGISTRATION_REQUEST:
if (SESSION_SYNC_DONE(amf_ue,
AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT) &&
SESSION_SYNC_DONE(amf_ue,
AMF_UPDATE_SM_CONTEXT_ACTIVATING)) {
AMF_UPDATE_SM_CONTEXT_REGISTRATION_REQUEST)) {
nas_5gs_send_registration_accept(amf_ue);
/* After sending accept message,
* N2 tranfer message is freed */
AMF_UE_CLEAR_N2_TRANSFER(
amf_ue, pdu_session_resource_setup_request);
}
break;
case OGS_NAS_5GS_SERVICE_REQUEST:
} else if (state == AMF_UPDATE_SM_CONTEXT_SERVICE_REQUEST) {
AMF_SESS_STORE_N2_TRANSFER(
sess, pdu_session_resource_setup_request,
ogs_pkbuf_copy(n2smbuf));
if (SESSION_SYNC_DONE(amf_ue,
AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT) &&
SESSION_SYNC_DONE(amf_ue,
AMF_UPDATE_SM_CONTEXT_ACTIVATING)) {
AMF_UPDATE_SM_CONTEXT_SERVICE_REQUEST)) {
nas_5gs_send_service_accept(amf_ue);
/* After sending accept message,
* N2 tranfer message is freed */
AMF_UE_CLEAR_N2_TRANSFER(
amf_ue, pdu_session_resource_setup_request);
}
break;
default:
ogs_error("Unknown message type [%d]",
amf_ue->nas.message_type);
} else if (state == AMF_UPDATE_SM_CONTEXT_HANDOVER_REQUIRED) {
AMF_SESS_STORE_N2_TRANSFER(
sess, handover_request, ogs_pkbuf_copy(n2smbuf));
if (SESSION_SYNC_DONE(amf_ue,
AMF_UPDATE_SM_CONTEXT_HANDOVER_REQUIRED)) {
ngap_send_handover_request(amf_ue);
AMF_UE_CLEAR_N2_TRANSFER(amf_ue, handover_request);
}
} else {
ogs_error("Invalid STATE[%d]", state);
ogs_assert_if_reached();
}
break;
@ -271,10 +273,6 @@ int amf_nsmf_pdu_session_handle_update_sm_context(
return OGS_ERROR;
}
/*
* To Deliver N2 SM Content to gNB Temporarily,
* Store N2 SM Context in Session Context
*/
AMF_SESS_STORE_N2_TRANSFER(
sess, path_switch_request_ack,
ogs_pkbuf_copy(n2smbuf));
@ -282,11 +280,30 @@ int amf_nsmf_pdu_session_handle_update_sm_context(
if (SESSION_SYNC_DONE(amf_ue, state)) {
ngap_send_path_switch_ack(sess);
/* After sending ack message, N2 SM context is freed */
AMF_UE_CLEAR_N2_TRANSFER(amf_ue, path_switch_request_ack);
}
break;
case OpenAPI_n2_sm_info_type_HANDOVER_CMD:
if (!n2smbuf) {
ogs_error("[%s:%d] No N2 SM Content",
amf_ue->supi, sess->psi);
ngap_send_error_indication2(amf_ue,
NGAP_Cause_PR_protocol,
NGAP_CauseProtocol_semantic_error);
return OGS_ERROR;
}
AMF_SESS_STORE_N2_TRANSFER(
sess, handover_command, ogs_pkbuf_copy(n2smbuf));
if (SESSION_SYNC_DONE(amf_ue, state)) {
ngap_send_handover_command(amf_ue);
AMF_UE_CLEAR_N2_TRANSFER(amf_ue, handover_command);
}
break;
default:
ogs_error("Not implemented [%d]",
SmContextUpdatedData->n2_sm_info_type);
@ -335,7 +352,12 @@ int amf_nsmf_pdu_session_handle_update_sm_context(
NGAP_UE_CTX_REL_NG_REMOVE_AND_UNLINK, 0);
}
} else if (state == AMF_UPDATE_SM_CONTEXT_ACTIVATING) {
} else if (state == AMF_UPDATE_SM_CONTEXT_REGISTRATION_REQUEST) {
/* Not reached here */
ogs_assert_if_reached();
} else if (state == AMF_UPDATE_SM_CONTEXT_SERVICE_REQUEST) {
/* Not reached here */
ogs_assert_if_reached();
@ -363,6 +385,56 @@ int amf_nsmf_pdu_session_handle_update_sm_context(
sess->n1_released = true;
} else if (state == AMF_UPDATE_SM_CONTEXT_PATH_SWITCH_REQUEST) {
/* Not reached here */
ogs_assert_if_reached();
} else if (state == AMF_UPDATE_SM_CONTEXT_HANDOVER_REQUIRED) {
/* Not reached here */
ogs_assert_if_reached();
} else if (state == AMF_UPDATE_SM_CONTEXT_HANDOVER_REQ_ACK) {
/* Not reached here */
ogs_assert_if_reached();
} else if (state == AMF_UPDATE_SM_CONTEXT_HANDOVER_CANCEL) {
if (SESSION_SYNC_DONE(amf_ue, state)) {
ran_ue_t *source_ue = NULL, *target_ue = NULL;
source_ue = amf_ue->ran_ue;
ogs_assert(source_ue);
target_ue = source_ue->target_ue;
ogs_assert(target_ue);
ngap_send_handover_cancel_ack(source_ue);
ngap_send_ran_ue_context_release_command(target_ue,
NGAP_Cause_PR_radioNetwork,
NGAP_CauseRadioNetwork_handover_cancelled,
NGAP_UE_CTX_REL_NG_HANDOVER_COMPLETE,
ogs_time_from_msec(300));
}
} else if (state == AMF_UPDATE_SM_CONTEXT_HANDOVER_NOTIFY) {
if (SESSION_SYNC_DONE(amf_ue, state)) {
ran_ue_t *target_ue = NULL, *source_ue = NULL;
target_ue = amf_ue->ran_ue;
ogs_assert(target_ue);
source_ue = target_ue->source_ue;
ogs_assert(source_ue);
ngap_send_ran_ue_context_release_command(source_ue,
NGAP_Cause_PR_radioNetwork,
NGAP_CauseRadioNetwork_successful_handover,
NGAP_UE_CTX_REL_NG_HANDOVER_COMPLETE,
ogs_time_from_msec(300));
}
} else if (state == AMF_REMOVE_S1_CONTEXT_BY_LO_CONNREFUSED) {
if (SESSION_SYNC_DONE(amf_ue, state)) {
ran_ue_t *ran_ue = ran_ue_cycle(amf_ue->ran_ue);
@ -406,20 +478,21 @@ int amf_nsmf_pdu_session_handle_update_sm_context(
} else {
ogs_error("Invalid STATE[%d]", state);
ogs_assert_if_reached();
}
/*
* If resource-status has already been updated by
* notify(/namf-callback/v1/{supi}/sm-context-status/{psi})
* Remove 'amf_sess_t' context to call
* amf_nsmf_pdu_session_handle_release_sm_context().
* amf_nsmf_pdusession_handle_release_sm_context().
*/
if (sess->n1_released == true &&
sess->n2_released == true &&
sess->resource_status == OpenAPI_resource_status_RELEASED) {
ogs_debug("[%s:%d] SM context remove", amf_ue->supi, sess->psi);
amf_nsmf_pdu_session_handle_release_sm_context(
amf_nsmf_pdusession_handle_release_sm_context(
sess, AMF_SESS_SM_CONTEXT_NO_STATE);
}
}
@ -499,7 +572,7 @@ int amf_nsmf_pdu_session_handle_update_sm_context(
return OGS_OK;
}
int amf_nsmf_pdu_session_handle_release_sm_context(amf_sess_t *sess, int state)
int amf_nsmf_pdusession_handle_release_sm_context(amf_sess_t *sess, int state)
{
amf_ue_t *amf_ue = NULL;
@ -515,9 +588,10 @@ int amf_nsmf_pdu_session_handle_release_sm_context(amf_sess_t *sess, int state)
* 2. Release All SM contexts
* 3. Registration accept
*/
if (SESSION_SYNC_DONE(amf_ue,
AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT) &&
SESSION_SYNC_DONE(amf_ue, AMF_UPDATE_SM_CONTEXT_ACTIVATING))
if (SESSION_SYNC_DONE(
amf_ue, AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT) &&
SESSION_SYNC_DONE(
amf_ue, AMF_UPDATE_SM_CONTEXT_REGISTRATION_REQUEST))
nas_5gs_send_registration_accept(amf_ue);
} else if (state == AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT) {
@ -527,7 +601,7 @@ int amf_nsmf_pdu_session_handle_release_sm_context(amf_sess_t *sess, int state)
* 3. Service accept
*/
if (SESSION_SYNC_DONE(amf_ue, AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT) &&
SESSION_SYNC_DONE(amf_ue, AMF_UPDATE_SM_CONTEXT_ACTIVATING))
SESSION_SYNC_DONE(amf_ue, AMF_UPDATE_SM_CONTEXT_SERVICE_REQUEST))
nas_5gs_send_service_accept(amf_ue);
} else {

View File

@ -26,11 +26,11 @@ extern "C" {
#include "context.h"
int amf_nsmf_pdu_session_handle_create_sm_context(
int amf_nsmf_pdusession_handle_create_sm_context(
amf_sess_t *sess, ogs_sbi_message_t *message);
int amf_nsmf_pdu_session_handle_update_sm_context(
int amf_nsmf_pdusession_handle_update_sm_context(
amf_sess_t *sess, int state, ogs_sbi_message_t *recvmsg);
int amf_nsmf_pdu_session_handle_release_sm_context(amf_sess_t *sess, int state);
int amf_nsmf_pdusession_handle_release_sm_context(amf_sess_t *sess, int state);
#ifdef __cplusplus
}

View File

@ -167,9 +167,9 @@ void amf_sess_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
}
}
void amf_sbi_send_activating_session(amf_sess_t *sess)
void amf_sbi_send_activating_session(amf_sess_t *sess, int state)
{
amf_nsmf_pdu_session_update_sm_context_param_t param;
amf_nsmf_pdusession_update_sm_context_param_t param;
ogs_assert(sess);
@ -177,14 +177,14 @@ void amf_sbi_send_activating_session(amf_sess_t *sess)
param.upCnxState = OpenAPI_up_cnx_state_ACTIVATING;
amf_sess_sbi_discover_and_send(OpenAPI_nf_type_SMF,
sess, AMF_UPDATE_SM_CONTEXT_ACTIVATING, &param,
amf_nsmf_pdu_session_build_update_sm_context);
sess, state, &param,
amf_nsmf_pdusession_build_update_sm_context);
}
void amf_sbi_send_deactivate_session(
amf_sess_t *sess, int state, int group, int cause)
{
amf_nsmf_pdu_session_update_sm_context_param_t param;
amf_nsmf_pdusession_update_sm_context_param_t param;
ogs_assert(sess);
@ -196,7 +196,7 @@ void amf_sbi_send_deactivate_session(
param.ue_timezone = true;
amf_sess_sbi_discover_and_send(OpenAPI_nf_type_SMF,
sess, state, &param, amf_nsmf_pdu_session_build_update_sm_context);
sess, state, &param, amf_nsmf_pdusession_build_update_sm_context);
}
void amf_sbi_send_deactivate_all_sessions(
@ -258,7 +258,7 @@ void amf_sbi_send_release_session(amf_sess_t *sess, int state)
amf_sess_sbi_discover_and_send(
OpenAPI_nf_type_SMF, sess, state, NULL,
amf_nsmf_pdu_session_build_release_sm_context);
amf_nsmf_pdusession_build_release_sm_context);
/* Prevent to invoke SMF for this session */
CLEAR_SM_CONTEXT_REF(sess);

View File

@ -38,23 +38,29 @@ void amf_ue_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
ogs_sbi_request_t *(*build)(amf_ue_t *amf_ue, void *data));
#define AMF_SESS_SM_CONTEXT_NO_STATE 0
#define AMF_UPDATE_SM_CONTEXT_ACTIVATED 1
#define AMF_UPDATE_SM_CONTEXT_DEACTIVATED 2
#define AMF_UPDATE_SM_CONTEXT_ACTIVATING 3
#define AMF_UPDATE_SM_CONTEXT_MODIFIED 4
#define AMF_UPDATE_SM_CONTEXT_N2_RELEASED 5
#define AMF_UPDATE_SM_CONTEXT_N1_RELEASED 6
#define AMF_RELEASE_SM_CONTEXT_NG_CONTEXT_REMOVE 7
#define AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT 8
#define AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT 9
#define AMF_REMOVE_S1_CONTEXT_BY_LO_CONNREFUSED 10
#define AMF_REMOVE_S1_CONTEXT_BY_RESET_ALL 11
#define AMF_REMOVE_S1_CONTEXT_BY_RESET_PARTIAL 12
#define AMF_UPDATE_SM_CONTEXT_ACTIVATED 11
#define AMF_UPDATE_SM_CONTEXT_DEACTIVATED 12
#define AMF_UPDATE_SM_CONTEXT_REGISTRATION_REQUEST 13
#define AMF_UPDATE_SM_CONTEXT_SERVICE_REQUEST 14
#define AMF_UPDATE_SM_CONTEXT_MODIFIED 15
#define AMF_UPDATE_SM_CONTEXT_N2_RELEASED 16
#define AMF_UPDATE_SM_CONTEXT_N1_RELEASED 17
#define AMF_UPDATE_SM_CONTEXT_PATH_SWITCH_REQUEST 18
#define AMF_UPDATE_SM_CONTEXT_HANDOVER_REQUIRED 19
#define AMF_UPDATE_SM_CONTEXT_HANDOVER_REQ_ACK 20
#define AMF_UPDATE_SM_CONTEXT_HANDOVER_NOTIFY 21
#define AMF_UPDATE_SM_CONTEXT_HANDOVER_CANCEL 22
#define AMF_RELEASE_SM_CONTEXT_NG_CONTEXT_REMOVE 31
#define AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT 32
#define AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT 33
#define AMF_REMOVE_S1_CONTEXT_BY_LO_CONNREFUSED 51
#define AMF_REMOVE_S1_CONTEXT_BY_RESET_ALL 52
#define AMF_REMOVE_S1_CONTEXT_BY_RESET_PARTIAL 53
void amf_sess_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
amf_sess_t *sess, int state, void *data,
ogs_sbi_request_t *(*build)(amf_sess_t *sess, void *data));
void amf_sbi_send_activating_session(amf_sess_t *sess);
void amf_sbi_send_activating_session(amf_sess_t *sess, int state);
void amf_sbi_send_deactivate_session(
amf_sess_t *sess, int state, int group, int cause);

View File

@ -2027,6 +2027,10 @@ enb_ue_t *enb_ue_add(mme_enb_t *enb, uint32_t enb_ue_s1ap_id)
enb_ue->enb_ostream_id =
OGS_NEXT_ID(enb->ostream_id, 1, enb->max_num_of_ostreams-1);
enb_ue->t_s1_holding = ogs_timer_add(
ogs_app()->timer_mgr, mme_timer_s1_holding_timer_expire, enb_ue);
ogs_assert(enb_ue->t_s1_holding);
enb_ue->enb = enb;
ogs_list_add(&enb->enb_ue_list, enb_ue);
@ -2046,8 +2050,8 @@ void enb_ue_remove(enb_ue_t *enb_ue)
ogs_list_remove(&enb->enb_ue_list, enb_ue);
if (enb_ue->t_s1_holding)
ogs_timer_delete(enb_ue->t_s1_holding);
ogs_assert(enb_ue->t_s1_holding);
ogs_timer_delete(enb_ue->t_s1_holding);
ogs_pool_free(&enb_ue_pool, enb_ue);

View File

@ -262,7 +262,7 @@ struct enb_ue_s {
#define S1AP_UE_CTX_REL_S1_CONTEXT_REMOVE 1
#define S1AP_UE_CTX_REL_S1_REMOVE_AND_UNLINK 2
#define S1AP_UE_CTX_REL_UE_CONTEXT_REMOVE 3
#define S1AP_UE_CTX_REL_DELETE_INDIRECT_TUNNEL 4
#define S1AP_UE_CTX_REL_S1_HANDOVER_COMPLETE 4
#define S1AP_UE_CTX_REL_S1_PAGING 5
uint8_t ue_ctx_rel_action;

View File

@ -304,7 +304,7 @@ void mme_s11_handle_modify_bearer_response(
s1ap_send_ue_context_release_command(source_ue,
S1AP_Cause_PR_radioNetwork,
S1AP_CauseRadioNetwork_successful_handover,
S1AP_UE_CTX_REL_DELETE_INDIRECT_TUNNEL,
S1AP_UE_CTX_REL_S1_HANDOVER_COMPLETE,
ogs_time_from_msec(300));
);
}

View File

@ -1782,13 +1782,9 @@ ogs_pkbuf_t *s1ap_build_handover_preparation_failure(
}
ogs_pkbuf_t *s1ap_build_handover_request(
mme_ue_t *mme_ue, enb_ue_t *target_ue,
S1AP_ENB_UE_S1AP_ID_t *enb_ue_s1ap_id,
S1AP_MME_UE_S1AP_ID_t *mme_ue_s1ap_id,
S1AP_HandoverType_t *handovertype,
S1AP_Cause_t *cause,
S1AP_Source_ToTarget_TransparentContainer_t
*source_totarget_transparentContainer)
enb_ue_t *target_ue, S1AP_HandoverType_t *handovertype, S1AP_Cause_t *cause,
S1AP_Source_ToTarget_TransparentContainer_t
*source_totarget_transparentContainer)
{
int rv;
@ -1807,6 +1803,7 @@ ogs_pkbuf_t *s1ap_build_handover_request(
S1AP_UESecurityCapabilities_t *UESecurityCapabilities = NULL;
S1AP_SecurityContext_t *SecurityContext = NULL;
mme_ue_t *mme_ue = NULL;
mme_sess_t *sess = NULL;
mme_bearer_t *bearer = NULL;
ogs_subscription_data_t *subscription_data = NULL;
@ -1816,6 +1813,7 @@ ogs_pkbuf_t *s1ap_build_handover_request(
ogs_assert(source_totarget_transparentContainer);
ogs_assert(target_ue);
mme_ue = target_ue->mme_ue;
ogs_assert(mme_ue);
subscription_data = &mme_ue->subscription_data;
ogs_assert(subscription_data);
@ -1985,8 +1983,8 @@ ogs_pkbuf_t *s1ap_build_handover_request(
}
ogs_s1ap_buffer_to_OCTET_STRING(
source_totarget_transparentContainer->buf,
source_totarget_transparentContainer->size,
source_totarget_transparentContainer->buf,
source_totarget_transparentContainer->size,
Source_ToTarget_TransparentContainer);
UESecurityCapabilities->encryptionAlgorithms.size = 2;

View File

@ -64,11 +64,7 @@ ogs_pkbuf_t *s1ap_build_handover_preparation_failure(
enb_ue_t *source_ue, S1AP_Cause_t *cause);
ogs_pkbuf_t *s1ap_build_handover_request(
mme_ue_t *mme_ue, enb_ue_t *target_ue,
S1AP_ENB_UE_S1AP_ID_t *enb_ue_s1ap_id,
S1AP_MME_UE_S1AP_ID_t *mme_ue_s1ap_id,
S1AP_HandoverType_t *handovertype,
S1AP_Cause_t *cause,
enb_ue_t *target_ue, S1AP_HandoverType_t *handovertype, S1AP_Cause_t *cause,
S1AP_Source_ToTarget_TransparentContainer_t
*source_totarget_transparentContainer);

View File

@ -1253,8 +1253,8 @@ void s1ap_handle_ue_context_release_action(enb_ue_t *enb_ue)
ogs_expect_or_return(mme_ue);
mme_ue_remove(mme_ue);
break;
case S1AP_UE_CTX_REL_DELETE_INDIRECT_TUNNEL:
ogs_debug(" Action: Delete indirect tunnel");
case S1AP_UE_CTX_REL_S1_HANDOVER_COMPLETE:
ogs_debug(" Action: S1 handover complete");
source_ue_deassociate_target_ue(enb_ue);
enb_ue_remove(enb_ue);
@ -1556,15 +1556,15 @@ void s1ap_handle_enb_configuration_transfer(
target_tac = be16toh(target_tac);
ogs_debug(" Source : ENB_ID[%s:%d], TAC[%d]",
sourceeNB_ID->global_ENB_ID.eNB_ID.present ==
S1AP_ENB_ID_PR_homeENB_ID ? "Home" :
sourceeNB_ID->global_ENB_ID.eNB_ID.present ==
sourceeNB_ID->global_ENB_ID.eNB_ID.present ==
S1AP_ENB_ID_PR_homeENB_ID ? "Home" :
sourceeNB_ID->global_ENB_ID.eNB_ID.present ==
S1AP_ENB_ID_PR_macroENB_ID ? "Macro" : "Others",
source_enb_id, source_tac);
ogs_debug(" Target : ENB_ID[%s:%d], TAC[%d]",
targeteNB_ID->global_ENB_ID.eNB_ID.present ==
S1AP_ENB_ID_PR_homeENB_ID ? "Home" :
targeteNB_ID->global_ENB_ID.eNB_ID.present ==
targeteNB_ID->global_ENB_ID.eNB_ID.present ==
S1AP_ENB_ID_PR_homeENB_ID ? "Home" :
targeteNB_ID->global_ENB_ID.eNB_ID.present ==
S1AP_ENB_ID_PR_macroENB_ID ? "Macro" : "Others",
target_enb_id, target_tac);
@ -1687,9 +1687,8 @@ void s1ap_handle_handover_required(mme_enb_t *enb, ogs_s1ap_message_t *message)
ogs_assert(HandoverType);
source_ue->handover_type = *HandoverType;
s1ap_send_handover_request(mme_ue, target_enb,
ENB_UE_S1AP_ID, MME_UE_S1AP_ID,
HandoverType, Cause,
s1ap_send_handover_request(
source_ue, target_enb, HandoverType, Cause,
Source_ToTarget_TransparentContainer);
}
@ -1885,7 +1884,7 @@ void s1ap_handle_handover_failure(mme_enb_t *enb, ogs_s1ap_message_t *message)
s1ap_send_ue_context_release_command(
target_ue, S1AP_Cause_PR_radioNetwork,
S1AP_CauseRadioNetwork_ho_failure_in_target_EPC_eNB_or_target_system,
S1AP_UE_CTX_REL_DELETE_INDIRECT_TUNNEL, 0);
S1AP_UE_CTX_REL_S1_HANDOVER_COMPLETE, 0);
}
void s1ap_handle_handover_cancel(mme_enb_t *enb, ogs_s1ap_message_t *message)
@ -1954,7 +1953,7 @@ void s1ap_handle_handover_cancel(mme_enb_t *enb, ogs_s1ap_message_t *message)
s1ap_send_ue_context_release_command(
target_ue, S1AP_Cause_PR_radioNetwork,
S1AP_CauseRadioNetwork_handover_cancelled,
S1AP_UE_CTX_REL_DELETE_INDIRECT_TUNNEL,
S1AP_UE_CTX_REL_S1_HANDOVER_COMPLETE,
ogs_time_from_msec(300));
ogs_debug("Handover Cancel : "

View File

@ -284,7 +284,7 @@ void s1ap_send_ue_context_modification_request(mme_ue_t *mme_ue)
void s1ap_send_ue_context_release_command(
enb_ue_t *enb_ue, S1AP_Cause_PR group, long cause,
uint8_t action, uint32_t delay)
uint8_t action, ogs_time_t duration)
{
int rv;
ogs_pkbuf_t *s1apbuf = NULL;
@ -298,22 +298,15 @@ void s1ap_send_ue_context_release_command(
ogs_assert(action != S1AP_UE_CTX_REL_INVALID_ACTION);
enb_ue->ue_ctx_rel_action = action;
ogs_debug(" Group[%d] Cause[%d] Action[%d] Delay[%d]",
group, (int)cause, action, delay);
ogs_debug(" Group[%d] Cause[%d] Action[%d] Duration[%d]",
group, (int)cause, action, (int)duration);
s1apbuf = s1ap_build_ue_context_release_command(enb_ue, group, cause);
ogs_expect_or_return(s1apbuf);
rv = s1ap_delayed_send_to_enb_ue(enb_ue, s1apbuf, delay);
rv = s1ap_delayed_send_to_enb_ue(enb_ue, s1apbuf, duration);
ogs_expect(rv == OGS_OK);
if (enb_ue->t_s1_holding)
ogs_timer_delete(enb_ue->t_s1_holding);
enb_ue->t_s1_holding = ogs_timer_add(
ogs_app()->timer_mgr, mme_timer_s1_holding_timer_expire, enb_ue);
ogs_assert(enb_ue->t_s1_holding);
ogs_timer_start(enb_ue->t_s1_holding,
mme_timer_cfg(MME_TIMER_S1_HOLDING)->duration);
}
@ -430,28 +423,21 @@ void s1ap_send_handover_cancel_ack(enb_ue_t *source_ue)
void s1ap_send_handover_request(
mme_ue_t *mme_ue,
mme_enb_t *target_enb,
S1AP_ENB_UE_S1AP_ID_t *enb_ue_s1ap_id,
S1AP_MME_UE_S1AP_ID_t *mme_ue_s1ap_id,
S1AP_HandoverType_t *handovertype,
S1AP_Cause_t *cause,
enb_ue_t *source_ue, mme_enb_t *target_enb,
S1AP_HandoverType_t *handovertype, S1AP_Cause_t *cause,
S1AP_Source_ToTarget_TransparentContainer_t
*source_totarget_transparentContainer)
{
int rv;
ogs_pkbuf_t *s1apbuf = NULL;
enb_ue_t *source_ue = NULL, *target_ue = NULL;
enb_ue_t *target_ue = NULL;
ogs_info("Handover request");
ogs_assert(target_enb);
ogs_assert(mme_ue);
source_ue = enb_ue_cycle(mme_ue->enb_ue);
ogs_assert(source_ue);
ogs_assert(source_ue->target_ue == NULL);
ogs_assert(target_enb);
target_ue = enb_ue_add(target_enb, INVALID_UE_S1AP_ID);
ogs_assert(target_ue);
@ -463,9 +449,8 @@ void s1ap_send_handover_request(
source_ue_associate_target_ue(source_ue, target_ue);
s1apbuf = s1ap_build_handover_request(mme_ue, target_ue,
enb_ue_s1ap_id, mme_ue_s1ap_id,
handovertype, cause,
s1apbuf = s1ap_build_handover_request(
target_ue, handovertype, cause,
source_totarget_transparentContainer);
ogs_expect_or_return(s1apbuf);

View File

@ -54,7 +54,7 @@ void s1ap_send_initial_context_setup_request(mme_ue_t *mme_ue);
void s1ap_send_ue_context_modification_request(mme_ue_t *mme_ue);
void s1ap_send_ue_context_release_command(
enb_ue_t *enb_ue, S1AP_Cause_PR group, long cause,
uint8_t action, uint32_t delay);
uint8_t action, ogs_time_t duration);
void s1ap_send_paging(mme_ue_t *mme_ue, S1AP_CNDomain_t cn_domain);
@ -69,12 +69,8 @@ void s1ap_send_handover_preparation_failure(
enb_ue_t *source_ue, S1AP_Cause_t *cause);
void s1ap_send_handover_request(
mme_ue_t *mme_ue,
mme_enb_t *target_enb,
S1AP_ENB_UE_S1AP_ID_t *enb_ue_s1ap_id,
S1AP_MME_UE_S1AP_ID_t *mme_ue_s1ap_id,
S1AP_HandoverType_t *handovertype,
S1AP_Cause_t *cause,
enb_ue_t *source_ue, mme_enb_t *target_enb,
S1AP_HandoverType_t *handovertype, S1AP_Cause_t *cause,
S1AP_Source_ToTarget_TransparentContainer_t
*source_totarget_transparentContainer);

View File

@ -302,6 +302,13 @@ typedef struct smf_sess_s {
int pdu_session_resource_release;
} ngap_state;
/* Handover */
struct {
bool prepared;
uint32_t gnb_n3_teid;
ogs_ip_t gnb_n3_ip;
} handover; /* Saved from N2-Handover Request Acknowledge */
ogs_list_t bearer_list;
ogs_gtp_node_t *gnode;

View File

@ -329,8 +329,25 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
break;
case OpenAPI_n2_sm_info_type_PATH_SWITCH_REQ:
rv = ngap_handle_pdu_session_resource_to_be_switched_dl_transfer(
sess, stream, pkbuf);
rv = ngap_handle_path_switch_request_transfer(sess, stream, pkbuf);
if (rv != OGS_OK) {
ogs_error("[%s:%d] Cannot handle NGAP message",
smf_ue->supi, sess->psi);
OGS_FSM_TRAN(s, smf_gsm_state_exception);
}
break;
case OpenAPI_n2_sm_info_type_HANDOVER_REQUIRED:
rv = ngap_handle_handover_required_transfer(sess, stream, pkbuf);
if (rv != OGS_OK) {
ogs_error("[%s:%d] Cannot handle NGAP message",
smf_ue->supi, sess->psi);
OGS_FSM_TRAN(s, smf_gsm_state_exception);
}
break;
case OpenAPI_n2_sm_info_type_HANDOVER_REQ_ACK:
rv = ngap_handle_handover_request_ack(sess, stream, pkbuf);
if (rv != OGS_OK) {
ogs_error("[%s:%d] Cannot handle NGAP message",
smf_ue->supi, sess->psi);

View File

@ -195,7 +195,7 @@ void smf_5gc_n4_handle_session_establishment_response(
param.n1smbuf = gsm_build_pdu_session_establishment_accept(sess);
ogs_assert(param.n1smbuf);
param.n2smbuf = ngap_build_pdu_session_resource_setup_request_transfer(
sess);
sess);
ogs_assert(param.n2smbuf);
smf_namf_comm_send_n1_n2_message_transfer(sess, &param);
@ -299,13 +299,18 @@ void smf_5gc_n4_handle_session_modification_response(
}
if (flags & OGS_PFCP_MODIFY_ACTIVATE) {
if (flags & OGS_PFCP_MODIFY_PATH_SWITCH) {
if (flags & OGS_PFCP_MODIFY_XN_HANDOVER) {
ogs_pkbuf_t *n2smbuf =
ngap_build_path_switch_request_ack_transfer(sess);
ogs_assert(n2smbuf);
smf_sbi_send_sm_context_updated_data_n2smbuf(sess, stream,
OpenAPI_n2_sm_info_type_PATH_SWITCH_REQ_ACK, n2smbuf);
} else if (flags & OGS_PFCP_MODIFY_N2_HANDOVER) {
smf_sbi_send_sm_context_updated_data_ho_state(
sess, stream, OpenAPI_ho_state_COMPLETED);
} else {
sess->paging.ue_requested_pdu_session_establishment_done = true;
smf_sbi_send_http_status_no_content(stream);
@ -778,7 +783,8 @@ void smf_n4_handle_session_report_request(
memset(&param, 0, sizeof(param));
param.state = SMF_NETWORK_TRIGGERED_SERVICE_REQUEST;
param.n2smbuf =
ngap_build_pdu_session_resource_setup_request_transfer(sess);
ngap_build_pdu_session_resource_setup_request_transfer(
sess);
ogs_assert(param.n2smbuf);
param.n1n2_failure_txf_notif_uri = true;

View File

@ -303,14 +303,14 @@ ogs_pkbuf_t *ngap_build_path_switch_request_ack_transfer(smf_sess_t *sess)
{
NGAP_PathSwitchRequestAcknowledgeTransfer_t message;
#if 0
#if 0 /* The following is optional. So I've removed */
ogs_ip_t upf_n3_ip;
NGAP_UPTransportLayerInformation_t *UPTransportLayerInformation = NULL;
NGAP_GTPTunnel_t *gTPTunnel = NULL;
#endif
ogs_assert(sess);
#endif
ogs_debug("PathSwitchRequestAcknowledgeTransfer");
memset(&message, 0, sizeof(NGAP_PathSwitchRequestAcknowledgeTransfer_t));
@ -334,3 +334,39 @@ ogs_pkbuf_t *ngap_build_path_switch_request_ack_transfer(smf_sess_t *sess)
return ogs_asn_encode(
&asn_DEF_NGAP_PathSwitchRequestAcknowledgeTransfer, &message);
}
ogs_pkbuf_t *ngap_build_handover_command_transfer(smf_sess_t *sess)
{
NGAP_HandoverCommandTransfer_t message;
#if 0 /* The following is optional. So I've removed */
ogs_ip_t upf_n3_ip;
NGAP_UPTransportLayerInformation_t *dLForwardingUP_TNLInformation = NULL;
NGAP_GTPTunnel_t *gTPTunnel = NULL;
#endif
ogs_assert(sess);
ogs_debug("HandoverCommandTransfer");
memset(&message, 0, sizeof(NGAP_HandoverCommandTransfer_t));
#if 0 /* The following is optional. So I've removed */
message.dLForwardingUP_TNLInformation = dLForwardingUP_TNLInformation =
CALLOC(1, sizeof(*dLForwardingUP_TNLInformation));
ogs_assert(dLForwardingUP_TNLInformation);
dLForwardingUP_TNLInformation->present =
NGAP_UPTransportLayerInformation_PR_gTPTunnel;
dLForwardingUP_TNLInformation->choice.gTPTunnel = gTPTunnel =
CALLOC(1, sizeof(*gTPTunnel));
ogs_assert(gTPTunnel);
ogs_sockaddr_to_ip(sess->upf_n3_addr, sess->upf_n3_addr6, &upf_n3_ip);
ogs_asn_ip_to_BIT_STRING(&upf_n3_ip, &gTPTunnel->transportLayerAddress);
ogs_asn_uint32_to_OCTET_STRING(sess->upf_n3_teid, &gTPTunnel->gTP_TEID);
#endif
return ogs_asn_encode(
&asn_DEF_NGAP_HandoverCommandTransfer, &message);
}

View File

@ -37,6 +37,8 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command_transfer(
ogs_pkbuf_t *ngap_build_path_switch_request_ack_transfer(smf_sess_t *sess);
ogs_pkbuf_t *ngap_build_handover_command_transfer(smf_sess_t *sess);
#ifdef __cplusplus
}
#endif

View File

@ -20,6 +20,7 @@
#include "ngap-handler.h"
#include "sbi-path.h"
#include "pfcp-path.h"
#include "ngap-path.h"
int ngap_handle_pdu_session_resource_setup_response_transfer(
smf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_pkbuf_t *pkbuf)
@ -230,7 +231,7 @@ cleanup:
return rv;
}
int ngap_handle_pdu_session_resource_to_be_switched_dl_transfer(
int ngap_handle_path_switch_request_transfer(
smf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_pkbuf_t *pkbuf)
{
smf_ue_t *smf_ue = NULL;
@ -246,6 +247,7 @@ int ngap_handle_pdu_session_resource_to_be_switched_dl_transfer(
NGAP_PathSwitchRequestTransfer_t message;
NGAP_UPTransportLayerInformation_t *dL_NGU_UP_TNLInformation = NULL;
NGAP_QosFlowAcceptedItem_t *acceptedQosFlowItem = NULL;
NGAP_GTPTunnel_t *gTPTunnel = NULL;
NGAP_QosFlowAcceptedList_t *qosFlowAcceptedList = NULL;
@ -274,11 +276,11 @@ int ngap_handle_pdu_session_resource_to_be_switched_dl_transfer(
if (dL_NGU_UP_TNLInformation->present !=
NGAP_UPTransportLayerInformation_PR_gTPTunnel) {
ogs_error(
"[%s:%d] Unknown NGAP_UPTransportLayerInformation.present [%d]",
"[%s:%d] Unknown dL_NGU_UP_TNLInformation->present [%d]",
smf_ue->supi, sess->psi, dL_NGU_UP_TNLInformation->present);
smf_sbi_send_sm_context_update_error(stream,
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
"Unknown NGAP_UPTransportLayerInformation.present",
"Unknown dL_NGU_UP_TNLInformation->present",
smf_ue->supi, NULL, NULL);
goto cleanup;
}
@ -306,7 +308,6 @@ int ngap_handle_pdu_session_resource_to_be_switched_dl_transfer(
qosFlowAcceptedList = &message.qosFlowAcceptedList;
for (i = 0; i < qosFlowAcceptedList->list.count; i++) {
NGAP_QosFlowAcceptedItem_t *acceptedQosFlowItem = NULL;
acceptedQosFlowItem = (NGAP_QosFlowAcceptedItem_t *)
qosFlowAcceptedList->list.array[i];
if (acceptedQosFlowItem) {
@ -339,7 +340,7 @@ int ngap_handle_pdu_session_resource_to_be_switched_dl_transfer(
if (far_update) {
smf_5gc_pfcp_send_session_modification_request(
sess, stream,
OGS_PFCP_MODIFY_ACTIVATE | OGS_PFCP_MODIFY_PATH_SWITCH |
OGS_PFCP_MODIFY_ACTIVATE | OGS_PFCP_MODIFY_XN_HANDOVER |
OGS_PFCP_MODIFY_END_MARKER);
} else {
/* ACTIVATED Is NOT Included in RESPONSE */
@ -352,3 +353,150 @@ cleanup:
ogs_asn_free(&asn_DEF_NGAP_PathSwitchRequestTransfer, &message);
return rv;
}
int ngap_handle_handover_required_transfer(
smf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_pkbuf_t *pkbuf)
{
smf_ue_t *smf_ue = NULL;
int rv;
NGAP_HandoverRequiredTransfer_t message;
ogs_pkbuf_t *n2smbuf = NULL;
ogs_assert(pkbuf);
ogs_assert(stream);
ogs_assert(sess);
smf_ue = sess->smf_ue;
ogs_assert(smf_ue);
rv = ogs_asn_decode(&asn_DEF_NGAP_HandoverRequiredTransfer,
&message, sizeof(message), pkbuf);
if (rv != OGS_OK) {
ogs_error("[%s:%d] Cannot decode NGAP message",
smf_ue->supi, sess->psi);
smf_sbi_send_sm_context_update_error(stream,
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
"No N2 SM Info Type", smf_ue->supi, NULL, NULL);
goto cleanup;
}
n2smbuf = ngap_build_pdu_session_resource_setup_request_transfer(sess);
ogs_assert(n2smbuf);
smf_sbi_send_sm_context_updated_data(
sess, stream, 0, OpenAPI_ho_state_PREPARING,
NULL, OpenAPI_n2_sm_info_type_PDU_RES_SETUP_REQ, n2smbuf);
rv = OGS_OK;
cleanup:
ogs_asn_free(&asn_DEF_NGAP_HandoverRequiredTransfer, &message);
return rv;
}
int ngap_handle_handover_request_ack(
smf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_pkbuf_t *pkbuf)
{
smf_ue_t *smf_ue = NULL;
smf_bearer_t *qos_flow = NULL;
int rv, i;
ogs_pfcp_far_t *dl_far = NULL;
NGAP_HandoverRequestAcknowledgeTransfer_t message;
NGAP_UPTransportLayerInformation_t *dL_NGU_UP_TNLInformation = NULL;
NGAP_QosFlowListWithDataForwarding_t *qosFlowSetupResponseList = NULL;
NGAP_QosFlowItemWithDataForwarding_t *qosFlowSetupResponseItem = NULL;
NGAP_GTPTunnel_t *gTPTunnel = NULL;
ogs_pkbuf_t *n2smbuf = NULL;
ogs_assert(pkbuf);
ogs_assert(stream);
ogs_assert(sess);
smf_ue = sess->smf_ue;
ogs_assert(smf_ue);
rv = ogs_asn_decode(&asn_DEF_NGAP_HandoverRequestAcknowledgeTransfer,
&message, sizeof(message), pkbuf);
if (rv != OGS_OK) {
ogs_error("[%s:%d] Cannot decode NGAP message",
smf_ue->supi, sess->psi);
smf_sbi_send_sm_context_update_error(stream,
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
"No N2 SM Info Type", smf_ue->supi, NULL, NULL);
goto cleanup;
}
rv = OGS_ERROR;
dL_NGU_UP_TNLInformation = &message.dL_NGU_UP_TNLInformation;
if (dL_NGU_UP_TNLInformation->present !=
NGAP_UPTransportLayerInformation_PR_gTPTunnel) {
ogs_error(
"[%s:%d] Unknown dL_NGU_UP_TNLInformation->present [%d]",
smf_ue->supi, sess->psi, dL_NGU_UP_TNLInformation->present);
smf_sbi_send_sm_context_update_error(stream,
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
"Unknown dL_NGU_UP_TNLInformation->present",
smf_ue->supi, NULL, NULL);
goto cleanup;
}
gTPTunnel = dL_NGU_UP_TNLInformation->choice.gTPTunnel;
if (!gTPTunnel) {
ogs_error("[%s:%d] No GTPTunnel", smf_ue->supi, sess->psi);
smf_sbi_send_sm_context_update_error(stream,
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
"No GTPTunnel", smf_ue->supi, NULL, NULL);
goto cleanup;
}
/* Store FAR */
ogs_asn_BIT_STRING_to_ip(&gTPTunnel->transportLayerAddress,
&sess->handover.gnb_n3_ip);
ogs_asn_OCTET_STRING_to_uint32(&gTPTunnel->gTP_TEID,
&sess->handover.gnb_n3_teid);
sess->handover.prepared = true;
qosFlowSetupResponseList = &message.qosFlowSetupResponseList;
for (i = 0; i < qosFlowSetupResponseList->list.count; i++) {
qosFlowSetupResponseItem = (NGAP_QosFlowItemWithDataForwarding_t *)
qosFlowSetupResponseList->list.array[i];
if (qosFlowSetupResponseItem) {
qos_flow = smf_qos_flow_find_by_qfi(sess,
qosFlowSetupResponseItem->qosFlowIdentifier);
if (qos_flow) {
dl_far = qos_flow->dl_far;
ogs_assert(dl_far);
dl_far->handover.prepared = true;
} else {
ogs_error("[%s:%d] No QoS flow", smf_ue->supi, sess->psi);
smf_sbi_send_sm_context_update_error(stream,
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
"No QoS flow", smf_ue->supi, NULL, NULL);
goto cleanup;
}
}
}
n2smbuf = ngap_build_handover_command_transfer(sess);
ogs_assert(n2smbuf);
smf_sbi_send_sm_context_updated_data(
sess, stream, 0, OpenAPI_ho_state_PREPARED,
NULL, OpenAPI_n2_sm_info_type_HANDOVER_CMD, n2smbuf);
rv = OGS_OK;
cleanup:
ogs_asn_free(&asn_DEF_NGAP_HandoverRequestAcknowledgeTransfer, &message);
return rv;
}

View File

@ -30,7 +30,11 @@ int ngap_handle_pdu_session_resource_setup_response_transfer(
smf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_pkbuf_t *pkbuf);
int ngap_handle_pdu_session_resource_modify_response_transfer(
smf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_pkbuf_t *pkbuf);
int ngap_handle_pdu_session_resource_to_be_switched_dl_transfer(
int ngap_handle_path_switch_request_transfer(
smf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_pkbuf_t *pkbuf);
int ngap_handle_handover_required_transfer(
smf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_pkbuf_t *pkbuf);
int ngap_handle_handover_request_ack(
smf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_pkbuf_t *pkbuf);
#ifdef __cplusplus

View File

@ -341,14 +341,7 @@ bool smf_nsmf_handle_update_sm_context(
ngap_send_to_n2sm(
sess, stream, SmContextUpdateData->n2_sm_info_type, n2smbuf);
} else {
if (!SmContextUpdateData->up_cnx_state) {
ogs_error("[%s:%d] No upCnxState", smf_ue->supi, sess->psi);
smf_sbi_send_sm_context_update_error(stream,
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
"No upCnxState", smf_ue->supi, NULL, NULL);
return false;
}
} else if (SmContextUpdateData->up_cnx_state) {
if (SmContextUpdateData->up_cnx_state ==
OpenAPI_up_cnx_state_DEACTIVATED) {
@ -450,6 +443,96 @@ bool smf_nsmf_handle_update_sm_context(
return false;
}
} else if (SmContextUpdateData->ho_state) {
if (SmContextUpdateData->ho_state == OpenAPI_ho_state_COMPLETED) {
bool far_update = false;
smf_bearer_t *qos_flow = NULL;
if (sess->handover.prepared == true) {
/* Need to Update? */
if (memcmp(&sess->gnb_n3_ip, &sess->handover.gnb_n3_ip,
sizeof(sess->gnb_n3_ip)) != 0 ||
sess->gnb_n3_teid != sess->handover.gnb_n3_teid)
far_update = true;
memcpy(&sess->gnb_n3_ip,
&sess->handover.gnb_n3_ip, sizeof(sess->gnb_n3_ip));
sess->gnb_n3_teid = sess->handover.gnb_n3_teid;
}
sess->handover.prepared = false;
ogs_list_for_each(&sess->bearer_list, qos_flow) {
ogs_pfcp_far_t *dl_far = qos_flow->dl_far;
ogs_assert(dl_far);
if (dl_far->handover.prepared == true) {
if (dl_far->apply_action != OGS_PFCP_APPLY_ACTION_FORW) {
far_update = true;
}
dl_far->apply_action = OGS_PFCP_APPLY_ACTION_FORW;
ogs_pfcp_ip_to_outer_header_creation(
&sess->gnb_n3_ip,
&dl_far->outer_header_creation,
&dl_far->outer_header_creation_len);
dl_far->outer_header_creation.teid = sess->gnb_n3_teid;
}
dl_far->handover.prepared = false;
}
if (far_update) {
smf_5gc_pfcp_send_session_modification_request(
sess, stream,
OGS_PFCP_MODIFY_ACTIVATE | OGS_PFCP_MODIFY_N2_HANDOVER |
OGS_PFCP_MODIFY_END_MARKER);
} else {
char *strerror = ogs_msprintf(
"[%s:%d] No FAR Update", smf_ue->supi, sess->psi);
ogs_assert(strerror);
ogs_error("%s", strerror);
smf_sbi_send_sm_context_update_error(
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
strerror, NULL, NULL, NULL);
ogs_free(strerror);
return false;
}
} else if (SmContextUpdateData->ho_state ==
OpenAPI_ho_state_CANCELLED) {
smf_bearer_t *qos_flow = NULL;
sess->handover.prepared = false;
ogs_list_for_each(&sess->bearer_list, qos_flow) {
ogs_pfcp_far_t *dl_far = qos_flow->dl_far;
ogs_assert(dl_far);
dl_far->handover.prepared = false;
}
smf_sbi_send_sm_context_updated_data_ho_state(
sess, stream, OpenAPI_ho_state_CANCELLED);
} else {
char *strerror = ogs_msprintf("[%s:%d] Invalid hoState [%d]",
smf_ue->supi, sess->psi, SmContextUpdateData->ho_state);
ogs_assert(strerror);
ogs_error("%s", strerror);
smf_sbi_send_sm_context_update_error(stream,
OGS_SBI_HTTP_STATUS_BAD_REQUEST, strerror, NULL, NULL, NULL);
ogs_free(strerror);
return false;
}
} else {
ogs_error("[%s:%d] No UpdateData", smf_ue->supi, sess->psi);
smf_sbi_send_sm_context_update_error(stream,
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
"No UpdateData", smf_ue->supi, NULL, NULL);
return false;
}
return true;

View File

@ -236,6 +236,7 @@ void smf_sbi_send_sm_context_create_error(
void smf_sbi_send_sm_context_updated_data(
smf_sess_t *sess, ogs_sbi_stream_t *stream,
OpenAPI_up_cnx_state_e up_cnx_state,
OpenAPI_ho_state_e ho_state,
ogs_pkbuf_t *n1smbuf,
OpenAPI_n2_sm_info_type_e n2type, ogs_pkbuf_t *n2smbuf)
{
@ -251,7 +252,9 @@ void smf_sbi_send_sm_context_updated_data(
ogs_assert(sess);
ogs_assert(stream);
ogs_assert(up_cnx_state != OpenAPI_up_cnx_state_NULL || n1smbuf || n2smbuf);
ogs_assert(up_cnx_state != OpenAPI_up_cnx_state_NULL ||
ho_state != OpenAPI_ho_state_NULL ||
n1smbuf || n2smbuf);
memset(&sendmsg, 0, sizeof(sendmsg));
@ -260,6 +263,9 @@ void smf_sbi_send_sm_context_updated_data(
/* up_cnx_state */
SmContextUpdatedData.up_cnx_state = up_cnx_state;
/* ho_state */
SmContextUpdatedData.ho_state = ho_state;
/* n1smbuf */
if (n1smbuf) {
n1SmMsg.content_id = (char *)OGS_SBI_CONTENT_5GNAS_SM_ID;

View File

@ -54,18 +54,23 @@ void smf_sbi_send_sm_context_create_error(
#define smf_sbi_send_sm_context_updated_data_up_cnx_state( \
__sESS, __sTREAM, __uPCnxState) \
smf_sbi_send_sm_context_updated_data(\
__sESS, __sTREAM, __uPCnxState, NULL, 0, NULL)
__sESS, __sTREAM, __uPCnxState, 0, NULL, 0, NULL)
#define smf_sbi_send_sm_context_updated_data_n2smbuf( \
__sESS, __sTREAM, __n2Type, __n2SmBuf) \
smf_sbi_send_sm_context_updated_data(\
__sESS, __sTREAM, 0, NULL, __n2Type, __n2SmBuf)
__sESS, __sTREAM, 0, 0, NULL, __n2Type, __n2SmBuf)
#define smf_sbi_send_sm_context_updated_data_ho_state( \
__sESS, __sTREAM, __hoState) \
smf_sbi_send_sm_context_updated_data(\
__sESS, __sTREAM, 0, __hoState, NULL, 0, NULL)
#define smf_sbi_send_sm_context_updated_data_n1_n2_message( \
__sESS, __sTREAM, __n1SmBuf, __n2Type, __n2SmBuf) \
smf_sbi_send_sm_context_updated_data(\
__sESS, __sTREAM, 0, __n1SmBuf, __n2Type, __n2SmBuf)
__sESS, __sTREAM, 0, 0, __n1SmBuf, __n2Type, __n2SmBuf)
void smf_sbi_send_sm_context_updated_data(
smf_sess_t *sess, ogs_sbi_stream_t *stream,
OpenAPI_up_cnx_state_e up_cnx_state,
OpenAPI_ho_state_e ho_state,
ogs_pkbuf_t *n1smbuf,
OpenAPI_n2_sm_info_type_e n2type, ogs_pkbuf_t *n2smbuf);

View File

@ -25,6 +25,10 @@ static ogs_pkbuf_t *testngap_build_pdu_session_resource_modify_response_trasfer(
test_bearer_t *qos_flow);
static ogs_pkbuf_t *testngap_build_path_switch_request_trasfer(
test_sess_t *sess);
static ogs_pkbuf_t *testngap_build_handover_required_transfer(
test_sess_t *sess, bool direct);
static ogs_pkbuf_t *testngap_build_handover_request_ack_transfer(
test_sess_t *sess);
ogs_pkbuf_t *testngap_build_ng_setup_request(uint32_t gnb_id, uint8_t bitsize)
{
@ -1149,6 +1153,101 @@ ogs_pkbuf_t *testngap_build_pdu_session_resource_release_response(
return ogs_ngap_encode(&pdu);
}
ogs_pkbuf_t *testngap_build_uplink_ran_configuration_transfer(
uint32_t source_gnb_id, uint8_t source_bitsize,
uint32_t target_gnb_id, uint8_t target_bitsize)
{
int rv;
ogs_plmn_id_t *plmn_id = NULL;
NGAP_NGAP_PDU_t pdu;
NGAP_InitiatingMessage_t *initiatingMessage = NULL;
NGAP_UplinkRANConfigurationTransfer_t
*UplinkRANConfigurationTransfer = NULL;
NGAP_UplinkRANConfigurationTransferIEs_t *ie = NULL;
NGAP_SONConfigurationTransfer_t *SONConfigurationTransfer = NULL;
NGAP_SourceRANNodeID_t *sourceRANNodeID = NULL;
NGAP_GlobalRANNodeID_t *sourceGlobalRANNodeID;
NGAP_GlobalGNB_ID_t *sourceGlobalGNB_ID;
NGAP_TAI_t *sourceSelectedTAI;
NGAP_TargetRANNodeID_t *targetRANNodeID = NULL;
NGAP_GlobalRANNodeID_t *targetGlobalRANNodeID;
NGAP_GlobalGNB_ID_t *targetGlobalGNB_ID;
NGAP_TAI_t *targetSelectedTAI;
NGAP_SONInformation_t *sONInformation = NULL;
NGAP_SONInformationRequest_t *sONInformationRequest = NULL;
ogs_debug("Uplink Configuration Transfer");
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
ogs_assert(pdu.choice.initiatingMessage);
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode =
NGAP_ProcedureCode_id_UplinkRANConfigurationTransfer;
initiatingMessage->criticality = NGAP_Criticality_ignore;
initiatingMessage->value.present =
NGAP_InitiatingMessage__value_PR_UplinkRANConfigurationTransfer;
UplinkRANConfigurationTransfer =
&initiatingMessage->value.choice.UplinkRANConfigurationTransfer;
ie = CALLOC(1, sizeof(NGAP_UplinkRANConfigurationTransferIEs_t));
ogs_assert(ie);
ASN_SEQUENCE_ADD(&UplinkRANConfigurationTransfer->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_SONConfigurationTransferUL;
ie->criticality = NGAP_Criticality_ignore;
ie->value.present = NGAP_UplinkRANConfigurationTransferIEs__value_PR_SONConfigurationTransfer;
SONConfigurationTransfer = &ie->value.choice.SONConfigurationTransfer;
plmn_id = &test_self()->plmn_support[0].plmn_id;
targetRANNodeID = &SONConfigurationTransfer->targetRANNodeID;
targetGlobalRANNodeID = &targetRANNodeID->globalRANNodeID;
targetSelectedTAI = &targetRANNodeID->selectedTAI;
targetGlobalRANNodeID->present = NGAP_GlobalRANNodeID_PR_globalGNB_ID;
targetGlobalRANNodeID->choice.globalGNB_ID = targetGlobalGNB_ID =
CALLOC(1, sizeof(*targetGlobalGNB_ID));
ogs_assert(targetGlobalGNB_ID);
ogs_asn_buffer_to_OCTET_STRING(
plmn_id, OGS_PLMN_ID_LEN, &targetGlobalGNB_ID->pLMNIdentity);
ogs_ngap_uint32_to_GNB_ID(target_gnb_id, target_bitsize,
&targetGlobalGNB_ID->gNB_ID);
ogs_ngap_5gs_tai_to_ASN(&test_self()->nr_tai, targetSelectedTAI);
sourceRANNodeID = &SONConfigurationTransfer->sourceRANNodeID;
sourceGlobalRANNodeID = &sourceRANNodeID->globalRANNodeID;
sourceSelectedTAI = &sourceRANNodeID->selectedTAI;
sourceGlobalRANNodeID->present = NGAP_GlobalRANNodeID_PR_globalGNB_ID;
sourceGlobalRANNodeID->choice.globalGNB_ID = sourceGlobalGNB_ID =
CALLOC(1, sizeof(*sourceGlobalGNB_ID));
ogs_assert(sourceGlobalGNB_ID);
ogs_asn_buffer_to_OCTET_STRING(
plmn_id, OGS_PLMN_ID_LEN, &sourceGlobalGNB_ID->pLMNIdentity);
ogs_ngap_uint32_to_GNB_ID(source_gnb_id, source_bitsize,
&sourceGlobalGNB_ID->gNB_ID);
ogs_ngap_5gs_tai_to_ASN(&test_self()->nr_tai, sourceSelectedTAI);
sONInformation = &SONConfigurationTransfer->sONInformation;
sONInformation->present = NGAP_SONInformation_PR_sONInformationRequest;
sONInformationRequest = &sONInformation->choice.sONInformationRequest;
*sONInformationRequest =
NGAP_SONInformationRequest_xn_TNL_configuration_info;
return ogs_ngap_encode(&pdu);
}
ogs_pkbuf_t *testngap_build_path_switch_request(test_ue_t *test_ue)
{
int rv;
@ -1315,6 +1414,610 @@ ogs_pkbuf_t *testngap_build_path_switch_request(test_ue_t *test_ue)
return ogs_ngap_encode(&pdu);
}
ogs_pkbuf_t *testngap_build_handover_required(
test_ue_t *test_ue, NGAP_HandoverType_t handover_type,
uint32_t gnb_id, uint8_t bitsize,
NGAP_Cause_PR group, long cause,
bool direct)
{
test_sess_t *sess = NULL;
ogs_pkbuf_t *n2smbuf = NULL;
ogs_plmn_id_t *plmn_id = NULL;
NGAP_NGAP_PDU_t pdu;
NGAP_InitiatingMessage_t *initiatingMessage = NULL;
NGAP_HandoverRequired_t *HandoverRequired = NULL;
NGAP_HandoverRequiredIEs_t *ie = NULL;
NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL;
NGAP_RAN_UE_NGAP_ID_t *RAN_UE_NGAP_ID = NULL;
NGAP_HandoverType_t *HandoverType = NULL;
NGAP_Cause_t *Cause = NULL;
NGAP_TargetID_t *TargetID = NULL;
NGAP_TargetRANNodeID_t *targetRANNodeID = NULL;
NGAP_GlobalRANNodeID_t *globalRANNodeID = NULL;
NGAP_GlobalGNB_ID_t *globalGNB_ID = NULL;
NGAP_TAI_t *selectedTAI = NULL;
NGAP_PDUSessionResourceListHORqd_t *PDUSessionList = NULL;
NGAP_PDUSessionResourceItemHORqd_t *PDUSessionItem = NULL;
OCTET_STRING_t *transfer = NULL;
NGAP_SourceToTarget_TransparentContainer_t
*SourceToTarget_TransparentContainer = NULL;
uint8_t tmp[OGS_MAX_SDU_LEN];
char *_container =
"40"
"0300001100000a00 010002f839000102 0120000002f83900 0000001000000a";
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
ogs_assert(pdu.choice.initiatingMessage);
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode =
NGAP_ProcedureCode_id_HandoverPreparation;
initiatingMessage->criticality = NGAP_Criticality_reject;
initiatingMessage->value.present =
NGAP_InitiatingMessage__value_PR_HandoverRequired;
HandoverRequired = &initiatingMessage->value.choice.HandoverRequired;
ie = CALLOC(1, sizeof(NGAP_HandoverRequiredIEs_t));
ogs_assert(ie);
ASN_SEQUENCE_ADD(&HandoverRequired->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID;
ie->criticality = NGAP_Criticality_reject;
ie->value.present = NGAP_HandoverRequiredIEs__value_PR_AMF_UE_NGAP_ID;
AMF_UE_NGAP_ID = &ie->value.choice.AMF_UE_NGAP_ID;
ie = CALLOC(1, sizeof(NGAP_HandoverRequiredIEs_t));
ogs_assert(ie);
ASN_SEQUENCE_ADD(&HandoverRequired->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID;
ie->criticality = NGAP_Criticality_reject;
ie->value.present = NGAP_HandoverRequiredIEs__value_PR_RAN_UE_NGAP_ID;
RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID;
asn_uint642INTEGER(AMF_UE_NGAP_ID, test_ue->amf_ue_ngap_id);
*RAN_UE_NGAP_ID = test_ue->ran_ue_ngap_id;
ie = CALLOC(1, sizeof(NGAP_HandoverRequiredIEs_t));
ASN_SEQUENCE_ADD(&HandoverRequired->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_HandoverType;
ie->criticality = NGAP_Criticality_reject;
ie->value.present = NGAP_HandoverRequiredIEs__value_PR_HandoverType;
HandoverType = &ie->value.choice.HandoverType;
*HandoverType = handover_type;
ie = CALLOC(1, sizeof(NGAP_HandoverRequiredIEs_t));
ogs_assert(ie);
ASN_SEQUENCE_ADD(&HandoverRequired->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_Cause;
ie->criticality = NGAP_Criticality_ignore;
ie->value.present = NGAP_HandoverRequiredIEs__value_PR_Cause;
Cause = &ie->value.choice.Cause;
Cause->present = group;
Cause->choice.radioNetwork = cause;
ie = CALLOC(1, sizeof(NGAP_HandoverRequiredIEs_t));
ogs_assert(ie);
ASN_SEQUENCE_ADD(&HandoverRequired->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_TargetID;
ie->criticality = NGAP_Criticality_reject;
ie->value.present = NGAP_HandoverRequiredIEs__value_PR_TargetID;
TargetID = &ie->value.choice.TargetID;
TargetID->present = NGAP_TargetID_PR_targetRANNodeID;
TargetID->choice.targetRANNodeID = targetRANNodeID =
CALLOC(1, sizeof(*targetRANNodeID));
ogs_assert(targetRANNodeID);
globalRANNodeID = &targetRANNodeID->globalRANNodeID;
globalRANNodeID->present = NGAP_GlobalRANNodeID_PR_globalGNB_ID;
globalRANNodeID->choice.globalGNB_ID = globalGNB_ID =
CALLOC(1, sizeof(*globalGNB_ID));
ogs_assert(globalGNB_ID);
plmn_id = &test_self()->plmn_support[0].plmn_id;
ogs_asn_buffer_to_OCTET_STRING(
plmn_id, OGS_PLMN_ID_LEN, &globalGNB_ID->pLMNIdentity);
ogs_ngap_uint32_to_GNB_ID(gnb_id, bitsize, &globalGNB_ID->gNB_ID);
selectedTAI = &targetRANNodeID->selectedTAI;
ogs_ngap_5gs_tai_to_ASN(&test_ue->nr_tai, selectedTAI);
ogs_list_for_each(&test_ue->sess_list, sess) {
if (!PDUSessionList) {
ie = CALLOC(1, sizeof(NGAP_HandoverRequiredIEs_t));
ogs_assert(ie);
ASN_SEQUENCE_ADD(&HandoverRequired->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceListHORqd;
ie->criticality = NGAP_Criticality_reject;
ie->value.present = NGAP_HandoverRequiredIEs__value_PR_PDUSessionResourceListHORqd;
PDUSessionList = &ie->value.choice.PDUSessionResourceListHORqd;
}
PDUSessionItem = CALLOC(1, sizeof(*PDUSessionItem));
ogs_assert(PDUSessionItem);
ASN_SEQUENCE_ADD(&PDUSessionList->list, PDUSessionItem);
PDUSessionItem->pDUSessionID = sess->psi;
n2smbuf = testngap_build_handover_required_transfer(sess, direct);
ogs_assert(n2smbuf);
transfer = &PDUSessionItem->handoverRequiredTransfer;
transfer->size = n2smbuf->len;
transfer->buf = CALLOC(transfer->size, sizeof(uint8_t));
memcpy(transfer->buf, n2smbuf->data, transfer->size);
ogs_pkbuf_free(n2smbuf);
}
ie = CALLOC(1, sizeof(NGAP_HandoverRequiredIEs_t));
ogs_assert(ie);
ASN_SEQUENCE_ADD(&HandoverRequired->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_SourceToTarget_TransparentContainer;
ie->criticality = NGAP_Criticality_reject;
ie->value.present = NGAP_HandoverRequiredIEs__value_PR_SourceToTarget_TransparentContainer;
SourceToTarget_TransparentContainer =
&ie->value.choice.SourceToTarget_TransparentContainer;
OGS_HEX(_container, strlen(_container), tmp),
SourceToTarget_TransparentContainer->size = 32;
SourceToTarget_TransparentContainer->buf =
CALLOC(SourceToTarget_TransparentContainer->size, sizeof(uint8_t));
memcpy(SourceToTarget_TransparentContainer->buf,
tmp, SourceToTarget_TransparentContainer->size);
return ogs_ngap_encode(&pdu);
}
ogs_pkbuf_t *testngap_build_handover_request_ack(test_ue_t *test_ue)
{
int rv;
test_sess_t *sess = NULL;
NGAP_NGAP_PDU_t pdu;
NGAP_SuccessfulOutcome_t *successfulOutcome = NULL;
NGAP_HandoverRequestAcknowledge_t *HandoverRequestAcknowledge = NULL;
NGAP_HandoverRequestAcknowledgeIEs_t *ie = NULL;
NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL;
NGAP_RAN_UE_NGAP_ID_t *RAN_UE_NGAP_ID = NULL;
NGAP_PDUSessionResourceAdmittedList_t *PDUSessionList = NULL;
NGAP_PDUSessionResourceAdmittedItem_t *PDUSessionItem = NULL;
NGAP_TargetToSource_TransparentContainer_t
*TargetToSource_TransparentContainer = NULL;
uint8_t tmp[OGS_MAX_SDU_LEN];
char *_container =
"00010000";
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome;
pdu.choice.successfulOutcome = CALLOC(1, sizeof(NGAP_SuccessfulOutcome_t));
successfulOutcome = pdu.choice.successfulOutcome;
successfulOutcome->procedureCode =
NGAP_ProcedureCode_id_HandoverResourceAllocation;
successfulOutcome->criticality = NGAP_Criticality_reject;
successfulOutcome->value.present =
NGAP_SuccessfulOutcome__value_PR_HandoverRequestAcknowledge;
HandoverRequestAcknowledge =
&successfulOutcome->value.choice.HandoverRequestAcknowledge;
ie = CALLOC(1, sizeof(NGAP_HandoverRequestAcknowledgeIEs_t));
ogs_assert(ie);
ASN_SEQUENCE_ADD(&HandoverRequestAcknowledge->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID;
ie->criticality = NGAP_Criticality_ignore;
ie->value.present =
NGAP_HandoverRequestAcknowledgeIEs__value_PR_AMF_UE_NGAP_ID;
AMF_UE_NGAP_ID = &ie->value.choice.AMF_UE_NGAP_ID;
ie = CALLOC(1, sizeof(NGAP_HandoverRequestAcknowledgeIEs_t));
ogs_assert(ie);
ASN_SEQUENCE_ADD(&HandoverRequestAcknowledge->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID;
ie->criticality = NGAP_Criticality_ignore;
ie->value.present =
NGAP_HandoverRequestAcknowledgeIEs__value_PR_RAN_UE_NGAP_ID;
RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID;
asn_uint642INTEGER(AMF_UE_NGAP_ID, test_ue->amf_ue_ngap_id);
test_ue->ran_ue_ngap_id++;
*RAN_UE_NGAP_ID = test_ue->ran_ue_ngap_id;
ogs_list_for_each(&test_ue->sess_list, sess) {
OCTET_STRING_t *transfer = NULL;
ogs_pkbuf_t *n2smbuf = NULL;
if (!PDUSessionList) {
ie = CALLOC(1, sizeof(NGAP_HandoverRequestAcknowledgeIEs_t));
ogs_assert(ie);
ASN_SEQUENCE_ADD(&HandoverRequestAcknowledge->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceAdmittedList;
ie->criticality = NGAP_Criticality_ignore;
ie->value.present = NGAP_HandoverRequestAcknowledgeIEs__value_PR_PDUSessionResourceAdmittedList;
PDUSessionList = &ie->value.choice.PDUSessionResourceAdmittedList;
}
PDUSessionItem = CALLOC(1,
sizeof(struct NGAP_PDUSessionResourceAdmittedItem));
ogs_assert(PDUSessionItem);
ASN_SEQUENCE_ADD(&PDUSessionList->list, PDUSessionItem);
PDUSessionItem->pDUSessionID = sess->psi;
n2smbuf = testngap_build_handover_request_ack_transfer(sess);
ogs_assert(n2smbuf);
transfer = &PDUSessionItem->handoverRequestAcknowledgeTransfer;
transfer->size = n2smbuf->len;
transfer->buf = CALLOC(transfer->size, sizeof(uint8_t));
memcpy(transfer->buf, n2smbuf->data, transfer->size);
ogs_pkbuf_free(n2smbuf);
}
ie = CALLOC(1, sizeof(NGAP_HandoverRequestAcknowledgeIEs_t));
ogs_assert(ie);
ASN_SEQUENCE_ADD(&HandoverRequestAcknowledge->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_TargetToSource_TransparentContainer;
ie->criticality = NGAP_Criticality_reject;
ie->value.present = NGAP_HandoverRequestAcknowledgeIEs__value_PR_TargetToSource_TransparentContainer;
TargetToSource_TransparentContainer =
&ie->value.choice.TargetToSource_TransparentContainer;
OGS_HEX(_container, strlen(_container), tmp),
TargetToSource_TransparentContainer->size = 4;
TargetToSource_TransparentContainer->buf =
CALLOC(TargetToSource_TransparentContainer->size, sizeof(uint8_t));
memcpy(TargetToSource_TransparentContainer->buf,
tmp, TargetToSource_TransparentContainer->size);
return ogs_ngap_encode(&pdu);
}
ogs_pkbuf_t *testngap_build_uplink_ran_status_transfer(test_ue_t *test_ue)
{
test_sess_t *sess = NULL;
NGAP_NGAP_PDU_t pdu;
NGAP_InitiatingMessage_t *initiatingMessage = NULL;
NGAP_UplinkRANStatusTransfer_t *UplinkRANStatusTransfer = NULL;
NGAP_UplinkRANStatusTransferIEs_t *ie = NULL;
NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL;
NGAP_RAN_UE_NGAP_ID_t *RAN_UE_NGAP_ID = NULL;
NGAP_RANStatusTransfer_TransparentContainer_t
*RANStatusTransfer_TransparentContainer = NULL;
NGAP_DRBsSubjectToStatusTransferList_t *StatusTransferList = NULL;
ogs_assert(test_ue);
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode =
NGAP_ProcedureCode_id_UplinkRANStatusTransfer;
initiatingMessage->criticality = NGAP_Criticality_ignore;
initiatingMessage->value.present =
NGAP_InitiatingMessage__value_PR_UplinkRANStatusTransfer;
UplinkRANStatusTransfer = &initiatingMessage->value.choice.UplinkRANStatusTransfer;
ie = CALLOC(1, sizeof(NGAP_UplinkRANStatusTransferIEs_t));
ogs_assert(ie);
ASN_SEQUENCE_ADD(&UplinkRANStatusTransfer->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID;
ie->criticality = NGAP_Criticality_reject;
ie->value.present =
NGAP_UplinkRANStatusTransferIEs__value_PR_AMF_UE_NGAP_ID;
AMF_UE_NGAP_ID = &ie->value.choice.AMF_UE_NGAP_ID;
ie = CALLOC(1, sizeof(NGAP_UplinkRANStatusTransferIEs_t));
ogs_assert(ie);
ASN_SEQUENCE_ADD(&UplinkRANStatusTransfer->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID;
ie->criticality = NGAP_Criticality_reject;
ie->value.present =
NGAP_UplinkRANStatusTransferIEs__value_PR_RAN_UE_NGAP_ID;
RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID;
asn_uint642INTEGER(AMF_UE_NGAP_ID, test_ue->amf_ue_ngap_id);
*RAN_UE_NGAP_ID = test_ue->ran_ue_ngap_id;
ie = CALLOC(1, sizeof(NGAP_UplinkRANStatusTransferIEs_t));
ogs_assert(ie);
ASN_SEQUENCE_ADD(&UplinkRANStatusTransfer->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_RANStatusTransfer_TransparentContainer;
ie->criticality = NGAP_Criticality_reject;
ie->value.present = NGAP_UplinkRANStatusTransferIEs__value_PR_RANStatusTransfer_TransparentContainer;
RANStatusTransfer_TransparentContainer =
&ie->value.choice.RANStatusTransfer_TransparentContainer;
StatusTransferList = &RANStatusTransfer_TransparentContainer->dRBsSubjectToStatusTransferList;
ogs_list_for_each(&test_ue->sess_list, sess) {
NGAP_DRBsSubjectToStatusTransferItem_t *StatusTransferItem = NULL;
NGAP_DRB_ID_t *dRB_ID = NULL;
NGAP_DRBStatusUL_t *dRBStatusUL = NULL;
NGAP_DRBStatusUL12_t *dRBStatusUL12 = NULL;
NGAP_COUNTValueForPDCP_SN12_t *uL_COUNTValue = NULL;
NGAP_DRBStatusDL_t *dRBStatusDL = NULL;
NGAP_DRBStatusDL18_t *dRBStatusDL18 = NULL;
NGAP_COUNTValueForPDCP_SN18_t *dL_COUNTValue = NULL;
StatusTransferItem = CALLOC(1, sizeof(*StatusTransferItem));
ogs_assert(StatusTransferItem);
ASN_SEQUENCE_ADD(&StatusTransferList->list, StatusTransferItem);
dRB_ID = &StatusTransferItem->dRB_ID;
*dRB_ID = sess->psi;
dRBStatusUL = &StatusTransferItem->dRBStatusUL;
dRBStatusUL->present = NGAP_DRBStatusUL_PR_dRBStatusUL12;
dRBStatusUL->choice.dRBStatusUL12 = dRBStatusUL12 =
CALLOC(1, sizeof(*dRBStatusUL12));
uL_COUNTValue = &dRBStatusUL12->uL_COUNTValue;
uL_COUNTValue->pDCP_SN12 = 1;
uL_COUNTValue->hFN_PDCP_SN12 = 2;
dRBStatusDL = &StatusTransferItem->dRBStatusDL;
dRBStatusDL->present = NGAP_DRBStatusDL_PR_dRBStatusDL18;
dRBStatusDL->choice.dRBStatusDL18 = dRBStatusDL18 =
CALLOC(1, sizeof(*dRBStatusDL18));
dL_COUNTValue = &dRBStatusDL18->dL_COUNTValue;
dL_COUNTValue->pDCP_SN18 = 3;
dL_COUNTValue->hFN_PDCP_SN18 = 4;
}
return ogs_ngap_encode(&pdu);
}
ogs_pkbuf_t *testngap_build_handover_notify(test_ue_t *test_ue)
{
NGAP_NGAP_PDU_t pdu;
NGAP_InitiatingMessage_t *initiatingMessage = NULL;
NGAP_HandoverNotify_t *HandoverNotify = NULL;
NGAP_HandoverNotifyIEs_t *ie = NULL;
NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL;
NGAP_RAN_UE_NGAP_ID_t *RAN_UE_NGAP_ID = NULL;
NGAP_UserLocationInformation_t *UserLocationInformation = NULL;
NGAP_UserLocationInformationNR_t *userLocationInformationNR = NULL;
NGAP_NR_CGI_t *nR_CGI = NULL;
NGAP_TAI_t *tAI = NULL;
ogs_assert(test_ue);
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode =
NGAP_ProcedureCode_id_HandoverNotification;
initiatingMessage->criticality = NGAP_Criticality_ignore;
initiatingMessage->value.present =
NGAP_InitiatingMessage__value_PR_HandoverNotify;
HandoverNotify = &initiatingMessage->value.choice.HandoverNotify;
ie = CALLOC(1, sizeof(NGAP_HandoverNotifyIEs_t));
ogs_assert(ie);
ASN_SEQUENCE_ADD(&HandoverNotify->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID;
ie->criticality = NGAP_Criticality_reject;
ie->value.present = NGAP_HandoverNotifyIEs__value_PR_AMF_UE_NGAP_ID;
AMF_UE_NGAP_ID = &ie->value.choice.AMF_UE_NGAP_ID;
ie = CALLOC(1, sizeof(NGAP_HandoverNotifyIEs_t));
ogs_assert(ie);
ASN_SEQUENCE_ADD(&HandoverNotify->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID;
ie->criticality = NGAP_Criticality_reject;
ie->value.present = NGAP_HandoverNotifyIEs__value_PR_RAN_UE_NGAP_ID;
RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID;
asn_uint642INTEGER(AMF_UE_NGAP_ID, test_ue->amf_ue_ngap_id);
*RAN_UE_NGAP_ID = test_ue->ran_ue_ngap_id;
ie = CALLOC(1, sizeof(NGAP_HandoverNotifyIEs_t));
ogs_assert(ie);
ASN_SEQUENCE_ADD(&HandoverNotify->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_UserLocationInformation;
ie->criticality = NGAP_Criticality_ignore;
ie->value.present =
NGAP_HandoverNotifyIEs__value_PR_UserLocationInformation;
UserLocationInformation = &ie->value.choice.UserLocationInformation;
userLocationInformationNR =
CALLOC(1, sizeof(NGAP_UserLocationInformationNR_t));
ogs_assert(userLocationInformationNR);
nR_CGI = &userLocationInformationNR->nR_CGI;
ogs_ngap_nr_cgi_to_ASN(&test_ue->nr_cgi, nR_CGI);
tAI = &userLocationInformationNR->tAI;
ogs_ngap_5gs_tai_to_ASN(&test_ue->nr_tai, tAI);
UserLocationInformation->present =
NGAP_UserLocationInformation_PR_userLocationInformationNR;
UserLocationInformation->choice.userLocationInformationNR =
userLocationInformationNR;
return ogs_ngap_encode(&pdu);
}
ogs_pkbuf_t *testngap_build_handover_failure(test_ue_t *test_ue,
NGAP_Cause_PR group, long cause)
{
int rv;
NGAP_NGAP_PDU_t pdu;
NGAP_UnsuccessfulOutcome_t *unsuccessfulOutcome = NULL;
NGAP_HandoverFailure_t *HandoverFailure = NULL;
NGAP_HandoverFailureIEs_t *ie = NULL;
NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL;
NGAP_Cause_t *Cause = NULL;
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_unsuccessfulOutcome;
pdu.choice.unsuccessfulOutcome =
CALLOC(1, sizeof(NGAP_UnsuccessfulOutcome_t));
unsuccessfulOutcome = pdu.choice.unsuccessfulOutcome;
unsuccessfulOutcome->procedureCode =
NGAP_ProcedureCode_id_HandoverResourceAllocation;
unsuccessfulOutcome->criticality = NGAP_Criticality_reject;
unsuccessfulOutcome->value.present =
NGAP_UnsuccessfulOutcome__value_PR_HandoverFailure;
HandoverFailure = &unsuccessfulOutcome->value.choice.HandoverFailure;
ie = CALLOC(1, sizeof(NGAP_HandoverFailureIEs_t));
ogs_assert(ie);
ASN_SEQUENCE_ADD(&HandoverFailure->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID;
ie->criticality = NGAP_Criticality_ignore;
ie->value.present = NGAP_HandoverFailureIEs__value_PR_AMF_UE_NGAP_ID;
AMF_UE_NGAP_ID = &ie->value.choice.AMF_UE_NGAP_ID;
ie = CALLOC(1, sizeof(NGAP_HandoverFailureIEs_t));
ASN_SEQUENCE_ADD(&HandoverFailure->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_Cause;
ie->criticality = NGAP_Criticality_ignore;
ie->value.present = NGAP_HandoverFailureIEs__value_PR_Cause;
Cause = &ie->value.choice.Cause;
asn_uint642INTEGER(AMF_UE_NGAP_ID, test_ue->amf_ue_ngap_id);
Cause->present = group;
Cause->choice.radioNetwork = cause;
return ogs_ngap_encode(&pdu);
}
ogs_pkbuf_t *testngap_build_handover_cancel(test_ue_t *test_ue,
NGAP_Cause_PR group, long cause)
{
NGAP_NGAP_PDU_t pdu;
NGAP_InitiatingMessage_t *initiatingMessage = NULL;
NGAP_HandoverCancel_t *HandoverCancel = NULL;
NGAP_HandoverCancelIEs_t *ie = NULL;
NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL;
NGAP_RAN_UE_NGAP_ID_t *RAN_UE_NGAP_ID = NULL;
NGAP_Cause_t *Cause = NULL;
ogs_assert(test_ue);
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = NGAP_ProcedureCode_id_HandoverCancel;
initiatingMessage->criticality = NGAP_Criticality_reject;
initiatingMessage->value.present =
NGAP_InitiatingMessage__value_PR_HandoverCancel;
HandoverCancel = &initiatingMessage->value.choice.HandoverCancel;
ie = CALLOC(1, sizeof(NGAP_HandoverCancelIEs_t));
ogs_assert(ie);
ASN_SEQUENCE_ADD(&HandoverCancel->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID;
ie->criticality = NGAP_Criticality_reject;
ie->value.present = NGAP_HandoverCancelIEs__value_PR_AMF_UE_NGAP_ID;
AMF_UE_NGAP_ID = &ie->value.choice.AMF_UE_NGAP_ID;
ie = CALLOC(1, sizeof(NGAP_HandoverCancelIEs_t));
ogs_assert(ie);
ASN_SEQUENCE_ADD(&HandoverCancel->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID;
ie->criticality = NGAP_Criticality_reject;
ie->value.present = NGAP_HandoverCancelIEs__value_PR_RAN_UE_NGAP_ID;
RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID;
asn_uint642INTEGER(AMF_UE_NGAP_ID, test_ue->amf_ue_ngap_id);
*RAN_UE_NGAP_ID = test_ue->ran_ue_ngap_id;
ie = CALLOC(1, sizeof(NGAP_HandoverCancelIEs_t));
ogs_assert(ie);
ASN_SEQUENCE_ADD(&HandoverCancel->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_Cause;
ie->criticality = NGAP_Criticality_ignore;
ie->value.present = NGAP_HandoverCancelIEs__value_PR_Cause;
Cause = &ie->value.choice.Cause;
Cause->present = group;
Cause->choice.radioNetwork = cause;
return ogs_ngap_encode(&pdu);
}
static ogs_pkbuf_t *testngap_build_pdu_session_resource_setup_response_trasfer(
test_sess_t *sess)
{
@ -1340,6 +2043,7 @@ static ogs_pkbuf_t *testngap_build_pdu_session_resource_setup_response_trasfer(
memset(&message, 0, sizeof(message));
dLQosFlowPerTNLInformation = &message.dLQosFlowPerTNLInformation;
uPTransportLayerInformation =
&dLQosFlowPerTNLInformation->uPTransportLayerInformation;
@ -1450,6 +2154,93 @@ static ogs_pkbuf_t *testngap_build_path_switch_request_trasfer(
qosFlowAcceptedItem->qosFlowIdentifier = qos_flow->qfi;
}
return ogs_asn_encode(
&asn_DEF_NGAP_PathSwitchRequestTransfer, &message);
return ogs_asn_encode(&asn_DEF_NGAP_PathSwitchRequestTransfer, &message);
}
static ogs_pkbuf_t *testngap_build_handover_required_transfer(
test_sess_t *sess, bool direct)
{
int rv;
test_bearer_t *qos_flow = NULL;
ogs_gtp_f_teid_t f_teid;
ogs_ip_t ip;
int len;
ogs_assert(sess);
NGAP_HandoverRequiredTransfer_t message;
NGAP_DirectForwardingPathAvailability_t
*directForwardingPathAvailability = NULL;
memset(&message, 0, sizeof(message));
if (direct == true) {
message.directForwardingPathAvailability =
directForwardingPathAvailability =
CALLOC(1, sizeof(*directForwardingPathAvailability));
*directForwardingPathAvailability =
NGAP_DirectForwardingPathAvailability_direct_path_available;
}
return ogs_asn_encode(&asn_DEF_NGAP_HandoverRequiredTransfer, &message);
}
static ogs_pkbuf_t *testngap_build_handover_request_ack_transfer(
test_sess_t *sess)
{
int rv;
test_bearer_t *qos_flow = NULL;
ogs_gtp_f_teid_t f_teid;
ogs_ip_t ip;
int len;
ogs_assert(sess);
NGAP_HandoverRequestAcknowledgeTransfer_t message;
NGAP_UPTransportLayerInformation_t *dL_NGU_UP_TNLInformation = NULL;
NGAP_QosFlowListWithDataForwarding_t *qosFlowSetupResponseList = NULL;
NGAP_QosFlowItemWithDataForwarding_t *qosFlowSetupResponseItem = NULL;
NGAP_GTPTunnel_t *gTPTunnel = NULL;
memset(&message, 0, sizeof(message));
dL_NGU_UP_TNLInformation = &message.dL_NGU_UP_TNLInformation;
dL_NGU_UP_TNLInformation->present =
NGAP_UPTransportLayerInformation_PR_gTPTunnel;
dL_NGU_UP_TNLInformation->choice.gTPTunnel = gTPTunnel =
CALLOC(1, sizeof(struct NGAP_GTPTunnel));
ogs_assert(gTPTunnel);
ogs_assert(sess->gnb_n3_addr || sess->gnb_n3_addr6);
rv = ogs_gtp_sockaddr_to_f_teid(
sess->gnb_n3_addr, sess->gnb_n3_addr6, &f_teid, &len);
ogs_assert(rv == OGS_OK);
rv = ogs_gtp_f_teid_to_ip(&f_teid, &ip);
ogs_assert(rv == OGS_OK);
ogs_asn_ip_to_BIT_STRING(&ip, &gTPTunnel->transportLayerAddress);
ogs_asn_uint32_to_OCTET_STRING(sess->gnb_n3_teid, &gTPTunnel->gTP_TEID);
qosFlowSetupResponseList = &message.qosFlowSetupResponseList;
ogs_list_for_each(&sess->bearer_list, qos_flow) {
qosFlowSetupResponseItem =
CALLOC(1, sizeof(struct NGAP_QosFlowItemWithDataForwarding));
ogs_assert(qosFlowSetupResponseItem);
ASN_SEQUENCE_ADD(&qosFlowSetupResponseList->list,
qosFlowSetupResponseItem);
qosFlowSetupResponseItem->qosFlowIdentifier = qos_flow->qfi;
}
return ogs_asn_encode(
&asn_DEF_NGAP_HandoverRequestAcknowledgeTransfer, &message);
}

View File

@ -52,8 +52,25 @@ ogs_pkbuf_t *testngap_build_pdu_session_resource_modify_response(
ogs_pkbuf_t *testngap_build_pdu_session_resource_release_response(
test_sess_t *sess);
ogs_pkbuf_t *testngap_build_uplink_ran_configuration_transfer(
uint32_t source_gnb_id, uint8_t source_bitsize,
uint32_t target_gnb_id, uint8_t target_bitsize);
ogs_pkbuf_t *testngap_build_path_switch_request(test_ue_t *test_ue);
ogs_pkbuf_t *testngap_build_handover_required(
test_ue_t *test_ue, NGAP_HandoverType_t handover_type,
uint32_t gnb_id, uint8_t bitsize,
NGAP_Cause_PR group, long cause,
bool direct);
ogs_pkbuf_t *testngap_build_uplink_ran_status_transfer(test_ue_t *test_ue);
ogs_pkbuf_t *testngap_build_handover_request_ack(test_ue_t *test_ue);
ogs_pkbuf_t *testngap_build_handover_notify(test_ue_t *test_ue);
ogs_pkbuf_t *testngap_build_handover_failure(test_ue_t *test_ue,
NGAP_Cause_PR group, long cause);
ogs_pkbuf_t *testngap_build_handover_cancel(test_ue_t *test_ue,
NGAP_Cause_PR group, long cause);
#ifdef __cplusplus
}
#endif

View File

@ -600,3 +600,42 @@ void testngap_handle_pdu_session_resource_release_command(
if (NAS_PDU)
testngap_send_to_nas(test_ue, NAS_PDU);
}
void testngap_handle_handover_request(
test_ue_t *test_ue, ogs_ngap_message_t *message)
{
int rv, i;
char buf[OGS_ADDRSTRLEN];
NGAP_NGAP_PDU_t pdu;
NGAP_InitiatingMessage_t *initiatingMessage = NULL;
NGAP_HandoverRequest_t *HandoverRequest = NULL;
NGAP_HandoverRequestIEs_t *ie = NULL;
NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL;
ogs_assert(test_ue);
ogs_assert(message);
initiatingMessage = message->choice.initiatingMessage;
ogs_assert(initiatingMessage);
HandoverRequest = &initiatingMessage->value.choice.HandoverRequest;
ogs_assert(HandoverRequest);
for (i = 0; i < HandoverRequest->protocolIEs.list.count; i++) {
ie = HandoverRequest->protocolIEs.list.array[i];
switch (ie->id) {
case NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID:
AMF_UE_NGAP_ID = &ie->value.choice.AMF_UE_NGAP_ID;
break;
default:
break;
}
}
if (AMF_UE_NGAP_ID) {
uint64_t amf_ue_ngap_id;
asn_INTEGER2ulong(AMF_UE_NGAP_ID, (unsigned long *)&amf_ue_ngap_id);
test_ue->amf_ue_ngap_id = (uint64_t)amf_ue_ngap_id;
}
}

View File

@ -33,6 +33,7 @@ void testngap_handle_initial_context_setup_request(
test_ue_t *test_ue, ogs_ngap_message_t *message);
void testngap_handle_ue_release_context_command(
test_ue_t *test_ue, ogs_ngap_message_t *message);
void testngap_handle_pdu_session_resource_setup_request(
test_ue_t *test_ue, ogs_ngap_message_t *message);
void testngap_handle_pdu_session_resource_modify_request(
@ -40,6 +41,9 @@ void testngap_handle_pdu_session_resource_modify_request(
void testngap_handle_pdu_session_resource_release_command(
test_ue_t *test_ue, ogs_ngap_message_t *message);
void testngap_handle_handover_request(
test_ue_t *test_ue, ogs_ngap_message_t *message);
#ifdef __cplusplus
}
#endif

View File

@ -65,6 +65,13 @@ void testngap_recv(test_ue_t *test_ue, ogs_pkbuf_t *pkbuf)
case NGAP_ProcedureCode_id_PDUSessionResourceRelease:
testngap_handle_pdu_session_resource_release_command(test_ue, pdu);
break;
case NGAP_ProcedureCode_id_DownlinkRANConfigurationTransfer:
break;
case NGAP_ProcedureCode_id_HandoverResourceAllocation:
testngap_handle_handover_request(test_ue, pdu);
break;
case NGAP_ProcedureCode_id_DownlinkRANStatusTransfer:
break;
case NGAP_ProcedureCode_id_ErrorIndication:
case NGAP_ProcedureCode_id_Paging:
/* Nothing */
@ -88,6 +95,10 @@ void testngap_recv(test_ue_t *test_ue, ogs_pkbuf_t *pkbuf)
break;
case NGAP_ProcedureCode_id_PathSwitchRequest:
break;
case NGAP_ProcedureCode_id_HandoverPreparation:
break;
case NGAP_ProcedureCode_id_HandoverCancel:
break;
case NGAP_ProcedureCode_id_NGReset:
break;
default:
@ -106,6 +117,8 @@ void testngap_recv(test_ue_t *test_ue, ogs_pkbuf_t *pkbuf)
switch (unsuccessfulOutcome->procedureCode) {
case NGAP_ProcedureCode_id_NGSetup:
break;
case NGAP_ProcedureCode_id_HandoverPreparation:
break;
default:
ogs_error("Not implemented(choice:%d, proc:%d)",
pdu->present, (int)unsuccessfulOutcome->procedureCode);

1850
tests/handover/5gc-n2-test.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,7 @@
abts_suite *test_epc_x2(abts_suite *suite);
abts_suite *test_epc_s1(abts_suite *suite);
abts_suite *test_5gc_xn(abts_suite *suite);
abts_suite *test_5gc_n2(abts_suite *suite);
const struct testlist {
abts_suite *(*func)(abts_suite *suite);
@ -29,6 +30,7 @@ const struct testlist {
{test_epc_x2},
{test_epc_s1},
{test_5gc_xn},
{test_5gc_n2},
{NULL},
};

View File

@ -20,6 +20,7 @@ testapp_handover_sources = files('''
epc-x2-test.c
epc-s1-test.c
5gc-xn-test.c
5gc-n2-test.c
'''.split())
testapp_handover_exe = executable('handover',