Merge "FIX: move some end-to-end test configs to values.yaml for nanobot"
[it/test.git] / simulators / e2sim / src / e2sim.c
1 /*
2  *
3  * Copyright 2019 AT&T Intellectual Property
4  * Copyright 2019 Nokia
5  *
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
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  */
19
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <time.h>
24 #include <string.h>
25 #include <assert.h>
26 #include <unistd.h>             //for close()
27 #include <arpa/inet.h>  //for inet_ntop()
28
29 #include "e2sim_defs.h"
30 #include "e2sim_sctp.h"
31 #include "x2ap_message_handler.h"
32
33 //OSN 2019
34 #include "Pendulum_asn_codec.h"
35 #include "adruino_serial.h"
36
37 //rmr
38 #include <errno.h>
39 #include <sys/epoll.h>
40 #include <rmr/rmr.h>
41 #include "rmr_wrapper.h"
42
43 static void pendulum_control_E2_agent(int client_fd)
44 {
45  printf("--------------------------------------\n");
46  printf("E2 AGENT - START PENDULUM CONTROL\n");
47  printf("--------------------------------------\n");
48
49  uint8_t   *buffer;
50  uint32_t  len;
51  clock_t   begin;
52  double    rtt; //ms
53
54  uint8_t recv_buf[MAX_SCTP_BUFFER];
55  int     recv_len;
56
57  double angle;
58  double torque;
59  long   sqn;
60  int    count = 0;
61
62  //serial
63  int serial_fd;
64  char serial_buffer[MAX_SERIAL_BUFFER];
65  serial_fd = start_serial_inferface(DEFAULT_BAUDRATE, DEFAULT_SERIAL_PORT);
66
67  int MSG_NUM = 10;
68
69  // printf("Enter number of messages: ");
70  // scanf("%d", &MSG_NUM);
71  //
72  // //fgets(serial_buffer, MAX_SERIAL_BUFFER, stdin);
73  // serialport_write(serial_fd, serial_buffer);
74
75  serialport_write(serial_fd, "hello arduino\n");
76
77  // for(int i = 0; i < MSG_NUM; i++)
78  while(1)
79  {
80
81    printf("----------------\n");
82    count += 1;
83    buffer  = NULL;
84    len     = 0;
85
86    //1.Read from serial
87    serial_readline(serial_fd, serial_buffer, MAX_SERIAL_BUFFER);
88    if(serial_buffer[0] == '\n')
89    {
90      //printf("RECEIVED EOL\n");
91      continue;
92    }
93    //printf("[Adruino] %s", serial_buffer);
94
95    begin = clock();
96
97    //2. Encode pendulum angle to ASN1 message
98    len = pendulum_create_asn_msg(&buffer, 0, 0, 0, serial_buffer);
99
100    //3. Send ASN1 message to socket
101    if(sctp_send_to_socket(client_fd, buffer, (size_t)len) > 0){
102      printf("Sent ASN1 message to E2 Termination\n");
103    }
104
105    // 4. Receive response from E2 Termination
106    memset(recv_buf, 0, sizeof(recv_buf));
107    recv_len = 0;
108    recv_len = recv(client_fd, &recv_buf, sizeof(recv_buf), 0);
109    if(recv_len == -1)
110    {
111      perror("recv()");
112      return;
113    }
114
115    char *recv_str;
116    recv_str = pendulum_get_strval(recv_buf, recv_len);
117    printf("Received response message #%d from xApp: %s\n", count, recv_str);
118
119    // 5. TODO: Send response to serial
120    serial_writeline(serial_fd, recv_str);
121
122    //serialport_write(serial_fd, "hello\n");
123
124    begin = clock() - begin;
125    rtt = 1000*((double)begin)/CLOCKS_PER_SEC; // in ms
126    printf("E2Agent-RIC-E2Agent RTT = %f ms\n", rtt);
127  }
128
129
130  close(client_fd);
131 }
132
133 int main(int argc, char *argv[])
134 {
135  printf("E2 Simulator. Version %s\n", VERSION);
136  // test_rmr(); return 0;
137  // test_adruino_serial(); return 0;
138
139  char* server_ip         = DEFAULT_SCTP_IP;
140  int server_port         = X2AP_SCTP_PORT;
141
142  int             server_fd;
143  int             client_fd;
144  struct sockaddr client_addr;
145  socklen_t       client_addr_size;
146
147  //read input
148  if(argc == 3) //user provided IP and PORT
149  {
150    server_ip = argv[1];
151    server_port = atoi(argv[2]);
152    if(server_port < 1 || server_port > 65535) {
153      printf("Invalid port number (%d). Valid values are between 1 and 65535.\n"            , server_port);
154      return -1;
155    }
156  }
157  else if(argc == 2) //user provided only IP
158  {
159    server_ip = argv[1];
160  }
161  else if(argc == 1)
162  {
163    server_ip = DEFAULT_SCTP_IP;
164  }
165  else
166  {
167    printf("Unrecognized option.\n");
168    printf("Usage: %s [SERVER IP ADDRESS] [SERVER PORT]\n", argv[0]);
169    return -1;
170  }
171
172  server_fd = sctp_start_server(server_ip, server_port);
173
174  printf("Waiting for connection...\n");
175  client_fd = accept(server_fd, &client_addr, &client_addr_size);
176  if(client_fd == -1){
177    perror("accept()");
178    close(client_fd);
179    return -1;
180  }
181
182  //Todo: retrieve client ip addr
183  struct sockaddr_in* client_ipv4 = (struct sockaddr_in*)&client_addr;
184  char client_ip_addr[INET_ADDRSTRLEN];
185  inet_ntop(AF_INET, &(client_ipv4->sin_addr), client_ip_addr, INET_ADDRSTRLEN);
186
187  printf("New client connected from %s\n", client_ip_addr);
188
189  // while(1) //put while loop if want to receive from multiple clients
190  // {
191    uint8_t recv_buf[MAX_SCTP_BUFFER];
192    int     recv_len = 0;
193
194    memset(recv_buf, 0, sizeof(recv_buf));
195
196    printf("------------------------\n");
197    recv_len = recv(client_fd, &recv_buf, sizeof(recv_buf), 0);
198    if(recv_len == -1)
199    {
200      perror("recv()");
201      return -1;
202    }
203    else if(recv_len == 0)
204    {
205      printf("\nConnection from %s closed by remote peer\n", client_ip_addr);
206      if(close(client_fd) == -1)
207      {
208        perror("close");
209      }
210      return -1;
211    }
212
213    //printf("Received a message of size %d\n", recv_len);
214
215    //TODO: check PPID here before calling x2ap handler
216
217    sctp_data_t response = {NULL, 0};
218    x2ap_eNB_handle_message(recv_buf, recv_len, &response);
219
220    //=======================================================================
221    //reply to client
222    assert(response.data != NULL);
223    if(sctp_send_to_socket(client_fd, response.data, (size_t)response.len) > 0){
224      printf("Sent X2 SETUP RESPONSE \n");
225    } else{
226      perror("send to socket");
227      return -1;
228    }
229
230    printf("X2 Setup Completed \n");
231
232    //=========================================================================
233    // Pendulum interaction
234    // Send pendulum state to E2 Termination and receive response
235    pendulum_control_E2_agent(client_fd);
236  // } //end while
237
238  close(client_fd);
239
240  return 0;
241 }