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 #define TLOG_TAG "coverage-common-ipc"
18
19 #include <lib/coverage/common/ipc.h>
20 #include <lib/tipc/tipc.h>
21 #include <trusty_log.h>
22 #include <uapi/err.h>
23
coverage_send(handle_t chan,void * msg,size_t msg_len,handle_t * h)24 int coverage_send(handle_t chan, void* msg, size_t msg_len, handle_t* h) {
25 int rc;
26 struct iovec iov = {
27 .iov_base = msg,
28 .iov_len = msg_len,
29 };
30 struct ipc_msg ipc_msg = {
31 .iov = &iov,
32 .num_iov = 1,
33 .handles = h,
34 .num_handles = h ? 1 : 0,
35 };
36
37 rc = send_msg(chan, &ipc_msg);
38 if (rc != (int)msg_len) {
39 TLOGE("failed (%d) to send_msg()\n", rc);
40 if (rc >= 0) {
41 rc = ERR_BAD_LEN;
42 }
43 return rc;
44 }
45
46 return NO_ERROR;
47 }
48
coverage_recv(handle_t chan,void * msg,size_t msg_len,handle_t * h)49 int coverage_recv(handle_t chan, void* msg, size_t msg_len, handle_t* h) {
50 int rc;
51 struct ipc_msg_info msg_inf;
52
53 rc = get_msg(chan, &msg_inf);
54 if (rc != NO_ERROR) {
55 TLOGE("failed (%d) to get_msg()\n", rc);
56 return rc;
57 }
58
59 struct iovec iov = {
60 .iov_base = msg,
61 .iov_len = msg_len,
62 };
63 struct ipc_msg ipc_msg = {
64 .iov = &iov,
65 .num_iov = 1,
66 .handles = h,
67 .num_handles = h ? 1 : 0,
68 };
69
70 rc = read_msg(chan, msg_inf.id, 0, &ipc_msg);
71 if (rc != (int)msg_len) {
72 TLOGE("failed (%d) to read_msg()\n", rc);
73 if (rc >= 0) {
74 rc = ERR_BAD_LEN;
75 }
76 goto out;
77 }
78
79 rc = NO_ERROR;
80 out:
81 put_msg(chan, msg_inf.id);
82 return rc;
83 }
84
coverage_rpc(handle_t chan,void * req,size_t req_len,handle_t * req_h,void * resp,size_t resp_len,handle_t * resp_h)85 int coverage_rpc(handle_t chan,
86 void* req,
87 size_t req_len,
88 handle_t* req_h,
89 void* resp,
90 size_t resp_len,
91 handle_t* resp_h) {
92 int rc;
93 uevent_t evt;
94
95 rc = coverage_send(chan, req, req_len, req_h);
96 if (rc != NO_ERROR) {
97 TLOGE("failed (%d) to send request\n", rc);
98 return rc;
99 }
100
101 rc = wait(chan, &evt, INFINITE_TIME);
102 if (rc != NO_ERROR) {
103 TLOGE("failed (%d) to wait for reply\n", rc);
104 return rc;
105 }
106
107 rc = coverage_recv(chan, resp, resp_len, resp_h);
108 if (rc != NO_ERROR) {
109 TLOGE("failed (%d) to receive response\n", rc);
110 return rc;
111 }
112
113 return NO_ERROR;
114 }
115
coverage_aggregator_rpc(handle_t chan,struct coverage_aggregator_req * req,handle_t * req_h,struct coverage_aggregator_resp * resp,handle_t * resp_h)116 int coverage_aggregator_rpc(handle_t chan,
117 struct coverage_aggregator_req* req,
118 handle_t* req_h,
119 struct coverage_aggregator_resp* resp,
120 handle_t* resp_h) {
121 int rc = coverage_rpc(chan, req, sizeof(*req), req_h, resp, sizeof(*resp),
122 resp_h);
123 if (rc != NO_ERROR) {
124 return rc;
125 }
126
127 if (resp->hdr.cmd != (req->hdr.cmd | COVERAGE_AGGREGATOR_CMD_RESP_BIT)) {
128 TLOGE("cmd 0x%x: unknown command\n", resp->hdr.cmd);
129 return ERR_CMD_UNKNOWN;
130 }
131
132 return NO_ERROR;
133 }
134
coverage_client_rpc(handle_t chan,struct coverage_client_req * req,handle_t * req_h,struct coverage_client_resp * resp,handle_t * resp_h)135 int coverage_client_rpc(handle_t chan,
136 struct coverage_client_req* req,
137 handle_t* req_h,
138 struct coverage_client_resp* resp,
139 handle_t* resp_h) {
140 int rc = coverage_rpc(chan, req, sizeof(*req), req_h, resp, sizeof(*resp),
141 resp_h);
142 if (rc != NO_ERROR) {
143 return rc;
144 }
145
146 if (resp->hdr.cmd != (req->hdr.cmd | COVERAGE_CLIENT_CMD_RESP_BIT)) {
147 TLOGE("cmd 0x%x: unknown command\n", resp->hdr.cmd);
148 return ERR_CMD_UNKNOWN;
149 }
150
151 return NO_ERROR;
152 }
153