Merge "Initial docs skeleton"
[it/test.git] / ons_2019_demo / pendulum_xapp / pendulum_xapp.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 // :vim ts=4 sw=4 noet:
21 /*
22 Mnemonic:       rmr_rcvr2.c
23 Abstract:       Very simple test listener built on RMr libraries. It does nothing
24 but return the message it recevied back to the sender.
25
26 Define these environment variables to have some control:
27 RMR_SEED_RT -- path to the static routing table
28 RMR_RTG_SVC -- host:port of the route table generator
29
30 One command line parm is accepted: stats frequency.  This is a number, n,
31 which causes stats to be generated after every n messages. If set to 0
32 each message is written when received and no stats (msg rate) is generated.
33
34 Date:           11 February 2018
35 Author:         E. Scott Daniels
36
37 Mods:           18 Mar 2019 -- simplified for demo base.
38  */
39
40 #include <unistd.h>
41 #include <errno.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <time.h>
45
46 #include <rmr/rmr.h>
47 #include <sys/time.h>
48
49 long current_timestamp_in_us(){
50         struct timeval currentTime;
51         gettimeofday(&currentTime, NULL);
52         return currentTime.tv_sec * (int)1e6 + currentTime.tv_usec;
53 }
54
55 long delay=0; //sent from the a1 med in milliseconds
56 void handle_pendulum_angle_message(void* mrc,rmr_mbuf_t* msg){
57         fprintf(stderr, "Sleeping for %ld microseconds", delay);
58         // usleep(delay/20000.0); //sleep for <delay> us
59   usleep(delay/20); //ms
60   int max_rt=2;
61         fprintf( stderr, "Received message from E2 termination of type:%d (pendulum control), with content:%s\n",msg->mtype,msg->payload);
62         msg->len = snprintf( msg->payload, 1024, "$%d#\n",(int)delay/20000);
63         msg->mtype=33;
64         msg = rmr_rts_msg( mrc, msg );                                                          // this is a retur to sender; preferred
65         if( (msg = rmr_rts_msg( mrc, msg )) != NULL ) {
66                 max_rt = 2;//should be small to prevent rmr issues
67                 while( max_rt > 0 && msg->state != RMR_OK && errno == EAGAIN ) {                // just keep trying
68                         max_rt--;
69                         rmr_rts_msg( mrc, msg );
70                         //rmr_send_msg (mrc, msg);
71                 }
72         }
73 }
74
75
76 //void handle_pendulum_angle_message(){
77 //      int mtype=33;
78 //      char* message="Reply hello back to Arduino!";
79 //      rmr_pure_send(rmr_c, mtype, message );
80 //      printf("Sent message of type:%d to E2 terminator with content:%s\n",mtype,message);
81 //}
82
83 void handle_delay_insertion_message(void* mrc,rmr_mbuf_t* msg){
84         fprintf( stderr, "Received message from A1 mediator of type:%d (delay insert), with content:%s\n",msg->mtype,msg->payload);
85         delay = atol(msg->payload);//payload is being sent in microseconds
86 }
87
88
89
90 int main( int argc, char** argv ) {
91         void* mrc;                                              // msg router context
92         rmr_mbuf_t* msg = NULL;                         // message received
93         char*   listen_port;
94         int stat_freq = 20000;                          // write stats after reciving this many messages
95
96
97         if( (listen_port = getenv( "PENDULUM_XAPP_RMR_RCV_PORT" )) == NULL ) {
98                 listen_port = "4560";
99         }
100
101         if( argc > 1 ) {
102                 stat_freq = atoi( argv[1] );
103         }
104         fprintf( stderr, "<TEST> stats will be reported every %d messages\n", stat_freq );
105
106         mrc = rmr_init( listen_port, RMR_MAX_RCV_BYTES, RMRFL_NONE );   // start your engines!
107         if( mrc == NULL ) {
108                 fprintf( stderr, "<TEST> ABORT:  unable to initialise RMr\n" );
109                 exit( 1 );
110         }
111
112         while( ! rmr_ready( mrc ) ) {
113                 fprintf( stderr, "<TEST> waiting for RMr to show ready\n" );
114                 sleep( 1 );
115         }
116         fprintf( stderr, "<TEST> RMr now shows ready\n" );
117
118         fprintf( stderr, "<TEST> listening on %s\n", listen_port);
119
120         fprintf( stderr, "======================================\n Pendulum Control xApp Running\n======================================\n");
121         long received_angle_message_time =0;
122         while( 1 ) {
123                 msg = rmr_rcv_msg( mrc, msg );                                          // block until one arrives
124                 if( msg == NULL ) {
125                         continue;                               // shouldn't happen, but don't crash if we get nothing
126                 }
127                 if( msg->mtype < 0 || msg->state != RMR_OK ) {
128                         fprintf( stderr, "[WRN] bad msg:  state=%d  errno=%d\n", msg->state, errno );
129                         continue;                       // just loop to receive another
130                 }
131
132                 switch (msg->mtype){
133                     case 0:
134                              received_angle_message_time = current_timestamp_in_us();
135                              handle_pendulum_angle_message(mrc,msg);
136                              fprintf(stderr, "Time taken to reply to E2 term:%ld micro seconds \n",current_timestamp_in_us()-received_angle_message_time);
137                              break;
138                     case 100:  handle_delay_insertion_message(mrc,msg);
139                              break;
140                     default: fprintf( stdout, "[WRN] bad msg: =%d\n", msg->mtype);
141                 }
142         }
143 }