1 /*****************************************************************************
3 # Copyright 2019 AT&T Intellectual Property *
4 # Copyright 2019 Nokia *
6 # Licensed under the Apache License, Version 2.0 (the "License"); *
7 # you may not use this file except in compliance with the License. *
8 # You may obtain a copy of the License at *
10 # http://www.apache.org/licenses/LICENSE-2.0 *
12 # Unless required by applicable law or agreed to in writing, software *
13 # distributed under the License is distributed on an "AS IS" BASIS, *
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
15 # See the License for the specific language governing permissions and *
16 # limitations under the License. *
18 ******************************************************************************/
21 #include <unistd.h> //for close()
23 #include <sys/socket.h>
24 #include <netinet/in.h>
25 #include <netinet/sctp.h>
26 #include <arpa/inet.h> //for inet_ntop()
29 #include "e2sim_sctp.hpp"
30 // #include "e2sim_defs.h"
33 #include <sys/types.h>
34 #include <sys/socket.h>
35 #include <netinet/sctp.h>
42 int sctp_start_server(const char *server_ip_str, const int server_port)
44 if(server_port < 1 || server_port > 65535) {
45 LOG_E("Invalid port number (%d). Valid values are between 1 and 65535.\n", server_port);
50 struct sockaddr* server_addr;
53 struct sockaddr_in server4_addr;
54 memset(&server4_addr, 0, sizeof(struct sockaddr_in));
56 struct sockaddr_in6 server6_addr;
57 memset(&server6_addr, 0, sizeof(struct sockaddr_in6));
59 if(inet_pton(AF_INET, server_ip_str, &server4_addr.sin_addr) == 1)
61 server4_addr.sin_family = AF_INET;
62 server4_addr.sin_port = htons(server_port);
64 server_addr = (struct sockaddr*)&server4_addr;
66 addr_len = sizeof(server4_addr);
68 else if(inet_pton(AF_INET6, server_ip_str, &server6_addr.sin6_addr) == 1)
70 server6_addr.sin6_family = AF_INET6;
71 server6_addr.sin6_port = htons(server_port);
73 server_addr = (struct sockaddr*)&server6_addr;
75 addr_len = sizeof(server6_addr);
78 perror("inet_pton()");
82 if((server_fd = socket(af, SOCK_STREAM, IPPROTO_SCTP)) == -1) {
87 if(bind(server_fd, server_addr, addr_len) == -1) {
92 if(listen(server_fd, SERVER_LISTEN_QUEUE_SIZE) != 0) {
97 assert(server_fd != 0);
99 LOG_I("[SCTP] Server started on %s:%d", server_ip_str, server_port);
104 int sctp_start_client(const char *server_ip_str, const int server_port)
108 struct sockaddr* server_addr;
111 struct sockaddr_in server4_addr;
112 memset(&server4_addr, 0, sizeof(struct sockaddr_in));
114 struct sockaddr_in6 server6_addr;
115 memset(&server6_addr, 0, sizeof(struct sockaddr_in6));
117 if(inet_pton(AF_INET, server_ip_str, &server4_addr.sin_addr) == 1)
119 server4_addr.sin_family = AF_INET;
120 server4_addr.sin_port = htons(server_port);
121 server_addr = (struct sockaddr*)&server4_addr;
122 addr_len = sizeof(server4_addr);
124 else if(inet_pton(AF_INET6, server_ip_str, &server6_addr.sin6_addr) == 1)
126 server6_addr.sin6_family = AF_INET6;
127 server6_addr.sin6_port = htons(server_port);
128 server_addr = (struct sockaddr*)&server6_addr;
129 addr_len = sizeof(server6_addr);
132 perror("inet_pton()");
136 if((client_fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_SCTP)) == -1)
142 //--------------------------------
143 //Bind before connect
145 if( setsockopt(client_fd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof optval) != 0 ){
146 perror("setsockopt port");
150 if( setsockopt(client_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval) != 0 ){
151 perror("setsockopt addr");
155 struct sockaddr_in6 client6_addr {};
156 client6_addr.sin6_family = AF_INET6;
157 client6_addr.sin6_port = htons(RIC_SCTP_SRC_PORT);
158 client6_addr.sin6_addr = in6addr_any;
160 LOG_I("[SCTP] Binding client socket to source port %d", RIC_SCTP_SRC_PORT);
161 if(bind(client_fd, (struct sockaddr*)&client6_addr, sizeof(client6_addr)) == -1) {
165 // end binding ---------------------
167 LOG_I("[SCTP] Connecting to server at %s:%d ...", server_ip_str, server_port);
168 if(connect(client_fd, server_addr, addr_len) == -1) {
172 assert(client_fd != 0);
174 LOG_I("[SCTP] Connection established");
179 int sctp_accept_connection(const char *server_ip_str, const int server_fd)
181 LOG_I("[SCTP] Waiting for new connection...");
183 struct sockaddr client_addr;
184 socklen_t client_addr_size;
188 client_fd = accept(server_fd, &client_addr, &client_addr_size);
195 //Retrieve client IP_ADDR
196 char client_ip6_addr[INET6_ADDRSTRLEN], client_ip4_addr[INET_ADDRSTRLEN];
197 if(strchr(server_ip_str, ':') != NULL) //IPv6
199 struct sockaddr_in6* client_ipv6 = (struct sockaddr_in6*)&client_addr;
200 inet_ntop(AF_INET6, &(client_ipv6->sin6_addr), client_ip6_addr, INET6_ADDRSTRLEN);
201 LOG_I("[SCTP] New client connected from %s", client_ip6_addr);
204 struct sockaddr_in* client_ipv4 = (struct sockaddr_in*)&client_addr;
205 inet_ntop(AF_INET, &(client_ipv4->sin_addr), client_ip4_addr, INET_ADDRSTRLEN);
206 LOG_I("[SCTP] New client connected from %s", client_ip4_addr);
212 int sctp_send_data(int &socket_fd, sctp_buffer_t &data)
214 int sent_len = send(socket_fd, (void*)(&(data.buffer[0])), data.len, 0);
217 perror("[SCTP] sctp_send_data");
224 int sctp_send_data_X2AP(int &socket_fd, sctp_buffer_t &data)
226 int sent_len = sctp_sendmsg(socket_fd, (void*)(&(data.buffer[0])), data.len,
227 NULL, 0, (uint32_t) X2AP_PPID, 0, 0, 0, 0);
230 perror("[SCTP] sctp_send_data");
237 Receive data from SCTP socket
240 0: close the connection
243 int sctp_receive_data(int &socket_fd, sctp_buffer_t &data)
245 //clear out the data before receiving
246 memset(data.buffer, 0, sizeof(data.buffer));
249 //receive data from the socket
250 int recv_len = recv(socket_fd, &(data.buffer), sizeof(data.buffer), 0);
253 perror("[SCTP] recv");
256 else if (recv_len == 0)
258 LOG_I("[SCTP] Connection closed by remote peer");
259 if(close(socket_fd) == -1)
261 perror("[SCTP] close");