blob: 2f49beaa2675e4835a2cb41cdd95b393b267039f [file] [log] [blame]
/*
*
* 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;
}