1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <app_mgmt_port_consts.h>
18 #include <app_mgmt_test.h>
19 #include <inttypes.h>
20 #include <lib/tipc/tipc.h>
21 #include <stddef.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <trusty_ipc.h>
26 #include <uapi/err.h>
27 
28 #define TLOG_TAG "port-waiter-srv"
29 
main(void)30 int main(void) {
31     int rc;
32     handle_t shandle = INVALID_IPC_HANDLE;
33     handle_t phandle = INVALID_IPC_HANDLE;
34     handle_t chandle = INVALID_IPC_HANDLE;
35     struct uevent uevt;
36     uuid_t peer_uuid;
37 
38     rc = connect(START_PORT, IPC_CONNECT_WAIT_FOR_PORT);
39     if (rc < 0) {
40         TLOGI("Failed (%d) to connect to start port\n", rc);
41         goto err_connect;
42     }
43     shandle = (handle_t)rc;
44 
45     rc = port_create(PORT_WAITER_PORT, 1, 1, IPC_PORT_ALLOW_TA_CONNECT);
46     if (rc < 0) {
47         TLOGI("Failed (%d) to create port-waiter port\n", rc);
48         goto err_port_create;
49     }
50     phandle = (handle_t)rc;
51 
52     rc = wait(phandle, &uevt, INFINITE_TIME);
53     if (rc != NO_ERROR || !(uevt.event & IPC_HANDLE_POLL_READY)) {
54         TLOGI("Port wait failed(%d) event:%d handle:%d\n", rc, uevt.event,
55               phandle);
56         goto err_wait_accept;
57     }
58 
59     rc = accept(uevt.handle, &peer_uuid);
60     if (rc == ERR_CHANNEL_CLOSED) {
61         /* client already closed connection, nothing to do */
62         goto err_channel_closed;
63     }
64     if (rc < 0) {
65         TLOGI("Accept failed %d\n", rc);
66         goto err_accept;
67     }
68 
69     chandle = (handle_t)rc;
70 
71     uint8_t cmd = CMD_EXIT;
72     rc = tipc_send1(shandle, &cmd, sizeof(cmd));
73     if (rc != (int)sizeof(cmd)) {
74         TLOGI("Failed (%d) to send exit command\n", rc);
75         goto err_send_cmd;
76     }
77 
78     rc = wait(shandle, &uevt, INFINITE_TIME);
79     if (rc != NO_ERROR || !(uevt.event & IPC_HANDLE_POLL_MSG)) {
80         TLOGI("Port wait failed(%d) event:%d handle:%d\n", rc, uevt.event,
81               shandle);
82         goto err_wait_resp;
83     }
84 
85     uint8_t rsp;
86     rc = tipc_recv1(shandle, sizeof(rsp), &rsp, sizeof(rsp));
87     if (rc != (int)sizeof(rsp)) {
88         TLOGI("Failed (%d) to receive exit response\n", rc);
89         goto err_recv_resp;
90     }
91 
92     TLOGI("Received exit response: %" PRIu8 "\n", rsp);
93 
94     rc = tipc_send1(chandle, &rsp, sizeof(rsp));
95     if (rc != (int)sizeof(rsp)) {
96         TLOGI("Failed (%d) to send exit response\n", rc);
97         goto err_send_resp;
98     }
99 
100     close(chandle);
101     close(phandle);
102     close(shandle);
103 
104     return 0;
105 
106 err_send_resp:
107 err_recv_resp:
108 err_wait_resp:
109 err_send_cmd:
110     close(chandle);
111 err_accept:
112 err_channel_closed:
113 err_wait_accept:
114     close(phandle);
115 err_port_create:
116     close(shandle);
117 err_connect:
118     return rc;
119 }
120