Move tipc-test from sample apps to /user/base/lib/tipc directory.
Bug: 159488974
Change-Id: I174ad64b4b932c9c4cddf701b0fb5cd1a128db7b
diff --git a/build-config-usertests b/build-config-usertests
index 7dc93e6..07b1441 100644
--- a/build-config-usertests
+++ b/build-config-usertests
@@ -17,7 +17,6 @@
[
# userspace tests that don't use storage
porttest("com.android.appmgmt-unittest.appmngr"),
- porttest("com.android.ipc-unittest.ctrl"),
porttest("com.android.libcxxtest"),
porttest("com.android.manifesttest"),
porttest("com.android.memref.test"),
diff --git a/ipc-unittest/include/app/ipc_unittest/common.h b/ipc-unittest/include/app/ipc_unittest/common.h
deleted file mode 100644
index 8d6d508..0000000
--- a/ipc-unittest/include/app/ipc_unittest/common.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-/* 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 FIRST_FREE_HANDLE (3)
-
-#define MSEC 1000000ULL
-#define SRV_PATH_BASE "com.android.ipc-unittest"
-
-#include <trusty_log.h>
diff --git a/ipc-unittest/include/app/ipc_unittest/ipc_unittest_uuid_consts.json b/ipc-unittest/include/app/ipc_unittest/ipc_unittest_uuid_consts.json
deleted file mode 100644
index 9f59750..0000000
--- a/ipc-unittest/include/app/ipc_unittest/ipc_unittest_uuid_consts.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "header": "ipc_unittest_uuid_consts.h",
- "constants":[
- {
- "name": "IPC_UNITTEST_MAIN_APP_UUID",
- "value": "766072e8-414e-48fc-9f8f-fb9a6f144124",
- "type": "uuid"
- },
- {
- "name": "IPC_UNITTEST_SRV_APP_UUID",
- "value": "fee67f9f-e1b1-4e3d-8455-047f6001afef",
- "type": "uuid"
- }
- ]
-}
diff --git a/ipc-unittest/main/main.c b/ipc-unittest/main/main.c
deleted file mode 100644
index d759f46..0000000
--- a/ipc-unittest/main/main.c
+++ /dev/null
@@ -1,2556 +0,0 @@
-/*
- * 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <trusty_ipc.h>
-#include <uapi/err.h>
-
-#define TLOG_TAG "ipc-unittest-main"
-#include <trusty_unittest.h>
-
-#include <app/ipc_unittest/common.h>
-#include <ipc_unittest_uuid_consts.h>
-#include <lib/tipc/tipc.h>
-#include <lib/unittest/unittest.h>
-
-/* */
-static handle_t handle_base; /* base of valid handle range */
-
-static const uuid_t srv_app_uuid = IPC_UNITTEST_SRV_APP_UUID;
-static const uintptr_t COOKIE_BASE = 100;
-
-#define ABORT_IF(_cond, lbl) \
- { \
- if (_cond) { \
- goto lbl; \
- } \
- }
-
-#define ABORT_IF_NOT_OK(lbl) ABORT_IF((HasFailure()), lbl)
-
-#define EXPECT_GT_ZERO(val, args...) EXPECT_GT(val, 0, ##args)
-#define EXPECT_GE_ZERO(val, args...) EXPECT_GE(val, 0, ##args)
-
-/****************************************************************************/
-
-/*
- * Fill specified buffer with incremental pattern
- */
-static void fill_test_buf(uint8_t* buf, size_t cnt, uint8_t seed) {
- if (!buf || !cnt)
- return;
-
- for (; cnt > 0; cnt--) {
- *buf++ = seed++;
- }
-}
-
-/*
- * Local wrapper on top of async connect that provides
- * synchronos connect with timeout.
- */
-int sync_connect(const char* path, unsigned int timeout) {
- int rc;
- uevent_t evt;
- handle_t chan;
-
- rc = connect(path, IPC_CONNECT_ASYNC | IPC_CONNECT_WAIT_FOR_PORT);
- if (rc >= 0) {
- chan = (handle_t)rc;
- rc = wait(chan, &evt, timeout);
- if (rc == 0) {
- rc = ERR_BAD_STATE;
- if (evt.handle == chan) {
- if (evt.event & IPC_HANDLE_POLL_READY)
- return chan;
-
- if (evt.event & IPC_HANDLE_POLL_HUP)
- rc = ERR_CHANNEL_CLOSED;
- }
- }
- close(chan);
- }
- return rc;
-}
-
-/****************************************************************************/
-
-/*
- * wait on handle negative test
- */
-TEST(ipc, wait_negative) {
- int rc;
- uevent_t event;
- uint32_t timeout = 1000; // 1 sec
-
- /* waiting on invalid handle. */
- rc = wait(INVALID_IPC_HANDLE, &event, timeout);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "wait on invalid handle");
-
- /*
- * call wait on an invalid (out of range) handle
- *
- * check handling of the following cases:
- * - handle is on the upper boundary of valid handle range
- * - handle is above of the upper boundary of valid handle range
- * - handle is below of valid handle range
- *
- * in all cases, the expected result is ERR_BAD_HANDLE error.
- */
- rc = wait(handle_base + MAX_USER_HANDLES, &event, timeout);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "wait on invalid handle");
-
- rc = wait(handle_base + MAX_USER_HANDLES + 1, &event, timeout);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "wait on invalid handle");
-
- rc = wait(handle_base - 1, &event, timeout);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "wait on invalid handle");
-
- /* waiting on non-existing handle that is in valid range. */
- for (unsigned int i = FIRST_FREE_HANDLE; i < MAX_USER_HANDLES; i++) {
- rc = wait(handle_base + i, &event, timeout);
- EXPECT_EQ(ERR_NOT_FOUND, rc, "wait on invalid handle");
- }
-}
-
-/*
- * Close handle unittest
- */
-TEST(ipc, close_handle_negative) {
- int rc;
-
- /* closing an invalid (negative value) handle. */
- rc = close(INVALID_IPC_HANDLE);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "closing invalid handle");
-
- /*
- * call close on an invalid (out of range) handle
- *
- * check handling of the following cases:
- * - handle is on the upper boundary of valid handle range
- * - handle is above of the upper boundary of valid handle range
- * - handle is below of valid handle range
- *
- * in all cases, the expected result is ERR_BAD_HANDLE error.
- */
- rc = close(handle_base + MAX_USER_HANDLES);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "closing invalid handle");
-
- rc = close(handle_base + MAX_USER_HANDLES + 1);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "closing invalid handle");
-
- rc = close(handle_base - 1);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "closing invalid handle");
-
- /* closing non-existing handle that is in valid range. */
- for (unsigned int i = FIRST_FREE_HANDLE; i < MAX_USER_HANDLES; i++) {
- rc = close(handle_base + i);
- EXPECT_EQ(ERR_NOT_FOUND, rc, "closing invalid handle");
- }
-}
-
-/*
- * Set cookie negative unittest
- */
-TEST(ipc, set_cookie_negative) {
- int rc;
-
- /* set cookie for invalid (negative value) handle. */
- rc = set_cookie(INVALID_IPC_HANDLE, (void*)0x1BEEF);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "set cookie for invalid handle");
-
- /*
- * calling set cookie for an invalid (out of range) handle
- *
- * check handling of the following cases:
- * - handle is on the upper boundary of valid handle range
- * - handle is above of the upper boundary of valid handle range
- * - handle is below of valid handle range
- *
- * in all cases, the expected result is ERR_BAD_HANDLE error.
- */
- rc = set_cookie(handle_base + MAX_USER_HANDLES, (void*)0x2BEEF);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "set cookie for invalid handle");
-
- rc = set_cookie(handle_base + MAX_USER_HANDLES + 1, (void*)0x2BEEF);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "set cookie for invalid handle");
-
- rc = set_cookie(handle_base - 1, (void*)0x2BEEF);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "set cookie for invalid handle");
-
- /* set cookie for non-existing handle that is in valid range. */
- for (unsigned int i = FIRST_FREE_HANDLE; i < MAX_USER_HANDLES; i++) {
- rc = set_cookie(handle_base + i, (void*)0x3BEEF);
- EXPECT_EQ(ERR_NOT_FOUND, rc, "set cookie for invalid handle");
- }
-}
-
-/****************************************************************************/
-
-/*
- * Port create unittest
- */
-TEST(ipc, port_create_negative) {
- int rc;
- char path[MAX_PORT_PATH_LEN + 16];
-
- /* create port with empty path */
- path[0] = '\0';
- rc = port_create(path, 2, 64, 0);
- EXPECT_EQ(ERR_INVALID_ARGS, rc, "empty path srv");
-
- /* create port with zero buffers */
- sprintf(path, "%s.port", SRV_PATH_BASE);
- rc = port_create(path, 0, 64, 0);
- EXPECT_EQ(ERR_INVALID_ARGS, rc, "no buffers");
-
- /* create port with zero buffer size */
- sprintf(path, "%s.port", SRV_PATH_BASE);
- rc = port_create(path, 2, 0, 0);
- EXPECT_EQ(ERR_INVALID_ARGS, rc, "zero buf size");
-
- /* create port with large number of buffers */
- sprintf(path, "%s.port", SRV_PATH_BASE);
- rc = port_create(path, MAX_PORT_BUF_NUM * 100, 64, 0);
- EXPECT_EQ(ERR_INVALID_ARGS, rc, "large buf num");
-
- /* create port with large buffer size */
- sprintf(path, "%s.port", SRV_PATH_BASE);
- rc = port_create(path, 2, MAX_PORT_BUF_SIZE * 100, 0);
- EXPECT_EQ(ERR_INVALID_ARGS, rc, "large buf size");
-
- /* create port with path oversized name */
- int len = sprintf(path, "%s.port", SRV_PATH_BASE);
- for (size_t i = len; i < sizeof(path); i++)
- path[i] = 'a';
- path[sizeof(path) - 1] = '\0';
- rc = port_create(path, 2, MAX_PORT_BUF_SIZE, 0);
- EXPECT_EQ(ERR_INVALID_ARGS, rc, "path is too long");
- rc = close((handle_t)rc);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "close port");
-}
-
-TEST(ipc, port_create) {
- int rc;
- unsigned int i;
- char path[MAX_PORT_PATH_LEN];
- handle_t ports[MAX_USER_HANDLES];
-
- /* create maximum number of ports */
- for (i = FIRST_FREE_HANDLE; 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_GT_ZERO(rc, "create ports");
- ports[i] = (handle_t)rc;
-
- /* create a new port that collide with an existing port */
- rc = port_create(path, 2, MAX_PORT_BUF_SIZE, 0);
- EXPECT_EQ(ERR_ALREADY_EXISTS, rc, "create existing port");
- }
-
- /* create one more that should succeed */
- sprintf(path, "%s.port.%s%d", SRV_PATH_BASE, "test", i);
- rc = port_create(path, 2, MAX_PORT_BUF_SIZE, 0);
- EXPECT_GT_ZERO(rc, "create ports");
- ports[i] = (handle_t)rc;
-
- /* but creating colliding port should fail with different
- error code because we actually exceeded max number of
- handles instead of colliding with an existing path */
- rc = port_create(path, 2, MAX_PORT_BUF_SIZE, 0);
- EXPECT_EQ(ERR_NO_RESOURCES, rc, "create existing port");
-
- sprintf(path, "%s.port.%s%d", SRV_PATH_BASE, "test", MAX_USER_HANDLES);
- rc = port_create(path, 2, MAX_PORT_BUF_SIZE, 0);
- EXPECT_EQ(ERR_NO_RESOURCES, rc, "max ports");
-
- /* close them all */
- for (i = FIRST_FREE_HANDLE; i < MAX_USER_HANDLES; i++) {
- /* close a valid port */
- rc = close(ports[i]);
- EXPECT_EQ(NO_ERROR, rc, "closing port");
-
- /* close previously closed port. It should fail! */
- rc = close(ports[i]);
- EXPECT_EQ(ERR_NOT_FOUND, rc, "closing closed port");
-
- ports[i] = INVALID_IPC_HANDLE;
- }
-}
-
-/*
- *
- */
-TEST(ipc, wait_on_port) {
- int rc;
- uevent_t event;
- char path[MAX_PORT_PATH_LEN];
- handle_t ports[MAX_USER_HANDLES];
-
- /* create maximum number of ports */
- for (unsigned int i = FIRST_FREE_HANDLE; 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_GT_ZERO(rc, "max ports");
- ports[i] = (handle_t)rc;
-
- rc = set_cookie(ports[i], (void*)(COOKIE_BASE + i));
- EXPECT_EQ(NO_ERROR, rc, "set cookie on port");
- }
-
- /* wait on each individual port */
- for (unsigned int i = FIRST_FREE_HANDLE; i < MAX_USER_HANDLES; i++) {
- /* wait with zero timeout */
- rc = wait(ports[i], &event, 0);
- EXPECT_EQ(ERR_TIMED_OUT, rc, "zero timeout");
-
- /* wait with non-zero timeout */
- rc = wait(ports[i], &event, 100);
- EXPECT_EQ(ERR_TIMED_OUT, rc, "non-zero timeout");
- }
-
- /* wait on all ports with zero timeout */
- rc = wait_any(&event, 0);
- EXPECT_EQ(ERR_TIMED_OUT, rc, "zero timeout");
-
- /* wait on all ports with non-zero timeout*/
- rc = wait_any(&event, 100);
- EXPECT_EQ(ERR_TIMED_OUT, rc, "non-zero timeout");
-
- /* close them all */
- for (unsigned int i = FIRST_FREE_HANDLE; i < MAX_USER_HANDLES; i++) {
- /* close a valid port */
- rc = close(ports[i]);
- EXPECT_EQ(NO_ERROR, rc, "closing closed port");
- ports[i] = INVALID_IPC_HANDLE;
- }
-}
-
-/****************************************************************************/
-
-/*
- * Connect unittests
- */
-TEST(ipc, connect_negative) {
- int rc;
- char path[MAX_PORT_PATH_LEN + 16] = "";
-
- /* try to connect to port with an empty name */
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_EQ(ERR_INVALID_ARGS, rc, "empty path");
-
- /* try to connect to non-existing port */
- sprintf(path, "%s.conn.%s", SRV_PATH_BASE, "blah-blah");
- rc = connect(path, 0);
- EXPECT_EQ(ERR_NOT_FOUND, rc, "non-existing path");
-
- /* try to connect to non-existing port */
- sprintf(path, "%s.conn.%s", SRV_PATH_BASE, "blah-blah");
- rc = connect(path, IPC_CONNECT_ASYNC);
- EXPECT_EQ(ERR_NOT_FOUND, rc, "non-existing path");
-
- /* try to connect to port with very long name */
- int len = sprintf(path, "%s.conn.", SRV_PATH_BASE);
- for (size_t i = len; i < sizeof(path); i++)
- path[i] = 'a';
- path[sizeof(path) - 1] = '\0';
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_EQ(ERR_INVALID_ARGS, rc, "long path");
-
- rc = close((handle_t)rc);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "close channel");
-}
-
-TEST(ipc, connect_close) {
- int rc;
- char path[MAX_PORT_PATH_LEN];
- handle_t chans[16];
-
- sprintf(path, "%s.srv.%s", SRV_PATH_BASE, "datasink");
-
- for (unsigned int j = FIRST_FREE_HANDLE; j < MAX_USER_HANDLES; j++) {
- /* do several iterations to make sure we are not
- not loosing handles */
- for (unsigned int i = 0; i < countof(chans); i++) {
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_GT_ZERO(rc, "connect/close");
- chans[i] = (handle_t)rc;
- }
-
- for (unsigned int i = 0; i < countof(chans); i++) {
- rc = close(chans[i]);
- EXPECT_EQ(NO_ERROR, rc, "connect/close");
- }
- }
-}
-
-static void run_connect_close_by_peer_test(const char* test) {
- int rc;
- char path[MAX_PORT_PATH_LEN];
- uevent_t event;
- handle_t chans[16];
- unsigned int chan_cnt = 0;
-
- /*
- * open up to 16 connection to specified test port which would
- * close them all in a different way:
- */
- sprintf(path, "%s.srv.%s", SRV_PATH_BASE, test);
- for (unsigned int i = 0; i < countof(chans); i++) {
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
-
- /*
- * depending on task scheduling connect might return real
- * handle that will be closed later or it might return
- * ERR_CHANNEL_CLOSED error if the channel has already been
- * closed. Both cases are correct and must be handled.
- */
- if (rc >= 0) {
- /* got real handle */
- chans[i] = (handle_t)rc;
-
- /* attach cookie for returned channel */
- rc = set_cookie((handle_t)rc, (void*)(COOKIE_BASE + i));
- EXPECT_EQ(NO_ERROR, rc, "%s", test);
-
- chan_cnt++;
- } else {
- /* could be already closed channel */
- EXPECT_EQ(ERR_CHANNEL_CLOSED, rc, "%s", test);
- }
-
- /* check if any channels are closed */
- while ((rc = wait_any(&event, 0)) == NO_ERROR) {
- EXPECT_EQ(IPC_HANDLE_POLL_HUP, event.event, "%s", test);
- uintptr_t idx = (uintptr_t)event.cookie - COOKIE_BASE;
- EXPECT_EQ(chans[idx], event.handle, "%s", test);
- EXPECT_GT(countof(chans), idx, "%s", test);
- if (idx < countof(chans)) {
- rc = close(chans[idx]);
- EXPECT_EQ(NO_ERROR, rc, "%s", test);
- chans[idx] = INVALID_IPC_HANDLE;
- }
- chan_cnt--;
- }
- }
-
- /* wait until all channels are closed */
- while (chan_cnt) {
- rc = wait_any(&event, 10000);
- EXPECT_EQ(NO_ERROR, rc, "%s", test);
- EXPECT_EQ(IPC_HANDLE_POLL_HUP, event.event, "%s", test);
-
- uintptr_t idx = (uintptr_t)event.cookie - COOKIE_BASE;
- EXPECT_GT(countof(chans), idx, "%s", test);
- EXPECT_EQ(chans[idx], event.handle, "%s", test);
- if (idx < countof(chans)) {
- rc = close(chans[idx]);
- EXPECT_EQ(NO_ERROR, rc, "%s", test);
- chans[idx] = INVALID_IPC_HANDLE;
- }
- chan_cnt--;
- }
-
- EXPECT_EQ(0, chan_cnt, "%s", test);
-}
-
-TEST(ipc, connect_close_by_peer_1) {
- run_connect_close_by_peer_test("closer1");
-}
-
-TEST(ipc, connect_close_by_peer_2) {
- run_connect_close_by_peer_test("closer2");
-}
-
-TEST(ipc, connect_close_by_peer_3) {
- run_connect_close_by_peer_test("closer3");
-}
-
-TEST(ipc, async_connect) {
- int rc;
- handle_t chan;
- uevent_t event;
- uuid_t peer_uuid = UUID_INITIAL_VALUE(peer_uuid);
- char path[MAX_PORT_PATH_LEN];
-
- sprintf(path, "%s.main.%s", SRV_PATH_BASE, "async");
-
- /* connect to non existing port synchronously without wait_for_port */
- rc = connect(path, 0);
- EXPECT_EQ(ERR_NOT_FOUND, rc, "async");
- rc = close((handle_t)rc);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "async");
-
- /* connect to non existing port asynchronously without wait_for_port */
- rc = connect(path, IPC_CONNECT_ASYNC);
- EXPECT_EQ(ERR_NOT_FOUND, rc, "async");
- rc = close((handle_t)rc);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "async");
-
- /* connect to non existing port asynchronously with wait_for_port */
- rc = connect(path, IPC_CONNECT_ASYNC | IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_GT_ZERO(rc, "async");
- if (rc >= 0) {
- chan = (handle_t)rc;
-
- /* wait on channel */
- rc = wait(chan, &event, 1000);
- EXPECT_EQ(ERR_TIMED_OUT, rc, "async");
-
- /* and close it */
- rc = close(chan);
- EXPECT_EQ(NO_ERROR, rc, "async");
- }
-
- /* connect to non-existing port asyncronously with wait_for_port */
- rc = connect(path, IPC_CONNECT_ASYNC | IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_GT_ZERO(rc, "async");
- chan = (handle_t)rc;
-
- if (rc >= 0) {
- handle_t port;
- uint32_t exp_event;
-
- /* wait on channel for connect */
- rc = wait(chan, &event, 100);
- EXPECT_EQ(ERR_TIMED_OUT, rc, "async");
-
- /* now create port */
- rc = port_create(path, 1, 64, IPC_PORT_ALLOW_TA_CONNECT);
- EXPECT_GT_ZERO(rc, "async");
- if (rc >= 0) {
- port = (handle_t)rc;
-
- /* and wait for incomming connections */
- exp_event = IPC_HANDLE_POLL_READY;
- rc = wait(port, &event, 1000);
- EXPECT_EQ(NO_ERROR, rc, "async");
- EXPECT_EQ(exp_event, event.event, "async");
-
- if (rc == NO_ERROR) {
- handle_t srv_chan;
-
- /* got one, accept it */
- rc = accept(port, &peer_uuid);
- EXPECT_GT_ZERO(rc, "async");
- srv_chan = (handle_t)rc;
-
- /* and close it */
- close(srv_chan);
-
- /* now wait on original chan:
- * there should be READY and HUP events
- */
- exp_event = IPC_HANDLE_POLL_READY | IPC_HANDLE_POLL_HUP;
- rc = wait(chan, &event, 1000);
- EXPECT_EQ(NO_ERROR, rc, "async");
- EXPECT_EQ(exp_event, event.event, "async");
- }
- close(port);
- }
- close(chan);
- }
-}
-
-TEST(ipc, connect_selfie) {
- int rc, rc1;
- uuid_t peer_uuid = UUID_INITIAL_VALUE(peer_uuid);
- uuid_t zero_uuid = UUID_INITIAL_VALUE(zero_uuid);
- char path[MAX_PORT_PATH_LEN];
- uint32_t connect_timeout = 1000; // 1 sec
-
- /* Try to connect to port that we register ourself.
- It is not very usefull scenario, just to make sure that
- nothing bad is happening */
- sprintf(path, "%s.main.%s", SRV_PATH_BASE, "selfie");
- rc = port_create(path, 2, MAX_PORT_BUF_SIZE, IPC_PORT_ALLOW_TA_CONNECT);
- EXPECT_GT_ZERO(rc, "selfie");
-
- if (rc >= 0) {
- handle_t test_port = rc;
-
- /* Since we are single threaded and cannot accept connection
- * we will always timeout.
- */
-
- /* with non-zero timeout */
- rc = sync_connect(path, connect_timeout);
- EXPECT_EQ(ERR_TIMED_OUT, rc, "selfie");
-
- /* with zero timeout */
- rc = sync_connect(path, 0);
- EXPECT_EQ(ERR_TIMED_OUT, rc, "selfie");
-
- /* since we did not call wait on port yet we have
- * 2 connection requests pending (attached to port)
- * teared down by peer (us).
- */
- uevent_t event;
- unsigned int exp_event = IPC_HANDLE_POLL_READY;
-
- int rc = wait_any(&event, INFINITE_TIME);
- EXPECT_EQ(NO_ERROR, rc, "wait on port");
- EXPECT_EQ(test_port, event.handle, "wait on port");
- EXPECT_EQ(exp_event, event.event, "wait on port");
-
- if (rc == NO_ERROR && (event.event & IPC_HANDLE_POLL_READY)) {
- /* we have pending connection, but it is already closed */
- rc = accept(test_port, &peer_uuid);
- EXPECT_EQ(ERR_CHANNEL_CLOSED, rc, "accept");
-
- rc1 = memcmp(&peer_uuid, &zero_uuid, sizeof(zero_uuid));
- EXPECT_EQ(0, rc1, "accept")
-
- /* the second one is closed too */
- rc = accept(test_port, &peer_uuid);
- EXPECT_EQ(ERR_CHANNEL_CLOSED, rc, "accept");
-
- rc1 = memcmp(&peer_uuid, &zero_uuid, sizeof(zero_uuid));
- EXPECT_EQ(0, rc1, "accept")
-
- /* There should be no more pending connections so next
- accept should return ERR_NO_MSG */
- rc = accept(test_port, &peer_uuid);
- EXPECT_EQ(ERR_NO_MSG, rc, "accept");
-
- rc1 = memcmp(&peer_uuid, &zero_uuid, sizeof(zero_uuid));
- EXPECT_EQ(0, rc1, "accept")
- }
-
- /* add couple connections back and destroy them along with port */
- rc = sync_connect(path, 0);
- EXPECT_EQ(ERR_TIMED_OUT, rc, "selfie");
-
- rc = sync_connect(path, 0);
- EXPECT_EQ(ERR_TIMED_OUT, rc, "selfie");
-
- /* close selfie port */
- rc = close(test_port);
- EXPECT_EQ(NO_ERROR, rc, "close selfie");
- }
-}
-
-TEST(ipc, connect_access) {
- int rc;
- char path[MAX_PORT_PATH_LEN];
-
- /* open connection to NS only accessible service */
- sprintf(path, "%s.srv.%s", SRV_PATH_BASE, "ns_only");
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
-
- /* It is expected to fail */
- EXPECT_EQ(ERR_ACCESS_DENIED, rc, "connect to ns_only");
-
- if (rc >= 0)
- close((handle_t)rc);
-
- /* open connection to TA only accessible service */
- sprintf(path, "%s.srv.%s", SRV_PATH_BASE, "ta_only");
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
-
- /* it is expected to succeed */
- EXPECT_GT_ZERO(rc, "connect to ta_only");
-
- if (rc >= 0)
- close((handle_t)rc);
-}
-
-/****************************************************************************/
-
-/*
- * Accept negative test
- */
-TEST(ipc, accept_negative) {
- int rc, rc1;
- char path[MAX_PORT_PATH_LEN];
- handle_t chan;
- uuid_t peer_uuid = UUID_INITIAL_VALUE(peer_uuid);
- uuid_t zero_uuid = UUID_INITIAL_VALUE(zero_uuid);
-
- /* accept on invalid (negative value) handle */
- rc = accept(INVALID_IPC_HANDLE, &peer_uuid);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "accept on invalid handle");
-
- rc1 = memcmp(&peer_uuid, &zero_uuid, sizeof(zero_uuid));
- EXPECT_EQ(0, rc1, "accept")
-
- /*
- * calling accept on an invalid (out of range) handle
- *
- * check handling of the following cases:
- * - handle is on the upper boundary of valid handle range
- * - handle is above of the upper boundary of valid handle range
- * - handle is below of valid handle range
- *
- * in all cases, the expected result is ERR_BAD_HANDLE error.
- */
- rc = accept(handle_base + MAX_USER_HANDLES, &peer_uuid);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "accept on invalid handle");
-
- rc = accept(handle_base + MAX_USER_HANDLES + 1, &peer_uuid);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "accept on invalid handle");
-
- rc = accept(handle_base - 1, &peer_uuid);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "accept on invalid handle");
-
- rc1 = memcmp(&peer_uuid, &zero_uuid, sizeof(zero_uuid));
- EXPECT_EQ(0, rc1, "accept")
-
- /* accept on non-existing handle that is in valid range */
- for (unsigned int i = FIRST_FREE_HANDLE; i < MAX_USER_HANDLES; i++) {
- rc = accept(handle_base + i, &peer_uuid);
- EXPECT_EQ(ERR_NOT_FOUND, rc, "accept on invalid handle");
-
- rc1 = memcmp(&peer_uuid, &zero_uuid, sizeof(zero_uuid));
- EXPECT_EQ(0, rc1, "accept")
- }
-
- /* connect to datasink service */
- sprintf(path, "%s.srv.%s", SRV_PATH_BASE, "datasink");
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_GT_ZERO(rc, "connect to datasink");
- chan = (handle_t)rc;
-
- /* call accept on channel handle which is an invalid operation */
- rc = accept(chan, &peer_uuid);
- EXPECT_EQ(ERR_INVALID_ARGS, rc, "accept on channel");
-
- rc1 = memcmp(&peer_uuid, &zero_uuid, sizeof(zero_uuid));
- EXPECT_EQ(0, rc1, "accept")
-
- rc = close(chan);
- EXPECT_EQ(NO_ERROR, rc, "close channnel")
-}
-
-
-/*
- * Disabled per b/140836874 - believed to be a race in the test code, not
- * in IPC.
- */
-TEST(ipc, DISABLED_accept) {
- int rc, rc1;
- uevent_t event;
- char path[MAX_PORT_PATH_LEN];
- handle_t ports[MAX_USER_HANDLES];
- uuid_t peer_uuid = UUID_INITIAL_VALUE(peer_uuid);
- uuid_t zero_uuid = UUID_INITIAL_VALUE(zero_uuid);
-
- /* create maximum number of ports */
- for (unsigned int i = FIRST_FREE_HANDLE; i < MAX_USER_HANDLES; i++) {
- sprintf(path, "%s.port.accept%d", SRV_PATH_BASE, i);
- rc = port_create(path, 2, MAX_PORT_BUF_SIZE, IPC_PORT_ALLOW_TA_CONNECT);
- EXPECT_GT_ZERO(rc, "max ports");
- ports[i] = (handle_t)rc;
-
- rc = set_cookie(ports[i], (void*)(COOKIE_BASE + ports[i]));
- EXPECT_EQ(NO_ERROR, rc, "set cookie on port");
- }
-
- /* poke connect service to initiate connections to us */
- sprintf(path, "%s.srv.%s", SRV_PATH_BASE, "connect");
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
- if (rc >= 0)
- close((handle_t)rc);
-
- /* handle incoming connections */
- for (unsigned int i = FIRST_FREE_HANDLE; i < MAX_USER_HANDLES; i++) {
- rc = wait_any(&event, 1000);
- EXPECT_EQ(NO_ERROR, rc, "accept test");
- EXPECT_EQ(IPC_HANDLE_POLL_READY, event.event, "accept test");
-
- /* check port cookie */
- void* exp_cookie = (void*)(COOKIE_BASE + event.handle);
- EXPECT_EQ(exp_cookie, event.cookie, "accept test");
-
- /* accept connection - should fail because we do not
- have any room for handles */
- rc = accept(event.handle, &peer_uuid);
- EXPECT_EQ(ERR_NO_RESOURCES, rc, "accept test");
-
- /* check peer uuid */
- rc1 = memcmp(&peer_uuid, &zero_uuid, sizeof(zero_uuid));
- EXPECT_EQ(0, rc1, "accept test")
- }
-
- /* free 1 handle so we have room and repeat test */
- rc = close(ports[FIRST_FREE_HANDLE]);
- EXPECT_EQ(NO_ERROR, 0, "close accept test");
- ports[2] = INVALID_IPC_HANDLE;
-
- /* poke connect service to initiate connections to us */
- sprintf(path, "%s.srv.%s", SRV_PATH_BASE, "connect");
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
- if (rc >= 0)
- close((handle_t)rc);
-
- /* handle incoming connections */
- for (unsigned int i = FIRST_FREE_HANDLE; i < MAX_USER_HANDLES - 1; i++) {
- rc = wait_any(&event, 3000);
- EXPECT_EQ(NO_ERROR, rc, "accept test");
- EXPECT_EQ(IPC_HANDLE_POLL_READY, event.event, "accept test");
-
- /* check port cookie */
- void* exp_cookie = (void*)(COOKIE_BASE + event.handle);
- EXPECT_EQ(exp_cookie, event.cookie, "accept test");
-
- rc = accept(event.handle, &peer_uuid);
- EXPECT_EQ(handle_base + FIRST_FREE_HANDLE, rc, "accept test");
-
- /* check peer uuid */
- rc1 = memcmp(&peer_uuid, &srv_app_uuid, sizeof(srv_app_uuid));
- EXPECT_EQ(0, rc1, "accept test")
-
- rc = close((handle_t)rc);
- EXPECT_EQ(NO_ERROR, rc, "accept test");
- }
-
- /* close them all */
- for (unsigned int i = FIRST_FREE_HANDLE + 1; i < MAX_USER_HANDLES; i++) {
- /* close a valid port */
- rc = close(ports[i]);
- EXPECT_EQ(NO_ERROR, rc, "close port");
- ports[i] = INVALID_IPC_HANDLE;
- }
-}
-
-/****************************************************************************/
-
-TEST(ipc, get_msg_negative) {
- int rc;
- ipc_msg_info_t inf;
- handle_t port;
- handle_t chan;
- char path[MAX_PORT_PATH_LEN];
-
- /* get_msg on invalid (negative value) handle. */
- rc = get_msg(INVALID_IPC_HANDLE, &inf);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "get_msg on invalid handle");
-
- /*
- * calling get_msg on an invalid (out of range) handle
- *
- * check handling of the following cases:
- * - handle is on the upper boundary of valid handle range
- * - handle is above of the upper boundary of valid handle range
- * - handle is below of valid handle range
- *
- * in all cases, the expected result is ERR_BAD_HANDLE error.
- */
- rc = get_msg(handle_base + MAX_USER_HANDLES, &inf);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "get_msg on invalid handle");
-
- rc = get_msg(handle_base + MAX_USER_HANDLES + 1, &inf);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "get_msg on invalid handle");
-
- rc = get_msg(handle_base - 1, &inf);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "get_msg on invalid handle");
-
- /* get_msg on non-existing handle that is in valid range. */
- for (unsigned int i = FIRST_FREE_HANDLE; i < MAX_USER_HANDLES; i++) {
- rc = get_msg(handle_base + i, &inf);
- EXPECT_EQ(ERR_NOT_FOUND, rc, "get_msg on invalid handle");
- }
-
- /* calling get_msg on port handle should fail
- because get_msg is only applicable to channels */
- sprintf(path, "%s.main.%s", SRV_PATH_BASE, "datasink");
- rc = port_create(path, 2, MAX_PORT_BUF_SIZE, IPC_PORT_ALLOW_TA_CONNECT);
- EXPECT_GT_ZERO(rc, "create datasink port");
- port = (handle_t)rc;
-
- rc = get_msg(port, &inf);
- EXPECT_EQ(ERR_INVALID_ARGS, rc, "get_msg on port");
- close(port);
-
- /* call get_msg on channel that do not have any pending messages */
- sprintf(path, "%s.srv.%s", SRV_PATH_BASE, "datasink");
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_GT_ZERO(rc, "connect to datasink");
- chan = (handle_t)rc;
-
- rc = get_msg(chan, &inf);
- EXPECT_EQ(ERR_NO_MSG, rc, "get_msg on empty channel");
-
- rc = close(chan);
- EXPECT_EQ(NO_ERROR, rc, "close channnel");
-}
-
-TEST(ipc, put_msg_negative) {
- int rc;
- handle_t port;
- handle_t chan;
- char path[MAX_PORT_PATH_LEN];
-
- /* put_msg on invalid (negative value) handle */
- rc = put_msg(INVALID_IPC_HANDLE, 0);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "put_msg on invalid handle");
-
- /*
- * calling put_msg on an invalid (out of range) handle
- *
- * check handling of the following cases:
- * - handle is on the upper boundary of valid handle range
- * - handle is above of the upper boundary of valid handle range
- * - handle is below of valid handle range
- *
- * in all cases, the expected result is ERR_BAD_HANDLE error.
- */
- rc = put_msg(handle_base + MAX_USER_HANDLES, 0);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "put_msg on invalid handle");
-
- rc = put_msg(handle_base + MAX_USER_HANDLES + 1, 0);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "put_msg on invalid handle");
-
- rc = put_msg(handle_base - 1, 0);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "put_msg on invalid handle");
-
- /* put_msg on non-existing handle that is in valid range */
- for (unsigned int i = FIRST_FREE_HANDLE; i < MAX_USER_HANDLES; i++) {
- rc = put_msg(handle_base + i, 0);
- EXPECT_EQ(ERR_NOT_FOUND, rc, "put_msg on invalid handle");
- }
-
- /* calling put_msg on port handle should fail
- because put_msg is only applicable to channels */
- sprintf(path, "%s.main.%s", SRV_PATH_BASE, "datasink");
- rc = port_create(path, 2, MAX_PORT_BUF_SIZE, IPC_PORT_ALLOW_TA_CONNECT);
- EXPECT_GT_ZERO(rc, "create datasink port");
- port = (handle_t)rc;
-
- rc = put_msg(port, 0);
- EXPECT_EQ(ERR_INVALID_ARGS, rc, "put_msg on port");
- rc = close(port);
- EXPECT_EQ(NO_ERROR, rc, "close port");
-
- /* call put_msg on channel that do not have any pending messages */
- sprintf(path, "%s.srv.%s", SRV_PATH_BASE, "datasink");
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_GT_ZERO(rc, "connect to datasink");
- chan = (handle_t)rc;
-
- rc = put_msg(chan, 0);
- EXPECT_EQ(ERR_INVALID_ARGS, rc, "put_msg on empty channel");
- rc = close(chan);
- EXPECT_EQ(NO_ERROR, rc, "close channel");
-}
-
-/*
- * Send 10000 messages to datasink service
- */
-TEST(ipc, send_msg) {
- int rc;
- handle_t chan;
- char path[MAX_PORT_PATH_LEN];
- uint8_t buf0[64];
- uint8_t buf1[64];
- struct iovec iov[2];
- ipc_msg_t msg;
-
- /* prepare test buffer */
- fill_test_buf(buf0, sizeof(buf0), 0x55);
- fill_test_buf(buf1, sizeof(buf1), 0x44);
-
- iov[0].iov_base = buf0;
- iov[0].iov_len = sizeof(buf0);
- iov[1].iov_base = buf1;
- iov[1].iov_len = sizeof(buf1);
- msg.num_handles = 0;
- msg.handles = NULL;
- msg.num_iov = 2;
- msg.iov = iov;
-
- /* open connection to datasink service */
- sprintf(path, "%s.srv.%s", SRV_PATH_BASE, "datasink");
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_GT_ZERO(rc, "connect to datasink");
-
- if (rc >= 0) {
- chan = (handle_t)rc;
- for (unsigned int i = 0; i < 10000; i++) {
- rc = send_msg(chan, &msg);
- if (rc == ERR_NOT_ENOUGH_BUFFER) { /* wait for room */
- uevent_t uevt;
- unsigned int exp_event = IPC_HANDLE_POLL_SEND_UNBLOCKED;
- rc = wait(chan, &uevt, 1000);
- EXPECT_EQ(NO_ERROR, rc, "waiting for space");
- EXPECT_EQ(chan, uevt.handle, "waiting for space");
- EXPECT_EQ(exp_event, uevt.event, "waiting for space");
- } else {
- EXPECT_EQ(64, rc, "send_msg bulk")
- }
- if (HasFailure()) {
- TLOGI("%s: abort (rc = %d) test\n", __func__, rc);
- break;
- }
- }
- rc = close(chan);
- EXPECT_EQ(NO_ERROR, rc, "close channel");
- }
-}
-
-TEST(ipc, send_msg_negative) {
- int rc;
- handle_t port;
- handle_t chan;
- char path[MAX_PORT_PATH_LEN];
- uint8_t buf[64];
- struct iovec iov[2];
- ipc_msg_t msg;
-
- /* init msg to empty message */
- memset(&msg, 0, sizeof(msg));
-
- /* send_msg on invalid (negative value) handle */
- rc = send_msg(INVALID_IPC_HANDLE, &msg);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "send_msg on invalid handle");
-
- /* calling send_msg with NULL msg should fail for any handle */
- rc = send_msg(INVALID_IPC_HANDLE, NULL);
- EXPECT_EQ(ERR_FAULT, rc, "send_msg on NULL msg");
-
- /*
- * calling send_msg on an invalid (out of range) handle
- *
- * check handling of the following cases:
- * - handle is on the upper boundary of valid handle range
- * - handle is above of the upper boundary of valid handle range
- * - handle is below of valid handle range
- *
- * in all cases, the expected result is ERR_BAD_HANDLE error.
- */
- rc = send_msg(handle_base + MAX_USER_HANDLES, &msg);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "send_msg on invalid handle");
-
- rc = send_msg(handle_base + MAX_USER_HANDLES + 1, &msg);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "send_msg on invalid handle");
-
- rc = send_msg(handle_base - 1, &msg);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "send_msg on invalid handle");
-
- /* calling send_msg with NULL msg should fail for any handle */
- rc = send_msg(MAX_USER_HANDLES, NULL);
- EXPECT_EQ(ERR_FAULT, rc, "send_msg on NULL msg");
-
- /* send_msg on non-existing handle that is in valid range */
- for (unsigned int i = FIRST_FREE_HANDLE; i < MAX_USER_HANDLES; i++) {
- rc = send_msg(handle_base + i, &msg);
- EXPECT_EQ(ERR_NOT_FOUND, rc, "send on invalid handle");
-
- /* calling send_msg with NULL msg should fail for any handle */
- rc = send_msg(handle_base + i, NULL);
- EXPECT_EQ(ERR_FAULT, rc, "send_msg on NULL msg");
- }
-
- /* calling send_msg on port handle should fail
- because send_msg is only applicable to channels */
- sprintf(path, "%s.main.%s", SRV_PATH_BASE, "datasink");
- rc = port_create(path, 2, MAX_PORT_BUF_SIZE, IPC_PORT_ALLOW_TA_CONNECT);
- EXPECT_GT_ZERO(rc, "create datasink port");
- port = (handle_t)rc;
-
- rc = send_msg(port, &msg);
- EXPECT_EQ(ERR_INVALID_ARGS, rc, "send_msg on port");
- close(port);
-
- /* open connection to datasink service */
- sprintf(path, "%s.srv.%s", SRV_PATH_BASE, "datasink");
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_GT_ZERO(rc, "connect to datasink");
- chan = (handle_t)rc;
-
- /* send message with handles pointing to NULL */
- msg.num_handles = 1;
- msg.handles = NULL;
- rc = send_msg(chan, &msg);
- EXPECT_EQ(ERR_FAULT, rc, "sending handles");
-
- /* reset handles */
- msg.num_handles = 0;
- msg.handles = NULL;
-
- /* set num_iov to non zero but keep iov ptr NULL */
- msg.num_iov = 1;
- msg.iov = NULL;
- rc = send_msg(chan, &msg);
- EXPECT_EQ(ERR_FAULT, rc, "sending bad iovec array");
-
- /* send msg with iovec with bad base ptr */
- iov[0].iov_len = sizeof(buf) / 2;
- iov[0].iov_base = NULL;
- iov[1].iov_len = sizeof(buf) / 2;
- iov[1].iov_base = NULL;
- msg.num_iov = 2;
- msg.iov = iov;
- rc = send_msg(chan, &msg);
- EXPECT_EQ(ERR_FAULT, rc, "sending bad iovec");
-
- /* send msg with iovec with bad base ptr */
- iov[0].iov_len = sizeof(buf) / 2;
- iov[0].iov_base = buf;
- iov[1].iov_len = sizeof(buf) / 2;
- iov[1].iov_base = NULL;
- msg.num_iov = 2;
- msg.iov = iov;
- rc = send_msg(chan, &msg);
- EXPECT_EQ(ERR_FAULT, rc, "sending bad iovec");
-
- rc = close(chan);
- EXPECT_EQ(NO_ERROR, rc, "close channel");
-}
-
-TEST(ipc, read_msg_negative) {
- int rc;
- handle_t port;
- handle_t chan;
- uevent_t uevt;
- char path[MAX_PORT_PATH_LEN];
- uint8_t tx_buf[64];
- uint8_t rx_buf[64];
- ipc_msg_info_t inf;
- ipc_msg_t tx_msg;
- struct iovec tx_iov;
- ipc_msg_t rx_msg;
- struct iovec rx_iov[2];
-
- /* init msg to empty message */
- memset(&rx_msg, 0, sizeof(rx_msg));
- memset(&tx_msg, 0, sizeof(tx_msg));
-
- /* read_msg on invalid (negative value) handle */
- rc = read_msg(INVALID_IPC_HANDLE, 0, 0, &rx_msg);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "read_msg on invalid handle");
-
- rc = read_msg(INVALID_IPC_HANDLE, 0, 0, NULL);
- EXPECT_EQ(ERR_FAULT, rc, "read_msg on invalid handle");
-
- /*
- * calling read_msg on an invalid (out of range) handle
- *
- * check handling of the following cases:
- * - handle is on the upper boundary of valid handle range
- * - handle is above of the upper boundary of valid handle range
- * - handle is below of valid handle range
- *
- * in all cases, the expected result is ERR_BAD_HANDLE error.
- */
- rc = read_msg(handle_base + MAX_USER_HANDLES, 0, 0, &rx_msg);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "read_msg on bad handle");
-
- rc = read_msg(handle_base + MAX_USER_HANDLES + 1, 0, 0, &rx_msg);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "read_msg on bad handle");
-
- rc = read_msg(handle_base - 1, 0, 0, &rx_msg);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "read_msg on bad handle");
-
- /* calling read_msg with NULL msg should fail for any handle */
- rc = read_msg(handle_base + MAX_USER_HANDLES, 0, 0, NULL);
- EXPECT_EQ(ERR_FAULT, rc, "read_msg on NULL msg");
-
- /* send_msg on non-existing handle that is in valid range */
- for (unsigned int i = FIRST_FREE_HANDLE; i < MAX_USER_HANDLES; i++) {
- rc = read_msg(handle_base + i, 0, 0, &rx_msg);
- EXPECT_EQ(ERR_NOT_FOUND, rc, "read_msg on non existing handle");
-
- /* calling send_msg with NULL msg should fail for any handle */
- rc = read_msg(handle_base + i, 0, 0, NULL);
- EXPECT_EQ(ERR_FAULT, rc, "read_msg on NULL msg");
- }
-
- /* calling read_msg on port handle should fail
- because read_msg is only applicable to channels */
- sprintf(path, "%s.main.%s", SRV_PATH_BASE, "datasink");
- rc = port_create(path, 2, MAX_PORT_BUF_SIZE, IPC_PORT_ALLOW_TA_CONNECT);
- EXPECT_GT_ZERO(rc, "create datasink port");
- port = (handle_t)rc;
-
- rc = read_msg(port, 0, 0, &rx_msg);
- EXPECT_EQ(ERR_INVALID_ARGS, rc, "read_msg on port");
- close(port);
-
- /* open connection to echo service */
- sprintf(path, "%s.srv.%s", SRV_PATH_BASE, "echo");
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_GT_ZERO(rc, "connect to datasink");
- chan = (handle_t)rc;
-
- /* NULL msg on valid channel */
- rc = read_msg(chan, 0, 0, NULL);
- EXPECT_EQ(ERR_FAULT, rc, "read_msg on NULL msg");
-
- /* read_msg on invalid msg id */
- rc = read_msg(chan, 0, 0, &rx_msg);
- EXPECT_EQ(ERR_INVALID_ARGS, rc, "read_msg on invalid msg id");
-
- rc = read_msg(chan, 1000, 0, &rx_msg);
- EXPECT_EQ(ERR_INVALID_ARGS, rc, "read_msg on invalid msg id");
-
- /* send a message to echo service */
- memset(tx_buf, 0x55, sizeof(tx_buf));
- tx_iov.iov_base = tx_buf;
- tx_iov.iov_len = sizeof(tx_buf);
- tx_msg.num_iov = 1;
- tx_msg.iov = &tx_iov;
- tx_msg.num_handles = 0;
- tx_msg.handles = NULL;
-
- rc = send_msg(chan, &tx_msg);
- EXPECT_EQ(64, rc, "sending msg to echo");
-
- /* and wait for response */
- rc = wait(chan, &uevt, 1000);
- EXPECT_EQ(NO_ERROR, rc, "waiting on echo response");
- EXPECT_EQ(chan, uevt.handle, "wait on channel");
-
- rc = get_msg(chan, &inf);
- EXPECT_EQ(NO_ERROR, rc, "getting echo msg");
- EXPECT_EQ(sizeof(tx_buf), inf.len, "echo message reply length");
-
- /* now we have valid message with valid id */
-
- rx_iov[0].iov_len = sizeof(rx_buf) / 2;
- rx_iov[1].iov_len = sizeof(rx_buf) / 2;
-
- /* read message with invalid iovec array */
- rx_msg.iov = NULL;
- rx_msg.num_iov = 2;
- rc = read_msg(chan, inf.id, 0, &rx_msg);
- EXPECT_EQ(ERR_FAULT, rc, "read with invalid iovec array");
-
- /* read with invalid iovec entry */
- rx_iov[0].iov_base = NULL;
- rx_iov[1].iov_base = NULL;
- rx_msg.iov = rx_iov;
- rc = read_msg(chan, inf.id, 0, &rx_msg);
- EXPECT_EQ(ERR_FAULT, rc, "read with invalid iovec");
-
- rx_iov[0].iov_base = rx_buf;
- rx_iov[1].iov_base = NULL;
- rc = read_msg(chan, inf.id, 0, &rx_msg);
- EXPECT_EQ(ERR_FAULT, rc, "read with invalid iovec");
-
- rx_iov[0].iov_base = rx_buf;
- rx_iov[1].iov_base = rx_buf + sizeof(rx_buf) / 2;
-
- /* read with invalid offset with valid iovec array */
- rc = read_msg(chan, inf.id, inf.len + 1, &rx_msg);
- EXPECT_EQ(ERR_INVALID_ARGS, rc, "read with invalid offset");
-
- /* cleanup */
- rc = put_msg(chan, inf.id);
- EXPECT_EQ(NO_ERROR, rc, "putting echo msg");
-
- rc = close(chan);
- EXPECT_EQ(NO_ERROR, rc, "close channel");
-}
-
-TEST(ipc, end_to_end_msg) {
- int rc;
- handle_t chan;
- uevent_t uevt;
- char path[MAX_PORT_PATH_LEN];
- uint8_t tx_buf[64];
- uint8_t rx_buf[64];
- ipc_msg_info_t inf;
- ipc_msg_t tx_msg;
- struct iovec tx_iov;
- ipc_msg_t rx_msg;
- struct iovec rx_iov;
-
- tx_iov.iov_base = tx_buf;
- tx_iov.iov_len = sizeof(tx_buf);
- tx_msg.num_iov = 1;
- tx_msg.iov = &tx_iov;
- tx_msg.num_handles = 0;
- tx_msg.handles = NULL;
-
- rx_iov.iov_base = rx_buf;
- rx_iov.iov_len = sizeof(rx_buf);
- rx_msg.num_iov = 1;
- rx_msg.iov = &rx_iov;
- rx_msg.num_handles = 0;
- rx_msg.handles = NULL;
-
- memset(tx_buf, 0x55, sizeof(tx_buf));
- memset(rx_buf, 0xaa, sizeof(rx_buf));
-
- sprintf(path, "%s.srv.%s", SRV_PATH_BASE, "echo");
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_GT_ZERO(rc, "connect to echo");
-
- if (rc >= 0) {
- unsigned int tx_cnt = 0;
- unsigned int rx_cnt = 0;
-
- chan = (handle_t)rc;
-
- /* send 10000 messages synchronously, waiting for reply
- for each one
- */
- tx_cnt = 10000;
- while (tx_cnt) {
- /* send a message */
- rc = send_msg(chan, &tx_msg);
- EXPECT_EQ(64, rc, "sending msg to echo");
-
- /* wait for response */
- rc = wait(chan, &uevt, 1000);
- EXPECT_EQ(NO_ERROR, rc, "waiting on echo response");
- EXPECT_EQ(chan, uevt.handle, "wait on channel");
-
- /* get a reply */
- rc = get_msg(chan, &inf);
- EXPECT_EQ(NO_ERROR, rc, "getting echo msg");
-
- /* read reply data */
- rc = read_msg(chan, inf.id, 0, &rx_msg);
- EXPECT_EQ(64, rc, "reading echo msg");
-
- /* discard reply */
- rc = put_msg(chan, inf.id);
- EXPECT_EQ(NO_ERROR, rc, "putting echo msg");
-
- tx_cnt--;
- }
-
- /* send/receive 10000 messages asynchronously. */
- rx_cnt = tx_cnt = 10000;
- while (tx_cnt || rx_cnt) {
- /* send messages until all buffers are full */
- while (tx_cnt) {
- rc = send_msg(chan, &tx_msg);
- if (rc == ERR_NOT_ENOUGH_BUFFER)
- break; /* no more space */
- EXPECT_EQ(64, rc, "sending msg to echo");
- if (rc != 64)
- goto abort_test;
- tx_cnt--;
- }
-
- /* wait for reply msg or room */
- rc = wait(chan, &uevt, 1000);
- EXPECT_EQ(NO_ERROR, rc, "waiting for reply");
- EXPECT_EQ(chan, uevt.handle, "wait on channel");
-
- /* drain all messages */
- while (rx_cnt) {
- /* get a reply */
- rc = get_msg(chan, &inf);
- if (rc == ERR_NO_MSG)
- break; /* no more messages */
-
- EXPECT_EQ(NO_ERROR, rc, "getting echo msg");
-
- /* read reply data */
- rc = read_msg(chan, inf.id, 0, &rx_msg);
- EXPECT_EQ(64, rc, "reading echo msg");
-
- /* discard reply */
- rc = put_msg(chan, inf.id);
- EXPECT_EQ(NO_ERROR, rc, "putting echo msg");
-
- rx_cnt--;
- }
-
- if (HasFailure())
- break;
- }
-
- abort_test:
- EXPECT_EQ(0, tx_cnt, "tx_cnt");
- EXPECT_EQ(0, rx_cnt, "rx_cnt");
-
- rc = close(chan);
- EXPECT_EQ(NO_ERROR, rc, "close channel");
- }
-}
-
-/****************************************************************************/
-
-TEST(ipc, hset_create) {
- handle_t hset1;
- handle_t hset2;
-
- hset1 = handle_set_create();
- EXPECT_GE_ZERO((int)hset1, "create handle set1");
-
- hset2 = handle_set_create();
- EXPECT_GE_ZERO((int)hset2, "create handle set2");
-
- close(hset1);
- close(hset2);
-}
-
-TEST(ipc, hset_add_mod_del) {
- int rc;
- handle_t hset1;
- handle_t hset2;
-
- hset1 = handle_set_create();
- EXPECT_GE_ZERO((int)hset1, "create handle set1");
-
- hset2 = handle_set_create();
- EXPECT_GE_ZERO((int)hset2, "create handle set2");
-
- ABORT_IF_NOT_OK(abort_test);
-
- uevent_t evt = {
- .handle = hset2,
- .event = ~0U,
- .cookie = NULL,
- };
-
- /* add handle to handle set */
- rc = handle_set_ctrl(hset1, HSET_ADD, &evt);
- EXPECT_EQ(0, rc, "hset add");
-
- /* modify handle attributes in handle set */
- rc = handle_set_ctrl(hset1, HSET_MOD, &evt);
- EXPECT_EQ(0, rc, "hset mod");
-
- /* remove handle from handle set */
- rc = handle_set_ctrl(hset1, HSET_DEL, &evt);
- EXPECT_EQ(0, rc, "hset del");
-
-abort_test:
- close(hset1);
- close(hset2);
-}
-
-TEST(ipc, hset_add_self) {
- int rc;
- handle_t hset1;
-
- hset1 = handle_set_create();
- EXPECT_GE_ZERO((int)hset1, "create handle set1");
-
- ABORT_IF_NOT_OK(abort_test);
-
- uevent_t evt = {
- .handle = hset1,
- .event = ~0U,
- .cookie = NULL,
- };
-
- /* add handle to handle set */
- rc = handle_set_ctrl(hset1, HSET_ADD, &evt);
- EXPECT_EQ(ERR_INVALID_ARGS, rc, "hset add self");
-
-abort_test:
- close(hset1);
-}
-
-TEST(ipc, hset_add_loop) {
- int rc;
- handle_t hset1;
- handle_t hset2;
- handle_t hset3;
-
- hset1 = handle_set_create();
- EXPECT_GE_ZERO((int)hset1, "create handle set1");
-
- hset2 = handle_set_create();
- EXPECT_GE_ZERO((int)hset2, "create handle set2");
-
- hset3 = handle_set_create();
- EXPECT_GE_ZERO((int)hset3, "create handle set3");
-
- ABORT_IF_NOT_OK(abort_test);
-
- uevent_t evt = {
- .handle = hset2,
- .event = ~0U,
- .cookie = NULL,
- };
-
- /* add hset2 to hset1 */
- rc = handle_set_ctrl(hset1, HSET_ADD, &evt);
- EXPECT_EQ(0, rc, "add hset2 to hset1");
-
- /* add hset3 to hset2 */
- evt.handle = hset3;
- rc = handle_set_ctrl(hset2, HSET_ADD, &evt);
- EXPECT_EQ(0, rc, "add hset3 to hset2");
-
- /* add hset1 to hset3 */
- evt.handle = hset1;
- rc = handle_set_ctrl(hset3, HSET_ADD, &evt);
- EXPECT_EQ(ERR_INVALID_ARGS, rc, "add hset1 to hset3");
-
-abort_test:
- close(hset2);
- close(hset1);
- close(hset3);
-}
-
-TEST(ipc, hset_add_duplicate) {
- int rc;
- handle_t hset1;
- handle_t hset2;
-
- hset1 = handle_set_create();
- EXPECT_GE_ZERO((int)hset1, "create handle set1");
-
- hset2 = handle_set_create();
- EXPECT_GE_ZERO((int)hset2, "create handle set2");
-
- ABORT_IF_NOT_OK(abort_test);
-
- uevent_t evt = {
- .handle = hset2,
- .event = ~0U,
- .cookie = NULL,
- };
-
- /* add hset2 to hset1 */
- rc = handle_set_ctrl(hset1, HSET_ADD, &evt);
- EXPECT_EQ(0, rc, "add hset2 to hset1");
-
- /* add hset2 to hset1 again */
- rc = handle_set_ctrl(hset1, HSET_ADD, &evt);
- EXPECT_EQ(ERR_ALREADY_EXISTS, rc, "add hset2 to hset1");
-
-abort_test:
- close(hset1);
- close(hset2);
-}
-
-TEST(ipc, hset_wait_on_empty_set) {
- int rc;
- uevent_t evt;
- handle_t hset1;
-
- hset1 = handle_set_create();
- EXPECT_GE_ZERO((int)hset1, "create hset");
-
- ABORT_IF_NOT_OK(abort_test);
-
- /* wait with zero timeout */
- rc = wait(hset1, &evt, 0);
- EXPECT_EQ(ERR_NOT_FOUND, rc, "wait on empty hset");
-
- /* wait with non-zero timeout */
- rc = wait(hset1, &evt, 100);
- EXPECT_EQ(ERR_NOT_FOUND, rc, "wait on empty hset");
-
- close(hset1);
-
-abort_test:;
-}
-
-TEST(ipc, hset_wait_on_non_empty_set) {
- int rc;
- handle_t hset1;
- handle_t hset2;
-
- hset1 = handle_set_create();
- EXPECT_GE_ZERO((int)hset1, "create handle set1");
-
- hset2 = handle_set_create();
- EXPECT_GE_ZERO((int)hset2, "create handle set2");
-
- ABORT_IF_NOT_OK(abort_test);
-
- uevent_t evt = {
- .handle = hset2,
- .event = ~0U,
- .cookie = NULL,
- };
-
- /* add hset2 to hset1 */
- rc = handle_set_ctrl(hset1, HSET_ADD, &evt);
- EXPECT_EQ(0, rc, "add hset2 to hset1");
-
- /* wait with zero timeout on hset1 */
- rc = wait(hset1, &evt, 0);
- EXPECT_EQ(ERR_TIMED_OUT, rc, "wait on empty hset");
-
- /* wait with non-zero timeout on hset1 */
- rc = wait(hset1, &evt, 100);
- EXPECT_EQ(ERR_TIMED_OUT, rc, "wait on empty hset");
-
-abort_test:
- close(hset1);
- close(hset2);
-}
-
-/*
- * Disabled per b/140836874 - believed to be a race in the test code, not
- * in IPC.
- */
-TEST(ipc, DISABLED_hset_add_chan) {
- int rc;
- uevent_t evt;
- handle_t hset1;
- handle_t hset2;
- handle_t chan1;
- handle_t chan2;
- void* cookie1 = (void*)"cookie1";
- void* cookie2 = (void*)"cookie2";
- void* cookie11 = (void*)"cookie11";
- void* cookie12 = (void*)"cookie12";
- void* cookie21 = (void*)"cookie21";
- void* cookie22 = (void*)"cookie22";
- void* cookiehs2 = (void*)"cookiehs2";
- uint8_t buf0[64];
- struct iovec iov;
- ipc_msg_t msg;
-
- /* prepare test buffer */
- fill_test_buf(buf0, sizeof(buf0), 0x55);
-
- chan1 = connect(SRV_PATH_BASE ".srv.echo", IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_GT_ZERO((int)chan1, "connect to echo chan1");
-
- rc = set_cookie(chan1, cookie1);
- EXPECT_EQ(0, rc, "cookie1");
-
- chan2 = connect(SRV_PATH_BASE ".srv.echo", IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_GT_ZERO((int)chan2, "connect to echo chan2");
-
- rc = set_cookie(chan2, cookie2);
- EXPECT_EQ(0, rc, "cookie2");
-
- /* send message over chan1 and chan2 */
- iov.iov_base = buf0;
- iov.iov_len = sizeof(buf0);
- msg.num_handles = 0;
- msg.handles = NULL;
- msg.num_iov = 1;
- msg.iov = &iov;
-
- rc = send_msg(chan1, &msg);
- EXPECT_EQ(64, rc, "send over chan1");
-
- rc = send_msg(chan2, &msg);
- EXPECT_EQ(64, rc, "send over chan2");
-
- hset1 = handle_set_create();
- EXPECT_GE_ZERO((int)hset1, "create handle set1");
-
- hset2 = handle_set_create();
- EXPECT_GE_ZERO((int)hset2, "create handle set2");
-
- ABORT_IF_NOT_OK(abort_test);
-
- /* chan1 to hset2 */
- evt.handle = chan1;
- evt.event = ~0U;
- evt.cookie = cookie12;
- rc = handle_set_ctrl(hset2, HSET_ADD, &evt);
- EXPECT_EQ(0, rc, "add hset2 to hset1");
-
- /* chan2 to hset2 */
- evt.handle = chan2;
- evt.event = ~0U;
- evt.cookie = cookie22;
- rc = handle_set_ctrl(hset2, HSET_ADD, &evt);
- EXPECT_EQ(0, rc, "add hset2 to hset1");
-
- /* add hset2 to hset1 */
- evt.handle = hset2;
- evt.event = ~0U;
- evt.cookie = cookiehs2;
- rc = handle_set_ctrl(hset1, HSET_ADD, &evt);
- EXPECT_EQ(0, rc, "add hset2 to hset1");
-
- /* chan1 to hset1 */
- evt.handle = chan1;
- evt.event = ~0U;
- evt.cookie = cookie11;
- rc = handle_set_ctrl(hset1, HSET_ADD, &evt);
- EXPECT_EQ(0, rc, "add hset2 to hset1");
-
- /* chan2 to hset1 */
- evt.handle = chan2;
- evt.event = ~0U;
- evt.cookie = cookie21;
- rc = handle_set_ctrl(hset1, HSET_ADD, &evt);
- EXPECT_EQ(0, rc, "add hset2 to hset1");
-
- /* wait on chan1 directly */
- rc = wait(chan1, &evt, 1000);
- EXPECT_EQ(0, rc, "wait on chan1");
- EXPECT_EQ(chan1, evt.handle, "event.handle");
- EXPECT_EQ(cookie1, evt.cookie, "event.cookie");
-
- /* wait on chan2 directly */
- rc = wait(chan2, &evt, 1000);
- EXPECT_EQ(0, rc, "wait on chan2");
- EXPECT_EQ(chan2, evt.handle, "event.handle");
- EXPECT_EQ(cookie2, evt.cookie, "event.cookie");
-
- /* wait on hset1 */
- rc = wait(hset1, &evt, 1000);
- EXPECT_EQ(0, rc, "wait on hset1");
- EXPECT_EQ(hset2, evt.handle, "event.handle");
- EXPECT_EQ(cookiehs2, evt.cookie, "event.cookie");
-
- /* wait on hset1 again (chan1 should be ready) */
- rc = wait(hset1, &evt, 1000);
- EXPECT_EQ(0, rc, "wait on hset1");
- EXPECT_EQ(chan1, evt.handle, "event.handle");
- EXPECT_EQ(cookie11, evt.cookie, "event.cookie");
-
- /* wait on hset1 again (chan2 should be ready) */
- rc = wait(hset1, &evt, 1000);
- EXPECT_EQ(0, rc, "wait on hset1");
- EXPECT_EQ(chan2, evt.handle, "event.handle");
- EXPECT_EQ(cookie21, evt.cookie, "event.cookie");
-
- /* wait on hset1 again (hset2 should be ready) */
- rc = wait(hset1, &evt, 1000);
- EXPECT_EQ(0, rc, "wait on hset1");
- EXPECT_EQ(hset2, evt.handle, "event.handle");
- EXPECT_EQ(cookiehs2, evt.cookie, "event.cookie");
-
- /* wait on hset2 (chan1 should be ready) */
- rc = wait(hset2, &evt, 1000);
- EXPECT_EQ(0, rc, "wait on hset2");
- EXPECT_EQ(chan1, evt.handle, "event.handle");
- EXPECT_EQ(cookie12, evt.cookie, "event.cookie");
-
- /* wait on hset2 again (chan2 should be ready) */
- rc = wait(hset2, &evt, 1000);
- EXPECT_EQ(0, rc, "wait on hset2");
- EXPECT_EQ(chan2, evt.handle, "event.handle");
- EXPECT_EQ(cookie22, evt.cookie, "event.cookie");
-
- /* wait on hset2 again (chan1 should be ready) */
- rc = wait(hset2, &evt, 1000);
- EXPECT_EQ(0, rc, "wait on chan1");
- EXPECT_EQ(chan1, evt.handle, "event.handle");
- EXPECT_EQ(cookie12, evt.cookie, "event.cookie");
-
-abort_test:
- close(chan1);
- close(chan2);
- close(hset1);
- close(hset2);
-}
-
-TEST(ipc, hset_event_mask) {
- int rc;
- uevent_t evt;
- handle_t hset1;
- handle_t chan1;
- void* cookie1 = (void*)"cookie1";
- void* cookie11 = (void*)"cookie11";
- uint8_t buf0[64];
- struct iovec iov;
- ipc_msg_t msg;
-
- /* prepare test buffer */
- fill_test_buf(buf0, sizeof(buf0), 0x55);
-
- chan1 = connect(SRV_PATH_BASE ".srv.echo", IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_GT_ZERO((int)chan1, "connect to echo");
-
- rc = set_cookie(chan1, cookie1);
- EXPECT_EQ(0, rc, "cookie1");
-
- /* send message over chan1 and chan2 */
- iov.iov_base = buf0;
- iov.iov_len = sizeof(buf0);
- msg.num_handles = 0;
- msg.handles = NULL;
- msg.num_iov = 1;
- msg.iov = &iov;
-
- rc = send_msg(chan1, &msg);
- EXPECT_EQ(64, rc, "send over chan1");
-
- hset1 = handle_set_create();
- EXPECT_GE_ZERO((int)hset1, "create handle set1");
-
- ABORT_IF_NOT_OK(abort_test);
-
- /* chan1 to hset1 */
- evt.handle = chan1;
- evt.event = ~0U;
- evt.cookie = cookie11;
- rc = handle_set_ctrl(hset1, HSET_ADD, &evt);
- EXPECT_EQ(0, rc, "add chan1 to hset1");
-
- /* wait of chan1 handle */
- rc = wait(chan1, &evt, 100);
- EXPECT_EQ(0, rc, "wait on chan1");
- EXPECT_EQ(chan1, evt.handle, "event.handle");
- EXPECT_EQ(cookie1, evt.cookie, "event.cookie");
-
- /* wait on hset1 (should get chan1) */
- rc = wait(hset1, &evt, 100);
- EXPECT_EQ(0, rc, "wait on hset1");
- EXPECT_EQ(chan1, evt.handle, "event.handle");
- EXPECT_EQ(cookie11, evt.cookie, "event.cookie");
-
- /* mask off chan1 in hset1 */
- evt.handle = chan1;
- evt.event = 0;
- evt.cookie = cookie11;
- rc = handle_set_ctrl(hset1, HSET_MOD, &evt);
- EXPECT_EQ(0, rc, "mod chan1 in hset1");
-
- /* wait on hset1 (should get chan1) */
- rc = wait(hset1, &evt, 100);
- EXPECT_EQ(ERR_TIMED_OUT, rc, "wait on hset1");
-
- /* unmask off chan1 in hset1 */
- evt.handle = chan1;
- evt.event = ~0U;
- evt.cookie = cookie11;
- rc = handle_set_ctrl(hset1, HSET_MOD, &evt);
- EXPECT_EQ(0, rc, "mod chan1 in hset1");
-
- /* wait on hset1 (should get chan1) */
- rc = wait(hset1, &evt, 100);
- EXPECT_EQ(0, rc, "wait on hset1");
- EXPECT_EQ(chan1, evt.handle, "event.handle");
- EXPECT_EQ(cookie11, evt.cookie, "event.cookie");
-
-abort_test:
- close(chan1);
- close(hset1);
-}
-
-/****************************************************************************/
-
-TEST(ipc, send_handle) {
- int rc;
- struct iovec iov;
- ipc_msg_t msg;
- handle_t hchan1;
- handle_t hchan2;
- uint8_t buf0[64];
- char path[MAX_PORT_PATH_LEN];
-
- /* prepare test buffer */
- fill_test_buf(buf0, sizeof(buf0), 0x55);
-
- /* open connection to datasink service */
- sprintf(path, "%s.srv.%s", SRV_PATH_BASE, "datasink");
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_GT_ZERO(rc, "connect to datasink");
- ABORT_IF_NOT_OK(err_connect1);
- hchan1 = (handle_t)rc;
-
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_GT_ZERO(rc, "connect to datasink");
- ABORT_IF_NOT_OK(err_connect2);
- hchan2 = (handle_t)rc;
-
- /* send hchan2 handle over hchan1 connection */
- iov.iov_base = buf0;
- iov.iov_len = sizeof(buf0);
- msg.iov = &iov;
- msg.num_iov = 1;
- msg.handles = &hchan2;
- msg.num_handles = 1;
-
- /* send and wait a bit */
- rc = send_msg(hchan1, &msg);
- EXPECT_EQ(64, rc, "send handle");
- trusty_nanosleep(0, 0, 100 * MSEC);
-
- /* send it again and close it */
- rc = send_msg(hchan1, &msg);
- EXPECT_EQ(64, rc, "send handle");
- rc = close(hchan2);
- EXPECT_EQ(NO_ERROR, rc, "close chan2");
-
-err_connect2:
- rc = close(hchan1);
- EXPECT_EQ(NO_ERROR, rc, "close chan1");
-err_connect1:;
-}
-
-TEST(ipc, send_handle_negative) {
- int rc;
- ipc_msg_t msg;
- handle_t hchan;
- handle_t hsend[10];
- char path[MAX_PORT_PATH_LEN];
-
- /* open connection to datasink service */
- sprintf(path, "%s.srv.%s", SRV_PATH_BASE, "datasink");
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_GT_ZERO(rc, "connect to datasink");
- ABORT_IF_NOT_OK(err_connect);
- hchan = (handle_t)rc;
-
- for (unsigned int i = 0; i < countof(hsend); i++)
- hsend[i] = hchan;
-
- /* send 8 copies of yourself to datasync (should be fine) */
- msg.iov = NULL;
- msg.num_iov = 0;
- msg.handles = &hsend[0];
- msg.num_handles = 8;
- rc = send_msg(hchan, &msg);
- EXPECT_EQ(0, rc, "send handle");
-
- /* send 8 copies of yourself to datasync with handle poiting to NULL*/
- msg.iov = NULL;
- msg.num_iov = 0;
- msg.handles = NULL;
- msg.num_handles = 8;
- rc = send_msg(hchan, &msg);
- EXPECT_EQ(ERR_FAULT, rc, "send handle");
-
- /* call with invalid handle should return ERR_FAULT */
- msg.handles = (handle_t*)0x100;
- msg.num_handles = 8;
- rc = send_msg(hchan, &msg);
- EXPECT_EQ(ERR_FAULT, rc, "send handle");
-
- /* send more then 8, should fail */
- msg.handles = &hsend[0];
- msg.num_handles = 10;
- rc = send_msg(hchan, &msg);
- EXPECT_EQ(ERR_TOO_BIG, rc, "send handle");
-
- rc = close(hchan);
- EXPECT_EQ(NO_ERROR, rc, "close chan");
-err_connect:;
-}
-
-TEST(ipc, recv_handle) {
- int rc;
- handle_t hchan1;
- handle_t hchan2;
- handle_t hrecv[2];
- uint8_t buf0[64];
- struct iovec iov;
- ipc_msg_t msg;
- uevent_t evt;
- ipc_msg_info_t inf;
- char path[MAX_PORT_PATH_LEN];
-
- /* prepare test buffer */
- fill_test_buf(buf0, sizeof(buf0), 0x55);
-
- /* open connection to echo service */
- sprintf(path, "%s.srv.%s", SRV_PATH_BASE, "echo");
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_GT_ZERO(rc, "connect to echo");
- ABORT_IF_NOT_OK(err_connect1);
- hchan1 = (handle_t)rc;
-
- /* open second connection to echo service */
- sprintf(path, "%s.srv.%s", SRV_PATH_BASE, "echo");
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_GT_ZERO(rc, "connect to echo");
- ABORT_IF_NOT_OK(err_connect2);
- hchan2 = (handle_t)rc;
-
- /* send message with handle */
- iov.iov_base = buf0;
- iov.iov_len = sizeof(buf0);
- msg.iov = &iov;
- msg.num_iov = 1;
- msg.handles = &hchan2;
- msg.num_handles = 1;
-
- rc = send_msg(hchan1, &msg);
- EXPECT_EQ(64, rc, "send_handle");
-
- /* wait for reply */
- rc = wait(hchan1, &evt, 1000);
- EXPECT_EQ(0, rc, "wait for reply");
- EXPECT_EQ(hchan1, evt.handle, "event.handle");
-
- /* get reply message */
- rc = get_msg(hchan1, &inf);
- EXPECT_EQ(NO_ERROR, rc, "getting echo reply");
- EXPECT_EQ(sizeof(buf0), inf.len, "reply len");
- EXPECT_EQ(1, inf.num_handles, "reply num_handles");
-
- /* read reply data and no handles */
- hrecv[0] = INVALID_IPC_HANDLE;
- hrecv[1] = INVALID_IPC_HANDLE;
- msg.handles = &hrecv[0];
- msg.num_handles = 0;
- rc = read_msg(hchan1, inf.id, 0, &msg);
- EXPECT_EQ(64, rc, "reading echo reply");
-
- rc = close(hrecv[0]);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "close reply handle");
-
- rc = close(hrecv[1]);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "close reply handle");
-
- /* read reply data and 1 handle */
- hrecv[0] = INVALID_IPC_HANDLE;
- hrecv[1] = INVALID_IPC_HANDLE;
- msg.handles = &hrecv[0];
- msg.num_handles = 1;
- rc = read_msg(hchan1, inf.id, 0, &msg);
- EXPECT_EQ(64, rc, "reading echo reply");
-
- rc = close(hrecv[0]);
- EXPECT_EQ(0, rc, "close reply handle");
-
- rc = close(hrecv[1]);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "close reply handle");
-
- /* read reply data and 2 handles (second one should be invalid) */
- hrecv[0] = INVALID_IPC_HANDLE;
- hrecv[1] = INVALID_IPC_HANDLE;
- msg.handles = &hrecv[0];
- msg.num_handles = 2;
- rc = read_msg(hchan1, inf.id, 0, &msg);
- EXPECT_EQ(64, rc, "reading echo reply");
-
- rc = close(hrecv[0]);
- EXPECT_EQ(0, rc, "close reply handle");
-
- rc = close(hrecv[1]);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "close reply handle");
-
- /* read 1 handle with no data */
- hrecv[0] = INVALID_IPC_HANDLE;
- hrecv[1] = INVALID_IPC_HANDLE;
- msg.num_iov = 0;
- msg.handles = &hrecv[0];
- msg.num_handles = 1;
- rc = read_msg(hchan1, inf.id, 0, &msg);
- EXPECT_EQ(0, rc, "reading echo reply");
-
- EXPECT_EQ(INVALID_IPC_HANDLE, hrecv[1], "reading echo reply");
-
- /* read same handle for the second time */
- msg.handles = &hrecv[1];
- msg.num_handles = 1;
- rc = read_msg(hchan1, inf.id, 0, &msg);
- EXPECT_EQ(0, rc, "reading echo reply");
-
- rc = close(hrecv[0]);
- EXPECT_EQ(0, rc, "close reply handle");
-
- rc = close(hrecv[1]);
- EXPECT_EQ(0, rc, "close reply handle");
-
- /* discard reply */
- rc = put_msg(hchan1, inf.id);
- EXPECT_EQ(NO_ERROR, rc, "putting echo reply");
-
- close(hchan2);
- EXPECT_EQ(NO_ERROR, rc, "close chan2");
-err_connect2:
- close(hchan1);
- EXPECT_EQ(NO_ERROR, rc, "close chan1");
-err_connect1:;
-}
-
-TEST(ipc, recv_handle_negative) {
- int rc;
- handle_t hchan1;
- ipc_msg_t msg;
- uevent_t evt;
- ipc_msg_info_t inf;
- char path[MAX_PORT_PATH_LEN];
-
- /* open connection to echo service */
- sprintf(path, "%s.srv.%s", SRV_PATH_BASE, "echo");
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_GT_ZERO(rc, "connect to echo");
- ABORT_IF_NOT_OK(err_connect1);
- hchan1 = (handle_t)rc;
-
- /* send message with handle attached */
- msg.iov = NULL;
- msg.num_iov = 0;
- msg.handles = &hchan1;
- msg.num_handles = 1;
-
- rc = send_msg(hchan1, &msg);
- EXPECT_EQ(0, rc, "send_handle");
-
- /* wait for reply */
- rc = wait(hchan1, &evt, 1000);
- EXPECT_EQ(0, rc, "wait for reply");
- EXPECT_EQ(hchan1, evt.handle, "event.handle");
-
- /* get reply message */
- rc = get_msg(hchan1, &inf);
- EXPECT_EQ(NO_ERROR, rc, "getting echo reply");
- EXPECT_EQ(0, inf.len, "reply len");
- EXPECT_EQ(1, inf.num_handles, "reply num_handles");
-
- /* read reply data with handles pointing to NULL */
- msg.handles = NULL;
- msg.num_handles = 1;
- rc = read_msg(hchan1, inf.id, 0, &msg);
- EXPECT_EQ(ERR_FAULT, rc, "reading echo reply");
-
- /* read reply data and bad handle ptr */
- msg.handles = (handle_t*)0x100;
- msg.num_handles = 1;
- rc = read_msg(hchan1, inf.id, 0, &msg);
- EXPECT_EQ(ERR_FAULT, rc, "reading echo reply");
-
- /* discard reply */
- rc = put_msg(hchan1, inf.id);
- EXPECT_EQ(NO_ERROR, rc, "putting echo reply");
-
- rc = close(hchan1);
- EXPECT_EQ(NO_ERROR, rc, "close chan1");
-err_connect1:;
-}
-
-TEST(ipc, send_handle_bulk) {
- int rc;
- struct iovec iov;
- ipc_msg_t msg;
- handle_t hchan1;
- handle_t hchan2;
- uint8_t buf0[64];
- char path[MAX_PORT_PATH_LEN];
-
- /* prepare test buffer */
- fill_test_buf(buf0, sizeof(buf0), 0x55);
-
- /* open connection to datasink service */
- sprintf(path, "%s.srv.%s", SRV_PATH_BASE, "datasink");
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_GT_ZERO(rc, "connect to datasink");
- ABORT_IF_NOT_OK(err_connect1);
- hchan1 = (handle_t)rc;
-
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_GT_ZERO(rc, "connect to datasink");
- ABORT_IF_NOT_OK(err_connect2);
- hchan2 = (handle_t)rc;
-
- /* send hchan2 handle over hchan1 connection */
- iov.iov_base = buf0;
- iov.iov_len = sizeof(buf0);
- msg.iov = &iov;
- msg.num_iov = 1;
- msg.handles = &hchan2;
- msg.num_handles = 1;
-
- for (unsigned int i = 0; (i < 10000) && !HasFailure(); i++) {
- while (!HasFailure()) {
- rc = send_msg(hchan1, &msg);
- if (rc == ERR_NOT_ENOUGH_BUFFER) { /* wait for room */
- uevent_t uevt;
- unsigned int exp_event = IPC_HANDLE_POLL_SEND_UNBLOCKED;
- rc = wait(hchan1, &uevt, 10000);
- EXPECT_EQ(NO_ERROR, rc, "waiting for space");
- EXPECT_EQ(hchan1, uevt.handle, "waiting for space");
- EXPECT_EQ(exp_event, uevt.event, "waiting for space");
- } else {
- EXPECT_EQ(64, rc, "send_msg bulk");
- break;
- }
- }
- }
- rc = close(hchan2);
- EXPECT_EQ(NO_ERROR, rc, "close chan2");
-
- /* repeat the same while closing handle after sending it */
- for (unsigned int i = 0; (i < 10000) && !HasFailure(); i++) {
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_GT_ZERO(rc, "connect to datasink");
- ABORT_IF_NOT_OK(err_connect2);
- hchan2 = (handle_t)rc;
-
- /* send hchan2 handle over hchan1 connection */
- iov.iov_base = buf0;
- iov.iov_len = sizeof(buf0);
- msg.iov = &iov;
- msg.num_iov = 1;
- msg.handles = &hchan2;
- msg.num_handles = 1;
-
- while (!HasFailure()) {
- rc = send_msg(hchan1, &msg);
- if (rc == ERR_NOT_ENOUGH_BUFFER) { /* wait for room */
- uevent_t uevt;
- unsigned int exp_event = IPC_HANDLE_POLL_SEND_UNBLOCKED;
- rc = wait(hchan1, &uevt, 10000);
- EXPECT_EQ(NO_ERROR, rc, "waiting for space");
- EXPECT_EQ(hchan1, uevt.handle, "waiting for space");
- EXPECT_EQ(exp_event, uevt.event, "waiting for space");
- } else {
- EXPECT_EQ(64, rc, "send_msg bulk");
- break;
- }
- }
- rc = close(hchan2);
- EXPECT_EQ(NO_ERROR, rc, "close chan2");
- }
-
-err_connect2:
- rc = close(hchan1);
- EXPECT_EQ(NO_ERROR, rc, "close chan1");
-err_connect1:;
-}
-
-TEST(ipc, echo_handle_bulk) {
- int rc;
- handle_t hchan1;
- handle_t hchan2;
- handle_t hrecv;
- uint8_t buf0[64];
- struct iovec iov;
- ipc_msg_t msg;
- uevent_t evt;
- ipc_msg_info_t inf;
- char path[MAX_PORT_PATH_LEN];
-
- /* prepare test buffer */
- fill_test_buf(buf0, sizeof(buf0), 0x55);
-
- /* open connection to echo service */
- sprintf(path, "%s.srv.%s", SRV_PATH_BASE, "echo");
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_GT_ZERO(rc, "connect to echo");
- ABORT_IF_NOT_OK(err_connect1);
- hchan1 = (handle_t)rc;
-
- /* open second connection to echo service */
- sprintf(path, "%s.srv.%s", SRV_PATH_BASE, "echo");
- rc = connect(path, IPC_CONNECT_WAIT_FOR_PORT);
- EXPECT_GT_ZERO(rc, "connect to echo");
- ABORT_IF_NOT_OK(err_connect2);
- hchan2 = (handle_t)rc;
-
- /* send the same handle 10000 times */
- for (unsigned int i = 0; (i < 10000) && !HasFailure(); i++) {
- /* send message with handle */
- iov.iov_base = buf0;
- iov.iov_len = sizeof(buf0);
- msg.iov = &iov;
- msg.num_iov = 1;
- msg.handles = &hchan2;
- msg.num_handles = 1;
-
- while (!HasFailure()) {
- rc = send_msg(hchan1, &msg);
- EXPECT_EQ(64, rc, "send_handle");
- if (rc == ERR_NOT_ENOUGH_BUFFER) { /* wait for room */
- uevent_t uevt;
- unsigned int exp_event = IPC_HANDLE_POLL_SEND_UNBLOCKED;
- rc = wait(hchan1, &uevt, 10000);
- EXPECT_EQ(NO_ERROR, rc, "waiting for space");
- EXPECT_EQ(hchan1, uevt.handle, "waiting for space");
- EXPECT_EQ(exp_event, uevt.event, "waiting for space");
- } else {
- EXPECT_EQ(64, rc, "send_msg bulk");
- break;
- }
- }
-
- /* wait for reply */
- rc = wait(hchan1, &evt, 1000);
- EXPECT_EQ(0, rc, "wait for reply");
- EXPECT_EQ(hchan1, evt.handle, "event.handle");
-
- /* get reply message */
- rc = get_msg(hchan1, &inf);
- EXPECT_EQ(NO_ERROR, rc, "getting echo reply");
- EXPECT_EQ(sizeof(buf0), inf.len, "reply len");
- EXPECT_EQ(1, inf.num_handles, "reply num_handles");
-
- /* read reply data and 1 handle */
- hrecv = INVALID_IPC_HANDLE;
- msg.handles = &hrecv;
- msg.num_handles = 1;
- rc = read_msg(hchan1, inf.id, 0, &msg);
- EXPECT_EQ(64, rc, "reading echo reply");
-
- /* discard reply */
- rc = put_msg(hchan1, inf.id);
- EXPECT_EQ(NO_ERROR, rc, "putting echo reply");
-
- /* close received handle */
- rc = close(hrecv);
- EXPECT_EQ(0, rc, "close reply handle");
- }
-
- rc = close(hchan2);
- EXPECT_EQ(NO_ERROR, rc, "close chan2");
-err_connect2:
- rc = close(hchan1);
- EXPECT_EQ(NO_ERROR, rc, "close chan1");
-err_connect1:;
-}
-
-/*
- * TIPC wrapper libtrary tests
- */
-TEST(ipc, tipc_connect) {
- int rc;
- handle_t h = INVALID_IPC_HANDLE;
- char path[MAX_PORT_PATH_LEN];
-
- /* Make tipc_connect fail and check if handle is unchanged */
- rc = tipc_connect(&h, NULL);
- EXPECT_EQ(ERR_FAULT, rc, "failed tipc_connect");
- EXPECT_EQ(INVALID_IPC_HANDLE, h, "failed tipc_connect")
-
- rc = close(h);
- EXPECT_EQ(ERR_BAD_HANDLE, rc, "close failed tipc_connect");
-
- /* Normal case: should succeed */
- sprintf(path, "%s.srv.%s", SRV_PATH_BASE, "echo");
- rc = tipc_connect(&h, path);
- EXPECT_EQ(0, rc, "tipc_connect");
- EXPECT_GT_ZERO(h, "tipc_connect");
-
- rc = close(h);
- EXPECT_EQ(0, rc, "close tipc_connect");
-}
-
-TEST(ipc, tipc_send_recv_1) {
- int rc;
- uint8_t tx_buf[64];
- uint8_t rx_buf[64];
- char path[MAX_PORT_PATH_LEN];
- handle_t h = INVALID_IPC_HANDLE;
- struct uevent evt = UEVENT_INITIAL_VALUE(evt);
-
- /* open connection to echo service */
- sprintf(path, "%s.srv.%s", SRV_PATH_BASE, "echo");
- rc = tipc_connect(&h, path);
- EXPECT_EQ(0, rc, "tipc_connect");
- EXPECT_GT_ZERO(h, "tipc_connect");
-
- /* send/receive zero length message */
- rc = tipc_send1(h, NULL, 0);
- EXPECT_EQ(0, rc, "tipc_send_one");
-
- rc = wait(h, &evt, INFINITE_TIME);
- EXPECT_EQ(0, rc, "wait for reply");
-
- rc = tipc_recv1(h, 0, rx_buf, sizeof(rx_buf));
- EXPECT_EQ(0, rc, "tipc_recv_one");
-
- /* send/receive normal message: should succeed */
- memset(tx_buf, 0x55, sizeof(tx_buf));
- memset(rx_buf, 0xaa, sizeof(rx_buf));
-
- rc = tipc_send1(h, tx_buf, sizeof(tx_buf) / 2);
- EXPECT_EQ(sizeof(tx_buf) / 2, (size_t)rc, "tipc_send1");
-
- rc = wait(h, &evt, INFINITE_TIME);
- EXPECT_EQ(0, rc, "wait for reply");
-
- rc = tipc_recv1(h, 0, rx_buf, sizeof(rx_buf));
- EXPECT_EQ(sizeof(tx_buf) / 2, (size_t)rc, "tipc_recv1");
-
- rc = memcmp(tx_buf, rx_buf, sizeof(tx_buf) / 2);
- EXPECT_EQ(0, rc, "memcmp");
-
- /*
- * send and then receive into small buffer: test should fail and
- * message should be discarded
- */
- memset(tx_buf, 0x55, sizeof(tx_buf));
- memset(rx_buf, 0xaa, sizeof(rx_buf));
-
- rc = tipc_send1(h, tx_buf, sizeof(tx_buf));
- EXPECT_EQ(sizeof(tx_buf), (size_t)rc, "tipc_send1");
-
- rc = wait(h, &evt, INFINITE_TIME);
- EXPECT_EQ(0, rc, "wait for reply");
-
- rc = tipc_recv1(h, 0, rx_buf, sizeof(rx_buf) / 2);
- EXPECT_EQ(ERR_BAD_LEN, rc, "tipc_recv1");
-
- /*
- * send and then receive message shorter them minimum: should fail
- */
- memset(tx_buf, 0x55, sizeof(tx_buf));
- memset(rx_buf, 0xaa, sizeof(rx_buf));
-
- rc = tipc_send1(h, tx_buf, sizeof(tx_buf) / 2);
- EXPECT_EQ(sizeof(tx_buf) / 2, (size_t)rc, "tipc_send1");
-
- rc = wait(h, &evt, INFINITE_TIME);
- EXPECT_EQ(0, rc, "wait for reply");
-
- rc = tipc_recv1(h, sizeof(rx_buf), rx_buf, sizeof(rx_buf));
- EXPECT_EQ(ERR_BAD_LEN, rc, "tipc_recv1");
-
- /* clean up */
- rc = close(h);
- EXPECT_EQ(0, rc, "close tipc_connect");
-}
-
-TEST(ipc, tipc_send_recv_hdr_payload) {
- int rc;
- uint8_t tx_hdr[32];
- uint8_t tx_buf[64];
- uint8_t rx_hdr[32];
- uint8_t rx_buf[64];
- char path[MAX_PORT_PATH_LEN];
- handle_t h = INVALID_IPC_HANDLE;
- struct uevent evt = UEVENT_INITIAL_VALUE(evt);
-
- sprintf(path, "%s.srv.%s", SRV_PATH_BASE, "echo");
- rc = tipc_connect(&h, path);
- EXPECT_EQ(0, rc, "tipc_connect");
- EXPECT_GT_ZERO(h, "tipc_connect");
-
- /* send/receive normal message: should succeed */
- memset(tx_hdr, 0xaa, sizeof(tx_hdr));
- memset(tx_buf, 0x55, sizeof(tx_buf));
- memset(rx_hdr, 0x55, sizeof(rx_hdr));
- memset(rx_buf, 0xaa, sizeof(rx_buf));
-
- rc = tipc_send2(h, tx_hdr, sizeof(tx_hdr), tx_buf, sizeof(tx_buf) / 2);
- EXPECT_EQ(sizeof(tx_hdr) + sizeof(tx_buf) / 2, (size_t)rc, "tipc_send_two");
-
- rc = wait(h, &evt, INFINITE_TIME);
- EXPECT_EQ(0, rc, "wait for reply");
-
- rc = tipc_recv_hdr_payload(h, rx_hdr, sizeof(rx_hdr), rx_buf,
- sizeof(rx_buf));
- EXPECT_EQ(sizeof(tx_hdr) + sizeof(tx_buf) / 2, (size_t)rc,
- "tipc_recv_hdr_payload");
-
- rc = memcmp(tx_hdr, rx_hdr, sizeof(tx_hdr));
- EXPECT_EQ(0, rc, "memcmp");
-
- rc = memcmp(tx_buf, rx_buf, sizeof(tx_buf) / 2);
- EXPECT_EQ(0, rc, "memcmp");
-
- /* send/receive message with zero length header */
- memset(tx_hdr, 0xaa, sizeof(tx_hdr));
- memset(tx_buf, 0x55, sizeof(tx_buf));
- memset(rx_hdr, 0xaa, sizeof(rx_hdr));
- memset(rx_buf, 0xaa, sizeof(rx_buf));
-
- rc = tipc_send2(h, NULL, 0, tx_buf, sizeof(tx_buf) / 2);
- EXPECT_EQ(sizeof(tx_buf) / 2, (size_t)rc, "tipc_send_two");
-
- rc = wait(h, &evt, INFINITE_TIME);
- EXPECT_EQ(0, rc, "wait for reply");
-
- rc = tipc_recv_hdr_payload(h, NULL, 0, rx_buf, sizeof(rx_buf));
- EXPECT_EQ(sizeof(tx_buf) / 2, (size_t)rc, "tipc_recv_hdr_payload");
-
- rc = memcmp(tx_buf, rx_buf, sizeof(tx_buf) / 2);
- EXPECT_EQ(0, rc, "memcmp");
-
- /* send/receive message with zero length payload */
- memset(tx_hdr, 0xaa, sizeof(tx_hdr));
- memset(tx_buf, 0x55, sizeof(tx_buf));
- memset(rx_hdr, 0xaa, sizeof(rx_hdr));
- memset(rx_buf, 0xaa, sizeof(rx_buf));
-
- rc = tipc_send2(h, tx_hdr, sizeof(tx_hdr), NULL, 0);
- EXPECT_EQ(sizeof(tx_hdr), (size_t)rc, "tipc_send_two");
-
- rc = wait(h, &evt, INFINITE_TIME);
- EXPECT_EQ(0, rc, "wait for reply");
-
- rc = tipc_recv_hdr_payload(h, rx_hdr, sizeof(rx_hdr), rx_buf,
- sizeof(rx_buf));
- EXPECT_EQ(sizeof(tx_hdr), (size_t)rc, "tipc_recv_hdr_payload");
-
- rc = memcmp(tx_hdr, rx_hdr, sizeof(tx_hdr));
- EXPECT_EQ(0, rc, "memcmp");
-
- /*
- * send/receive header into larger buffer: should fail as more data expected
- */
- memset(tx_hdr, 0xaa, sizeof(tx_hdr));
- memset(tx_buf, 0x55, sizeof(tx_buf));
- memset(rx_hdr, 0xaa, sizeof(rx_hdr));
- memset(rx_buf, 0xaa, sizeof(rx_buf));
-
- rc = tipc_send2(h, tx_hdr, sizeof(tx_hdr) / 2, NULL, 0);
- EXPECT_EQ(sizeof(tx_hdr) / 2, (size_t)rc, "tipc_send_two");
-
- rc = wait(h, &evt, INFINITE_TIME);
- EXPECT_EQ(0, rc, "wait for reply");
-
- rc = tipc_recv_hdr_payload(h, rx_hdr, sizeof(rx_hdr), NULL, 0);
- EXPECT_EQ(ERR_BAD_LEN, rc, "tipc_recv_hdr_payload");
-
- /*
- * send/receive message into short buffer: should fail as bigger buffer
- * is expected
- */
- memset(tx_hdr, 0xaa, sizeof(tx_hdr));
- memset(tx_buf, 0x55, sizeof(tx_buf));
- memset(rx_hdr, 0xaa, sizeof(rx_hdr));
- memset(rx_buf, 0xaa, sizeof(rx_buf));
-
- rc = tipc_send2(h, tx_hdr, sizeof(tx_hdr), tx_buf, sizeof(tx_buf));
- EXPECT_EQ(sizeof(tx_hdr) + sizeof(tx_buf), (size_t)rc, "tipc_send_two");
-
- rc = wait(h, &evt, INFINITE_TIME);
- EXPECT_EQ(0, rc, "wait for reply");
-
- rc = tipc_recv_hdr_payload(h, rx_hdr, sizeof(rx_hdr), rx_buf,
- sizeof(rx_buf) / 2);
- EXPECT_EQ(ERR_BAD_LEN, rc, "tipc_recv_hdr_payload");
-
- rc = close(h);
- EXPECT_EQ(0, rc, "close tipc_connect");
-}
-
-/****************************************************************************/
-
-static void kernel_wait_any_bug_workaround(void) {
- int ret;
- uevent_t event;
-
- /* HACK: clear stuck event on handleset */
- ret = wait_any(&event, 0);
- if (ret == 0) {
- TLOGI("retry ret %d, event handle %d, event 0x%x\n", ret, event.handle,
- event.event);
- ret = wait(event.handle, &event, 0);
- TLOGI("nested ret %d, event handle %d, event 0x%x\n", ret, event.handle,
- event.event);
- }
-}
-
-static bool run_test(struct unittest* test) {
- /*
- * HACK: unittest library uses a hset. First handle is one before the port
- * handle
- */
- handle_base = test->_port_handle - 1;
-
- kernel_wait_any_bug_workaround();
-
- return RUN_ALL_TESTS();
-}
-
-/*
- * Application entry point
- */
-int main(void) {
- struct unittest ipc_unittest = {
- .port_name = SRV_PATH_BASE ".ctrl",
- .run_test = run_test,
- };
- struct unittest* unittest = &ipc_unittest;
-
- TLOGI("Welcome to IPC unittest!!!\n");
-
- return unittest_main(&unittest, 1);
-}
diff --git a/ipc-unittest/main/manifest.json b/ipc-unittest/main/manifest.json
deleted file mode 100644
index 2b510cd..0000000
--- a/ipc-unittest/main/manifest.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "uuid": "IPC_UNITTEST_MAIN_APP_UUID",
- "min_heap": 16384,
- "min_stack": 8192
-}
diff --git a/ipc-unittest/main/rules.mk b/ipc-unittest/main/rules.mk
deleted file mode 100644
index e3bc1d8..0000000
--- a/ipc-unittest/main/rules.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-# 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.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-LOCAL_DIR := $(GET_LOCAL_DIR)
-
-MODULE := $(LOCAL_DIR)
-
-MANIFEST := $(LOCAL_DIR)/manifest.json
-
-CONSTANTS := $(LOCAL_DIR)/../include/app/ipc_unittest/ipc_unittest_uuid_consts.json
-
-MODULE_INCLUDES += \
- $(LOCAL_DIR)/../include \
-
-MODULE_SRCS += \
- $(LOCAL_DIR)/main.c \
-
-MODULE_DEPS += \
- trusty/user/base/lib/libc-trusty \
- trusty/user/base/lib/tipc \
- trusty/user/base/lib/unittest \
-
-include make/module.mk
diff --git a/ipc-unittest/srv/manifest.json b/ipc-unittest/srv/manifest.json
deleted file mode 100644
index 431098e..0000000
--- a/ipc-unittest/srv/manifest.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "uuid": "IPC_UNITTEST_SRV_APP_UUID",
- "min_heap": 16384,
- "min_stack": 8192
-}
diff --git a/ipc-unittest/srv/rules.mk b/ipc-unittest/srv/rules.mk
deleted file mode 100644
index e750ea9..0000000
--- a/ipc-unittest/srv/rules.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-# 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.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-LOCAL_DIR := $(GET_LOCAL_DIR)
-
-MODULE := $(LOCAL_DIR)
-
-MANIFEST := $(LOCAL_DIR)/manifest.json
-
-CONSTANTS := $(LOCAL_DIR)/../include/app/ipc_unittest/ipc_unittest_uuid_consts.json
-
-MODULE_INCLUDES += \
- $(LOCAL_DIR)/../include \
-
-MODULE_SRCS += \
- $(LOCAL_DIR)/srv.c \
-
-MODULE_DEPS += \
- trusty/user/base/lib/libc-trusty \
-
-include make/module.mk
diff --git a/ipc-unittest/srv/srv.c b/ipc-unittest/srv/srv.c
deleted file mode 100644
index 9ffb3a4..0000000
--- a/ipc-unittest/srv/srv.c
+++ /dev/null
@@ -1,850 +0,0 @@
-/*
- * 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <assert.h>
-#include <lk/list.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <trusty_ipc.h>
-#include <uapi/err.h>
-
-#define TLOG_TAG "ipc-unittest-srv"
-
-#include <app/ipc_unittest/common.h>
-#include <ipc_unittest_uuid_consts.h>
-
-typedef void (*event_handler_proc_t)(const uevent_t* ev);
-
-typedef struct tipc_event_handler {
- event_handler_proc_t proc;
- void* priv;
-} tipc_event_handler_t;
-
-typedef struct tipc_srv {
- const char* name;
- unsigned int msg_num;
- size_t msg_size;
- unsigned int port_flags;
- size_t port_state_size;
- size_t chan_state_size;
- event_handler_proc_t port_handler;
- event_handler_proc_t chan_handler;
-} tipc_srv_t;
-
-typedef struct tipc_srv_state {
- const struct tipc_srv* service;
- handle_t port;
- void* priv;
- tipc_event_handler_t handler;
-} tipc_srv_state_t;
-
-/* closer services */
-static void closer1_handle_port(const uevent_t* ev);
-
-typedef struct closer1_state {
- unsigned int conn_cnt;
-} closer1_state_t;
-
-static void closer2_handle_port(const uevent_t* ev);
-
-typedef struct closer2_state {
- unsigned int conn_cnt;
-} closer2_state_t;
-
-static void closer3_handle_port(const uevent_t* ev);
-
-typedef struct closer3_state {
- handle_t chans[4];
- unsigned int chan_cnt;
-} closer3_state_t;
-
-/* connect service */
-static void connect_handle_port(const uevent_t* ev);
-
-/* datasync service */
-static void datasink_handle_port(const uevent_t* ev);
-static void datasink_handle_chan(const uevent_t* ev);
-
-/* datasink service has no per channel state so we can
- * just attach handler struct directly to channel handle
- */
-static struct tipc_event_handler _datasink_chan_handler = {
- .proc = datasink_handle_chan,
- .priv = NULL,
-};
-
-/* echo service */
-static void echo_handle_port(const uevent_t* ev);
-static void echo_handle_chan(const uevent_t* ev);
-
-typedef struct echo_chan_state {
- struct tipc_event_handler handler;
- unsigned int msg_max_num;
- unsigned int msg_cnt;
- unsigned int msg_next_r;
- unsigned int msg_next_w;
- struct ipc_msg_info msg_queue[0];
-} echo_chan_state_t;
-
-/* uuid service */
-static void uuid_handle_port(const uevent_t* ev);
-
-/* Other globals */
-static bool stopped = false;
-
-/************************************************************************/
-
-#define IPC_PORT_ALLOW_ALL \
- (IPC_PORT_ALLOW_NS_CONNECT | IPC_PORT_ALLOW_TA_CONNECT)
-
-#define SRV_NAME(name) SRV_PATH_BASE ".srv." name
-
-static const struct tipc_srv _services[] = {
- {
- .name = SRV_NAME("closer1"),
- .msg_num = 2,
- .msg_size = 64,
- .port_flags = IPC_PORT_ALLOW_ALL,
- .port_handler = closer1_handle_port,
- .port_state_size = sizeof(struct closer1_state),
- .chan_handler = NULL,
- },
- {
- .name = SRV_NAME("closer2"),
- .msg_num = 2,
- .msg_size = 64,
- .port_flags = IPC_PORT_ALLOW_ALL,
- .port_handler = closer2_handle_port,
- .port_state_size = sizeof(struct closer2_state),
- .chan_handler = NULL,
- },
- {
- .name = SRV_NAME("closer3"),
- .msg_num = 2,
- .msg_size = 64,
- .port_flags = IPC_PORT_ALLOW_ALL,
- .port_handler = closer3_handle_port,
- .port_state_size = sizeof(struct closer3_state),
- .chan_handler = NULL,
- },
- {
- .name = SRV_NAME("connect"),
- .msg_num = 2,
- .msg_size = 64,
- .port_flags = IPC_PORT_ALLOW_TA_CONNECT,
- .port_handler = connect_handle_port,
- .chan_handler = NULL,
- },
- /* datasink services */
- {
- .name = SRV_NAME("datasink"),
- .msg_num = 2,
- .msg_size = 64,
- .port_flags = IPC_PORT_ALLOW_ALL,
- .port_handler = datasink_handle_port,
- .chan_handler = NULL,
- },
- {
- .name = SRV_NAME("ns_only"),
- .msg_num = 8,
- .msg_size = 64,
- .port_flags = IPC_PORT_ALLOW_NS_CONNECT,
- .port_handler = datasink_handle_port,
- .chan_handler = NULL,
- },
- {
- .name = SRV_NAME("ta_only"),
- .msg_num = 8,
- .msg_size = 64,
- .port_flags = IPC_PORT_ALLOW_TA_CONNECT,
- .port_handler = datasink_handle_port,
- .chan_handler = NULL,
- },
- /* echo */
- {
- .name = SRV_NAME("echo"),
- .msg_num = 8,
- .msg_size = MAX_PORT_BUF_SIZE,
- .port_flags = IPC_PORT_ALLOW_ALL,
- .port_handler = echo_handle_port,
- .chan_handler = echo_handle_chan,
- },
- /* uuid test */
- {
- .name = SRV_NAME("uuid"),
- .msg_num = 2,
- .msg_size = 64,
- .port_flags = IPC_PORT_ALLOW_ALL,
- .port_handler = uuid_handle_port,
- .chan_handler = NULL,
- },
-};
-
-static struct tipc_srv_state _srv_states[countof(_services)] = {
- [0 ...(countof(_services) - 1)] =
- {
- .port = INVALID_IPC_HANDLE,
- },
-};
-
-/************************************************************************/
-
-static struct tipc_srv_state* get_srv_state(const uevent_t* ev) {
- return containerof(ev->cookie, struct tipc_srv_state, handler);
-}
-
-static void _destroy_service(struct tipc_srv_state* state) {
- if (!state) {
- TLOGI("non-null state expected\n");
- return;
- }
-
- /* free state if any */
- if (state->priv) {
- free(state->priv);
- state->priv = NULL;
- }
-
- /* close port */
- if (state->port != INVALID_IPC_HANDLE) {
- int rc = close(state->port);
- if (rc != NO_ERROR) {
- TLOGI("Failed (%d) to close port %d\n", rc, state->port);
- }
- state->port = INVALID_IPC_HANDLE;
- }
-
- /* reset handler */
- state->service = NULL;
- state->handler.proc = NULL;
- state->handler.priv = NULL;
-}
-
-/*
- * Create service
- */
-static int _create_service(const struct tipc_srv* srv,
- struct tipc_srv_state* state) {
- if (!srv || !state) {
- TLOGI("null services specified\n");
- return ERR_INVALID_ARGS;
- }
-
- /* create port */
- int rc = port_create(srv->name, srv->msg_num, srv->msg_size,
- srv->port_flags);
- if (rc < 0) {
- TLOGI("Failed (%d) to create port\n", rc);
- return rc;
- }
-
- /* setup port state */
- state->port = (handle_t)rc;
- state->handler.proc = srv->port_handler;
- state->handler.priv = state;
- state->service = srv;
- state->priv = NULL;
-
- if (srv->port_state_size) {
- /* allocate port state */
- state->priv = calloc(1, srv->port_state_size);
- if (!state->priv) {
- rc = ERR_NO_MEMORY;
- goto err_calloc;
- }
- }
-
- /* attach handler to port handle */
- rc = set_cookie(state->port, &state->handler);
- if (rc < 0) {
- TLOGI("Failed (%d) to set cookie on port %d\n", rc, state->port);
- goto err_set_cookie;
- }
-
- return NO_ERROR;
-
-err_calloc:
-err_set_cookie:
- _destroy_service(state);
- return rc;
-}
-
-/*
- * Restart specified service
- */
-static int restart_service(struct tipc_srv_state* state) {
- if (!state) {
- TLOGI("non-null state expected\n");
- return ERR_INVALID_ARGS;
- }
-
- const struct tipc_srv* srv = state->service;
- _destroy_service(state);
- return _create_service(srv, state);
-}
-
-/*
- * Kill all servoces
- */
-static void kill_services(void) {
- TLOGI("Terminating unittest services\n");
-
- /* close any opened ports */
- for (unsigned int i = 0; i < countof(_services); i++) {
- _destroy_service(&_srv_states[i]);
- }
-}
-
-/*
- * Initialize all services
- */
-static int init_services(void) {
- TLOGI("Init unittest services!!!\n");
-
- for (unsigned int i = 0; i < countof(_services); i++) {
- int rc = _create_service(&_services[i], &_srv_states[i]);
- if (rc < 0) {
- TLOGI("Failed (%d) to create service %s\n", rc, _services[i].name);
- return rc;
- }
- }
-
- return 0;
-}
-
-/*
- * Handle common port errors
- */
-static bool handle_port_errors(const uevent_t* ev) {
- if ((ev->event & IPC_HANDLE_POLL_ERROR) ||
- (ev->event & IPC_HANDLE_POLL_HUP) ||
- (ev->event & IPC_HANDLE_POLL_MSG) ||
- (ev->event & IPC_HANDLE_POLL_SEND_UNBLOCKED)) {
- /* should never happen with port handles */
- TLOGI("error event (0x%x) for port (%d)\n", ev->event, ev->handle);
-
- /* recreate service */
- restart_service(get_srv_state(ev));
- return true;
- }
-
- return false;
-}
-
-/****************************** connect test service *********************/
-
-/*
- * Local wrapper on top of async connect that provides
- * synchronos connect with timeout.
- */
-int sync_connect(const char* path, unsigned int timeout) {
- int rc;
- uevent_t evt;
- handle_t chan;
-
- rc = connect(path, IPC_CONNECT_ASYNC | IPC_CONNECT_WAIT_FOR_PORT);
- if (rc >= 0) {
- chan = (handle_t)rc;
- rc = wait(chan, &evt, timeout);
- if (rc == 0) {
- rc = ERR_BAD_STATE;
- if (evt.handle == chan) {
- if (evt.event & IPC_HANDLE_POLL_READY)
- return chan;
-
- if (evt.event & IPC_HANDLE_POLL_HUP)
- rc = ERR_CHANNEL_CLOSED;
- }
- }
- close(chan);
- }
- return rc;
-}
-
-static void connect_handle_port(const uevent_t* ev) {
- uuid_t peer_uuid;
-
- if (handle_port_errors(ev))
- return;
-
- if (ev->event & IPC_HANDLE_POLL_READY) {
- char path[MAX_PORT_PATH_LEN];
-
- /* accept incomming connection and close it */
- int rc = accept(ev->handle, &peer_uuid);
- if (rc < 0 && rc != ERR_CHANNEL_CLOSED) {
- TLOGI("accept failed (%d)\n", rc);
- return;
- }
- if (rc >= 0) {
- close((handle_t)rc);
- }
-
- /* but then issue a series of connect requests */
- for (unsigned int i = FIRST_FREE_HANDLE; i < MAX_USER_HANDLES; i++) {
- sprintf(path, "%s.port.accept%d", SRV_PATH_BASE, i);
- rc = sync_connect(path, 1000);
- close((handle_t)rc);
- }
- }
-}
-
-/****************************** closer services **************************/
-
-static void closer1_handle_port(const uevent_t* ev) {
- uuid_t peer_uuid;
- struct closer1_state* st = get_srv_state(ev)->priv;
-
- if (handle_port_errors(ev))
- return;
-
- if (ev->event & IPC_HANDLE_POLL_READY) {
- /* new connection request, bump counter */
- st->conn_cnt++;
-
- /* accept it */
- int rc = accept(ev->handle, &peer_uuid);
- if (rc < 0) {
- TLOGI("accept failed (%d)\n", rc);
- return;
- }
- handle_t chan = (handle_t)rc;
-
- if (st->conn_cnt & 1) {
- /* sleep a bit */
- trusty_nanosleep(0, 0, 100 * MSEC);
- }
- /* and close it */
- rc = close(chan);
- if (rc != NO_ERROR) {
- TLOGI("Failed (%d) to close chan %d\n", rc, chan);
- }
- }
-}
-
-static void closer2_handle_port(const uevent_t* ev) {
- struct closer2_state* st = get_srv_state(ev)->priv;
-
- if (handle_port_errors(ev))
- return;
-
- if (ev->event & IPC_HANDLE_POLL_READY) {
- /* new connection request, bump counter */
- st->conn_cnt++;
- if (st->conn_cnt & 1) {
- /* sleep a bit */
- trusty_nanosleep(0, 0, 100 * MSEC);
- }
-
- /*
- * then close the port without accepting any connections
- * and restart it again
- */
- restart_service(get_srv_state(ev));
- }
-}
-
-static void closer3_handle_port(const uevent_t* ev) {
- uuid_t peer_uuid;
- struct closer3_state* st = get_srv_state(ev)->priv;
-
- if (handle_port_errors(ev))
- return;
-
- if (ev->event & IPC_HANDLE_POLL_READY) {
- /* accept connection */
- int rc = accept(ev->handle, &peer_uuid);
- if (rc < 0) {
- TLOGI("accept failed (%d)\n", rc);
- return;
- }
- /* add it to connection pool */
- st->chans[st->chan_cnt++] = (handle_t)rc;
-
- /* attach datasink service handler just in case */
- set_cookie((handle_t)rc, &_datasink_chan_handler);
-
- /* when max number of connection reached */
- if (st->chan_cnt == countof(st->chans)) {
- /* wait a bit */
- trusty_nanosleep(0, 0, 100 * MSEC);
-
- /* and close them all */
- for (unsigned int i = 0; i < st->chan_cnt; i++)
- close(st->chans[i]);
- st->chan_cnt = 0;
- }
- return;
- }
-}
-
-/****************************** datasync service **************************/
-
-static int datasink_handle_msg(const uevent_t* ev) {
- int rc;
- ipc_msg_info_t inf;
-
- /* for all messages */
- for (;;) {
- /* get message */
- rc = get_msg(ev->handle, &inf);
- if (rc == ERR_NO_MSG)
- break; /* no new messages */
-
- if (rc != NO_ERROR) {
- TLOGI("failed (%d) to get_msg for chan (%d)\n", rc, ev->handle);
- return rc;
- }
-
- /* and retire it without actually reading */
- rc = put_msg(ev->handle, inf.id);
- if (rc != NO_ERROR) {
- TLOGI("failed (%d) to putt_msg for chan (%d)\n", rc, ev->handle);
- return rc;
- }
- }
-
- return NO_ERROR;
-}
-
-/*
- * Datasink service channel handler
- */
-static void datasink_handle_chan(const uevent_t* ev) {
- if ((ev->event & IPC_HANDLE_POLL_ERROR) ||
- (ev->event & IPC_HANDLE_POLL_SEND_UNBLOCKED)) {
- /* close it as it is in an error state */
- TLOGI("error event (0x%x) for chan (%d)\n", ev->event, ev->handle);
- close(ev->handle);
- return;
- }
-
- if (ev->event & IPC_HANDLE_POLL_MSG) {
- if (datasink_handle_msg(ev) != 0) {
- close(ev->handle);
- return;
- }
- }
-
- if (ev->event & IPC_HANDLE_POLL_HUP) {
- /* closed by peer */
- close(ev->handle);
- return;
- }
-}
-
-/*
- * Datasink service port event handler
- */
-static void datasink_handle_port(const uevent_t* ev) {
- uuid_t peer_uuid;
-
- if (handle_port_errors(ev))
- return;
-
- if (ev->event & IPC_HANDLE_POLL_READY) {
- /* incomming connection: accept it */
- int rc = accept(ev->handle, &peer_uuid);
- if (rc < 0) {
- TLOGI("failed (%d) to accept on port %d\n", rc, ev->handle);
- return;
- }
-
- handle_t chan = (handle_t)rc;
- rc = set_cookie(chan, &_datasink_chan_handler);
- if (rc) {
- TLOGI("failed (%d) to set_cookie on chan %d\n", rc, chan);
- }
- }
-}
-
-/****************************** echo service **************************/
-
-static uint8_t echo_msg_buf[MAX_PORT_BUF_SIZE];
-
-static int _echo_handle_msg(const uevent_t* ev, int delay) {
- int rc;
- struct iovec iov;
- ipc_msg_t msg;
- handle_t handles[8];
- echo_chan_state_t* st = containerof(ev->cookie, echo_chan_state_t, handler);
-
- /* get all messages */
- while (st->msg_cnt != st->msg_max_num) {
- rc = get_msg(ev->handle, &st->msg_queue[st->msg_next_w]);
- if (rc == ERR_NO_MSG)
- break; /* no new messages */
-
- if (rc != NO_ERROR) {
- TLOGI("failed (%d) to get_msg for chan (%d)\n", rc, ev->handle);
- return rc;
- }
-
- st->msg_cnt++;
- st->msg_next_w++;
- if (st->msg_next_w == st->msg_max_num)
- st->msg_next_w = 0;
- }
-
- /* handle all messages in queue */
- while (st->msg_cnt) {
- /* init message structure */
- iov.iov_base = echo_msg_buf;
- iov.iov_len = sizeof(echo_msg_buf);
- msg.num_iov = 1;
- msg.iov = &iov;
- msg.handles = handles;
- msg.num_handles = st->msg_queue[st->msg_next_r].num_handles;
-
- /* read msg content */
- rc = read_msg(ev->handle, st->msg_queue[st->msg_next_r].id, 0, &msg);
- if (rc < 0) {
- TLOGI("failed (%d) to read_msg for chan (%d)\n", rc, ev->handle);
- return rc;
- }
-
- /* update number of bytes received */
- iov.iov_len = (size_t)rc;
-
- /* optionally sleep a bit an send it back */
- if (delay) {
- trusty_nanosleep(0, 0, 1000);
- }
-
- /* and send it back */
- rc = send_msg(ev->handle, &msg);
-
- /* close all received handles */
- for (unsigned int i = 0; i < msg.num_handles; i++) {
- close(handles[i]);
- }
-
- if (rc == ERR_NOT_ENOUGH_BUFFER)
- break;
-
- if (rc < 0) {
- TLOGI("failed (%d) to send_msg for chan (%d)\n", rc, ev->handle);
- return rc;
- }
-
- /* retire original message */
- rc = put_msg(ev->handle, st->msg_queue[st->msg_next_r].id);
- if (rc != NO_ERROR) {
- TLOGI("failed (%d) to put_msg for chan (%d)\n", rc, ev->handle);
- return rc;
- }
-
- /* advance queue */
- st->msg_cnt--;
- st->msg_next_r++;
- if (st->msg_next_r == st->msg_max_num)
- st->msg_next_r = 0;
- }
- return NO_ERROR;
-}
-
-static int echo_handle_msg(const uevent_t* ev) {
- return _echo_handle_msg(ev, false);
-}
-
-/*
- * echo service channel handler
- */
-static void echo_handle_chan(const uevent_t* ev) {
- if (ev->event & IPC_HANDLE_POLL_ERROR) {
- /* close it as it is in an error state */
- TLOGI("error event (0x%x) for chan (%d)\n", ev->event, ev->handle);
- goto close_it;
- }
-
- if (ev->event & (IPC_HANDLE_POLL_MSG | IPC_HANDLE_POLL_SEND_UNBLOCKED)) {
- if (echo_handle_msg(ev) != 0) {
- TLOGI("error event (0x%x) for chan (%d)\n", ev->event, ev->handle);
- goto close_it;
- }
- }
-
- if (ev->event & IPC_HANDLE_POLL_HUP) {
- goto close_it;
- }
-
- return;
-
-close_it:
- free(ev->cookie);
- close(ev->handle);
-}
-
-/*
- * echo service port event handler
- */
-static void echo_handle_port(const uevent_t* ev) {
- uuid_t peer_uuid;
- struct echo_chan_state* chan_st;
- const struct tipc_srv* srv = get_srv_state(ev)->service;
-
- if (handle_port_errors(ev))
- return;
-
- if (ev->event & IPC_HANDLE_POLL_READY) {
- handle_t chan;
-
- /* incomming connection: accept it */
- int rc = accept(ev->handle, &peer_uuid);
- if (rc < 0) {
- TLOGI("failed (%d) to accept on port %d\n", rc, ev->handle);
- return;
- }
- chan = (handle_t)rc;
-
- chan_st = calloc(1, sizeof(struct echo_chan_state) +
- sizeof(ipc_msg_info_t) * srv->msg_num);
- if (!chan_st) {
- TLOGI("failed (%d) to callocate state for chan %d\n", rc, chan);
- close(chan);
- return;
- }
-
- /* init state */
- chan_st->msg_max_num = srv->msg_num;
- chan_st->handler.proc = srv->chan_handler;
- chan_st->handler.priv = chan_st;
-
- /* attach it to handle */
- rc = set_cookie(chan, &chan_st->handler);
- if (rc) {
- TLOGI("failed (%d) to set_cookie on chan %d\n", rc, chan);
- free(chan_st);
- close(chan);
- return;
- }
- }
-}
-
-/***************************************************************************/
-
-/*
- * uuid service port event handler
- */
-static void uuid_handle_port(const uevent_t* ev) {
- ipc_msg_t msg;
- struct iovec iov;
- uuid_t peer_uuid;
-
- if (handle_port_errors(ev))
- return;
-
- if (ev->event & IPC_HANDLE_POLL_READY) {
- handle_t chan;
-
- /* incomming connection: accept it */
- int rc = accept(ev->handle, &peer_uuid);
- if (rc < 0) {
- TLOGI("failed (%d) to accept on port %d\n", rc, ev->handle);
- return;
- }
- chan = (handle_t)rc;
-
- /* send interface uuid */
- iov.iov_base = &peer_uuid;
- iov.iov_len = sizeof(peer_uuid);
- msg.num_iov = 1;
- msg.iov = &iov;
- msg.num_handles = 0;
- msg.handles = NULL;
- rc = send_msg(chan, &msg);
- if (rc < 0) {
- TLOGI("failed (%d) to send_msg for chan (%d)\n", rc, chan);
- }
-
- /* and close channel */
- close(chan);
- }
-}
-
-/***************************************************************************/
-
-/*
- * Dispatch event
- */
-static void dispatch_event(const uevent_t* ev) {
- assert(ev);
-
- if (ev->event == IPC_HANDLE_POLL_NONE) {
- /* not really an event, do nothing */
- TLOGI("got an empty event\n");
- return;
- }
-
- if (ev->handle == INVALID_IPC_HANDLE) {
- /* not a valid handle */
- TLOGI("got an event (0x%x) with invalid handle (%d)", ev->event,
- ev->handle);
- return;
- }
-
- /* check if we have handler */
- struct tipc_event_handler* handler = ev->cookie;
- if (handler && handler->proc) {
- /* invoke it */
- handler->proc(ev);
- return;
- }
-
- /* no handler? close it */
- TLOGI("no handler for event (0x%x) with handle %d\n", ev->event,
- ev->handle);
- close(ev->handle);
-
- return;
-}
-
-/*
- * Main entry point of service task
- */
-int main(void) {
- int rc;
- uevent_t event;
-
- /* Initialize service */
- rc = init_services();
- if (rc != NO_ERROR) {
- TLOGI("Failed (%d) to init service", rc);
- kill_services();
- return -1;
- }
-
- /* handle events */
- while (!stopped) {
- event.handle = INVALID_IPC_HANDLE;
- event.event = 0;
- event.cookie = NULL;
- rc = wait_any(&event, INFINITE_TIME);
- if (rc < 0) {
- TLOGI("wait_any failed (%d)", rc);
- continue;
- }
- if (rc == NO_ERROR) { /* got an event */
- dispatch_event(&event);
- }
- }
-
- kill_services();
- return 0;
-}
diff --git a/usertests-inc.mk b/usertests-inc.mk
index 8e16068..2a0626e 100644
--- a/usertests-inc.mk
+++ b/usertests-inc.mk
@@ -20,8 +20,6 @@
trusty/user/app/sample/app-mgmt-test/port-start-srv \
trusty/user/app/sample/app-mgmt-test/restart-srv \
trusty/user/app/sample/hwcrypto-unittest \
- trusty/user/app/sample/ipc-unittest/main \
- trusty/user/app/sample/ipc-unittest/srv \
trusty/user/app/sample/manifest-test \
trusty/user/app/sample/libcxx-test \
trusty/user/app/sample/memref-test \