Enhanced SIM for E2AP v1 for TS UC
[sim/e2-interface.git] / e2sim / e2apv1sim / test / Pendulum / e2sim_closedloop.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  fprintf(stderr, "--------------------------------------\n");
46  fprintf(stderr, "E2 AGENT - START PENDULUM CONTROL\n");
47  fprintf(stderr, "--------------------------------------\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  // char *delay_str_prev = "$0#\n";
68  // //char *delay_str_new;
69  //
70  // int MSG_NUM = 10;
71  //
72  // //Always start with 0 delay
73  // serialport_write(serial_fd, "$0#\n");
74
75  // for(int i = 0; i < MSG_NUM; i++)
76  while(1)
77  {
78
79    fprintf(stderr, "----------------\n");
80    count += 1;
81    buffer  = NULL;
82    len     = 0;
83
84    // //1.Read from serial
85    // serial_readline(serial_fd, serial_buffer, MAX_SERIAL_BUFFER);
86    // if(serial_buffer[0] == '\n')
87    // {
88    //   //fprintf(stderr, "RECEIVED EOL\n");
89    //   continue;
90    // }
91    // //fprintf(stderr, "[Adruino] %s", serial_buffer);
92    usleep(5*1000);
93
94    snprintf(serial_buffer, sizeof(serial_buffer)-1, "E2 AGENT PING");
95
96    begin = clock();
97
98    //2. Encode pendulum angle to ASN1 message
99
100    len = pendulum_create_asn_msg(&buffer, 0, 0, 0, serial_buffer);
101
102    //3. Send ASN1 message to socket
103    if(sctp_send_to_socket(client_fd, buffer, (size_t)len) > 0){
104      fprintf(stderr, "Sent ASN1 message to E2 Termination\n");
105    }
106
107    // 4. Receive response from E2 Termination
108    memset(recv_buf, 0, sizeof(recv_buf));
109    recv_len = 0;
110    recv_len = recv(client_fd, &recv_buf, sizeof(recv_buf), 0);
111    if(recv_len == -1)
112    {
113      perror("recv()");
114      return;
115    }
116
117    char *recv_str;
118    recv_str = pendulum_get_strval(recv_buf, recv_len);
119    fprintf(stderr, "Received response message #%d from xApp: %s\n", count, recv_str);
120
121    // 5. TODO: Send response to serial
122    // Compare if delay has changed:
123    // if(strcmp(delay_str_prev, recv_str) != 0) {
124    //   serial_writeline(serial_fd, recv_str);
125    // }
126
127    //serial_writeline(serial_fd, recv_str);
128
129    //Write to a file
130    FILE *f;
131    f = fopen("arduino_delay.txt", "w");
132    fprintf(f, "%s", recv_str);
133    fclose(f);
134
135    begin = clock() - begin;
136    rtt = 1000*((double)begin)/CLOCKS_PER_SEC; // in ms
137    fprintf(stderr, "E2Agent-RIC-E2Agent RTT = %f ms\n", rtt);
138
139  }
140
141  close(client_fd);
142 }
143
144 int main(int argc, char *argv[])
145 {
146  fprintf(stderr, "E2 AGENT - PENDULUM CONTROL. Version %s\n", VERSION);
147
148  // char *recv_str = "9";
149  // int delay;
150  //
151  // printf("delay = %d\n", atoi(recv_str));
152  //
153  // long delay = 22.5;
154  //
155  // printf("delay = %d\n", (int)delay);
156  // return 0;
157
158  // test_rmr(); return 0;
159  // test_adruino_serial(); return 0;
160
161  char* server_ip         = DEFAULT_SCTP_IP;
162  int server_port         = X2AP_SCTP_PORT;
163
164  int             server_fd;
165  int             client_fd;
166  struct sockaddr client_addr;
167  socklen_t       client_addr_size;
168
169  //read input
170  if(argc == 3) //user provided IP and PORT
171  {
172    server_ip = argv[1];
173    server_port = atoi(argv[2]);
174    if(server_port < 1 || server_port > 65535) {
175      fprintf(stderr, "Invalid port number (%d). Valid values are between 1 and 65535.\n"            , server_port);
176      return -1;
177    }
178  }
179  else if(argc == 2) //user provided only IP
180  {
181    server_ip = argv[1];
182  }
183  else if(argc == 1)
184  {
185    server_ip = DEFAULT_SCTP_IP;
186  }
187  else
188  {
189    fprintf(stderr, "Unrecognized option.\n");
190    fprintf(stderr, "Usage: %s [SERVER IP ADDRESS] [SERVER PORT]\n", argv[0]);
191    return -1;
192  }
193
194  server_fd = sctp_start_server(server_ip, server_port);
195
196  fprintf(stderr, "Waiting for connection...\n");
197  client_fd = accept(server_fd, &client_addr, &client_addr_size);
198  if(client_fd == -1){
199    perror("accept()");
200    close(client_fd);
201    return -1;
202  }
203
204  //Todo: retrieve client ip addr
205  struct sockaddr_in* client_ipv4 = (struct sockaddr_in*)&client_addr;
206  char client_ip_addr[INET_ADDRSTRLEN];
207  inet_ntop(AF_INET, &(client_ipv4->sin_addr), client_ip_addr, INET_ADDRSTRLEN);
208
209  fprintf(stderr, "New client connected from %s\n", client_ip_addr);
210
211  // while(1) //put while loop if want to receive from multiple clients
212  // {
213    uint8_t recv_buf[MAX_SCTP_BUFFER];
214    int     recv_len = 0;
215
216    memset(recv_buf, 0, sizeof(recv_buf));
217
218    fprintf(stderr, "------------------------\n");
219    recv_len = recv(client_fd, &recv_buf, sizeof(recv_buf), 0);
220    if(recv_len == -1)
221    {
222      perror("recv()");
223      return -1;
224    }
225    else if(recv_len == 0)
226    {
227      fprintf(stderr, "\nConnection from %s closed by remote peer\n", client_ip_addr);
228      if(close(client_fd) == -1)
229      {
230        perror("close");
231      }
232      return -1;
233    }
234
235    //fprintf(stderr, "Received a message of size %d\n", recv_len);
236
237    //TODO: check PPID here before calling x2ap handler
238
239    sctp_data_t response = {NULL, 0};
240    x2ap_eNB_handle_message(recv_buf, recv_len, &response);
241
242    //=======================================================================
243    //reply to client
244    assert(response.data != NULL);
245    if(sctp_send_to_socket(client_fd, response.data, (size_t)response.len) > 0){
246      fprintf(stderr, "Sent X2 SETUP RESPONSE \n");
247    } else{
248      perror("send to socket");
249      return -1;
250    }
251
252    fprintf(stderr, "X2 Setup Completed \n");
253
254    //=========================================================================
255    // Pendulum interaction
256    // Send pendulum state to E2 Termination and receive response
257    pendulum_control_E2_agent(client_fd);
258  // } //end while
259
260  close(client_fd);
261
262  return 0;
263 }