Negociate SCTP stream ID with eNodeB (#63)

This commit is contained in:
Sukchan Lee 2018-05-18 17:14:29 +09:00
parent 76d8df3879
commit 9a0afe035a
7 changed files with 65 additions and 36 deletions

View File

@ -106,6 +106,13 @@ typedef struct ipsubnet_t {
c_uint32_t mask[4];
} ipsubnet_t;
typedef struct _sctp_info_t {
c_uint32_t ppid;
c_uint16_t stream_no;
c_uint16_t inbound_streams;
c_uint16_t outbound_streams;
} sctp_info_t;
/*
* Init/Final
*/
@ -207,7 +214,7 @@ CORE_DECLARE(int) core_sctp_sendmsg(sock_id id, const void *msg, size_t len,
#define CORE_SCTP_EAGAIN -2
#define CORE_SCTP_REMOTE_CLOSED -3
CORE_DECLARE(int) core_sctp_recvmsg(sock_id id, void *msg, size_t len,
c_sockaddr_t *from, c_uint32_t *ppid, c_uint16_t *stream_no);
c_sockaddr_t *from, sctp_info_t *sinfo);
/*
* TUN Driver
*/

View File

@ -202,14 +202,14 @@ int core_sctp_sendmsg(sock_id id, const void *msg, size_t len,
}
int core_sctp_recvmsg(sock_id id, void *msg, size_t len,
c_sockaddr_t *from, c_uint32_t *ppid, c_uint16_t *stream_no)
c_sockaddr_t *from, sctp_info_t *sinfo)
{
sock_t *sock = (sock_t *)id;
int size;
socklen_t addrlen = sizeof(struct sockaddr_storage);
int flags = 0;
struct sctp_sndrcvinfo sinfo;
struct sctp_sndrcvinfo sndrcvinfo;
d_assert(id, return -1,);
@ -217,7 +217,7 @@ int core_sctp_recvmsg(sock_id id, void *msg, size_t len,
{
size = sctp_recvmsg(sock->fd, msg, len,
from ? &from->sa : NULL, from ? &addrlen : NULL,
&sinfo, &flags);
&sndrcvinfo, &flags);
if (size < 0)
{
if (errno != EAGAIN)
@ -251,7 +251,18 @@ int core_sctp_recvmsg(sock_id id, void *msg, size_t len,
}
if (not->sn_assoc_change.sac_state == SCTP_COMM_UP)
d_trace(3, "SCTP_COMM_UP\n");
{
d_trace(3, "SCTP_COMM_UP : inboud:%d, outbound = %d\n",
not->sn_assoc_change.sac_inbound_streams,
not->sn_assoc_change.sac_outbound_streams);
}
if (sinfo)
{
sinfo->inbound_streams =
not->sn_assoc_change.sac_inbound_streams;
sinfo->outbound_streams =
not->sn_assoc_change.sac_outbound_streams;
}
break;
case SCTP_SEND_FAILED :
d_error("SCTP_SEND_FAILED"
@ -281,14 +292,10 @@ int core_sctp_recvmsg(sock_id id, void *msg, size_t len,
} while(1);
if (ppid)
if (sinfo)
{
*ppid = ntohl(sinfo.sinfo_ppid);
}
if (stream_no)
{
*stream_no = sinfo.sinfo_stream;
sinfo->ppid = ntohl(sndrcvinfo.sinfo_ppid);
sinfo->stream_no = sndrcvinfo.sinfo_stream;
}
return size;

View File

@ -56,6 +56,7 @@ static void *THREAD_FUNC test2_main(thread_id id, void *data)
char str[STRLEN];
ssize_t size;
c_uint32_t ppid;
sctp_info_t sinfo;
c_sockaddr_t *addr;
c_sockaddr_t from;
@ -66,9 +67,9 @@ static void *THREAD_FUNC test2_main(thread_id id, void *data)
rv = core_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
size = core_sctp_recvmsg(sctp, str, STRLEN, &from, &ppid, NULL);
size = core_sctp_recvmsg(sctp, str, STRLEN, &from, &sinfo);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ABTS_INT_EQUAL(tc, PPID, ppid);
ABTS_INT_EQUAL(tc, PPID, sinfo.ppid);
rv = sock_delete(sctp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
@ -149,7 +150,7 @@ static void sctp_test3(abts_case *tc, void *data)
c_sockaddr_t from, *addr;
char str[STRLEN];
char buf[CORE_ADDRSTRLEN];
c_uint32_t ppid;
sctp_info_t sinfo;
rv = core_getaddrinfo(&addr, AF_INET, NULL, PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
@ -161,9 +162,9 @@ static void sctp_test3(abts_case *tc, void *data)
rv = thread_create(&test3_thread, NULL, test3_main, tc);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
size = core_sctp_recvmsg(sctp, str, STRLEN, &from, &ppid, NULL);
size = core_sctp_recvmsg(sctp, str, STRLEN, &from, &sinfo);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ABTS_INT_EQUAL(tc, PPID, ppid);
ABTS_INT_EQUAL(tc, PPID, sinfo.ppid);
thread_join(&rv, test3_thread);
ABTS_INT_EQUAL(tc, strlen(DATASTR), rv);
@ -181,7 +182,7 @@ static void *THREAD_FUNC test4_main(thread_id id, void *data)
c_sockaddr_t *addr;
char str[STRLEN];
ssize_t size;
c_uint32_t ppid;
sctp_info_t sinfo;
rv = core_getaddrinfo(&addr, AF_UNSPEC, NULL, PORT, 0);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
@ -193,9 +194,9 @@ static void *THREAD_FUNC test4_main(thread_id id, void *data)
size = core_sctp_sendmsg(sctp, DATASTR, strlen(DATASTR), NULL, PPID, 0);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
size = core_sctp_recvmsg(sctp, str, STRLEN, NULL, &ppid, NULL);
size = core_sctp_recvmsg(sctp, str, STRLEN, NULL, &sinfo);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ABTS_INT_EQUAL(tc, PPID, ppid);
ABTS_INT_EQUAL(tc, PPID, sinfo.ppid);
rv = sock_delete(sctp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
@ -211,7 +212,7 @@ static void sctp_test4(abts_case *tc, void *data)
ssize_t size;
c_sockaddr_t from, *addr;
char str[STRLEN];
c_uint32_t ppid;
sctp_info_t sinfo;
char buf[CORE_ADDRSTRLEN];
rv = core_getaddrinfo(&addr, AF_INET6, NULL, PORT, AI_PASSIVE);
@ -224,10 +225,10 @@ static void sctp_test4(abts_case *tc, void *data)
rv = thread_create(&test4_thread, NULL, test4_main, tc);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
size = core_sctp_recvmsg(sctp, str, STRLEN, &from, &ppid, NULL);
size = core_sctp_recvmsg(sctp, str, STRLEN, &from, &sinfo);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ABTS_STR_EQUAL(tc, "::1", CORE_ADDR(&from, buf));
ABTS_INT_EQUAL(tc, PPID, ppid);
ABTS_INT_EQUAL(tc, PPID, sinfo.ppid);
size = core_sctp_sendmsg(sctp, DATASTR, strlen(DATASTR), &from, PPID, 0);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
@ -247,7 +248,7 @@ static void *THREAD_FUNC test5_main(thread_id id, void *data)
sock_id sctp;
char str[STRLEN];
c_sockaddr_t from, *remote_addr, *addr;
c_uint32_t ppid;
sctp_info_t sinfo;
ssize_t size;
char buf[CORE_ADDRSTRLEN];
@ -271,10 +272,10 @@ static void *THREAD_FUNC test5_main(thread_id id, void *data)
remote_addr, PPID, 0);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
size = core_sctp_recvmsg(sctp, str, STRLEN, &from, &ppid, NULL);
size = core_sctp_recvmsg(sctp, str, STRLEN, &from, &sinfo);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ABTS_STR_EQUAL(tc, "::1", CORE_ADDR(&from, buf));
ABTS_INT_EQUAL(tc, PPID, ppid);
ABTS_INT_EQUAL(tc, PPID, sinfo.ppid);
rv = sock_delete(sctp);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
@ -291,7 +292,7 @@ static void sctp_test5(abts_case *tc, void *data)
c_sockaddr_t from, *addr;
socklen_t addrlen;
char str[STRLEN];
c_uint32_t ppid;
sctp_info_t sinfo;
char buf[CORE_ADDRSTRLEN];
rv = core_getaddrinfo(&addr, AF_INET6, NULL, PORT, AI_PASSIVE);
@ -304,12 +305,13 @@ static void sctp_test5(abts_case *tc, void *data)
rv = thread_create(&test5_thread, NULL, test5_main, tc);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
size = core_sctp_recvmsg(sctp, str, STRLEN, &from, &ppid, NULL);
size = core_sctp_recvmsg(sctp, str, STRLEN, &from, &sinfo);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ABTS_STR_EQUAL(tc, "::1", CORE_ADDR(&from, buf));
ABTS_INT_EQUAL(tc, PPID, ppid);
ABTS_INT_EQUAL(tc, PPID, sinfo.ppid);
size = core_sctp_sendmsg(sctp, DATASTR, strlen(DATASTR), &from, ppid, 0);
size = core_sctp_sendmsg(sctp, DATASTR, strlen(DATASTR), &from,
sinfo.ppid, 0);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
thread_join(&rv, test5_thread);

View File

@ -1610,6 +1610,8 @@ mme_enb_t* mme_enb_add(sock_id sock, c_sockaddr_t *addr)
enb->addr = addr;
enb->sock_type = mme_enb_sock_type(enb->sock);
enb->inbound_streams = context_self()->parameter.sctp_streams;
list_init(&enb->enb_ue_list);
hash_set(self.enb_sock_hash, &enb->sock, sizeof(enb->sock), enb);
@ -1926,10 +1928,13 @@ static status_t mme_ue_new_guti(mme_ue_t *mme_ue)
mme_ue_t* mme_ue_add(enb_ue_t *enb_ue)
{
mme_enb_t *enb = NULL;
mme_ue_t *mme_ue = NULL;
event_t e;
d_assert(enb_ue, return NULL, "Null param");
d_assert(enb_ue, return NULL,);
enb = enb_ue->enb;
d_assert(enb, return NULL,);
index_alloc(&mme_ue_pool, &mme_ue);
d_assert(mme_ue, return NULL, "Null param");
@ -1944,8 +1949,7 @@ mme_ue_t* mme_ue_add(enb_ue_t *enb_ue)
* 0 : Non UE signalling
* 1-29 : UE specific association
*/
mme_ue->ostream_id = NEXT_ID(self.ostream_id,
1, context_self()->parameter.sctp_streams-1);
mme_ue->ostream_id = NEXT_ID(self.ostream_id, 1, enb->inbound_streams-1);
/* Create New GUTI */
mme_ue_new_guti(mme_ue);

View File

@ -149,6 +149,8 @@ typedef struct _mme_enb_t {
sock_id sock; /* eNB S1AP Socket */
c_sockaddr_t *addr; /* eNB S1AP Address */
c_uint16_t inbound_streams; /* SCTP Max number of inbound streams */
c_uint8_t num_of_supported_ta_list;
tai_t supported_ta_list[MAX_NUM_OF_TAI * MAX_NUM_OF_BPLMN];

View File

@ -1,5 +1,6 @@
#define TRACE_MODULE _mme_sm
#include "core_debug.h"
#include "core_lib.h"
#include "s1ap/s1ap_message.h"
#include "nas/nas_message.h"
@ -160,6 +161,7 @@ void mme_state_operational(fsm_t *s, event_t *e)
sock_id sock = 0;
c_sockaddr_t *addr = NULL;
pkbuf_t *pkbuf = NULL;
c_uint16_t inbound_streams = 0;
sock = (sock_id)event_get_param1(e);
d_assert(sock, break, "Null param");
@ -170,6 +172,7 @@ void mme_state_operational(fsm_t *s, event_t *e)
pkbuf = (pkbuf_t *)event_get_param3(e);
d_assert(pkbuf, break, "Null param");
inbound_streams = (c_uint16_t)event_get_param4(e);
enb = mme_enb_find_by_addr(addr);
CORE_FREE(addr);
@ -177,6 +180,9 @@ void mme_state_operational(fsm_t *s, event_t *e)
d_assert(FSM_STATE(&enb->sm), pkbuf_free(pkbuf); break,
"No S1AP State Machine");
if (inbound_streams)
inbound_streams = c_min(inbound_streams, enb->inbound_streams);
rv = s1ap_decode_pdu(&message, pkbuf);
if (rv != CORE_OK)
{

View File

@ -71,7 +71,7 @@ status_t s1ap_recv(sock_id id, pkbuf_t *pkbuf)
{
int size;
size = core_sctp_recvmsg(id, pkbuf->payload, MAX_SDU_LEN, NULL, NULL, NULL);
size = core_sctp_recvmsg(id, pkbuf->payload, MAX_SDU_LEN, NULL, NULL);
if (size <= 0)
{
d_error("s1ap_recv() failed");
@ -128,6 +128,7 @@ int s1ap_recv_handler(sock_id sock, void *data)
int size;
event_t e;
c_sockaddr_t *addr = NULL;
sctp_info_t sinfo;
d_assert(sock, return -1, "Null param");
@ -144,8 +145,7 @@ int s1ap_recv_handler(sock_id sock, void *data)
return -1;
}
size = core_sctp_recvmsg(sock, pkbuf->payload, pkbuf->len,
NULL, NULL, NULL);
size = core_sctp_recvmsg(sock, pkbuf->payload, pkbuf->len, NULL, &sinfo);
if (size <= 0)
{
pkbuf_free(pkbuf);
@ -199,6 +199,7 @@ int s1ap_recv_handler(sock_id sock, void *data)
event_set_param1(&e, (c_uintptr_t)sock);
event_set_param2(&e, (c_uintptr_t)addr);
event_set_param3(&e, (c_uintptr_t)pkbuf);
event_set_param4(&e, (c_uintptr_t)sinfo.inbound_streams);
rv = mme_event_send(&e);
if (rv != CORE_OK)
{