CI: Add silent cmake SonarCloud scan
[ric-plt/lib/rmr.git] / examples / sender.c
1 // :vim ts=4 sw=4 noet:
2 /*
3 ==================================================================================
4         Copyright (c) 2019-2020 Nokia
5         Copyright (c) 2018-2020 AT&T Intellectual Property.
6
7    Licensed under the Apache License, Version 2.0 (the "License");
8    you may not use this file except in compliance with the License.
9    You may obtain a copy of the License at
10
11            http://www.apache.org/licenses/LICENSE-2.0
12
13    Unless required by applicable law or agreed to in writing, software
14    distributed under the License is distributed on an "AS IS" BASIS,
15    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16    See the License for the specific language governing permissions and
17    limitations under the License.
18 ==================================================================================
19 */
20
21 /*
22         Mnemonic:       sender.c
23         Abstract:       Very simple test sender. Sends messages with a given delay between each.
24                                 The sender also uses epoll_wait() to ensure that any received messages
25                                 don't clog the queue.
26
27         Parms:          The following positional parameters are recognised on the command line:
28                                         [listen_port [delay [stats-freq] [msg-type]]]]
29
30                                         Defaults:
31                                                 listen_port 43086
32                                                 delay (mu-sec) 1000000 (1 sec)
33                                                 stats-freq 10
34                                                 msg-type 0
35
36         Date:           1 April 2019
37
38         CAUTION:        This example is now being pulled directly into the user documentation.
39                                 Because of this some altered line lengths and/or parameter list breaks
40                                 which seem strage have been applied to ensure that it formats nicely.
41                                 All code following the 'start_example' tag below is included.
42 */
43 // start_example
44
45 #include <unistd.h>
46 #include <errno.h>
47 #include <string.h>
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <sys/epoll.h>
51 #include <time.h>
52
53 #include <rmr/rmr.h>
54
55 int main( int argc, char** argv ) {
56         void* mrc;                                                      // msg router context
57         struct epoll_event events[1];           // list of events to give to epoll
58         struct epoll_event epe;                // event definition for event to listen to
59         int     ep_fd = -1;                                     // epoll's file des (given to epoll_wait)
60         int rcv_fd;                                                     // file des for epoll checks
61         int nready;                                                     // number of events ready for receive
62         rmr_mbuf_t*             sbuf;                           // send buffer
63         rmr_mbuf_t*             rbuf;                           // received buffer
64         int     count = 0;
65         int     rcvd_count = 0;
66         char*   listen_port = "43086";
67         int             delay = 1000000;                        // mu-sec delay between messages
68         int             mtype = 0;
69         int             stats_freq = 100;
70
71         if( argc > 1 ) {                                        // simplistic arg picking
72                 listen_port = argv[1];
73         }
74         if( argc > 2 ) {
75                 delay = atoi( argv[2] );
76         }
77         if( argc > 3 ) {
78                 mtype = atoi( argv[3] );
79         }
80
81         fprintf( stderr, "<DEMO> listen port: %s; mtype: %d; delay: %d\n",
82                 listen_port, mtype, delay );
83
84         if( (mrc = rmr_init( listen_port, 1400, RMRFL_NONE )) == NULL ) {
85                 fprintf( stderr, "<DEMO> unable to initialise RMR\n" );
86                 exit( 1 );
87         }
88
89         rcv_fd = rmr_get_rcvfd( mrc );  // set up epoll things, start by getting the FD from RMR
90         if( rcv_fd < 0 ) {
91                 fprintf( stderr, "<DEMO> unable to set up polling fd\n" );
92                 exit( 1 );
93         }
94         if( (ep_fd = epoll_create1( 0 )) < 0 ) {
95                 fprintf( stderr, "[FAIL] unable to create epoll fd: %d\n", errno );
96                 exit( 1 );
97         }
98         epe.events = EPOLLIN;
99         epe.data.fd = rcv_fd;
100
101         if( epoll_ctl( ep_fd, EPOLL_CTL_ADD, rcv_fd, &epe ) != 0 )  {
102                 fprintf( stderr, "[FAIL] epoll_ctl status not 0 : %s\n", strerror( errno ) );
103                 exit( 1 );
104         }
105
106         sbuf = rmr_alloc_msg( mrc, 256 );       // alloc 1st send buf; subsequent bufs alloc on send
107         rbuf = NULL;                                            // don't need to alloc receive buffer
108
109         while( ! rmr_ready( mrc ) ) {           // must have route table
110                 sleep( 1 );                                             // wait til we get one
111         }
112         fprintf( stderr, "<DEMO> rmr is ready\n" );
113
114
115         while( 1 ) {                    // send messages until the cows come home
116                 snprintf( sbuf->payload, 200,
117                         "count=%d received= %d ts=%lld %d stand up and cheer!", // create the payload
118                         count, rcvd_count, (long long) time( NULL ), rand() );
119
120                 sbuf->mtype = mtype;                                                    // fill in the message bits
121                 sbuf->len =  strlen( sbuf->payload ) + 1;               // send full ascii-z string
122                 sbuf->state = 0;
123                 sbuf = rmr_send_msg( mrc, sbuf );                               // send & get next buf to fill in
124                 while( sbuf->state == RMR_ERR_RETRY ) {                 // soft failure (device busy?) retry
125                         sbuf = rmr_send_msg( mrc, sbuf );                       // w/ simple spin that doesn't give up
126                 }
127                 count++;
128
129                 // check to see if anything was received and pull all messages in
130                 while( (nready = epoll_wait( ep_fd, events, 1, 0 )) > 0 ) { // 0 is non-blocking
131                         if( events[0].data.fd == rcv_fd ) {     // waiting on 1 thing, so [0] is ok
132                                 errno = 0;
133                                 rbuf = rmr_rcv_msg( mrc, rbuf );        // receive and ignore; just count
134                                 if( rbuf ) {
135                                         rcvd_count++;
136                                 }
137                         }
138                 }
139
140                 if( (count % stats_freq) == 0 ) {                       // occasional stats out to tty
141                         fprintf( stderr, "<DEMO> sent %d   received %d\n", count, rcvd_count );
142                 }
143
144                 usleep( delay );
145         }
146 }
147