Compare commits

..

40 Commits

Author SHA1 Message Date
Sukchan Lee
5ee7cdd3f8 Release v0.3.9 2018-06-03 01:42:05 +00:00
Sukchan Lee
048eb3f2b2 Change default DISPLAY environment.
We set the DISPLAY=docker.for.mac.localhost:0
If you want to use wireshark in Linux, you need to set DISPLAY to :0.
2018-06-03 10:32:28 +09:00
Sukchan Lee
352b02fc3e Fix the Dockerfile error 2018-06-03 10:17:56 +09:00
Sukchan Lee
9d8695fa31 Update logging message 2018-05-31 09:40:34 +09:00
Sukchan Lee
9415f5215c Fix SCTP for Mac OS X 2018-05-30 22:17:46 +09:00
Sukchan Lee
8c674aa134 Update logging 2018-05-30 21:58:10 +09:00
Sukchan Lee
3b9b1108b1 Configure Outbound streams on SCTP_COMM_UP 2018-05-30 21:49:17 +09:00
Sukchan Lee
9aed43075c SCTP recv interface will be changed. (Progressing...) 2018-05-30 17:45:14 +09:00
Sukchan Lee
3d78f285be Install wireshark in docker 2018-05-30 15:05:47 +09:00
Sukchan Lee
749d632b86 Change the name of docker image 2018-05-29 17:41:11 +09:00
Sukchan Lee
37ecb9a63b Change debian package in docker 2018-05-29 16:03:29 +09:00
Sukchan Lee
0d3af830bb Unlink debian from ubuntu 2018-05-29 13:05:37 +09:00
Sukchan Lee
7c7cfd1cbf Support bionic in Docker 2018-05-29 11:20:48 +09:00
Sukchan Lee
4f1efbb521 Add wireshark in Docker 2018-05-29 11:15:18 +09:00
Sukchan Lee
2fb37ad797 Change the assert to warning
- When UEContextReleaseComplete is received,
    It could be unknown MME-UE-S1AP-ID.
- So, we change the log from assert to warning
2018-05-23 20:40:46 +09:00
Sukchan Lee
ffa6c2c15b Fix the bug of invalid TAU update result.
- MME should set TAU update result in TAU accept message. TAU udpate
result should be derived from TAU request message.
2018-05-22 19:21:34 +09:00
Sukchan Lee
c906b243a2 fix the encryption bug 2018-05-22 17:39:43 +09:00
Sukchan Lee
056fc43d34 Fix the bug for EIA2 (#64) 2018-05-22 11:31:09 +09:00
Sukchan Lee
76c84bdaa4 Fix the bug in building TAU accept message (#29)
- TAU accept should be integrity protected
2018-05-21 15:17:34 +09:00
Sukchan Lee
6ae20c9d1c refine code 2018-05-19 06:16:53 +09:00
Sukchan Lee
fe84604fa0 Oops! Change inbound_streams to outbound_streams (#63) 2018-05-19 06:06:02 +09:00
Sukchan Lee
85a2a64b65 Support Mac OS X for SCTP streams negotiations 2018-05-18 23:08:57 +09:00
Sukchan Lee
f5c203d3ac remove redundant code 2018-05-18 17:32:56 +09:00
Sukchan Lee
9a0afe035a Negociate SCTP stream ID with eNodeB (#63) 2018-05-18 17:14:29 +09:00
Sukchan Lee
76d8df3879 remove d_error 2018-05-18 15:52:47 +09:00
Sukchan Lee
550a606306 Update error message if SGW is not running (#59) 2018-05-14 21:46:19 +09:00
Sukchan Lee
1b21c21395 change warning to trace 2018-05-13 21:14:51 +09:00
Sukchan Lee
157dab73c7 fix the linux for SCTP streams 2018-05-13 18:31:01 +09:00
Sukchan Lee
7dba30b1e6 S1AP sends SCTP packet with stream id (#54) 2018-05-13 18:02:24 +09:00
Sukchan Lee
55fa0115e8 Merge branch 'master' into stream 2018-05-13 17:01:36 +09:00
Sukchan Lee
2142d406f0 fix the timezone for GTPv2 message 2018-05-13 17:00:57 +09:00
Sukchan Lee
9d84d4d43a Fix the timezone error 2018-05-13 16:45:49 +09:00
Sukchan Lee
57ef9697c3 Merge branch 'stream' of https://github.com/acetcom/nextepc into stream 2018-05-13 10:04:12 +09:00
Sukchan Lee
280aaf9fe1 Add SCTP output stream generator (#54) 2018-05-10 11:19:05 +09:00
Sukchan Lee
529b55c16b Introduce new configuration for SCTP streams (#54)
SCTP initmsg
 - Number of output streams : configured(default:30)
 - Maximum input streams : 65535
 - Maximum attempts : 4
 - Maximum initial timeout : 8 seconds
2018-05-10 10:35:15 +09:00
Sukchan Lee
10f59c850b Generate SCTP output stream identifier 2018-05-09 23:09:04 +09:00
Sukchan Lee
e18467889c Introduce new configuration for SCTP streams
SCTP initmsg
 - Number of output streams : configured(default:30)
 - Maximum input streams : 65535
 - Maximum attempts : 4
 - Maximum initial timeout : 8 seconds
2018-05-09 22:11:25 +09:00
Sukchan Lee
3148d4cd67 Support Ubuntu 18.04 LTS (bionic) 2018-05-05 22:52:03 +09:00
Sukchan Lee
de92fdd5c7 Update debian changelog for ubuntu 18.04(bionic)
We've release ubuntu 18.04 LTS(bionic)
2018-05-05 21:51:50 +09:00
Sukchan Lee
f3ddfaec44 Fix the docker development environment 2018-05-02 22:11:02 +09:00
53 changed files with 707 additions and 2479 deletions

View File

@@ -8,7 +8,7 @@ dnl This program is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
AC_INIT([NextEPC], [0.3.8], [acetcom@gmail.com]) AC_INIT([NextEPC], [0.3.9], [acetcom@gmail.com])
AC_SUBST(LIBVERSION) AC_SUBST(LIBVERSION)
LIBVERSION=1:0:0 LIBVERSION=1:0:0

30
debian/changelog vendored
View File

@@ -1,3 +1,33 @@
nextepc (0.3.9~artful) artful; urgency=medium
* Bug Fixed
-- Sukchan Lee <acetcom@gmail.com> Sun, 03 Jun 2018 01:40:44 +0000
nextepc (0.3.9~xenial) xenial; urgency=medium
* Bug Fixed
-- Sukchan Lee <acetcom@gmail.com> Sun, 03 Jun 2018 01:39:33 +0000
nextepc (0.3.9~bionic) bionic; urgency=medium
* Bug Fixed
-- Sukchan Lee <acetcom@gmail.com> Sun, 03 Jun 2018 01:38:15 +0000
nextepc (0.3.8-1~bionic) bionic; urgency=medium
* Bug Fixed
-- Sukchan Lee <acetcom@gmail.com> Sat, 05 May 2018 22:37:45 +0900
nextepc (0.3.8~bionic) bionic; urgency=medium
* Bug Fixed
-- Sukchan Lee <acetcom@gmail.com> Sat, 05 May 2018 21:48:55 +0900
nextepc (0.3.8~xenial) xenial; urgency=medium nextepc (0.3.8~xenial) xenial; urgency=medium
* Bug Fixed * Bug Fixed

1
debian/control vendored
View File

@@ -14,6 +14,7 @@ Build-Depends: debhelper (>= 9),
libgnutls28-dev, libgnutls28-dev,
libgcrypt-dev, libgcrypt-dev,
libssl-dev, libssl-dev,
libidn11-dev,
libmongoc-dev, libmongoc-dev,
libbson-dev, libbson-dev,
libyaml-dev libyaml-dev

View File

@@ -1,274 +0,0 @@
#ifndef __CORE_NET_H__
#define __CORE_NET_H__
#include "core.h"
#include "core_errno.h"
#include "core_index.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#if HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#if HAVE_NETDB_H
#include <netdb.h>
#endif
#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#define MAX_NET_POOL_SIZE 512
/* Max length of interface name, ex: eth0, ath0 .. */
#define MAX_IFNAME_LEN 16
#define INET_NTOP(src, dst) inet_ntop(AF_INET,(void *)(c_uintptr_t)(src),(dst),INET_ADDRSTRLEN)
#define INET6_NTOP(src, dst) inet_ntop(AF_INET6,(void *)(src),(dst),INET6_ADDRSTRLEN)
/** Network handler */
typedef int (*net_handler)(void *net_sl, void *data);
/** Network socket descriptor */
typedef struct {
int type;
int proto;
#define SCTP_S1AP_PPID 18
#define SCTP_X2AP_PPID 27
c_uint32_t ppid;
int sock_id;
#if 0 /* deprecated */
struct sockaddr_in local;
#endif
struct sockaddr_in remote;
int opt;
int sndrcv_errno;
} net_sock_t;
/** Network socket handler */
typedef int (*net_sock_handler)(net_sock_t *net_sock, void *data);
/** Basic socket library */
/** Initialize network library */
CORE_DECLARE(status_t) net_init(void);
/** Finalize network library */
CORE_DECLARE(status_t) net_final(void);
/**
* Create network session.
* @param net_sock Connected network session.
* @param host Host IP address to be connected.
* @param lport Local Port number(only for UDP)
* @param rport Remote Port number
* @param proto Protocol proto
* @param type Protocol type
* @param flag Option flags to be set for this connection
*/
CORE_DECLARE(int) net_open(net_sock_t **net_sock,const char *host,
const int lport,
const int rport,
int type, int proto);
/**
* Create network session.
* @param net_sock Connected network session.
* @param local_addr Local Host IP address to bind(Network order)
* @param remote_host Remote Host IP address to be connected.
* @param lport Local Port number(only for UDP)
* @param rport Remote Port number
* @param proto Protocol proto
* @param type Protocol type
* @param flag Option flags to be set for this connection
*/
CORE_DECLARE(int) net_open_ext(net_sock_t **net_sock,
const c_uint32_t local_addr,
const char *remote_host,
const int lport,
const int rport,
int type, int proto, c_uint32_t ppid, const int flag);
/**
* Read the data from the socket
* @param net_sock Socket which created before
* @param buffer Buffer which data be saved
* @param size Total length of buffer
* @param timeout Wait timeout. If 0 , it will block until data ready
*/
CORE_DECLARE(int) net_read(net_sock_t *net_sock, char *buffer, size_t size,int timeout);
/** Write the data into the socket
* @param net_sock Socket which created before
* @param buffer Buffer which data be saved
* @param size Total length of buffer
*/
CORE_DECLARE(int) net_write(net_sock_t *net_sock, char *buffer, size_t size,
struct sockaddr_in *dest_addr, int addrlen);
CORE_DECLARE(int) net_send(net_sock_t *net_sock, char *buffer, size_t size);
CORE_DECLARE(int) net_sendto(net_sock_t *net_sock, char *buffer, size_t size,
c_uint32_t addr, c_uint16_t port);
/** Close the socket
* @param net_sock Socket to be closed
*/
CORE_DECLARE(int) net_close(net_sock_t *net_sock);
/** Wait the new socket session until given timeout
* @param new_accept_sock Newly created socket for new connection
* @param net_sock Listend socket before created
* @param timeout Wait timeout. If 0, it will be blocked until new connection
* received
*/
CORE_DECLARE(int) net_accept(net_sock_t **new_accept_sock,
net_sock_t *net_sock, int timeout);
/** Create socket and listen to the specified port
* @param net_sock Returned socket
* @param type Protocol type
* @param proto Protocol proto
* @param ppid SCTP PPID
* @param addr Specific address
* @param port Port number
*/
CORE_DECLARE(int) net_listen_ext(net_sock_t **net_sock,
const int type, const int proto, const c_uint32_t ppid,
const c_uint32_t addr, const int port);
/** Create socket and listen to the specified port
* @param net_sock Returned socket
* @param type Protocol type
* @param proto Protocol proto
* @param port Port number
*/
CORE_DECLARE(int) net_listen(
net_sock_t **net_sock, const int type, const int proto,
const int port);
/** Network application protocol */
#define MAX_FTP_SESSION_SIZE 10
typedef struct {
net_sock_t *ctrl_sock; /* Control channel */
net_sock_t *data_sock; /* Data channel */
int flag;
char cmd_buf[256];
char resp_buf[256];
} net_ftp_t;
/** Open ftp session.
* @param host host name or IP address to connect
* @param username User ID or NULL if username is anonymous
* @param passwd Password or NULL if no passwd
* @param flag Option flags
* @param ftp_session Ftp session structure. If connection failed , it will be NULL
*/
CORE_DECLARE(int) net_ftp_open(const char *host,
const char *username,
const char *passwd,
int flag,
net_ftp_t **ftp_session);
/** Retrieve file using FTP
* @param ftp_session Ftp session which created from net_ftp_open
* @param remote_filename Remote filename to retrieve
* @param local_filename Local filename. If null, the same name as remote will
* be used.
*/
CORE_DECLARE(int) net_ftp_get(net_ftp_t *ftp_session,
const char *remote_filename,
const char *local_filename);
/** Upload file using FTP
* @param ftp_session Ftp session which created from net_ftp_open
* @param local_filename Local filename to upload.
* @param remote_filename Remote filename.If null, the same name as local will
* be used.
*/
CORE_DECLARE(int) net_ftp_put(net_ftp_t *ftp_session,
const char *local_filename,
const char *remote_filename);
/** Quit from ftp
* @param ftp_session Ftp session which created from net_ftp_open
*/
CORE_DECLARE(int) net_ftp_quit(net_ftp_t *ftp_session);
/** Close ftp session
* @param ftp_session Ftp session which created from net_ftp_open
*/
CORE_DECLARE(int) net_ftp_close(net_ftp_t *ftp_session);
/** Network session pool */
CORE_DECLARE(int) net_pool_avail();
/** Network link interface */
typedef struct {
int fd;
int ioctl_sock;
char ifname[MAX_IFNAME_LEN];
struct sockaddr hwaddr;
} net_link_t;
/** Network link handler */
typedef int (*net_link_handler)(net_link_t *net_sock, void *data);
/** Open network interface */
CORE_DECLARE(int) net_link_open(net_link_t **net_link, char *device, int proto);
/** Close network interface */
CORE_DECLARE(int) net_link_close(net_link_t *net_link);
/** Enable or disable promisc mode of network interface */
CORE_DECLARE(int) net_link_promisc(net_link_t *net_link, int enable);
/** Write the data into the link */
CORE_DECLARE(int) net_link_write(net_link_t *net_link, char *buf, int len);
/** Reate the data from the link */
CORE_DECLARE(int) net_link_read(net_link_t *net_link, char *buffer, int size,
int timeout);
/** Open the specified protocol raw socket */
CORE_DECLARE(int) net_raw_open(net_link_t **net_link, int proto);
/** Clse the specified protocol raw socket */
CORE_DECLARE(int) net_raw_close(net_link_t *net_link);
CORE_DECLARE(int) net_link_sendto(net_link_t *net_link, char *buf, int len,
struct sockaddr *dest_addr, int addrlen);
/** Register net_sock */
CORE_DECLARE(int) net_register_sock(net_sock_t *net_sock,
net_sock_handler handler, void *data);
/** Register net_link */
CORE_DECLARE(int) net_register_link(net_link_t *net_link,
net_link_handler handler, void *data);
/** Unregister net_sock */
CORE_DECLARE(int) net_unregister_sock(net_sock_t *net_sock);
/** Unregister net_link */
CORE_DECLARE(int) net_unregister_link(net_link_t *net_link);
/** Read the multiple fds and run the registered handler
* @param timeout timeout(milliseconds)
*/
CORE_DECLARE(int) net_fds_read_run(long timeout);
/** TunTap interface */
CORE_DECLARE(int) net_tun_open(net_link_t **net_link, char *name, int is_tap);
CORE_DECLARE(int) net_tun_set_ipv4(
net_link_t *net_link, c_uint32_t addr, c_uint8_t bits);
CORE_DECLARE(int) net_tun_close(net_link_t *net_link);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ! __CORE_NET_H__ */

View File

@@ -5,8 +5,6 @@
#include "core_time.h" #include "core_time.h"
#include "core_list.h" #include "core_list.h"
#define NO_FD_LOCK 1 /* New experimental method */
#if HAVE_ARPA_INET_H #if HAVE_ARPA_INET_H
#include <arpa/inet.h> #include <arpa/inet.h>
#endif #endif
@@ -106,6 +104,13 @@ typedef struct ipsubnet_t {
c_uint32_t mask[4]; c_uint32_t mask[4];
} ipsubnet_t; } 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 * Init/Final
*/ */
@@ -194,6 +199,8 @@ CORE_DECLARE(status_t) tcp_client(sock_id *new, c_sockaddr_t *sa_list);
/* /*
* SCTP Socket * SCTP Socket
*/ */
CORE_DECLARE(void) sctp_set_num_ostreams(int sctp_streams);
CORE_DECLARE(status_t) sctp_socket(sock_id *new, int family, int type); CORE_DECLARE(status_t) sctp_socket(sock_id *new, int family, int type);
CORE_DECLARE(status_t) sctp_server(sock_id *new, CORE_DECLARE(status_t) sctp_server(sock_id *new,
int type, c_sockaddr_t *sa_list); int type, c_sockaddr_t *sa_list);
@@ -202,10 +209,10 @@ CORE_DECLARE(status_t) sctp_client(sock_id *new,
CORE_DECLARE(status_t) sctp_connect(sock_id id, c_sockaddr_t *sa_list); CORE_DECLARE(status_t) sctp_connect(sock_id id, c_sockaddr_t *sa_list);
CORE_DECLARE(int) core_sctp_sendmsg(sock_id id, const void *msg, size_t len, CORE_DECLARE(int) core_sctp_sendmsg(sock_id id, const void *msg, size_t len,
c_sockaddr_t *to, c_uint32_t ppid, c_uint16_t stream_no); c_sockaddr_t *to, c_uint32_t ppid, c_uint16_t stream_no);
#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, 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, 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);
/* /*
* TUN Driver * TUN Driver
*/ */

File diff suppressed because it is too large Load Diff

View File

@@ -12,8 +12,16 @@ static status_t set_paddrparams(sock_id id, c_uint32_t spp_hbinterval);
static status_t set_rtoinfo(sock_id id, static status_t set_rtoinfo(sock_id id,
c_uint32_t srto_initial, c_uint32_t srto_min, c_uint32_t srto_max); c_uint32_t srto_initial, c_uint32_t srto_min, c_uint32_t srto_max);
static status_t set_initmsg(sock_id id, static status_t set_initmsg(sock_id id,
c_uint32_t sinit_num_ostreams, c_uint32_t sinit_max_instreams,
c_uint32_t sinit_max_attempts, c_uint32_t sinit_max_init_timeo); c_uint32_t sinit_max_attempts, c_uint32_t sinit_max_init_timeo);
static int sctp_num_ostreams = -1;
void sctp_set_num_ostreams(int sctp_streams)
{
sctp_num_ostreams = sctp_streams;
}
status_t sctp_socket(sock_id *new, int family, int type) status_t sctp_socket(sock_id *new, int family, int type)
{ {
status_t rv; status_t rv;
@@ -41,10 +49,11 @@ status_t sctp_socket(sock_id *new, int family, int type)
/* /*
* INITMSG * INITMSG
* *
* max number of input streams : 65535
* max attemtps : 4 * max attemtps : 4
* max initial timeout : 8 secs * max initial timeout : 8 secs
*/ */
rv = set_initmsg(*new, 4, 8000); rv = set_initmsg(*new, sctp_num_ostreams, 65535, 4, 8000);
d_assert(rv == CORE_OK, return CORE_ERROR,); d_assert(rv == CORE_OK, return CORE_ERROR,);
return CORE_OK; return CORE_OK;
@@ -193,73 +202,60 @@ 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, 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, int *msg_flags)
{ {
sock_t *sock = (sock_t *)id; sock_t *sock = (sock_t *)id;
int size; int size;
socklen_t addrlen = sizeof(struct sockaddr_storage); socklen_t addrlen = sizeof(struct sockaddr_storage);
int flags = 0; int flags = 0;
struct sctp_sndrcvinfo sinfo; struct sctp_sndrcvinfo sndrcvinfo;
d_assert(id, return -1,); d_assert(id, return -1,);
size = sctp_recvmsg(sock->fd, msg, len,
from ? &from->sa : NULL, from ? &addrlen : NULL,
&sndrcvinfo, &flags);
if (size < 0)
{
d_error("sctp_recvmsg(%d) failed(%d:%s)",
size, errno, strerror(errno));
return size;
}
if (msg_flags)
{
*msg_flags = flags;
}
if (sinfo)
{
sinfo->ppid = ntohl(sndrcvinfo.sinfo_ppid);
sinfo->stream_no = sndrcvinfo.sinfo_stream;
}
return size;
}
int core_sctp_recvdata(sock_id id, void *msg, size_t len,
c_sockaddr_t *from, sctp_info_t *sinfo)
{
int size;
int flags = 0;
do do
{ {
size = sctp_recvmsg(sock->fd, msg, len, size = core_sctp_recvmsg(id, msg, len, from, sinfo, &flags);
from ? &from->sa : NULL, from ? &addrlen : NULL,
&sinfo, &flags);
if (size < 0) if (size < 0)
{ {
if (errno != EAGAIN) d_error("core_sctp_recvdata(%d) failed(%d:%s)",
{ size, errno, strerror(errno));
d_error("sctp_recvmsg(%d) failed(%d:%s)",
size, errno, strerror(errno));
}
return size; return size;
} }
if (flags & MSG_NOTIFICATION) if (flags & MSG_NOTIFICATION)
{ {
union sctp_notification *not = (union sctp_notification *)msg; /* Nothing */
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\n");
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) else if (flags & MSG_EOR)
{ {
@@ -267,21 +263,11 @@ int core_sctp_recvmsg(sock_id id, void *msg, size_t len,
} }
else else
{ {
return CORE_SCTP_EAGAIN; d_assert(0, return -1,);
} }
} while(1); } while(1);
if (ppid)
{
*ppid = ntohl(sinfo.sinfo_ppid);
}
if (stream_no)
{
*stream_no = sinfo.sinfo_stream;
}
return size; return size;
} }
@@ -394,6 +380,7 @@ static status_t set_rtoinfo(sock_id id,
} }
static status_t set_initmsg(sock_id id, static status_t set_initmsg(sock_id id,
c_uint32_t sinit_num_ostreams, c_uint32_t sinit_max_instreams,
c_uint32_t sinit_max_attempts, c_uint32_t sinit_max_init_timeo) c_uint32_t sinit_max_attempts, c_uint32_t sinit_max_init_timeo)
{ {
sock_t *sock = (sock_t *)id; sock_t *sock = (sock_t *)id;
@@ -401,7 +388,8 @@ static status_t set_initmsg(sock_id id,
socklen_t socklen; socklen_t socklen;
d_assert(id, return CORE_ERROR,); d_assert(id, return CORE_ERROR,);
d_assert(sinit_num_ostreams > 1, return CORE_ERROR,
"Invalid SCTP number of output streams = %d\n", sctp_num_ostreams);
memset(&initmsg, 0, sizeof(initmsg)); memset(&initmsg, 0, sizeof(initmsg));
socklen = sizeof(initmsg); socklen = sizeof(initmsg);
@@ -419,6 +407,8 @@ static status_t set_initmsg(sock_id id,
initmsg.sinit_max_attempts, initmsg.sinit_max_attempts,
initmsg.sinit_max_init_timeo); initmsg.sinit_max_init_timeo);
initmsg.sinit_num_ostreams = sinit_num_ostreams;
initmsg.sinit_max_instreams = sinit_max_instreams;
initmsg.sinit_max_attempts = sinit_max_attempts; initmsg.sinit_max_attempts = sinit_max_attempts;
initmsg.sinit_max_init_timeo = sinit_max_init_timeo; initmsg.sinit_max_init_timeo = sinit_max_init_timeo;

View File

@@ -9,14 +9,6 @@
#define MAX_SOCK_POOL_SIZE 512 #define MAX_SOCK_POOL_SIZE 512
#define MAX_SOCK_NODE_POOL_SIZE 512 #define MAX_SOCK_NODE_POOL_SIZE 512
#if NO_FD_LOCK
#define FD_LOCK
#define FD_UNLOCK
#else
#define FD_LOCK mutex_lock(mutex);
#define FD_UNLOCK mutex_unlock(mutex);
#endif
static int max_fd; static int max_fd;
static list_t fd_list; static list_t fd_list;
static fd_set read_fds; static fd_set read_fds;
@@ -667,8 +659,6 @@ status_t sock_register(sock_id id, sock_handler handler, void *data)
return CORE_ERROR; return CORE_ERROR;
} }
FD_LOCK
if (sock->fd > max_fd) if (sock->fd > max_fd)
{ {
max_fd = sock->fd; max_fd = sock->fd;
@@ -678,8 +668,6 @@ status_t sock_register(sock_id id, sock_handler handler, void *data)
list_append(&fd_list, sock); list_append(&fd_list, sock);
FD_UNLOCK
return CORE_OK; return CORE_OK;
} }
@@ -687,12 +675,8 @@ status_t sock_unregister(sock_id id)
{ {
d_assert(id, return CORE_ERROR,); d_assert(id, return CORE_ERROR,);
FD_LOCK
list_remove(&fd_list, id); list_remove(&fd_list, id);
FD_UNLOCK
return CORE_OK; return CORE_OK;
} }
@@ -701,19 +685,15 @@ int sock_is_registered(sock_id id)
sock_t *sock = (sock_t *)id; sock_t *sock = (sock_t *)id;
sock_t *iter = NULL; sock_t *iter = NULL;
FD_LOCK
d_assert(id, return CORE_ERROR,); d_assert(id, return CORE_ERROR,);
for (iter = list_first(&fd_list); iter != NULL; iter = list_next(iter)) for (iter = list_first(&fd_list); iter != NULL; iter = list_next(iter))
{ {
if (iter == sock) if (iter == sock)
{ {
FD_UNLOCK
return 1; return 1;
} }
} }
FD_UNLOCK
return 0; return 0;
} }
@@ -810,23 +790,17 @@ static void set_fds(fd_set *fds)
{ {
sock_t *sock = NULL; sock_t *sock = NULL;
FD_LOCK
FD_ZERO(fds); FD_ZERO(fds);
for (sock = list_first(&fd_list); sock != NULL; sock = list_next(sock)) for (sock = list_first(&fd_list); sock != NULL; sock = list_next(sock))
{ {
FD_SET(sock->fd, fds); FD_SET(sock->fd, fds);
} }
FD_UNLOCK
} }
static void fd_dispatch(fd_set *fds) static void fd_dispatch(fd_set *fds)
{ {
sock_t *sock = NULL; sock_t *sock = NULL;
FD_LOCK
for (sock = list_first(&fd_list); sock != NULL; sock = list_next(sock)) for (sock = list_first(&fd_list); sock != NULL; sock = list_next(sock))
{ {
if (FD_ISSET(sock->fd, fds)) if (FD_ISSET(sock->fd, fds))
@@ -837,6 +811,4 @@ static void fd_dispatch(fd_set *fds)
} }
} }
} }
FD_UNLOCK
} }

View File

@@ -123,8 +123,7 @@ status_t time_exp_get(c_time_t *t, time_exp_t *xt)
return CORE_OK; return CORE_OK;
} }
status_t time_exp_gmt_get(c_time_t *t, status_t time_exp_gmt_get(c_time_t *t, time_exp_t *xt)
time_exp_t *xt)
{ {
status_t status = time_exp_get(t, xt); status_t status = time_exp_get(t, xt);
if (status == CORE_OK) if (status == CORE_OK)

View File

@@ -56,6 +56,7 @@ static void *THREAD_FUNC test2_main(thread_id id, void *data)
char str[STRLEN]; char str[STRLEN];
ssize_t size; ssize_t size;
c_uint32_t ppid; c_uint32_t ppid;
sctp_info_t sinfo;
c_sockaddr_t *addr; c_sockaddr_t *addr;
c_sockaddr_t from; c_sockaddr_t from;
@@ -66,9 +67,9 @@ static void *THREAD_FUNC test2_main(thread_id id, void *data)
rv = core_freeaddrinfo(addr); rv = core_freeaddrinfo(addr);
ABTS_INT_EQUAL(tc, CORE_OK, rv); ABTS_INT_EQUAL(tc, CORE_OK, rv);
size = core_sctp_recvmsg(sctp, str, STRLEN, &from, &ppid, NULL); size = core_sctp_recvdata(sctp, str, STRLEN, &from, &sinfo);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size); ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ABTS_INT_EQUAL(tc, PPID, ppid); ABTS_INT_EQUAL(tc, PPID, sinfo.ppid);
rv = sock_delete(sctp); rv = sock_delete(sctp);
ABTS_INT_EQUAL(tc, CORE_OK, rv); 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; c_sockaddr_t from, *addr;
char str[STRLEN]; char str[STRLEN];
char buf[CORE_ADDRSTRLEN]; char buf[CORE_ADDRSTRLEN];
c_uint32_t ppid; sctp_info_t sinfo;
rv = core_getaddrinfo(&addr, AF_INET, NULL, PORT, AI_PASSIVE); rv = core_getaddrinfo(&addr, AF_INET, NULL, PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, CORE_OK, rv); 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); rv = thread_create(&test3_thread, NULL, test3_main, tc);
ABTS_INT_EQUAL(tc, CORE_OK, rv); ABTS_INT_EQUAL(tc, CORE_OK, rv);
size = core_sctp_recvmsg(sctp, str, STRLEN, &from, &ppid, NULL); size = core_sctp_recvdata(sctp, str, STRLEN, &from, &sinfo);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size); 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); thread_join(&rv, test3_thread);
ABTS_INT_EQUAL(tc, strlen(DATASTR), rv); 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; c_sockaddr_t *addr;
char str[STRLEN]; char str[STRLEN];
ssize_t size; ssize_t size;
c_uint32_t ppid; sctp_info_t sinfo;
rv = core_getaddrinfo(&addr, AF_UNSPEC, NULL, PORT, 0); rv = core_getaddrinfo(&addr, AF_UNSPEC, NULL, PORT, 0);
ABTS_INT_EQUAL(tc, CORE_OK, rv); 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); size = core_sctp_sendmsg(sctp, DATASTR, strlen(DATASTR), NULL, PPID, 0);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size); ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
size = core_sctp_recvmsg(sctp, str, STRLEN, NULL, &ppid, NULL); size = core_sctp_recvdata(sctp, str, STRLEN, NULL, &sinfo);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size); ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ABTS_INT_EQUAL(tc, PPID, ppid); ABTS_INT_EQUAL(tc, PPID, sinfo.ppid);
rv = sock_delete(sctp); rv = sock_delete(sctp);
ABTS_INT_EQUAL(tc, CORE_OK, rv); ABTS_INT_EQUAL(tc, CORE_OK, rv);
@@ -211,7 +212,7 @@ static void sctp_test4(abts_case *tc, void *data)
ssize_t size; ssize_t size;
c_sockaddr_t from, *addr; c_sockaddr_t from, *addr;
char str[STRLEN]; char str[STRLEN];
c_uint32_t ppid; sctp_info_t sinfo;
char buf[CORE_ADDRSTRLEN]; char buf[CORE_ADDRSTRLEN];
rv = core_getaddrinfo(&addr, AF_INET6, NULL, PORT, AI_PASSIVE); 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); rv = thread_create(&test4_thread, NULL, test4_main, tc);
ABTS_INT_EQUAL(tc, CORE_OK, rv); ABTS_INT_EQUAL(tc, CORE_OK, rv);
size = core_sctp_recvmsg(sctp, str, STRLEN, &from, &ppid, NULL); size = core_sctp_recvdata(sctp, str, STRLEN, &from, &sinfo);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size); ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ABTS_STR_EQUAL(tc, "::1", CORE_ADDR(&from, buf)); 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, PPID, 0);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size); 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; sock_id sctp;
char str[STRLEN]; char str[STRLEN];
c_sockaddr_t from, *remote_addr, *addr; c_sockaddr_t from, *remote_addr, *addr;
c_uint32_t ppid; sctp_info_t sinfo;
ssize_t size; ssize_t size;
char buf[CORE_ADDRSTRLEN]; char buf[CORE_ADDRSTRLEN];
@@ -271,10 +272,10 @@ static void *THREAD_FUNC test5_main(thread_id id, void *data)
remote_addr, PPID, 0); remote_addr, PPID, 0);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size); ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
size = core_sctp_recvmsg(sctp, str, STRLEN, &from, &ppid, NULL); size = core_sctp_recvdata(sctp, str, STRLEN, &from, &sinfo);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size); ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ABTS_STR_EQUAL(tc, "::1", CORE_ADDR(&from, buf)); 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); rv = sock_delete(sctp);
ABTS_INT_EQUAL(tc, CORE_OK, rv); 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; c_sockaddr_t from, *addr;
socklen_t addrlen; socklen_t addrlen;
char str[STRLEN]; char str[STRLEN];
c_uint32_t ppid; sctp_info_t sinfo;
char buf[CORE_ADDRSTRLEN]; char buf[CORE_ADDRSTRLEN];
rv = core_getaddrinfo(&addr, AF_INET6, NULL, PORT, AI_PASSIVE); 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); rv = thread_create(&test5_thread, NULL, test5_main, tc);
ABTS_INT_EQUAL(tc, CORE_OK, rv); ABTS_INT_EQUAL(tc, CORE_OK, rv);
size = core_sctp_recvmsg(sctp, str, STRLEN, &from, &ppid, NULL); size = core_sctp_recvdata(sctp, str, STRLEN, &from, &sinfo);
ABTS_INT_EQUAL(tc, strlen(DATASTR), size); ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
ABTS_STR_EQUAL(tc, "::1", CORE_ADDR(&from, buf)); 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); ABTS_INT_EQUAL(tc, strlen(DATASTR), size);
thread_join(&rv, test5_thread); thread_join(&rv, test5_thread);

View File

@@ -632,8 +632,11 @@ status_t gtp_xact_timeout(index_t index, c_uintptr_t event)
pkbuf = xact->seq[xact->step-1].pkbuf; pkbuf = xact->seq[xact->step-1].pkbuf;
d_assert(pkbuf, return CORE_ERROR, "Null param"); d_assert(pkbuf, return CORE_ERROR, "Null param");
d_assert(gtp_send(xact->gnode, pkbuf) == CORE_OK, if (gtp_send(xact->gnode, pkbuf) != CORE_OK)
goto out, "gtp_send error"); {
d_error("gtp_send() failed");
goto out;
}
} }
else else
{ {

View File

@@ -11,6 +11,8 @@
#include "context.h" #include "context.h"
#define DEFAULT_SCTP_STREAMS 30
static context_t self; static context_t self;
static int context_initialized = 0; static int context_initialized = 0;
@@ -103,6 +105,7 @@ status_t context_setup_trace_module()
static status_t context_prepare() static status_t context_prepare()
{ {
self.logger.console = -1; self.logger.console = -1;
self.parameter.sctp_streams = DEFAULT_SCTP_STREAMS;
return CORE_OK; return CORE_OK;
} }
@@ -256,6 +259,11 @@ status_t context_parse_config()
self.parameter.no_pcrf = self.parameter.no_pcrf =
yaml_iter_bool(&parameter_iter); yaml_iter_bool(&parameter_iter);
} }
else if (!strcmp(parameter_key, "sctp_streams"))
{
const char *v = yaml_iter_value(&parameter_iter);
if (v) self.parameter.sctp_streams = atoi(v);
}
else if (!strcmp(parameter_key, "no_ipv4")) else if (!strcmp(parameter_key, "no_ipv4"))
{ {
self.parameter.no_ipv4 = self.parameter.no_ipv4 =

View File

@@ -54,6 +54,7 @@ typedef struct _context_t {
int no_pcrf; int no_pcrf;
/* Network */ /* Network */
int sctp_streams;
int no_ipv4; int no_ipv4;
int no_ipv6; int no_ipv6;
int prefer_ipv4; int prefer_ipv4;

View File

@@ -333,10 +333,14 @@ status_t emm_build_tau_accept(pkbuf_t **emmbuf, mme_ue_t *mme_ue)
d_assert(mme_ue, return CORE_ERROR,); d_assert(mme_ue, return CORE_ERROR,);
memset(&message, 0, sizeof(message)); memset(&message, 0, sizeof(message));
message.h.security_header_type =
NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM; message.emm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.message_type = NAS_TRACKING_AREA_UPDATE_ACCEPT; message.emm.h.message_type = NAS_TRACKING_AREA_UPDATE_ACCEPT;
tau_accept->eps_update_result.result = NAS_EPS_UPDATE_RESULT_TA_UPDATED; tau_accept->eps_update_result.result = mme_ue->nas_eps.update.update_type;
/* Set T3412 */ /* Set T3412 */
tau_accept->presencemask |= tau_accept->presencemask |=
@@ -428,7 +432,8 @@ status_t emm_build_tau_reject(pkbuf_t **emmbuf, nas_emm_cause_t emm_cause,
d_assert(mme_ue, return CORE_ERROR,); d_assert(mme_ue, return CORE_ERROR,);
d_trace(3, "[EMM] Tracking area update reject\n"); d_trace(3, "[EMM] Tracking area update reject\n");
d_trace(5, " IMSI[%s] Cause[%d]\n", mme_ue->imsi_bcd, emm_cause); d_trace(5, " IMSI[%s] Cause[%d]\n",
MME_UE_HAVE_IMSI(mme_ue) ? mme_ue->imsi_bcd : "Unknown", emm_cause);
memset(&message, 0, sizeof(message)); memset(&message, 0, sizeof(message));
message.emm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM; message.emm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;

View File

@@ -180,11 +180,24 @@ status_t emm_handle_attach_complete(
nas_daylight_saving_time_t *network_daylight_saving_time = nas_daylight_saving_time_t *network_daylight_saving_time =
&emm_information->network_daylight_saving_time; &emm_information->network_daylight_saving_time;
time_exp_t time_exp; time_exp_t xt_gmt, xt_local;
time_exp_lt(&time_exp, time_now());
rv = time_exp_gmt(&xt_gmt, time_now());
d_assert(rv == CORE_OK, return CORE_ERROR,);
rv = time_exp_lt(&xt_local, time_now());
d_assert(rv == CORE_OK, return CORE_ERROR,);
d_assert(mme_ue, return CORE_ERROR, "Null param"); d_assert(mme_ue, return CORE_ERROR, "Null param");
d_trace(5, " GMT Time[Y:M:D H:M:S GMT] - %d:%d:%d, %d:%d:%d, %d\n",
xt_gmt.tm_year, xt_gmt.tm_mon, xt_gmt.tm_mday,
xt_gmt.tm_hour, xt_gmt.tm_min, xt_gmt.tm_sec,
xt_gmt.tm_gmtoff);
d_trace(5, " LOCAL Time[Y:M:D H:M:S GMT] - %d:%d:%d, %d:%d:%d, %d\n",
xt_local.tm_year, xt_local.tm_mon, xt_local.tm_mday,
xt_local.tm_hour, xt_local.tm_min, xt_local.tm_sec,
xt_local.tm_gmtoff);
rv = nas_send_emm_to_esm(mme_ue, &attach_complete->esm_message_container); rv = nas_send_emm_to_esm(mme_ue, &attach_complete->esm_message_container);
d_assert(rv == CORE_OK, return CORE_ERROR, "nas_send_emm_to_esm failed"); d_assert(rv == CORE_OK, return CORE_ERROR, "nas_send_emm_to_esm failed");
@@ -199,22 +212,22 @@ status_t emm_handle_attach_complete(
emm_information->presencemask |= emm_information->presencemask |=
NAS_EMM_INFORMATION_UNIVERSAL_TIME_AND_LOCAL_TIME_ZONE_PRESENT; NAS_EMM_INFORMATION_UNIVERSAL_TIME_AND_LOCAL_TIME_ZONE_PRESENT;
universal_time_and_local_time_zone->year = universal_time_and_local_time_zone->year =
NAS_TIME_TO_BCD(time_exp.tm_year % 100); NAS_TIME_TO_BCD(xt_gmt.tm_year % 100);
universal_time_and_local_time_zone->mon = universal_time_and_local_time_zone->mon =
NAS_TIME_TO_BCD(time_exp.tm_mon+1); NAS_TIME_TO_BCD(xt_gmt.tm_mon+1);
universal_time_and_local_time_zone->mday = universal_time_and_local_time_zone->mday =
NAS_TIME_TO_BCD(time_exp.tm_mday); NAS_TIME_TO_BCD(xt_gmt.tm_mday);
universal_time_and_local_time_zone->hour = universal_time_and_local_time_zone->hour =
NAS_TIME_TO_BCD(time_exp.tm_hour); NAS_TIME_TO_BCD(xt_gmt.tm_hour);
universal_time_and_local_time_zone->min = NAS_TIME_TO_BCD(time_exp.tm_min); universal_time_and_local_time_zone->min = NAS_TIME_TO_BCD(xt_gmt.tm_min);
universal_time_and_local_time_zone->sec = NAS_TIME_TO_BCD(time_exp.tm_sec); universal_time_and_local_time_zone->sec = NAS_TIME_TO_BCD(xt_gmt.tm_sec);
if (time_exp.tm_gmtoff > 0) if (xt_local.tm_gmtoff >= 0)
universal_time_and_local_time_zone->sign = 0; universal_time_and_local_time_zone->sign = 0;
else else
universal_time_and_local_time_zone->sign = 1; universal_time_and_local_time_zone->sign = 1;
/* quarters of an hour */ /* quarters of an hour */
universal_time_and_local_time_zone->gmtoff = universal_time_and_local_time_zone->gmtoff =
NAS_TIME_TO_BCD(time_exp.tm_gmtoff / 900); NAS_TIME_TO_BCD(xt_local.tm_gmtoff / 900);
emm_information->presencemask |= emm_information->presencemask |=
NAS_EMM_INFORMATION_NETWORK_DAYLIGHT_SAVING_TIME_PRESENT; NAS_EMM_INFORMATION_NETWORK_DAYLIGHT_SAVING_TIME_PRESENT;

View File

@@ -1610,6 +1610,8 @@ mme_enb_t* mme_enb_add(sock_id sock, c_sockaddr_t *addr)
enb->addr = addr; enb->addr = addr;
enb->sock_type = mme_enb_sock_type(enb->sock); enb->sock_type = mme_enb_sock_type(enb->sock);
enb->outbound_streams = context_self()->parameter.sctp_streams;
list_init(&enb->enb_ue_list); list_init(&enb->enb_ue_list);
hash_set(self.enb_sock_hash, &enb->sock, sizeof(enb->sock), enb); hash_set(self.enb_sock_hash, &enb->sock, sizeof(enb->sock), enb);
@@ -1640,12 +1642,6 @@ status_t mme_enb_remove(mme_enb_t *enb)
enb_ue_remove_in_enb(enb); enb_ue_remove_in_enb(enb);
#ifdef NO_FD_LOCK
#else
#error do not use lock in socket fd
if (enb->sock_type == SOCK_STREAM)
s1ap_delete(enb->sock);
#endif
CORE_FREE(enb->addr); CORE_FREE(enb->addr);
index_free(&mme_enb_pool, enb); index_free(&mme_enb_pool, enb);
@@ -1661,12 +1657,10 @@ status_t mme_enb_remove_all()
for (hi = mme_enb_first(); hi; hi = mme_enb_next(hi)) for (hi = mme_enb_first(); hi; hi = mme_enb_next(hi))
{ {
enb = mme_enb_this(hi); enb = mme_enb_this(hi);
#ifdef NO_FD_LOCK
if (enb->sock_type == SOCK_STREAM) if (enb->sock_type == SOCK_STREAM)
s1ap_delete(enb->sock); s1ap_delete(enb->sock);
#else
#error do not use lock in socket fd
#endif
mme_enb_remove(enb); mme_enb_remove(enb);
} }
@@ -1926,10 +1920,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_ue_t* mme_ue_add(enb_ue_t *enb_ue)
{ {
mme_enb_t *enb = NULL;
mme_ue_t *mme_ue = NULL; mme_ue_t *mme_ue = NULL;
event_t e; 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); index_alloc(&mme_ue_pool, &mme_ue);
d_assert(mme_ue, return NULL, "Null param"); d_assert(mme_ue, return NULL, "Null param");
@@ -1938,6 +1935,14 @@ mme_ue_t* mme_ue_add(enb_ue_t *enb_ue)
mme_ue->mme_s11_teid = mme_ue->index; mme_ue->mme_s11_teid = mme_ue->index;
/*
* SCTP output stream identification
* Default context_self()->parameter.sctp_streams : 30
* 0 : Non UE signalling
* 1-29 : UE specific association
*/
mme_ue->ostream_id = NEXT_ID(self.ostream_id, 1, enb->outbound_streams-1);
/* Create New GUTI */ /* Create New GUTI */
mme_ue_new_guti(mme_ue); mme_ue_new_guti(mme_ue);

View File

@@ -113,6 +113,7 @@ typedef struct _mme_context_t {
/* Generator for unique identification */ /* Generator for unique identification */
c_uint32_t mme_ue_s1ap_id; /* mme_ue_s1ap_id generator */ c_uint32_t mme_ue_s1ap_id; /* mme_ue_s1ap_id generator */
c_uint16_t ostream_id; /* ostream_id generator */
/* M-TMSI Pool */ /* M-TMSI Pool */
struct { struct {
@@ -148,6 +149,8 @@ typedef struct _mme_enb_t {
sock_id sock; /* eNB S1AP Socket */ sock_id sock; /* eNB S1AP Socket */
c_sockaddr_t *addr; /* eNB S1AP Address */ c_sockaddr_t *addr; /* eNB S1AP Address */
c_uint16_t outbound_streams; /* SCTP Max number of outbound streams */
c_uint8_t num_of_supported_ta_list; c_uint8_t num_of_supported_ta_list;
tai_t supported_ta_list[MAX_NUM_OF_TAI * MAX_NUM_OF_BPLMN]; tai_t supported_ta_list[MAX_NUM_OF_TAI * MAX_NUM_OF_BPLMN];
@@ -244,6 +247,8 @@ struct _mme_ue_t {
c_uint32_t mme_s11_teid; /* MME-S11-TEID is derived from INDEX */ c_uint32_t mme_s11_teid; /* MME-S11-TEID is derived from INDEX */
c_uint32_t sgw_s11_teid; /* SGW-S11-TEID is received from SGW */ c_uint32_t sgw_s11_teid; /* SGW-S11-TEID is received from SGW */
c_uint16_t ostream_id; /* SCTP output stream identification */
/* UE Info */ /* UE Info */
tai_t tai; tai_t tai;
e_cgi_t e_cgi; e_cgi_t e_cgi;

View File

@@ -22,6 +22,8 @@ char* mme_event_get_name(event_t *e)
return "MME_EVT_S1AP_DELAYED_SEND"; return "MME_EVT_S1AP_DELAYED_SEND";
case MME_EVT_S1AP_LO_ACCEPT: case MME_EVT_S1AP_LO_ACCEPT:
return "MME_EVT_S1AP_LO_ACCEPT"; return "MME_EVT_S1AP_LO_ACCEPT";
case MME_EVT_S1AP_LO_SCTP_COMM_UP:
return "MME_EVT_S1AP_LO_SCTP_COMM_UP";
case MME_EVT_S1AP_LO_CONNREFUSED: case MME_EVT_S1AP_LO_CONNREFUSED:
return "MME_EVT_S1AP_LO_CONNREFUSED"; return "MME_EVT_S1AP_LO_CONNREFUSED";
case MME_EVT_S1AP_S1_HOLDING_TIMER: case MME_EVT_S1AP_S1_HOLDING_TIMER:

View File

@@ -16,6 +16,7 @@ typedef enum {
MME_EVT_S1AP_MESSAGE, MME_EVT_S1AP_MESSAGE,
MME_EVT_S1AP_DELAYED_SEND, MME_EVT_S1AP_DELAYED_SEND,
MME_EVT_S1AP_LO_ACCEPT, MME_EVT_S1AP_LO_ACCEPT,
MME_EVT_S1AP_LO_SCTP_COMM_UP,
MME_EVT_S1AP_LO_CONNREFUSED, MME_EVT_S1AP_LO_CONNREFUSED,
MME_EVT_S1AP_S1_HOLDING_TIMER, MME_EVT_S1AP_S1_HOLDING_TIMER,

View File

@@ -7,6 +7,7 @@
#include "gtp/gtp_xact.h" #include "gtp/gtp_xact.h"
#include "app/context.h"
#include "mme_event.h" #include "mme_event.h"
#include "mme_fd_path.h" #include "mme_fd_path.h"
@@ -42,7 +43,9 @@ status_t mme_initialize()
if (rv != CORE_OK) return CORE_ERROR; if (rv != CORE_OK) return CORE_ERROR;
#define USRSCTP_LOCAL_UDP_PORT 9899 #define USRSCTP_LOCAL_UDP_PORT 9899
rv = s1ap_init(USRSCTP_LOCAL_UDP_PORT); rv = s1ap_init(
context_self()->parameter.sctp_streams,
USRSCTP_LOCAL_UDP_PORT);
if (rv != CORE_OK) return rv; if (rv != CORE_OK) return rv;
rv = thread_create(&sm_thread, NULL, sm_main, NULL); rv = thread_create(&sm_thread, NULL, sm_main, NULL);

View File

@@ -205,7 +205,7 @@ status_t mme_s11_build_create_session_request(
/* UE Time Zone */ /* UE Time Zone */
memset(&ue_timezone, 0, sizeof(ue_timezone)); memset(&ue_timezone, 0, sizeof(ue_timezone));
time_exp_lt(&time_exp, time_now()); time_exp_lt(&time_exp, time_now());
if (time_exp.tm_gmtoff > 0) if (time_exp.tm_gmtoff >= 0)
ue_timezone.sign = 0; ue_timezone.sign = 0;
else else
ue_timezone.sign = 1; ue_timezone.sign = 1;
@@ -426,7 +426,7 @@ status_t mme_s11_build_create_bearer_response(
/* UE Time Zone */ /* UE Time Zone */
memset(&ue_timezone, 0, sizeof(ue_timezone)); memset(&ue_timezone, 0, sizeof(ue_timezone));
time_exp_lt(&time_exp, time_now()); time_exp_lt(&time_exp, time_now());
if (time_exp.tm_gmtoff > 0) if (time_exp.tm_gmtoff >= 0)
ue_timezone.sign = 0; ue_timezone.sign = 0;
else else
ue_timezone.sign = 1; ue_timezone.sign = 1;
@@ -503,7 +503,7 @@ status_t mme_s11_build_update_bearer_response(
/* UE Time Zone */ /* UE Time Zone */
memset(&ue_timezone, 0, sizeof(ue_timezone)); memset(&ue_timezone, 0, sizeof(ue_timezone));
time_exp_lt(&time_exp, time_now()); time_exp_lt(&time_exp, time_now());
if (time_exp.tm_gmtoff > 0) if (time_exp.tm_gmtoff >= 0)
ue_timezone.sign = 0; ue_timezone.sign = 0;
else else
ue_timezone.sign = 1; ue_timezone.sign = 1;
@@ -580,7 +580,7 @@ status_t mme_s11_build_delete_bearer_response(
/* UE Time Zone */ /* UE Time Zone */
memset(&ue_timezone, 0, sizeof(ue_timezone)); memset(&ue_timezone, 0, sizeof(ue_timezone));
time_exp_lt(&time_exp, time_now()); time_exp_lt(&time_exp, time_now());
if (time_exp.tm_gmtoff > 0) if (time_exp.tm_gmtoff >= 0)
ue_timezone.sign = 0; ue_timezone.sign = 0;
else else
ue_timezone.sign = 1; ue_timezone.sign = 1;

View File

@@ -1,5 +1,6 @@
#define TRACE_MODULE _mme_sm #define TRACE_MODULE _mme_sm
#include "core_debug.h" #include "core_debug.h"
#include "core_lib.h"
#include "s1ap/s1ap_message.h" #include "s1ap/s1ap_message.h"
#include "nas/nas_message.h" #include "nas/nas_message.h"
@@ -95,11 +96,12 @@ void mme_state_operational(fsm_t *s, event_t *e)
if (!enb) if (!enb)
{ {
#if USE_USRSCTP != 1 #if USE_USRSCTP != 1
status_t rv = sock_register(sock, s1ap_recv_handler, NULL); status_t rv;
rv = sock_register(sock, s1ap_recv_handler, NULL);
d_assert(rv == CORE_OK, break, "register s1ap_recv_cb failed"); d_assert(rv == CORE_OK, break, "register s1ap_recv_cb failed");
#endif #endif
enb = mme_enb_add(sock, addr);
mme_enb_t *enb = mme_enb_add(sock, addr);
d_assert(enb, break, "Null param"); d_assert(enb, break, "Null param");
} }
else else
@@ -112,6 +114,45 @@ void mme_state_operational(fsm_t *s, event_t *e)
break; 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);
enb = mme_enb_find_by_addr(addr);
if (!enb)
{
#if USE_USRSCTP != 1
status_t rv;
rv = sock_register(sock, s1ap_recv_handler, NULL);
d_assert(rv == CORE_OK, break, "register s1ap_recv_cb failed");
#endif
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);
d_trace(3, "eNB-S1 SCTP_COMM_UP[%s] Outbound Streams[%d]\n",
CORE_ADDR(addr, buf), enb->outbound_streams);
break;
}
case MME_EVT_S1AP_LO_CONNREFUSED: case MME_EVT_S1AP_LO_CONNREFUSED:
{ {
mme_enb_t *enb = NULL; mme_enb_t *enb = NULL;
@@ -123,27 +164,12 @@ void mme_state_operational(fsm_t *s, event_t *e)
addr = (c_sockaddr_t *)event_get_param2(e); addr = (c_sockaddr_t *)event_get_param2(e);
d_assert(addr, break, "Null param"); d_assert(addr, break, "Null param");
#ifdef NO_FD_LOCK
enb = mme_enb_find_by_addr(addr); enb = mme_enb_find_by_addr(addr);
#else
#error do not use lock in socket fd
/*
* <Connection Refused>
* if socket type is SOCK_STREAM,
* I'm not sure whether address is available or not.
* So, I'll use 'sock_id' at this point.
*/
if (mme_enb_sock_type(sock) == SOCK_STREAM)
enb = mme_enb_find_by_sock(sock);
else
enb = mme_enb_find_by_addr(addr);
#endif
CORE_FREE(addr); CORE_FREE(addr);
if (enb) if (enb)
{ {
d_trace(1, "eNB-S1[%x] connection refused!!!\n", d_trace(1, "eNB-S1[%x] connection refused!!!\n", enb->enb_id);
enb->enb_id);
mme_enb_remove(enb); mme_enb_remove(enb);
} }
else else
@@ -181,8 +207,7 @@ void mme_state_operational(fsm_t *s, event_t *e)
if (rv != CORE_OK) if (rv != CORE_OK)
{ {
d_print_hex(pkbuf->payload, pkbuf->len); d_print_hex(pkbuf->payload, pkbuf->len);
d_assert(0, d_assert(0, s1ap_free_pdu(&message); pkbuf_free(pkbuf); break,
s1ap_free_pdu(&message); pkbuf_free(pkbuf); break,
"Can't decode S1AP_PDU"); "Can't decode S1AP_PDU");
} }
@@ -196,12 +221,12 @@ void mme_state_operational(fsm_t *s, event_t *e)
} }
case MME_EVT_S1AP_DELAYED_SEND: case MME_EVT_S1AP_DELAYED_SEND:
{ {
mme_enb_t *enb = NULL; enb_ue_t *enb_ue = NULL;
pkbuf_t *pkbuf = NULL; pkbuf_t *pkbuf = NULL;
tm_block_id timer = 0; tm_block_id timer = 0;
enb = mme_enb_find(event_get_param1(e)); enb_ue = enb_ue_find(event_get_param1(e));
d_assert(enb, break,); d_assert(enb_ue, break,);
pkbuf = (pkbuf_t *)event_get_param2(e); pkbuf = (pkbuf_t *)event_get_param2(e);
d_assert(pkbuf, break,); d_assert(pkbuf, break,);
@@ -209,7 +234,7 @@ void mme_state_operational(fsm_t *s, event_t *e)
timer = event_get_param3(e); timer = event_get_param3(e);
d_assert(timer, pkbuf_free(pkbuf); break,); d_assert(timer, pkbuf_free(pkbuf); break,);
rv = s1ap_send_to_enb(enb, pkbuf); rv = s1ap_send_to_enb_ue(enb_ue, pkbuf);
d_assert(rv == CORE_OK, pkbuf_free(pkbuf),); d_assert(rv == CORE_OK, pkbuf_free(pkbuf),);
tm_delete(timer); tm_delete(timer);
@@ -281,8 +306,8 @@ void mme_state_operational(fsm_t *s, event_t *e)
{ {
#if 1 /* IMPLICIT_S1_RELEASE */ #if 1 /* IMPLICIT_S1_RELEASE */
/* Implcit S1 release */ /* Implcit S1 release */
d_warn("Implicit S1 release"); d_trace(5, "Implicit S1 release\n");
d_warn(" ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]", d_trace(5, " ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]\n",
mme_ue->enb_ue->enb_ue_s1ap_id, mme_ue->enb_ue->enb_ue_s1ap_id,
mme_ue->enb_ue->mme_ue_s1ap_id); mme_ue->enb_ue->mme_ue_s1ap_id);
rv = enb_ue_remove(mme_ue->enb_ue); rv = enb_ue_remove(mme_ue->enb_ue);

View File

@@ -11,16 +11,13 @@
status_t nas_send_to_enb(mme_ue_t *mme_ue, pkbuf_t *pkbuf) status_t nas_send_to_enb(mme_ue_t *mme_ue, pkbuf_t *pkbuf)
{ {
mme_enb_t *enb = NULL;
enb_ue_t *enb_ue = NULL; enb_ue_t *enb_ue = NULL;
d_assert(mme_ue, return CORE_ERROR, "Null param"); d_assert(mme_ue, return CORE_ERROR, "Null param");
enb_ue = mme_ue->enb_ue; enb_ue = mme_ue->enb_ue;
d_assert(enb_ue, return CORE_ERROR, "Null param"); d_assert(enb_ue, return CORE_ERROR, "Null param");
enb = enb_ue->enb;
d_assert(enb, return CORE_ERROR, "Null param");
return s1ap_send_to_enb(enb, pkbuf); return s1ap_send_to_enb_ue(enb_ue, pkbuf);
} }
status_t nas_send_emm_to_esm( status_t nas_send_emm_to_esm(
@@ -394,7 +391,7 @@ status_t nas_send_tau_accept(
status_t rv; status_t rv;
pkbuf_t *emmbuf = NULL; pkbuf_t *emmbuf = NULL;
d_assert(mme_ue, return CORE_ERROR, "Null param"); d_assert(mme_ue, return CORE_ERROR,);
d_trace(3, "[EMM] Tracking area update accept\n"); d_trace(3, "[EMM] Tracking area update accept\n");
d_trace(5, " IMSI[%s]\n", mme_ue->imsi_bcd); d_trace(5, " IMSI[%s]\n", mme_ue->imsi_bcd);

View File

@@ -65,11 +65,6 @@ status_t nas_security_encode(
d_assert(nas_plain_encode(&new, message) == CORE_OK, d_assert(nas_plain_encode(&new, message) == CORE_OK,
return CORE_ERROR, "NAS encoding error"); return CORE_ERROR, "NAS encoding error");
/* encode sequence number */
d_assert(CORE_OK == pkbuf_header(new, 1),
pkbuf_free(new);return CORE_ERROR, "pkbuf_header error");
*(c_uint8_t *)(new->payload) = h.sequence_number;
if (ciphered) if (ciphered)
{ {
/* encrypt NAS message */ /* encrypt NAS message */
@@ -78,6 +73,11 @@ status_t nas_security_encode(
NAS_SECURITY_DOWNLINK_DIRECTION, new); NAS_SECURITY_DOWNLINK_DIRECTION, new);
} }
/* encode sequence number */
d_assert(CORE_OK == pkbuf_header(new, 1),
pkbuf_free(new);return CORE_ERROR, "pkbuf_header error");
*(c_uint8_t *)(new->payload) = h.sequence_number;
if (integrity_protected) if (integrity_protected)
{ {
c_uint8_t mac[NAS_SECURITY_MAC_SIZE]; c_uint8_t mac[NAS_SECURITY_MAC_SIZE];
@@ -114,9 +114,11 @@ status_t nas_security_decode(mme_ue_t *mme_ue,
if (security_header_type.service_request) if (security_header_type.service_request)
{ {
#define SHORT_MAC_SIZE 2
nas_ksi_and_sequence_number_t *ksi_and_sequence_number = nas_ksi_and_sequence_number_t *ksi_and_sequence_number =
pkbuf->payload + 1; pkbuf->payload + 1;
c_uint16_t original_pkbuf_len = pkbuf->len; c_uint16_t original_pkbuf_len = pkbuf->len;
c_uint8_t original_mac[SHORT_MAC_SIZE];
c_uint8_t estimated_sequence_number; c_uint8_t estimated_sequence_number;
c_uint8_t sequence_number_high_3bit; c_uint8_t sequence_number_high_3bit;
c_uint8_t mac[NAS_SECURITY_MAC_SIZE]; c_uint8_t mac[NAS_SECURITY_MAC_SIZE];
@@ -143,10 +145,14 @@ status_t nas_security_decode(mme_ue_t *mme_ue,
mme_ue->ul_count.sqn = estimated_sequence_number; mme_ue->ul_count.sqn = estimated_sequence_number;
pkbuf->len = 2; pkbuf->len = 2;
memcpy(original_mac, pkbuf->payload + 2, SHORT_MAC_SIZE);
nas_mac_calculate(mme_ue->selected_int_algorithm, nas_mac_calculate(mme_ue->selected_int_algorithm,
mme_ue->knas_int, mme_ue->ul_count.i32, NAS_SECURITY_BEARER, mme_ue->knas_int, mme_ue->ul_count.i32, NAS_SECURITY_BEARER,
NAS_SECURITY_UPLINK_DIRECTION, pkbuf, mac); NAS_SECURITY_UPLINK_DIRECTION, pkbuf, mac);
pkbuf->len = original_pkbuf_len; pkbuf->len = original_pkbuf_len;
memcpy(pkbuf->payload + 2, original_mac, SHORT_MAC_SIZE);
if (memcmp(mac + 2, pkbuf->payload + 2, 2) != 0) if (memcmp(mac + 2, pkbuf->payload + 2, 2) != 0)
{ {
@@ -193,22 +199,17 @@ status_t nas_security_decode(mme_ue_t *mme_ue,
mme_ue->ul_count.overflow++; mme_ue->ul_count.overflow++;
mme_ue->ul_count.sqn = h->sequence_number; mme_ue->ul_count.sqn = h->sequence_number;
if (security_header_type.ciphered)
{
/* decrypt NAS message */
nas_encrypt(mme_ue->selected_enc_algorithm,
mme_ue->knas_enc, mme_ue->ul_count.i32, NAS_SECURITY_BEARER,
NAS_SECURITY_UPLINK_DIRECTION, pkbuf);
}
if (security_header_type.integrity_protected) if (security_header_type.integrity_protected)
{ {
c_uint8_t mac[NAS_SECURITY_MAC_SIZE]; c_uint8_t mac[NAS_SECURITY_MAC_SIZE];
c_uint32_t mac32; c_uint32_t mac32;
c_uint32_t original_mac = h->message_authentication_code;
/* calculate NAS MAC(message authentication code) */ /* calculate NAS MAC(message authentication code) */
nas_mac_calculate(mme_ue->selected_int_algorithm, nas_mac_calculate(mme_ue->selected_int_algorithm,
mme_ue->knas_int, mme_ue->ul_count.i32, NAS_SECURITY_BEARER, mme_ue->knas_int, mme_ue->ul_count.i32, NAS_SECURITY_BEARER,
NAS_SECURITY_UPLINK_DIRECTION, pkbuf, mac); NAS_SECURITY_UPLINK_DIRECTION, pkbuf, mac);
h->message_authentication_code = original_mac;
memcpy(&mac32, mac, NAS_SECURITY_MAC_SIZE); memcpy(&mac32, mac, NAS_SECURITY_MAC_SIZE);
if (h->message_authentication_code != mac32) if (h->message_authentication_code != mac32)
@@ -222,6 +223,14 @@ status_t nas_security_decode(mme_ue_t *mme_ue,
/* NAS EMM Header or ESM Header */ /* NAS EMM Header or ESM Header */
d_assert(CORE_OK == pkbuf_header(pkbuf, -1), d_assert(CORE_OK == pkbuf_header(pkbuf, -1),
return CORE_ERROR, "pkbuf_header error"); return CORE_ERROR, "pkbuf_header error");
if (security_header_type.ciphered)
{
/* decrypt NAS message */
nas_encrypt(mme_ue->selected_enc_algorithm,
mme_ue->knas_enc, mme_ue->ul_count.i32, NAS_SECURITY_BEARER,
NAS_SECURITY_UPLINK_DIRECTION, pkbuf);
}
} }
return CORE_OK; return CORE_OK;

View File

@@ -159,7 +159,7 @@ void s1ap_handle_s1_setup_request(mme_enb_t *enb, s1ap_message_t *message)
return, "s1ap_build_setup_failure() failed"); return, "s1ap_build_setup_failure() failed");
} }
d_assert(s1ap_send_to_enb(enb, s1apbuf) == CORE_OK,, d_assert(s1ap_send_to_enb(enb, s1apbuf, S1AP_NON_UE_SIGNALLING) == CORE_OK,,
"s1ap_send_to_enb() failed"); "s1ap_send_to_enb() failed");
} }
@@ -273,8 +273,8 @@ void s1ap_handle_initial_ue_message(mme_enb_t *enb, s1ap_message_t *message)
{ {
#if 1 /* IMPLICIT_S1_RELEASE */ #if 1 /* IMPLICIT_S1_RELEASE */
/* Implcit S1 release */ /* Implcit S1 release */
d_warn("Implicit S1 release"); d_trace(5, "Implicit S1 release\n");
d_warn(" ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]", d_trace(5, " ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]\n",
mme_ue->enb_ue->enb_ue_s1ap_id, mme_ue->enb_ue->enb_ue_s1ap_id,
mme_ue->enb_ue->mme_ue_s1ap_id); mme_ue->enb_ue->mme_ue_s1ap_id);
rv = enb_ue_remove(mme_ue->enb_ue); rv = enb_ue_remove(mme_ue->enb_ue);
@@ -974,7 +974,16 @@ void s1ap_handle_ue_context_release_complete(
d_assert(MME_UE_S1AP_ID, return,); d_assert(MME_UE_S1AP_ID, return,);
enb_ue = enb_ue_find_by_mme_ue_s1ap_id(*MME_UE_S1AP_ID); enb_ue = enb_ue_find_by_mme_ue_s1ap_id(*MME_UE_S1AP_ID);
d_assert(enb_ue, return, "No UE Context[%d]", *MME_UE_S1AP_ID); if (!enb_ue)
{
d_warn("No ENB UE Context : MME_UE_S1AP_ID[%d]", *MME_UE_S1AP_ID);
rv = s1ap_send_error_indication(enb,
MME_UE_S1AP_ID, NULL,
S1AP_Cause_PR_radioNetwork,
S1AP_CauseRadioNetwork_unknown_mme_ue_s1ap_id);
d_assert(rv == CORE_OK, return, "s1ap send error");
return;
}
mme_ue = enb_ue->mme_ue; mme_ue = enb_ue->mme_ue;
d_trace(5, " ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]\n", d_trace(5, " ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]\n",
@@ -1083,8 +1092,9 @@ void s1ap_handle_paging(mme_ue_t *mme_ue)
} }
/* Send to enb */ /* Send to enb */
d_assert(s1ap_send_to_enb(enb, s1apbuf) == CORE_OK, return, d_assert(s1ap_send_to_enb(
"s1ap send error"); enb, s1apbuf, S1AP_NON_UE_SIGNALLING) == CORE_OK,
return, "s1ap send error");
} }
} }
} }
@@ -1117,6 +1127,7 @@ void s1ap_handle_path_switch_request(
enb_ue_t *enb_ue = NULL; enb_ue_t *enb_ue = NULL;
mme_ue_t *mme_ue = NULL; mme_ue_t *mme_ue = NULL;
pkbuf_t *s1apbuf = NULL;
d_assert(enb, return,); d_assert(enb, return,);
d_assert(enb->sock, return,); d_assert(enb->sock, return,);
@@ -1187,10 +1198,14 @@ void s1ap_handle_path_switch_request(
d_error("Cannot find UE from sourceMME-UE-S1AP-ID[%d] and eNB[%s:%d]", d_error("Cannot find UE from sourceMME-UE-S1AP-ID[%d] and eNB[%s:%d]",
*MME_UE_S1AP_ID, CORE_ADDR(enb->addr, buf), enb->enb_id); *MME_UE_S1AP_ID, CORE_ADDR(enb->addr, buf), enb->enb_id);
s1ap_send_path_switch_failure(enb, rv = s1ap_build_path_switch_failure(&s1apbuf,
*ENB_UE_S1AP_ID, *MME_UE_S1AP_ID, *ENB_UE_S1AP_ID, *MME_UE_S1AP_ID,
S1AP_Cause_PR_radioNetwork, S1AP_Cause_PR_radioNetwork,
S1AP_CauseRadioNetwork_unknown_mme_ue_s1ap_id); S1AP_CauseRadioNetwork_unknown_mme_ue_s1ap_id);
d_assert(rv == CORE_OK && s1apbuf, return, "s1ap build error");
rv = s1ap_send_to_enb(enb, s1apbuf, S1AP_NON_UE_SIGNALLING);
d_assert(rv == CORE_OK,, "s1ap send error");
return; return;
} }
@@ -1207,9 +1222,13 @@ void s1ap_handle_path_switch_request(
} }
else else
{ {
s1ap_send_path_switch_failure(enb, rv = s1ap_build_path_switch_failure(&s1apbuf,
*ENB_UE_S1AP_ID, *MME_UE_S1AP_ID, *ENB_UE_S1AP_ID, *MME_UE_S1AP_ID,
S1AP_Cause_PR_nas, S1AP_CauseNas_authentication_failure); S1AP_Cause_PR_nas, S1AP_CauseNas_authentication_failure);
d_assert(rv == CORE_OK && s1apbuf, return, "s1ap build error");
rv = s1ap_send_to_enb_ue(enb_ue, s1apbuf);
d_assert(rv == CORE_OK,, "s1ap send error");
return; return;
} }

View File

@@ -68,7 +68,7 @@ static status_t s1ap_delete_list(list_t *list)
return CORE_OK; return CORE_OK;
} }
status_t s1ap_send_to_enb(mme_enb_t *enb, pkbuf_t *pkbuf) status_t s1ap_send_to_enb(mme_enb_t *enb, pkbuf_t *pkbuf, c_uint16_t stream_no)
{ {
char buf[CORE_ADDRSTRLEN]; char buf[CORE_ADDRSTRLEN];
status_t rv; status_t rv;
@@ -81,7 +81,8 @@ status_t s1ap_send_to_enb(mme_enb_t *enb, pkbuf_t *pkbuf)
CORE_ADDR(enb->addr, buf), enb->enb_id); CORE_ADDR(enb->addr, buf), enb->enb_id);
rv = s1ap_send(enb->sock, pkbuf, rv = s1ap_send(enb->sock, pkbuf,
enb->sock_type == SOCK_STREAM ? NULL : enb->addr); enb->sock_type == SOCK_STREAM ? NULL : enb->addr,
stream_no);
if (rv != CORE_OK) if (rv != CORE_OK)
{ {
d_error("s1_send error"); d_error("s1_send error");
@@ -91,12 +92,26 @@ status_t s1ap_send_to_enb(mme_enb_t *enb, pkbuf_t *pkbuf)
return CORE_OK;; return CORE_OK;;
} }
status_t s1ap_delayed_send_to_enb( status_t s1ap_send_to_enb_ue(enb_ue_t *enb_ue, pkbuf_t *pkbuf)
mme_enb_t *enb, pkbuf_t *pkbuf, c_uint32_t duration) {
mme_enb_t *enb = NULL;
mme_ue_t *mme_ue = NULL;
d_assert(enb_ue, return CORE_ERROR,);
enb = enb_ue->enb;
d_assert(enb, return CORE_ERROR,);
mme_ue = enb_ue->mme_ue;
d_assert(mme_ue, return CORE_ERROR,);
return s1ap_send_to_enb(enb, pkbuf, mme_ue->ostream_id);
}
status_t s1ap_delayed_send_to_enb_ue(
enb_ue_t *enb_ue, pkbuf_t *pkbuf, c_uint32_t duration)
{ {
tm_block_id timer = 0; tm_block_id timer = 0;
d_assert(enb, return CORE_ERROR,); d_assert(enb_ue, return CORE_ERROR,);
d_assert(pkbuf, return CORE_ERROR,); d_assert(pkbuf, return CORE_ERROR,);
if (duration) if (duration)
@@ -105,7 +120,7 @@ status_t s1ap_delayed_send_to_enb(
&mme_self()->tm_service, MME_EVT_S1AP_DELAYED_SEND, duration); &mme_self()->tm_service, MME_EVT_S1AP_DELAYED_SEND, duration);
d_assert(timer, return CORE_ERROR,); d_assert(timer, return CORE_ERROR,);
timer_set_param1(timer, (c_uintptr_t)enb->index); timer_set_param1(timer, (c_uintptr_t)enb_ue->index);
timer_set_param2(timer, (c_uintptr_t)pkbuf); timer_set_param2(timer, (c_uintptr_t)pkbuf);
timer_set_param3(timer, timer); timer_set_param3(timer, timer);
@@ -115,7 +130,10 @@ status_t s1ap_delayed_send_to_enb(
} }
else else
{ {
return s1ap_send_to_enb(enb, pkbuf); mme_enb_t *enb = NULL;
enb = enb_ue->enb;
d_assert(enb, return CORE_ERROR,);
return s1ap_send_to_enb_ue(enb_ue, pkbuf);
} }
} }
@@ -246,7 +264,6 @@ status_t s1ap_send_ue_context_release_command(
c_uint8_t action, c_uint32_t delay) c_uint8_t action, c_uint32_t delay)
{ {
status_t rv; status_t rv;
mme_enb_t *enb = NULL;
pkbuf_t *s1apbuf = NULL; pkbuf_t *s1apbuf = NULL;
d_assert(action != S1AP_UE_CTX_REL_INVALID_ACTION, return CORE_ERROR, d_assert(action != S1AP_UE_CTX_REL_INVALID_ACTION, return CORE_ERROR,
@@ -254,8 +271,6 @@ status_t s1ap_send_ue_context_release_command(
d_assert(enb_ue, return CORE_ERROR, "Null param"); d_assert(enb_ue, return CORE_ERROR, "Null param");
enb_ue->ue_ctx_rel_action = action; enb_ue->ue_ctx_rel_action = action;
enb = enb_ue->enb;
d_assert(enb, return CORE_ERROR, "Null param");
d_trace(3, "[MME] UE Context release command\n"); d_trace(3, "[MME] UE Context release command\n");
d_trace(5, " ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]\n", d_trace(5, " ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]\n",
@@ -266,7 +281,7 @@ status_t s1ap_send_ue_context_release_command(
rv = s1ap_build_ue_context_release_command(&s1apbuf, enb_ue, group, cause); rv = s1ap_build_ue_context_release_command(&s1apbuf, enb_ue, group, cause);
d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error"); d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error");
rv = s1ap_delayed_send_to_enb(enb, s1apbuf, delay); rv = s1ap_delayed_send_to_enb_ue(enb_ue, s1apbuf, delay);
d_assert(rv == CORE_OK,, "s1ap send error"); d_assert(rv == CORE_OK,, "s1ap send error");
return CORE_OK; return CORE_OK;
@@ -286,7 +301,7 @@ status_t s1ap_send_mme_configuration_transfer(
&s1apbuf, SONConfigurationTransfer); &s1apbuf, SONConfigurationTransfer);
d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error"); d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error");
rv = s1ap_send_to_enb(target_enb, s1apbuf); rv = s1ap_send_to_enb(target_enb, s1apbuf, S1AP_NON_UE_SIGNALLING);
d_assert(rv == CORE_OK,, "s1ap send error"); d_assert(rv == CORE_OK,, "s1ap send error");
return rv; return rv;
@@ -308,40 +323,17 @@ status_t s1ap_send_path_switch_ack(mme_ue_t *mme_ue)
return CORE_OK; return CORE_OK;
} }
status_t s1ap_send_path_switch_failure(mme_enb_t *enb,
c_uint32_t enb_ue_s1ap_id, c_uint32_t mme_ue_s1ap_id,
S1AP_Cause_PR group, long cause)
{
status_t rv;
pkbuf_t *s1apbuf = NULL;
d_assert(enb, return CORE_ERROR, "Null param");
rv = s1ap_build_path_switch_failure(&s1apbuf,
enb_ue_s1ap_id, mme_ue_s1ap_id, group, cause);
d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error");
rv = s1ap_send_to_enb(enb, s1apbuf);
d_assert(rv == CORE_OK,, "s1ap send error");
return rv;
}
status_t s1ap_send_handover_command(enb_ue_t *source_ue) status_t s1ap_send_handover_command(enb_ue_t *source_ue)
{ {
status_t rv; status_t rv;
pkbuf_t *s1apbuf = NULL; pkbuf_t *s1apbuf = NULL;
mme_enb_t *enb = NULL;
d_assert(source_ue, return CORE_ERROR,); d_assert(source_ue, return CORE_ERROR,);
enb = source_ue->enb;
d_assert(enb, return CORE_ERROR,);
rv = s1ap_build_handover_command(&s1apbuf, source_ue); rv = s1ap_build_handover_command(&s1apbuf, source_ue);
d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error"); d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error");
rv = s1ap_send_to_enb(enb, s1apbuf); rv = s1ap_send_to_enb_ue(source_ue, s1apbuf);
d_assert(rv == CORE_OK,, "s1ap send error"); d_assert(rv == CORE_OK,, "s1ap send error");
return rv; return rv;
@@ -353,17 +345,13 @@ status_t s1ap_send_handover_preparation_failure(
status_t rv; status_t rv;
pkbuf_t *s1apbuf = NULL; pkbuf_t *s1apbuf = NULL;
mme_enb_t *enb = NULL;
d_assert(source_ue, return CORE_ERROR,); d_assert(source_ue, return CORE_ERROR,);
d_assert(cause, return CORE_ERROR,); d_assert(cause, return CORE_ERROR,);
enb = source_ue->enb;
d_assert(enb, return CORE_ERROR,);
rv = s1ap_build_handover_preparation_failure(&s1apbuf, source_ue, cause); rv = s1ap_build_handover_preparation_failure(&s1apbuf, source_ue, cause);
d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error"); d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error");
rv = s1ap_send_to_enb(enb, s1apbuf); rv = s1ap_send_to_enb_ue(source_ue, s1apbuf);
d_assert(rv == CORE_OK,, "s1ap send error"); d_assert(rv == CORE_OK,, "s1ap send error");
return rv; return rv;
@@ -374,16 +362,12 @@ status_t s1ap_send_handover_cancel_ack(enb_ue_t *source_ue)
status_t rv; status_t rv;
pkbuf_t *s1apbuf = NULL; pkbuf_t *s1apbuf = NULL;
mme_enb_t *enb = NULL;
d_assert(source_ue, return CORE_ERROR,); d_assert(source_ue, return CORE_ERROR,);
enb = source_ue->enb;
d_assert(enb, return CORE_ERROR,);
rv = s1ap_build_handover_cancel_ack(&s1apbuf, source_ue); rv = s1ap_build_handover_cancel_ack(&s1apbuf, source_ue);
d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error"); d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error");
rv = s1ap_send_to_enb(enb, s1apbuf); rv = s1ap_send_to_enb_ue(source_ue, s1apbuf);
d_assert(rv == CORE_OK,, "s1ap send error"); d_assert(rv == CORE_OK,, "s1ap send error");
return rv; return rv;
@@ -432,7 +416,7 @@ status_t s1ap_send_handover_request(
source_totarget_transparentContainer); source_totarget_transparentContainer);
d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error"); d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error");
rv = s1ap_send_to_enb(target_enb, s1apbuf); rv = s1ap_send_to_enb_ue(target_ue, s1apbuf);
d_assert(rv == CORE_OK,, "s1ap send error"); d_assert(rv == CORE_OK,, "s1ap send error");
return rv; return rv;
@@ -446,17 +430,13 @@ status_t s1ap_send_mme_status_transfer(
status_t rv; status_t rv;
pkbuf_t *s1apbuf = NULL; pkbuf_t *s1apbuf = NULL;
mme_enb_t *enb = NULL;
d_assert(target_ue, return CORE_ERROR,); d_assert(target_ue, return CORE_ERROR,);
enb = target_ue->enb;
d_assert(enb, return CORE_ERROR,);
rv = s1ap_build_mme_status_transfer(&s1apbuf, target_ue, rv = s1ap_build_mme_status_transfer(&s1apbuf, target_ue,
enb_statustransfer_transparentContainer); enb_statustransfer_transparentContainer);
d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error"); d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error");
rv = s1ap_send_to_enb(enb, s1apbuf); rv = s1ap_send_to_enb_ue(target_ue, s1apbuf);
d_assert(rv == CORE_OK,, "s1ap send error"); d_assert(rv == CORE_OK,, "s1ap send error");
return rv; return rv;
@@ -477,7 +457,7 @@ status_t s1ap_send_error_indication(
mme_ue_s1ap_id, enb_ue_s1ap_id, group, cause); mme_ue_s1ap_id, enb_ue_s1ap_id, group, cause);
d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error"); d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error");
rv = s1ap_send_to_enb(enb, s1apbuf); rv = s1ap_send_to_enb(enb, s1apbuf, S1AP_NON_UE_SIGNALLING);
d_assert(rv == CORE_OK,, "s1ap send error"); d_assert(rv == CORE_OK,, "s1ap send error");
return rv; return rv;
@@ -495,7 +475,7 @@ status_t s1ap_send_s1_reset_ack(
rv = s1ap_build_s1_reset_ack(&s1apbuf, partOfS1_Interface); rv = s1ap_build_s1_reset_ack(&s1apbuf, partOfS1_Interface);
d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error"); d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error");
rv = s1ap_send_to_enb(enb, s1apbuf); rv = s1ap_send_to_enb(enb, s1apbuf, S1AP_NON_UE_SIGNALLING);
d_assert(rv == CORE_OK,, "s1ap send error"); d_assert(rv == CORE_OK,, "s1ap send error");
return rv; return rv;

View File

@@ -10,7 +10,9 @@
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
CORE_DECLARE(status_t) s1ap_init(c_uint16_t port); #define S1AP_NON_UE_SIGNALLING 0
CORE_DECLARE(status_t) s1ap_init(int sctp_streams, c_uint16_t port);
CORE_DECLARE(status_t) s1ap_final(); CORE_DECLARE(status_t) s1ap_final();
CORE_DECLARE(status_t) s1ap_open(); CORE_DECLARE(status_t) s1ap_open();
@@ -22,14 +24,15 @@ CORE_DECLARE(status_t) s1ap_delete(sock_id sock);
CORE_DECLARE(int) s1ap_recv_handler(sock_id sock, void *data); CORE_DECLARE(int) s1ap_recv_handler(sock_id sock, void *data);
CORE_DECLARE(status_t) s1ap_send(sock_id sock, CORE_DECLARE(status_t) s1ap_send(sock_id sock,
pkbuf_t *pkbuf, c_sockaddr_t *addr); pkbuf_t *pkbuf, c_sockaddr_t *addr, c_uint16_t stream_no);
CORE_DECLARE(status_t) s1ap_recv(sock_id id, pkbuf_t *pkbuf); CORE_DECLARE(status_t) s1ap_recv(sock_id id, pkbuf_t *pkbuf);
CORE_DECLARE(status_t) s1ap_send_to_enb(mme_enb_t *enb, pkbuf_t *pkb); CORE_DECLARE(status_t) s1ap_send_to_enb(
CORE_DECLARE(status_t) s1ap_delayed_send_to_enb(mme_enb_t *enb, mme_enb_t *enb, pkbuf_t *pkb, c_uint16_t stream_no);
CORE_DECLARE(status_t) s1ap_send_to_enb_ue(enb_ue_t *enb_ue, pkbuf_t *pkbuf);
CORE_DECLARE(status_t) s1ap_delayed_send_to_enb_ue(enb_ue_t *enb_ue,
pkbuf_t *pkbuf, c_uint32_t duration); pkbuf_t *pkbuf, c_uint32_t duration);
CORE_DECLARE(status_t) s1ap_send_to_nas( CORE_DECLARE(status_t) s1ap_send_to_nas(enb_ue_t *enb_ue,
enb_ue_t *enb_ue,
S1AP_ProcedureCode_t procedureCode, S1AP_NAS_PDU_t *nasPdu); S1AP_ProcedureCode_t procedureCode, S1AP_NAS_PDU_t *nasPdu);
CORE_DECLARE(status_t) s1ap_send_to_esm(mme_ue_t *mme_ue, pkbuf_t *esmbuf); CORE_DECLARE(status_t) s1ap_send_to_esm(mme_ue_t *mme_ue, pkbuf_t *esmbuf);
@@ -44,9 +47,6 @@ CORE_DECLARE(status_t) s1ap_send_mme_configuration_transfer(
S1AP_SONConfigurationTransfer_t *SONConfigurationTransfer); S1AP_SONConfigurationTransfer_t *SONConfigurationTransfer);
CORE_DECLARE(status_t) s1ap_send_path_switch_ack(mme_ue_t *mme_ue); CORE_DECLARE(status_t) s1ap_send_path_switch_ack(mme_ue_t *mme_ue);
CORE_DECLARE(status_t) s1ap_send_path_switch_failure(mme_enb_t *enb,
c_uint32_t enb_ue_s1ap_id, c_uint32_t mme_ue_s1ap_id,
S1AP_Cause_PR group, long cause);
CORE_DECLARE(status_t) s1ap_send_handover_command(enb_ue_t *source_ue); CORE_DECLARE(status_t) s1ap_send_handover_command(enb_ue_t *source_ue);
CORE_DECLARE(status_t) s1ap_send_handover_preparation_failure( CORE_DECLARE(status_t) s1ap_send_handover_preparation_failure(

View File

@@ -3,14 +3,19 @@
#include "core_debug.h" #include "core_debug.h"
#include "core_thread.h" #include "core_thread.h"
#if HAVE_NETINET_SCTP_H
#include <netinet/sctp.h>
#endif
#include "mme_event.h" #include "mme_event.h"
#include "s1ap_path.h" #include "s1ap_path.h"
static int s1ap_accept_handler(sock_id sock, void *data); static int s1ap_accept_handler(sock_id sock, void *data);
status_t s1ap_init(c_uint16_t port) status_t s1ap_init(int sctp_streams, c_uint16_t port)
{ {
sctp_set_num_ostreams(sctp_streams);
return CORE_OK; return CORE_OK;
} }
@@ -44,7 +49,8 @@ status_t s1ap_delete(sock_id sock)
return sock_delete(sock); return sock_delete(sock);
} }
status_t s1ap_send(sock_id sock, pkbuf_t *pkbuf, c_sockaddr_t *addr) status_t s1ap_send(sock_id sock, pkbuf_t *pkbuf,
c_sockaddr_t *addr, c_uint16_t stream_no)
{ {
int sent; int sent;
@@ -52,7 +58,7 @@ status_t s1ap_send(sock_id sock, pkbuf_t *pkbuf, c_sockaddr_t *addr)
d_assert(pkbuf, return CORE_ERROR,); d_assert(pkbuf, return CORE_ERROR,);
sent = core_sctp_sendmsg(sock, pkbuf->payload, pkbuf->len, sent = core_sctp_sendmsg(sock, pkbuf->payload, pkbuf->len,
addr, SCTP_S1AP_PPID, 0); addr, SCTP_S1AP_PPID, stream_no);
d_trace(50, "[S1AP] SEND[%d] : ", sent); d_trace(50, "[S1AP] SEND[%d] : ", sent);
d_trace_hex(50, pkbuf->payload, pkbuf->len); d_trace_hex(50, pkbuf->payload, pkbuf->len);
if (sent < 0 || sent != pkbuf->len) if (sent < 0 || sent != pkbuf->len)
@@ -69,7 +75,7 @@ status_t s1ap_recv(sock_id id, pkbuf_t *pkbuf)
{ {
int size; int size;
size = core_sctp_recvmsg(id, pkbuf->payload, MAX_SDU_LEN, NULL, NULL, NULL); size = core_sctp_recvdata(id, pkbuf->payload, MAX_SDU_LEN, NULL, NULL);
if (size <= 0) if (size <= 0)
{ {
d_error("s1ap_recv() failed"); d_error("s1ap_recv() failed");
@@ -121,11 +127,12 @@ static int s1ap_accept_handler(sock_id id, void *data)
int s1ap_recv_handler(sock_id sock, void *data) int s1ap_recv_handler(sock_id sock, void *data)
{ {
status_t rv;
pkbuf_t *pkbuf; pkbuf_t *pkbuf;
int size; int size;
event_t e; event_t e;
c_sockaddr_t *addr = NULL; c_sockaddr_t *addr = NULL;
sctp_info_t sinfo;
int flags = 0;
d_assert(sock, return -1, "Null param"); d_assert(sock, return -1, "Null param");
@@ -142,67 +149,162 @@ int s1ap_recv_handler(sock_id sock, void *data)
return -1; return -1;
} }
size = core_sctp_recvmsg(sock, pkbuf->payload, pkbuf->len, size = core_sctp_recvmsg(
NULL, NULL, NULL); sock, pkbuf->payload, pkbuf->len, NULL, &sinfo, &flags);
if (size <= 0) 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)
{ {
return 0; union sctp_notification *not =
} (union sctp_notification *)pkbuf->payload;
if (size == CORE_SCTP_REMOTE_CLOSED)
{
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); switch(not->sn_header.sn_type)
event_set_param1(&e, (c_uintptr_t)sock); {
event_set_param2(&e, (c_uintptr_t)addr); case SCTP_ASSOC_CHANGE :
#ifdef NO_FD_LOCK
sock_delete(sock);
#else
#error do not use lock in socket fd
#endif
if (mme_event_send(&e) != CORE_OK)
{ {
d_error("Event MME_EVT_S1AP_LO_CONNREFUSED failed"); d_trace(5, "SCTP_ASSOC_CHANGE:"
CORE_FREE(addr); "[T:%d, F:0x%x, S:%d, I/O:%d/%d]\n",
not->sn_assoc_change.sac_type,
not->sn_assoc_change.sac_flags,
not->sn_assoc_change.sac_state,
not->sn_assoc_change.sac_inbound_streams,
not->sn_assoc_change.sac_outbound_streams);
if (not->sn_assoc_change.sac_state == SCTP_COMM_UP)
{
d_trace(5, "SCTP_COMM_UP\n");
addr = core_calloc(1, sizeof(c_sockaddr_t));
d_assert(addr, pkbuf_free(pkbuf); return -1,);
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_SCTP_COMM_UP failed");
CORE_FREE(addr);
}
}
else if (not->sn_assoc_change.sac_state == SCTP_SHUTDOWN_COMP ||
not->sn_assoc_change.sac_state == SCTP_COMM_LOST)
{
if (not->sn_assoc_change.sac_state == SCTP_SHUTDOWN_COMP)
d_trace(5, "SCTP_SHUTDOWN_COMP\n");
if (not->sn_assoc_change.sac_state == SCTP_COMM_LOST)
d_trace(5, "SCTP_COMM_LOST\n");
addr = core_calloc(1, sizeof(c_sockaddr_t));
d_assert(addr, pkbuf_free(pkbuf); 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);
if (mme_event_send(&e) != CORE_OK)
{
d_error("Event MME_EVT_S1AP_LO_CONNREFUSED failed");
CORE_FREE(addr);
}
sock_delete(sock);
}
break;
} }
case SCTP_SHUTDOWN_EVENT :
{
d_trace(5, "SCTP_SHUTDOWN_EVENT:[T:%d, F:0x%x, L:%d]\n",
not->sn_shutdown_event.sse_type,
not->sn_shutdown_event.sse_flags,
not->sn_shutdown_event.sse_length);
return 0; addr = core_calloc(1, sizeof(c_sockaddr_t));
d_assert(addr, pkbuf_free(pkbuf); 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);
if (mme_event_send(&e) != CORE_OK)
{
d_error("Event MME_EVT_S1AP_LO_CONNREFUSED failed");
CORE_FREE(addr);
}
sock_delete(sock);
break;
}
case SCTP_PEER_ADDR_CHANGE:
{
d_warn("SCTP_PEER_ADDR_CHANGE:[T:%d, F:0x%x, S:%d]\n",
not->sn_paddr_change.spc_type,
not->sn_paddr_change.spc_flags,
not->sn_paddr_change.spc_error);
break;
}
case SCTP_REMOTE_ERROR:
{
d_warn("SCTP_REMOTE_ERROR:[T:%d, F:0x%x, S:%d]\n",
not->sn_remote_error.sre_type,
not->sn_remote_error.sre_flags,
not->sn_remote_error.sre_error);
break;
}
case SCTP_SEND_FAILED :
{
d_error("SCTP_SEND_FAILED:[T:%d, F:0x%x, S:%d]\n",
not->sn_send_failed.ssf_type,
not->sn_send_failed.ssf_flags,
not->sn_send_failed.ssf_error);
break;
}
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)
{
addr = core_calloc(1, sizeof(c_sockaddr_t));
d_assert(addr, pkbuf_free(pkbuf); return -1,);
memcpy(addr, sock_remote_addr(sock), sizeof(c_sockaddr_t));
if (errno != EAGAIN) 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)
{ {
d_error("core_sctp_recvmsg(%d) failed(%d:%s)", d_error("Event MME_EVT_S1AP_MESSAGE failed");
size, errno, strerror(errno)); pkbuf_free(pkbuf);
CORE_FREE(addr);
} }
return 0; return 0;
} }
else
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);
rv = mme_event_send(&e);
if (rv != CORE_OK)
{ {
pkbuf_free(pkbuf); d_assert(0, pkbuf_free(pkbuf); return -1,
CORE_FREE(addr); "Unknown flags : 0x%x", flags);
} }
pkbuf_free(pkbuf);
return 0; return 0;
} }

View File

@@ -37,7 +37,9 @@ static int s1ap_usrsctp_recv_handler(struct socket *sock,
static c_sockaddr_t *usrsctp_remote_addr(union sctp_sockstore *store); static c_sockaddr_t *usrsctp_remote_addr(union sctp_sockstore *store);
static void debug_printf(const char *format, ...); static void debug_printf(const char *format, ...);
status_t s1ap_init(c_uint16_t port) static int sctp_num_ostreams = -1;
status_t s1ap_init(int sctp_streams, c_uint16_t port)
{ {
usrsctp_init(port, NULL, debug_printf); usrsctp_init(port, NULL, debug_printf);
#ifdef SCTP_DEBUG #ifdef SCTP_DEBUG
@@ -45,6 +47,7 @@ status_t s1ap_init(c_uint16_t port)
#endif #endif
usrsctp_sysctl_set_sctp_blackhole(2); usrsctp_sysctl_set_sctp_blackhole(2);
usrsctp_sysctl_set_sctp_enable_sack_immediately(1); usrsctp_sysctl_set_sctp_enable_sack_immediately(1);
sctp_num_ostreams = sctp_streams;
return CORE_OK; return CORE_OK;
} }
@@ -158,7 +161,8 @@ status_t sctp_client(sock_id *new, int type, c_sockaddr_t *sa_list)
return CORE_OK; return CORE_OK;
} }
status_t s1ap_send(sock_id id, pkbuf_t *pkbuf, c_sockaddr_t *addr) status_t s1ap_send(sock_id id, pkbuf_t *pkbuf,
c_sockaddr_t *addr, c_uint16_t stream_no)
{ {
ssize_t sent; ssize_t sent;
struct socket *sock = (struct socket *)id; struct socket *sock = (struct socket *)id;
@@ -169,6 +173,7 @@ status_t s1ap_send(sock_id id, pkbuf_t *pkbuf, c_sockaddr_t *addr)
memset((void *)&sndinfo, 0, sizeof(struct sctp_sndinfo)); memset((void *)&sndinfo, 0, sizeof(struct sctp_sndinfo));
sndinfo.snd_ppid = htonl(SCTP_S1AP_PPID); sndinfo.snd_ppid = htonl(SCTP_S1AP_PPID);
sndinfo.snd_sid = stream_no;
sent = usrsctp_sendv(sock, pkbuf->payload, pkbuf->len, sent = usrsctp_sendv(sock, pkbuf->payload, pkbuf->len,
addr ? &addr->sa : NULL, addr ? 1 : 0, addr ? &addr->sa : NULL, addr ? 1 : 0,
(void *)&sndinfo, (socklen_t)sizeof(struct sctp_sndinfo), (void *)&sndinfo, (socklen_t)sizeof(struct sctp_sndinfo),
@@ -238,6 +243,8 @@ static status_t s1ap_usrsctp_socket(sock_id *new,
SCTP_ADAPTATION_INDICATION, SCTP_ADAPTATION_INDICATION,
SCTP_PARTIAL_DELIVERY_EVENT SCTP_PARTIAL_DELIVERY_EVENT
}; };
struct sctp_initmsg initmsg;
socklen_t socklen;
int i; int i;
if (!(sock = usrsctp_socket(family, type, IPPROTO_SCTP, if (!(sock = usrsctp_socket(family, type, IPPROTO_SCTP,
@@ -268,6 +275,50 @@ static status_t s1ap_usrsctp_socket(sock_id *new,
} }
} }
memset(&initmsg, 0, sizeof(struct sctp_initmsg));
socklen = sizeof(struct sctp_initmsg);
if (usrsctp_getsockopt(sock, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, &socklen) != 0)
{
d_error("getsockopt for SCTP_INITMSG failed(%d:%s)",
errno, strerror( errno ));
return CORE_ERROR;
}
d_trace(3, "Old INITMSG (numout:%d maxin:%d maxattempt:%d maxinit_to:%d)\n",
initmsg.sinit_num_ostreams,
initmsg.sinit_max_instreams,
initmsg.sinit_max_attempts,
initmsg.sinit_max_init_timeo);
/*
* INITMSG
*
* max number of input streams : 65535
* max attemtps : 4
* max initial timeout : 8 secs
*/
d_assert(sctp_num_ostreams > 1, return CORE_ERROR,
"Invalid SCTP number of output streams = %d\n", sctp_num_ostreams);
initmsg.sinit_num_ostreams = sctp_num_ostreams;
initmsg.sinit_max_instreams = 65535;
initmsg.sinit_max_attempts = 4;
initmsg.sinit_max_init_timeo = 8000;
if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_INITMSG,
&initmsg, sizeof(initmsg)) != 0)
{
d_error("setsockopt for SCTP_INITMSG failed(%d:%s)",
errno, strerror( errno ));
return CORE_ERROR;
}
d_trace(3,"New INITMSG (numout:%d maxin:%d maxattempt:%d maxinit_to:%d)\n",
initmsg.sinit_num_ostreams,
initmsg.sinit_max_instreams,
initmsg.sinit_max_attempts,
initmsg.sinit_max_init_timeo);
*new = (sock_id)sock; *new = (sock_id)sock;
return CORE_OK; return CORE_OK;
@@ -354,11 +405,14 @@ static int s1ap_usrsctp_recv_handler(struct socket *sock,
switch(not->sn_header.sn_type) switch(not->sn_header.sn_type)
{ {
case SCTP_ASSOC_CHANGE : case SCTP_ASSOC_CHANGE :
d_trace(9, "SCTP_ASSOC_CHANGE" {
"(type:0x%x, flags:0x%x, state:0x%x)\n", d_trace(5, "SCTP_ASSOC_CHANGE:"
"[T:%d, F:0x%x, S:%d, I/O:%d/%d]\n",
not->sn_assoc_change.sac_type, not->sn_assoc_change.sac_type,
not->sn_assoc_change.sac_flags, not->sn_assoc_change.sac_flags,
not->sn_assoc_change.sac_state); not->sn_assoc_change.sac_state,
not->sn_assoc_change.sac_inbound_streams,
not->sn_assoc_change.sac_outbound_streams);
if (not->sn_assoc_change.sac_state == if (not->sn_assoc_change.sac_state ==
SCTP_SHUTDOWN_COMP || SCTP_SHUTDOWN_COMP ||
@@ -369,6 +423,13 @@ static int s1ap_usrsctp_recv_handler(struct socket *sock,
usrsctp_remote_addr(&store); usrsctp_remote_addr(&store);
d_assert(addr, return 1,); d_assert(addr, return 1,);
if (not->sn_assoc_change.sac_state ==
SCTP_SHUTDOWN_COMP)
d_trace(5, "SCTP_SHUTDOWN_COMP\n");
if (not->sn_assoc_change.sac_state ==
SCTP_COMM_LOST)
d_trace(5, "SCTP_COMM_LOST\n");
event_set(&e, MME_EVT_S1AP_LO_CONNREFUSED); event_set(&e, MME_EVT_S1AP_LO_CONNREFUSED);
event_set_param1(&e, (c_uintptr_t)sock); event_set_param1(&e, (c_uintptr_t)sock);
event_set_param2(&e, (c_uintptr_t)addr); event_set_param2(&e, (c_uintptr_t)addr);
@@ -383,31 +444,33 @@ static int s1ap_usrsctp_recv_handler(struct socket *sock,
usrsctp_remote_addr(&store); usrsctp_remote_addr(&store);
d_assert(addr, return 1,); d_assert(addr, return 1,);
event_set(&e, MME_EVT_S1AP_LO_ACCEPT); d_trace(5, "SCTP_COMM_UP\n");
event_set(&e, MME_EVT_S1AP_LO_SCTP_COMM_UP);
event_set_param1(&e, (c_uintptr_t)sock); event_set_param1(&e, (c_uintptr_t)sock);
event_set_param2(&e, (c_uintptr_t)addr); 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) if (mme_event_send(&e) != CORE_OK)
{ {
CORE_FREE(addr); CORE_FREE(addr);
} }
} }
break;
case SCTP_PEER_ADDR_CHANGE:
break;
case SCTP_SEND_FAILED :
d_error("flags:0x%x - SCTP_SEND_FAILED"
"(type:0x%x, flags:0x%x, error:0x%x)\n",
flags,
not->sn_send_failed_event.ssfe_type,
not->sn_send_failed_event.ssfe_flags,
not->sn_send_failed_event.ssfe_error);
break; break;
}
case SCTP_SHUTDOWN_EVENT : case SCTP_SHUTDOWN_EVENT :
{ {
c_sockaddr_t *addr = usrsctp_remote_addr(&store); c_sockaddr_t *addr = usrsctp_remote_addr(&store);
d_assert(addr, return 1,); d_assert(addr, return 1,);
d_trace(5, "SCTP_SHUTDOWN_EVENT:"
"[T:0x%x, F:0x%x, L:0x%x]\n",
not->sn_shutdown_event.sse_type,
not->sn_shutdown_event.sse_flags,
not->sn_shutdown_event.sse_length);
event_set(&e, MME_EVT_S1AP_LO_CONNREFUSED); event_set(&e, MME_EVT_S1AP_LO_CONNREFUSED);
event_set_param1(&e, (c_uintptr_t)sock); event_set_param1(&e, (c_uintptr_t)sock);
event_set_param2(&e, (c_uintptr_t)addr); event_set_param2(&e, (c_uintptr_t)addr);
@@ -417,19 +480,34 @@ static int s1ap_usrsctp_recv_handler(struct socket *sock,
} }
break; break;
} }
case SCTP_PEER_ADDR_CHANGE:
{
d_warn("SCTP_PEER_ADDR_CHANGE:"
"[T:%d, F:0x%x, S:%d]\n",
not->sn_paddr_change.spc_type,
not->sn_paddr_change.spc_flags,
not->sn_paddr_change.spc_error);
break;
}
case SCTP_REMOTE_ERROR: case SCTP_REMOTE_ERROR:
{ {
d_warn("flags:0x%x - SCTP_REMOTE_ERROR" d_warn("SCTP_REMOTE_ERROR:[T:%d, F:0x%x, S:%d]\n",
"(type:0x%x, flags:0x%x, error:0x%x)\n",
flags,
not->sn_remote_error.sre_type, not->sn_remote_error.sre_type,
not->sn_remote_error.sre_flags, not->sn_remote_error.sre_flags,
not->sn_remote_error.sre_error); not->sn_remote_error.sre_error);
break; break;
} }
case SCTP_SEND_FAILED :
{
d_error("SCTP_SEND_FAILED:[T:%d, F:0x%x, S:%d]\n",
not->sn_send_failed.ssf_type,
not->sn_send_failed.ssf_flags,
not->sn_send_failed.ssf_error);
break;
}
default : default :
d_error("Discarding event with unknown " d_error("Discarding event with "
"flags = 0x%x, type 0x%x", "unknown flags:0x%x type:0x%x",
flags, not->sn_header.sn_type); flags, not->sn_header.sn_type);
break; break;
} }

View File

@@ -13,6 +13,9 @@ logger:
# #
# parameter: # parameter:
# #
# o Number of output streams per SCTP associations.
# sctp_streams: 30
#
# o Disable use of IPv4 addresses (only IPv6) # o Disable use of IPv4 addresses (only IPv6)
# no_ipv4: true # no_ipv4: true
# #

View File

@@ -1,7 +1,7 @@
ARG dist=ubuntu ARG dist=ubuntu
ARG tag=latest ARG tag=latest
ARG username=acetcom ARG username=acetcom
FROM ${username}/${dist}-${tag}-base FROM ${username}/${dist}-${tag}-nextepc-base
MAINTAINER Sukchan Lee <acetcom@gmail.com> MAINTAINER Sukchan Lee <acetcom@gmail.com>

View File

@@ -1,7 +1,7 @@
ARG dist=centos ARG dist=centos
ARG tag=latest ARG tag=latest
ARG username=acetcom ARG username=acetcom
FROM ${username}/${dist}-${tag}-base FROM ${username}/${dist}-${tag}-nextepc-base
MAINTAINER Sukchan Lee <acetcom@gmail.com> MAINTAINER Sukchan Lee <acetcom@gmail.com>

View File

@@ -1 +0,0 @@
ubuntu/

View File

@@ -0,0 +1,37 @@
ARG dist=debian
ARG tag=jessie
FROM ${dist}:${tag}
MAINTAINER Sukchan Lee <acetcom@gmail.com>
RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y --no-install-recommends \
autoconf \
automake \
libtool \
gcc \
flex \
bison \
git \
libsctp-dev \
libgnutls28-dev \
libgcrypt-dev \
libssl-dev \
libidn11-dev \
libyaml-dev \
build-essential \
iproute2 \
ca-certificates \
netbase \
curl \
pkg-config && \
apt-get clean
WORKDIR /root
RUN curl -SLO "https://github.com/mongodb/mongo-c-driver/releases/download/1.9.2/mongo-c-driver-1.9.2.tar.gz"; \
tar xzf mongo-c-driver-1.9.2.tar.gz; \
cd mongo-c-driver-1.9.2; \
./configure --disable-automatic-init-and-cleanup; \
make -j `nproc` install; \
ldconfig;

View File

@@ -0,0 +1 @@
../../ubuntu/bionic/dev

View File

@@ -0,0 +1 @@
stretch

View File

@@ -0,0 +1 @@
stretch

View File

@@ -0,0 +1,40 @@
ARG dist=debian
ARG tag=stable
FROM ${dist}:${tag}
MAINTAINER Sukchan Lee <acetcom@gmail.com>
ARG tag=stable
RUN apt-get update && \
apt-get install -y netselect-apt && \
apt-get clean && \
if [ "x$tag" = "xlatest" ]; then \
netselect-apt -o /etc/apt/sources.list; \
else \
netselect-apt ${tag} -o /etc/apt/sources.list; \
fi
RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y --no-install-recommends \
autoconf \
automake \
libtool \
gcc \
flex \
bison \
git \
libsctp-dev \
libgnutls28-dev \
libgcrypt-dev \
libssl-dev \
libidn11-dev \
libmongoc-dev \
libbson-dev \
libyaml-dev \
build-essential \
iproute2 \
ca-certificates \
netbase \
pkg-config && \
apt-get clean

View File

@@ -0,0 +1 @@
../../ubuntu/bionic/dev

View File

@@ -3,7 +3,7 @@ version: '3'
services: services:
run: run:
network_mode: "host" network_mode: "host"
image: ${USER}/${DIST-ubuntu}-${TAG-latest}-build image: ${USER}/${DIST-ubuntu}-${TAG-latest}-nextepc-build
depends_on: depends_on:
- mongodb - mongodb
- build - build

View File

@@ -2,7 +2,7 @@ version: '3'
services: services:
test: test:
image: ${USER}/${DIST-ubuntu}-${TAG-latest}-build image: ${USER}/${DIST-ubuntu}-${TAG-latest}-nextepc-build
depends_on: depends_on:
- mongodb - mongodb
- build - build

View File

@@ -28,7 +28,7 @@ services:
args: args:
dist: ${DIST-ubuntu} dist: ${DIST-ubuntu}
tag: ${TAG-latest} tag: ${TAG-latest}
image: ${USER}/${DIST-ubuntu}-${TAG-latest}-base image: ${USER}/${DIST-ubuntu}-${TAG-latest}-nextepc-base
command: /bin/bash -c "echo 'base' services" command: /bin/bash -c "echo 'base' services"
build: build:
@@ -38,7 +38,7 @@ services:
dist: ${DIST-ubuntu} dist: ${DIST-ubuntu}
tag: ${TAG-latest} tag: ${TAG-latest}
username: ${USER} username: ${USER}
image: ${USER}/${DIST-ubuntu}-${TAG-latest}-build image: ${USER}/${DIST-ubuntu}-${TAG-latest}-nextepc-build
depends_on: depends_on:
- base - base
command: /bin/bash -c "echo 'build' services" command: /bin/bash -c "echo 'build' services"
@@ -50,12 +50,13 @@ services:
dist: ${DIST-ubuntu} dist: ${DIST-ubuntu}
tag: ${TAG-latest} tag: ${TAG-latest}
username: ${USER} username: ${USER}
image: ${USER}/${DIST-ubuntu}-${TAG-latest}-dev image: ${USER}/${DIST-ubuntu}-${TAG-latest}-nextepc-dev
depends_on: depends_on:
- mongodb - mongodb
- base - base
environment: environment:
DB_URI: mongodb://mongodb/nextepc - DB_URI=mongodb://mongodb/nextepc
- DISPLAY=docker.for.mac.localhost:0
cap_add: cap_add:
- NET_ADMIN - NET_ADMIN
devices: devices:
@@ -65,9 +66,16 @@ services:
volumes: volumes:
- home:/home/${USER} - home:/home/${USER}
- ${HOME}:/mnt - ${HOME}:/mnt
- /tmp/.X11-unix:/tmp/.X11-unix
hostname: nextepc-dev hostname: nextepc-dev
command: /bin/bash -c "chmod 666 /dev/net/tun; /root/setup.sh; su acetcom" user: ${USER}
entrypoint: /bin/bash -c "/bin/bash -c \"$${@}\""
command: |
/bin/bash -c "
sudo chmod 666 /dev/net/tun
sudo /root/setup.sh
/bin/bash || exit 0
"
volumes: volumes:
mongodb: {} mongodb: {}
home: {} home: {}

View File

@@ -1,7 +1,7 @@
ARG dist=fedora ARG dist=fedora
ARG tag=latest ARG tag=latest
ARG username=acetcom ARG username=acetcom
FROM ${username}/${dist}-${tag}-base FROM ${username}/${dist}-${tag}-nextepc-base
MAINTAINER Sukchan Lee <acetcom@gmail.com> MAINTAINER Sukchan Lee <acetcom@gmail.com>

View File

@@ -1 +1 @@
xenial bionic

View File

@@ -18,6 +18,7 @@ RUN apt-get update && \
libgnutls28-dev \ libgnutls28-dev \
libgcrypt-dev \ libgcrypt-dev \
libssl-dev \ libssl-dev \
libidn11-dev \
libmongoc-dev \ libmongoc-dev \
libbson-dev \ libbson-dev \
libyaml-dev \ libyaml-dev \

View File

@@ -1,12 +1,13 @@
ARG dist=ubuntu ARG dist=ubuntu
ARG tag=latest ARG tag=latest
ARG username=acetcom ARG username=acetcom
FROM ${username}/${dist}-${tag}-base FROM ${username}/${dist}-${tag}-nextepc-base
MAINTAINER Sukchan Lee <acetcom@gmail.com> MAINTAINER Sukchan Lee <acetcom@gmail.com>
RUN apt-get update && \ RUN apt-get update && \
apt-get upgrade -y && \ apt-get upgrade -y && \
DEBIAN_FRONTEND=noninteractive \
apt-get install -y --no-install-recommends \ apt-get install -y --no-install-recommends \
debhelper \ debhelper \
devscripts \ devscripts \
@@ -19,6 +20,7 @@ RUN apt-get update && \
vim \ vim \
sudo \ sudo \
iputils-ping \ iputils-ping \
wireshark \
net-tools && \ net-tools && \
apt-get clean apt-get clean

View File

@@ -1 +0,0 @@
trusty

View File

@@ -1 +1 @@
xenial bionic

View File

@@ -0,0 +1 @@
bionic

View File

@@ -114,7 +114,7 @@ status_t tests1ap_enb_read(sock_id id, pkbuf_t *recvbuf)
status_t tests1ap_enb_send(sock_id id, pkbuf_t *sendbuf) status_t tests1ap_enb_send(sock_id id, pkbuf_t *sendbuf)
{ {
return s1ap_send(id, sendbuf, NULL); return s1ap_send(id, sendbuf, NULL, 0);
} }
status_t tests1ap_build_setup_req( status_t tests1ap_build_setup_req(

View File

@@ -1,6 +1,6 @@
{ {
"name": "nextepc", "name": "nextepc",
"version": "0.3.8", "version": "0.3.9",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "nextepc", "name": "nextepc",
"version": "0.3.8", "version": "0.3.9",
"description": "NextEPC", "description": "NextEPC",
"main": "index.js", "main": "index.js",
"repository": "https://github.com/acetcom/nextepc", "repository": "https://github.com/acetcom/nextepc",