open5gs/src/mme/s1ap_path.c

201 lines
4.9 KiB
C
Raw Normal View History

2017-02-13 05:17:26 +00:00
#define TRACE_MODULE _s1ap_path
2017-02-13 04:19:53 +00:00
#include "core.h"
#include "core_debug.h"
#include "core_net.h"
2017-02-15 11:16:50 +00:00
#include "s1ap_message.h"
2017-02-13 07:03:12 +00:00
2017-02-13 04:19:53 +00:00
#include "event.h"
2017-03-06 08:55:50 +00:00
#include "context.h"
2017-02-13 05:17:26 +00:00
#include "s1ap_path.h"
2017-02-13 04:19:53 +00:00
2017-02-13 05:17:26 +00:00
static int _s1ap_accept_cb(net_sock_t *net_sock, void *data);
2017-02-13 04:19:53 +00:00
2017-03-06 08:55:50 +00:00
status_t s1ap_open(void)
2017-02-13 04:19:53 +00:00
{
char buf[INET_ADDRSTRLEN];
int rc;
2017-03-23 14:05:40 +00:00
rc = net_listen_with_addr(&mme_self()->s1ap_sock,
SOCK_STREAM, IPPROTO_SCTP, mme_self()->s1ap_port,
mme_self()->mme_local_addr);
2017-02-13 04:19:53 +00:00
if (rc != 0)
{
d_error("Can't establish S1-ENB(port:%d) path(%d:%s)",
2017-03-23 14:05:40 +00:00
mme_self()->s1ap_port, errno, strerror(errno));
mme_self()->s1ap_sock = NULL;
2017-02-13 04:19:53 +00:00
return CORE_ERROR;
}
rc = net_register_sock(
2017-03-23 14:05:40 +00:00
mme_self()->s1ap_sock, _s1ap_accept_cb, NULL);
2017-02-13 04:19:53 +00:00
if (rc != 0)
{
d_error("Can't establish S1-ENB path(%d:%s)",
errno, strerror(errno));
2017-03-23 14:05:40 +00:00
net_close(mme_self()->s1ap_sock);
mme_self()->s1ap_sock = NULL;
2017-02-13 04:19:53 +00:00
return CORE_ERROR;
}
d_trace(1, "s1_enb_listen() %s:%d\n",
2017-03-23 14:05:40 +00:00
INET_NTOP(&mme_self()->mme_local_addr, buf), mme_self()->s1ap_port);
2017-02-13 04:19:53 +00:00
return CORE_OK;
}
2017-02-13 05:17:26 +00:00
status_t s1ap_close()
2017-02-13 04:19:53 +00:00
{
d_assert(mme_self(), return CORE_ERROR, "Null param");
2017-03-23 14:05:40 +00:00
d_assert(mme_self()->s1ap_sock != NULL, return CORE_ERROR,
2017-02-13 04:19:53 +00:00
"S1-ENB path already opened");
2017-03-23 14:05:40 +00:00
net_unregister_sock(mme_self()->s1ap_sock);
net_close(mme_self()->s1ap_sock);
mme_self()->s1ap_sock = NULL;
2017-02-13 04:19:53 +00:00
return CORE_OK;
}
2017-02-13 05:17:26 +00:00
static int _s1ap_accept_cb(net_sock_t *net_sock, void *data)
2017-02-13 04:19:53 +00:00
{
char buf[INET_ADDRSTRLEN];
ssize_t r;
net_sock_t *remote_sock;
d_assert(net_sock, return -1, "Null param");
r = net_accept(&remote_sock, net_sock, 0);
if (r > 0)
{
d_trace(1, "eNB-S1 accepted[%s] in s1_path module\n",
INET_NTOP(&remote_sock->remote.sin_addr.s_addr, buf));
event_t e;
2017-03-05 08:05:30 +00:00
event_set(&e, EVT_LO_ENB_S1AP_ACCEPT);
event_set_param1(&e, (c_uintptr_t)remote_sock);
2017-03-06 08:55:50 +00:00
event_send(mme_self()->queue_id, &e);
2017-02-13 04:19:53 +00:00
}
else
{
d_error("net_accept failed(r = %d, errno = %d)", r, errno);
}
return r;
}
2017-03-06 08:55:50 +00:00
static status_t s1ap_recv(net_sock_t *net_sock, pkbuf_t *pkbuf)
2017-02-13 04:19:53 +00:00
{
event_t e;
d_assert(net_sock, return CORE_ERROR, "Null param");
2017-03-05 08:05:30 +00:00
d_assert(pkbuf, return CORE_ERROR, "Null param");
2017-02-13 04:19:53 +00:00
d_trace(1, "S1AP_PDU is received from eNB-Inf\n");
2017-03-05 08:05:30 +00:00
d_trace_hex(1, pkbuf->payload, pkbuf->len);
2017-02-13 04:19:53 +00:00
2017-03-05 08:07:43 +00:00
event_set(&e, EVT_MSG_ENB_S1AP);
2017-03-05 08:05:30 +00:00
event_set_param1(&e, (c_uintptr_t)net_sock);
event_set_param2(&e, (c_uintptr_t)pkbuf);
2017-02-13 04:19:53 +00:00
2017-03-06 08:55:50 +00:00
return event_send(mme_self()->queue_id, &e);
2017-02-13 04:19:53 +00:00
}
2017-02-13 05:17:26 +00:00
int _s1ap_recv_cb(net_sock_t *net_sock, void *data)
2017-02-13 04:19:53 +00:00
{
status_t rv;
2017-03-05 08:05:30 +00:00
pkbuf_t *pkbuf;
2017-02-13 04:19:53 +00:00
ssize_t r;
d_assert(net_sock, return -1, "Null param");
2017-03-24 12:19:24 +00:00
pkbuf = pkbuf_alloc(0, MAX_SDU_LEN);
2017-03-05 08:05:30 +00:00
d_assert(pkbuf, return -1, "Can't allocate pkbufuf");
2017-02-13 04:19:53 +00:00
2017-03-05 08:05:30 +00:00
r = net_read(net_sock, pkbuf->payload, pkbuf->len, 0);
2017-02-13 04:19:53 +00:00
if (r == -2)
{
2017-03-05 08:05:30 +00:00
pkbuf_free(pkbuf);
2017-02-13 04:19:53 +00:00
}
else if (r <= 0)
{
2017-03-05 08:05:30 +00:00
pkbuf_free(pkbuf);
2017-02-13 04:19:53 +00:00
if (net_sock->sndrcv_errno == EAGAIN)
{
2017-02-13 04:38:57 +00:00
d_warn("net_read failed(%d:%s)",
2017-02-13 04:19:53 +00:00
net_sock->sndrcv_errno, strerror(net_sock->sndrcv_errno));
return 0;
}
else if (net_sock->sndrcv_errno == ECONNREFUSED)
{
2017-02-13 04:38:57 +00:00
d_warn("net_read failed(%d:%s)",
2017-02-13 04:19:53 +00:00
net_sock->sndrcv_errno, strerror(net_sock->sndrcv_errno));
}
else
{
2017-02-13 04:38:57 +00:00
d_error("net_read failed(%d:%s)",
2017-02-13 04:19:53 +00:00
net_sock->sndrcv_errno, strerror(net_sock->sndrcv_errno));
}
event_t e;
2017-03-05 08:05:30 +00:00
event_set(&e, EVT_LO_ENB_S1AP_CONNREFUSED);
event_set_param1(&e, (c_uintptr_t)net_sock);
2017-03-06 08:55:50 +00:00
event_send(mme_self()->queue_id, &e);
2017-02-13 04:19:53 +00:00
return -1;
}
else
{
2017-03-05 08:05:30 +00:00
pkbuf->len = r;
2017-02-13 04:19:53 +00:00
2017-03-06 08:55:50 +00:00
rv = s1ap_recv(net_sock, pkbuf);
2017-02-13 04:19:53 +00:00
if (rv == CORE_ERROR)
{
2017-03-05 08:05:30 +00:00
pkbuf_free(pkbuf);
2017-02-13 04:19:53 +00:00
d_error("s1_recv() failed");
return -1;
}
}
return 0;
}
2017-03-05 08:05:30 +00:00
status_t s1ap_send(net_sock_t *s, pkbuf_t *pkbuf)
2017-02-13 04:19:53 +00:00
{
char buf[INET_ADDRSTRLEN];
ssize_t sent;
d_assert(s, return CORE_ERROR, "Null param");
2017-03-05 08:05:30 +00:00
d_assert(pkbuf, return CORE_ERROR, "Null param");
2017-02-13 04:19:53 +00:00
2017-03-05 08:05:30 +00:00
sent = net_send(s, pkbuf->payload, pkbuf->len);
2017-02-13 04:19:53 +00:00
d_trace(1,"Sent %d->%d bytes to [%s:%d]\n",
2017-03-05 08:05:30 +00:00
pkbuf->len, sent, INET_NTOP(&s->remote.sin_addr.s_addr, buf),
2017-02-13 04:19:53 +00:00
ntohs(s->remote.sin_port));
2017-03-05 08:05:30 +00:00
d_trace_hex(1, pkbuf->payload, pkbuf->len);
if (sent < 0 || sent != pkbuf->len)
2017-02-13 04:19:53 +00:00
{
d_error("net_send error (%d:%s)",
s->sndrcv_errno, strerror(s->sndrcv_errno));
return CORE_ERROR;
}
return CORE_OK;
}
2017-03-05 08:05:30 +00:00
status_t s1ap_send_to_enb(enb_ctx_t *enb, pkbuf_t *pkbuf)
2017-02-13 04:19:53 +00:00
{
2017-03-07 07:19:18 +00:00
status_t rv = CORE_ERROR;
d_assert(enb,,);
d_assert(pkbuf,,);
d_assert(enb->s1ap_sock,,);
2017-02-13 04:19:53 +00:00
2017-03-07 05:47:17 +00:00
rv = s1ap_send(enb->s1ap_sock, pkbuf);
pkbuf_free(pkbuf);
return rv;
2017-02-13 04:19:53 +00:00
}