2017-02-13 05:17:26 +00:00
|
|
|
#define TRACE_MODULE _s1ap_path
|
2017-02-13 04:19:53 +00:00
|
|
|
|
|
|
|
#include "core_debug.h"
|
2017-02-13 07:03:12 +00:00
|
|
|
|
2017-04-04 01:49:19 +00:00
|
|
|
#include "mme_event.h"
|
2017-03-26 06:34:34 +00:00
|
|
|
|
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-27 04:22:42 +00:00
|
|
|
status_t s1ap_listen(void)
|
2017-02-13 04:19:53 +00:00
|
|
|
{
|
|
|
|
char buf[INET_ADDRSTRLEN];
|
|
|
|
int rc;
|
|
|
|
|
2017-04-09 08:24:24 +00:00
|
|
|
rc = net_listen_ext(&mme_self()->s1ap_sock,
|
|
|
|
SOCK_STREAM, IPPROTO_SCTP, SCTP_S1AP_PPID,
|
|
|
|
mme_self()->s1ap_addr, mme_self()->s1ap_port);
|
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-26 15:48:33 +00:00
|
|
|
INET_NTOP(&mme_self()->s1ap_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-04-13 10:32:56 +00:00
|
|
|
event_set(&e, MME_EVT_S1AP_ENB_LO_ACCEPT);
|
2017-03-05 08:05:30 +00:00
|
|
|
event_set_param1(&e, (c_uintptr_t)remote_sock);
|
2017-03-27 01:22:30 +00:00
|
|
|
/* FIXME : how to close remote_sock */
|
2017-03-26 16:50:01 +00:00
|
|
|
mme_event_send(&e);
|
2017-02-13 04:19:53 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
d_error("net_accept failed(r = %d, errno = %d)", r, errno);
|
|
|
|
}
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2017-04-09 06:15:12 +00:00
|
|
|
static status_t s1ap_recv(net_sock_t *sock, pkbuf_t *pkbuf)
|
2017-02-13 04:19:53 +00:00
|
|
|
{
|
|
|
|
event_t e;
|
|
|
|
|
2017-04-09 06:15:12 +00:00
|
|
|
d_assert(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
|
|
|
|
2017-07-31 13:35:25 +00:00
|
|
|
d_trace(10, "S1AP_PDU is received from eNB-Inf\n");
|
|
|
|
d_trace_hex(10, pkbuf->payload, pkbuf->len);
|
2017-02-13 04:19:53 +00:00
|
|
|
|
2017-04-13 10:32:56 +00:00
|
|
|
event_set(&e, MME_EVT_S1AP_ENB_MSG);
|
2017-04-11 00:19:33 +00:00
|
|
|
event_set_param1(&e, (c_uintptr_t)sock->app_index);
|
2017-03-05 08:05:30 +00:00
|
|
|
event_set_param2(&e, (c_uintptr_t)pkbuf);
|
2017-03-26 16:50:01 +00:00
|
|
|
return mme_event_send(&e);
|
2017-02-13 04:19:53 +00:00
|
|
|
}
|
|
|
|
|
2017-04-09 06:15:12 +00:00
|
|
|
int _s1ap_recv_cb(net_sock_t *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;
|
|
|
|
|
2017-04-09 06:15:12 +00:00
|
|
|
d_assert(sock, return -1, "Null param");
|
2017-02-13 04:19:53 +00:00
|
|
|
|
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-04-09 06:15:12 +00:00
|
|
|
r = net_read(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
|
|
|
|
2017-04-09 06:15:12 +00:00
|
|
|
if (sock->sndrcv_errno == EAGAIN)
|
2017-02-13 04:19:53 +00:00
|
|
|
{
|
2017-02-13 04:38:57 +00:00
|
|
|
d_warn("net_read failed(%d:%s)",
|
2017-04-09 06:15:12 +00:00
|
|
|
sock->sndrcv_errno, strerror(sock->sndrcv_errno));
|
2017-02-13 04:19:53 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2017-04-09 06:15:12 +00:00
|
|
|
else if (sock->sndrcv_errno == ECONNREFUSED)
|
2017-02-13 04:19:53 +00:00
|
|
|
{
|
2017-02-13 04:38:57 +00:00
|
|
|
d_warn("net_read failed(%d:%s)",
|
2017-04-09 06:15:12 +00:00
|
|
|
sock->sndrcv_errno, strerror(sock->sndrcv_errno));
|
2017-02-13 04:19:53 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-02-13 04:38:57 +00:00
|
|
|
d_error("net_read failed(%d:%s)",
|
2017-04-09 06:15:12 +00:00
|
|
|
sock->sndrcv_errno, strerror(sock->sndrcv_errno));
|
2017-02-13 04:19:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
event_t e;
|
|
|
|
|
2017-04-13 10:32:56 +00:00
|
|
|
event_set(&e, MME_EVT_S1AP_ENB_LO_CONNREFUSED);
|
2017-04-11 00:19:33 +00:00
|
|
|
event_set_param1(&e, (c_uintptr_t)sock->app_index);
|
2017-03-26 16:50:01 +00:00
|
|
|
mme_event_send(&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-04-09 06:15:12 +00:00
|
|
|
rv = s1ap_recv(sock, pkbuf);
|
2017-03-27 01:22:30 +00:00
|
|
|
if (rv != CORE_OK)
|
2017-02-13 04:19:53 +00:00
|
|
|
{
|
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-07-31 13:35:25 +00:00
|
|
|
d_trace(10,"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-07-31 13:35:25 +00:00
|
|
|
d_trace_hex(10, pkbuf->payload, pkbuf->len);
|
2017-03-05 08:05:30 +00:00
|
|
|
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;
|
|
|
|
}
|
2017-03-26 16:50:01 +00:00
|
|
|
pkbuf_free(pkbuf);
|
2017-02-13 04:19:53 +00:00
|
|
|
|
|
|
|
return CORE_OK;
|
|
|
|
}
|
|
|
|
|
2017-04-06 11:10:00 +00:00
|
|
|
status_t s1ap_send_to_enb(mme_enb_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);
|
2017-03-26 16:50:01 +00:00
|
|
|
if (rv != CORE_OK)
|
|
|
|
{
|
|
|
|
d_error("s1_send error");
|
|
|
|
pkbuf_free(pkbuf);
|
|
|
|
}
|
2017-03-07 05:47:17 +00:00
|
|
|
|
|
|
|
return rv;
|
2017-02-13 04:19:53 +00:00
|
|
|
}
|