[SGsAP] Changed message if Paging failed (#1701)

The problem occurred in the following scenario:

1. VLR sent PAGING-REQUEST to the MME
2. MME sent S1-Paging to the UE
3. Paging failed
4. MME responded SERVICE-REQUEST to the VLR
5. VLR sent DOWNLINK-UNITDATA to the MME
6. Even though there is no S1 Context,
   MME try to sent DownlinkNASTransport message to the UE.
7. So, the problem occurred.

I've changed the number 4 PAGING-REJECT instead of SERVICE-REQUEST.
This commit is contained in:
Sukchan Lee 2022-08-19 18:58:55 +09:00
parent 909f407c20
commit 321c8d4cf9
9 changed files with 82 additions and 34 deletions

View File

@ -1927,6 +1927,11 @@ int mme_enb_sock_type(ogs_sock_t *sock)
return SOCK_STREAM;
}
mme_enb_t *mme_enb_cycle(mme_enb_t *enb)
{
return ogs_pool_cycle(&mme_enb_pool, enb);
}
/** enb_ue_context handling function */
enb_ue_t *enb_ue_add(mme_enb_t *enb, uint32_t enb_ue_s1ap_id)
{
@ -2389,6 +2394,11 @@ void mme_ue_remove_all(void)
}
}
mme_ue_t *mme_ue_cycle(mme_ue_t *mme_ue)
{
return ogs_pool_cycle(&mme_ue_pool, mme_ue);
}
void mme_ue_fsm_init(mme_ue_t *mme_ue)
{
mme_event_t e;

View File

@ -764,6 +764,7 @@ mme_enb_t *mme_enb_find_by_addr(ogs_sockaddr_t *addr);
mme_enb_t *mme_enb_find_by_enb_id(uint32_t enb_id);
int mme_enb_set_enb_id(mme_enb_t *enb, uint32_t enb_id);
int mme_enb_sock_type(ogs_sock_t *sock);
mme_enb_t *mme_enb_cycle(mme_enb_t *enb);
enb_ue_t *enb_ue_add(mme_enb_t *enb, uint32_t enb_ue_s1ap_id);
void enb_ue_remove(enb_ue_t *enb_ue);
@ -794,6 +795,7 @@ mme_ue_t *mme_ue_add(enb_ue_t *enb_ue);
void mme_ue_hash_remove(mme_ue_t *mme_ue);
void mme_ue_remove(mme_ue_t *mme_ue);
void mme_ue_remove_all(void);
mme_ue_t *mme_ue_cycle(mme_ue_t *mme_ue);
void mme_ue_fsm_init(mme_ue_t *mme_ue);
void mme_ue_fsm_fini(mme_ue_t *mme_ue);

View File

@ -173,7 +173,7 @@ void mme_send_after_paging(mme_ue_t *mme_ue, bool failed)
case MME_PAGING_TYPE_CS_CALL_SERVICE:
if (failed == true) {
ogs_assert(OGS_OK ==
sgsap_send_service_request(
sgsap_send_paging_reject(
mme_ue, SGSAP_SGS_CAUSE_UE_UNREACHABLE));
} else {
/* Nothing */
@ -182,7 +182,7 @@ void mme_send_after_paging(mme_ue_t *mme_ue, bool failed)
case MME_PAGING_TYPE_SMS_SERVICE:
if (failed == true) {
ogs_assert(OGS_OK ==
sgsap_send_service_request(
sgsap_send_paging_reject(
mme_ue, SGSAP_SGS_CAUSE_UE_UNREACHABLE));
} else {
ogs_assert(OGS_OK ==
@ -193,9 +193,7 @@ void mme_send_after_paging(mme_ue_t *mme_ue, bool failed)
case MME_PAGING_TYPE_DETACH_TO_UE:
if (failed == true) {
/* Nothing */
ogs_fatal("MME-initiated Detach should not be invoked "
"if Paging failed");
ogs_assert_if_reached();
ogs_warn("MME-initiated Detach cannot be invoked");
} else {
ogs_assert(OGS_OK == nas_eps_send_detach_request(mme_ue));
if (MME_P_TMSI_IS_AVAILABLE(mme_ue)) {

View File

@ -28,13 +28,16 @@
int nas_eps_send_to_enb(mme_ue_t *mme_ue, ogs_pkbuf_t *pkbuf)
{
enb_ue_t *enb_ue = NULL;
ogs_assert(pkbuf);
ogs_assert(mme_ue);
enb_ue = enb_ue_cycle(mme_ue->enb_ue);
ogs_expect_or_return_val(enb_ue, OGS_ERROR);
mme_ue = mme_ue_cycle(mme_ue);
if (!mme_ue) {
ogs_warn("UE(mme-ue) context has already been removed");
ogs_pkbuf_free(pkbuf);
return OGS_ERROR;
}
return s1ap_send_to_enb_ue(enb_ue, pkbuf);
return s1ap_send_to_enb_ue(mme_ue->enb_ue, pkbuf);
}
int nas_eps_send_emm_to_esm(mme_ue_t *mme_ue,
@ -69,22 +72,28 @@ int nas_eps_send_to_downlink_nas_transport(mme_ue_t *mme_ue, ogs_pkbuf_t *pkbuf)
enb_ue_t *enb_ue = NULL;
ogs_assert(pkbuf);
ogs_assert(mme_ue);
mme_ue = mme_ue_cycle(mme_ue);
if (!mme_ue) {
ogs_warn("UE(mme-ue) context has already been removed");
ogs_pkbuf_free(pkbuf);
return OGS_ERROR;
}
enb_ue = enb_ue_cycle(mme_ue->enb_ue);
if (!enb_ue) {
ogs_error("S1 context has already been removed");
ogs_warn("S1 context has already been removed");
ogs_pkbuf_free(pkbuf);
return OGS_ERROR;
} else {
s1apbuf = s1ap_build_downlink_nas_transport(enb_ue, pkbuf);
ogs_expect_or_return_val(s1apbuf, OGS_ERROR);
rv = nas_eps_send_to_enb(mme_ue, s1apbuf);
ogs_expect(rv == OGS_OK);
return rv;
}
s1apbuf = s1ap_build_downlink_nas_transport(enb_ue, pkbuf);
ogs_expect_or_return_val(s1apbuf, OGS_ERROR);
rv = nas_eps_send_to_enb(mme_ue, s1apbuf);
ogs_expect(rv == OGS_OK);
return rv;
}
int nas_eps_send_attach_accept(mme_ue_t *mme_ue)

View File

@ -51,8 +51,15 @@ int s1ap_send_to_enb(mme_enb_t *enb, ogs_pkbuf_t *pkbuf, uint16_t stream_no)
{
char buf[OGS_ADDRSTRLEN];
ogs_assert(enb);
ogs_assert(pkbuf);
enb = mme_enb_cycle(enb);
if (!enb) {
ogs_warn("eNB has already been removed");
ogs_pkbuf_free(pkbuf);
return OGS_ERROR;
}
ogs_assert(enb->sctp.sock);
if (enb->sctp.sock->fd == INVALID_SOCKET) {
ogs_fatal("eNB SCTP socket has already been destroyed");
@ -77,13 +84,16 @@ int s1ap_send_to_enb(mme_enb_t *enb, ogs_pkbuf_t *pkbuf, uint16_t stream_no)
int s1ap_send_to_enb_ue(enb_ue_t *enb_ue, ogs_pkbuf_t *pkbuf)
{
mme_enb_t *enb = NULL;
ogs_assert(pkbuf);
ogs_assert(enb_ue);
enb = enb_ue->enb;
ogs_assert(enb);
enb_ue = enb_ue_cycle(enb_ue);
if (!enb_ue) {
ogs_warn("S1 context has already been removed");
ogs_pkbuf_free(pkbuf);
return OGS_ERROR;
}
return s1ap_send_to_enb(enb, pkbuf, enb_ue->enb_ostream_id);
return s1ap_send_to_enb(enb_ue->enb, pkbuf, enb_ue->enb_ostream_id);
}
int s1ap_delayed_send_to_enb_ue(

View File

@ -237,7 +237,6 @@ ogs_pkbuf_t *sgsap_build_paging_reject(
root = ogs_tlv_add(NULL, OGS_TLV_MODE_T1_L1,
SGSAP_IE_IMSI_TYPE, SGSAP_IE_IMSI_LEN, 0, nas_mobile_identity_imsi);
sgs_cause = SGSAP_SGS_CAUSE_IMSI_UNKNOWN;
ogs_tlv_add(root, OGS_TLV_MODE_T1_L1,
SGSAP_IE_SGS_CAUSE_TYPE, SGSAP_IE_SGS_CAUSE_LEN, 0, &sgs_cause);

View File

@ -209,7 +209,7 @@ void sgsap_handle_location_update_reject(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
return;
error:
ogs_error("Error processing SGsAP LU REJECT");
return;
@ -333,7 +333,7 @@ void sgsap_handle_paging_request(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
ogs_nas_eps_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
} else
ogs_expect_or_return(0);
if (mme_ue) {
@ -386,7 +386,7 @@ paging_reject:
ogs_debug(" IMSI[%s]", imsi_bcd);
sgsap_send_to_vlr_with_sid(
vlr,
vlr,
sgsap_build_paging_reject(
nas_mobile_identity_imsi, nas_mobile_identity_imsi_len,
SGSAP_SGS_CAUSE_IMSI_UNKNOWN),
@ -445,7 +445,7 @@ void sgsap_handle_downlink_unitdata(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
ogs_nas_eps_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
} else
ogs_assert_if_reached();
ogs_expect_or_return(mme_ue);
@ -514,7 +514,7 @@ void sgsap_handle_release_request(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
ogs_nas_eps_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
} else
ogs_expect_or_return(0);
if (mme_ue)
@ -571,7 +571,7 @@ void sgsap_handle_mm_information_request(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
ogs_nas_eps_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
} else
ogs_expect_or_return(0);
if (mme_ue)

View File

@ -175,6 +175,25 @@ int sgsap_send_mo_csfb_indication(mme_ue_t *mme_ue)
return rv;
}
int sgsap_send_paging_reject(mme_ue_t *mme_ue, uint8_t sgs_cause)
{
int rv;
ogs_pkbuf_t *pkbuf = NULL;
ogs_assert(mme_ue);
ogs_debug("[SGSAP] PAGING-REJECT");
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
pkbuf = sgsap_build_paging_reject(
&mme_ue->nas_mobile_identity_imsi,
SGSAP_IE_IMSI_LEN, sgs_cause);
ogs_expect_or_return_val(pkbuf, OGS_ERROR);
rv = sgsap_send_to_vlr(mme_ue, pkbuf);
ogs_expect(rv == OGS_OK);
return rv;
}
int sgsap_send_service_request(mme_ue_t *mme_ue, uint8_t emm_mode)
{
int rv;

View File

@ -47,6 +47,7 @@ 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);
int sgsap_send_mo_csfb_indication(mme_ue_t *mme_ue);
int sgsap_send_paging_reject(mme_ue_t *mme_ue, uint8_t sgs_cause);
int sgsap_send_service_request(mme_ue_t *mme_ue, uint8_t emm_mode);
int sgsap_send_reset_ack(mme_vlr_t *vlr);
int sgsap_send_uplink_unitdata(mme_ue_t *mme_ue,