S1AP sends SCTP packet with stream id (#54)

This commit is contained in:
Sukchan Lee 2018-05-13 18:02:24 +09:00
parent 55fa0115e8
commit 7dba30b1e6
11 changed files with 70 additions and 93 deletions

View File

@ -189,7 +189,7 @@ int core_sctp_sendmsg(sock_id id, const void *msg, size_t len,
to ? &to->sa : NULL, addrlen,
htonl(ppid),
0, /* flags */
stream_no,
htons(stream_no),
0, /* timetolive */
0); /* context */
if (size < 0)

View File

@ -1761,17 +1761,6 @@ enb_ue_t* enb_ue_add(mme_enb_t *enb)
index_alloc(&enb_ue_pool, &enb_ue);
d_assert(enb_ue, return NULL, "Null param");
/*
* We'll use self.mme_ue_s1ap_id for generating SCTP stream id
*
* Default number of output stream : 30
* 0 : Non UE assocation
* 1 ~ 29 : UE specific association
*/
enb_ue->ostream_id = self.mme_ue_s1ap_id %
(context_self()->parameter.sctp_streams - 1) + 1;
enb_ue->enb_ue_s1ap_id = INVALID_UE_S1AP_ID;
enb_ue->mme_ue_s1ap_id = NEXT_ID(self.mme_ue_s1ap_id, 1, 0xffffffff);
enb_ue->enb = enb;

View File

@ -160,8 +160,6 @@ struct _enb_ue_t {
lnode_t node; /* A node of list_t */
index_t index; /* An index of this node */
c_uint16_t ostream_id; /* SCTP Output Stream Identifier */
/* UE identity */
#define INVALID_UE_S1AP_ID 0xffffffff /* Initial value of enb_ue_s1ap_id */
c_uint32_t enb_ue_s1ap_id; /* eNB-UE-S1AP-ID received from eNB */

View File

@ -196,12 +196,12 @@ void mme_state_operational(fsm_t *s, event_t *e)
}
case MME_EVT_S1AP_DELAYED_SEND:
{
mme_enb_t *enb = NULL;
enb_ue_t *enb_ue = NULL;
pkbuf_t *pkbuf = NULL;
tm_block_id timer = 0;
enb = mme_enb_find(event_get_param1(e));
d_assert(enb, break,);
enb_ue = enb_ue_find(event_get_param1(e));
d_assert(enb_ue, break,);
pkbuf = (pkbuf_t *)event_get_param2(e);
d_assert(pkbuf, break,);
@ -209,7 +209,7 @@ void mme_state_operational(fsm_t *s, event_t *e)
timer = event_get_param3(e);
d_assert(timer, pkbuf_free(pkbuf); break,);
rv = s1ap_send_to_enb(enb, pkbuf);
rv = s1ap_send_to_enb_ue(enb_ue, pkbuf);
d_assert(rv == CORE_OK, pkbuf_free(pkbuf),);
tm_delete(timer);

View File

@ -11,16 +11,13 @@
status_t nas_send_to_enb(mme_ue_t *mme_ue, pkbuf_t *pkbuf)
{
mme_enb_t *enb = NULL;
enb_ue_t *enb_ue = NULL;
d_assert(mme_ue, return CORE_ERROR, "Null param");
enb_ue = mme_ue->enb_ue;
d_assert(enb_ue, return CORE_ERROR, "Null param");
enb = enb_ue->enb;
d_assert(enb, return CORE_ERROR, "Null param");
return s1ap_send_to_enb(enb, pkbuf);
return s1ap_send_to_enb_ue(enb_ue, pkbuf);
}
status_t nas_send_emm_to_esm(

View File

@ -159,7 +159,7 @@ void s1ap_handle_s1_setup_request(mme_enb_t *enb, s1ap_message_t *message)
return, "s1ap_build_setup_failure() failed");
}
d_assert(s1ap_send_to_enb(enb, s1apbuf) == CORE_OK,,
d_assert(s1ap_send_to_enb(enb, s1apbuf, S1AP_NON_UE_SIGNALLING) == CORE_OK,,
"s1ap_send_to_enb() failed");
}
@ -1083,8 +1083,9 @@ void s1ap_handle_paging(mme_ue_t *mme_ue)
}
/* Send to enb */
d_assert(s1ap_send_to_enb(enb, s1apbuf) == CORE_OK, return,
"s1ap send error");
d_assert(s1ap_send_to_enb(
enb, s1apbuf, S1AP_NON_UE_SIGNALLING) == CORE_OK,
return, "s1ap send error");
}
}
}
@ -1117,6 +1118,7 @@ void s1ap_handle_path_switch_request(
enb_ue_t *enb_ue = NULL;
mme_ue_t *mme_ue = NULL;
pkbuf_t *s1apbuf = NULL;
d_assert(enb, return,);
d_assert(enb->sock, return,);
@ -1187,10 +1189,14 @@ void s1ap_handle_path_switch_request(
d_error("Cannot find UE from sourceMME-UE-S1AP-ID[%d] and eNB[%s:%d]",
*MME_UE_S1AP_ID, CORE_ADDR(enb->addr, buf), enb->enb_id);
s1ap_send_path_switch_failure(enb,
rv = s1ap_build_path_switch_failure(&s1apbuf,
*ENB_UE_S1AP_ID, *MME_UE_S1AP_ID,
S1AP_Cause_PR_radioNetwork,
S1AP_CauseRadioNetwork_unknown_mme_ue_s1ap_id);
d_assert(rv == CORE_OK && s1apbuf, return, "s1ap build error");
rv = s1ap_send_to_enb(enb, s1apbuf, S1AP_NON_UE_SIGNALLING);
d_assert(rv == CORE_OK,, "s1ap send error");
return;
}
@ -1207,9 +1213,13 @@ void s1ap_handle_path_switch_request(
}
else
{
s1ap_send_path_switch_failure(enb,
rv = s1ap_build_path_switch_failure(&s1apbuf,
*ENB_UE_S1AP_ID, *MME_UE_S1AP_ID,
S1AP_Cause_PR_nas, S1AP_CauseNas_authentication_failure);
d_assert(rv == CORE_OK && s1apbuf, return, "s1ap build error");
rv = s1ap_send_to_enb_ue(enb_ue, s1apbuf);
d_assert(rv == CORE_OK,, "s1ap send error");
return;
}

View File

@ -68,7 +68,7 @@ static status_t s1ap_delete_list(list_t *list)
return CORE_OK;
}
status_t s1ap_send_to_enb(mme_enb_t *enb, pkbuf_t *pkbuf)
status_t s1ap_send_to_enb(mme_enb_t *enb, pkbuf_t *pkbuf, c_uint16_t stream_no)
{
char buf[CORE_ADDRSTRLEN];
status_t rv;
@ -81,7 +81,8 @@ status_t s1ap_send_to_enb(mme_enb_t *enb, pkbuf_t *pkbuf)
CORE_ADDR(enb->addr, buf), enb->enb_id);
rv = s1ap_send(enb->sock, pkbuf,
enb->sock_type == SOCK_STREAM ? NULL : enb->addr);
enb->sock_type == SOCK_STREAM ? NULL : enb->addr,
stream_no);
if (rv != CORE_OK)
{
d_error("s1_send error");
@ -91,12 +92,26 @@ status_t s1ap_send_to_enb(mme_enb_t *enb, pkbuf_t *pkbuf)
return CORE_OK;;
}
status_t s1ap_delayed_send_to_enb(
mme_enb_t *enb, pkbuf_t *pkbuf, c_uint32_t duration)
status_t s1ap_send_to_enb_ue(enb_ue_t *enb_ue, pkbuf_t *pkbuf)
{
mme_enb_t *enb = NULL;
mme_ue_t *mme_ue = NULL;
d_assert(enb_ue, return CORE_ERROR,);
enb = enb_ue->enb;
d_assert(enb, return CORE_ERROR,);
mme_ue = enb_ue->mme_ue;
d_assert(mme_ue, return CORE_ERROR,);
return s1ap_send_to_enb(enb, pkbuf, mme_ue->ostream_id);
}
status_t s1ap_delayed_send_to_enb_ue(
enb_ue_t *enb_ue, pkbuf_t *pkbuf, c_uint32_t duration)
{
tm_block_id timer = 0;
d_assert(enb, return CORE_ERROR,);
d_assert(enb_ue, return CORE_ERROR,);
d_assert(pkbuf, return CORE_ERROR,);
if (duration)
@ -105,7 +120,7 @@ status_t s1ap_delayed_send_to_enb(
&mme_self()->tm_service, MME_EVT_S1AP_DELAYED_SEND, duration);
d_assert(timer, return CORE_ERROR,);
timer_set_param1(timer, (c_uintptr_t)enb->index);
timer_set_param1(timer, (c_uintptr_t)enb_ue->index);
timer_set_param2(timer, (c_uintptr_t)pkbuf);
timer_set_param3(timer, timer);
@ -115,7 +130,10 @@ status_t s1ap_delayed_send_to_enb(
}
else
{
return s1ap_send_to_enb(enb, pkbuf);
mme_enb_t *enb = NULL;
enb = enb_ue->enb;
d_assert(enb, return CORE_ERROR,);
return s1ap_send_to_enb_ue(enb_ue, pkbuf);
}
}
@ -133,7 +151,7 @@ status_t s1ap_send_to_esm(mme_ue_t *mme_ue, pkbuf_t *esmbuf)
return CORE_OK;
}
status_t s1ap_send_to_nas(enb_ue_t *enb_ue,
S1AP_ProcedureCode_t procedureCode, S1AP_NAS_PDU_t *nasPdu)
{
@ -246,7 +264,6 @@ status_t s1ap_send_ue_context_release_command(
c_uint8_t action, c_uint32_t delay)
{
status_t rv;
mme_enb_t *enb = NULL;
pkbuf_t *s1apbuf = NULL;
d_assert(action != S1AP_UE_CTX_REL_INVALID_ACTION, return CORE_ERROR,
@ -254,8 +271,6 @@ status_t s1ap_send_ue_context_release_command(
d_assert(enb_ue, return CORE_ERROR, "Null param");
enb_ue->ue_ctx_rel_action = action;
enb = enb_ue->enb;
d_assert(enb, return CORE_ERROR, "Null param");
d_trace(3, "[MME] UE Context release command\n");
d_trace(5, " ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]\n",
@ -266,7 +281,7 @@ status_t s1ap_send_ue_context_release_command(
rv = s1ap_build_ue_context_release_command(&s1apbuf, enb_ue, group, cause);
d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error");
rv = s1ap_delayed_send_to_enb(enb, s1apbuf, delay);
rv = s1ap_delayed_send_to_enb_ue(enb_ue, s1apbuf, delay);
d_assert(rv == CORE_OK,, "s1ap send error");
return CORE_OK;
@ -286,7 +301,7 @@ status_t s1ap_send_mme_configuration_transfer(
&s1apbuf, SONConfigurationTransfer);
d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error");
rv = s1ap_send_to_enb(target_enb, s1apbuf);
rv = s1ap_send_to_enb(target_enb, s1apbuf, S1AP_NON_UE_SIGNALLING);
d_assert(rv == CORE_OK,, "s1ap send error");
return rv;
@ -308,40 +323,17 @@ status_t s1ap_send_path_switch_ack(mme_ue_t *mme_ue)
return CORE_OK;
}
status_t s1ap_send_path_switch_failure(mme_enb_t *enb,
c_uint32_t enb_ue_s1ap_id, c_uint32_t mme_ue_s1ap_id,
S1AP_Cause_PR group, long cause)
{
status_t rv;
pkbuf_t *s1apbuf = NULL;
d_assert(enb, return CORE_ERROR, "Null param");
rv = s1ap_build_path_switch_failure(&s1apbuf,
enb_ue_s1ap_id, mme_ue_s1ap_id, group, cause);
d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error");
rv = s1ap_send_to_enb(enb, s1apbuf);
d_assert(rv == CORE_OK,, "s1ap send error");
return rv;
}
status_t s1ap_send_handover_command(enb_ue_t *source_ue)
{
status_t rv;
pkbuf_t *s1apbuf = NULL;
mme_enb_t *enb = NULL;
d_assert(source_ue, return CORE_ERROR,);
enb = source_ue->enb;
d_assert(enb, return CORE_ERROR,);
rv = s1ap_build_handover_command(&s1apbuf, source_ue);
d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error");
rv = s1ap_send_to_enb(enb, s1apbuf);
rv = s1ap_send_to_enb_ue(source_ue, s1apbuf);
d_assert(rv == CORE_OK,, "s1ap send error");
return rv;
@ -353,17 +345,13 @@ status_t s1ap_send_handover_preparation_failure(
status_t rv;
pkbuf_t *s1apbuf = NULL;
mme_enb_t *enb = NULL;
d_assert(source_ue, return CORE_ERROR,);
d_assert(cause, return CORE_ERROR,);
enb = source_ue->enb;
d_assert(enb, return CORE_ERROR,);
rv = s1ap_build_handover_preparation_failure(&s1apbuf, source_ue, cause);
d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error");
rv = s1ap_send_to_enb(enb, s1apbuf);
rv = s1ap_send_to_enb_ue(source_ue, s1apbuf);
d_assert(rv == CORE_OK,, "s1ap send error");
return rv;
@ -374,16 +362,12 @@ status_t s1ap_send_handover_cancel_ack(enb_ue_t *source_ue)
status_t rv;
pkbuf_t *s1apbuf = NULL;
mme_enb_t *enb = NULL;
d_assert(source_ue, return CORE_ERROR,);
enb = source_ue->enb;
d_assert(enb, return CORE_ERROR,);
rv = s1ap_build_handover_cancel_ack(&s1apbuf, source_ue);
d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error");
rv = s1ap_send_to_enb(enb, s1apbuf);
rv = s1ap_send_to_enb_ue(source_ue, s1apbuf);
d_assert(rv == CORE_OK,, "s1ap send error");
return rv;
@ -432,7 +416,7 @@ status_t s1ap_send_handover_request(
source_totarget_transparentContainer);
d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error");
rv = s1ap_send_to_enb(target_enb, s1apbuf);
rv = s1ap_send_to_enb_ue(target_ue, s1apbuf);
d_assert(rv == CORE_OK,, "s1ap send error");
return rv;
@ -446,17 +430,13 @@ status_t s1ap_send_mme_status_transfer(
status_t rv;
pkbuf_t *s1apbuf = NULL;
mme_enb_t *enb = NULL;
d_assert(target_ue, return CORE_ERROR,);
enb = target_ue->enb;
d_assert(enb, return CORE_ERROR,);
rv = s1ap_build_mme_status_transfer(&s1apbuf, target_ue,
enb_statustransfer_transparentContainer);
d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error");
rv = s1ap_send_to_enb(enb, s1apbuf);
rv = s1ap_send_to_enb_ue(target_ue, s1apbuf);
d_assert(rv == CORE_OK,, "s1ap send error");
return rv;
@ -477,7 +457,7 @@ status_t s1ap_send_error_indication(
mme_ue_s1ap_id, enb_ue_s1ap_id, group, cause);
d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error");
rv = s1ap_send_to_enb(enb, s1apbuf);
rv = s1ap_send_to_enb(enb, s1apbuf, S1AP_NON_UE_SIGNALLING);
d_assert(rv == CORE_OK,, "s1ap send error");
return rv;
@ -495,7 +475,7 @@ status_t s1ap_send_s1_reset_ack(
rv = s1ap_build_s1_reset_ack(&s1apbuf, partOfS1_Interface);
d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error");
rv = s1ap_send_to_enb(enb, s1apbuf);
rv = s1ap_send_to_enb(enb, s1apbuf, S1AP_NON_UE_SIGNALLING);
d_assert(rv == CORE_OK,, "s1ap send error");
return rv;

View File

@ -10,6 +10,8 @@
extern "C" {
#endif /* __cplusplus */
#define S1AP_NON_UE_SIGNALLING 0
CORE_DECLARE(status_t) s1ap_init(int sctp_streams, c_uint16_t port);
CORE_DECLARE(status_t) s1ap_final();
@ -22,14 +24,15 @@ CORE_DECLARE(status_t) s1ap_delete(sock_id sock);
CORE_DECLARE(int) s1ap_recv_handler(sock_id sock, void *data);
CORE_DECLARE(status_t) s1ap_send(sock_id sock,
pkbuf_t *pkbuf, c_sockaddr_t *addr);
pkbuf_t *pkbuf, c_sockaddr_t *addr, c_uint16_t stream_no);
CORE_DECLARE(status_t) s1ap_recv(sock_id id, pkbuf_t *pkbuf);
CORE_DECLARE(status_t) s1ap_send_to_enb(mme_enb_t *enb, pkbuf_t *pkb);
CORE_DECLARE(status_t) s1ap_delayed_send_to_enb(mme_enb_t *enb,
CORE_DECLARE(status_t) s1ap_send_to_enb(
mme_enb_t *enb, pkbuf_t *pkb, c_uint16_t stream_no);
CORE_DECLARE(status_t) s1ap_send_to_enb_ue(enb_ue_t *enb_ue, pkbuf_t *pkbuf);
CORE_DECLARE(status_t) s1ap_delayed_send_to_enb_ue(enb_ue_t *enb_ue,
pkbuf_t *pkbuf, c_uint32_t duration);
CORE_DECLARE(status_t) s1ap_send_to_nas(
enb_ue_t *enb_ue,
CORE_DECLARE(status_t) s1ap_send_to_nas(enb_ue_t *enb_ue,
S1AP_ProcedureCode_t procedureCode, S1AP_NAS_PDU_t *nasPdu);
CORE_DECLARE(status_t) s1ap_send_to_esm(mme_ue_t *mme_ue, pkbuf_t *esmbuf);
@ -44,9 +47,6 @@ CORE_DECLARE(status_t) s1ap_send_mme_configuration_transfer(
S1AP_SONConfigurationTransfer_t *SONConfigurationTransfer);
CORE_DECLARE(status_t) s1ap_send_path_switch_ack(mme_ue_t *mme_ue);
CORE_DECLARE(status_t) s1ap_send_path_switch_failure(mme_enb_t *enb,
c_uint32_t enb_ue_s1ap_id, c_uint32_t mme_ue_s1ap_id,
S1AP_Cause_PR group, long cause);
CORE_DECLARE(status_t) s1ap_send_handover_command(enb_ue_t *source_ue);
CORE_DECLARE(status_t) s1ap_send_handover_preparation_failure(

View File

@ -45,7 +45,8 @@ status_t s1ap_delete(sock_id sock)
return sock_delete(sock);
}
status_t s1ap_send(sock_id sock, pkbuf_t *pkbuf, c_sockaddr_t *addr)
status_t s1ap_send(sock_id sock, pkbuf_t *pkbuf,
c_sockaddr_t *addr, c_uint16_t stream_no)
{
int sent;

View File

@ -161,7 +161,8 @@ status_t sctp_client(sock_id *new, int type, c_sockaddr_t *sa_list)
return CORE_OK;
}
status_t s1ap_send(sock_id id, pkbuf_t *pkbuf, c_sockaddr_t *addr)
status_t s1ap_send(sock_id id, pkbuf_t *pkbuf,
c_sockaddr_t *addr, c_uint16_t stream_no)
{
ssize_t sent;
struct socket *sock = (struct socket *)id;
@ -172,6 +173,7 @@ status_t s1ap_send(sock_id id, pkbuf_t *pkbuf, c_sockaddr_t *addr)
memset((void *)&sndinfo, 0, sizeof(struct sctp_sndinfo));
sndinfo.snd_ppid = htonl(SCTP_S1AP_PPID);
sndinfo.snd_sid = stream_no;
sent = usrsctp_sendv(sock, pkbuf->payload, pkbuf->len,
addr ? &addr->sa : NULL, addr ? 1 : 0,
(void *)&sndinfo, (socklen_t)sizeof(struct sctp_sndinfo),

View File

@ -114,7 +114,7 @@ status_t tests1ap_enb_read(sock_id id, pkbuf_t *recvbuf)
status_t tests1ap_enb_send(sock_id id, pkbuf_t *sendbuf)
{
return s1ap_send(id, sendbuf, NULL);
return s1ap_send(id, sendbuf, NULL, 0);
}
status_t tests1ap_build_setup_req(