Implement downlink data notfication(Not tested yet)

This commit is contained in:
James Park 2017-08-02 16:18:19 -07:00
parent faa05ed5e1
commit 55c3d5e92e
14 changed files with 211 additions and 7 deletions

View File

@ -785,3 +785,27 @@ void emm_handle_service_request(
d_assert(emm_send_to_enb(enb_ue, s1apbuf) == CORE_OK,, "s1ap send error");
}
void emm_handle_downlink_data_notification(mme_bearer_t *bearer)
{
status_t rv;
mme_ue_t *mme_ue = NULL;
mme_sess_t *sess;
pkbuf_t *s11buf = NULL;
d_assert(bearer, return, "Null param");
mme_ue = bearer->mme_ue;
d_assert(mme_ue, return, "Null param");
sess = mme_sess_find_by_ebi(mme_ue, bearer->ebi);
d_assert(sess, return, "Null param");
/* Build Downlink data notification ack */
rv = mme_s11_build_downlink_data_notification_ack(&s11buf, sess);
d_assert(rv == CORE_OK, return, "S11 build error");
rv = mme_s11_send_to_sgw(bearer->sgw,
GTP_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE_TYPE, sess->sgw_s11_teid,
s11buf);
/* FIXME : Send s1 paging */
}

View File

@ -31,6 +31,7 @@ CORE_DECLARE(void) emm_handle_delete_session_request(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);
CORE_DECLARE(void) emm_handle_downlink_data_notification(mme_bearer_t *bearer);
#ifdef __cplusplus
}

View File

@ -59,6 +59,8 @@ void emm_state_operational(fsm_t *s, event_t *e)
break;
case GTP_DELETE_SESSION_RESPONSE_TYPE:
emm_handle_delete_session_response(bearer);
case GTP_DOWNLINK_DATA_NOTIFICATION_TYPE:
emm_handle_downlink_data_notification(bearer);
break;
}

View File

@ -250,3 +250,34 @@ status_t mme_s11_build_release_access_bearers_request(pkbuf_t **pkbuf)
return CORE_OK;
}
status_t mme_s11_build_downlink_data_notification_ack(pkbuf_t **pkbuf,
mme_sess_t *sess)
{
status_t rv;
mme_ue_t *mme_ue = NULL;
gtp_message_t gtp_message;
gtp_downlink_data_notification_acknowledge_t *ack =
&gtp_message.downlink_data_notification_acknowledge;
gtp_cause_t cause;
d_assert(sess, return CORE_ERROR, "Null param");
mme_ue = sess->mme_ue;
d_assert(mme_ue, return CORE_ERROR, "Null param");
memset(&gtp_message, 0, sizeof(gtp_message_t));
memset(&cause, 0, sizeof(cause));
cause.value = GTP_CAUSE_REQUEST_ACCEPTED;
ack->cause.presence = 1;
ack->cause.data = &cause;
ack->cause.len = sizeof(cause);
rv = gtp_build_msg(pkbuf, GTP_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE_TYPE,
&gtp_message);
d_assert(rv == CORE_OK, return CORE_ERROR, "gtp build failed");
return CORE_OK;
}

View File

@ -15,7 +15,8 @@ CORE_DECLARE(status_t) mme_s11_build_delete_session_request(
pkbuf_t **pkbuf, mme_sess_t *sess);
CORE_DECLARE(status_t) mme_s11_build_release_access_bearers_request(
pkbuf_t **pkbuf);
CORE_DECLARE(status_t) mme_s11_build_downlink_data_notification_ack(
pkbuf_t **pkbuf, mme_sess_t *sess);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -158,3 +158,24 @@ void mme_s11_handle_release_access_bearers_response(
event_set_param3(&e, (c_uintptr_t)GTP_RELEASE_ACCESS_BEARERS_RESPONSE_TYPE);
mme_event_send(&e);
}
void mme_s11_handle_downlink_data_notification(
mme_sess_t *sess, gtp_downlink_data_notification_t *noti)
{
event_t e;
mme_bearer_t *bearer = NULL;
d_assert(sess, return, "Null param");
d_assert(noti, return, "Null param");
d_trace(3, "[GTP] Downlink Data Notification : "
"MME[%d] <-- SGW[%d]\n", sess->mme_s11_teid, sess->sgw_s11_teid);
bearer = mme_bearer_find_by_sess_ebi(sess, noti->eps_bearer_id.u8);
d_assert(bearer, return, "No ESM Context");
event_set(&e, MME_EVT_EMM_BEARER_FROM_S11);
event_set_param1(&e, (c_uintptr_t)bearer->index);
event_set_param2(&e, (c_uintptr_t)GTP_DOWNLINK_DATA_NOTIFICATION_TYPE);
mme_event_send(&e);
}

View File

@ -17,6 +17,8 @@ CORE_DECLARE(void) mme_s11_handle_delete_session_response(
mme_sess_t *sess, gtp_delete_session_response_t *rsp);
CORE_DECLARE(void) mme_s11_handle_release_access_bearers_response(
mme_sess_t *sess, gtp_release_access_bearers_response_t *rsp);
CORE_DECLARE(void) mme_s11_handle_downlink_data_notification(
mme_sess_t *sess, gtp_downlink_data_notification_t *noti);
#ifdef __cplusplus
}

View File

@ -326,6 +326,11 @@ void mme_state_operational(fsm_t *s, event_t *e)
mme_s11_handle_release_access_bearers_response(
sess, &gtp_message.release_access_bearers_response);
break;
case GTP_DOWNLINK_DATA_NOTIFICATION_TYPE:
mme_s11_handle_downlink_data_notification(
sess, &gtp_message.downlink_data_notification);
break;
default:
d_warn("Not implmeneted(type:%d)", type);
break;

View File

@ -86,9 +86,19 @@ typedef struct _sgw_bearer_t {
c_uint32_t pgw_s5u_teid;
c_uint32_t pgw_s5u_addr;
c_uint32_t state;
sgw_sess_t *sess;
} sgw_bearer_t;
#define SGW_DL_NOTI_SENT 0x0001
#define CHECK_DL_NOTI_SENT(bearer) ((bearer)->state & SGW_DL_NOTI_SENT)
#define SET_DL_NOTI_SETNT(bearer) \
do { \
(bearer)->state |= SGW_DL_NOTI_SENT;\
} while (0)
CORE_DECLARE(status_t) sgw_context_init(void);
CORE_DECLARE(status_t) sgw_context_final(void);
CORE_DECLARE(sgw_context_t*) sgw_self(void);
@ -116,6 +126,7 @@ CORE_DECLARE(sgw_bearer_t*) sgw_bearer_find_by_id(
CORE_DECLARE(sgw_bearer_t*) sgw_default_bearer_in_sess(sgw_sess_t *sess);
CORE_DECLARE(sgw_bearer_t*) sgw_bearer_first(sgw_sess_t *sess);
CORE_DECLARE(sgw_bearer_t*) sgw_bearer_next(sgw_bearer_t *bearer);
CORE_DECLARE(sgw_bearer_t*) sgw_bearer_find(index_t index);
#ifdef __cplusplus

View File

@ -15,6 +15,8 @@ typedef enum {
SGW_EVT_TRANSACTION_T3,
SGW_EVT_LO_DLDATA_NOTI,
SGW_EVT_TOP,
} event_e;

View File

@ -319,12 +319,25 @@ void sgw_handle_release_access_bearers_request(gtp_xact_t *xact,
gtp_release_access_bearers_response_t *rsp = NULL;
pkbuf_t *pkbuf = NULL;
gtp_message_t gtp_message;
sgw_bearer_t *bearer = NULL, *next_bearer = NULL;
gtp_cause_t cause;
d_assert(sess, return, "Null param");
d_assert(xact, return, "Null param");
/* Release S1U(DL) path */
bearer = list_first(&sess->bearer_list);
while (bearer)
{
next_bearer = list_next(bearer);
bearer->enb_s1u_teid = 0;
bearer->enb_s1u_addr = 0;
bearer = next_bearer;
}
rsp = &gtp_message.release_access_bearers_response;
memset(&gtp_message, 0, sizeof(gtp_message_t));
@ -347,3 +360,50 @@ void sgw_handle_release_access_bearers_request(gtp_xact_t *xact,
d_trace(3, "[GTP] Release Access Bearers Reqeust : "
"MME[%d] --> SGW[%d]\n", sess->mme_s11_teid, sess->sgw_s11_teid);
}
void sgw_handle_lo_dldata_notification(sgw_bearer_t *bearer)
{
status_t rv;
gtp_downlink_data_notification_t *noti = NULL;
pkbuf_t *pkbuf = NULL;
gtp_message_t gtp_message;
sgw_sess_t *sess = NULL;
gtp_xact_t *xact = NULL;
/* FIXME : ARP should be retrieved from ? */
c_uint8_t arp = 0x61;
d_assert(bearer, return, "Null param");
sess = bearer->sess;
d_assert(sess, return, "Null param");
/* Build downlink notification message */
noti = &gtp_message.downlink_data_notification;
memset(&gtp_message, 0, sizeof(gtp_message_t));
noti->eps_bearer_id.presence = 1;
noti->eps_bearer_id.u8 = bearer->id;
/* FIXME : ARP should be retrieved from ? */
noti->allocation_retention_priority.presence = 1;
noti->allocation_retention_priority.data = &arp;
noti->allocation_retention_priority.len = sizeof(arp);
rv = gtp_build_msg(&pkbuf,
GTP_DOWNLINK_DATA_NOTIFICATION_TYPE, &gtp_message);
d_assert(rv == CORE_OK, return, "gtp build failed");
xact = gtp_xact_local_create(&sgw_self()->gtp_xact_ctx,
sgw_self()->s11_sock, &sgw_self()->s11_node);
d_assert(xact, return , "Null param");
d_assert(sgw_s11_send_to_mme(xact,
GTP_DOWNLINK_DATA_NOTIFICATION_TYPE,
sess->mme_s11_teid, pkbuf) == CORE_OK, return,
"failed to send message");
d_trace(3, "[GTP] Downlink Data Notification : "
"SGW[%d] --> MME[%d]\n", sess->sgw_s11_teid, sess->mme_s11_teid);
}

View File

@ -26,6 +26,7 @@ CORE_DECLARE(void) sgw_handle_delete_session_response(gtp_xact_t *xact,
CORE_DECLARE(void) sgw_handle_release_access_bearers_request(gtp_xact_t *xact,
sgw_sess_t *sess, gtp_release_access_bearers_request_t *req);
CORE_DECLARE(void) sgw_handle_lo_dldata_notification(sgw_bearer_t *bearer);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -108,13 +108,41 @@ static int _gtpv1_s5u_recv_cb(net_sock_t *sock, void *data)
bearer = sgw_bearer_find_by_sgw_s5u_teid(teid);
if (bearer)
{
/* Convert Teid and send to enodeB via s1u */
gtp_h->teid = htonl(bearer->enb_s1u_teid);
gnode.addr = bearer->enb_s1u_addr;
gnode.port = GTPV1_U_UDP_PORT;
if (bearer->enb_s1u_teid)
{
/* Convert Teid and send to enodeB via s1u */
gtp_h->teid = htonl(bearer->enb_s1u_teid);
gnode.addr = bearer->enb_s1u_addr;
gnode.port = GTPV1_U_UDP_PORT;
gtp_send(sgw_self()->s1u_sock, &gnode, pkbuf);
gtp_send(sgw_self()->s1u_sock, &gnode, pkbuf);
}
else
{
/* S1U path is deactivated.
* Send downlink_data_notification to MME.
* FIXME : Data buffering required
*
*/
if (CHECK_DL_NOTI_SENT(bearer))
{
event_t e;
status_t rv;
event_set(&e, SGW_EVT_S5C_SESSION_MSG);
event_set_param1(&e, (c_uintptr_t)bearer->index);
rv = sgw_event_send(&e);
if (rv != CORE_OK)
{
d_error("sgw_event_send error");
pkbuf_free(pkbuf);
return -1;
}
SET_DL_NOTI_SETNT(bearer);
}
}
}
}

View File

@ -122,6 +122,21 @@ void sgw_state_operational(fsm_t *s, event_t *e)
gtp_xact_timeout(event_get_param1(e));
break;
}
case SGW_EVT_LO_DLDATA_NOTI:
{
index_t index = (index_t)event_get_param1(e);
sgw_bearer_t* bearer = sgw_bearer_find(index);
if (!bearer)
{
d_error("Can not find bearer with index(%d)",index);
break;
}
sgw_handle_lo_dldata_notification(bearer);
break;
}
default:
{
d_error("No handler for event %s", sgw_event_get_name(e));