mirror of
				https://github.com/open5gs/open5gs.git
				synced 2025-10-31 12:03:46 +00:00 
			
		
		
		
	Compare commits
	
		
			40 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 5ee7cdd3f8 | ||
|  | 048eb3f2b2 | ||
|  | 352b02fc3e | ||
|  | 9d8695fa31 | ||
|  | 9415f5215c | ||
|  | 8c674aa134 | ||
|  | 3b9b1108b1 | ||
|  | 9aed43075c | ||
|  | 3d78f285be | ||
|  | 749d632b86 | ||
|  | 37ecb9a63b | ||
|  | 0d3af830bb | ||
|  | 7c7cfd1cbf | ||
|  | 4f1efbb521 | ||
|  | 2fb37ad797 | ||
|  | ffa6c2c15b | ||
|  | c906b243a2 | ||
|  | 056fc43d34 | ||
|  | 76c84bdaa4 | ||
|  | 6ae20c9d1c | ||
|  | fe84604fa0 | ||
|  | 85a2a64b65 | ||
|  | f5c203d3ac | ||
|  | 9a0afe035a | ||
|  | 76d8df3879 | ||
|  | 550a606306 | ||
|  | 1b21c21395 | ||
|  | 157dab73c7 | ||
|  | 7dba30b1e6 | ||
|  | 55fa0115e8 | ||
|  | 2142d406f0 | ||
|  | 9d84d4d43a | ||
|  | 57ef9697c3 | ||
|  | 280aaf9fe1 | ||
|  | 529b55c16b | ||
|  | 10f59c850b | ||
|  | e18467889c | ||
|  | 3148d4cd67 | ||
|  | de92fdd5c7 | ||
|  | f3ddfaec44 | 
| @@ -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 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) | ||||
| LIBVERSION=1:0:0 | ||||
|   | ||||
							
								
								
									
										30
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							| @@ -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 | ||||
|  | ||||
|   * Bug Fixed  | ||||
|   | ||||
							
								
								
									
										1
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							| @@ -14,6 +14,7 @@ Build-Depends: debhelper (>= 9), | ||||
|                libgnutls28-dev, | ||||
|                libgcrypt-dev, | ||||
|                libssl-dev, | ||||
|                libidn11-dev, | ||||
|                libmongoc-dev, | ||||
|                libbson-dev, | ||||
|                libyaml-dev | ||||
|   | ||||
| @@ -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__ */ | ||||
| @@ -5,8 +5,6 @@ | ||||
| #include "core_time.h" | ||||
| #include "core_list.h" | ||||
|  | ||||
| #define NO_FD_LOCK              1  /* New experimental method */ | ||||
|  | ||||
| #if HAVE_ARPA_INET_H | ||||
| #include <arpa/inet.h> | ||||
| #endif | ||||
| @@ -106,6 +104,13 @@ typedef struct ipsubnet_t { | ||||
|     c_uint32_t mask[4]; | ||||
| } ipsubnet_t; | ||||
|  | ||||
| typedef struct _sctp_info_t { | ||||
|     c_uint32_t ppid; | ||||
|     c_uint16_t stream_no; | ||||
|     c_uint16_t inbound_streams; | ||||
|     c_uint16_t outbound_streams; | ||||
| } sctp_info_t; | ||||
|  | ||||
| /* | ||||
|  * Init/Final | ||||
|  */ | ||||
| @@ -194,6 +199,8 @@ CORE_DECLARE(status_t) tcp_client(sock_id *new, c_sockaddr_t *sa_list); | ||||
| /* | ||||
|  * 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_server(sock_id *new, | ||||
|         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(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); | ||||
| #define CORE_SCTP_EAGAIN            -2 | ||||
| #define CORE_SCTP_REMOTE_CLOSED     -3 | ||||
| CORE_DECLARE(int) core_sctp_recvmsg(sock_id id, void *msg, size_t len, | ||||
|         c_sockaddr_t *from, c_uint32_t *ppid, c_uint16_t *stream_no); | ||||
|         c_sockaddr_t *from, sctp_info_t *sinfo, 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 | ||||
|  */ | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -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, | ||||
|         c_uint32_t srto_initial, c_uint32_t srto_min, c_uint32_t srto_max); | ||||
| 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); | ||||
|  | ||||
| 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 rv; | ||||
| @@ -41,10 +49,11 @@ status_t sctp_socket(sock_id *new, int family, int type) | ||||
|     /* | ||||
|      * INITMSG | ||||
|      *  | ||||
|      * max number of input streams : 65535 | ||||
|      * max attemtps : 4 | ||||
|      * 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,); | ||||
|  | ||||
|     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, | ||||
|         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; | ||||
|     int size; | ||||
|     socklen_t addrlen = sizeof(struct sockaddr_storage); | ||||
|  | ||||
|     int flags = 0; | ||||
|     struct sctp_sndrcvinfo sinfo; | ||||
|     struct sctp_sndrcvinfo sndrcvinfo; | ||||
|  | ||||
|     d_assert(id, return -1,); | ||||
|  | ||||
|     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 | ||||
|     { | ||||
|         size = sctp_recvmsg(sock->fd, msg, len, | ||||
|                     from ? &from->sa : NULL,  from ? &addrlen : NULL, | ||||
|                     &sinfo, &flags); | ||||
|         size = core_sctp_recvmsg(id, msg, len, from, sinfo, &flags); | ||||
|         if (size < 0) | ||||
|         { | ||||
|             if (errno != EAGAIN) | ||||
|             { | ||||
|                 d_error("sctp_recvmsg(%d) failed(%d:%s)", | ||||
|                         size, errno, strerror(errno)); | ||||
|             } | ||||
|  | ||||
|             d_error("core_sctp_recvdata(%d) failed(%d:%s)", | ||||
|                     size, errno, strerror(errno)); | ||||
|             return size; | ||||
|         } | ||||
|  | ||||
|         if (flags & MSG_NOTIFICATION) | ||||
|         { | ||||
|             union sctp_notification *not = (union sctp_notification *)msg; | ||||
|  | ||||
|             switch(not->sn_header.sn_type)  | ||||
|             { | ||||
|                 case SCTP_ASSOC_CHANGE : | ||||
|                     d_trace(3, "SCTP_ASSOC_CHANGE" | ||||
|                             "(type:0x%x, flags:0x%x, state:0x%x)\n",  | ||||
|                             not->sn_assoc_change.sac_type, | ||||
|                             not->sn_assoc_change.sac_flags, | ||||
|                             not->sn_assoc_change.sac_state); | ||||
|  | ||||
|                     if (not->sn_assoc_change.sac_state ==  | ||||
|                             SCTP_SHUTDOWN_COMP || | ||||
|                         not->sn_assoc_change.sac_state ==  | ||||
|                             SCTP_COMM_LOST) | ||||
|                     { | ||||
|                         return CORE_SCTP_REMOTE_CLOSED; | ||||
|                     } | ||||
|  | ||||
|                     if (not->sn_assoc_change.sac_state == SCTP_COMM_UP) | ||||
|                         d_trace(3, "SCTP_COMM_UP\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; | ||||
|             } | ||||
|             /* Nothing */ | ||||
|         } | ||||
|         else if (flags & MSG_EOR) | ||||
|         { | ||||
| @@ -267,20 +263,10 @@ int core_sctp_recvmsg(sock_id id, void *msg, size_t len, | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             return CORE_SCTP_EAGAIN; | ||||
|             d_assert(0, return -1,); | ||||
|         } | ||||
|          | ||||
|     } while(1); | ||||
|  | ||||
|     if (ppid) | ||||
|     { | ||||
|         *ppid = ntohl(sinfo.sinfo_ppid); | ||||
|     } | ||||
|      | ||||
|     if (stream_no) | ||||
|     { | ||||
|         *stream_no = sinfo.sinfo_stream; | ||||
|     } | ||||
|     } while(1); | ||||
|  | ||||
|     return size; | ||||
| } | ||||
| @@ -394,6 +380,7 @@ static status_t set_rtoinfo(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) | ||||
| { | ||||
|     sock_t *sock = (sock_t *)id; | ||||
| @@ -401,7 +388,8 @@ static status_t set_initmsg(sock_id id, | ||||
|     socklen_t socklen; | ||||
|  | ||||
|     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)); | ||||
|     socklen = sizeof(initmsg); | ||||
| @@ -419,6 +407,8 @@ static status_t set_initmsg(sock_id id, | ||||
|                 initmsg.sinit_max_attempts, | ||||
|                 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_init_timeo = sinit_max_init_timeo; | ||||
|  | ||||
|   | ||||
| @@ -9,14 +9,6 @@ | ||||
| #define MAX_SOCK_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 list_t fd_list; | ||||
| static fd_set read_fds; | ||||
| @@ -667,8 +659,6 @@ status_t sock_register(sock_id id, sock_handler handler, void *data) | ||||
|         return CORE_ERROR; | ||||
|     } | ||||
|  | ||||
|     FD_LOCK | ||||
|  | ||||
|     if (sock->fd > max_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); | ||||
|  | ||||
|     FD_UNLOCK | ||||
|  | ||||
|     return CORE_OK; | ||||
| } | ||||
|  | ||||
| @@ -687,12 +675,8 @@ status_t sock_unregister(sock_id id) | ||||
| { | ||||
|     d_assert(id, return CORE_ERROR,); | ||||
|  | ||||
|     FD_LOCK | ||||
|  | ||||
|     list_remove(&fd_list, id); | ||||
|  | ||||
|     FD_UNLOCK | ||||
|  | ||||
|     return CORE_OK; | ||||
| } | ||||
|  | ||||
| @@ -701,19 +685,15 @@ int sock_is_registered(sock_id id) | ||||
|     sock_t *sock = (sock_t *)id; | ||||
|     sock_t *iter = NULL; | ||||
|  | ||||
|     FD_LOCK | ||||
|  | ||||
|     d_assert(id, return CORE_ERROR,); | ||||
|     for (iter = list_first(&fd_list); iter != NULL; iter = list_next(iter)) | ||||
|     { | ||||
|         if (iter == sock) | ||||
|         { | ||||
|             FD_UNLOCK | ||||
|             return 1; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     FD_UNLOCK | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| @@ -810,23 +790,17 @@ static void set_fds(fd_set *fds) | ||||
| { | ||||
|     sock_t *sock = NULL; | ||||
|  | ||||
|     FD_LOCK | ||||
|  | ||||
|     FD_ZERO(fds); | ||||
|     for (sock = list_first(&fd_list); sock != NULL; sock = list_next(sock)) | ||||
|     { | ||||
|         FD_SET(sock->fd, fds); | ||||
|     } | ||||
|  | ||||
|     FD_UNLOCK | ||||
| } | ||||
|  | ||||
| static void fd_dispatch(fd_set *fds) | ||||
| { | ||||
|     sock_t *sock = NULL; | ||||
|  | ||||
|     FD_LOCK | ||||
|  | ||||
|     for (sock = list_first(&fd_list); sock != NULL; sock = list_next(sock)) | ||||
|     { | ||||
|         if (FD_ISSET(sock->fd, fds)) | ||||
| @@ -837,6 +811,4 @@ static void fd_dispatch(fd_set *fds) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     FD_UNLOCK | ||||
| } | ||||
|   | ||||
| @@ -123,8 +123,7 @@ status_t time_exp_get(c_time_t *t, time_exp_t *xt) | ||||
|     return CORE_OK; | ||||
| } | ||||
|  | ||||
| status_t time_exp_gmt_get(c_time_t *t, | ||||
|                                                time_exp_t *xt) | ||||
| status_t time_exp_gmt_get(c_time_t *t, time_exp_t *xt) | ||||
| { | ||||
|     status_t status = time_exp_get(t, xt); | ||||
|     if (status == CORE_OK) | ||||
|   | ||||
| @@ -56,6 +56,7 @@ static void *THREAD_FUNC test2_main(thread_id id, void *data) | ||||
|     char str[STRLEN]; | ||||
|     ssize_t size; | ||||
|     c_uint32_t ppid; | ||||
|     sctp_info_t sinfo; | ||||
|     c_sockaddr_t *addr; | ||||
|     c_sockaddr_t from; | ||||
|  | ||||
| @@ -66,9 +67,9 @@ static void *THREAD_FUNC test2_main(thread_id id, void *data) | ||||
|     rv = core_freeaddrinfo(addr); | ||||
|     ABTS_INT_EQUAL(tc, CORE_OK, rv); | ||||
|  | ||||
|     size = core_sctp_recvmsg(sctp, str, STRLEN, &from, &ppid, NULL); | ||||
|     size = core_sctp_recvdata(sctp, str, STRLEN, &from, &sinfo); | ||||
|     ABTS_INT_EQUAL(tc, strlen(DATASTR), size); | ||||
|     ABTS_INT_EQUAL(tc, PPID, ppid); | ||||
|     ABTS_INT_EQUAL(tc, PPID, sinfo.ppid); | ||||
|  | ||||
|     rv = sock_delete(sctp); | ||||
|     ABTS_INT_EQUAL(tc, CORE_OK, rv); | ||||
| @@ -149,7 +150,7 @@ static void sctp_test3(abts_case *tc, void *data) | ||||
|     c_sockaddr_t from, *addr; | ||||
|     char str[STRLEN]; | ||||
|     char buf[CORE_ADDRSTRLEN]; | ||||
|     c_uint32_t ppid; | ||||
|     sctp_info_t sinfo; | ||||
|  | ||||
|     rv = core_getaddrinfo(&addr, AF_INET, NULL, PORT, AI_PASSIVE); | ||||
|     ABTS_INT_EQUAL(tc, CORE_OK, rv); | ||||
| @@ -161,9 +162,9 @@ static void sctp_test3(abts_case *tc, void *data) | ||||
|     rv = thread_create(&test3_thread, NULL, test3_main, tc); | ||||
|     ABTS_INT_EQUAL(tc, CORE_OK, rv); | ||||
|  | ||||
|     size = core_sctp_recvmsg(sctp, str, STRLEN, &from, &ppid, NULL); | ||||
|     size = core_sctp_recvdata(sctp, str, STRLEN, &from, &sinfo); | ||||
|     ABTS_INT_EQUAL(tc, strlen(DATASTR), size); | ||||
|     ABTS_INT_EQUAL(tc, PPID, ppid); | ||||
|     ABTS_INT_EQUAL(tc, PPID, sinfo.ppid); | ||||
|      | ||||
|     thread_join(&rv, test3_thread); | ||||
|     ABTS_INT_EQUAL(tc, strlen(DATASTR), rv); | ||||
| @@ -181,7 +182,7 @@ static void *THREAD_FUNC test4_main(thread_id id, void *data) | ||||
|     c_sockaddr_t *addr; | ||||
|     char str[STRLEN]; | ||||
|     ssize_t size; | ||||
|     c_uint32_t ppid; | ||||
|     sctp_info_t sinfo; | ||||
|  | ||||
|     rv = core_getaddrinfo(&addr, AF_UNSPEC, NULL, PORT, 0); | ||||
|     ABTS_INT_EQUAL(tc, CORE_OK, rv); | ||||
| @@ -193,9 +194,9 @@ static void *THREAD_FUNC test4_main(thread_id id, void *data) | ||||
|     size = core_sctp_sendmsg(sctp, DATASTR, strlen(DATASTR), NULL, PPID, 0); | ||||
|     ABTS_INT_EQUAL(tc, strlen(DATASTR), size); | ||||
|  | ||||
|     size = core_sctp_recvmsg(sctp, str, STRLEN, NULL, &ppid, NULL); | ||||
|     size = core_sctp_recvdata(sctp, str, STRLEN, NULL, &sinfo); | ||||
|     ABTS_INT_EQUAL(tc, strlen(DATASTR), size); | ||||
|     ABTS_INT_EQUAL(tc, PPID, ppid); | ||||
|     ABTS_INT_EQUAL(tc, PPID, sinfo.ppid); | ||||
|  | ||||
|     rv = sock_delete(sctp); | ||||
|     ABTS_INT_EQUAL(tc, CORE_OK, rv); | ||||
| @@ -211,7 +212,7 @@ static void sctp_test4(abts_case *tc, void *data) | ||||
|     ssize_t size; | ||||
|     c_sockaddr_t from, *addr; | ||||
|     char str[STRLEN]; | ||||
|     c_uint32_t ppid; | ||||
|     sctp_info_t sinfo; | ||||
|     char buf[CORE_ADDRSTRLEN]; | ||||
|  | ||||
|     rv = core_getaddrinfo(&addr, AF_INET6, NULL, PORT, AI_PASSIVE); | ||||
| @@ -224,10 +225,10 @@ static void sctp_test4(abts_case *tc, void *data) | ||||
|     rv = thread_create(&test4_thread, NULL, test4_main, tc); | ||||
|     ABTS_INT_EQUAL(tc, CORE_OK, rv); | ||||
|  | ||||
|     size = core_sctp_recvmsg(sctp, str, STRLEN, &from, &ppid, NULL); | ||||
|     size = core_sctp_recvdata(sctp, str, STRLEN, &from, &sinfo); | ||||
|     ABTS_INT_EQUAL(tc, strlen(DATASTR), size); | ||||
|     ABTS_STR_EQUAL(tc, "::1", CORE_ADDR(&from, buf)); | ||||
|     ABTS_INT_EQUAL(tc, PPID, ppid); | ||||
|     ABTS_INT_EQUAL(tc, PPID, sinfo.ppid); | ||||
|  | ||||
|     size = core_sctp_sendmsg(sctp, DATASTR, strlen(DATASTR), &from, PPID, 0); | ||||
|     ABTS_INT_EQUAL(tc, strlen(DATASTR), size); | ||||
| @@ -247,7 +248,7 @@ static void *THREAD_FUNC test5_main(thread_id id, void *data) | ||||
|     sock_id sctp; | ||||
|     char str[STRLEN]; | ||||
|     c_sockaddr_t from, *remote_addr, *addr; | ||||
|     c_uint32_t ppid; | ||||
|     sctp_info_t sinfo; | ||||
|     ssize_t size; | ||||
|     char buf[CORE_ADDRSTRLEN]; | ||||
|  | ||||
| @@ -271,10 +272,10 @@ static void *THREAD_FUNC test5_main(thread_id id, void *data) | ||||
|             remote_addr, PPID, 0); | ||||
|     ABTS_INT_EQUAL(tc, strlen(DATASTR), size); | ||||
|  | ||||
|     size = core_sctp_recvmsg(sctp, str, STRLEN, &from, &ppid, NULL); | ||||
|     size = core_sctp_recvdata(sctp, str, STRLEN, &from, &sinfo); | ||||
|     ABTS_INT_EQUAL(tc, strlen(DATASTR), size); | ||||
|     ABTS_STR_EQUAL(tc, "::1", CORE_ADDR(&from, buf)); | ||||
|     ABTS_INT_EQUAL(tc, PPID, ppid); | ||||
|     ABTS_INT_EQUAL(tc, PPID, sinfo.ppid); | ||||
|  | ||||
|     rv = sock_delete(sctp); | ||||
|     ABTS_INT_EQUAL(tc, CORE_OK, rv); | ||||
| @@ -291,7 +292,7 @@ static void sctp_test5(abts_case *tc, void *data) | ||||
|     c_sockaddr_t from, *addr; | ||||
|     socklen_t addrlen; | ||||
|     char str[STRLEN]; | ||||
|     c_uint32_t ppid; | ||||
|     sctp_info_t sinfo; | ||||
|     char buf[CORE_ADDRSTRLEN]; | ||||
|  | ||||
|     rv = core_getaddrinfo(&addr, AF_INET6, NULL, PORT, AI_PASSIVE); | ||||
| @@ -304,12 +305,13 @@ static void sctp_test5(abts_case *tc, void *data) | ||||
|     rv = thread_create(&test5_thread, NULL, test5_main, tc); | ||||
|     ABTS_INT_EQUAL(tc, CORE_OK, rv); | ||||
|  | ||||
|     size = core_sctp_recvmsg(sctp, str, STRLEN, &from, &ppid, NULL); | ||||
|     size = core_sctp_recvdata(sctp, str, STRLEN, &from, &sinfo); | ||||
|     ABTS_INT_EQUAL(tc, strlen(DATASTR), size); | ||||
|     ABTS_STR_EQUAL(tc, "::1", CORE_ADDR(&from, buf)); | ||||
|     ABTS_INT_EQUAL(tc, PPID, ppid); | ||||
|     ABTS_INT_EQUAL(tc, PPID, sinfo.ppid); | ||||
|  | ||||
|     size = core_sctp_sendmsg(sctp, DATASTR, strlen(DATASTR), &from, ppid, 0); | ||||
|     size = core_sctp_sendmsg(sctp, DATASTR, strlen(DATASTR), &from, | ||||
|             sinfo.ppid, 0); | ||||
|     ABTS_INT_EQUAL(tc, strlen(DATASTR), size); | ||||
|  | ||||
|     thread_join(&rv, test5_thread); | ||||
|   | ||||
| @@ -632,8 +632,11 @@ status_t gtp_xact_timeout(index_t index, c_uintptr_t event) | ||||
|             pkbuf = xact->seq[xact->step-1].pkbuf; | ||||
|             d_assert(pkbuf, return CORE_ERROR, "Null param"); | ||||
|  | ||||
|             d_assert(gtp_send(xact->gnode, pkbuf) == CORE_OK, | ||||
|                     goto out, "gtp_send error"); | ||||
|             if (gtp_send(xact->gnode, pkbuf) != CORE_OK) | ||||
|             { | ||||
|                 d_error("gtp_send() failed"); | ||||
|                 goto out; | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|   | ||||
| @@ -11,6 +11,8 @@ | ||||
|  | ||||
| #include "context.h" | ||||
|  | ||||
| #define DEFAULT_SCTP_STREAMS        30 | ||||
|  | ||||
| static context_t self; | ||||
|  | ||||
| static int context_initialized = 0; | ||||
| @@ -103,6 +105,7 @@ status_t context_setup_trace_module() | ||||
| static status_t context_prepare() | ||||
| { | ||||
|     self.logger.console = -1; | ||||
|     self.parameter.sctp_streams = DEFAULT_SCTP_STREAMS; | ||||
|  | ||||
|     return CORE_OK; | ||||
| } | ||||
| @@ -256,6 +259,11 @@ status_t context_parse_config() | ||||
|                     self.parameter.no_pcrf = | ||||
|                         yaml_iter_bool(¶meter_iter); | ||||
|                 } | ||||
|                 else if (!strcmp(parameter_key, "sctp_streams")) | ||||
|                 { | ||||
|                     const char *v = yaml_iter_value(¶meter_iter); | ||||
|                     if (v) self.parameter.sctp_streams = atoi(v); | ||||
|                 } | ||||
|                 else if (!strcmp(parameter_key, "no_ipv4")) | ||||
|                 { | ||||
|                     self.parameter.no_ipv4 = | ||||
|   | ||||
| @@ -54,6 +54,7 @@ typedef struct _context_t { | ||||
|         int no_pcrf; | ||||
|  | ||||
|         /* Network */ | ||||
|         int sctp_streams; | ||||
|         int no_ipv4; | ||||
|         int no_ipv6; | ||||
|         int prefer_ipv4; | ||||
|   | ||||
| @@ -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,); | ||||
|  | ||||
|     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.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 */ | ||||
|     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_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)); | ||||
|     message.emm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM; | ||||
|   | ||||
| @@ -180,11 +180,24 @@ status_t emm_handle_attach_complete( | ||||
|     nas_daylight_saving_time_t *network_daylight_saving_time =  | ||||
|         &emm_information->network_daylight_saving_time; | ||||
|  | ||||
|     time_exp_t time_exp; | ||||
|     time_exp_lt(&time_exp, time_now()); | ||||
|     time_exp_t xt_gmt, xt_local; | ||||
|  | ||||
|     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_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); | ||||
|     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 |= | ||||
|         NAS_EMM_INFORMATION_UNIVERSAL_TIME_AND_LOCAL_TIME_ZONE_PRESENT; | ||||
|     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 = | ||||
|                 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 =  | ||||
|                 NAS_TIME_TO_BCD(time_exp.tm_mday); | ||||
|                 NAS_TIME_TO_BCD(xt_gmt.tm_mday); | ||||
|     universal_time_and_local_time_zone->hour =  | ||||
|                 NAS_TIME_TO_BCD(time_exp.tm_hour); | ||||
|     universal_time_and_local_time_zone->min = NAS_TIME_TO_BCD(time_exp.tm_min); | ||||
|     universal_time_and_local_time_zone->sec = NAS_TIME_TO_BCD(time_exp.tm_sec); | ||||
|     if (time_exp.tm_gmtoff > 0) | ||||
|                 NAS_TIME_TO_BCD(xt_gmt.tm_hour); | ||||
|     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(xt_gmt.tm_sec); | ||||
|     if (xt_local.tm_gmtoff >= 0) | ||||
|         universal_time_and_local_time_zone->sign = 0; | ||||
|     else | ||||
|         universal_time_and_local_time_zone->sign = 1; | ||||
|     /* quarters of an hour */ | ||||
|     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 |= | ||||
|         NAS_EMM_INFORMATION_NETWORK_DAYLIGHT_SAVING_TIME_PRESENT; | ||||
|   | ||||
| @@ -1610,6 +1610,8 @@ mme_enb_t* mme_enb_add(sock_id sock, c_sockaddr_t *addr) | ||||
|     enb->addr = addr; | ||||
|     enb->sock_type = mme_enb_sock_type(enb->sock); | ||||
|  | ||||
|     enb->outbound_streams = context_self()->parameter.sctp_streams; | ||||
|  | ||||
|     list_init(&enb->enb_ue_list); | ||||
|  | ||||
|     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); | ||||
|  | ||||
| #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); | ||||
|  | ||||
|     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)) | ||||
|     { | ||||
|         enb = mme_enb_this(hi); | ||||
| #ifdef NO_FD_LOCK | ||||
|  | ||||
|         if (enb->sock_type == SOCK_STREAM) | ||||
|             s1ap_delete(enb->sock); | ||||
| #else | ||||
| #error do not use lock in socket fd | ||||
| #endif | ||||
|  | ||||
|         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_enb_t *enb = NULL; | ||||
|     mme_ue_t *mme_ue = NULL; | ||||
|     event_t e; | ||||
|  | ||||
|     d_assert(enb_ue, return NULL, "Null param"); | ||||
|     d_assert(enb_ue, return NULL,); | ||||
|     enb = enb_ue->enb; | ||||
|     d_assert(enb, return NULL,); | ||||
|  | ||||
|     index_alloc(&mme_ue_pool, &mme_ue); | ||||
|     d_assert(mme_ue, return NULL, "Null param"); | ||||
| @@ -1938,6 +1935,14 @@ mme_ue_t* mme_ue_add(enb_ue_t *enb_ue) | ||||
|  | ||||
|     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 */ | ||||
|     mme_ue_new_guti(mme_ue); | ||||
|  | ||||
|   | ||||
| @@ -113,6 +113,7 @@ typedef struct _mme_context_t { | ||||
|  | ||||
|     /* Generator for unique identification */ | ||||
|     c_uint32_t      mme_ue_s1ap_id;         /* mme_ue_s1ap_id generator */ | ||||
|     c_uint16_t      ostream_id;             /* ostream_id generator */ | ||||
|  | ||||
|     /* M-TMSI Pool */ | ||||
|     struct { | ||||
| @@ -148,6 +149,8 @@ typedef struct _mme_enb_t { | ||||
|     sock_id         sock;       /* eNB S1AP Socket */ | ||||
|     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; | ||||
|     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      sgw_s11_teid;   /* SGW-S11-TEID is received from SGW */ | ||||
|  | ||||
|     c_uint16_t      ostream_id;     /* SCTP output stream identification */ | ||||
|  | ||||
|     /* UE Info */ | ||||
|     tai_t           tai; | ||||
|     e_cgi_t         e_cgi; | ||||
|   | ||||
| @@ -22,6 +22,8 @@ char* mme_event_get_name(event_t *e) | ||||
|             return "MME_EVT_S1AP_DELAYED_SEND"; | ||||
|         case 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: | ||||
|             return "MME_EVT_S1AP_LO_CONNREFUSED"; | ||||
|         case MME_EVT_S1AP_S1_HOLDING_TIMER: | ||||
|   | ||||
| @@ -16,6 +16,7 @@ typedef enum { | ||||
|     MME_EVT_S1AP_MESSAGE, | ||||
|     MME_EVT_S1AP_DELAYED_SEND, | ||||
|     MME_EVT_S1AP_LO_ACCEPT, | ||||
|     MME_EVT_S1AP_LO_SCTP_COMM_UP, | ||||
|     MME_EVT_S1AP_LO_CONNREFUSED, | ||||
|     MME_EVT_S1AP_S1_HOLDING_TIMER, | ||||
|  | ||||
|   | ||||
| @@ -7,6 +7,7 @@ | ||||
|  | ||||
| #include "gtp/gtp_xact.h" | ||||
|  | ||||
| #include "app/context.h" | ||||
| #include "mme_event.h" | ||||
|  | ||||
| #include "mme_fd_path.h" | ||||
| @@ -42,7 +43,9 @@ status_t mme_initialize() | ||||
|     if (rv != CORE_OK) return CORE_ERROR; | ||||
|  | ||||
| #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; | ||||
|  | ||||
|     rv = thread_create(&sm_thread, NULL, sm_main, NULL); | ||||
|   | ||||
| @@ -205,7 +205,7 @@ status_t mme_s11_build_create_session_request( | ||||
|     /* UE Time Zone */ | ||||
|     memset(&ue_timezone, 0, sizeof(ue_timezone)); | ||||
|     time_exp_lt(&time_exp, time_now()); | ||||
|     if (time_exp.tm_gmtoff > 0) | ||||
|     if (time_exp.tm_gmtoff >= 0) | ||||
|         ue_timezone.sign = 0; | ||||
|     else | ||||
|         ue_timezone.sign = 1; | ||||
| @@ -426,7 +426,7 @@ status_t mme_s11_build_create_bearer_response( | ||||
|     /* UE Time Zone */ | ||||
|     memset(&ue_timezone, 0, sizeof(ue_timezone)); | ||||
|     time_exp_lt(&time_exp, time_now()); | ||||
|     if (time_exp.tm_gmtoff > 0) | ||||
|     if (time_exp.tm_gmtoff >= 0) | ||||
|         ue_timezone.sign = 0; | ||||
|     else | ||||
|         ue_timezone.sign = 1; | ||||
| @@ -503,7 +503,7 @@ status_t mme_s11_build_update_bearer_response( | ||||
|     /* UE Time Zone */ | ||||
|     memset(&ue_timezone, 0, sizeof(ue_timezone)); | ||||
|     time_exp_lt(&time_exp, time_now()); | ||||
|     if (time_exp.tm_gmtoff > 0) | ||||
|     if (time_exp.tm_gmtoff >= 0) | ||||
|         ue_timezone.sign = 0; | ||||
|     else | ||||
|         ue_timezone.sign = 1; | ||||
| @@ -580,7 +580,7 @@ status_t mme_s11_build_delete_bearer_response( | ||||
|     /* UE Time Zone */ | ||||
|     memset(&ue_timezone, 0, sizeof(ue_timezone)); | ||||
|     time_exp_lt(&time_exp, time_now()); | ||||
|     if (time_exp.tm_gmtoff > 0) | ||||
|     if (time_exp.tm_gmtoff >= 0) | ||||
|         ue_timezone.sign = 0; | ||||
|     else | ||||
|         ue_timezone.sign = 1; | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| #define TRACE_MODULE _mme_sm | ||||
| #include "core_debug.h" | ||||
| #include "core_lib.h" | ||||
|  | ||||
| #include "s1ap/s1ap_message.h" | ||||
| #include "nas/nas_message.h" | ||||
| @@ -95,11 +96,12 @@ void mme_state_operational(fsm_t *s, event_t *e) | ||||
|             if (!enb) | ||||
|             { | ||||
| #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"); | ||||
| #endif | ||||
|  | ||||
|                 mme_enb_t *enb = mme_enb_add(sock, addr); | ||||
|                 enb = mme_enb_add(sock, addr); | ||||
|                 d_assert(enb, break, "Null param"); | ||||
|             } | ||||
|             else | ||||
| @@ -112,6 +114,45 @@ void mme_state_operational(fsm_t *s, event_t *e) | ||||
|  | ||||
|             break; | ||||
|         } | ||||
|         case MME_EVT_S1AP_LO_SCTP_COMM_UP: | ||||
|         { | ||||
|             mme_enb_t *enb = NULL; | ||||
|             sock_id sock = 0; | ||||
|             c_sockaddr_t *addr = NULL; | ||||
|             c_uint16_t outbound_streams = 0; | ||||
|  | ||||
|             sock = (sock_id)event_get_param1(e); | ||||
|             d_assert(sock, break, "Null param"); | ||||
|             addr = (c_sockaddr_t *)event_get_param2(e); | ||||
|             d_assert(addr, break, "Null param"); | ||||
|  | ||||
|             outbound_streams = (c_uint16_t)event_get_param4(e); | ||||
|  | ||||
|             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: | ||||
|         { | ||||
|             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); | ||||
|             d_assert(addr, break, "Null param"); | ||||
|  | ||||
| #ifdef NO_FD_LOCK | ||||
|             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); | ||||
|  | ||||
|             if (enb) | ||||
|             { | ||||
|                 d_trace(1, "eNB-S1[%x] connection refused!!!\n",  | ||||
|                         enb->enb_id); | ||||
|                 d_trace(1, "eNB-S1[%x] connection refused!!!\n", enb->enb_id); | ||||
|                 mme_enb_remove(enb); | ||||
|             } | ||||
|             else | ||||
| @@ -181,8 +207,7 @@ void mme_state_operational(fsm_t *s, event_t *e) | ||||
|             if (rv != CORE_OK) | ||||
|             { | ||||
|                 d_print_hex(pkbuf->payload, pkbuf->len); | ||||
|                 d_assert(0,  | ||||
|                         s1ap_free_pdu(&message); pkbuf_free(pkbuf); break, | ||||
|                 d_assert(0, s1ap_free_pdu(&message); pkbuf_free(pkbuf); break, | ||||
|                         "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: | ||||
|         { | ||||
|             mme_enb_t *enb = NULL; | ||||
|             enb_ue_t *enb_ue = NULL; | ||||
|             pkbuf_t *pkbuf = NULL; | ||||
|             tm_block_id timer = 0; | ||||
|  | ||||
|             enb = mme_enb_find(event_get_param1(e)); | ||||
|             d_assert(enb, break,); | ||||
|             enb_ue = enb_ue_find(event_get_param1(e)); | ||||
|             d_assert(enb_ue, break,); | ||||
|  | ||||
|             pkbuf = (pkbuf_t *)event_get_param2(e); | ||||
|             d_assert(pkbuf, break,); | ||||
| @@ -209,7 +234,7 @@ void mme_state_operational(fsm_t *s, event_t *e) | ||||
|             timer = event_get_param3(e); | ||||
|             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),); | ||||
|  | ||||
|             tm_delete(timer); | ||||
| @@ -281,8 +306,8 @@ void mme_state_operational(fsm_t *s, event_t *e) | ||||
|                 { | ||||
| #if 1 /* IMPLICIT_S1_RELEASE */ | ||||
|                    /* Implcit S1 release */ | ||||
|                     d_warn("Implicit S1 release"); | ||||
|                     d_warn("    ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]", | ||||
|                     d_trace(5, "Implicit S1 release\n"); | ||||
|                     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->mme_ue_s1ap_id); | ||||
|                     rv = enb_ue_remove(mme_ue->enb_ue); | ||||
|   | ||||
| @@ -11,16 +11,13 @@ | ||||
|  | ||||
| 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; | ||||
|  | ||||
|     d_assert(mme_ue, return CORE_ERROR, "Null param"); | ||||
|     enb_ue = mme_ue->enb_ue; | ||||
|     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( | ||||
| @@ -394,7 +391,7 @@ status_t nas_send_tau_accept( | ||||
|     status_t rv; | ||||
|     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(5, "    IMSI[%s]\n", mme_ue->imsi_bcd); | ||||
|   | ||||
| @@ -65,11 +65,6 @@ status_t nas_security_encode( | ||||
|         d_assert(nas_plain_encode(&new, message) == CORE_OK,  | ||||
|                 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) | ||||
|         { | ||||
|             /* encrypt NAS message */ | ||||
| @@ -78,6 +73,11 @@ status_t nas_security_encode( | ||||
|                 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) | ||||
|         { | ||||
|             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) | ||||
|     { | ||||
| #define SHORT_MAC_SIZE 2 | ||||
|         nas_ksi_and_sequence_number_t *ksi_and_sequence_number = | ||||
|             pkbuf->payload + 1; | ||||
|         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 sequence_number_high_3bit; | ||||
|         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; | ||||
|  | ||||
|         pkbuf->len = 2; | ||||
|         memcpy(original_mac, pkbuf->payload + 2, SHORT_MAC_SIZE); | ||||
|  | ||||
|         nas_mac_calculate(mme_ue->selected_int_algorithm, | ||||
|             mme_ue->knas_int, mme_ue->ul_count.i32, NAS_SECURITY_BEARER, | ||||
|             NAS_SECURITY_UPLINK_DIRECTION, pkbuf, mac); | ||||
|  | ||||
|         pkbuf->len = original_pkbuf_len; | ||||
|         memcpy(pkbuf->payload + 2, original_mac, SHORT_MAC_SIZE); | ||||
|  | ||||
|         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.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) | ||||
|         { | ||||
|             c_uint8_t mac[NAS_SECURITY_MAC_SIZE]; | ||||
|             c_uint32_t mac32; | ||||
|             c_uint32_t original_mac = h->message_authentication_code; | ||||
|  | ||||
|             /* calculate NAS MAC(message authentication code) */ | ||||
|             nas_mac_calculate(mme_ue->selected_int_algorithm, | ||||
|                 mme_ue->knas_int, mme_ue->ul_count.i32, NAS_SECURITY_BEARER,  | ||||
|                 NAS_SECURITY_UPLINK_DIRECTION, pkbuf, mac); | ||||
|             h->message_authentication_code = original_mac; | ||||
|  | ||||
|             memcpy(&mac32, mac, NAS_SECURITY_MAC_SIZE); | ||||
|             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 */ | ||||
|         d_assert(CORE_OK == pkbuf_header(pkbuf, -1), | ||||
|             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; | ||||
|   | ||||
| @@ -159,7 +159,7 @@ void s1ap_handle_s1_setup_request(mme_enb_t *enb, s1ap_message_t *message) | ||||
|                 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"); | ||||
| } | ||||
|  | ||||
| @@ -273,8 +273,8 @@ void s1ap_handle_initial_ue_message(mme_enb_t *enb, s1ap_message_t *message) | ||||
|                 { | ||||
| #if 1  /* IMPLICIT_S1_RELEASE */ | ||||
|                    /* Implcit S1 release */ | ||||
|                     d_warn("Implicit S1 release"); | ||||
|                     d_warn("    ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]", | ||||
|                     d_trace(5, "Implicit S1 release\n"); | ||||
|                     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->mme_ue_s1ap_id); | ||||
|                     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,); | ||||
|     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; | ||||
|  | ||||
|     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 */ | ||||
|                 d_assert(s1ap_send_to_enb(enb, s1apbuf) == CORE_OK, return, | ||||
|                         "s1ap send error"); | ||||
|                 d_assert(s1ap_send_to_enb( | ||||
|                         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; | ||||
|     mme_ue_t *mme_ue = NULL; | ||||
|     pkbuf_t *s1apbuf = NULL; | ||||
|  | ||||
|     d_assert(enb, 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]", | ||||
|                 *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, | ||||
|                 S1AP_Cause_PR_radioNetwork, | ||||
|                 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; | ||||
|     } | ||||
|  | ||||
| @@ -1207,9 +1222,13 @@ void s1ap_handle_path_switch_request( | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         s1ap_send_path_switch_failure(enb, | ||||
|         rv = s1ap_build_path_switch_failure(&s1apbuf, | ||||
|                 *ENB_UE_S1AP_ID, *MME_UE_S1AP_ID, | ||||
|                 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; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -68,7 +68,7 @@ static status_t s1ap_delete_list(list_t *list) | ||||
|     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]; | ||||
|     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); | ||||
|  | ||||
|     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) | ||||
|     { | ||||
|         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;; | ||||
| } | ||||
|  | ||||
| status_t s1ap_delayed_send_to_enb( | ||||
|         mme_enb_t *enb, pkbuf_t *pkbuf, c_uint32_t duration) | ||||
| status_t s1ap_send_to_enb_ue(enb_ue_t *enb_ue, pkbuf_t *pkbuf) | ||||
| { | ||||
|     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; | ||||
|  | ||||
|     d_assert(enb, return CORE_ERROR,); | ||||
|     d_assert(enb_ue, return CORE_ERROR,); | ||||
|     d_assert(pkbuf, return CORE_ERROR,); | ||||
|          | ||||
|     if (duration) | ||||
| @@ -105,7 +120,7 @@ status_t s1ap_delayed_send_to_enb( | ||||
|                 &mme_self()->tm_service, MME_EVT_S1AP_DELAYED_SEND, duration); | ||||
|         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_param3(timer, timer); | ||||
|  | ||||
| @@ -115,7 +130,10 @@ status_t s1ap_delayed_send_to_enb( | ||||
|     } | ||||
|     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); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -133,7 +151,7 @@ status_t s1ap_send_to_esm(mme_ue_t *mme_ue, pkbuf_t *esmbuf) | ||||
|  | ||||
|     return CORE_OK; | ||||
| } | ||||
|  | ||||
|   | ||||
| status_t s1ap_send_to_nas(enb_ue_t *enb_ue, | ||||
|         S1AP_ProcedureCode_t procedureCode, S1AP_NAS_PDU_t *nasPdu) | ||||
| { | ||||
| @@ -246,7 +264,6 @@ status_t s1ap_send_ue_context_release_command( | ||||
|     c_uint8_t action, c_uint32_t delay) | ||||
| { | ||||
|     status_t rv; | ||||
|     mme_enb_t *enb = NULL; | ||||
|     pkbuf_t *s1apbuf = NULL; | ||||
|  | ||||
|     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"); | ||||
|     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(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); | ||||
|     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"); | ||||
|  | ||||
|     return CORE_OK; | ||||
| @@ -286,7 +301,7 @@ status_t s1ap_send_mme_configuration_transfer( | ||||
|             &s1apbuf, SONConfigurationTransfer); | ||||
|     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"); | ||||
|  | ||||
|     return rv; | ||||
| @@ -308,40 +323,17 @@ status_t s1ap_send_path_switch_ack(mme_ue_t *mme_ue) | ||||
|     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 rv; | ||||
|     pkbuf_t *s1apbuf = NULL; | ||||
|  | ||||
|     mme_enb_t *enb = NULL; | ||||
|  | ||||
|     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); | ||||
|     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"); | ||||
|  | ||||
|     return rv; | ||||
| @@ -353,17 +345,13 @@ status_t s1ap_send_handover_preparation_failure( | ||||
|     status_t rv; | ||||
|     pkbuf_t *s1apbuf = NULL; | ||||
|  | ||||
|     mme_enb_t *enb = NULL; | ||||
|  | ||||
|     d_assert(source_ue, 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); | ||||
|     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"); | ||||
|  | ||||
|     return rv; | ||||
| @@ -374,16 +362,12 @@ status_t s1ap_send_handover_cancel_ack(enb_ue_t *source_ue) | ||||
|     status_t rv; | ||||
|     pkbuf_t *s1apbuf = NULL; | ||||
|  | ||||
|     mme_enb_t *enb = NULL; | ||||
|  | ||||
|     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); | ||||
|     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"); | ||||
|  | ||||
|     return rv; | ||||
| @@ -432,7 +416,7 @@ status_t s1ap_send_handover_request( | ||||
|             source_totarget_transparentContainer); | ||||
|     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"); | ||||
|  | ||||
|     return rv; | ||||
| @@ -446,17 +430,13 @@ status_t s1ap_send_mme_status_transfer( | ||||
|     status_t rv; | ||||
|     pkbuf_t *s1apbuf = NULL; | ||||
|  | ||||
|     mme_enb_t *enb = NULL; | ||||
|  | ||||
|     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, | ||||
|             enb_statustransfer_transparentContainer); | ||||
|     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"); | ||||
|  | ||||
|     return rv; | ||||
| @@ -477,7 +457,7 @@ status_t s1ap_send_error_indication( | ||||
|             mme_ue_s1ap_id, enb_ue_s1ap_id, group, cause); | ||||
|     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"); | ||||
|  | ||||
|     return rv; | ||||
| @@ -495,7 +475,7 @@ status_t s1ap_send_s1_reset_ack( | ||||
|     rv = s1ap_build_s1_reset_ack(&s1apbuf, partOfS1_Interface); | ||||
|     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"); | ||||
|  | ||||
|     return rv; | ||||
|   | ||||
| @@ -10,7 +10,9 @@ | ||||
| extern "C" { | ||||
| #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_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(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_send_to_enb(mme_enb_t *enb, pkbuf_t *pkb); | ||||
| CORE_DECLARE(status_t) s1ap_delayed_send_to_enb(mme_enb_t *enb, | ||||
| CORE_DECLARE(status_t) s1ap_send_to_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); | ||||
| CORE_DECLARE(status_t) s1ap_send_to_nas( | ||||
|         enb_ue_t *enb_ue, | ||||
| CORE_DECLARE(status_t) s1ap_send_to_nas(enb_ue_t *enb_ue, | ||||
|         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); | ||||
|  | ||||
| @@ -44,9 +47,6 @@ CORE_DECLARE(status_t) s1ap_send_mme_configuration_transfer( | ||||
|         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_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_preparation_failure( | ||||
|   | ||||
| @@ -3,14 +3,19 @@ | ||||
| #include "core_debug.h" | ||||
| #include "core_thread.h" | ||||
|  | ||||
| #if HAVE_NETINET_SCTP_H | ||||
| #include <netinet/sctp.h> | ||||
| #endif | ||||
|  | ||||
| #include "mme_event.h" | ||||
|  | ||||
| #include "s1ap_path.h" | ||||
|  | ||||
| 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; | ||||
| } | ||||
|  | ||||
| @@ -44,7 +49,8 @@ status_t s1ap_delete(sock_id 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; | ||||
|  | ||||
| @@ -52,7 +58,7 @@ status_t s1ap_send(sock_id sock, pkbuf_t *pkbuf, c_sockaddr_t *addr) | ||||
|     d_assert(pkbuf, return CORE_ERROR,); | ||||
|  | ||||
|     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_hex(50, pkbuf->payload, pkbuf->len); | ||||
|     if (sent < 0 || sent != pkbuf->len) | ||||
| @@ -69,7 +75,7 @@ status_t s1ap_recv(sock_id id, pkbuf_t *pkbuf) | ||||
| { | ||||
|     int size; | ||||
|  | ||||
|     size = core_sctp_recvmsg(id, pkbuf->payload, MAX_SDU_LEN, NULL, NULL, NULL); | ||||
|     size = core_sctp_recvdata(id, pkbuf->payload, MAX_SDU_LEN, NULL, NULL); | ||||
|     if (size <= 0) | ||||
|     { | ||||
|         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) | ||||
| { | ||||
|     status_t rv; | ||||
|     pkbuf_t *pkbuf; | ||||
|     int size; | ||||
|     event_t e; | ||||
|     c_sockaddr_t *addr = NULL; | ||||
|     sctp_info_t sinfo; | ||||
|     int flags = 0; | ||||
|  | ||||
|     d_assert(sock, return -1, "Null param"); | ||||
|  | ||||
| @@ -142,67 +149,162 @@ int s1ap_recv_handler(sock_id sock, void *data) | ||||
|         return -1; | ||||
|     } | ||||
|  | ||||
|     size = core_sctp_recvmsg(sock, pkbuf->payload, pkbuf->len, | ||||
|             NULL, NULL, NULL); | ||||
|     if (size <= 0) | ||||
|     size = core_sctp_recvmsg( | ||||
|             sock, pkbuf->payload, pkbuf->len, NULL, &sinfo, &flags); | ||||
|     if (size < 0) | ||||
|     { | ||||
|         pkbuf_free(pkbuf); | ||||
|         d_error("core_sctp_recvmsg(%d) failed(%d:%s)", | ||||
|                 size, errno, strerror(errno)); | ||||
|         return size; | ||||
|     } | ||||
|  | ||||
|         if (size == CORE_SCTP_EAGAIN) | ||||
|         { | ||||
|             return 0; | ||||
|         } | ||||
|         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)); | ||||
|     if (flags & MSG_NOTIFICATION) | ||||
|     { | ||||
|         union sctp_notification *not = | ||||
|             (union sctp_notification *)pkbuf->payload; | ||||
|  | ||||
|             event_set(&e, MME_EVT_S1AP_LO_CONNREFUSED); | ||||
|             event_set_param1(&e, (c_uintptr_t)sock); | ||||
|             event_set_param2(&e, (c_uintptr_t)addr); | ||||
| #ifdef NO_FD_LOCK | ||||
|             sock_delete(sock); | ||||
| #else | ||||
| #error do not use lock in socket fd | ||||
| #endif | ||||
|             if (mme_event_send(&e) != CORE_OK) | ||||
|         switch(not->sn_header.sn_type)  | ||||
|         { | ||||
|             case SCTP_ASSOC_CHANGE : | ||||
|             { | ||||
|                 d_error("Event MME_EVT_S1AP_LO_CONNREFUSED failed"); | ||||
|                 CORE_FREE(addr); | ||||
|                 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_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)", | ||||
|                     size, errno, strerror(errno)); | ||||
|             d_error("Event MME_EVT_S1AP_MESSAGE failed"); | ||||
|             pkbuf_free(pkbuf); | ||||
|             CORE_FREE(addr); | ||||
|         } | ||||
|  | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     pkbuf->len = size; | ||||
|  | ||||
|     d_trace(50, "[S1AP] RECV : "); | ||||
|     d_trace_hex(50, pkbuf->payload, pkbuf->len); | ||||
|  | ||||
|     addr = core_calloc(1, sizeof(c_sockaddr_t)); | ||||
|     d_assert(addr, return -1,); | ||||
|     memcpy(addr, sock_remote_addr(sock), sizeof(c_sockaddr_t)); | ||||
|  | ||||
|     event_set(&e, MME_EVT_S1AP_MESSAGE); | ||||
|     event_set_param1(&e, (c_uintptr_t)sock); | ||||
|     event_set_param2(&e, (c_uintptr_t)addr); | ||||
|     event_set_param3(&e, (c_uintptr_t)pkbuf); | ||||
|     rv = mme_event_send(&e); | ||||
|     if (rv != CORE_OK) | ||||
|     else | ||||
|     { | ||||
|         pkbuf_free(pkbuf); | ||||
|         CORE_FREE(addr); | ||||
|         d_assert(0, pkbuf_free(pkbuf); return -1, | ||||
|                 "Unknown flags : 0x%x", flags); | ||||
|     } | ||||
|      | ||||
|  | ||||
|     pkbuf_free(pkbuf); | ||||
|     return 0; | ||||
| } | ||||
|   | ||||
| @@ -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 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); | ||||
| #ifdef SCTP_DEBUG | ||||
| @@ -45,6 +47,7 @@ status_t s1ap_init(c_uint16_t port) | ||||
| #endif | ||||
|     usrsctp_sysctl_set_sctp_blackhole(2); | ||||
|     usrsctp_sysctl_set_sctp_enable_sack_immediately(1); | ||||
|     sctp_num_ostreams = sctp_streams; | ||||
|  | ||||
|     return CORE_OK; | ||||
| } | ||||
| @@ -158,7 +161,8 @@ status_t sctp_client(sock_id *new, int type, c_sockaddr_t *sa_list) | ||||
|     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; | ||||
|     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)); | ||||
|     sndinfo.snd_ppid = htonl(SCTP_S1AP_PPID); | ||||
|     sndinfo.snd_sid = stream_no; | ||||
|     sent = usrsctp_sendv(sock, pkbuf->payload, pkbuf->len,  | ||||
|             addr ? &addr->sa : NULL, addr ? 1 : 0, | ||||
|             (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_PARTIAL_DELIVERY_EVENT | ||||
|     }; | ||||
|     struct sctp_initmsg initmsg; | ||||
|     socklen_t socklen; | ||||
|     int i; | ||||
|  | ||||
|     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; | ||||
|  | ||||
|     return CORE_OK; | ||||
| @@ -354,11 +405,14 @@ static int s1ap_usrsctp_recv_handler(struct socket *sock, | ||||
|                 switch(not->sn_header.sn_type)  | ||||
|                 { | ||||
|                     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_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 ==  | ||||
|                                 SCTP_SHUTDOWN_COMP || | ||||
| @@ -369,6 +423,13 @@ static int s1ap_usrsctp_recv_handler(struct socket *sock, | ||||
|                                 usrsctp_remote_addr(&store); | ||||
|                             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_param1(&e, (c_uintptr_t)sock); | ||||
|                             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); | ||||
|                             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_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) | ||||
|                             { | ||||
|                                 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; | ||||
|                     } | ||||
|                     case SCTP_SHUTDOWN_EVENT : | ||||
|                     { | ||||
|                         c_sockaddr_t *addr = usrsctp_remote_addr(&store); | ||||
|                         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_param1(&e, (c_uintptr_t)sock); | ||||
|                         event_set_param2(&e, (c_uintptr_t)addr); | ||||
| @@ -417,19 +480,34 @@ static int s1ap_usrsctp_recv_handler(struct socket *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("flags:0x%x - SCTP_REMOTE_ERROR" | ||||
|                                 "(type:0x%x, flags:0x%x, error:0x%x)\n", | ||||
|                                 flags, | ||||
|                         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",  | ||||
|                         d_error("Discarding event with " | ||||
|                                 "unknown flags:0x%x type:0x%x", | ||||
|                                 flags, not->sn_header.sn_type); | ||||
|                         break; | ||||
|                 } | ||||
|   | ||||
| @@ -13,6 +13,9 @@ logger: | ||||
| #  | ||||
| # parameter: | ||||
| # | ||||
| #  o Number of output streams per SCTP associations. | ||||
| #      sctp_streams: 30 | ||||
| # | ||||
| #  o Disable use of IPv4 addresses (only IPv6) | ||||
| #      no_ipv4: true | ||||
| # | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| ARG dist=ubuntu | ||||
| ARG tag=latest | ||||
| ARG username=acetcom | ||||
| FROM ${username}/${dist}-${tag}-base | ||||
| FROM ${username}/${dist}-${tag}-nextepc-base | ||||
|  | ||||
| MAINTAINER Sukchan Lee <acetcom@gmail.com> | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| ARG dist=centos | ||||
| ARG tag=latest | ||||
| ARG username=acetcom | ||||
| FROM ${username}/${dist}-${tag}-base | ||||
| FROM ${username}/${dist}-${tag}-nextepc-base | ||||
|  | ||||
| MAINTAINER Sukchan Lee <acetcom@gmail.com> | ||||
|  | ||||
|   | ||||
| @@ -1 +0,0 @@ | ||||
| ubuntu/ | ||||
							
								
								
									
										37
									
								
								support/docker/debian/jessie/base/Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								support/docker/debian/jessie/base/Dockerfile
									
									
									
									
									
										Normal 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; | ||||
							
								
								
									
										1
									
								
								support/docker/debian/jessie/dev
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								support/docker/debian/jessie/dev
									
									
									
									
									
										Symbolic link
									
								
							| @@ -0,0 +1 @@ | ||||
| ../../ubuntu/bionic/dev | ||||
							
								
								
									
										1
									
								
								support/docker/debian/latest
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								support/docker/debian/latest
									
									
									
									
									
										Symbolic link
									
								
							| @@ -0,0 +1 @@ | ||||
| stretch | ||||
							
								
								
									
										1
									
								
								support/docker/debian/stable
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								support/docker/debian/stable
									
									
									
									
									
										Symbolic link
									
								
							| @@ -0,0 +1 @@ | ||||
| stretch | ||||
							
								
								
									
										40
									
								
								support/docker/debian/stretch/base/Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								support/docker/debian/stretch/base/Dockerfile
									
									
									
									
									
										Normal 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 | ||||
							
								
								
									
										1
									
								
								support/docker/debian/stretch/dev
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								support/docker/debian/stretch/dev
									
									
									
									
									
										Symbolic link
									
								
							| @@ -0,0 +1 @@ | ||||
| ../../ubuntu/bionic/dev | ||||
| @@ -3,7 +3,7 @@ version: '3' | ||||
| services: | ||||
|   run: | ||||
|     network_mode: "host" | ||||
|     image: ${USER}/${DIST-ubuntu}-${TAG-latest}-build | ||||
|     image: ${USER}/${DIST-ubuntu}-${TAG-latest}-nextepc-build | ||||
|     depends_on: | ||||
|       - mongodb | ||||
|       - build | ||||
|   | ||||
| @@ -2,7 +2,7 @@ version: '3' | ||||
|  | ||||
| services: | ||||
|   test: | ||||
|     image: ${USER}/${DIST-ubuntu}-${TAG-latest}-build | ||||
|     image: ${USER}/${DIST-ubuntu}-${TAG-latest}-nextepc-build | ||||
|     depends_on: | ||||
|       - mongodb | ||||
|       - build | ||||
|   | ||||
| @@ -28,7 +28,7 @@ services: | ||||
|       args: | ||||
|         dist: ${DIST-ubuntu} | ||||
|         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" | ||||
|  | ||||
|   build: | ||||
| @@ -38,7 +38,7 @@ services: | ||||
|         dist: ${DIST-ubuntu} | ||||
|         tag: ${TAG-latest} | ||||
|         username: ${USER} | ||||
|     image: ${USER}/${DIST-ubuntu}-${TAG-latest}-build | ||||
|     image: ${USER}/${DIST-ubuntu}-${TAG-latest}-nextepc-build | ||||
|     depends_on: | ||||
|       - base | ||||
|     command: /bin/bash -c "echo 'build' services" | ||||
| @@ -50,12 +50,13 @@ services: | ||||
|         dist: ${DIST-ubuntu} | ||||
|         tag: ${TAG-latest} | ||||
|         username: ${USER} | ||||
|     image: ${USER}/${DIST-ubuntu}-${TAG-latest}-dev | ||||
|     image: ${USER}/${DIST-ubuntu}-${TAG-latest}-nextepc-dev | ||||
|     depends_on: | ||||
|       - mongodb | ||||
|       - base | ||||
|     environment: | ||||
|       DB_URI: mongodb://mongodb/nextepc | ||||
|       - DB_URI=mongodb://mongodb/nextepc | ||||
|       - DISPLAY=docker.for.mac.localhost:0 | ||||
|     cap_add: | ||||
|       - NET_ADMIN | ||||
|     devices: | ||||
| @@ -65,9 +66,16 @@ services: | ||||
|     volumes: | ||||
|       - home:/home/${USER} | ||||
|       - ${HOME}:/mnt | ||||
|       - /tmp/.X11-unix:/tmp/.X11-unix | ||||
|     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: | ||||
|   mongodb: {} | ||||
|   home: {} | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| ARG dist=fedora | ||||
| ARG tag=latest | ||||
| ARG username=acetcom | ||||
| FROM ${username}/${dist}-${tag}-base | ||||
| FROM ${username}/${dist}-${tag}-nextepc-base | ||||
|  | ||||
| MAINTAINER Sukchan Lee <acetcom@gmail.com> | ||||
|  | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| xenial | ||||
| bionic | ||||
| @@ -18,6 +18,7 @@ RUN apt-get update && \ | ||||
|         libgnutls28-dev \ | ||||
|         libgcrypt-dev \ | ||||
|         libssl-dev \ | ||||
|         libidn11-dev \ | ||||
|         libmongoc-dev \ | ||||
|         libbson-dev \ | ||||
|         libyaml-dev \ | ||||
| @@ -1,12 +1,13 @@ | ||||
| ARG dist=ubuntu | ||||
| ARG tag=latest | ||||
| ARG username=acetcom | ||||
| FROM ${username}/${dist}-${tag}-base | ||||
| FROM ${username}/${dist}-${tag}-nextepc-base | ||||
| 
 | ||||
| MAINTAINER Sukchan Lee <acetcom@gmail.com> | ||||
| 
 | ||||
| RUN apt-get update && \ | ||||
|     apt-get upgrade -y && \ | ||||
|     DEBIAN_FRONTEND=noninteractive \ | ||||
|     apt-get install -y --no-install-recommends \ | ||||
|         debhelper \ | ||||
|         devscripts \ | ||||
| @@ -19,6 +20,7 @@ RUN apt-get update && \ | ||||
|         vim \ | ||||
|         sudo \ | ||||
|         iputils-ping \ | ||||
|         wireshark \ | ||||
|         net-tools && \ | ||||
|     apt-get clean | ||||
| 
 | ||||
| @@ -1 +0,0 @@ | ||||
| trusty | ||||
| @@ -1 +1 @@ | ||||
| xenial | ||||
| bionic | ||||
							
								
								
									
										1
									
								
								support/docker/ubuntu/xenial
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								support/docker/ubuntu/xenial
									
									
									
									
									
										Symbolic link
									
								
							| @@ -0,0 +1 @@ | ||||
| bionic | ||||
| @@ -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) | ||||
| { | ||||
|     return s1ap_send(id, sendbuf, NULL); | ||||
|     return s1ap_send(id, sendbuf, NULL, 0); | ||||
| } | ||||
|  | ||||
| status_t tests1ap_build_setup_req( | ||||
|   | ||||
							
								
								
									
										2
									
								
								webui/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								webui/package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "nextepc", | ||||
|   "version": "0.3.8", | ||||
|   "version": "0.3.9", | ||||
|   "lockfileVersion": 1, | ||||
|   "requires": true, | ||||
|   "dependencies": { | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "nextepc", | ||||
|   "version": "0.3.8", | ||||
|   "version": "0.3.9", | ||||
|   "description": "NextEPC", | ||||
|   "main": "index.js", | ||||
|   "repository": "https://github.com/acetcom/nextepc", | ||||
|   | ||||
		Reference in New Issue
	
	Block a user