update it

This commit is contained in:
Sukchan Lee 2017-09-11 23:58:16 +09:00
parent b7c544c8db
commit 4595fd666d
11 changed files with 176 additions and 50 deletions

View File

@ -79,7 +79,7 @@ void esm_state_inactive(fsm_t *s, event_t *e)
if (MME_HAVE_ENB_S1U_PATH(bearer))
{
rv = mme_gtp_send_modify_bearer_request(bearer);
rv = mme_gtp_send_modify_bearer_request(bearer, 0);
d_assert(rv == CORE_OK, return,
"mme_gtp_send_modify_bearer_request failed");
}

View File

@ -123,7 +123,8 @@ status_t mme_gtp_send_create_session_request(mme_sess_t *sess)
}
status_t mme_gtp_send_modify_bearer_request(mme_bearer_t *bearer)
status_t mme_gtp_send_modify_bearer_request(
mme_bearer_t *bearer, c_uint32_t presencemask)
{
status_t rv;
@ -144,7 +145,8 @@ status_t mme_gtp_send_modify_bearer_request(mme_bearer_t *bearer)
h.type = GTP_MODIFY_BEARER_REQUEST_TYPE;
h.teid = mme_ue->sgw_s11_teid;
rv = mme_s11_build_modify_bearer_request(&pkbuf, h.type, bearer);
rv = mme_s11_build_modify_bearer_request(
&pkbuf, h.type, bearer, presencemask);
d_assert(rv == CORE_OK, return CORE_ERROR, "S11 build error");
xact = gtp_xact_local_create(sess->sgw, &h, pkbuf);

View File

@ -14,7 +14,7 @@ CORE_DECLARE(status_t) mme_gtp_close();
CORE_DECLARE(status_t) mme_gtp_send_create_session_request(mme_sess_t *sess);
CORE_DECLARE(status_t) mme_gtp_send_modify_bearer_request(
mme_bearer_t *bearer);
mme_bearer_t *bearer, c_uint32_t presencemask);
CORE_DECLARE(status_t) mme_gtp_send_delete_session_request(
mme_sess_t *sess);
CORE_DECLARE(status_t) mme_gtp_send_delete_all_sessions(

View File

@ -8,6 +8,8 @@
#include "types.h"
#include "mme_context.h"
#include "mme_s11_build.h"
status_t mme_s11_build_create_session_request(
pkbuf_t **pkbuf, c_uint8_t type, mme_sess_t *sess)
{
@ -158,14 +160,16 @@ status_t mme_s11_build_create_session_request(
return CORE_OK;
}
status_t mme_s11_build_modify_bearer_request(
pkbuf_t **pkbuf, c_uint8_t type, mme_bearer_t *bearer)
status_t mme_s11_build_modify_bearer_request(pkbuf_t **pkbuf,
c_uint8_t type, mme_bearer_t *bearer, c_uint32_t presencemask)
{
status_t rv;
gtp_message_t gtp_message;
gtp_modify_bearer_request_t *req = &gtp_message.modify_bearer_request;
gtp_f_teid_t enb_s1u_teid;
gtp_uli_t uli;
char uli_buf[GTP_MAX_ULI_LEN];
d_assert(bearer, return CORE_ERROR, "Null param");
@ -187,6 +191,25 @@ status_t mme_s11_build_modify_bearer_request(
req->bearer_contexts_to_be_modified.s1_u_enodeb_f_teid.len =
GTP_F_TEID_IPV4_LEN;
if (presencemask & MME_S11_MODIFY_BEARER_REQUEST_ULI_PRESENT)
{
mme_ue_t *mme_ue = bearer->mme_ue;
d_assert(mme_ue, return CORE_ERROR, "Null param");
memset(&uli, 0, sizeof(gtp_uli_t));
uli.flags.e_cgi = 1;
uli.flags.tai = 1;
memcpy(&uli.tai.plmn_id, &mme_ue->enb_ue->tai.plmn_id,
sizeof(uli.tai.plmn_id));
uli.tai.tac = mme_ue->enb_ue->tai.tac;
memcpy(&uli.e_cgi.plmn_id, &mme_ue->enb_ue->e_cgi.plmn_id,
sizeof(uli.e_cgi.plmn_id));
uli.e_cgi.cell_id = mme_ue->enb_ue->e_cgi.cell_id;
req->user_location_information.presence = 1;
gtp_build_uli(&req->user_location_information, &uli,
uli_buf, GTP_MAX_ULI_LEN);
}
gtp_message.h.type = type;
rv = gtp_build_msg(pkbuf, &gtp_message);
d_assert(rv == CORE_OK, return CORE_ERROR, "gtp build failed");
@ -251,10 +274,16 @@ status_t mme_s11_build_create_bearer_response(
gtp_message_t gtp_message;
gtp_create_bearer_response_t *rsp = &gtp_message.create_bearer_response;
mme_ue_t *mme_ue = NULL;
gtp_cause_t cause;
gtp_f_teid_t enb_s1u_teid, sgw_s1u_teid;
gtp_uli_t uli;
char uli_buf[GTP_MAX_ULI_LEN];
d_assert(bearer, return CORE_ERROR, "Null param");
mme_ue = bearer->mme_ue;
d_assert(mme_ue, return CORE_ERROR, "Null param");
memset(&gtp_message, 0, sizeof(gtp_message_t));
@ -295,6 +324,19 @@ status_t mme_s11_build_create_bearer_response(
rsp->bearer_contexts.cause.len = sizeof(cause);
rsp->bearer_contexts.cause.data = &cause;
memset(&uli, 0, sizeof(gtp_uli_t));
uli.flags.e_cgi = 1;
uli.flags.tai = 1;
memcpy(&uli.tai.plmn_id, &mme_ue->enb_ue->tai.plmn_id,
sizeof(uli.tai.plmn_id));
uli.tai.tac = mme_ue->enb_ue->tai.tac;
memcpy(&uli.e_cgi.plmn_id, &mme_ue->enb_ue->e_cgi.plmn_id,
sizeof(uli.e_cgi.plmn_id));
uli.e_cgi.cell_id = mme_ue->enb_ue->e_cgi.cell_id;
rsp->user_location_information.presence = 1;
gtp_build_uli(&rsp->user_location_information, &uli,
uli_buf, GTP_MAX_ULI_LEN);
/* TODO : UE Time Zone */
gtp_message.h.type = type;

View File

@ -9,16 +9,23 @@ extern "C" {
CORE_DECLARE(status_t) mme_s11_build_create_session_request(
pkbuf_t **pkbuf, c_uint8_t type, mme_sess_t *sess);
CORE_DECLARE(status_t) mme_s11_build_modify_bearer_request(
pkbuf_t **pkbuf, c_uint8_t type, mme_bearer_t *bearer);
#define MME_S11_MODIFY_BEARER_REQUEST_ULI_PRESENT (1<<0)
CORE_DECLARE(status_t) mme_s11_build_modify_bearer_request(pkbuf_t **pkbuf,
c_uint8_t type, mme_bearer_t *bearer, c_uint32_t presencemask);
CORE_DECLARE(status_t) mme_s11_build_delete_session_request(
pkbuf_t **pkbuf, c_uint8_t type, mme_sess_t *sess);
CORE_DECLARE(status_t) mme_s11_build_create_bearer_response(
pkbuf_t **pkbuf, c_uint8_t type, mme_bearer_t *bearer);
CORE_DECLARE(status_t) mme_s11_build_release_access_bearers_request(
pkbuf_t **pkbuf, c_uint8_t type);
CORE_DECLARE(status_t) mme_s11_build_downlink_data_notification_ack(
pkbuf_t **pkbuf, c_uint8_t type, mme_ue_t *mme_ue);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -9,6 +9,7 @@
#include "nas_path.h"
#include "mme_gtp_path.h"
#include "mme_s11_build.h"
#include "s1ap_build.h"
#include "s1ap_handler.h"
@ -246,30 +247,6 @@ void s1ap_handle_ue_capability_info_indication(
enb->enb_id);
}
void s1ap_handle_activate_default_bearer_accept(mme_bearer_t *bearer)
{
status_t rv;
mme_bearer_t *dedicated_bearer = NULL;
d_assert(bearer, return, "Null param");
rv = mme_gtp_send_modify_bearer_request(bearer);
d_assert(rv == CORE_OK, return,
"mme_gtp_send_modify_bearer_request failed");
dedicated_bearer = mme_bearer_next(bearer);
while(dedicated_bearer)
{
rv = nas_send_activate_dedicated_bearer_context_request(
dedicated_bearer);
d_assert(rv == CORE_OK, return,
"nas_send_activate_dedicated_bearer_context failed");
dedicated_bearer = mme_bearer_next(dedicated_bearer);
}
}
void s1ap_handle_initial_context_setup_response(
mme_enb_t *enb, s1ap_message_t *message)
{
@ -316,9 +293,13 @@ void s1ap_handle_initial_context_setup_response(
if (FSM_CHECK(&bearer->sm, esm_state_active))
{
status_t rv;
rv = mme_gtp_send_modify_bearer_request(bearer);
d_assert(rv == CORE_OK, return,
"mme_gtp_send_modify_bearer_request failed");
c_uint32_t presencemask = 0;
if (mme_ue->nas_eps.type == MME_UE_EPS_UPDATE_TYPE)
presencemask = MME_S11_MODIFY_BEARER_REQUEST_ULI_PRESENT;
rv = mme_gtp_send_modify_bearer_request(bearer, presencemask);
d_assert(rv == CORE_OK, return, "gtp send failed");
}
}
}
@ -376,15 +357,13 @@ void s1ap_handle_e_rab_setup_response(
if (bearer->ebi == linked_bearer->ebi)
{
rv = mme_gtp_send_modify_bearer_request(bearer);
d_assert(rv == CORE_OK, return,
"mme_gtp_send_modify_bearer_request failed");
rv = mme_gtp_send_modify_bearer_request(bearer, 0);
d_assert(rv == CORE_OK, return, "gtp send failed");
}
else
{
rv = mme_gtp_send_create_bearer_response(bearer);
d_assert(rv == CORE_OK, return,
"mme_gtp_send_create_bearer_response failed");
d_assert(rv == CORE_OK, return, "gtp send failed");
}
}
}
@ -623,6 +602,8 @@ void s1ap_handle_path_switch_request(
for (i = 0; i < ies->e_RABToBeSwitchedDLList.
s1ap_E_RABToBeSwitchedDLItem.count; i++)
{
status_t rv;
mme_bearer_t *bearer = NULL;
S1ap_E_RABToBeSwitchedDLItem_t *e_rab = NULL;
@ -638,6 +619,10 @@ void s1ap_handle_path_switch_request(
bearer->enb_s1u_teid = ntohl(bearer->enb_s1u_teid);
memcpy(&bearer->enb_s1u_addr, e_rab->transportLayerAddress.buf,
sizeof(bearer->enb_s1u_addr));
rv = mme_gtp_send_modify_bearer_request(
bearer, MME_S11_MODIFY_BEARER_REQUEST_ULI_PRESENT);
d_assert(rv == CORE_OK, return, "gtp send failed");
}
d_trace(3, "[S1AP] PathSwitchRequest : "

View File

@ -18,6 +18,7 @@ void pgw_s5c_handle_create_session_request(
gtp_bearer_qos_t bearer_qos;
gtp_ambr_t *ambr = NULL;
gtp_uli_t uli;
c_uint16_t decoded = 0;
d_assert(xact, return, "Null param");
d_assert(sess, return, "Null param");
@ -78,9 +79,10 @@ void pgw_s5c_handle_create_session_request(
bearer->sgw_s5u_teid = ntohl(sgw_s5u_teid->teid);
bearer->sgw_s5u_addr = sgw_s5u_teid->ipv4_addr;
d_assert(gtp_parse_bearer_qos(&bearer_qos,
&req->bearer_contexts_to_be_created.bearer_level_qos) ==
req->bearer_contexts_to_be_created.bearer_level_qos.len, return,);
decoded = gtp_parse_bearer_qos(&bearer_qos,
&req->bearer_contexts_to_be_created.bearer_level_qos);
d_assert(req->bearer_contexts_to_be_created.bearer_level_qos.len ==
decoded, return,);
sess->pdn.qos.qci = bearer_qos.qci;
sess->pdn.qos.arp.priority_level = bearer_qos.priority_level;
sess->pdn.qos.arp.pre_emption_capability =
@ -97,8 +99,8 @@ void pgw_s5c_handle_create_session_request(
}
/* Set User Location Information */
d_assert(gtp_parse_uli(&uli, &req->user_location_information) ==
req->user_location_information.len, return,);
decoded = gtp_parse_uli(&uli, &req->user_location_information);
d_assert(req->user_location_information.len == decoded, return,);
memcpy(&sess->tai.plmn_id, &uli.tai.plmn_id, sizeof(uli.tai.plmn_id));
sess->tai.tac = uli.tai.tac;
memcpy(&sess->e_cgi.plmn_id, &uli.e_cgi.plmn_id, sizeof(uli.e_cgi.plmn_id));

View File

@ -51,11 +51,6 @@ typedef struct _sgw_ue_t {
lnode_t node; /* A node of list_t */
index_t index; /* An index of this node */
/* UE identity */
c_uint8_t imsi[MAX_IMSI_LEN];
int imsi_len;
c_int8_t imsi_bcd[MAX_IMSI_BCD_LEN+1];
/* IMPORTANT!
* SGW-S11-F-TEID is same with an index */
c_uint32_t sgw_s11_teid;
@ -63,6 +58,11 @@ typedef struct _sgw_ue_t {
c_uint32_t mme_s11_teid; /* MME-S11-F-TEID */
c_uint32_t mme_s11_addr; /* MME-S11-F-TEID IPv4 Address */
/* UE identity */
c_uint8_t imsi[MAX_IMSI_LEN];
int imsi_len;
c_int8_t imsi_bcd[MAX_IMSI_BCD_LEN+1];
#define SGW_S1U_INACTIVE 0x0001
#define SGW_DL_NOTI_SENT 0x0002
@ -129,6 +129,9 @@ typedef struct _sgw_bearer_t {
c_uint32_t pgw_s5u_teid;
c_uint32_t pgw_s5u_addr;
/* User-Lication-Info */
tai_t tai;
e_cgi_t e_cgi;
/* Pkts which will be buffered in case of UE-IDLE */
c_uint32_t num_buffered_pkt;

View File

@ -349,3 +349,38 @@ status_t sgw_gtp_close()
return CORE_OK;
}
status_t sgw_gtp_send_end_marker(sgw_bearer_t *bearer)
{
status_t rv;
pkbuf_t *pkbuf = NULL;
gtp_header_t *h = NULL;
gtp_node_t gnode;
d_assert(bearer, return CORE_ERROR,);
pkbuf = pkbuf_alloc(0, 100 /* enough for END_MARKER; use smaller buffer */);
d_assert(pkbuf, return CORE_ERROR,);
h = (gtp_header_t *)pkbuf->payload;
memset(h, 0, GTPV1U_HEADER_LEN);
/*
* Flags
* 0x20 - Version : GTP release 99 version (1)
* 0x10 - Protocol Type : GTP (1)
*/
h->flags = 0x30;
h->type = GTPU_MSGTYPE_END_MARKER;
h->teid = htonl(bearer->enb_s1u_teid);
gnode.addr = bearer->enb_s1u_addr;
gnode.port = GTPV1_U_UDP_PORT;
gnode.sock = sgw_self()->s1u_sock;
rv = gtp_send(&gnode, pkbuf);
d_assert(rv == CORE_OK, , "gtp send failed");
pkbuf_free(pkbuf);
return rv;
}

View File

@ -10,6 +10,8 @@ extern "C" {
CORE_DECLARE(status_t) sgw_gtp_open();
CORE_DECLARE(status_t) sgw_gtp_close();
CORE_DECLARE(status_t) sgw_gtp_send_end_marker(sgw_bearer_t *bearer);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -14,6 +14,7 @@ void sgw_s11_handle_create_session_request(gtp_xact_t *s11_xact,
sgw_ue_t *sgw_ue, gtp_message_t *gtp_message)
{
status_t rv;
c_uint16_t decoded;
gtp_create_session_request_t *req = NULL;
pkbuf_t *pkbuf = NULL;
gtp_f_teid_t *mme_s11_teid = NULL;
@ -22,6 +23,7 @@ void sgw_s11_handle_create_session_request(gtp_xact_t *s11_xact,
c_uint32_t addr;
c_uint16_t port;
gtp_f_teid_t sgw_s5c_teid, sgw_s5u_teid;
gtp_uli_t uli;
gtp_xact_t *s5c_xact = NULL;
sgw_sess_t *sess = NULL;
@ -58,6 +60,11 @@ void sgw_s11_handle_create_session_request(gtp_xact_t *s11_xact,
d_error("No PGW IP");
return;
}
if (req->user_location_information.presence == 0)
{
d_error("No User Location Inforamtion");
return;
}
sess = sgw_sess_find_by_ebi(sgw_ue,
req->bearer_contexts_to_be_created.eps_bearer_id.u8);
@ -121,6 +128,14 @@ void sgw_s11_handle_create_session_request(gtp_xact_t *s11_xact,
req->bearer_contexts_to_be_created.s5_s8_u_sgw_f_teid.len =
GTP_F_TEID_IPV4_LEN;
/* Set User Location Information */
decoded = gtp_parse_uli(&uli, &req->user_location_information);
d_assert(req->user_location_information.len == decoded, return,);
memcpy(&bearer->tai.plmn_id, &uli.tai.plmn_id, sizeof(uli.tai.plmn_id));
bearer->tai.tac = uli.tai.tac;
memcpy(&bearer->e_cgi.plmn_id, &uli.e_cgi.plmn_id, sizeof(uli.e_cgi.plmn_id));
bearer->e_cgi.cell_id = uli.e_cgi.cell_id;
gtp_message->h.type = GTP_CREATE_SESSION_REQUEST_TYPE;
gtp_message->h.teid = sess->pgw_s5c_teid;
@ -143,6 +158,7 @@ CORE_DECLARE(void) sgw_s11_handle_modify_bearer_request(gtp_xact_t *s11_xact,
sgw_ue_t *sgw_ue, gtp_modify_bearer_request_t *req)
{
status_t rv;
c_uint16_t decoded;
sgw_bearer_t *bearer = NULL;
gtp_modify_bearer_response_t *rsp = NULL;
pkbuf_t *pkbuf = NULL;
@ -150,6 +166,7 @@ CORE_DECLARE(void) sgw_s11_handle_modify_bearer_request(gtp_xact_t *s11_xact,
gtp_cause_t cause;
gtp_f_teid_t *enb_s1u_teid = NULL;
gtp_uli_t uli;
d_assert(s11_xact, return, "Null param");
d_assert(sgw_ue, return, "Null param");
@ -175,6 +192,23 @@ CORE_DECLARE(void) sgw_s11_handle_modify_bearer_request(gtp_xact_t *s11_xact,
req->bearer_contexts_to_be_modified.eps_bearer_id.u8);
d_assert(bearer, return, "No Bearer Context");
/* Set User Location Information */
if (req->user_location_information.presence == 1)
{
decoded = gtp_parse_uli(&uli, &req->user_location_information);
d_assert(req->user_location_information.len == decoded, return,);
memcpy(&bearer->tai.plmn_id, &uli.tai.plmn_id, sizeof(uli.tai.plmn_id));
bearer->tai.tac = uli.tai.tac;
memcpy(&bearer->e_cgi.plmn_id, &uli.e_cgi.plmn_id, sizeof(uli.e_cgi.plmn_id));
if (bearer->e_cgi.cell_id != uli.e_cgi.cell_id)
{
rv = sgw_gtp_send_end_marker(bearer);
d_assert(rv == CORE_OK, return, "gtp send failed");
bearer->e_cgi.cell_id = uli.e_cgi.cell_id;
}
}
/* Data Plane(DL) : eNB-S1U */
enb_s1u_teid = req->bearer_contexts_to_be_modified.s1_u_enodeb_f_teid.data;
bearer->enb_s1u_teid = ntohl(enb_s1u_teid->teid);
@ -256,6 +290,7 @@ void sgw_s11_handle_create_bearer_response(gtp_xact_t *s11_xact,
sgw_ue_t *sgw_ue, gtp_message_t *gtp_message)
{
status_t rv;
c_uint16_t decoded;
pkbuf_t *pkbuf = NULL;
gtp_xact_t *s5c_xact = NULL;
sgw_sess_t *sess = NULL;
@ -264,6 +299,7 @@ void sgw_s11_handle_create_bearer_response(gtp_xact_t *s11_xact,
gtp_f_teid_t *sgw_s1u_teid = NULL, *enb_s1u_teid = NULL;
gtp_f_teid_t sgw_s5u_teid, pgw_s5u_teid;
gtp_uli_t uli;
d_assert(s11_xact, return, "Null param");
d_assert(sgw_ue, return, "Null param");
@ -294,6 +330,11 @@ void sgw_s11_handle_create_bearer_response(gtp_xact_t *s11_xact,
d_error("No SGW TEID");
return;
}
if (req->user_location_information.presence == 0)
{
d_error("No User Location Inforamtion");
return;
}
/* Correlate with SGW-S1U-TEID */
sgw_s1u_teid = req->bearer_contexts.s4_u_sgsn_f_teid.data;
@ -315,6 +356,13 @@ void sgw_s11_handle_create_bearer_response(gtp_xact_t *s11_xact,
bearer->enb_s1u_addr = enb_s1u_teid->ipv4_addr;
req->bearer_contexts.s1_u_enodeb_f_teid.presence = 0;
decoded = gtp_parse_uli(&uli, &req->user_location_information);
d_assert(req->user_location_information.len == decoded, return,);
memcpy(&bearer->tai.plmn_id, &uli.tai.plmn_id, sizeof(uli.tai.plmn_id));
bearer->tai.tac = uli.tai.tac;
memcpy(&bearer->e_cgi.plmn_id, &uli.e_cgi.plmn_id, sizeof(uli.e_cgi.plmn_id));
bearer->e_cgi.cell_id = uli.e_cgi.cell_id;
/* Reset UE state */
SGW_RESET_UE_STATE(sgw_ue, SGW_S1U_INACTIVE);