Negociate SCTP stream ID with eNodeB (#63)
This commit is contained in:
parent
76d8df3879
commit
9a0afe035a
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue