X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?p=sim%2Fe2-interface.git;a=blobdiff_plain;f=e2sim%2Fe2apv1sim%2Fricsim%2Fsrc%2FSCTP%2Fe2sim_sctp.cpp;fp=e2sim%2Fe2apv1sim%2Fricsim%2Fsrc%2FSCTP%2Fe2sim_sctp.cpp;h=55547b4a82ebb08db603e4bf285e9847c392a3b2;hp=0000000000000000000000000000000000000000;hb=3ebf932d23dcbec9ed19f4a51f9d00a0a54f5124;hpb=6896318f2b4ff01b4a88b16019c3dc93b0b693f5 diff --git a/e2sim/e2apv1sim/ricsim/src/SCTP/e2sim_sctp.cpp b/e2sim/e2apv1sim/ricsim/src/SCTP/e2sim_sctp.cpp new file mode 100644 index 0000000..55547b4 --- /dev/null +++ b/e2sim/e2apv1sim/ricsim/src/SCTP/e2sim_sctp.cpp @@ -0,0 +1,297 @@ +/***************************************************************************** +# * +# Copyright 2019 AT&T Intellectual Property * +# Copyright 2019 Nokia * +# * +# Licensed under the Apache License, Version 2.0 (the "License"); * +# you may not use this file except in compliance with the License. * +# You may obtain a copy of the License at * +# * +# http://www.apache.org/licenses/LICENSE-2.0 * +# * +# Unless required by applicable law or agreed to in writing, software * +# distributed under the License is distributed on an "AS IS" BASIS, * +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * +# See the License for the specific language governing permissions and * +# limitations under the License. * +# * +******************************************************************************/ +#include +#include +#include //for close() +#include +#include +#include +#include +#include //for inet_ntop() +#include + +#include "e2sim_sctp.hpp" +// #include "e2sim_defs.h" + + +#include +#include +#include +#include +#include +#include +#include +#include + +int sctp_start_server(const char *server_ip_str, const int server_port) +{ + if(server_port < 1 || server_port > 65535) { + LOG_E("Invalid port number (%d). Valid values are between 1 and 65535.\n", server_port); + exit(1); + } + + int server_fd, af; + struct sockaddr* server_addr; + size_t addr_len; + + struct sockaddr_in server4_addr; + memset(&server4_addr, 0, sizeof(struct sockaddr_in)); + + struct sockaddr_in6 server6_addr; + memset(&server6_addr, 0, sizeof(struct sockaddr_in6)); + + if(inet_pton(AF_INET, server_ip_str, &server4_addr.sin_addr) == 1) + { + server4_addr.sin_family = AF_INET; + server4_addr.sin_port = htons(server_port); + + server_addr = (struct sockaddr*)&server4_addr; + af = AF_INET; + addr_len = sizeof(server4_addr); + } + else if(inet_pton(AF_INET6, server_ip_str, &server6_addr.sin6_addr) == 1) + { + server6_addr.sin6_family = AF_INET6; + server6_addr.sin6_port = htons(server_port); + + server_addr = (struct sockaddr*)&server6_addr; + af = AF_INET6; + addr_len = sizeof(server6_addr); + } + else { + perror("inet_pton()"); + exit(1); + } + + if((server_fd = socket(af, SOCK_STREAM, IPPROTO_SCTP)) == -1) { + perror("socket"); + exit(1); + } + + //set send_buffer + // int sendbuff = 10000; + // socklen_t optlen = sizeof(sendbuff); + // if(getsockopt(server_fd, SOL_SOCKET, SO_SNDBUF, &sendbuff, &optlen) == -1) { + // perror("getsockopt send"); + // exit(1); + // } + // else + // LOG_D("[SCTP] send buffer size = %d\n", sendbuff); + + + if(bind(server_fd, server_addr, addr_len) == -1) { + perror("bind"); + exit(1); + } + + if(listen(server_fd, SERVER_LISTEN_QUEUE_SIZE) != 0) { + perror("listen"); + exit(1); + } + + assert(server_fd != 0); + + LOG_I("[SCTP] Server started on %s:%d", server_ip_str, server_port); + + return server_fd; +} + +int sctp_start_client(const char *server_ip_str, const int server_port) +{ + int client_fd, af; + + struct sockaddr* server_addr; + size_t addr_len; + + struct sockaddr_in server4_addr; + memset(&server4_addr, 0, sizeof(struct sockaddr_in)); + + struct sockaddr_in6 server6_addr; + memset(&server6_addr, 0, sizeof(struct sockaddr_in6)); + + if(inet_pton(AF_INET, server_ip_str, &server4_addr.sin_addr) == 1) + { + server4_addr.sin_family = AF_INET; + server4_addr.sin_port = htons(server_port); + server_addr = (struct sockaddr*)&server4_addr; + addr_len = sizeof(server4_addr); + } + else if(inet_pton(AF_INET6, server_ip_str, &server6_addr.sin6_addr) == 1) + { + server6_addr.sin6_family = AF_INET6; + server6_addr.sin6_port = htons(server_port); + server_addr = (struct sockaddr*)&server6_addr; + addr_len = sizeof(server6_addr); + } + else { + perror("inet_pton()"); + exit(1); + } + + if((client_fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_SCTP)) == -1) + { + perror("socket"); + exit(1); + } + + // int sendbuff = 10000; + // socklen_t optlen = sizeof(sendbuff); + // if(getsockopt(client_fd, SOL_SOCKET, SO_SNDBUF, &sendbuff, &optlen) == -1) { + // perror("getsockopt send"); + // exit(1); + // } + // else + // LOG_D("[SCTP] send buffer size = %d\n", sendbuff); + + //-------------------------------- + //Bind before connect + auto optval = 1; + if( setsockopt(client_fd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof optval) != 0 ){ + perror("setsockopt port"); + exit(1); + } + + if( setsockopt(client_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval) != 0 ){ + perror("setsockopt addr"); + exit(1); + } + + struct sockaddr_in6 client6_addr {}; + client6_addr.sin6_family = AF_INET6; + client6_addr.sin6_port = htons(RIC_SCTP_SRC_PORT); + client6_addr.sin6_addr = in6addr_any; + + LOG_I("[SCTP] Binding client socket to source port %d", RIC_SCTP_SRC_PORT); + if(bind(client_fd, (struct sockaddr*)&client6_addr, sizeof(client6_addr)) == -1) { + perror("bind"); + exit(1); + } + // end binding --------------------- + + LOG_I("[SCTP] Connecting to server at %s:%d ...", server_ip_str, server_port); + if(connect(client_fd, server_addr, addr_len) == -1) { + perror("connect"); + exit(1); + } + assert(client_fd != 0); + + LOG_I("[SCTP] Connection established"); + + return client_fd; +} + +int sctp_accept_connection(const char *server_ip_str, const int server_fd) +{ + LOG_I("[SCTP] Waiting for new connection..."); + + struct sockaddr client_addr; + socklen_t client_addr_size; + int client_fd; + + //Blocking call + client_fd = accept(server_fd, &client_addr, &client_addr_size); + fprintf(stderr, "client fd is %d\n", client_fd); + if(client_fd == -1){ + perror("accept()"); + close(client_fd); + exit(1); + } + + //Retrieve client IP_ADDR + char client_ip6_addr[INET6_ADDRSTRLEN], client_ip4_addr[INET_ADDRSTRLEN]; + if(strchr(server_ip_str, ':') != NULL) //IPv6 + { + struct sockaddr_in6* client_ipv6 = (struct sockaddr_in6*)&client_addr; + inet_ntop(AF_INET6, &(client_ipv6->sin6_addr), client_ip6_addr, INET6_ADDRSTRLEN); + LOG_I("[SCTP] New client connected from %s", client_ip6_addr); + } + else { + struct sockaddr_in* client_ipv4 = (struct sockaddr_in*)&client_addr; + inet_ntop(AF_INET, &(client_ipv4->sin_addr), client_ip4_addr, INET_ADDRSTRLEN); + LOG_I("[SCTP] New client connected from %s", client_ip4_addr); + } + + return client_fd; +} + +int sctp_send_data(int &socket_fd, sctp_buffer_t &data) +{ + fprintf(stderr,"in sctp send data func\n"); + fprintf(stderr,"data.len is %d", data.len); + int sent_len = send(socket_fd, (void*)(&(data.buffer[0])), data.len, 0); + fprintf(stderr,"after getting sent_len\n"); + + if(sent_len == -1) { + perror("[SCTP] sctp_send_data"); + exit(1); + } + + return sent_len; +} + +int sctp_send_data_X2AP(int &socket_fd, sctp_buffer_t &data) +{ + int sent_len = sctp_sendmsg(socket_fd, (void*)(&(data.buffer[0])), data.len, + NULL, 0, (uint32_t) X2AP_PPID, 0, 0, 0, 0); + + if(sent_len == -1) { + perror("[SCTP] sctp_send_data"); + exit(1); + } + +} + +/* +Receive data from SCTP socket +Outcome of recv() +-1: exit the program +0: close the connection ++: new data +*/ +int sctp_receive_data(int &socket_fd, sctp_buffer_t &data) +{ + //clear out the data before receiving + fprintf(stderr, "receive data1\n"); + memset(data.buffer, 0, sizeof(data.buffer)); + fprintf(stderr, "receive data2\n"); + data.len = 0; + + //receive data from the socket + int recv_len = recv(socket_fd, &(data.buffer), sizeof(data.buffer), 0); + fprintf(stderr, "receive data3\n"); + + if(recv_len == -1) + { + perror("[SCTP] recv"); + exit(1); + } + else if (recv_len == 0) + { + LOG_I("[SCTP] Connection closed by remote peer"); + if(close(socket_fd) == -1) + { + perror("[SCTP] close"); + } + return -1; + } + + data.len = recv_len; + + return recv_len; +}