• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 <lib/tidl/android-base/unique_fd.h>
18 #include <trusty_ipc.h>
19 #include <uapi/err.h>
20 
21 namespace tidl {
22 namespace ipc {
23 
connect(const char * path,uint32_t flags,android::base::unique_fd & out_fd)24 int connect(const char* path,
25             uint32_t flags,
26             android::base::unique_fd& out_fd) {
27     int rc = ::connect(path, flags);
28     if (rc < 0) {
29         return rc;
30     }
31 
32     out_fd.reset(static_cast<handle_t>(rc));
33     return NO_ERROR;
34 }
35 
send(handle_t chan,const void * buf,size_t len,handle_t * handles,uint32_t num_handles)36 int send(handle_t chan,
37          const void* buf,
38          size_t len,
39          handle_t* handles,
40          uint32_t num_handles) {
41     struct iovec iov = {
42             .iov_base = (void*)buf,
43             .iov_len = len,
44     };
45     ipc_msg_t msg = {
46             .num_iov = 1,
47             .iov = &iov,
48             .num_handles = num_handles,
49             .handles = handles,
50     };
51     return send_msg(chan, &msg);
52 }
53 
recv(handle_t chan,size_t min_sz,void * buf,size_t buf_sz,handle_t * handles,uint32_t num_handles)54 int recv(handle_t chan,
55          size_t min_sz,
56          void* buf,
57          size_t buf_sz,
58          handle_t* handles,
59          uint32_t num_handles) {
60     int rc;
61     ipc_msg_info_t msg_inf;
62 
63     rc = get_msg(chan, &msg_inf);
64     if (rc)
65         return rc;
66 
67     if (msg_inf.len < min_sz || msg_inf.len > buf_sz) {
68         /* unexpected msg size: buffer too small or too big */
69         rc = ERR_BAD_LEN;
70     } else {
71         struct iovec iov = {
72                 .iov_base = buf,
73                 .iov_len = buf_sz,
74         };
75         ipc_msg_t msg = {
76                 .num_iov = 1,
77                 .iov = &iov,
78                 .num_handles = num_handles,
79                 .handles = handles,
80         };
81         rc = read_msg(chan, msg_inf.id, 0, &msg);
82     }
83 
84     put_msg(chan, msg_inf.id);
85     return rc;
86 }
87 
send(handle_t chan,const void * hdr,size_t hdr_len,const void * payload1,size_t payload1_len,handle_t * handles,uint32_t num_handles)88 int send(handle_t chan,
89          const void* hdr,
90          size_t hdr_len,
91          const void* payload1,
92          size_t payload1_len,
93          handle_t* handles,
94          uint32_t num_handles) {
95     struct iovec iovs[] = {
96             {
97                     .iov_base = (void*)hdr,
98                     .iov_len = hdr_len,
99             },
100             {
101                     .iov_base = (void*)payload1,
102                     .iov_len = payload1_len,
103             },
104     };
105     ipc_msg_t msg = {
106             .num_iov = static_cast<uint32_t>(countof(iovs)),
107             .iov = iovs,
108             .num_handles = num_handles,
109             .handles = handles,
110     };
111     return send_msg(chan, &msg);
112 }
113 
recv(handle_t chan,size_t min_sz,void * buf1,size_t buf1_sz,void * buf2,size_t buf2_sz,handle_t * handles,uint32_t num_handles)114 int recv(handle_t chan,
115          size_t min_sz,
116          void* buf1,
117          size_t buf1_sz,
118          void* buf2,
119          size_t buf2_sz,
120          handle_t* handles,
121          uint32_t num_handles) {
122     int rc;
123     ipc_msg_info_t msg_inf;
124 
125     rc = get_msg(chan, &msg_inf);
126     if (rc)
127         return rc;
128 
129     if (msg_inf.len < min_sz || (msg_inf.len > (buf1_sz + buf2_sz))) {
130         /* unexpected msg size: buffer too small or too big */
131         rc = ERR_BAD_LEN;
132     } else {
133         struct iovec iovs[] = {
134                 {
135                         .iov_base = buf1,
136                         .iov_len = buf1_sz,
137                 },
138                 {
139                         .iov_base = buf2,
140                         .iov_len = buf2_sz,
141                 },
142         };
143         ipc_msg_t msg = {
144                 .num_iov = static_cast<uint32_t>(countof(iovs)),
145                 .iov = iovs,
146                 .num_handles = num_handles,
147                 .handles = handles,
148         };
149         rc = read_msg(chan, msg_inf.id, 0, &msg);
150     }
151 
152     put_msg(chan, msg_inf.id);
153     return rc;
154 }
155 
send(handle_t chan,const void * hdr,size_t hdr_len,const void * payload1,size_t payload1_len,const void * payload2,size_t payload2_len,handle_t * handles,uint32_t num_handles)156 int send(handle_t chan,
157          const void* hdr,
158          size_t hdr_len,
159          const void* payload1,
160          size_t payload1_len,
161          const void* payload2,
162          size_t payload2_len,
163          handle_t* handles,
164          uint32_t num_handles) {
165     struct iovec iovs[] = {
166             {
167                     .iov_base = (void*)hdr,
168                     .iov_len = hdr_len,
169             },
170             {
171                     .iov_base = (void*)payload1,
172                     .iov_len = payload1_len,
173             },
174             {
175                     .iov_base = (void*)payload2,
176                     .iov_len = payload2_len,
177             },
178     };
179     ipc_msg_t msg = {
180             .num_iov = static_cast<uint32_t>(countof(iovs)),
181             .iov = iovs,
182             .num_handles = num_handles,
183             .handles = handles,
184     };
185     return send_msg(chan, &msg);
186 }
187 
recv(handle_t chan,size_t min_sz,void * buf1,size_t buf1_sz,void * buf2,size_t buf2_sz,void * buf3,size_t buf3_sz,handle_t * handles,uint32_t num_handles)188 int recv(handle_t chan,
189          size_t min_sz,
190          void* buf1,
191          size_t buf1_sz,
192          void* buf2,
193          size_t buf2_sz,
194          void* buf3,
195          size_t buf3_sz,
196          handle_t* handles,
197          uint32_t num_handles) {
198     int rc;
199     ipc_msg_info_t msg_inf;
200 
201     rc = get_msg(chan, &msg_inf);
202     if (rc)
203         return rc;
204 
205     if (msg_inf.len < min_sz || (msg_inf.len > (buf1_sz + buf2_sz + buf3_sz))) {
206         /* unexpected msg size: buffer too small or too big */
207         rc = ERR_BAD_LEN;
208     } else {
209         struct iovec iovs[] = {
210                 {
211                         .iov_base = buf1,
212                         .iov_len = buf1_sz,
213                 },
214                 {
215                         .iov_base = buf2,
216                         .iov_len = buf2_sz,
217                 },
218                 {
219                         .iov_base = buf3,
220                         .iov_len = buf3_sz,
221                 },
222         };
223         ipc_msg_t msg = {
224                 .num_iov = static_cast<uint32_t>(countof(iovs)),
225                 .iov = iovs,
226                 .num_handles = num_handles,
227                 .handles = handles,
228         };
229         rc = read_msg(chan, msg_inf.id, 0, &msg);
230     }
231 
232     put_msg(chan, msg_inf.id);
233     return rc;
234 }
235 
wait_for_msg(handle_t chan)236 int wait_for_msg(handle_t chan) {
237     uevent_t event = UEVENT_INITIAL_VALUE(event);
238     int rc = wait(chan, &event, INFINITE_TIME);
239     if (rc != NO_ERROR) {
240         return rc;
241     }
242 
243     if (event.event & IPC_HANDLE_POLL_HUP) {
244         return ERR_CHANNEL_CLOSED;
245     }
246     if (!(event.event & IPC_HANDLE_POLL_MSG)) {
247         return ERR_IO;
248     }
249 
250     return NO_ERROR;
251 }
252 
253 }  // namespace ipc
254 }  // namespace tidl
255