Fix missing realloc function in SI

The realloc payload function was missing in the SI port.

This change also adds the ability to build and run SI95
test applications in the test_app directory. NNG tests
are still run by default (this will be changed eventually).

Signed-off-by: E. Scott Daniels <daniels@research.att.com>
Change-Id: Ie8a453a009767afcf23eac610dc5f976b880d0aa
diff --git a/CHANGES b/CHANGES
index 3ae419a..976169f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,9 @@
 API and build change  and fix summaries. Doc correctsions
 and/or changes are not mentioned here; see the commit messages.
 
+2020 January 21; verison 3.0.2
+	Fix bug in SI95 (missing reallocate payload function).
+
 2020 January 20; verison 3.0.1
 	Enable support for dynamic route table updates via RMR session.
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d44827a..ef8308b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -38,7 +38,7 @@
 
 set( major_version "3" )		# should be automatically populated from git tag later, but until CI process sets a tag we use this
 set( minor_version "0" )
-set( patch_level "1" )
+set( patch_level "2" )
 
 set( install_root "${CMAKE_INSTALL_PREFIX}" )
 set( install_inc "include/rmr" )
diff --git a/src/rmr/si/src/rmr_si.c b/src/rmr/si/src/rmr_si.c
index 8e499c1..fd8dcb0 100644
--- a/src/rmr/si/src/rmr_si.c
+++ b/src/rmr/si/src/rmr_si.c
@@ -1031,6 +1031,34 @@
 }
 
 /*
+	Given an existing message buffer, reallocate the payload portion to
+	be at least new_len bytes.  The message header will remain such that
+	the caller may use the rmr_rts_msg() function to return a payload
+	to the sender. 
+
+	The mbuf passed in may or may not be reallocated and the caller must
+	use the returned pointer and should NOT assume that it can use the 
+	pointer passed in with the exceptions based on the clone flag.
+
+	If the clone flag is set, then a duplicated message, with larger payload
+	size, is allocated and returned.  The old_msg pointer in this situation is
+	still valid and must be explicitly freed by the application. If the clone 
+	message is not set (0), then any memory management of the old message is
+	handled by the function.
+
+	If the copy flag is set, the contents of the old message's payload is 
+	copied to the reallocated payload.  If the flag is not set, then the 
+	contents of the payload is undetermined.
+*/
+extern rmr_mbuf_t* rmr_realloc_payload( rmr_mbuf_t* old_msg, int new_len, int copy, int clone ) {
+	if( old_msg == NULL ) {
+		return NULL;
+	}
+
+	return realloc_payload( old_msg, new_len, copy, clone );	// message allocation is transport specific, so this is a passthrough
+}
+
+/*
 	Enable low latency things in the transport (when supported).
 */
 extern void rmr_set_low_latency( void* vctx ) {
diff --git a/src/rmr/si/src/sr_si_static.c b/src/rmr/si/src/sr_si_static.c
index 703e80c..0ca5eec 100644
--- a/src/rmr/si/src/sr_si_static.c
+++ b/src/rmr/si/src/sr_si_static.c
@@ -141,6 +141,7 @@
 		}
 	}
 
+	msg->rts_fd = -1;					// must force to be invalid; not a received message that can be returned
 
 	if( !msg->alloc_len && (msg->tp_buf = (void *) malloc( mlen )) == NULL ) {
 		fprintf( stderr, "[CRI] rmr_alloc_zc: cannot get memory for zero copy buffer: %d bytes\n", (int) mlen );
@@ -419,6 +420,127 @@
 }
 
 /*
+	Realloc the message such that the payload is at least payload_len bytes.  
+	The clone and copy options affect what portion of the original payload is copied to
+	the reallocated message, and whether or not the original payload is lost after the
+	reallocation process has finished.
+
+		copy == true
+		The entire payload from the original message will be coppied to the reallocated
+		payload.
+
+		copy == false
+		Only the header (preserving return to sender information, message type, etc)
+		is preserved after reallocation; the payload used lengrh is set to 0 and the
+		payload is NOT initialised/cleared.
+
+		clone == true
+		The orignal message is preserved and a completely new message buffer and payload
+		are allocated (even if the size given is the same). A pointer to the new message
+		buffer is returned and it is the user application's responsibility to manage the
+		old buffer (e.g. free when not needed).
+
+		clone == false
+		The old payload will be lost after reallocation. The message buffer pointer which
+		is returned will likely reference the same structure (don't depend on that).
+		
+
+	CAUTION:
+	If the message is not a message which was received, the mtype, sub-id, length values in the
+	RMR header in the allocated transport buffer will NOT be accurate and will cause the resulting
+	mbuffer information for mtype and subid to be reset even when copy is true. To avoid silently
+	resetting information in the mbuffer, this funciton will reset the mbuf values from the current
+	settings and NOT from the copied RMR header in transport buffer.
+*/
+static inline rmr_mbuf_t* realloc_payload( rmr_mbuf_t* old_msg, int payload_len, int copy, int clone ) {
+	rmr_mbuf_t* nm = NULL;	// new message buffer when cloning
+	size_t	mlen;
+	uta_mhdr_t* omhdr;		// old message header
+	int		tr_old_len;		// tr size in new buffer
+	int		old_psize = 0;	// size of payload in the message passed in (alloc size - tp header and rmr header lengths)
+	int		hdr_len = 0;	// length of RMR and transport headers in old msg
+	void*	old_tp_buf;		// pointer to the old tp buffer
+	int		free_tp = 1;	// free the transport buffer (old) when done (when not cloning)
+	int		old_mt;			// msg type and sub-id from the message passed in
+	int		old_sid;
+	int		old_len;
+	int		old_rfd;		// rts file descriptor from old message
+
+	if( old_msg == NULL || payload_len <= 0 ) {
+		errno = EINVAL;
+		return NULL;
+	}
+
+	old_mt = old_msg->mtype;			// preserve mbuf info
+	old_sid = old_msg->sub_id;
+	old_len = old_msg->len;
+	old_rfd = old_msg->rts_fd;
+
+	old_psize = old_msg->alloc_len - (RMR_HDR_LEN( old_msg->header ) + TP_HDR_LEN);		// user payload size in orig message
+
+	if( !clone  && payload_len <= old_psize ) {										// not cloning and old is large enough; nothing to do
+		if( DEBUG ) fprintf( stderr, "[DBUG] rmr_realloc_payload: old msg payload larger than requested: cur=%d need=%d\n", old_psize, payload_len );
+		return old_msg;
+	}
+
+	hdr_len = RMR_HDR_LEN( old_msg->header ) + TP_HDR_LEN;				// with SI we manage the transport header; must include in len
+	old_tp_buf = old_msg->tp_buf;
+
+	if( clone ) {
+		if( DEBUG ) fprintf( stderr, "[DBUG] rmr_realloc_payload: cloning message\n" );
+		free_tp = 0;
+
+		nm = (rmr_mbuf_t *) malloc( sizeof( *nm ) );
+		if( nm == NULL ) {
+			fprintf( stderr, "[CRI] rmr_realloc_payload: cannot get memory for message buffer. bytes requested: %d\n", (int) sizeof(*nm) );
+			return NULL;
+		}
+		memset( nm, 0, sizeof( *nm ) );
+		nm->rts_fd = old_rfd;				// this is managed only in the mbuf; dup now
+	} else {
+		nm = old_msg;
+	}
+
+	omhdr = old_msg->header;
+	mlen = hdr_len + (payload_len > old_psize ? payload_len : old_psize);		// must have larger in case copy is true
+
+	if( DEBUG ) fprintf( stderr, "[DBUG] reallocate for payload increase. new message size: %d\n", (int) mlen );	
+	if( (nm->tp_buf = (char *) malloc( sizeof( char ) * mlen )) == NULL ) {
+		fprintf( stderr, "[CRI] rmr_realloc_payload: cannot get memory for zero copy buffer. bytes requested: %d\n", (int) mlen );
+		return NULL;
+	}
+
+	nm->header = ((char *) nm->tp_buf) + TP_HDR_LEN;			// point at the new header and copy from old
+	SET_HDR_LEN( nm->header );
+
+	if( copy ) {																// if we need to copy the old payload too
+		if( DEBUG ) fprintf( stderr, "[DBUG] rmr_realloc_payload: copy payload into new message: %d bytes\n", old_psize );
+		memcpy( nm->header, omhdr, sizeof( char ) * (old_psize + RMR_HDR_LEN( omhdr )) );
+	} else {																	// just need to copy header
+		if( DEBUG ) fprintf( stderr, "[DBUG] rmr_realloc_payload: copy only header into new message: %d bytes\n", RMR_HDR_LEN( nm->header ) );
+		memcpy( nm->header, omhdr, sizeof( char ) * RMR_HDR_LEN( omhdr ) );
+	}
+
+	ref_tpbuf( nm, mlen );			// set payload and other pointers in the message to the new tp buffer
+
+	if( !copy ) {
+		nm->mtype = -1;						// didn't copy payload, so mtype, sub-id, and rts fd are invalid
+		nm->sub_id = -1;
+		nm->len = 0;						// and len is 0
+	} else {
+		nm->len = old_len;					// we must force these to avoid losing info if msg wasn't a received message
+		nm->mtype = old_mt;
+		nm->sub_id = old_sid;
+	}
+
+	if( free_tp ) {
+		free( old_tp_buf );				// we did not clone, so free b/c no references
+	}
+
+	return nm;
+}
+
+/*
 	For SI95 based transport all receives are driven through the threaded
 	ring and thus this function should NOT be called. If it is we will panic
 	and abort straight away.
@@ -443,7 +565,7 @@
 static void* rcv_payload( uta_ctx_t* ctx, rmr_mbuf_t* old_msg ) {
 	return NULL;
 /*
-FIXME: not implemented yet
+FIXME: do we need this in the SI world?  The only user was the route table collector
 	int state;
 	rmr_mbuf_t*	msg = NULL;		// msg received
 	size_t	rsize;				// nng needs to write back the size received... grrr
diff --git a/test/app_test/Makefile b/test/app_test/Makefile
index 670ca1f..fe4cd33 100644
--- a/test/app_test/Makefile
+++ b/test/app_test/Makefile
@@ -1,7 +1,7 @@
 #
 #=================================================================================
-#    Copyright (c) 2019 Nokia
-#    Copyright (c) 2018-2019 AT&T Intellectual Property.
+#    Copyright (c) 2019-2020 Nokia
+#    Copyright (c) 2018-2020 AT&T Intellectual Property.
 #
 #   Licensed under the Apache License, Version 2.0 (the "License");
 #   you may not use this file except in compliance with the License.
@@ -54,42 +54,22 @@
 
 # ------ nng based builds ------------------------------------------------------------
 
-receiver: receiver.c
+%:%.c
 	gcc -I $${C_INCLUDE_PATH:-.} $< -g -o $@ -lrmr_nng -lnng -lpthread -lm
 
+# special build as it reuses an existing source module
 mt_receiver: receiver.c
 	gcc -I $${C_INCLUDE_PATH:-.} -DMTC $< -g -o $@ -lrmr_nng -lnng -lpthread -lm
 
-lreceiver: lreceiver.c
-	gcc -I $${C_INCLUDE_PATH:-.} $< -g -o $@ -lrmr_nng -lnng -lpthread -lm
-
-ex_rts_receiver: ex_rts_receiver.c
-	gcc $(ex_cflags) -I $${C_INCLUDE_PATH:-.} $< -g -o $@ -lrmr_nng -lnng -lpthread -lm
-
-v_sender: v_sender.c
-	gcc -I $${C_INCLUDE_PATH:-.} $< -g -o $@ -lrmr_nng -lnng -lpthread -lm
-
-sender: sender.c
-	gcc -I $${C_INCLUDE_PATH:-.} $< -g -o $@ -lrmr_nng -lnng -lpthread -lm
-
-caller: caller.c
-	gcc -I $${C_INCLUDE_PATH:-.} $< -g -o $@ -lrmr_nng -lnng -lpthread -lm
-
-lcaller: lcaller.c
-	gcc -I $${C_INCLUDE_PATH:-.} $< -g -o $@  -lrmr_nng -lnng -lpthread -lm
-
-lsender: lsender.c
-	gcc -I $${C_INCLUDE_PATH:-.} $< -g -o $@  -lrmr_nng -lnng -lpthread -lm
-
-
 
 # ----- si test builds -------------------------------------------------------------
 
-sender_si: sender.c
+%_si : %.c
 	gcc -I $${C_INCLUDE_PATH:-.} $< -g -o $@ -lrmr_si -lpthread -lm
 
-receiver_si: receiver.c
-	gcc -I $${C_INCLUDE_PATH:-.} $< -g -o $@ -lrmr_si -lpthread -lm
+# explicit rule because there is no mt_recever.c
+mt_receiver_si: receiver.c
+	gcc -I $${C_INCLUDE_PATH:-.} -DMTC $< -g -o $@ -lrmr_si -lpthread -lm
 
 
 # --------- housekeeping -----------------------------------------------------------
diff --git a/test/app_test/caller.c b/test/app_test/caller.c
index c72e072..8f93603 100644
--- a/test/app_test/caller.c
+++ b/test/app_test/caller.c
@@ -144,7 +144,7 @@
 			rt_count++;
 		}
 		while( sbuf != NULL && sbuf->state == RMR_ERR_RETRY ) {				// send blocked; keep trying
-			sbuf = rmr_mt_call( control->mrc, sbuf, control->id, 100 );		// call and wait up to 100ms for a response
+			sbuf = rmr_mt_call( control->mrc, sbuf, control->id, 5000 );	// call and wait up to 5s for a response
 		}
 
 		if( sbuf != NULL ) {
@@ -166,7 +166,7 @@
 					break;
 
 				default:
-					fprintf( stderr, "unexpected error: tid=%d rmr-state=%d ernro=%d\n", control->id, sbuf->state, errno );
+					fprintf( stderr, "<CALLR> unexpected error: tid=%d rmr-state=%d ernro=%d\n", control->id, sbuf->state, errno );
 					sbuf = rmr_alloc_msg( control->mrc, 512 );			// allocate a sendable buffer
 					if( successful ) {
 						fail_count++;							// count failures after first successful message
diff --git a/test/app_test/lcaller.c b/test/app_test/lcaller.c
index 0d246d8..b490781 100644
--- a/test/app_test/lcaller.c
+++ b/test/app_test/lcaller.c
@@ -162,11 +162,11 @@
 
 	if( hist ) {
 		for( j = 0; j < td->nbins; j++ ) {
-			fprintf( stderr, "%3d %d\n", j, out ? td->out_bins[j] : td->in_bins[j] );
+			fprintf( stderr, "<LCALLER> hist: bin[%03d] %d\n", j, out ? td->out_bins[j] : td->in_bins[j] );
 		}
 	}
 
-	fprintf( stderr, "%s: oor=%d max=%.2fms  mean=%.2fms  95th=%.2fms 99th=%.2f\n", 
+	fprintf( stderr, "<LCALLER> %s: oor=%d max=%.2fms  mean=%.2fms  95th=%.2fms 99th=%.2f\n", 
 		out ? "out" : " in", oor, (double)max/1000000.0, (double)mean/100.0, (double) i95/100.0, i99/100.0 );
 }
 
@@ -293,7 +293,7 @@
 					break;
 
 				default:
-					fprintf( stderr, "unexpected error: tid=%d rmr-state=%d ernro=%d\n", control->id, sbuf->state, errno );
+					fprintf( stderr, "<LCALLER> unexpected error: tid=%d rmr-state=%d ernro=%d\n", control->id, sbuf->state, errno );
 					sbuf = rmr_alloc_msg( control->mrc, 512 );			// allocate a sendable buffer
 					if( successful ) {
 						fail_count++;							// count failures after first successful message
diff --git a/test/app_test/lreceiver.c b/test/app_test/lreceiver.c
index 161abc7..2801e42 100644
--- a/test/app_test/lreceiver.c
+++ b/test/app_test/lreceiver.c
@@ -139,8 +139,8 @@
 		msg = rmr_torcv_msg( mrc, msg, 1000 );				// pop every second or so to timeout if needed
 
 		if( msg ) {
-			active = 1;
 			if( msg->state == RMR_OK ) {
+				active = 1;
 				lmc = (lc_msg_t *) msg->payload;
 				clock_gettime( CLOCK_REALTIME, &lmc->turn_ts );		// mark time that we received it.
 				count++;
diff --git a/test/app_test/run_all.ksh b/test/app_test/run_all.ksh
index 69d3d79..1aebe03 100644
--- a/test/app_test/run_all.ksh
+++ b/test/app_test/run_all.ksh
@@ -1,8 +1,8 @@
 #!/usr/bin/env ksh
 # vim: ts=4 sw=4 noet :
 #==================================================================================
-#    Copyright (c) 2019 Nokia
-#    Copyright (c) 2018-2019 AT&T Intellectual Property.
+#    Copyright (c) 2019-2020 Nokia
+#    Copyright (c) 2018-2020 AT&T Intellectual Property.
 #
 #   Licensed under the Apache License, Version 2.0 (the "License");
 #   you may not use this file except in compliance with the License.
@@ -38,6 +38,7 @@
 
 build=""
 errors=0
+si_flag=""				# eventually we'll default to -S to run SI tests over NNG tests
 
 while [[ $1 == "-"* ]]
 do
@@ -45,6 +46,8 @@
 		-B)	build="-B";;
 		-e)	capture_file=$2; >$capture_file; shift;;
 		-i)	installed="-i";;
+		-N)	si_flag="";;			# turn on NNG tests (off si)
+		-S)	si_flag="-S";;			# turn on si based tests
 
 		*)	echo "'$1' is not a recognised option and is ignored";;
 	esac
@@ -53,22 +56,22 @@
 done
 
 echo "----- app --------------------"
-run_test run_app_test.ksh -v $installed $build
+run_test run_app_test.ksh $si_flag -v $installed $build
 
 echo "----- multi ------------------"
-run_test run_multi_test.ksh
+run_test run_multi_test.ksh $si_flag
 
 echo "----- round robin -----------"
-run_test run_rr_test.ksh
+run_test run_rr_test.ksh $si_flag
 
 echo "----- rts -------------------"
-run_test run_rts_test.ksh -s 5 -d 100
+run_test run_rts_test.ksh $si_flag -s 5 -d 100
 
 echo "----- extended payload nocopy no clone------"
-run_test run_exrts_test.ksh -d 10 -n 1000
+run_test run_exrts_test.ksh $si_flag -d 10 -n 1000
 
 echo "----- extended payload copy clone------"
-run_test run_exrts_test.ksh -d 10 -n 1000 -c 11
+run_test run_exrts_test.ksh $si_flag -d 10 -n 1000 -c 11
 
 if (( errors == 0 ))
 then
diff --git a/test/app_test/run_app_test.ksh b/test/app_test/run_app_test.ksh
index f83270a..65adf68 100644
--- a/test/app_test/run_app_test.ksh
+++ b/test/app_test/run_app_test.ksh
@@ -1,8 +1,8 @@
 #!/usr/bin/env ksh
 # vim: ts=4 sw=4 noet :
 #==================================================================================
-#    Copyright (c) 2019 Nokia
-#    Copyright (c) 2018-2019 AT&T Intellectual Property.
+#    Copyright (c) 2019-2020 Nokia
+#    Copyright (c) 2018-2020 AT&T Intellectual Property.
 #
 #   Licensed under the Apache License, Version 2.0 (the "License");
 #   you may not use this file except in compliance with the License.
@@ -39,7 +39,7 @@
 # file in order for the 'main' to pick them up easily.
 #
 function run_sender {
-	./sender $nmsg $delay
+	./sender${si} $nmsg $delay
 	echo $? >/tmp/PID$$.src		# must communicate state back via file b/c asynch
 }
 
@@ -47,9 +47,9 @@
 	if (( mt_receiver ))
 	then
 		echo "<TEST> testing with mt-receiver" >&2
-		./mt_receiver $nmsg
+		./mt_receiver${si} $nmsg
 	else
-		./receiver $nmsg
+		./receiver${si} $nmsg
 	fi
 	echo $? >/tmp/PID$$.rrc
 }
@@ -108,6 +108,7 @@
 keep=0
 mt_receiver=0				# -m sets in order to test with multi-threaded receive stuff
 force_make=0
+si=""						# -S sets to build and test SI versions
 
 
 while [[ $1 == -* ]]
@@ -121,15 +122,18 @@
 		-M)	force_make=1;;
 		-m)	mt_receiver=1;;
 		-n)	nmsg=$2; shift;;
+		-N)	si="";;							# build and test NNG versions (off si)
+		-S)	si="_si";;						# build and test SI95 versions
 		-v)	verbose=1;;
 
 		*)	echo "unrecognised option: $1"
-			echo "usage: $0 [-B] [-d micor-sec-delay] [-i] [-k] [-M] [-m] [-n num-msgs]"
+			echo "usage: $0 [-B] [-d micor-sec-delay] [-i] [-k] [-M] [-m] [-n num-msgs] [-S]"
 			echo "  -B forces an RMR rebuild which will use .build"
 			echo "  -i causes the installd libraries (/usr/local) to be referenced; -B is ignored if supplied"
 			echo "  -k keeps the route table"
 			echo "  -M force make on test applications"
 			echo "  -m test with mt-receive mode"
+			echo "  -S build/test SI95 based binaries"
 			echo ""
 			echo "total number of messages must > 20 to correctly test hairpin loop removal"
 			exit 1
@@ -188,11 +192,11 @@
 
 export RMR_SEED_RT=${RMR_SEED_RT:-./app_test.rt}		# allow easy testing with different rt
 
-if (( force_make )) || [[ ! -f ./sender || ! -f ./receiver ]]
+if (( force_make )) || [[ ! -f ./sender${si} || ! -f ./receiver${si} ]]
 then
-	if ! make -B >/dev/null 2>&1
+	if ! make -B sender${si} receiver${si} >/dev/null 2>&1
 	then
-		echo "[FAIL] cannot find sender binary, and cannot make it.... humm?"
+		echo "[FAIL] cannot find sender${si} and/or receiver${si}binary, and cannot make them.... humm?"
 		exit 1
 	fi
 fi
diff --git a/test/app_test/run_call_test.ksh b/test/app_test/run_call_test.ksh
index 6e03a4b..207bb40 100644
--- a/test/app_test/run_call_test.ksh
+++ b/test/app_test/run_call_test.ksh
@@ -1,8 +1,8 @@
 #!/usr/bin/env ksh
 # vim: ts=4 sw=4 noet :
 #==================================================================================
-#    Copyright (c) 2019 Nokia
-#    Copyright (c) 2018-2019 AT&T Intellectual Property.
+#    Copyright (c) 2019-2020 Nokia
+#    Copyright (c) 2018-2020 AT&T Intellectual Property.
 #
 #   Licensed under the Apache License, Version 2.0 (the "License");
 #   you may not use this file except in compliance with the License.
@@ -56,13 +56,13 @@
 # file in order for the 'main' to pick them up easily.
 #
 function run_sender {
-	./caller $nmsg $delay $nthreads
+	./caller${si} $nmsg $delay $nthreads
 	echo $? >/tmp/PID$$.src		# must communicate state back via file b/c asynch
 }
 
 # start receiver listening for nmsgs from each thread
 function run_rcvr {
-	./mt_receiver $(( nmsg * nthreads ))		# we'll test with the RMr multi threaded receive function
+	./mt_receiver${si} $(( nmsg * nthreads ))		# we'll test with the RMr multi threaded receive function
 	echo $? >/tmp/PID$$.rrc
 }
 
@@ -71,7 +71,7 @@
 # be received concurrently.
 #
 function run_pinger {
-    RMR_RTG_SVC=9999 ./sender 100 100 4 3333 >/dev/NULL 2>&1  # send pings
+    RMR_RTG_SVC=9999 ./sender${si} 100 100 4 3333 >/dev/NULL 2>&1  # send pings
 }
 
 
@@ -85,21 +85,21 @@
 # receiver, and all others go to the caller.
 
 newrt | start
-mse | 0 |  0 | localhost:43086
-mse | 1 | 10 | localhost:43086
-mse | 2 | 20 | localhost:43086
-rte | 3 | localhost:43086
-mse | 3 | 100 | localhost:43086	# special test to ensure that this does not affect previous entry
-rte | 4 | localhost:43086
-rte | 5 | localhost:4560
-rte | 6 | localhost:43086
-rte | 7 | localhost:43086
-rte | 8 | localhost:43086
-rte | 9 | localhost:43086
-rte | 10 | localhost:43086
-rte | 11 | localhost:43086
-rte | 12 | localhost:43086
-rte | 13 | localhost:43086
+mse | 0 |  0 | $localhost:43086
+mse | 1 | 10 | $localhost:43086
+mse | 2 | 20 | $localhost:43086
+rte | 3 | $localhost:43086
+mse | 3 | 100 | $localhost:43086	# special test to ensure that this does not affect previous entry
+rte | 4 | $localhost:43086
+rte | 5 | $localhost:4560
+rte | 6 | $localhost:43086
+rte | 7 | $localhost:43086
+rte | 8 | $localhost:43086
+rte | 9 | $localhost:43086
+rte | 10 | $localhost:43086
+rte | 11 | $localhost:43086
+rte | 12 | $localhost:43086
+rte | 13 | $localhost:43086
 
 newrt | end | 16
 endKat
@@ -114,6 +114,9 @@
 verbose=0
 nthreads=3
 dev_base=1					# -D turns off to allow this to run on installed libs
+force_make=0
+si=""
+localhost="localhost"
 
 
 
@@ -124,12 +127,19 @@
 		-d)	delay=$2; shift;;
 		-D)	dev_base=0;;
 		-n)	nmsg=$2; shift;;
+		-M)	force_make=1;;
+		-N) si="";;						# enable NNG testing (off si)
+		-S) si="_si"					# enable SI95 testing
+			localhost="127.0.0.1"
+			;;
 		-t)	nthreads=$2; shift;;
 		-v)	verbose=1;;
 
 		*)	echo "unrecognised option: $1"
-			echo "usage: $0 [-B] [-d micro-sec-delay] [-n num-msgs] [-t num-threads]"
-			echo "  -B forces a rebuild which will use .build"
+			echo "usage: $0 [-B] [-d micro-sec-delay] [-M] [-n num-msgs] [-S] [-t num-threads]"
+			echo "  -B forces an RMR rebuild which will use .build"
+			echo "  -M force test applications to rebuild"
+			echo "  -S build/test SI95 based binaries"
 			exit 1
 			;;
 	esac
@@ -180,11 +190,13 @@
 	mk_rt
 fi
 
-if [[ ! -f ./sender ]]
+if (( rebuild || force_make )) || [[ ! -f ./sender${si} || ! -f ./caller${si} || ! -f ./mt_receiver${si} ]]
 then
-	if ! make >/dev/null 2>&1
+	if ! make -B sender${si} caller${si} mt_receiver${si} >/tmp/PID$$.log 2>&1
 	then
-		echo "[FAIL] cannot find sender binary, and cannot make it.... humm?"
+		echo "[FAIL] cannot find caller{$si} and/or mt_receiver${si} binary, and cannot make them.... humm?"
+		cat /tmp/PID$$.log
+		rm -f /tmp/PID$$.*
 		exit 1
 	fi
 fi
diff --git a/test/app_test/run_exrts_test.ksh b/test/app_test/run_exrts_test.ksh
index cb3be8b..58913b4 100644
--- a/test/app_test/run_exrts_test.ksh
+++ b/test/app_test/run_exrts_test.ksh
@@ -1,8 +1,8 @@
 #!/usr/bin/env ksh
 # vim: ts=4 sw=4 noet :
 #==================================================================================
-#    Copyright (c) 2019 Nokia
-#    Copyright (c) 2018-2019 AT&T Intellectual Property.
+#    Copyright (c) 2019-2020 Nokia
+#    Copyright (c) 2018-2020 AT&T Intellectual Property.
 #
 #   Licensed under the Apache License, Version 2.0 (the "License");
 #   you may not use this file except in compliance with the License.
@@ -42,7 +42,7 @@
 # file in order for the 'main' to pick them up easily.
 #
 function run_sender {
-	./v_sender ${nmsg:-10} ${delay:-100000} ${mtype_start_stop:-0:1} 
+	./v_sender${si} ${nmsg:-10} ${delay:-100000} ${mtype_start_stop:-0:1} 
 	echo $? >/tmp/PID$$.src		# must communicate state back via file b/c asynch
 }
 
@@ -52,7 +52,7 @@
 
 	port=$(( 4460 + ${1:-0} ))
 	export RMR_RTG_SVC=$(( 9990 + $1 ))
-	./ex_rts_receiver $copyclone -p $port
+	./ex_rts_receiver${si} $copyclone -p $port
 	echo $? >/tmp/PID$$.$1.rrc
 }
 
@@ -105,6 +105,7 @@
 nrcvrs=1					# this is sane, but -r allows it to be set up
 use_installed=0
 mtype_start_stop=""
+si=""						# -S will enable si library testing
 
 while [[ $1 == -* ]]
 do
@@ -114,18 +115,22 @@
 		-d)	delay=${2//,/}; shift;;				# delay in micro seconds allow 1,000 to make it easier on user
 		-i)	use_installed=1;;
 		-m)	mtype_start_stop="$2"; shift;;
-		-M)	mt_call="EX_CFLAGS=-DMTC=1";;					# turn on mt-call receiver option
+		-M)	mt_call_flag="EX_CFLAGS=-DMTC=1";;	# turn on mt-call receiver option
+		-N)	si="";;								# enable nng based testing
 		-n)	nmsg=$2; shift;;
 		-r) nrcvrs=$2; shift;;
+		-S)	si="_si";;							# run SI95 based binaries
 		-v)	verbose=1;;
 
 		*)	echo "unrecognised option: $1"
-			echo "usage: $0 [-B] [-c caller-threads] [-d micor-sec-delay] [-i] [-M] [-m mtype] [-n num-msgs] [-r num-receivers] [-v]"
+			echo "usage: $0 [-B] [-c caller-threads] [-d micor-sec-delay] [-i] [-M] [-m mtype] [-n num-msgs] [-r num-receivers] [-S] [-v]"
 			echo "  -B forces a rebuild which will use .build"
 			echo "  -i will use installed libraries (/usr/local) and cause -B to be ignored if supplied)"
 			echo "  -m mtype  will set the stopping (max) message type; sender will loop through 0 through mtype-1"
 			echo "  -m start:stop  will set the starting and stopping mtypes; start through stop -1"
 			echo "  -M enables mt-call receive processing to test the RMR asynch receive pthread"
+			echo "  -N enables NNG based testing (default)"
+			echo "  -S enables SI95 based testing"
 			echo ""
 			echo "The receivers will run until they have not received a message for a few seconds. The"
 			echo "sender will send the requested number of messages, 10 by default."
@@ -178,7 +183,7 @@
 
 set_rt $nrcvrs														# set up the rt for n receivers
 
-if ! make $mt_call -B v_sender ex_rts_receiver >/tmp/PID$$.log 2>&1			# for sanity, always rebuild test binaries
+if ! make -B $mt_call_flag v_sender${si} ex_rts_receiver${si} >/tmp/PID$$.log 2>&1			# for sanity, always rebuild test binaries
 then
 	echo "[FAIL] cannot make binaries"
 	cat /tmp/PID$$.log
diff --git a/test/app_test/run_lcall_test.ksh b/test/app_test/run_lcall_test.ksh
index b01aba2..2a34d93 100644
--- a/test/app_test/run_lcall_test.ksh
+++ b/test/app_test/run_lcall_test.ksh
@@ -1,8 +1,8 @@
 #!/usr/bin/env ksh
 # vim: ts=4 sw=4 noet :
 #==================================================================================
-#    Copyright (c) 2019 Nokia
-#    Copyright (c) 2018-2019 AT&T Intellectual Property.
+#    Copyright (c) 2019-2020 Nokia
+#    Copyright (c) 2018-2020 AT&T Intellectual Property.
 #
 #   Licensed under the Apache License, Version 2.0 (the "License");
 #   you may not use this file except in compliance with the License.
@@ -51,7 +51,7 @@
 # file in order for the 'main' to pick them up easily.
 #
 function run_sender {
-	./lcaller ${nmsg:-10} ${delay:-500} ${cthreads:-3} 
+	./lcaller${si} ${nmsg:-10} ${delay:-500} ${cthreads:-3} 
 	echo $? >/tmp/PID$$.src		# must communicate state back via file b/c asynch
 }
 
@@ -61,7 +61,7 @@
 
 	port=$(( 4460 + ${1:-0} ))
 	export RMR_RTG_SVC=$(( 9990 + $1 ))
-	./lreceiver $(( ((nmsg * cthreads)/nrcvrs) + 10 )) $port
+	./lreceiver${si} $(( ((nmsg * cthreads)/nrcvrs) + 10 )) $port
 	echo $? >/tmp/PID$$.$1.rrc
 }
 
@@ -111,6 +111,8 @@
 verbose=0
 nrcvrs=3					# this is sane, but -r allows it to be set up
 use_installed=0
+force_make=0
+si=""
 
 while [[ $1 == -* ]]
 do
@@ -120,13 +122,18 @@
 		-d)	delay=$2; shift;;
 		-i)	use_installed=1;;
 		-n)	nmsg=$2; shift;;
+		-M)	force_make=1;;
+		-N)	si="";;					# build NNG binaries (turn off si)
 		-r)	nrcvrs=$2; shift;;
+		-S)	si="_si";;				# build SI95 binaries
 		-v)	verbose=1;;
 
 		*)	echo "unrecognised option: $1"
-			echo "usage: $0 [-B] [-c caller-threads] [-d micor-sec-delay] [-i] [-n num-msgs] [-r num-receivers]"
-			echo "  -B forces a rebuild which will use .build"
+			echo "usage: $0 [-B] [-c caller-threads] [-d micor-sec-delay] [-i] [-M] [-n num-msgs] [-r num-receivers] [-S]"
+			echo "  -B forces an RMR rebuild which will use .build"
 			echo "  -i will use installed libraries (/usr/local) and cause -B to be ignored if supplied)"
+			echo "  -M force test applictions to be remade"
+			echo "  -S build/test SI95 based binaries"
 			exit 1
 			;;
 	esac
@@ -175,11 +182,11 @@
 
 set_rt $nrcvrs						# set up the rt for n receivers
 
-if (( rebuild )) || [[ ! -f ./lcaller ]]
+if (( force_make || rebuild )) || [[ ! -f ./lcaller{$si} || ! -f ./lreceiver${si} ]]
 then
-	if ! make -B lcaller lreceiver >/dev/null 2>&1
+	if ! make -B lcaller${si} lreceiver${si} >/dev/null 2>&1
 	then
-		echo "[FAIL] cannot find lcaller binary, and cannot make it.... humm?"
+		echo "[FAIL] cannot find lcaller${si} and/or lreceiver${si} binary, and cannot make them.... humm?"
 		exit 1
 	fi
 fi
diff --git a/test/app_test/run_multi_test.ksh b/test/app_test/run_multi_test.ksh
index 99a147b..12ab660 100644
--- a/test/app_test/run_multi_test.ksh
+++ b/test/app_test/run_multi_test.ksh
@@ -1,8 +1,8 @@
 #!/usr/bin/env ksh
 # vim: ts=4 sw=4 noet :
 #==================================================================================
-#    Copyright (c) 2019 Nokia
-#    Copyright (c) 2018-2019 AT&T Intellectual Property.
+#    Copyright (c) 2019-2020 Nokia
+#    Copyright (c) 2018-2020 AT&T Intellectual Property.
 #
 #   Licensed under the Apache License, Version 2.0 (the "License");
 #   you may not use this file except in compliance with the License.
@@ -45,7 +45,7 @@
 # It doesn't happen all of the time, but frequently enough to be annoying. 
 #
 function run_sender {
-	RMR_ASYNC_CONN=0 ./sender $nmsg $delay
+	RMR_ASYNC_CONN=0 ./sender${si} $nmsg $delay
 	echo $? >/tmp/PID$$.src		# must communicate state back via file b/c asynch
 }
 
@@ -55,7 +55,7 @@
 
 	port=$(( 4460 + ${1:-0} ))
 	export RMR_RTG_SVC=$(( 9990 + $1 ))
-	./receiver $nmsg $port
+	./receiver${si} $nmsg $port
 	echo $? >/tmp/PID$$.$1.rrc
 }
 
@@ -104,6 +104,8 @@
 nopull=""
 verbose=0
 nrcvrs=3					# this is sane, but -r allows it to be set up
+force_make=0
+si=""
 
 while [[ $1 == -* ]]
 do
@@ -112,12 +114,17 @@
 		-b)	rebuild=1; nopull="nopull";;		# enable build but without pull
 		-d)	delay=$2; shift;;
 		-n)	nmsg=$2; shift;;
+		-N)	si="";;								# buld/run NNG binaries (turn off si)
+		-M)	force_make=1;;
 		-r)	nrcvrs=$2; shift;;
+		-S)	si="_si";;							# buld/run SI95 binaries
 		-v)	verbose=1;;
 
 		*)	echo "unrecognised option: $1"
-			echo "usage: $0 [-B] [-d micor-sec-delay] [-n num-msgs]"
+			echo "usage: $0 [-B] [-d micor-sec-delay] [-M] [-n num-msgs] [-S]"
 			echo "  -B forces an RMR rebuild which will use .build"
+			echo "  -m force test applications to be remade"
+			echo "  -S build/test SI95 based binaries"
 			exit 1
 			;;
 	esac
@@ -158,11 +165,11 @@
 
 set_rt $nrcvrs						# set up the rt for n receivers
 
-if [[ ! -f ./sender ]]
+if (( rebuild || force_make )) || [[ ! -f ./sender${si} || ! -f ./receiver${si} ]]
 then
 	if ! make >/dev/null 2>&1
 	then
-		echo "[FAIL] cannot find sender binary, and cannot make it.... humm?"
+		echo "[FAIL] cannot find sender${si} and/or receiver${si} binary, and cannot make them.... humm?"
 		exit 1
 	fi
 fi
diff --git a/test/app_test/run_rr_test.ksh b/test/app_test/run_rr_test.ksh
index 329d59f..e78cc4e 100644
--- a/test/app_test/run_rr_test.ksh
+++ b/test/app_test/run_rr_test.ksh
@@ -1,8 +1,8 @@
 #!/usr/bin/env ksh
 # vim: ts=4 sw=4 noet :
 #==================================================================================
-#    Copyright (c) 2019 Nokia
-#    Copyright (c) 2018-2019 AT&T Intellectual Property.
+#    Copyright (c) 2019-2020 Nokia
+#    Copyright (c) 2018-2020 AT&T Intellectual Property.
 #
 #   Licensed under the Apache License, Version 2.0 (the "License");
 #   you may not use this file except in compliance with the License.
@@ -43,7 +43,7 @@
 #
 function run_sender {
 	export RMR_RTG_SVC=8990
-	./sender $(( nmsg * nrcvrs ))  $delay $max_mtype
+	./sender${si} $(( nmsg * nrcvrs ))  $delay $max_mtype
 	echo $? >/tmp/PID$$.src		# must communicate state back via file b/c asynch
 }
 
@@ -53,7 +53,7 @@
 
 	port=$(( 4560 + ${1:-0} ))
 	export RMR_RTG_SVC=$(( 9990 + $1 ))
-	./receiver $nmsg $port
+	./receiver${si} $nmsg $port
 	echo $? >/tmp/PID$$.$1.rrc
 }
 
@@ -105,6 +105,8 @@
 verbose=0
 max_mtype=1					# causes all msgs to go with type 1; use -M to set up, but likely harder to validate
 nrcvrs=3					# this is sane, but -r allows it to be set up
+force_make=0
+si=""
 
 while [[ $1 == -* ]]
 do
@@ -114,12 +116,16 @@
 		-d)	delay=$2; shift;;
 		-m) max_mtype=$2; shift;;
 		-n)	nmsg=$2; shift;;
+		-N)	si="";;								# build/run NNG binaries
 		-r)	nrcvrs=$2; shift;;
+		-S)	si="_si";;							# build/run SI95 binaries
 		-v)	verbose=1;;
 
 		*)	echo "unrecognised option: $1"
-			echo "usage: $0 [-B] [-d micor-sec-delay] [-n num-msgs]"
+			echo "usage: $0 [-B] [-d micor-sec-delay] [-M] [-n num-msgs] [-S]"
 			echo "  -B forces a rebuild which will use .build"
+			echo "  -M force test applications to be remade"
+			echo "  -S build/test SI95 based binaries"
 			exit 1
 			;;
 	esac
@@ -160,11 +166,11 @@
 
 set_rt $nrcvrs
 
-if [[ ! -f ./sender ]]
+if (( rebuild || force_make )) || [[ ! -f ./sender${si} || ! -f ./receiver${si} ]]
 then
 	if ! make >/dev/null 2>&1
 	then
-		echo "[FAIL] cannot find sender binary, and cannot make it.... humm?"
+		echo "[FAIL] cannot find sender${si} and/or receiver${si} binary, and cannot make them.... humm?"
 		exit 1
 	fi
 fi
diff --git a/test/app_test/run_rts_test.ksh b/test/app_test/run_rts_test.ksh
index 4ec6afe..bb874f0 100644
--- a/test/app_test/run_rts_test.ksh
+++ b/test/app_test/run_rts_test.ksh
@@ -1,8 +1,8 @@
 #!/usr/bin/env ksh
 # vim: ts=4 sw=4 noet :
 #==================================================================================
-#    Copyright (c) 2019 Nokia
-#    Copyright (c) 2018-2019 AT&T Intellectual Property.
+#    Copyright (c) 2019-2020 Nokia
+#    Copyright (c) 2018-2020 AT&T Intellectual Property.
 #
 #   Licensed under the Apache License, Version 2.0 (the "License");
 #   you may not use this file except in compliance with the License.
@@ -42,7 +42,7 @@
 function run_sender {
 	export RMR_RTG_SVC=$(( 9991 + $1 ))
 	port=$((  43080 + $1 ))
-	./sender $nmsg $delay 5:6 $port
+	./sender${si} $nmsg $delay 5:6 $port
 	echo $? >/tmp/PID$$.$1.src		# must communicate state back via file b/c asynch
 }
 
@@ -52,7 +52,7 @@
 
 	port=4460
 	export RMR_RTG_SVC=9990
-	./receiver $(( nmsg * nsenders ))  $port
+	./receiver${si} $(( nmsg * nsenders ))  $port
 	echo $? >/tmp/PID$$.rrc
 }
 
@@ -78,6 +78,7 @@
 nopull=""
 verbose=0
 nsenders=3					# this is sane, but -s allows it to be set up
+si=""
 
 while [[ $1 == -* ]]
 do
@@ -86,12 +87,16 @@
 		-b)	rebuild=1; nopull="nopull";;	# build without pulling
 		-d)	delay=$2; shift;;
 		-n)	nmsg=$2; shift;;
+		-N) si="";;							# enable NNG tests (disable si)
 		-s)	nsenders=$2; shift;;
+		-S) si="_si";;						# enable SI95 tests
 		-v)	verbose=1;;
 
 		*)	echo "unrecognised option: $1"
-			echo "usage: $0 [-B] [-d micor-sec-delay] [-n num-msgs] [-s nsenders]"
+			echo "usage: $0 [-B] [-d micor-sec-delay] [-M] [-n num-msgs] [-s nsenders] [-S]"
 			echo "  -B forces a rebuild which will use .build"
+			echo "  -M force test applications to be remade"
+			echo "  -S build/test SI95 based binaries"
 			exit 1
 			;;
 	esac
@@ -132,11 +137,11 @@
 
 set_rt 		# create the route table
 
-if [[ ! -f ./sender ]]
+if [[ ! -f ./sender${si} || ! -f ./receiver${si} ]]
 then
-	if ! make >/dev/null 2>&1
+	if ! make ./sender${si} ./receiver${si} >/dev/null 2>&1
 	then
-		echo "[FAIL] cannot find sender binary, and cannot make it.... humm?"
+		echo "[FAIL] cannot find sender${si} and/or receiver${si} binary, and cannot make them.... humm?"
 		exit 1
 	fi
 fi