[ipc-unittest] Send test output and status back to client

Change-Id: I95149befc4448593acfc999377e937fec852ed31
diff --git a/ipc-unittest/include/app/ipc_unittest/common.h b/ipc-unittest/include/app/ipc_unittest/common.h
index 7551d77..c86b409 100644
--- a/ipc-unittest/include/app/ipc_unittest/common.h
+++ b/ipc-unittest/include/app/ipc_unittest/common.h
@@ -16,14 +16,18 @@
 
 #pragma once
 
+int ipc_printf(const char *fmt, ...);
+
 /* 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  4096    /* max size of per port buffer    */
 
-#define TLOGI(fmt, ...) \
-    fprintf(stderr, "%s: %d: " fmt, LOG_TAG, __LINE__,  ## __VA_ARGS__)
+#define TLOGI(fmt, ...) do { \
+    fprintf(stderr, "%s: %d: " fmt, LOG_TAG, __LINE__,  ## __VA_ARGS__); \
+    ipc_printf("%s: %d: " fmt, LOG_TAG, __LINE__,  ## __VA_ARGS__); \
+} while(0)
 
 #define MSEC 1000000ULL
 #define SRV_PATH_BASE   "com.android.ipc-unittest"
diff --git a/ipc-unittest/main/main.c b/ipc-unittest/main/main.c
index f3f5508..63ffd07 100644
--- a/ipc-unittest/main/main.c
+++ b/ipc-unittest/main/main.c
@@ -2630,6 +2630,76 @@
 		TLOGI("Some tests FAILED\n");
 }
 
+static int send_msg_wait(handle_t handle, struct ipc_msg *msg)
+{
+    int ret;
+    struct uevent ev;
+
+    ret = send_msg(handle, msg);
+    if (ret != ERR_NOT_ENOUGH_BUFFER) {
+        return ret;
+    }
+
+    ret= wait(handle, &ev, -1);
+    if (ret < 0) {
+        return ret;
+    }
+
+    if (ev.event & IPC_HANDLE_POLL_SEND_UNBLOCKED) {
+        return send_msg(handle, msg);
+    }
+
+    if (ev.event & IPC_HANDLE_POLL_MSG) {
+        return ERR_BUSY;
+    }
+
+    if (ev.event & IPC_HANDLE_POLL_HUP) {
+        return ERR_CHANNEL_CLOSED;
+    }
+
+    return ret;
+}
+
+enum test_message_header {
+	TEST_PASSED = 0,
+	TEST_FAILED = 1,
+	TEST_MESSAGE = 2,
+	TEST_MESSAGE_HEADER_COUNT = 3,
+};
+
+static handle_t ipc_printf_handle = INVALID_IPC_HANDLE;
+int ipc_printf(const char *fmt, ...)
+{
+	char buf[256];
+	iovec_t tx_iov = {buf, 1};
+	ipc_msg_t tx_msg = {1, &tx_iov, 0, NULL};
+	va_list ap;
+	int ret;
+	int slen;
+
+	if (ipc_printf_handle == INVALID_IPC_HANDLE) {
+		return 0;
+	}
+
+	va_start(ap, fmt);
+	ret = vsnprintf(buf + 1, sizeof(buf) - 1, fmt, ap);
+	va_end(ap);
+
+	if (ret < 0) {
+		return ret;
+	}
+	slen = ret;
+
+	buf[0] = TEST_MESSAGE;
+	tx_iov.len = 1 + ret;
+	ret = send_msg_wait(ipc_printf_handle, &tx_msg);
+	if (ret < 0) {
+		return ret;
+	}
+
+	return slen;
+}
+
 /*
  *  Application entry point
  */
@@ -2663,8 +2733,28 @@
 				/* get connection request */
 				rc = accept(uevt.handle, &peer_uuid);
 				if (rc >= 0) {
+					char tx_buffer[1];
+					iovec_t tx_iov = {
+						tx_buffer,
+						sizeof(tx_buffer)
+					};
+					ipc_msg_t tx_msg = {
+						1,
+						&tx_iov,
+						0,
+						NULL
+					};
+
 					/* then run unittest test */
+					ipc_printf_handle = rc;
 					run_all_tests();
+					ipc_printf_handle = INVALID_IPC_HANDLE;
+
+					tx_buffer[0] = (_tests_failed != 0) ?
+					               TEST_FAILED :
+					               TEST_PASSED;
+
+					send_msg_wait(rc, &tx_msg);
 
 					/* and close it */
 					close(rc);
diff --git a/ipc-unittest/srv/srv.c b/ipc-unittest/srv/srv.c
index 3b08f77..82d69b7 100644
--- a/ipc-unittest/srv/srv.c
+++ b/ipc-unittest/srv/srv.c
@@ -863,6 +863,11 @@
 	return;
 }
 
+int ipc_printf(const char *fmt, ...)
+{
+	return 0;
+}
+
 /*
  *  Main entry point of service task
  */