[SGsAP] DETACH-INDICATOIN/ACK is done

This commit is contained in:
Sukchan Lee 2019-07-05 18:13:32 +09:00
parent a372bd2949
commit cc83c6a586
13 changed files with 139 additions and 40 deletions

View File

@ -28,7 +28,6 @@
#include "nas-path.h"
#include "mme-fd-path.h"
#include "mme-gtp-path.h"
#include "sgsap-path.h"
#include "emm-handler.h"
@ -268,9 +267,6 @@ int emm_handle_attach_complete(
ogs_debug("[EMM] EMM information");
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
if (mme_ue->vlr)
sgsap_send_tmsi_reallocation_complete(mme_ue);
return OGS_OK;
}

View File

@ -30,6 +30,7 @@
#include "esm-handler.h"
#include "nas-path.h"
#include "s1ap-path.h"
#include "sgsap-path.h"
#include "mme-gtp-path.h"
#include "mme-path.h"
#include "mme-sm.h"
@ -206,8 +207,12 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e)
return;
}
rv = mme_send_delete_session_or_detach(mme_ue);
ogs_assert(rv == OGS_OK);
if (mme_ue->p_tmsi) {
rv = sgsap_send_detach_indication(mme_ue);
} else {
rv = mme_send_delete_session_or_detach(mme_ue);
ogs_assert(rv == OGS_OK);
}
OGS_FSM_TRAN(s, &emm_state_de_registered);
return;
@ -592,6 +597,9 @@ void emm_state_initial_context_setup(ogs_fsm_t *s, mme_event_t *e)
OGS_FSM_TRAN(s, emm_state_exception);
break;
}
if (mme_ue->p_tmsi)
sgsap_send_tmsi_reallocation_complete(mme_ue);
OGS_FSM_TRAN(s, &emm_state_registered);
break;
case NAS_ATTACH_REQUEST:

View File

@ -90,8 +90,7 @@ ogs_pkbuf_t *sgsap_build_tmsi_reallocation_complete(mme_ue_t *mme_ue)
return pkbuf;
}
ogs_pkbuf_t *sgsap_build_detach_indication(mme_ue_t *mme_ue,
uint8_t msg_type, uint8_t detach_type)
ogs_pkbuf_t *sgsap_build_detach_indication(mme_ue_t *mme_ue)
{
mme_vlr_t *vlr = NULL;
ogs_tlv_t *root = NULL;
@ -100,33 +99,35 @@ ogs_pkbuf_t *sgsap_build_detach_indication(mme_ue_t *mme_ue,
char mme_name[SGSAP_IE_MME_NAME_LEN+1];
int mme_name_len = 0;
served_gummei_t *served_gummei = &mme_self()->served_gummei[0];
nas_lai_t lai;
uint8_t type = SGSAP_EPS_DETACH_INDICATION;
uint8_t indication = SGSAP_EPS_DETACH_UE_INITIATED;
ogs_assert(mme_ue);
vlr = mme_ue->vlr;
ogs_assert(vlr);
switch (detach_type) {
switch (mme_ue->nas_eps.detach.detach_type) {
/* 0 0 1 : EPS detach */
case NAS_DETACH_TYPE_FROM_UE_EPS_DETACH:
type = SGSAP_EPS_DETACH_INDICATION;
indication = SGSAP_EPS_DETACH_UE_INITIATED;
break;
/* 0 1 0 : IMSI detach */
case NAS_DETACH_TYPE_FROM_UE_IMSI_DETACH:
type = SGSAP_IMSI_DETACH_INDICATION;
indication = SGSAP_IMSI_DETACH_EXPLICIT_UE_INITIATED;
break;
case 6: /* 1 1 0 : reserved */
case 7: /* 1 1 1 : reserved */
ogs_warn("Unknown Detach type[%d]", detach_type);
ogs_warn("Unknown Detach type[%d]", mme_ue->nas_eps.detach.detach_type);
break;
/* 0 1 1 : combined EPS/IMSI detach */
case NAS_DETACH_TYPE_FROM_UE_COMBINED_EPS_IMSI_DETACH:
type = SGSAP_IMSI_DETACH_INDICATION;
indication = SGSAP_IMSI_DETACH_COMBINED_UE_INITIATED;
default: /* all other values */
break;
}
ogs_debug(" INDICATION[%d]", indication);
root = ogs_tlv_add(NULL, SGSAP_IE_IMSI_TYPE, SGSAP_IE_IMSI_LEN, 0,
&mme_ue->nas_mobile_identity_imsi);
@ -136,21 +137,22 @@ ogs_pkbuf_t *sgsap_build_detach_indication(mme_ue_t *mme_ue,
served_gummei->mme_gid[0],
&served_gummei->plmn_id[0]);
ogs_tlv_add(root, SGSAP_IE_MME_NAME_TYPE, mme_name_len, 0, mme_name);
if (msg_type == SGSAP_EPS_DETACH_INDICATION)
if (type == SGSAP_EPS_DETACH_INDICATION) {
ogs_debug("[SGSAP] EPS-DETACH-INDICATION");
ogs_tlv_add(root, SGSAP_IE_EPS_DETACH_INDICATION_TYPE,
SGSAP_IE_EPS_DETACH_INDICATION_LEN, 0, &indication);
else if (msg_type == SGSAP_IMSI_DETACH_INDICATION)
} else if (type == SGSAP_IMSI_DETACH_INDICATION) {
ogs_debug("[SGSAP] IMSI-DETACH-INDICATION");
ogs_tlv_add(root, SGSAP_IE_IMSI_DETACH_INDICATION_TYPE,
SGSAP_IE_IMSI_DETACH_INDICATION_LEN, 0, &indication);
else
} else
ogs_assert_if_reached();
memcpy(&lai, &vlr->lai, sizeof(nas_lai_t));
lai.lac = htons(lai.lac);
ogs_tlv_add(root, SGSAP_IE_LAI_TYPE, SGSAP_IE_LAI_LEN, 0, &lai);
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
ogs_debug(" INDICATION[%d]", indication);
pkbuf = ogs_pkbuf_alloc(NULL, MAX_SDU_LEN);
ogs_pkbuf_put_u8(pkbuf, msg_type);
ogs_pkbuf_put_u8(pkbuf, type);
ogs_pkbuf_put(pkbuf, MAX_SDU_LEN-1);
ogs_pkbuf_trim(pkbuf, 1+ogs_tlv_render(root,

View File

@ -28,8 +28,7 @@ extern "C" {
ogs_pkbuf_t *sgsap_build_location_update_request(mme_ue_t *mme_ue);
ogs_pkbuf_t *sgsap_build_tmsi_reallocation_complete(mme_ue_t *mme_ue);
ogs_pkbuf_t *sgsap_build_detach_indication(mme_ue_t *mme_ue,
uint8_t msg_type, uint8_t detach_type);
ogs_pkbuf_t *sgsap_build_detach_indication(mme_ue_t *mme_ue);
ogs_pkbuf_t *sgsap_build_service_request(mme_ue_t *mme_ue);
ogs_pkbuf_t *sgsap_build_mo_csfb_indication(mme_ue_t *mme_ue);

View File

@ -24,7 +24,7 @@
#include "nas-conv.h"
#include "nas-path.h"
void sgsap_handler_location_update_accept(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
void sgsap_handle_location_update_accept(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
{
ogs_tlv_t *root = NULL, *iter = NULL;
mme_ue_t *mme_ue = NULL;
@ -108,7 +108,7 @@ error:
mme_send_delete_session_or_ue_context_release(mme_ue, enb_ue);
}
void sgsap_handler_location_update_reject(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
void sgsap_handle_location_update_reject(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
{
ogs_tlv_t *root = NULL, *iter = NULL;
mme_ue_t *mme_ue = NULL;
@ -172,3 +172,62 @@ void sgsap_handler_location_update_reject(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
emm_cause, ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
mme_send_delete_session_or_ue_context_release(mme_ue, enb_ue);
}
void sgsap_handle_detach_ack(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
{
ogs_tlv_t *root = NULL, *iter = NULL;
mme_ue_t *mme_ue = NULL;
uint8_t type = 0;
nas_mobile_identity_imsi_t *nas_mobile_identity_imsi = NULL;
int nas_mobile_identity_imsi_len = 0;
ogs_assert(vlr);
ogs_assert(pkbuf);
type = *(unsigned char *)(pkbuf->data);
if (type == SGSAP_EPS_DETACH_ACK)
ogs_debug("[SGSAP] EPS-DETACH-ACK");
else if (type == SGSAP_IMSI_DETACH_ACK)
ogs_debug("[SGSAP] IMSI-DETACH-ACK");
else
ogs_assert_if_reached();
ogs_pkbuf_pull(pkbuf, 1);
root = ogs_tlv_parse_block(pkbuf->len, pkbuf->data, OGS_TLV_MODE_T1_L1);
ogs_assert(root);
iter = root;
while (iter) {
switch (iter->type) {
case SGSAP_IE_IMSI_TYPE:
nas_mobile_identity_imsi = iter->value;
nas_mobile_identity_imsi_len = iter->length;
break;
default:
ogs_warn("Invalid Type [%d]", iter->type);
break;
}
iter = iter->next;
}
ogs_tlv_free_all(root);
ogs_assert(nas_mobile_identity_imsi);
ogs_assert(nas_mobile_identity_imsi_len == SGSAP_IE_IMSI_LEN);
if (nas_mobile_identity_imsi->type == NAS_MOBILE_IDENTITY_IMSI) {
char imsi_bcd[MAX_IMSI_BCD_LEN+1];
nas_imsi_to_bcd(nas_mobile_identity_imsi,
nas_mobile_identity_imsi_len, imsi_bcd);
mme_ue = mme_ue_find_by_imsi_bcd(imsi_bcd);
} else
ogs_assert_if_reached();
ogs_assert(mme_ue);
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
mme_send_delete_session_or_detach(mme_ue);
}

View File

@ -26,8 +26,9 @@
extern "C" {
#endif
void sgsap_handler_location_update_accept(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf);
void sgsap_handler_location_update_reject(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf);
void sgsap_handle_location_update_accept(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf);
void sgsap_handle_location_update_reject(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf);
void sgsap_handle_detach_ack(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf);
#ifdef __cplusplus
}

View File

@ -149,22 +149,13 @@ int sgsap_send_tmsi_reallocation_complete(mme_ue_t *mme_ue)
return OGS_OK;
}
int sgsap_send_detach_indication(mme_ue_t *mme_ue,
uint8_t msg_type, uint8_t detach_type)
int sgsap_send_detach_indication(mme_ue_t *mme_ue)
{
int rv;
ogs_pkbuf_t *pkbuf = NULL;
ogs_assert(mme_ue);
if (msg_type == SGSAP_EPS_DETACH_INDICATION)
ogs_debug("[SGSAP] EPS-DETACH-INDICATION");
else if (msg_type == SGSAP_IMSI_DETACH_INDICATION)
ogs_debug("[SGSAP] IMSI-DETACH-INDICATION");
else
ogs_assert_if_reached();
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
pkbuf = sgsap_build_detach_indication(mme_ue, msg_type, detach_type);
pkbuf = sgsap_build_detach_indication(mme_ue);
rv = sgsap_send_to_vlr(mme_ue, pkbuf);
ogs_assert(rv == OGS_OK);

View File

@ -44,8 +44,7 @@ int sgsap_send_to_vlr(mme_ue_t *mme_ue, ogs_pkbuf_t *pkbuf);
int sgsap_send_location_update_request(mme_ue_t *mme_ue);
int sgsap_send_tmsi_reallocation_complete(mme_ue_t *mme_ue);
int sgsap_send_detach_indication(mme_ue_t *mme_ue,
uint8_t msg_type, uint8_t detach_type);
int sgsap_send_detach_indication(mme_ue_t *mme_ue);
#ifdef __cplusplus
}

View File

@ -118,10 +118,14 @@ void sgsap_state_connected(ogs_fsm_t *s, mme_event_t *e)
type = *(unsigned char *)(pkbuf->data);
switch (type) {
case SGSAP_LOCATION_UPDATE_ACCEPT:
sgsap_handler_location_update_accept(vlr, pkbuf);
sgsap_handle_location_update_accept(vlr, pkbuf);
break;
case SGSAP_LOCATION_UPDATE_REJECT:
sgsap_handler_location_update_reject(vlr, pkbuf);
sgsap_handle_location_update_reject(vlr, pkbuf);
break;
case SGSAP_EPS_DETACH_ACK:
case SGSAP_IMSI_DETACH_ACK:
sgsap_handle_detach_ack(vlr, pkbuf);
break;
default:
ogs_warn("Not implemented(type:%d)", type);

View File

@ -31,7 +31,9 @@ extern "C" {
#define SGSAP_LOCATION_UPDATE_REJECT 11
#define SGSAP_TMSI_REALLOCATION_COMPLETE 12
#define SGSAP_EPS_DETACH_INDICATION 17
#define SGSAP_EPS_DETACH_ACK 18
#define SGSAP_IMSI_DETACH_INDICATION 19
#define SGSAP_IMSI_DETACH_ACK 20
#define SGSAP_MO_CSFB_INDICIATION 24
#define SGSAP_IE_IMSI_TYPE 1

View File

@ -3045,3 +3045,25 @@ int testsgsap_location_update_reject(ogs_pkbuf_t **pkbuf, int i)
return OGS_OK;
}
int testsgsap_imsi_detach_ack(ogs_pkbuf_t **pkbuf, int i)
{
char *payload[TESTS1AP_MAX_MESSAGE] = {
"1401082926240000 111893"
"",
"",
};
uint16_t len[TESTS1AP_MAX_MESSAGE] = {
11,
0,
0,
};
char hexbuf[MAX_SDU_LEN];
*pkbuf = ogs_pkbuf_alloc(NULL, MAX_SDU_LEN);
ogs_pkbuf_put_data(*pkbuf,
OGS_HEX(payload[i], strlen(payload[i]), hexbuf), len[i]);
return OGS_OK;
}

View File

@ -131,6 +131,7 @@ int testgtpu_build_slacc_rs(ogs_pkbuf_t **sendbuf, int i);
int testsgsap_location_update_accept(ogs_pkbuf_t **pkbuf, int i);
int testsgsap_location_update_reject(ogs_pkbuf_t **pkbuf, int i);
int testsgsap_imsi_detach_ack(ogs_pkbuf_t **pkbuf, int i);
#ifdef __cplusplus
}

View File

@ -301,12 +301,27 @@ static void test1_func(abts_case *tc, void *data)
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
#if 0
ogs_msleep(50);
#endif
/* Send Detach Request */
rv = tests1ap_build_detach_request(&sendbuf, msgindex);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive SGsAP IMSI-DETACH-INDICATION */
recvbuf = testvlr_sgsap_read(sgsap);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Send SGsAP IMSI-DETACH-ACK */
rv = testsgsap_imsi_detach_ack(&sendbuf, 0);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = testvlr_sgsap_send(sgsap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive UE Context Release Command */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);