1*344aa361SAndroid Build Coastguard Worker /*
2*344aa361SAndroid Build Coastguard Worker * Copyright (c) 2022, Google Inc. All rights reserved
3*344aa361SAndroid Build Coastguard Worker *
4*344aa361SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining
5*344aa361SAndroid Build Coastguard Worker * a copy of this software and associated documentation files
6*344aa361SAndroid Build Coastguard Worker * (the "Software"), to deal in the Software without restriction,
7*344aa361SAndroid Build Coastguard Worker * including without limitation the rights to use, copy, modify, merge,
8*344aa361SAndroid Build Coastguard Worker * publish, distribute, sublicense, and/or sell copies of the Software,
9*344aa361SAndroid Build Coastguard Worker * and to permit persons to whom the Software is furnished to do so,
10*344aa361SAndroid Build Coastguard Worker * subject to the following conditions:
11*344aa361SAndroid Build Coastguard Worker *
12*344aa361SAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be
13*344aa361SAndroid Build Coastguard Worker * included in all copies or substantial portions of the Software.
14*344aa361SAndroid Build Coastguard Worker *
15*344aa361SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16*344aa361SAndroid Build Coastguard Worker * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17*344aa361SAndroid Build Coastguard Worker * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18*344aa361SAndroid Build Coastguard Worker * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19*344aa361SAndroid Build Coastguard Worker * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20*344aa361SAndroid Build Coastguard Worker * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21*344aa361SAndroid Build Coastguard Worker * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22*344aa361SAndroid Build Coastguard Worker */
23*344aa361SAndroid Build Coastguard Worker
24*344aa361SAndroid Build Coastguard Worker #include <err.h>
25*344aa361SAndroid Build Coastguard Worker #include <ktipc_test.h>
26*344aa361SAndroid Build Coastguard Worker #include <lib/ktipc/ktipc.h>
27*344aa361SAndroid Build Coastguard Worker #include <lib/unittest/unittest.h>
28*344aa361SAndroid Build Coastguard Worker #include <lk/init.h>
29*344aa361SAndroid Build Coastguard Worker
30*344aa361SAndroid Build Coastguard Worker #define TIMEOUT_MSEC 10000
31*344aa361SAndroid Build Coastguard Worker
32*344aa361SAndroid Build Coastguard Worker #define NUM_TEST_CONNECTIONS 100
33*344aa361SAndroid Build Coastguard Worker #define NUM_TEST_MESSAGES 50
34*344aa361SAndroid Build Coastguard Worker
35*344aa361SAndroid Build Coastguard Worker static char test_pattern[] = "abcdefghijklmnopqrstuvwxyz!";
36*344aa361SAndroid Build Coastguard Worker
send_cmd(struct handle * chan,enum ktipc_test_cmd cmd,char * buf,size_t len)37*344aa361SAndroid Build Coastguard Worker static void send_cmd(struct handle* chan,
38*344aa361SAndroid Build Coastguard Worker enum ktipc_test_cmd cmd,
39*344aa361SAndroid Build Coastguard Worker char* buf,
40*344aa361SAndroid Build Coastguard Worker size_t len) {
41*344aa361SAndroid Build Coastguard Worker struct ktipc_test_req req = {
42*344aa361SAndroid Build Coastguard Worker .cmd = cmd,
43*344aa361SAndroid Build Coastguard Worker };
44*344aa361SAndroid Build Coastguard Worker int rc = ktipc_send(chan, &req, sizeof(req), buf, len);
45*344aa361SAndroid Build Coastguard Worker ASSERT_GE(rc, 0);
46*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(sizeof(req) + len, (size_t)rc);
47*344aa361SAndroid Build Coastguard Worker
48*344aa361SAndroid Build Coastguard Worker test_abort:;
49*344aa361SAndroid Build Coastguard Worker }
50*344aa361SAndroid Build Coastguard Worker
wait_for_hup(struct handle * chan)51*344aa361SAndroid Build Coastguard Worker static void wait_for_hup(struct handle* chan) {
52*344aa361SAndroid Build Coastguard Worker int rc;
53*344aa361SAndroid Build Coastguard Worker uint32_t event;
54*344aa361SAndroid Build Coastguard Worker
55*344aa361SAndroid Build Coastguard Worker rc = handle_wait(chan, &event, TIMEOUT_MSEC);
56*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(NO_ERROR, rc);
57*344aa361SAndroid Build Coastguard Worker ASSERT_NE(0, (event & IPC_HANDLE_POLL_READY));
58*344aa361SAndroid Build Coastguard Worker
59*344aa361SAndroid Build Coastguard Worker if (!(event & IPC_HANDLE_POLL_HUP)) {
60*344aa361SAndroid Build Coastguard Worker /*
61*344aa361SAndroid Build Coastguard Worker * Service hasn't closed the channel yet, wait again.
62*344aa361SAndroid Build Coastguard Worker * We should only get READY once, so one extra wait should do it.
63*344aa361SAndroid Build Coastguard Worker */
64*344aa361SAndroid Build Coastguard Worker rc = handle_wait(chan, &event, TIMEOUT_MSEC);
65*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(NO_ERROR, rc);
66*344aa361SAndroid Build Coastguard Worker }
67*344aa361SAndroid Build Coastguard Worker
68*344aa361SAndroid Build Coastguard Worker ASSERT_NE(0, (event & IPC_HANDLE_POLL_HUP));
69*344aa361SAndroid Build Coastguard Worker
70*344aa361SAndroid Build Coastguard Worker test_abort:;
71*344aa361SAndroid Build Coastguard Worker }
72*344aa361SAndroid Build Coastguard Worker
73*344aa361SAndroid Build Coastguard Worker /*
74*344aa361SAndroid Build Coastguard Worker * Test that the service closes the channel on its end in case on_connect()
75*344aa361SAndroid Build Coastguard Worker * returns an error. The client should see this as a HUP.
76*344aa361SAndroid Build Coastguard Worker */
TEST(ktipctest,connecterr)77*344aa361SAndroid Build Coastguard Worker TEST(ktipctest, connecterr) {
78*344aa361SAndroid Build Coastguard Worker int rc;
79*344aa361SAndroid Build Coastguard Worker struct handle* chan = NULL;
80*344aa361SAndroid Build Coastguard Worker
81*344aa361SAndroid Build Coastguard Worker rc = ipc_port_connect_async(&kernel_uuid, KTIPC_TEST_SRV_PORT ".connecterr",
82*344aa361SAndroid Build Coastguard Worker IPC_PORT_PATH_MAX, IPC_CONNECT_WAIT_FOR_PORT,
83*344aa361SAndroid Build Coastguard Worker &chan);
84*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(NO_ERROR, rc);
85*344aa361SAndroid Build Coastguard Worker
86*344aa361SAndroid Build Coastguard Worker wait_for_hup(chan);
87*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(false, HasFailure());
88*344aa361SAndroid Build Coastguard Worker
89*344aa361SAndroid Build Coastguard Worker test_abort:
90*344aa361SAndroid Build Coastguard Worker if (chan) {
91*344aa361SAndroid Build Coastguard Worker handle_decref(chan);
92*344aa361SAndroid Build Coastguard Worker }
93*344aa361SAndroid Build Coastguard Worker }
94*344aa361SAndroid Build Coastguard Worker
95*344aa361SAndroid Build Coastguard Worker /* Test connections to ports blocked by UUID */
TEST(ktipctest,blockedport)96*344aa361SAndroid Build Coastguard Worker TEST(ktipctest, blockedport) {
97*344aa361SAndroid Build Coastguard Worker int rc;
98*344aa361SAndroid Build Coastguard Worker struct handle* chan = NULL;
99*344aa361SAndroid Build Coastguard Worker
100*344aa361SAndroid Build Coastguard Worker /*
101*344aa361SAndroid Build Coastguard Worker * ipc_port_connect_async() returns NO_ERROR for rejected connections,
102*344aa361SAndroid Build Coastguard Worker * even with IPC_CONNECT_WAIT_FOR_PORT. We check for a HUP below instead.
103*344aa361SAndroid Build Coastguard Worker */
104*344aa361SAndroid Build Coastguard Worker rc = ipc_port_connect_async(&kernel_uuid, KTIPC_TEST_SRV_PORT ".blocked",
105*344aa361SAndroid Build Coastguard Worker IPC_PORT_PATH_MAX, IPC_CONNECT_WAIT_FOR_PORT,
106*344aa361SAndroid Build Coastguard Worker &chan);
107*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(NO_ERROR, rc);
108*344aa361SAndroid Build Coastguard Worker
109*344aa361SAndroid Build Coastguard Worker wait_for_hup(chan);
110*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(false, HasFailure());
111*344aa361SAndroid Build Coastguard Worker
112*344aa361SAndroid Build Coastguard Worker test_abort:
113*344aa361SAndroid Build Coastguard Worker if (chan) {
114*344aa361SAndroid Build Coastguard Worker handle_decref(chan);
115*344aa361SAndroid Build Coastguard Worker }
116*344aa361SAndroid Build Coastguard Worker }
117*344aa361SAndroid Build Coastguard Worker
TEST(ktipctest,echo)118*344aa361SAndroid Build Coastguard Worker TEST(ktipctest, echo) {
119*344aa361SAndroid Build Coastguard Worker int rc;
120*344aa361SAndroid Build Coastguard Worker struct handle* chan[NUM_TEST_CONNECTIONS] = {
121*344aa361SAndroid Build Coastguard Worker [0 ...(NUM_TEST_CONNECTIONS - 1)] = NULL,
122*344aa361SAndroid Build Coastguard Worker };
123*344aa361SAndroid Build Coastguard Worker uint32_t event;
124*344aa361SAndroid Build Coastguard Worker
125*344aa361SAndroid Build Coastguard Worker for (size_t i = 0; i < NUM_TEST_CONNECTIONS; i++) {
126*344aa361SAndroid Build Coastguard Worker rc = ipc_port_connect_async(&kernel_uuid, KTIPC_TEST_SRV_PORT,
127*344aa361SAndroid Build Coastguard Worker IPC_PORT_PATH_MAX,
128*344aa361SAndroid Build Coastguard Worker IPC_CONNECT_WAIT_FOR_PORT, &chan[i]);
129*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(NO_ERROR, rc);
130*344aa361SAndroid Build Coastguard Worker
131*344aa361SAndroid Build Coastguard Worker rc = handle_wait(chan[i], &event, TIMEOUT_MSEC);
132*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(NO_ERROR, rc);
133*344aa361SAndroid Build Coastguard Worker ASSERT_NE(0, (event & IPC_HANDLE_POLL_READY));
134*344aa361SAndroid Build Coastguard Worker }
135*344aa361SAndroid Build Coastguard Worker
136*344aa361SAndroid Build Coastguard Worker const size_t len = countof(test_pattern);
137*344aa361SAndroid Build Coastguard Worker for (size_t i = 0; i < NUM_TEST_CONNECTIONS; i++) {
138*344aa361SAndroid Build Coastguard Worker for (size_t j = 0; j < NUM_TEST_MESSAGES; j++) {
139*344aa361SAndroid Build Coastguard Worker test_pattern[i % len] = (i + j) & 0xff;
140*344aa361SAndroid Build Coastguard Worker
141*344aa361SAndroid Build Coastguard Worker send_cmd(chan[i], KTIPC_TEST_CMD_ECHO, test_pattern, len);
142*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(false, HasFailure());
143*344aa361SAndroid Build Coastguard Worker
144*344aa361SAndroid Build Coastguard Worker rc = handle_wait(chan[i], &event, TIMEOUT_MSEC);
145*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(NO_ERROR, rc);
146*344aa361SAndroid Build Coastguard Worker ASSERT_NE(0, (event & IPC_HANDLE_POLL_MSG));
147*344aa361SAndroid Build Coastguard Worker
148*344aa361SAndroid Build Coastguard Worker char buf[countof(test_pattern)];
149*344aa361SAndroid Build Coastguard Worker rc = ktipc_recv(chan[i], len, buf, len);
150*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(len, rc);
151*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(buf, test_pattern, len));
152*344aa361SAndroid Build Coastguard Worker }
153*344aa361SAndroid Build Coastguard Worker }
154*344aa361SAndroid Build Coastguard Worker
155*344aa361SAndroid Build Coastguard Worker test_abort:
156*344aa361SAndroid Build Coastguard Worker for (size_t i = 0; i < NUM_TEST_CONNECTIONS; i++) {
157*344aa361SAndroid Build Coastguard Worker if (chan[i]) {
158*344aa361SAndroid Build Coastguard Worker handle_decref(chan[i]);
159*344aa361SAndroid Build Coastguard Worker }
160*344aa361SAndroid Build Coastguard Worker }
161*344aa361SAndroid Build Coastguard Worker }
162*344aa361SAndroid Build Coastguard Worker
163*344aa361SAndroid Build Coastguard Worker /* Test that sends and receives 8 buffers at once */
TEST(ktipctest,echo8)164*344aa361SAndroid Build Coastguard Worker TEST(ktipctest, echo8) {
165*344aa361SAndroid Build Coastguard Worker int rc;
166*344aa361SAndroid Build Coastguard Worker struct handle* chan = NULL;
167*344aa361SAndroid Build Coastguard Worker uint32_t event;
168*344aa361SAndroid Build Coastguard Worker
169*344aa361SAndroid Build Coastguard Worker rc = ipc_port_connect_async(&kernel_uuid, KTIPC_TEST_SRV_PORT,
170*344aa361SAndroid Build Coastguard Worker IPC_PORT_PATH_MAX, IPC_CONNECT_WAIT_FOR_PORT,
171*344aa361SAndroid Build Coastguard Worker &chan);
172*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(NO_ERROR, rc);
173*344aa361SAndroid Build Coastguard Worker
174*344aa361SAndroid Build Coastguard Worker rc = handle_wait(chan, &event, TIMEOUT_MSEC);
175*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(NO_ERROR, rc);
176*344aa361SAndroid Build Coastguard Worker ASSERT_NE(0, (event & IPC_HANDLE_POLL_READY));
177*344aa361SAndroid Build Coastguard Worker
178*344aa361SAndroid Build Coastguard Worker /*
179*344aa361SAndroid Build Coastguard Worker * Send different parts of the test pattern from various offsets as 8
180*344aa361SAndroid Build Coastguard Worker * different buffers so we pass the maximum number of arguments to
181*344aa361SAndroid Build Coastguard Worker * ktipc_send().
182*344aa361SAndroid Build Coastguard Worker */
183*344aa361SAndroid Build Coastguard Worker const size_t len = 4 * 7;
184*344aa361SAndroid Build Coastguard Worker struct ktipc_test_req req = {
185*344aa361SAndroid Build Coastguard Worker .cmd = KTIPC_TEST_CMD_ECHO,
186*344aa361SAndroid Build Coastguard Worker };
187*344aa361SAndroid Build Coastguard Worker rc = ktipc_send(chan, &req, sizeof(req), test_pattern, 4, test_pattern + 4,
188*344aa361SAndroid Build Coastguard Worker 4, test_pattern, 2, test_pattern + 2, 4, test_pattern + 6,
189*344aa361SAndroid Build Coastguard Worker 6, test_pattern, 6, test_pattern + 8, 2);
190*344aa361SAndroid Build Coastguard Worker ASSERT_GE(rc, 0);
191*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(sizeof(req) + len, (size_t)rc);
192*344aa361SAndroid Build Coastguard Worker
193*344aa361SAndroid Build Coastguard Worker rc = handle_wait(chan, &event, TIMEOUT_MSEC);
194*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(NO_ERROR, rc);
195*344aa361SAndroid Build Coastguard Worker ASSERT_NE(0, (event & IPC_HANDLE_POLL_MSG));
196*344aa361SAndroid Build Coastguard Worker
197*344aa361SAndroid Build Coastguard Worker /*
198*344aa361SAndroid Build Coastguard Worker * Read the message back into different buffers that add to the same total
199*344aa361SAndroid Build Coastguard Worker * length. We split the last 4-byte buffer into two smaller ones so that
200*344aa361SAndroid Build Coastguard Worker * we still get 8 buffers in total, so we test ktipc_recv() with the maximum
201*344aa361SAndroid Build Coastguard Worker * amount of allowed arguments.
202*344aa361SAndroid Build Coastguard Worker */
203*344aa361SAndroid Build Coastguard Worker char buf4[6][4];
204*344aa361SAndroid Build Coastguard Worker char buf2[2][2];
205*344aa361SAndroid Build Coastguard Worker rc = ktipc_recv(chan, len, buf4[0], 4, buf4[1], 4, buf4[2], 4, buf4[3], 4,
206*344aa361SAndroid Build Coastguard Worker buf4[4], 4, buf4[5], 4, buf2[0], 2, buf2[1], 2);
207*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(len, rc);
208*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(buf4[0], test_pattern + 0, 4));
209*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(buf4[1], test_pattern + 4, 4));
210*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(buf4[2], test_pattern + 0, 4));
211*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(buf4[3], test_pattern + 4, 4));
212*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(buf4[4], test_pattern + 8, 4));
213*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(buf4[5], test_pattern + 0, 4));
214*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(buf2[0], test_pattern + 4, 2));
215*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(buf2[1], test_pattern + 8, 2));
216*344aa361SAndroid Build Coastguard Worker
217*344aa361SAndroid Build Coastguard Worker test_abort:
218*344aa361SAndroid Build Coastguard Worker if (chan) {
219*344aa361SAndroid Build Coastguard Worker handle_decref(chan);
220*344aa361SAndroid Build Coastguard Worker }
221*344aa361SAndroid Build Coastguard Worker }
222*344aa361SAndroid Build Coastguard Worker
TEST(ktipctest,close)223*344aa361SAndroid Build Coastguard Worker TEST(ktipctest, close) {
224*344aa361SAndroid Build Coastguard Worker int rc;
225*344aa361SAndroid Build Coastguard Worker struct handle* chan = NULL;
226*344aa361SAndroid Build Coastguard Worker uint32_t start_close_counter, end_close_counter;
227*344aa361SAndroid Build Coastguard Worker uint32_t event;
228*344aa361SAndroid Build Coastguard Worker
229*344aa361SAndroid Build Coastguard Worker rc = ipc_port_connect_async(&kernel_uuid, KTIPC_TEST_SRV_PORT,
230*344aa361SAndroid Build Coastguard Worker IPC_PORT_PATH_MAX, IPC_CONNECT_WAIT_FOR_PORT,
231*344aa361SAndroid Build Coastguard Worker &chan);
232*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(NO_ERROR, rc);
233*344aa361SAndroid Build Coastguard Worker
234*344aa361SAndroid Build Coastguard Worker rc = handle_wait(chan, &event, TIMEOUT_MSEC);
235*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(NO_ERROR, rc);
236*344aa361SAndroid Build Coastguard Worker ASSERT_NE(0, (event & IPC_HANDLE_POLL_READY));
237*344aa361SAndroid Build Coastguard Worker
238*344aa361SAndroid Build Coastguard Worker send_cmd(chan, KTIPC_TEST_CMD_READ_CLOSE_COUNTER, NULL, 0);
239*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(false, HasFailure());
240*344aa361SAndroid Build Coastguard Worker
241*344aa361SAndroid Build Coastguard Worker rc = handle_wait(chan, &event, TIMEOUT_MSEC);
242*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(NO_ERROR, rc);
243*344aa361SAndroid Build Coastguard Worker ASSERT_NE(0, (event & IPC_HANDLE_POLL_MSG));
244*344aa361SAndroid Build Coastguard Worker
245*344aa361SAndroid Build Coastguard Worker rc = ktipc_recv(chan, sizeof(start_close_counter), &start_close_counter,
246*344aa361SAndroid Build Coastguard Worker sizeof(start_close_counter));
247*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(sizeof(start_close_counter), rc);
248*344aa361SAndroid Build Coastguard Worker
249*344aa361SAndroid Build Coastguard Worker /* Close the first channel */
250*344aa361SAndroid Build Coastguard Worker handle_decref(chan);
251*344aa361SAndroid Build Coastguard Worker chan = NULL;
252*344aa361SAndroid Build Coastguard Worker
253*344aa361SAndroid Build Coastguard Worker /* Now open a new channel and ask the server to close it */
254*344aa361SAndroid Build Coastguard Worker rc = ipc_port_connect_async(&kernel_uuid, KTIPC_TEST_SRV_PORT,
255*344aa361SAndroid Build Coastguard Worker IPC_PORT_PATH_MAX, IPC_CONNECT_WAIT_FOR_PORT,
256*344aa361SAndroid Build Coastguard Worker &chan);
257*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(NO_ERROR, rc);
258*344aa361SAndroid Build Coastguard Worker
259*344aa361SAndroid Build Coastguard Worker rc = handle_wait(chan, &event, TIMEOUT_MSEC);
260*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(NO_ERROR, rc);
261*344aa361SAndroid Build Coastguard Worker ASSERT_NE(0, (event & IPC_HANDLE_POLL_READY));
262*344aa361SAndroid Build Coastguard Worker
263*344aa361SAndroid Build Coastguard Worker send_cmd(chan, KTIPC_TEST_CMD_CLOSE, NULL, 0);
264*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(false, HasFailure());
265*344aa361SAndroid Build Coastguard Worker
266*344aa361SAndroid Build Coastguard Worker rc = handle_wait(chan, &event, TIMEOUT_MSEC);
267*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(NO_ERROR, rc);
268*344aa361SAndroid Build Coastguard Worker ASSERT_NE(0, (event & IPC_HANDLE_POLL_HUP));
269*344aa361SAndroid Build Coastguard Worker
270*344aa361SAndroid Build Coastguard Worker handle_decref(chan);
271*344aa361SAndroid Build Coastguard Worker chan = NULL;
272*344aa361SAndroid Build Coastguard Worker
273*344aa361SAndroid Build Coastguard Worker /* Read the close counter again; it should be 2 higher than the previous */
274*344aa361SAndroid Build Coastguard Worker rc = ipc_port_connect_async(&kernel_uuid, KTIPC_TEST_SRV_PORT,
275*344aa361SAndroid Build Coastguard Worker IPC_PORT_PATH_MAX, IPC_CONNECT_WAIT_FOR_PORT,
276*344aa361SAndroid Build Coastguard Worker &chan);
277*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(NO_ERROR, rc);
278*344aa361SAndroid Build Coastguard Worker
279*344aa361SAndroid Build Coastguard Worker rc = handle_wait(chan, &event, TIMEOUT_MSEC);
280*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(NO_ERROR, rc);
281*344aa361SAndroid Build Coastguard Worker ASSERT_NE(0, (event & IPC_HANDLE_POLL_READY));
282*344aa361SAndroid Build Coastguard Worker
283*344aa361SAndroid Build Coastguard Worker send_cmd(chan, KTIPC_TEST_CMD_READ_CLOSE_COUNTER, NULL, 0);
284*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(false, HasFailure());
285*344aa361SAndroid Build Coastguard Worker
286*344aa361SAndroid Build Coastguard Worker rc = handle_wait(chan, &event, TIMEOUT_MSEC);
287*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(NO_ERROR, rc);
288*344aa361SAndroid Build Coastguard Worker ASSERT_NE(0, (event & IPC_HANDLE_POLL_MSG));
289*344aa361SAndroid Build Coastguard Worker
290*344aa361SAndroid Build Coastguard Worker rc = ktipc_recv(chan, sizeof(end_close_counter), &end_close_counter,
291*344aa361SAndroid Build Coastguard Worker sizeof(end_close_counter));
292*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(sizeof(end_close_counter), rc);
293*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(start_close_counter + 2, end_close_counter);
294*344aa361SAndroid Build Coastguard Worker
295*344aa361SAndroid Build Coastguard Worker test_abort:
296*344aa361SAndroid Build Coastguard Worker if (chan) {
297*344aa361SAndroid Build Coastguard Worker handle_decref(chan);
298*344aa361SAndroid Build Coastguard Worker }
299*344aa361SAndroid Build Coastguard Worker }
300*344aa361SAndroid Build Coastguard Worker
TEST(ktipctest,blockedsend)301*344aa361SAndroid Build Coastguard Worker TEST(ktipctest, blockedsend) {
302*344aa361SAndroid Build Coastguard Worker int rc;
303*344aa361SAndroid Build Coastguard Worker struct handle* chan = NULL;
304*344aa361SAndroid Build Coastguard Worker uint32_t event;
305*344aa361SAndroid Build Coastguard Worker
306*344aa361SAndroid Build Coastguard Worker rc = ipc_port_connect_async(&kernel_uuid, KTIPC_TEST_SRV_PORT,
307*344aa361SAndroid Build Coastguard Worker IPC_PORT_PATH_MAX, IPC_CONNECT_WAIT_FOR_PORT,
308*344aa361SAndroid Build Coastguard Worker &chan);
309*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(NO_ERROR, rc);
310*344aa361SAndroid Build Coastguard Worker
311*344aa361SAndroid Build Coastguard Worker rc = handle_wait(chan, &event, TIMEOUT_MSEC);
312*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(NO_ERROR, rc);
313*344aa361SAndroid Build Coastguard Worker ASSERT_NE(0, (event & IPC_HANDLE_POLL_READY));
314*344aa361SAndroid Build Coastguard Worker
315*344aa361SAndroid Build Coastguard Worker /* Send the message twice, second one should get queued */
316*344aa361SAndroid Build Coastguard Worker const size_t len = countof(test_pattern);
317*344aa361SAndroid Build Coastguard Worker send_cmd(chan, KTIPC_TEST_CMD_ECHO, test_pattern, len);
318*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(false, HasFailure());
319*344aa361SAndroid Build Coastguard Worker
320*344aa361SAndroid Build Coastguard Worker rc = handle_wait(chan, &event, TIMEOUT_MSEC);
321*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(NO_ERROR, rc);
322*344aa361SAndroid Build Coastguard Worker ASSERT_NE(0, (event & IPC_HANDLE_POLL_MSG));
323*344aa361SAndroid Build Coastguard Worker
324*344aa361SAndroid Build Coastguard Worker /*
325*344aa361SAndroid Build Coastguard Worker * Send the second message before reading the first reply,
326*344aa361SAndroid Build Coastguard Worker * should force the service to queue
327*344aa361SAndroid Build Coastguard Worker */
328*344aa361SAndroid Build Coastguard Worker send_cmd(chan, KTIPC_TEST_CMD_ECHO, test_pattern, len);
329*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(false, HasFailure());
330*344aa361SAndroid Build Coastguard Worker
331*344aa361SAndroid Build Coastguard Worker /* Sleep to give the service a chance to run */
332*344aa361SAndroid Build Coastguard Worker thread_sleep(10);
333*344aa361SAndroid Build Coastguard Worker
334*344aa361SAndroid Build Coastguard Worker char buf[countof(test_pattern)];
335*344aa361SAndroid Build Coastguard Worker rc = ktipc_recv(chan, len, buf, len);
336*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(len, rc);
337*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(buf, test_pattern, len));
338*344aa361SAndroid Build Coastguard Worker
339*344aa361SAndroid Build Coastguard Worker rc = handle_wait(chan, &event, TIMEOUT_MSEC);
340*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(NO_ERROR, rc);
341*344aa361SAndroid Build Coastguard Worker ASSERT_NE(0, (event & IPC_HANDLE_POLL_MSG));
342*344aa361SAndroid Build Coastguard Worker
343*344aa361SAndroid Build Coastguard Worker rc = ktipc_recv(chan, len, buf, len);
344*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(len, rc);
345*344aa361SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(buf, test_pattern, len));
346*344aa361SAndroid Build Coastguard Worker
347*344aa361SAndroid Build Coastguard Worker test_abort:
348*344aa361SAndroid Build Coastguard Worker if (chan) {
349*344aa361SAndroid Build Coastguard Worker handle_decref(chan);
350*344aa361SAndroid Build Coastguard Worker }
351*344aa361SAndroid Build Coastguard Worker }
352*344aa361SAndroid Build Coastguard Worker
353*344aa361SAndroid Build Coastguard Worker PORT_TEST(ktipctest, "com.android.kernel.ktipc.test");
354