[app][sample][ipc-unittest] Update TIPC unittest

Fixup echo service to handle larger messages.
Add support for triggering unittest from Linux side.
Update unittest to accommodate the above changes.

Change-Id: I66f283b7bfb6281961bbbab3821bd7488c9b4134
diff --git a/ipc-unittest/main/main.c b/ipc-unittest/main/main.c
index 9e2bc82..f11066c 100644
--- a/ipc-unittest/main/main.c
+++ b/ipc-unittest/main/main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2014-2015 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -24,15 +24,15 @@
 #include <trace.h>
 
 /* Expected limits: should be in sync with kernel settings */
-#define MAX_USER_HANDLES    64    /* max number of user handles */
-#define MAX_PORT_PATH_LEN   64    /* max length of port path name   */
-#define MAX_PORT_BUF_NUM    32    /* max number of per port buffers */
-#define MAX_PORT_BUF_SIZE  512    /* max size of per port buffer    */
+#define MAX_USER_HANDLES     64    /* max number of user handles */
+#define MAX_PORT_PATH_LEN    64    /* max length of port path name   */
+#define MAX_PORT_BUF_NUM     32    /* max number of per port buffers */
+#define MAX_PORT_BUF_SIZE  4096    /* max size of per port buffer    */
 
 #define LOG_TAG "ipc-unittest-main"
 
 #define TLOGI(fmt, ...) \
-    fprintf(stderr, "%s: " fmt, LOG_TAG, ## __VA_ARGS__)
+    fprintf(stderr, "%s: %d: " fmt, LOG_TAG, __LINE__,  ## __VA_ARGS__)
 
 #define MSEC 1000000UL
 #define SRV_PATH_BASE   "com.android.ipc-unittest"
@@ -152,7 +152,7 @@
 	EXPECT_EQ (ERR_BAD_HANDLE, rc, "wait on invalid handle");
 
 	/* waiting on non-existing handle that is in valid range. */
-	for (uint i = 0; i < MAX_USER_HANDLES; i++) {
+	for (uint i = 2; i < MAX_USER_HANDLES; i++) {
 		rc = wait(i, &event, timeout);
 		EXPECT_EQ (ERR_NOT_FOUND, rc, "wait on invalid handle");
 	}
@@ -161,24 +161,6 @@
 }
 
 /*
- *  wait on any handle negative test
- */
-static void run_wait_any_negative_test(void)
-{
-	int rc;
-	uevent_t event;
-	lk_time_t timeout = 1000;  /* 1 sec */
-
-	TEST_BEGIN(__func__);
-
-	rc = wait_any(&event, timeout);
-	EXPECT_EQ (ERR_NOT_FOUND, rc, "no handles");
-
-	TEST_END
-}
-
-
-/*
  *  Close handle unittest
  */
 static void run_close_handle_negative_test(void)
@@ -196,7 +178,7 @@
 	EXPECT_EQ (ERR_BAD_HANDLE, rc, "closing invalid handle");
 
 	/* closing non-existing handle that is in valid range. */
-	for (uint i = 0; i < MAX_USER_HANDLES; i++) {
+	for (uint i = 2; i < MAX_USER_HANDLES; i++) {
 		rc = close(i);
 		EXPECT_EQ (ERR_NOT_FOUND, rc, "closing invalid handle");
 	}
@@ -222,7 +204,7 @@
 	EXPECT_EQ (ERR_BAD_HANDLE, rc, "set cookie for invalid handle");
 
 	/* set cookie for non-existing handle that is in valid range. */
-	for (uint i = 0; i < MAX_USER_HANDLES; i++) {
+	for (uint i = 2; i < MAX_USER_HANDLES; i++) {
 		rc = set_cookie(i, (void *) 0x3BEEF);
 		EXPECT_EQ (ERR_NOT_FOUND, rc, "set cookie for invalid handle");
 	}
@@ -290,7 +272,7 @@
 	TEST_BEGIN(__func__);
 
 	/* create maximum number of ports */
-	for (i = 0; i < MAX_USER_HANDLES-1; i++) {
+	for (i = 2; i < MAX_USER_HANDLES-1; i++) {
 		sprintf(path, "%s.port.%s%d", SRV_PATH_BASE, "test", i);
 		rc = port_create(path, 2, MAX_PORT_BUF_SIZE, 0);
 		EXPECT_GE_ZERO (rc, "create ports");
@@ -318,7 +300,7 @@
 	EXPECT_EQ (ERR_NO_RESOURCES, rc, "max ports");
 
 	/* close them all  */
-	for (i = 0; i < MAX_USER_HANDLES; i++) {
+	for (i = 2; i < MAX_USER_HANDLES; i++) {
 		/* close a valid port  */
 		rc = close(ports[i]);
 		EXPECT_EQ (NO_ERROR, rc, "closing port");
@@ -348,7 +330,7 @@
 	#define COOKIE_BASE 100
 
 	/* create maximum number of ports */
-	for (uint i = 0; i < MAX_USER_HANDLES; i++) {
+	for (uint i = 2; i < MAX_USER_HANDLES; i++) {
 		sprintf(path, "%s.port.%s%d", SRV_PATH_BASE, "test", i);
 		rc = port_create(path, 2, MAX_PORT_BUF_SIZE, 0);
 		EXPECT_GE_ZERO (rc, "max ports");
@@ -359,7 +341,7 @@
 	}
 
 	/* wait on each individual port */
-	for (uint i = 0; i < MAX_USER_HANDLES; i++) {
+	for (uint i = 2; i < MAX_USER_HANDLES; i++) {
 		/* wait with zero timeout */
 		rc = wait(ports[i], &event, 0);
 		EXPECT_EQ (NO_ERROR, rc, "zero timeout");
@@ -378,7 +360,7 @@
 	EXPECT_EQ (NO_ERROR, rc, "non-zero timeout");
 
 	/* close them all */
-	for (uint i = 0; i < MAX_USER_HANDLES; i++) {
+	for (uint i = 2; i < MAX_USER_HANDLES; i++) {
 		/* close a valid port  */
 		rc = close(ports[i]);
 		EXPECT_EQ (NO_ERROR, rc, "closing closed port");
@@ -434,7 +416,7 @@
 
 	sprintf(path, "%s.srv.%s", SRV_PATH_BASE, "datasink");
 
-	for (uint j = 0; j < MAX_USER_HANDLES; j++) {
+	for (uint j = 2; j < MAX_USER_HANDLES; j++) {
 		/* do several iterations to make sure we are not
 		   not loosing handles */
 		for (uint i = 0; i < countof(chans); i++) {
@@ -638,7 +620,7 @@
 	EXPECT_EQ (ERR_BAD_HANDLE, rc, "accept on invalid handle");
 
 	/* accept on non-existing handle that is in valid range */
-	for (uint i = 0; i < MAX_USER_HANDLES; i++) {
+	for (uint i = 2; i < MAX_USER_HANDLES; i++) {
 		rc = accept(i);
 		EXPECT_EQ (ERR_NOT_FOUND, rc, "accept on invalid handle");
 	}
@@ -671,7 +653,7 @@
 	#define COOKIE_BASE 100
 
 	/* create maximum number of ports */
-	for (uint i = 0; i < MAX_USER_HANDLES; i++) {
+	for (uint i = 2; i < MAX_USER_HANDLES; i++) {
 		sprintf(path, "%s.port.accept%d", SRV_PATH_BASE, i);
 		rc = port_create(path, 2, MAX_PORT_BUF_SIZE, 0);
 		EXPECT_GE_ZERO (rc, "max ports");
@@ -687,7 +669,7 @@
 	close(rc);
 
 	/* handle incoming connections */
-	for (uint i = 0; i < MAX_USER_HANDLES; i++ ) {
+	for (uint i = 2; i < MAX_USER_HANDLES; i++ ) {
 
 		rc = wait_any(&event, 1000);
 		EXPECT_EQ (1, rc, "accept test");
@@ -704,9 +686,9 @@
 	}
 
 	/* free 1 handle  so we have room and repeat test */
-	rc = close(ports[0]);
+	rc = close(ports[2]);
 	EXPECT_EQ(NO_ERROR, 0, "close accept test");
-	ports[0] = INVALID_IPC_HANDLE;
+	ports[2] = INVALID_IPC_HANDLE;
 
 
 	/* poke connect service to initiate connections to us */
@@ -715,7 +697,7 @@
 	close(rc);
 
 	/* handle incoming connections */
-	for (uint i = 0; i < MAX_USER_HANDLES-1; i++ ) {
+	for (uint i = 2; i < MAX_USER_HANDLES-1; i++ ) {
 
 		rc = wait_any(&event, 3000);
 		EXPECT_EQ (1, rc, "accept test");
@@ -726,14 +708,14 @@
 		EXPECT_EQ (exp_cookie, event.cookie, "accept test");
 
 		rc = accept (event.handle);
-		EXPECT_EQ (NO_ERROR, rc, "accept test");
+		EXPECT_EQ (2, rc, "accept test");
 
 		rc = close (rc);
 		EXPECT_EQ (NO_ERROR, rc, "accept test");
 	}
 
 	/* close them all */
-	for (uint i = 1; i < MAX_USER_HANDLES; i++) {
+	for (uint i = 3; i < MAX_USER_HANDLES; i++) {
 		/* close a valid port  */
 		rc = close(ports[i]);
 		EXPECT_EQ (NO_ERROR, rc, "close port");
@@ -764,7 +746,7 @@
 	EXPECT_EQ (ERR_BAD_HANDLE, rc, "get_msg on invalid handle");
 
 	/* get_msg on non-existing handle that is in valid range. */
-	for (uint i = 0; i < MAX_USER_HANDLES; i++) {
+	for (uint i = 2; i < MAX_USER_HANDLES; i++) {
 		rc = get_msg(i, &inf);
 		EXPECT_EQ (ERR_NOT_FOUND, rc, "get_msg on invalid handle");
 	}
@@ -814,7 +796,7 @@
 	EXPECT_EQ (ERR_BAD_HANDLE, rc, "put_msg on invalid handle");
 
 	/* put_msg on non-existing handle that is in valid range */
-	for (uint i = 0; i < MAX_USER_HANDLES; i++) {
+	for (uint i = 2; i < MAX_USER_HANDLES; i++) {
 		rc = put_msg (i, 0);
 		EXPECT_EQ (ERR_NOT_FOUND, rc, "put_msg on invalid handle");
 	}
@@ -930,7 +912,7 @@
 	EXPECT_EQ (ERR_FAULT, rc, "send_msg on NULL msg");
 
 	/* send_msg on non-existing handle that is in valid range */
-	for (uint i = 0; i < MAX_USER_HANDLES; i++) {
+	for (uint i = 2; i < MAX_USER_HANDLES; i++) {
 		rc = send_msg(i, &msg);
 		EXPECT_EQ (ERR_NOT_FOUND, rc, "send on invalid handle");
 
@@ -1031,7 +1013,7 @@
 	EXPECT_EQ (ERR_FAULT, rc, "read_msg on NULL msg");
 
 	/* send_msg on non-existing handle that is in valid range */
-	for (uint i = 0; i < MAX_USER_HANDLES; i++) {
+	for (uint i = 2; i < MAX_USER_HANDLES; i++) {
 		rc = read_msg(i, 0, 0, &rx_msg);
 		EXPECT_EQ (ERR_NOT_FOUND, rc, "read_msg on non existing handle");
 
@@ -1116,7 +1098,7 @@
 	rx_iov[1].base = rx_buf + sizeof(rx_buf) / 2;
 
 	/* read with invalid offset with valid iovec array */
-	rc = read_msg(chan, inf.id, inf.len, &rx_msg);
+	rc = read_msg(chan, inf.id, inf.len + 1, &rx_msg);
 	EXPECT_EQ (ERR_INVALID_ARGS, rc, "read with invalid offset");
 
 	/* read with handles */
@@ -1336,7 +1318,6 @@
 
 	/* negative tests */
 	run_wait_negative_test();
-	run_wait_any_negative_test();
 	run_close_handle_negative_test();
 	run_set_cookie_negative_test();
 	run_port_create_negative_test();
@@ -1356,19 +1337,21 @@
 }
 
 /*
- *
+ *  Application entry point
  */
-static void main_loop (void)
+int main(void)
 {
 	int rc;
 	char path[MAX_PORT_PATH_LEN];
 
+	TLOGI ("Welcome to IPC unittest!!!\n");
+
 	/* create control port and just wait on it */
         sprintf(path, "%s.%s", SRV_PATH_BASE, "ctrl");
 	rc = port_create(path,  1, MAX_PORT_BUF_SIZE, 0);
 	if (rc < 0) {
 		TLOGI("failed (%d) to create ctrl port\n", rc );
-		return;
+		return rc;
 	}
 
 	/* and just wait forever for now */
@@ -1383,30 +1366,19 @@
 				/* get connection request */
 				rc = accept(uevt.handle);
 				if (rc >= 0) {
+					/* then run unittest test */
+					run_all_tests();
+
 					/* and close it */
 					close(rc);
 				}
 			}
 		}
+		if (rc < 0)
+			break;
 	}
+
+	return rc;
 }
 
-/*
- *  Application entry point
- */
-int main(void)
-{
-	TLOGI ("Welcome to IPC unittest!!!\n");
-
-	/* wait a bit until things are settled */
-	nanosleep (0, 0, 5000 * MSEC);
-
-	/* then run unittest test */
-	run_all_tests();
-
-	/* and enter main loop */
-	main_loop ();
-
-	return 0;
-}
 
diff --git a/ipc-unittest/srv/srv.c b/ipc-unittest/srv/srv.c
index 8a5b3aa..35dc453 100644
--- a/ipc-unittest/srv/srv.c
+++ b/ipc-unittest/srv/srv.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2014-2015 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -51,6 +51,10 @@
 static handle_t datasink_port = INVALID_IPC_HANDLE;
 static handle_t echo_port     = INVALID_IPC_HANDLE;
 
+
+static void echo_handle_chan(const uevent_t *ev);
+static void datasink_handle_chan(const uevent_t *ev);
+
 /************************************************************************/
 
 /*
@@ -84,13 +88,14 @@
 /*
  *  Create port helper
  */
-static int _create_port(const char *name, uint nbuf, void *cookie)
+static int _create_port(const char *name, uint buf_num, uint buf_sz,
+                        void *cookie)
 {
 	handle_t port;
 	char path[MAX_PORT_PATH_LEN];
 
 	sprintf(path, "%s.srv.%s", SRV_PATH_BASE, name);
-	int rc = port_create(path, nbuf, 64, 0);
+	int rc = port_create(path, buf_num, buf_sz, 0);
 	if (rc < 0) {
 		TLOGI("Failed (%d) to create port\n", rc);
 		return INVALID_IPC_HANDLE;
@@ -128,32 +133,32 @@
 	int rc;
 	TLOGI ("Init unittest services!!!\n");
 
-	rc  = _create_port ("closer1", 2, closer1_handle_port);
+	rc = _create_port("closer1", 2, 64, closer1_handle_port);
 	if (rc < 0)
 		return -1;
 	closer1_port = (handle_t) rc;
 
-	rc = _create_port ("closer2", 2,  closer2_handle_port);
+	rc = _create_port("closer2", 2, 64, closer2_handle_port);
 	if (rc < 0)
 		return -1;
 	closer2_port = (handle_t) rc;
 
-	rc = _create_port ("closer3", 2, closer3_handle_port);
+	rc = _create_port("closer3", 2, 64, closer3_handle_port);
 	if (rc < 0)
 		return -1;
 	closer3_port = (handle_t) rc;
 
-	rc = _create_port ("connect", 2, connect_handle_port);
+	rc = _create_port("connect", 2, 64, connect_handle_port);
 	if (rc < 0)
 		return -1;
 	connect_port = (handle_t) rc;
 
-	rc = _create_port("datasink", 2, datasink_handle_port);
+	rc = _create_port("datasink", 2, 64, datasink_handle_port);
 	if (rc < 0)
 		return -1;
 	datasink_port = (handle_t) rc;
 
-	rc = _create_port("echo", 8, echo_handle_port);
+	rc = _create_port("echo", 8, 4096, echo_handle_port);
 	if (rc < 0)
 		return -1;
 	echo_port = (handle_t) rc;
@@ -175,7 +180,8 @@
 		close (ev->handle);
 
 		/* and recreate it */
-		connect_port = _create_port("connect", 2, connect_handle_port);
+		connect_port = _create_port("connect", 2, 64,
+		                             connect_handle_port);
 		return;
 	}
 
@@ -191,7 +197,7 @@
 		close (rc);
 
 		/* but then issue a series of connect requests */
-		for (uint i = 0; i < MAX_USER_HANDLES; i++) {
+		for (uint i = 2; i < MAX_USER_HANDLES; i++) {
 			sprintf(path, "%s.port.accept%d", SRV_PATH_BASE, i);
 			rc = connect(path, 1000);
 			close(rc);
@@ -213,7 +219,8 @@
 		/* close port */
 		close (ev->handle);
 		/* and recreate it */
-		closer1_port = _create_port("closer1", 2, closer1_handle_port);
+		closer1_port = _create_port("closer1", 2, 64,
+		                             closer1_handle_port);
 		return;
 	}
 
@@ -248,12 +255,13 @@
 		/* close port */
 		close (ev->handle);
 		/* and recreate it */
-		closer2_port = _create_port("closer1", 2, closer2_handle_port);
+		closer2_port = _create_port("closer2", 2, 64,
+		                             closer2_handle_port);
 		return;
 	}
 
 	if (ev->event & IPC_HANDLE_POLL_READY) {
-		/* new connection request, bunp counter */
+		/* new connection request, bump counter */
 		_conn_cnt++;
 
 		if (_conn_cnt & 1) {
@@ -263,7 +271,8 @@
 		/* then close the port without accepting any connections */
 		_close_port(closer2_port);
 		/* and recreate port again */
-		closer2_port = _create_port ("closer2", 2, closer2_handle_port);
+		closer2_port = _create_port ("closer2", 2, 64,
+		                              closer2_handle_port);
 		return;
 	}
 }
@@ -291,7 +300,8 @@
 		close (ev->handle);
 
 		/* and recreate it */
-		closer2_port = _create_port("closer1", 2, closer3_handle_port);
+		closer3_port = _create_port("closer3", 2, 64,
+		                             closer3_handle_port);
 		return;
 	}
 
@@ -307,8 +317,13 @@
 		/* add it to connection pool */
 		_chans[_chan_cnt++] = (handle_t) rc;
 
+		set_cookie((handle_t) rc, datasink_handle_chan);
+
 		/* when max number of connection reached */
 		if (_chan_cnt == countof(_chans)) {
+			/* wait a bit */
+			nanosleep (0, 0, 100 * MSEC);
+
 			/* close them all */
 			for (uint i = 0; i < countof(_chans); i++ ) {
 				_close_channel(_chans[i]);
@@ -398,7 +413,7 @@
 		close (ev->handle);
 
 		/* and recreate it */
-		datasink_port = _create_port("datasink", 2,
+		datasink_port = _create_port("datasink", 2, 64,
 		                              datasink_handle_port);
 		return;
 	}
@@ -425,23 +440,25 @@
 
 /******************************   echo service    **************************/
 
-static int echo_handle_msg(const uevent_t *ev)
+static uint8_t echo_msg_buf[4096];
+
+static int _echo_handle_message(const uevent_t *ev, int delay)
 {
 	int rc;
-	uint8_t buf[64];
 	ipc_msg_info_t inf;
 	ipc_msg_t      msg;
 	iovec_t        iov;
 
-	iov.base = buf;
-	iov.len  = sizeof(buf);
-	msg.num_iov = 1;
-	msg.iov     = &iov;
-	msg.num_handles = 0;
-	msg.handles  = NULL;
-
 	/* for all messages */
 	for (;;) {
+		/* init message structure */
+		iov.base = echo_msg_buf;
+		iov.len  = sizeof(echo_msg_buf);
+		msg.num_iov = 1;
+		msg.iov     = &iov;
+		msg.num_handles = 0;
+		msg.handles  = NULL;
+
 		/* get message */
 		rc = get_msg(ev->handle, &inf);
 		if (rc == ERR_NO_MSG)
@@ -454,14 +471,17 @@
 		}
 
 		/* read content */
-		rc = read_msg (ev->handle, inf.id, 0, &msg);
+		rc = read_msg(ev->handle, inf.id, 0, &msg);
 		if (rc < 0) {
 			TLOGI("failed (%d) to read_msg for chan (%d)\n",
 			      rc, ev->handle);
 			return rc;
 		}
 
-		/* retire it */
+		/* update numvber of bytes recieved */
+		iov.len = (size_t) rc;
+
+		/* retire original message */
 		rc = put_msg(ev->handle, inf.id);
 		if (rc != NO_ERROR) {
 			TLOGI("failed (%d) to put_msg for chan (%d)\n",
@@ -470,10 +490,12 @@
 		}
 
 		/* sleep a bit an send it back */
-		nanosleep (0, 0, 1000);
+		if (delay) {
+			nanosleep (0, 0, 1000);
+		}
 
-		/* end send it back */
-		rc = send_msg (ev->handle, &msg);
+		/* and send it back */
+		rc = send_msg(ev->handle, &msg);
 		if (rc < 0) {
 			TLOGI("failed (%d) to send_msg for chan (%d)\n",
 			      rc, ev->handle);
@@ -483,6 +505,11 @@
 	return NO_ERROR;
 }
 
+static int echo_handle_msg(const uevent_t *ev)
+{
+	return _echo_handle_message(ev, false);
+}
+
 /*
  *  echo service channel handler
  */
@@ -527,7 +554,8 @@
 		close (ev->handle);
 
 		/* and recreate it */
-		echo_port = _create_port("echo", 8, echo_handle_port);
+		echo_port = _create_port("echo", 8, 4096,
+		                          echo_handle_port);
 		return;
 	}