| /* |
| * |
| * 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 <stdio.h> |
| #include <stdlib.h> |
| #include <time.h> |
| #include <string.h> |
| #include <assert.h> |
| #include <unistd.h> //for close() |
| #include <arpa/inet.h> //for inet_ntop() |
| |
| #include "e2sim_defs.h" |
| #include "e2sim_sctp.h" |
| #include "x2ap_message_handler.h" |
| |
| //OSN 2019 |
| #include "Pendulum_asn_codec.h" |
| #include "adruino_serial.h" |
| |
| //rmr |
| #include <errno.h> |
| #include <sys/epoll.h> |
| #include <rmr/rmr.h> |
| #include "rmr_wrapper.h" |
| |
| static void pendulum_control_E2_agent(int client_fd) |
| { |
| printf("--------------------------------------\n"); |
| printf("E2 AGENT - START PENDULUM CONTROL\n"); |
| printf("--------------------------------------\n"); |
| |
| uint8_t *buffer; |
| uint32_t len; |
| clock_t begin; |
| double rtt; //ms |
| |
| uint8_t recv_buf[MAX_SCTP_BUFFER]; |
| int recv_len; |
| |
| double angle; |
| double torque; |
| long sqn; |
| int count = 0; |
| |
| //serial |
| int serial_fd; |
| char serial_buffer[MAX_SERIAL_BUFFER]; |
| serial_fd = start_serial_inferface(DEFAULT_BAUDRATE, DEFAULT_SERIAL_PORT); |
| |
| int MSG_NUM = 10; |
| |
| // printf("Enter number of messages: "); |
| // scanf("%d", &MSG_NUM); |
| // |
| // //fgets(serial_buffer, MAX_SERIAL_BUFFER, stdin); |
| // serialport_write(serial_fd, serial_buffer); |
| |
| serialport_write(serial_fd, "hello arduino\n"); |
| |
| // for(int i = 0; i < MSG_NUM; i++) |
| while(1) |
| { |
| |
| printf("----------------\n"); |
| count += 1; |
| buffer = NULL; |
| len = 0; |
| |
| //1.Read from serial |
| serial_readline(serial_fd, serial_buffer, MAX_SERIAL_BUFFER); |
| if(serial_buffer[0] == '\n') |
| { |
| //printf("RECEIVED EOL\n"); |
| continue; |
| } |
| //printf("[Adruino] %s", serial_buffer); |
| |
| begin = clock(); |
| |
| //2. Encode pendulum angle to ASN1 message |
| len = pendulum_create_asn_msg(&buffer, 0, 0, 0, serial_buffer); |
| |
| //3. Send ASN1 message to socket |
| if(sctp_send_to_socket(client_fd, buffer, (size_t)len) > 0){ |
| printf("Sent ASN1 message to E2 Termination\n"); |
| } |
| |
| // 4. Receive response from E2 Termination |
| memset(recv_buf, 0, sizeof(recv_buf)); |
| recv_len = 0; |
| recv_len = recv(client_fd, &recv_buf, sizeof(recv_buf), 0); |
| if(recv_len == -1) |
| { |
| perror("recv()"); |
| return; |
| } |
| |
| char *recv_str; |
| recv_str = pendulum_get_strval(recv_buf, recv_len); |
| printf("Received response message #%d from xApp: %s\n", count, recv_str); |
| |
| // 5. TODO: Send response to serial |
| serial_writeline(serial_fd, recv_str); |
| |
| //serialport_write(serial_fd, "hello\n"); |
| |
| begin = clock() - begin; |
| rtt = 1000*((double)begin)/CLOCKS_PER_SEC; // in ms |
| printf("E2Agent-RIC-E2Agent RTT = %f ms\n", rtt); |
| } |
| |
| |
| close(client_fd); |
| } |
| |
| int main(int argc, char *argv[]) |
| { |
| printf("E2 Simulator. Version %s\n", VERSION); |
| // test_rmr(); return 0; |
| // test_adruino_serial(); return 0; |
| |
| char* server_ip = DEFAULT_SCTP_IP; |
| int server_port = X2AP_SCTP_PORT; |
| |
| int server_fd; |
| int client_fd; |
| struct sockaddr client_addr; |
| socklen_t client_addr_size; |
| |
| //read input |
| if(argc == 3) //user provided IP and PORT |
| { |
| server_ip = argv[1]; |
| server_port = atoi(argv[2]); |
| if(server_port < 1 || server_port > 65535) { |
| printf("Invalid port number (%d). Valid values are between 1 and 65535.\n" , server_port); |
| return -1; |
| } |
| } |
| else if(argc == 2) //user provided only IP |
| { |
| server_ip = argv[1]; |
| } |
| else if(argc == 1) |
| { |
| server_ip = DEFAULT_SCTP_IP; |
| } |
| else |
| { |
| printf("Unrecognized option.\n"); |
| printf("Usage: %s [SERVER IP ADDRESS] [SERVER PORT]\n", argv[0]); |
| return -1; |
| } |
| |
| server_fd = sctp_start_server(server_ip, server_port); |
| |
| printf("Waiting for connection...\n"); |
| client_fd = accept(server_fd, &client_addr, &client_addr_size); |
| if(client_fd == -1){ |
| perror("accept()"); |
| close(client_fd); |
| return -1; |
| } |
| |
| //Todo: retrieve client ip addr |
| struct sockaddr_in* client_ipv4 = (struct sockaddr_in*)&client_addr; |
| char client_ip_addr[INET_ADDRSTRLEN]; |
| inet_ntop(AF_INET, &(client_ipv4->sin_addr), client_ip_addr, INET_ADDRSTRLEN); |
| |
| printf("New client connected from %s\n", client_ip_addr); |
| |
| // while(1) //put while loop if want to receive from multiple clients |
| // { |
| uint8_t recv_buf[MAX_SCTP_BUFFER]; |
| int recv_len = 0; |
| |
| memset(recv_buf, 0, sizeof(recv_buf)); |
| |
| printf("------------------------\n"); |
| recv_len = recv(client_fd, &recv_buf, sizeof(recv_buf), 0); |
| if(recv_len == -1) |
| { |
| perror("recv()"); |
| return -1; |
| } |
| else if(recv_len == 0) |
| { |
| printf("\nConnection from %s closed by remote peer\n", client_ip_addr); |
| if(close(client_fd) == -1) |
| { |
| perror("close"); |
| } |
| return -1; |
| } |
| |
| //printf("Received a message of size %d\n", recv_len); |
| |
| //TODO: check PPID here before calling x2ap handler |
| |
| sctp_data_t response = {NULL, 0}; |
| x2ap_eNB_handle_message(recv_buf, recv_len, &response); |
| |
| //======================================================================= |
| //reply to client |
| assert(response.data != NULL); |
| if(sctp_send_to_socket(client_fd, response.data, (size_t)response.len) > 0){ |
| printf("Sent X2 SETUP RESPONSE \n"); |
| } else{ |
| perror("send to socket"); |
| return -1; |
| } |
| |
| printf("X2 Setup Completed \n"); |
| |
| //========================================================================= |
| // Pendulum interaction |
| // Send pendulum state to E2 Termination and receive response |
| pendulum_control_E2_agent(client_fd); |
| // } //end while |
| |
| close(client_fd); |
| |
| return 0; |
| } |