Initial commit of RMR Library
[ric-plt/lib/rmr.git] / examples / sender.c
diff --git a/examples/sender.c b/examples/sender.c
new file mode 100644 (file)
index 0000000..0fa5343
--- /dev/null
@@ -0,0 +1,120 @@
+// :vim ts=4 sw=4 noet:
+
+/*
+       Mnemonic:       sender.c
+       Abstract:       Very simple test sender. Sends messages with a given delay between each.
+                               The sender also uses epoll_wait() to ensure that any received messages
+                               don't clog the queue.
+
+       Parms:          The following positional parameters are recognised on the command line:
+                                       [listen_port [delay [stats-freq] [msg-type]]]]
+
+                                       Defaults:
+                                               listen_port 43086 
+                                               delay (mu-sec) 1000000 (1 sec)
+                                               stats-freq 10
+                                               msg-type 0
+
+       Date:           1 April 2019
+*/
+
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/epoll.h>
+#include <time.h>
+
+#include <rmr/rmr.h>
+
+int main( int argc, char** argv ) {
+    void* mrc;                                                 //msg router context
+    struct epoll_event events[1];                      // list of events to give to epoll
+    struct epoll_event epe;                 // event definition for event to listen to
+    int     ep_fd = -1;                                                // epoll's file des (given to epoll_wait)
+    int rcv_fd;                                                // file des that NNG tickles -- give this to epoll to listen on
+       int nready;                                                             // number of events ready for receive
+       rmr_mbuf_t*             sbuf;                                   // send buffer
+       rmr_mbuf_t*             rbuf;                                   // received buffer
+       int     count = 0;
+       int     rcvd_count = 0;
+       char*   listen_port = "43086";
+       int             delay = 1000000;                                                // mu-sec delay between messages
+       int             mtype = 0;
+       int             stats_freq = 100;
+
+       if( argc > 1 ) {
+               listen_port = argv[1];
+       }
+       if( argc > 2 ) {
+               delay = atoi( argv[2] );
+       }
+       if( argc > 3 ) {
+               mtype = atoi( argv[3] );
+       }
+
+       fprintf( stderr, "<DEMO> listen port: %s; mtype: %d; delay: %d\n", listen_port, mtype, delay );
+
+    if( (mrc = rmr_init( listen_port, 1400, RMRFL_NONE )) == NULL ) {
+               fprintf( stderr, "<DEMO> unable to initialise RMr\n" );
+               exit( 1 );
+       }
+
+    rcv_fd = rmr_get_rcvfd( mrc );                                     // set up epoll things, start by getting the FD from MRr
+       if( rcv_fd < 0 ) {
+               fprintf( stderr, "<DEMO> unable to set up polling fd\n" );
+               exit( 1 );
+       }
+       if( (ep_fd = epoll_create1( 0 )) < 0 ) {
+               fprintf( stderr, "[FAIL] unable to create epoll fd: %d\n", errno );
+               exit( 1 );
+       }
+    epe.events = EPOLLIN;
+    epe.data.fd = rcv_fd;
+
+    if( epoll_ctl( ep_fd, EPOLL_CTL_ADD, rcv_fd, &epe ) != 0 )  {
+               fprintf( stderr, "[FAIL] epoll_ctl status not 0 : %s\n", strerror( errno ) );
+               exit( 1 );
+       }
+
+       sbuf = rmr_alloc_msg( mrc, 256 );       // alloc first send buffer; subsequent buffers allcoated on send
+       rbuf = NULL;                                            // don't need to alloc receive buffer
+
+       while( ! rmr_ready( mrc ) ) {           // must have a route table before we can send; wait til RMr say it has one
+               sleep( 1 );
+       }
+       fprintf( stderr, "<DEMO> rmr is ready\n" );
+       
+
+    while( 1 ) {                                                                               // send messages until the cows come home
+               snprintf( sbuf->payload, 200, "count=%d received= %d ts=%lld %d stand up and cheer!",   // create the payload
+                       count, rcvd_count, (long long) time( NULL ), rand() );
+
+               sbuf->mtype = mtype;                                                    // fill in the message bits
+               sbuf->len =  strlen( sbuf->payload ) + 1;               // our receiver likely wants a nice acsii-z string
+               sbuf->state = 0;
+               sbuf = rmr_send_msg( mrc, sbuf );                               // send it (send returns an empty payload on success, or the original payload on fail/retry)
+               while( sbuf->state == RMR_ERR_RETRY ) {                 // soft failure (device busy?) retry
+                       sbuf = rmr_send_msg( mrc, sbuf );                       // retry send until it's good (simple test; real programmes should do better)
+               }
+               count++;
+
+               while( (nready = epoll_wait( ep_fd, events, 1, 0 )) > 0 ) {     // if something ready to receive (non-blocking check)
+                       if( events[0].data.fd == rcv_fd ) {             // we only are waiting on 1 thing, so [0] is ok
+                               errno = 0;
+                               rbuf = rmr_rcv_msg( mrc, rbuf );
+                               if( rbuf ) {
+                                       rcvd_count++;
+                               }
+                       }
+               }
+
+               if( (count % stats_freq) == 0 ) {
+                       fprintf( stderr, "<DEMO> sent %d   received %d\n", count, rcvd_count );
+               }
+
+               usleep( delay );
+    }
+}
+