forked from acouzens/open5gs
MME: support for IDR EPS_USER_STATE
keep track of whether we failed to page the UE, as that is needed to provide the correct user state to the HSS.
This commit is contained in:
parent
77d94c0301
commit
21f99ad08d
|
@ -144,6 +144,7 @@ void emm_state_registered(ogs_fsm_t *s, mme_event_t *e)
|
||||||
ogs_warn("Paging to IMSI[%s] failed. Stop paging",
|
ogs_warn("Paging to IMSI[%s] failed. Stop paging",
|
||||||
mme_ue->imsi_bcd);
|
mme_ue->imsi_bcd);
|
||||||
CLEAR_MME_UE_TIMER(mme_ue->t3413);
|
CLEAR_MME_UE_TIMER(mme_ue->t3413);
|
||||||
|
mme_ue->paging.failed = true;
|
||||||
|
|
||||||
if (MME_PAGING_ONGOING(mme_ue))
|
if (MME_PAGING_ONGOING(mme_ue))
|
||||||
mme_send_after_paging(mme_ue, true);
|
mme_send_after_paging(mme_ue, true);
|
||||||
|
|
|
@ -586,6 +586,7 @@ struct mme_ue_s {
|
||||||
ogs_assert(__mME); \
|
ogs_assert(__mME); \
|
||||||
ogs_debug("[%s] Clear Paging Info", (__mME)->imsi_bcd); \
|
ogs_debug("[%s] Clear Paging Info", (__mME)->imsi_bcd); \
|
||||||
(__mME)->paging.type = 0; \
|
(__mME)->paging.type = 0; \
|
||||||
|
(__mME)->paging.failed = false; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define MME_STORE_PAGING_INFO(__mME, __tYPE, __dATA) \
|
#define MME_STORE_PAGING_INFO(__mME, __tYPE, __dATA) \
|
||||||
|
@ -608,6 +609,7 @@ struct mme_ue_s {
|
||||||
#define MME_PAGING_TYPE_DETACH_TO_UE 7
|
#define MME_PAGING_TYPE_DETACH_TO_UE 7
|
||||||
int type;
|
int type;
|
||||||
void *data;
|
void *data;
|
||||||
|
bool failed;
|
||||||
} paging;
|
} paging;
|
||||||
|
|
||||||
/* SGW UE context */
|
/* SGW UE context */
|
||||||
|
|
|
@ -1932,7 +1932,7 @@ static int mme_ogs_diam_s6a_idr_cb( struct msg **msg, struct avp *avp,
|
||||||
char imsi_bcd[OGS_MAX_IMSI_BCD_LEN+1];
|
char imsi_bcd[OGS_MAX_IMSI_BCD_LEN+1];
|
||||||
uint32_t result_code = 0;
|
uint32_t result_code = 0;
|
||||||
bool has_subscriber_data;
|
bool has_subscriber_data;
|
||||||
|
|
||||||
struct msg *ans, *qry;
|
struct msg *ans, *qry;
|
||||||
|
|
||||||
mme_event_t *e = NULL;
|
mme_event_t *e = NULL;
|
||||||
|
@ -2022,7 +2022,7 @@ static int mme_ogs_diam_s6a_idr_cb( struct msg **msg, struct avp *avp,
|
||||||
|
|
||||||
uint32_t ida_cell_id = mme_ue->e_cgi.cell_id;
|
uint32_t ida_cell_id = mme_ue->e_cgi.cell_id;
|
||||||
uint16_t ida_tac = mme_ue->tai.tac;
|
uint16_t ida_tac = mme_ue->tai.tac;
|
||||||
|
|
||||||
struct avp *avp_mme_location_information;
|
struct avp *avp_mme_location_information;
|
||||||
struct avp *avp_e_utran_cell_global_identity;
|
struct avp *avp_e_utran_cell_global_identity;
|
||||||
struct avp *avp_tracking_area_identity;
|
struct avp *avp_tracking_area_identity;
|
||||||
|
@ -2088,18 +2088,58 @@ static int mme_ogs_diam_s6a_idr_cb( struct msg **msg, struct avp *avp,
|
||||||
ogs_assert(ret == 0);
|
ogs_assert(ret == 0);
|
||||||
|
|
||||||
ret = fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp);
|
ret = fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp);
|
||||||
ogs_assert(ret == 0);
|
ogs_assert(ret == 0);
|
||||||
} else {
|
}
|
||||||
if (!has_subscriber_data) {
|
if (idr_message->idr_flags & OGS_DIAM_S6A_IDR_FLAGS_EPS_USER_STATE) {
|
||||||
ogs_error("Insert Subscriber Data "
|
#define OGS_DIAM_S6A_USER_STATE_DETACHED 0
|
||||||
"with unsupported IDR Flags "
|
#define OGS_DIAM_S6A_USER_STATE_ATTACHED_NOT_REACHABLE_FOR_PAGING 1
|
||||||
"or no Subscriber-Data for IMSI[%s]", imsi_bcd);
|
#define OGS_DIAM_S6A_USER_STATE_ATTACHED_REACHABLE_FOR_PAGING 2
|
||||||
/* Set the Origin-Host, Origin-Realm, and Result-Code AVPs */
|
#define OGS_DIAM_S6A_USER_STATE_CONNECTED_NOT_REACHABLE_FOR_PAGING 3
|
||||||
ret = fd_msg_rescode_set(
|
#define OGS_DIAM_S6A_USER_STATE_CONNECTED_REACHABLE_FOR_PAGING 4
|
||||||
ans, (char*)"DIAMETER_UNABLE_TO_COMPLY", NULL, NULL, 1);
|
#define OGS_DIAM_S6A_USER_STATE_RESERVED 5
|
||||||
ogs_assert(ret == 0);
|
struct avp *avp_eps_user_state = NULL;
|
||||||
goto outnoexp;
|
struct avp *avp_mme_user_state = NULL;
|
||||||
}
|
struct avp *avp_user_state = NULL;
|
||||||
|
uint32_t user_state = 0;
|
||||||
|
|
||||||
|
/* check user state */
|
||||||
|
if (!ECM_CONNECTED(mme_ue))
|
||||||
|
user_state = OGS_DIAM_S6A_USER_STATE_DETACHED;
|
||||||
|
else if (mme_ue->paging.failed)
|
||||||
|
user_state = OGS_DIAM_S6A_USER_STATE_CONNECTED_NOT_REACHABLE_FOR_PAGING;
|
||||||
|
else
|
||||||
|
user_state = OGS_DIAM_S6A_USER_STATE_CONNECTED_REACHABLE_FOR_PAGING;
|
||||||
|
|
||||||
|
/* Set the EPS-User-State AVP */
|
||||||
|
ret = fd_msg_avp_new(ogs_diam_s6a_eps_user_state, 0, &avp_eps_user_state);
|
||||||
|
ogs_assert(ret == 0);
|
||||||
|
ret = fd_msg_avp_new(ogs_diam_s6a_mme_user_state, 0, &avp_mme_user_state);
|
||||||
|
ogs_assert(ret == 0);
|
||||||
|
ret = fd_msg_avp_new(ogs_diam_s6a_user_state, 0, &avp_user_state);
|
||||||
|
ogs_assert(ret == 0);
|
||||||
|
memset(&val, 0, sizeof(val));
|
||||||
|
val.i32 = user_state;
|
||||||
|
ret = fd_msg_avp_setvalue(avp_user_state, &val);
|
||||||
|
ogs_assert(ret == 0);
|
||||||
|
ret = fd_msg_avp_add(avp_mme_user_state, MSG_BRW_LAST_CHILD, avp_user_state);
|
||||||
|
ogs_assert(ret == 0);
|
||||||
|
ret = fd_msg_avp_add(avp_eps_user_state, MSG_BRW_LAST_CHILD, avp_mme_user_state);
|
||||||
|
ogs_assert(ret == 0);
|
||||||
|
ret = fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp_eps_user_state);
|
||||||
|
ogs_assert(ret == 0);
|
||||||
|
}
|
||||||
|
if (!has_subscriber_data &&
|
||||||
|
!(idr_message->idr_flags & OGS_DIAM_S6A_IDR_FLAGS_EPS_LOCATION_INFO) &&
|
||||||
|
!(idr_message->idr_flags & OGS_DIAM_S6A_IDR_FLAGS_EPS_USER_STATE))
|
||||||
|
{
|
||||||
|
ogs_error("Insert Subscriber Data "
|
||||||
|
"with unsupported IDR Flags "
|
||||||
|
"or no Subscriber-Data for IMSI[%s]", imsi_bcd);
|
||||||
|
/* Set the Origin-Host, Origin-Realm, and Result-Code AVPs */
|
||||||
|
ret = fd_msg_rescode_set(
|
||||||
|
ans, (char*)"DIAMETER_UNABLE_TO_COMPLY", NULL, NULL, 1);
|
||||||
|
ogs_assert(ret == 0);
|
||||||
|
goto outnoexp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the Origin-Host, Origin-Realm, andResult-Code AVPs */
|
/* Set the Origin-Host, Origin-Realm, andResult-Code AVPs */
|
||||||
|
|
|
@ -296,4 +296,7 @@ void mme_send_after_paging(mme_ue_t *mme_ue, bool failed)
|
||||||
cleanup:
|
cleanup:
|
||||||
CLEAR_SERVICE_INDICATOR(mme_ue);
|
CLEAR_SERVICE_INDICATOR(mme_ue);
|
||||||
MME_CLEAR_PAGING_INFO(mme_ue);
|
MME_CLEAR_PAGING_INFO(mme_ue);
|
||||||
|
/* the above will clear the failure flag, restore it if we failed */
|
||||||
|
if (failed)
|
||||||
|
mme_ue->paging.failed = true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue