Configure Outbound streams on SCTP_COMM_UP
This commit is contained in:
parent
9aed43075c
commit
3b9b1108b1
|
@ -213,10 +213,6 @@ CORE_DECLARE(int) core_sctp_recvmsg(sock_id id, void *msg, size_t len,
|
|||
c_sockaddr_t *from, sctp_info_t *sinfo, int *msg_flags);
|
||||
CORE_DECLARE(int) core_sctp_recvdata(sock_id id, void *msg, size_t len,
|
||||
c_sockaddr_t *from, sctp_info_t *sinfo);
|
||||
#define CORE_SCTP_EAGAIN -2
|
||||
#define CORE_SCTP_REMOTE_CLOSED -3
|
||||
CORE_DECLARE(int) core_sctp_recvmsg2(sock_id id, void *msg, size_t len,
|
||||
c_sockaddr_t *from, sctp_info_t *sinfo);
|
||||
/*
|
||||
* TUN Driver
|
||||
*/
|
||||
|
|
|
@ -271,106 +271,6 @@ int core_sctp_recvdata(sock_id id, void *msg, size_t len,
|
|||
return size;
|
||||
}
|
||||
|
||||
int core_sctp_recvmsg2(sock_id id, void *msg, size_t len,
|
||||
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 sndrcvinfo;
|
||||
|
||||
d_assert(id, return -1,);
|
||||
|
||||
do
|
||||
{
|
||||
size = sctp_recvmsg(sock->fd, msg, len,
|
||||
from ? &from->sa : NULL, from ? &addrlen : NULL,
|
||||
&sndrcvinfo, &flags);
|
||||
if (size < 0)
|
||||
{
|
||||
if (errno != EAGAIN)
|
||||
{
|
||||
d_error("sctp_recvmsg(%d) failed(%d:%s)",
|
||||
size, errno, strerror(errno));
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
if (flags & MSG_NOTIFICATION)
|
||||
{
|
||||
union sctp_notification *not = (union sctp_notification *)msg;
|
||||
|
||||
switch(not->sn_header.sn_type)
|
||||
{
|
||||
case SCTP_ASSOC_CHANGE :
|
||||
d_trace(3, "SCTP_ASSOC_CHANGE"
|
||||
"(type:0x%x, flags:0x%x, state:0x%x)\n",
|
||||
not->sn_assoc_change.sac_type,
|
||||
not->sn_assoc_change.sac_flags,
|
||||
not->sn_assoc_change.sac_state);
|
||||
|
||||
if (not->sn_assoc_change.sac_state ==
|
||||
SCTP_SHUTDOWN_COMP ||
|
||||
not->sn_assoc_change.sac_state ==
|
||||
SCTP_COMM_LOST)
|
||||
{
|
||||
return CORE_SCTP_REMOTE_CLOSED;
|
||||
}
|
||||
|
||||
if (not->sn_assoc_change.sac_state == SCTP_COMM_UP)
|
||||
{
|
||||
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"
|
||||
"(type:0x%x, flags:0x%x, error:0x%x)\n",
|
||||
not->sn_send_failed.ssf_type,
|
||||
not->sn_send_failed.ssf_flags,
|
||||
not->sn_send_failed.ssf_error);
|
||||
break;
|
||||
case SCTP_SHUTDOWN_EVENT :
|
||||
d_trace(3, "SCTP_SHUTDOWN_EVENT\n");
|
||||
return CORE_SCTP_REMOTE_CLOSED;
|
||||
default :
|
||||
d_error("Discarding event with unknown "
|
||||
"flags = 0x%x, type 0x%x",
|
||||
flags, not->sn_header.sn_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (flags & MSG_EOR)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CORE_SCTP_EAGAIN;
|
||||
}
|
||||
|
||||
} while(1);
|
||||
|
||||
if (sinfo)
|
||||
{
|
||||
sinfo->ppid = ntohl(sndrcvinfo.sinfo_ppid);
|
||||
sinfo->stream_no = sndrcvinfo.sinfo_stream;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static status_t subscribe_to_events(sock_id id)
|
||||
{
|
||||
sock_t *sock = (sock_t *)id;
|
||||
|
|
|
@ -95,9 +95,6 @@ void mme_state_operational(fsm_t *s, event_t *e)
|
|||
enb = mme_enb_find_by_addr(addr);
|
||||
if (!enb)
|
||||
{
|
||||
mme_enb_t *enb = NULL;
|
||||
c_uint16_t outbound_streams = 0;
|
||||
|
||||
#if USE_USRSCTP != 1
|
||||
status_t rv;
|
||||
|
||||
|
@ -107,11 +104,6 @@ void mme_state_operational(fsm_t *s, event_t *e)
|
|||
|
||||
enb = mme_enb_add(sock, addr);
|
||||
d_assert(enb, break, "Null param");
|
||||
|
||||
outbound_streams = (c_uint16_t)event_get_param3(e);
|
||||
if (outbound_streams)
|
||||
enb->outbound_streams =
|
||||
c_min(outbound_streams, enb->outbound_streams);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -123,6 +115,39 @@ void mme_state_operational(fsm_t *s, event_t *e)
|
|||
|
||||
break;
|
||||
}
|
||||
case MME_EVT_S1AP_LO_SCTP_COMM_UP:
|
||||
{
|
||||
mme_enb_t *enb = NULL;
|
||||
sock_id sock = 0;
|
||||
c_sockaddr_t *addr = NULL;
|
||||
c_uint16_t outbound_streams = 0;
|
||||
|
||||
sock = (sock_id)event_get_param1(e);
|
||||
d_assert(sock, break, "Null param");
|
||||
addr = (c_sockaddr_t *)event_get_param2(e);
|
||||
d_assert(addr, break, "Null param");
|
||||
|
||||
outbound_streams = (c_uint16_t)event_get_param4(e);
|
||||
|
||||
d_trace(3, "eNB-S1 SCTP_COMM_UP[%s] Outbound Streams[%d]\n",
|
||||
CORE_ADDR(addr, buf), outbound_streams);
|
||||
|
||||
enb = mme_enb_find_by_addr(addr);
|
||||
if (!enb)
|
||||
{
|
||||
enb = mme_enb_add(sock, addr);
|
||||
d_assert(enb, break, "Null param");
|
||||
}
|
||||
else
|
||||
{
|
||||
CORE_FREE(addr);
|
||||
}
|
||||
|
||||
enb->outbound_streams =
|
||||
c_min(outbound_streams, enb->outbound_streams);
|
||||
|
||||
break;
|
||||
}
|
||||
case MME_EVT_S1AP_LO_CONNREFUSED:
|
||||
{
|
||||
mme_enb_t *enb = NULL;
|
||||
|
@ -139,8 +164,7 @@ void mme_state_operational(fsm_t *s, event_t *e)
|
|||
|
||||
if (enb)
|
||||
{
|
||||
d_trace(1, "eNB-S1[%x] connection refused!!!\n",
|
||||
enb->enb_id);
|
||||
d_trace(1, "eNB-S1[%x] connection refused!!!\n", enb->enb_id);
|
||||
mme_enb_remove(enb);
|
||||
}
|
||||
else
|
||||
|
@ -157,7 +181,6 @@ 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 outbound_streams = 0;
|
||||
|
||||
sock = (sock_id)event_get_param1(e);
|
||||
d_assert(sock, break, "Null param");
|
||||
|
@ -168,7 +191,6 @@ void mme_state_operational(fsm_t *s, event_t *e)
|
|||
pkbuf = (pkbuf_t *)event_get_param3(e);
|
||||
d_assert(pkbuf, break, "Null param");
|
||||
|
||||
outbound_streams = (c_uint16_t)event_get_param4(e);
|
||||
enb = mme_enb_find_by_addr(addr);
|
||||
CORE_FREE(addr);
|
||||
|
||||
|
@ -176,10 +198,6 @@ 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 (outbound_streams)
|
||||
enb->outbound_streams =
|
||||
c_min(outbound_streams, enb->outbound_streams);
|
||||
|
||||
rv = s1ap_decode_pdu(&message, pkbuf);
|
||||
if (rv != CORE_OK)
|
||||
{
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
#include "core_debug.h"
|
||||
#include "core_thread.h"
|
||||
|
||||
#if HAVE_NETINET_SCTP_H
|
||||
#include <netinet/sctp.h>
|
||||
#endif
|
||||
|
||||
#include "mme_event.h"
|
||||
|
||||
#include "s1ap_path.h"
|
||||
|
@ -124,12 +128,12 @@ static int s1ap_accept_handler(sock_id id, void *data)
|
|||
|
||||
int s1ap_recv_handler(sock_id sock, void *data)
|
||||
{
|
||||
status_t rv;
|
||||
pkbuf_t *pkbuf;
|
||||
int size;
|
||||
event_t e;
|
||||
c_sockaddr_t *addr = NULL;
|
||||
sctp_info_t sinfo;
|
||||
int flags = 0;
|
||||
|
||||
d_assert(sock, return -1, "Null param");
|
||||
|
||||
|
@ -146,63 +150,141 @@ int s1ap_recv_handler(sock_id sock, void *data)
|
|||
return -1;
|
||||
}
|
||||
|
||||
size = core_sctp_recvmsg2(sock, pkbuf->payload, pkbuf->len, NULL, &sinfo);
|
||||
if (size <= 0)
|
||||
size = core_sctp_recvmsg(
|
||||
sock, pkbuf->payload, pkbuf->len, NULL, &sinfo, &flags);
|
||||
if (size < 0)
|
||||
{
|
||||
pkbuf_free(pkbuf);
|
||||
d_error("core_sctp_recvmsg(%d) failed(%d:%s)",
|
||||
size, errno, strerror(errno));
|
||||
return size;
|
||||
}
|
||||
|
||||
if (size == CORE_SCTP_EAGAIN)
|
||||
if (flags & MSG_NOTIFICATION)
|
||||
{
|
||||
union sctp_notification *not =
|
||||
(union sctp_notification *)pkbuf->payload;
|
||||
|
||||
switch(not->sn_header.sn_type)
|
||||
{
|
||||
return 0;
|
||||
case SCTP_ASSOC_CHANGE :
|
||||
d_trace(3, "SCTP_ASSOC_CHANGE"
|
||||
"(type:0x%x, flags:0x%x, state:0x%x)\n",
|
||||
not->sn_assoc_change.sac_type,
|
||||
not->sn_assoc_change.sac_flags,
|
||||
not->sn_assoc_change.sac_state);
|
||||
|
||||
if (not->sn_assoc_change.sac_state == SCTP_COMM_UP)
|
||||
{
|
||||
d_trace(3, "SCTP_COMM_UP : inbound:%d, outbound = %d\n",
|
||||
not->sn_assoc_change.sac_inbound_streams,
|
||||
not->sn_assoc_change.sac_outbound_streams);
|
||||
|
||||
addr = core_calloc(1, sizeof(c_sockaddr_t));
|
||||
d_assert(addr, pkbuf_free(pkbuf); return 0,);
|
||||
memcpy(addr, sock_remote_addr(sock), sizeof(c_sockaddr_t));
|
||||
|
||||
event_set(&e, MME_EVT_S1AP_LO_SCTP_COMM_UP);
|
||||
event_set_param1(&e, (c_uintptr_t)sock);
|
||||
event_set_param2(&e, (c_uintptr_t)addr);
|
||||
event_set_param3(&e,
|
||||
(c_uintptr_t)not->sn_assoc_change.sac_inbound_streams);
|
||||
event_set_param4(&e,
|
||||
(c_uintptr_t)not->sn_assoc_change.sac_outbound_streams);
|
||||
|
||||
if (mme_event_send(&e) != CORE_OK)
|
||||
{
|
||||
d_error("Event MME_EVT_S1AP_LO_CONNREFUSED failed");
|
||||
CORE_FREE(addr);
|
||||
}
|
||||
|
||||
pkbuf_free(pkbuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (not->sn_assoc_change.sac_state == SCTP_SHUTDOWN_COMP)
|
||||
d_trace(3, "SCTP_SHUTDOWN_COMP\n");
|
||||
if (not->sn_assoc_change.sac_state == SCTP_COMM_LOST)
|
||||
d_trace(3, "SCTP_COMM_LOST\n");
|
||||
|
||||
if (not->sn_assoc_change.sac_state == SCTP_SHUTDOWN_COMP ||
|
||||
not->sn_assoc_change.sac_state == SCTP_COMM_LOST)
|
||||
{
|
||||
addr = core_calloc(1, sizeof(c_sockaddr_t));
|
||||
d_assert(addr, pkbuf_free(pkbuf); return 0,);
|
||||
memcpy(addr, sock_remote_addr(sock), sizeof(c_sockaddr_t));
|
||||
|
||||
event_set(&e, MME_EVT_S1AP_LO_CONNREFUSED);
|
||||
event_set_param1(&e, (c_uintptr_t)sock);
|
||||
event_set_param2(&e, (c_uintptr_t)addr);
|
||||
|
||||
if (mme_event_send(&e) != CORE_OK)
|
||||
{
|
||||
d_error("Event MME_EVT_S1AP_LO_CONNREFUSED failed");
|
||||
CORE_FREE(addr);
|
||||
}
|
||||
|
||||
sock_delete(sock);
|
||||
pkbuf_free(pkbuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
case SCTP_SEND_FAILED :
|
||||
d_error("SCTP_SEND_FAILED"
|
||||
"(type:0x%x, flags:0x%x, error:0x%x)\n",
|
||||
not->sn_send_failed.ssf_type,
|
||||
not->sn_send_failed.ssf_flags,
|
||||
not->sn_send_failed.ssf_error);
|
||||
break;
|
||||
case SCTP_SHUTDOWN_EVENT :
|
||||
d_trace(3, "SCTP_SHUTDOWN_EVENT\n");
|
||||
|
||||
addr = core_calloc(1, sizeof(c_sockaddr_t));
|
||||
d_assert(addr, pkbuf_free(pkbuf); return 0,);
|
||||
memcpy(addr, sock_remote_addr(sock), sizeof(c_sockaddr_t));
|
||||
|
||||
event_set(&e, MME_EVT_S1AP_LO_CONNREFUSED);
|
||||
event_set_param1(&e, (c_uintptr_t)sock);
|
||||
event_set_param2(&e, (c_uintptr_t)addr);
|
||||
|
||||
if (mme_event_send(&e) != CORE_OK)
|
||||
{
|
||||
d_error("Event MME_EVT_S1AP_LO_CONNREFUSED failed");
|
||||
CORE_FREE(addr);
|
||||
}
|
||||
|
||||
sock_delete(sock);
|
||||
pkbuf_free(pkbuf);
|
||||
return 0;
|
||||
default :
|
||||
d_error("Discarding event with unknown flags:0x%x type:0x%x",
|
||||
flags, not->sn_header.sn_type);
|
||||
break;
|
||||
}
|
||||
if (size == CORE_SCTP_REMOTE_CLOSED)
|
||||
}
|
||||
else if (flags & MSG_EOR)
|
||||
{
|
||||
addr = core_calloc(1, sizeof(c_sockaddr_t));
|
||||
d_assert(addr, pkbuf_free(pkbuf); return 0,);
|
||||
memcpy(addr, sock_remote_addr(sock), sizeof(c_sockaddr_t));
|
||||
|
||||
event_set(&e, MME_EVT_S1AP_MESSAGE);
|
||||
event_set_param1(&e, (c_uintptr_t)sock);
|
||||
event_set_param2(&e, (c_uintptr_t)addr);
|
||||
event_set_param3(&e, (c_uintptr_t)pkbuf);
|
||||
if (mme_event_send(&e) != CORE_OK)
|
||||
{
|
||||
addr = core_calloc(1, sizeof(c_sockaddr_t));
|
||||
d_assert(addr, return -1,);
|
||||
memcpy(addr, sock_remote_addr(sock), sizeof(c_sockaddr_t));
|
||||
|
||||
event_set(&e, MME_EVT_S1AP_LO_CONNREFUSED);
|
||||
event_set_param1(&e, (c_uintptr_t)sock);
|
||||
event_set_param2(&e, (c_uintptr_t)addr);
|
||||
sock_delete(sock);
|
||||
if (mme_event_send(&e) != CORE_OK)
|
||||
{
|
||||
d_error("Event MME_EVT_S1AP_LO_CONNREFUSED failed");
|
||||
CORE_FREE(addr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (errno != EAGAIN)
|
||||
{
|
||||
d_error("core_sctp_recvmsg(%d) failed(%d:%s)",
|
||||
size, errno, strerror(errno));
|
||||
pkbuf_free(pkbuf);
|
||||
CORE_FREE(addr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
pkbuf->len = size;
|
||||
|
||||
d_trace(50, "[S1AP] RECV : ");
|
||||
d_trace_hex(50, pkbuf->payload, pkbuf->len);
|
||||
|
||||
addr = core_calloc(1, sizeof(c_sockaddr_t));
|
||||
d_assert(addr, return -1,);
|
||||
memcpy(addr, sock_remote_addr(sock), sizeof(c_sockaddr_t));
|
||||
|
||||
event_set(&e, MME_EVT_S1AP_MESSAGE);
|
||||
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.outbound_streams);
|
||||
rv = mme_event_send(&e);
|
||||
if (rv != CORE_OK)
|
||||
else
|
||||
{
|
||||
pkbuf_free(pkbuf);
|
||||
CORE_FREE(addr);
|
||||
d_assert(0, pkbuf_free(pkbuf); return 0, "Unknown flags : 0x%x", flags);
|
||||
}
|
||||
|
||||
|
||||
pkbuf_free(pkbuf);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -440,6 +440,8 @@ static int s1ap_usrsctp_recv_handler(struct socket *sock,
|
|||
event_set_param1(&e, (c_uintptr_t)sock);
|
||||
event_set_param2(&e, (c_uintptr_t)addr);
|
||||
event_set_param3(&e, (c_uintptr_t)
|
||||
not->sn_assoc_change.sac_inbound_streams);
|
||||
event_set_param4(&e, (c_uintptr_t)
|
||||
not->sn_assoc_change.sac_outbound_streams);
|
||||
if (mme_event_send(&e) != CORE_OK)
|
||||
{
|
||||
|
@ -510,7 +512,6 @@ static int s1ap_usrsctp_recv_handler(struct socket *sock,
|
|||
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)0);
|
||||
if (mme_event_send(&e) != CORE_OK)
|
||||
{
|
||||
pkbuf_free(pkbuf);
|
||||
|
|
Loading…
Reference in New Issue