detach done
This commit is contained in:
parent
8c157dec08
commit
62935bd625
|
@ -19,7 +19,7 @@
|
|||
#include "mme_s11_build.h"
|
||||
#include "mme_s11_path.h"
|
||||
|
||||
void emm_handle_identity_request(mme_ue_t *mme_ue);
|
||||
#include "emm_handler.h"
|
||||
|
||||
mme_ue_t *emm_find_ue_by_message(enb_ue_t *enb_ue, nas_message_t *message)
|
||||
{
|
||||
|
@ -569,26 +569,25 @@ void emm_handle_detach_request(
|
|||
status_t rv;
|
||||
mme_enb_t *enb = NULL;
|
||||
enb_ue_t *enb_ue = NULL;
|
||||
pkbuf_t *emmbuf = NULL, *s11buf = NULL, *s1apbuf = NULL;
|
||||
pkbuf_t *s11buf = NULL;
|
||||
mme_sess_t *sess;
|
||||
int delete_session_request_needed = 0;
|
||||
|
||||
nas_message_t message;
|
||||
nas_detach_type_t *detach_type = &detach_request->detach_type;
|
||||
|
||||
/* FIXME: nas_key_set_identifier is ignored
|
||||
* detach_type->tsc
|
||||
* detach_type->nas_key_set_identifier
|
||||
*/
|
||||
|
||||
d_assert(mme_ue, return, "Null param");
|
||||
enb_ue = mme_ue->enb_ue;
|
||||
d_assert(enb_ue, return, "Null param");
|
||||
enb = enb_ue->enb;
|
||||
d_assert(enb, return, "Null param");
|
||||
|
||||
/* Encode ue->s1ap.cause for later use */
|
||||
enb_ue->s1ap.cause.present = S1ap_Cause_PR_nas;
|
||||
enb_ue->s1ap.cause.choice.nas = S1ap_CauseNas_detach;
|
||||
/* save detach_type in MME UE context */
|
||||
d_assert(detach_type, return, "Null param");
|
||||
mme_ue->detach_type.tsc = detach_type->tsc;
|
||||
mme_ue->detach_type.nas_key_set_identifier =
|
||||
detach_type->nas_key_set_identifier;
|
||||
mme_ue->detach_type.switch_off = detach_type->switch_off;
|
||||
mme_ue->detach_type.detach_type = detach_type->detach_type;
|
||||
|
||||
switch (detach_type->detach_type)
|
||||
{
|
||||
|
@ -622,6 +621,8 @@ void emm_handle_detach_request(
|
|||
|
||||
if (bearer != NULL)
|
||||
{
|
||||
delete_session_request_needed = 1;
|
||||
|
||||
rv = mme_s11_build_delete_session_request(&s11buf, sess);
|
||||
d_assert(rv == CORE_OK, return, "S11 build error");
|
||||
|
||||
|
@ -633,9 +634,35 @@ void emm_handle_detach_request(
|
|||
sess = mme_sess_next(sess);
|
||||
}
|
||||
|
||||
if (!delete_session_request_needed)
|
||||
{
|
||||
emm_handle_detach_accept(mme_ue);
|
||||
}
|
||||
}
|
||||
|
||||
void emm_handle_detach_accept(mme_ue_t *mme_ue)
|
||||
{
|
||||
event_t e;
|
||||
|
||||
status_t rv;
|
||||
nas_message_t message;
|
||||
pkbuf_t *emmbuf = NULL, *s1apbuf = NULL;
|
||||
mme_enb_t *enb = NULL;
|
||||
enb_ue_t *enb_ue = NULL;
|
||||
nas_detach_type_t *detach_type = NULL;
|
||||
|
||||
d_assert(mme_ue, return, "Null param");
|
||||
enb_ue = mme_ue->enb_ue;
|
||||
d_assert(enb_ue, return, "Null param");
|
||||
enb = enb_ue->enb;
|
||||
d_assert(enb, return, "Null param");
|
||||
|
||||
detach_type = &mme_ue->detach_type;
|
||||
d_assert(detach_type, return, "Null param");
|
||||
|
||||
/* reply with detach accept */
|
||||
if ((detach_type->switch_off & 0x1) == 0)
|
||||
{
|
||||
/* reply with detach accept */
|
||||
memset(&message, 0, sizeof(message));
|
||||
message.h.security_header_type =
|
||||
NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
|
||||
|
@ -657,17 +684,26 @@ void emm_handle_detach_request(
|
|||
d_assert(s1ap_send_to_enb(enb, s1apbuf) == CORE_OK,, "s1ap send error");
|
||||
}
|
||||
|
||||
/* TODO: initiate s1 ue context release with a timeout value */
|
||||
event_set(&e, MME_EVT_S1AP_UE_FROM_EMM);
|
||||
event_set_param1(&e, (c_uintptr_t)enb->index);
|
||||
event_set_param2(&e, (c_uintptr_t)enb_ue->index);
|
||||
event_set_param3(&e, (c_uintptr_t)NAS_DETACH_ACCEPT);
|
||||
mme_event_send(&e);
|
||||
|
||||
#if 0
|
||||
rv = s1ap_build_ue_context_release_commmand(
|
||||
&s1apbuf, enb_ue, &enb_ue->s1ap.cause);
|
||||
d_assert(rv == CORE_OK && s1apbuf, return, "s1ap build error");
|
||||
|
||||
d_assert(s1ap_send_to_enb(enb, s1apbuf) == CORE_OK,, "s1ap send error");
|
||||
#endif
|
||||
}
|
||||
|
||||
void emm_handle_delete_session_response(mme_bearer_t *bearer)
|
||||
{
|
||||
status_t rv;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
mme_enb_t *enb = NULL;
|
||||
pkbuf_t *s1apbuf = NULL;
|
||||
mme_sess_t *sess;
|
||||
int b_wait = 0;
|
||||
enb_ue_t *enb_ue = NULL;
|
||||
|
||||
d_assert(bearer, return, "Null param");
|
||||
|
@ -681,32 +717,17 @@ void emm_handle_delete_session_response(mme_bearer_t *bearer)
|
|||
sess = mme_sess_find_by_ebi(mme_ue, bearer->ebi);
|
||||
mme_sess_remove(sess);
|
||||
|
||||
/* sess and bearer are not valid from here */
|
||||
d_info("[NAS] Delete Session Response : UE[%s] <-- EMM", mme_ue->imsi_bcd);
|
||||
|
||||
sess = mme_sess_first(mme_ue);
|
||||
while (sess != NULL)
|
||||
switch(mme_ue->last_emm_message_type)
|
||||
{
|
||||
mme_bearer_t *temp_bearer = mme_default_bearer_in_sess(sess);
|
||||
|
||||
if (temp_bearer != NULL)
|
||||
case NAS_DETACH_REQUEST:
|
||||
{
|
||||
b_wait = 1;
|
||||
emm_handle_detach_accept(mme_ue);
|
||||
break;
|
||||
}
|
||||
sess = mme_sess_next(sess);
|
||||
}
|
||||
|
||||
if (!b_wait)
|
||||
{
|
||||
d_info("[NAS] Detach done : UE[%s] <-- EMM", mme_ue->imsi_bcd);
|
||||
|
||||
rv = s1ap_build_ue_context_release_commmand(
|
||||
&s1apbuf, enb_ue, &enb_ue->s1ap.cause);
|
||||
d_assert(rv == CORE_OK && s1apbuf, return, "s1ap build error");
|
||||
|
||||
d_assert(s1ap_send_to_enb(enb, s1apbuf) == CORE_OK,, "s1ap send error");
|
||||
|
||||
/* TODO: launch a timer */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,10 +19,12 @@ CORE_DECLARE(void) emm_handle_attach_complete(
|
|||
mme_ue_t *mme_ue, nas_attach_complete_t *attach_complete);
|
||||
CORE_DECLARE(void) emm_handle_emm_status(
|
||||
mme_ue_t *mme_ue, nas_emm_status_t *emm_status);
|
||||
CORE_DECLARE(void) emm_handle_identity_request(mme_ue_t *mme_ue);
|
||||
CORE_DECLARE(void) emm_handle_identity_response(
|
||||
mme_ue_t *mme_ue, nas_identity_response_t *identity_response);
|
||||
CORE_DECLARE(void) emm_handle_detach_request(
|
||||
mme_ue_t *mme_ue, nas_detach_request_from_ue_t *detach_request);
|
||||
CORE_DECLARE(void) emm_handle_detach_accept(mme_ue_t *mme_ue);
|
||||
CORE_DECLARE(void) emm_handle_delete_session_response(mme_bearer_t *bearer);
|
||||
CORE_DECLARE(void) emm_handle_service_request(
|
||||
mme_ue_t *mme_ue, nas_service_request_t *service_request);
|
||||
|
|
|
@ -134,6 +134,9 @@ void emm_state_operational(fsm_t *s, event_t *e)
|
|||
break;
|
||||
}
|
||||
|
||||
/* save Last EMM Message Type in MME UE Context */
|
||||
mme_ue->last_emm_message_type = message->emm.h.message_type;
|
||||
|
||||
switch(message->emm.h.message_type)
|
||||
{
|
||||
case NAS_ATTACH_REQUEST:
|
||||
|
|
|
@ -123,11 +123,6 @@ struct _enb_ue_t {
|
|||
tai_t tai;
|
||||
e_cgi_t e_cgi;
|
||||
|
||||
/* S1AP transactions */
|
||||
struct {
|
||||
S1ap_Cause_t cause;
|
||||
} s1ap;
|
||||
|
||||
/* mme_ue_context */
|
||||
mme_ue_t *mme_ue;
|
||||
|
||||
|
@ -161,6 +156,7 @@ struct _mme_ue_t {
|
|||
e_cgi_t e_cgi;
|
||||
#endif
|
||||
plmn_id_t visited_plmn_id;
|
||||
nas_detach_type_t detach_type;
|
||||
|
||||
/* Security Context */
|
||||
int security_context_available;
|
||||
|
@ -208,9 +204,11 @@ struct _mme_ue_t {
|
|||
c_uint8_t ebi; /* EPS Bearer ID generator */
|
||||
list_t sess_list;
|
||||
|
||||
|
||||
/* enb ue context */
|
||||
/* eNB UE context */
|
||||
enb_ue_t *enb_ue;
|
||||
|
||||
/* Last Received NAS-EMM Messasge */
|
||||
c_uint8_t last_emm_message_type;
|
||||
};
|
||||
|
||||
typedef struct _mme_sess_t {
|
||||
|
|
|
@ -22,6 +22,8 @@ char* mme_event_get_name(event_t *e)
|
|||
return "MME_EVT_S1AP_ENB_LO_ACCEPT";
|
||||
case MME_EVT_S1AP_ENB_LO_CONNREFUSED:
|
||||
return"MME_EVT_S1AP_ENB_LO_CONNREFUSED";
|
||||
case MME_EVT_S1AP_UE_FROM_EMM:
|
||||
return "MME_EVT_S1AP_UE_FROM_EMM";
|
||||
case MME_EVT_S1AP_UE_FROM_S11:
|
||||
return "MME_EVT_S1AP_UE_FROM_S11";
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ typedef enum {
|
|||
MME_EVT_S1AP_ENB_MSG,
|
||||
MME_EVT_S1AP_ENB_LO_ACCEPT,
|
||||
MME_EVT_S1AP_ENB_LO_CONNREFUSED,
|
||||
MME_EVT_S1AP_UE_FROM_EMM,
|
||||
MME_EVT_S1AP_UE_FROM_S11,
|
||||
|
||||
MME_EVT_EMM_UE_MSG,
|
||||
|
|
|
@ -123,6 +123,7 @@ void mme_state_operational(fsm_t *s, event_t *e)
|
|||
break;
|
||||
}
|
||||
case MME_EVT_S1AP_ENB_MSG:
|
||||
case MME_EVT_S1AP_UE_FROM_EMM:
|
||||
case MME_EVT_S1AP_UE_FROM_S11:
|
||||
{
|
||||
s1ap_message_t message;
|
||||
|
|
|
@ -415,6 +415,26 @@ void s1ap_handle_ue_context_release_request(
|
|||
}
|
||||
}
|
||||
|
||||
void s1ap_handle_detach_accept(
|
||||
mme_enb_t *enb, enb_ue_t *enb_ue)
|
||||
{
|
||||
status_t rv;
|
||||
pkbuf_t *s1apbuf;
|
||||
S1ap_Cause_t cause;
|
||||
|
||||
d_assert(enb, return, "Null param");
|
||||
d_assert(enb_ue, return, "Null param");
|
||||
|
||||
cause.present = S1ap_Cause_PR_nas;
|
||||
cause.choice.nas = S1ap_CauseNas_detach;
|
||||
|
||||
rv = s1ap_build_ue_context_release_commmand(
|
||||
&s1apbuf, enb_ue, &cause);
|
||||
d_assert(rv == CORE_OK && s1apbuf, return, "s1ap build error");
|
||||
|
||||
d_assert(s1ap_send_to_enb(enb, s1apbuf) == CORE_OK,, "s1ap send error");
|
||||
}
|
||||
|
||||
void s1ap_handle_release_access_bearers_response(
|
||||
mme_enb_t *enb, enb_ue_t *enb_ue)
|
||||
{
|
||||
|
@ -455,6 +475,6 @@ void s1ap_handle_ue_context_release_complete(
|
|||
INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf),
|
||||
enb->enb_id);
|
||||
|
||||
d_assert(enb_ue_remove(enb_ue) == CORE_OK,, "No ENB_UE context");
|
||||
enb_ue_remove(enb_ue);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ CORE_DECLARE(void) s1ap_handle_ue_context_release_request(
|
|||
CORE_DECLARE(void) s1ap_handle_ue_context_release_complete(
|
||||
mme_enb_t *enb, s1ap_message_t *message);
|
||||
|
||||
CORE_DECLARE(void) s1ap_handle_detach_accept(mme_enb_t *enb, enb_ue_t *enb_ue);
|
||||
CORE_DECLARE(void) s1ap_handle_release_access_bearers_response(
|
||||
mme_enb_t *enb, enb_ue_t *enb_ue);
|
||||
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
#include "core_debug.h"
|
||||
|
||||
#include "nas_message.h"
|
||||
#include "gtp_tlv.h"
|
||||
|
||||
#include "mme_event.h"
|
||||
|
||||
#include "s1ap_build.h"
|
||||
|
@ -132,6 +135,33 @@ void s1ap_state_operational(fsm_t *s, event_t *e)
|
|||
|
||||
break;
|
||||
}
|
||||
case MME_EVT_S1AP_UE_FROM_EMM:
|
||||
{
|
||||
index_t enb_index = event_get_param1(e);
|
||||
index_t enb_ue_index = event_get_param2(e);
|
||||
mme_enb_t *enb = NULL;
|
||||
enb_ue_t *enb_ue = NULL;
|
||||
|
||||
d_assert(enb_index, return, "Null param");
|
||||
d_assert(enb_ue_index, return, "Null param");
|
||||
|
||||
enb = mme_enb_find(enb_index);
|
||||
d_assert(enb, return, "Null param");
|
||||
|
||||
enb_ue = enb_ue_find(enb_ue_index);
|
||||
d_assert(enb_ue, return, "Null param");
|
||||
|
||||
switch(event_get_param3(e))
|
||||
{
|
||||
case NAS_DETACH_ACCEPT:
|
||||
{
|
||||
s1ap_handle_detach_accept(enb, enb_ue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case MME_EVT_S1AP_UE_FROM_S11:
|
||||
{
|
||||
index_t enb_index = event_get_param1(e);
|
||||
|
|
Loading…
Reference in New Issue