1 page.title=Trusty API Reference 2 @jd:body 3 4 <!-- 5 Copyright 2016 The Android Open Source Project 6 7 Licensed under the Apache License, Version 2.0 (the "License"); 8 you may not use this file except in compliance with the License. 9 You may obtain a copy of the License at 10 11 http://www.apache.org/licenses/LICENSE-2.0 12 13 Unless required by applicable law or agreed to in writing, software 14 distributed under the License is distributed on an "AS IS" BASIS, 15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 See the License for the specific language governing permissions and 17 limitations under the License. 18 --> 19 <div id="qv-wrapper"> 20 <div id="qv"> 21 <h2>In this document</h2> 22 <ol id="auto-toc"> 23 </ol> 24 </div> 25 </div> 26 27 <p>The <a href="index.html">Trusty</a> API generally describes the 28 Trusty inter-process communication (IPC) 29 system, including communications with the non-secure world. This page defines the 30 relevant terms and provides a reference for the API 31 calls.</p> 32 33 <h2 id=ports_and_channels>Ports and channels</h2> 34 35 <p>Ports are used by Trusty applications to expose service end-points in the form 36 of a named path to which clients connect. This gives a simple, string-based 37 service ID for clients to use. The naming convention is reverse-DNS-style 38 naming, e.g. <code>com.google.servicename</code>.</p> 39 40 <p>When a client connects to a port, the client receives a channel for interacting 41 with a service. The service must accept an incoming connection, and when it 42 does, it too receives a channel. In essence, ports are used to look up services 43 and then communication occurs over a pair of connected channels (i.e., 44 connection instances on a port). When a client connects to a port, a symmetric, 45 bi-directional connection is established. Using this full-duplex path, clients 46 and servers can exchange arbitrary messages until either side decides to tear 47 down the connection.</p> 48 49 <p>Only secure-side trusted applications or Trusty kernel modules can create 50 ports. Applications running on the non-secure side (in the normal world) can 51 only connect to services published by the secure side.</p> 52 53 <p>Depending on requirements, a trusted application can be both a client and a 54 server at the same time. A trusted application that publishes a service (as a 55 server) might need to connect to other services (as a client).</p> 56 57 <h2 id=handle_api>Handle API</h2> 58 59 <p>Handles are unsigned integers representing resources such as ports and 60 channels, similar to file descriptors in UNIX. After handles are created, they 61 are placed into an application-specific handle table and can be referenced 62 later.</p> 63 64 <p>A caller can associate private data with a handle by using 65 the <code>set_cookie()</code> method.</p> 66 67 <h3 id=methods_handle_api>Methods in the Handle API</h3> 68 69 <p>Handles are only valid in the context of an application. An application should 70 not pass the value of a handle to other applications unless explicitly 71 specified. A handle value only should be interpreted by comparing it with 72 the <code>INVALID_IPC_HANDLE #define,</code> which an application can use as an 73 indication that a handle is invalid or unset.</p> 74 75 <h4 id=set_cookie>set_cookie()</h4> 76 77 <p>Associates the caller-provided private data with a specified handle.</p> 78 79 <pre> 80 long set_cookie(uint32_t handle, void *cookie) 81 </pre> 82 83 <p>[in] <code>handle</code>: Any handle returned by one of the API calls</p> 84 85 <p>[in] <code>cookie</code>: Pointer to arbitrary user-space data in the Trusty application</p> 86 87 <p>[retval]: <code>NO_ERROR</code> on success, <code>< 0</code> error code otherwise</p> 88 89 <p>This call is useful for handling events when they occur at a later time after 90 the handle has been created. The event-handling mechanism supplies the handle 91 and its cookie back to the event handler.</p> 92 93 <p>Handles can be waited upon for events by using the <code>wait()</code> 94 or <code>wait_any()</code> calls.</p> 95 96 <h4 id=wait>wait()</h4> 97 98 <p>Waits for an event to occur on a given handle for specified period of time.</p> 99 100 <pre> 101 long wait(uint32_t handle_id, uevent_t *event, unsigned long timeout_msecs) 102 </pre> 103 104 <p>[in] <code>handle_id</code>: Any handle returned by one of the API calls</p> 105 106 <p>[out] <code>event</code>: A pointer to the structure representing 107 an event that occurred on this handle</p> 108 109 <p>[in] <code>timeout_msecs</code>: A timeout value in milliseconds; a 110 value of -1 is an infinite timeout</p> 111 112 <p>[retval]: <code>NO_ERROR</code> if a valid event occurred within a 113 specified timeout interval; <code>ERR_TIMED_OUT</code> if a specified timeout elapsed but no 114 event has occurred; <code>< 0</code> for other errors</p> 115 116 <h4 id=wait_any>wait_any()</h4> 117 118 <p>Waits for any event to occur on any handle in the application handle table for 119 the specified period of time.</p> 120 121 <pre> 122 long wait_any(uevent_t *event, unsigned long timeout_msecs); 123 </pre> 124 125 <p>[out] <code>event</code>: A pointer to the structure representing an 126 event that occurred on this handle</p> 127 128 <p>[in] <code>timeout_msecs</code>: A timeout value in milliseconds. 129 A value of -1 is an infinite timeout</p> 130 131 <p>[retval]: <code>NO_ERROR</code> if a valid event occurred within a 132 specified timeout interval; <code>ERR_TIMED_OUT</code> if a specified timeout elapsed but no 133 event has occurred; <code>< 0</code> for other errors</p> 134 135 <p>Upon success (<code>retval == NO_ERROR</code>), the <code>wait()</code> 136 and <code>wait_any()</code> calls 137 fill a specified <code>uevent_t</code> structure with information about 138 the event that occurred.</p> 139 140 <pre> 141 typedef struct uevent { 142 uint32_t handle; /* handle this event is related to */ 143 uint32_t event; /* combination of IPC_HANDLE_POLL_XXX flags */ 144 void *cookie; /* cookie associated with this handle */ 145 } uevent_t; 146 </pre> 147 148 <p>The <code>event</code> field contains a combination of the following values:</p> 149 150 <pre> 151 enum { 152 IPC_HANDLE_POLL_NONE = 0x0, 153 IPC_HANDLE_POLL_READY = 0x1, 154 IPC_HANDLE_POLL_ERROR = 0x2, 155 IPC_HANDLE_POLL_HUP = 0x4, 156 IPC_HANDLE_POLL_MSG = 0x8, 157 IPC_HANDLE_POLL_SEND_UNBLOCKED = 0x10, 158 more values[TBD] 159 }; 160 </pre> 161 162 <p><code>IPC_HANDLE_POLL_NONE</code> - no events are actually pending, 163 caller should restart the wait</p> 164 165 <p><code>IPC_HANDLE_POLL_ERROR</code> - an unspecified internal error has occurred</p> 166 167 <p><code>IPC_HANDLE_POLL_READY</code> - depends on the handle type, as follows:</p> 168 169 <ul> 170 <li>For ports, this value indicates that there is a pending connection 171 <li>For channels, this value indicates that an asynchronous connection 172 (see <code>connect()</code>) was established 173 </ul> 174 175 <p>The following events are only relevant for channels:</p> 176 177 <ul> 178 <li><code>IPC_HANDLE_POLL_HUP</code> - indicates that a channel has been closed by a peer 179 <li><code>IPC_HANDLE_POLL_MSG</code> - indicates that there is a pending message for this channel 180 <li><code>IPC_HANDLE_POLL_SEND_UNBLOCKED</code> - indicates that a previously 181 send-blocked caller may attempt to send a 182 message again (see the description of <code>send_msg()</code> for details) 183 </ul> 184 185 <p>An event handler should be prepared to handle a combination of specified 186 events, as multiple bits might be set at the same time. For example, for a 187 channel, it is possible to have pending messages, and a connection closed by a 188 peer at the same time.</p> 189 190 <p>Most events are sticky. They persist as long as the underlying condition 191 persists (for example all pending messages are received and pending connection 192 requests are handled). The exception is the case of 193 the <code>IPC_HANDLE_POLL_SEND_UNBLOCKED</code> event, which 194 is cleared upon a read and the application has only one chance to 195 handle it.</p> 196 197 <p>Handles can be destroyed by calling the <code>close()</code> method.</p> 198 199 <h4 id=close>close()</h4> 200 201 <p>Destroys the resource associated with the specified handle and removes it from 202 the handle table.</p> 203 204 <pre> 205 long close(uint32_t handle_id); 206 </pre> 207 208 <p>[in] <code>handle_id</code>: Handle to destroy</p> 209 210 <p>[retval]: 0 if success; a negative error otherwise</p> 211 212 <h2 id=server_api>Server API</h2> 213 214 <p>A server begins by creating one or more <strong>named ports</strong> representing 215 its service end-points. Each port is represented by a handle.</p> 216 217 <h3 id=methods_server_api>Methods in the Server API</h3> 218 219 <h4 id=port_create>port_create()</h4> 220 221 <p>Creates a named service port.</p> 222 223 <pre> 224 long port_create (const char *path, uint num_recv_bufs, size_t recv_buf_size, 225 uint32_t flags) 226 </pre> 227 228 <p>[in] <code>path</code>: The string name of the port (as described above). This 229 name should be unique across the system; attempts to create a duplicate will fail.</p> 230 231 <p>[in] <code>num_recv_bufs</code>: The maximum number of buffers that a channel on 232 this port can pre-allocate to facilitate the exchange of data with the client. Buffers are counted 233 separately for data going in both directions, so specifying 1 here would mean 1 234 send and 1 receive buffer are preallocated. In general, the number of buffers 235 required depends on the higher-level protocol agreement between the client and 236 server. The number can be as little as 1 in case of a very synchronous protocol 237 (send message, receive reply before sending another). But the number can be 238 more if the client expects to send more than one message before a reply can 239 appear (e.g, one message as a prologue and another as the actual command). The 240 allocated buffer sets are per channel, so two separate connections (channels) 241 would have separate buffer sets.</p> 242 243 <p>[in] <code>recv_buf_size</code>: Maximum size of each individual buffer in the 244 above buffer set. This value is 245 protocol-dependent and effectively limits maximum message size you can exchange 246 with peer</p> 247 248 <p>[in] <code>flags</code>: A combination of flags that specifies additional port behavior</p> 249 250 <p>This value should be a combination of the following values:</p> 251 252 <p><code>IPC_PORT_ALLOW_TA_CONNECT</code> - allows a connection from other secure apps</p> 253 254 <p><code>IPC_PORT_ALLOW_NS_CONNECT</code> - allows a connection from the non-secure world</p> 255 256 <p>[retval]: Handle to the port created if non-negative or a specific error if 257 negative</p> 258 259 <p>The server then polls the list of port handles for incoming connections 260 using <code>wait()</code> or <code>wait_any()</code> calls. Upon receiving a connection 261 request indicated by the <code>IPC_HANDLE_POLL_READY</code> bit set in 262 the <code>event</code> field of the <code>uevent_t</code> structure, the 263 server should call <code>accept()</code> to finish establishing a connection and create a 264 channel (represented by 265 another handle) that can then be polled for incoming messages.</p> 266 267 <h4 id=accept>accept()</h4> 268 269 <p>Accepts an incoming connection and gets a handle to a channel.</p> 270 271 <pre> 272 long accept(uint32_t handle_id, uuid_t *peer_uuid); 273 </pre> 274 275 <p>[in] <code>handle_id</code>: Handle representing the port to which a client has connected</p> 276 277 <p>[out] <code>peer_uuid</code>: Pointer to a <code>uuud_t</code> structure to be 278 filled with the UUID of the connecting client application. It 279 will be set to all zeros if the connection originated from the non-secure world</p> 280 281 <p>[retval]: Handle to a channel (if non-negative) on which the server can 282 exchange messages with the client (or an error code otherwise)</p> 283 284 <h2 id=client_api>Client API</h2> 285 286 <p>This section contains the methods in the Client API.</p> 287 288 <h3 id=methods_client_api>Methods in the Client API</h3> 289 290 <h4 id=connect>connect()</h4> 291 292 <p>Initiates a connection to a port specified by name.</p> 293 294 <pre> 295 long connect(const char *path, uint flags); 296 </pre> 297 298 <p>[in] <code>path</code>: Name of a port published by a Trusty application</p> 299 300 <p>[in] <code>flags</code>: Specifies additional, optional behavior</p> 301 302 <p>[retval]: Handle to a channel over which messages can be exchanged with the 303 server; error if negative</p> 304 305 <p>If no <code>flags</code> are specified (the <code>flags</code> parameter 306 is set to 0), calling <code>connect()</code> initiates a synchronous connection 307 to a specified port that immediately 308 returns an error if the port does not exist, and creates a block until the 309 server otherwise accepts a connection.</p> 310 311 <p>This behavior can be altered by specifying a combination of two values, 312 described below:</p> 313 314 <pre> 315 enum { 316 IPC_CONNECT_WAIT_FOR_PORT = 0x1, 317 IPC_CONNECT_ASYNC = 0x2, 318 }; 319 </pre> 320 321 <p><code>IPC_CONNECT_WAIT_FOR_PORT</code> - forces a <code>connect()</code> 322 call to wait if the specified port does not immediately exist at execution, 323 instead of failing immediately.</p> 324 325 <p><code>IPC_CONNECT_ASYNC</code> - if set, initiates an asynchronous connection. An 326 application has to poll for 327 the returned handle (by calling <code>wait()</code> or <code>wait_any()</code>) for 328 a connection completion event indicated by the <code>IPC_HANDLE_POLL_READY</code> 329 bit set in the event field of the <code>uevent_t</code> structure before starting 330 normal operation.</p> 331 332 <h2 id=messaging_api>Messaging API</h2> 333 334 <p>The Messaging API calls enable the sending and reading of messages over a 335 previously established connection (channel). The Messaging API calls are the 336 same for servers and clients.</p> 337 338 <p>A client receives a handle to a channel by issuing a <code>connect()</code> 339 call, and a server gets a channel handle from an <code>accept()</code> call, 340 described above.</p> 341 342 <h4 id=structure_of_a_trusty_message>Structure of a Trusty message</h4> 343 344 <p>As shown in the following, messages exchanged by the Trusty API have a minimal 345 structure, leaving it to the server and client to agree on the semantics of the 346 actual contents:</p> 347 348 <pre> 349 /* 350 * IPC message 351 */ 352 typedef struct iovec { 353 void *base; 354 size_t len; 355 } iovec_t; 356 357 typedef struct ipc_msg { 358 uint num_iov; /* number of iovs in this message */ 359 iovec_t *iov; /* pointer to iov array */ 360 361 uint num_handles; /* reserved, currently not supported */ 362 handle_t *handles; /* reserved, currently not supported */ 363 } ipc_msg_t; 364 </pre> 365 366 <p>A message can be composed of one or more non-contiguous buffers represented by 367 an array of <code>iovec_t</code> structures. Trusty performs scatter-gather 368 reads and writes to these blocks 369 using the <code>iov</code> array. The content of buffers that can be described 370 by the <code>iov</code> array is completely arbitrary.</p> 371 372 <h3 id=methods_messaging_api>Methods in the Messaging API</h3> 373 374 <h4 id=send_msg>send_msg()</h4> 375 376 <p>Sends a message over a specified channel.</p> 377 378 <pre> 379 long send_msg(uint32_t handle, ipc_msg_t *msg); 380 </pre> 381 382 <p>[in] <code>handle</code>: Handle to the channel over which to send the message</p> 383 384 <p>[in] <code>msg</code>: Pointer to the <code>ipc_msg_t structure</code> describing the message</p> 385 386 <p>[retval]: Total number of bytes sent on success; a negative error otherwise</p> 387 388 <p>If the client (or server) is trying to send a message over the channel and 389 there is no space in the destination peer message queue, the channel might 390 enter a send-blocked state (this should never happen for a simple synchronous 391 request/reply protocol but might happen in more complicated cases) that is 392 indicated by returning an <code>ERR_NOT_ENOUGH_BUFFER</code> error code. 393 In such a case the caller must wait until the peer frees some 394 space in its receive queue by retrieving the handling and retiring messages, 395 indicated by the <code>IPC_HANDLE_POLL_SEND_UNBLOCKED</code> bit set in 396 the <code>event</code> field of the <code>uevent_t</code> structure 397 returned by the <code>wait()</code> or <code>wait_any()</code> call.</p> 398 399 <h4 id=get_msg>get_msg()</h4> 400 401 <p>Gets meta-information about the next message in an incoming message queue</p> 402 403 <p>of a specified channel.</p> 404 405 <pre> 406 long get_msg(uint32_t handle, ipc_msg_info_t *msg_info); 407 </pre> 408 409 <p>[in] <code>handle</code>: Handle of the channel on which a new message must be retrieved</p> 410 411 <p>[out] <code>msg_info</code>: Message information structure described as follows:</p> 412 413 <pre> 414 typedef struct ipc_msg_info { 415 size_t len; /* total message length */ 416 uint32_t id; /* message id */ 417 } ipc_msg_info_t; 418 </pre> 419 420 <p>Each message is assigned a unique ID across the set of outstanding messages, 421 and the total length of each message is filled in. If configured and allowed by the 422 protocol, there can be multiple outstanding (opened) messages at once for a 423 particular channel.</p> 424 425 <p>[retval]: <code>NO_ERROR</code> on success; a negative error otherwise</p> 426 427 <h4 id=read_msg>read_msg()</h4> 428 429 <p>Reads the content of the message with the specified ID starting from the 430 specified offset.</p> 431 432 <pre> 433 long read_msg(uint32_t handle, uint32_t msg_id, uint32_t offset, ipc_msg_t 434 *msg); 435 </pre> 436 437 <p>[in] <code>handle</code>: Handle of the channel from which to read the message</p> 438 439 <p>[in] <code>msg_id</code>: ID of the message to read</p> 440 441 <p>[in] <code>offset</code>: Offset into the message from which to start reading</p> 442 443 <p>[in] <code>msg</code>: Pointer to the <code>ipc_msg_t</code> structure describing 444 a set of buffers into which to store incoming message 445 data</p> 446 447 <p>[retval]: Total number of bytes stored in the <code>dst</code> buffers on 448 success; a negative error otherwise</p> 449 450 <p>The <code>read_msg</code> method can be called multiple times starting at 451 a different (not necessarily 452 sequential) offset as needed.</p> 453 454 <h4 id=put_msg>put_msg()</h4> 455 456 <p>Retires a message with a specified ID.</p> 457 458 <pre> 459 long put_msg(uint32_t handle, uint32_t msg_id); 460 </pre> 461 462 <p>[in] <code>handle</code>: Handle of the channel on which the message has arrived</p> 463 464 <p>[in] <code>msg_id</code>: ID of message being retired</p> 465 466 <p>[retval]: <code>NO_ERROR</code> on success; a negative error otherwise</p> 467 468 <p>Message content cannot be accessed after a message has been retired and the 469 buffer it occupied has been freed.</p> 470 471 <h2 id=file_descriptor_api>File Descriptor API</h2> 472 473 <p>The File Descriptor API includes <code>read()</code>, <code>write()</code>, 474 and <code>ioctl()</code> calls. All of these calls can operate on a predefined (static) set of file 475 descriptors traditionally represented by small numbers. In the current 476 implementation, the file descriptor space is separate from the IPC handle 477 space. The File Descriptor API in Trusty is 478 similar to a traditional file descriptor-based API.</p> 479 480 <p>By default, there are 3 predefined (standard and well-known) file descriptors:</p> 481 482 <ul> 483 <li>0 - standard input. The default implementation of standard input <code>fd</code> 484 is a no-op (as trusted applications are not expected to have an interactive 485 console) so reading, writing or invoking <code>ioctl()</code> on <code>fd</code> 0 486 should return an <code>ERR_NOT_SUPPORTED</code> error. 487 <li>1 - standard output. Data written to standard output can be routed (depending 488 on the LK debug level) to UART and/or a memory log available on the non-secure 489 side, depending on the platform and configuration. Non-critical debug logs and 490 messages should go in standard output. The <code>read()</code> and <code>ioctl()</code> 491 methods are no-ops and should return an <code>ERR_NOT_SUPPORTED</code> error. 492 <li>2 - standard error. Data written to standard error should be routed to the UART 493 or memory log available on the non-secure side, depending on the platform and 494 configuration. It is recommended to write only critical messages to standard 495 error, as this stream is very likely to be unthrottled. The <code>read()</code> and 496 <code>ioctl()</code> methods are no-ops and should return an <code>ERR_NOT_SUPPORTED</code> error. 497 </ul> 498 499 <p>Even though this set of file descriptors can be extended to implement more 500 <code>fds</code> (to implement platform-specific extensions), extending file descriptors needs 501 to be exercised with caution. Extending file descriptors is prone to create 502 conflicts and is not generally recommended.</p> 503 504 <h3 id=methods_file_descriptor_api>Methods in the File Descriptor API</h3> 505 506 <h4 id=read>read()</h4> 507 508 <p>Attempts to read up to <code>count</code> bytes of data from a specified file descriptor.</p> 509 510 <pre> 511 long read(uint32_t fd, void *buf, uint32_t count); 512 </pre> 513 514 <p>[in] <code>fd</code>: File descriptor from which to read</p> 515 516 <p>[out] <code>buf</code>: Pointer to a buffer into which to store data</p> 517 518 <p>[in] <code>count</code>: Maximum number of bytes to read</p> 519 520 <p>[retval]: Returned number of bytes read; a negative error otherwise</p> 521 522 <h4 id=write>write()</h4> 523 524 <p>Writes up to <code>count</code> bytes of data to specified file descriptor.</p> 525 526 <pre> 527 long write(uint32_t fd, void *buf, uint32_t count); 528 </pre> 529 530 <p>[in] <code>fd</code>: File descriptor to which to write</p> 531 532 <p>[out] <code>buf</code>: Pointer to data to write</p> 533 534 <p>[in] <code>count</code>: Maximum number of bytes to write</p> 535 536 <p>[retval]: Returned number of bytes written; a negative error otherwise</p> 537 538 <h4 id=ioctl>ioctl()</h4> 539 540 <p>Invokes a specified <code>ioctl</code> command for a given file descriptor.</p> 541 542 <pre> 543 long ioctl(uint32_t fd, uint32_t cmd, void *args); 544 </pre> 545 546 <p>[in] <code>fd</code>: File descriptor on which to invoke <code>ioctl()</code></p> 547 548 <p>[in] <code>cmd</code>: The <code>ioctl</code> command</p> 549 550 <p>[in/out] <code>args</code>: Pointer to <code>ioctl()</code> arguments</p> 551 552 <h2 id=miscellaneous_api>Miscellaneous API</h2> 553 554 <h3 id=methods_misc_api>Methods in the Miscellaneous API</h3> 555 556 <h4 id=gettime>gettime()</h4> 557 558 <p>Returns the current system time (in nanoseconds).</p> 559 560 <pre> 561 long gettime(uint32_t clock_id, uint32_t flags, uint64_t *time); 562 </pre> 563 564 <p>[in] <code>clock_id</code>: Platform-dependent; pass zero for default</p> 565 566 <p>[in] <code>flags</code>: Reserved, should be zero</p> 567 568 <p>[in] <code>time</code>: Pointer to an <code>int64_t</code> value to which to store the current time</p> 569 570 <p>[retval]: <code>NO_ERROR</code> on success; a negative error otherwise</p> 571 572 <h4 id=nanosleep>nanosleep()</h4> 573 574 <p>Suspends execution of the calling application for a specified period of time 575 and resumes it after that period.</p> 576 577 <pre> 578 long nanosleep(uint32_t clock_id, uint32_t flags, uint64_t sleep_time) 579 </pre> 580 581 <p>[in] <code>clock_id</code>: Reserved, should be zero</p> 582 583 <p>[in] <code>flags</code>: Reserved, should be zero</p> 584 585 <p>[in] <code>sleep_time</code>: Sleep time in nanoseconds</p> 586 587 <p>[retval]: <code>NO_ERROR</code> on success; a negative error otherwise</p> 588 589 <h2 id=example_of_a_trusted_application_server>Example of a trusted application server</h2> 590 591 <p>The following sample application shows the usage of the above APIs. The sample 592 creates an "echo" service that handles multiple incoming connections and 593 reflects back to the caller all messages it receives from clients originated 594 from the secure or non-secure side.</p> 595 596 <pre> 597 #include <assert.h> 598 #include <err.h> 599 #include <stddef.h> 600 #include <stdio.h> 601 #include <stdlib.h> 602 #include <string.h> 603 #include <trusty_std.h> 604 605 #include <app/echo/uuids.h> 606 607 #define LOG_TAG "echo_srv" 608 609 #define TLOGE(fmt, ...) \ 610 fprintf(stderr, "%s: %d: " fmt, LOG_TAG, __LINE__, ## __VA_ARGS__) 611 612 #define MAX_ECHO_MSG_SIZE 64 613 614 static const char *srv_name = "com.android.echo.srv.echo"; 615 616 static uint8_t msg_buf[MAX_ECHO_MSG_SIZE]; 617 618 /* 619 * Message handler 620 */ 621 static int handle_msg(handle_t chan) 622 { 623 int rc; 624 iovec_t iov; 625 ipc_msg_t msg; 626 ipc_msg_info_t msg_inf; 627 628 iov.base = msg_buf; 629 iov.len = sizeof(msg_buf); 630 631 msg.num_iov = 1; 632 msg.iov = &iov; 633 msg.num_handles = 0; 634 msg.handles = NULL; 635 636 /* get message info */ 637 rc = get_msg(chan, &msg_inf); 638 if (rc == ERR_NO_MSG) 639 return NO_ERROR; /* no new messages */ 640 641 if (rc != NO_ERROR) { 642 TLOGE("failed (%d) to get_msg for chan (%d)\n", 643 rc, chan); 644 return rc; 645 } 646 647 /* read msg content */ 648 rc = read_msg(chan, msg_inf.id, 0, &msg); 649 if (rc < 0) { 650 TLOGE("failed (%d) to read_msg for chan (%d)\n", 651 rc, chan); 652 return rc; 653 } 654 655 /* update number of bytes received */ 656 iov.len = (size_t) rc; 657 658 /* send message back to the caller */ 659 rc = send_msg(chan, &msg); 660 if (rc < 0) { 661 TLOGE("failed (%d) to send_msg for chan (%d)\n", 662 rc, chan); 663 return rc; 664 } 665 666 /* retire message */ 667 rc = put_msg(chan, msg_inf.id); 668 if ( rc != NO_ERROR) { 669 TLOGE("failed (%d) to put_msg for chan (%d)\n", 670 rc, chan); 671 return rc; 672 } 673 674 return NO_ERROR; 675 } 676 677 /* 678 * Channel event handler 679 */ 680 static void handle_channel_event(const uevent_t *ev) 681 { 682 int rc; 683 684 if (ev->event & IPC_HANDLE_POLL_MSG) { 685 rc = handle_msg(ev->handle); 686 if (rc != NO_ERROR) { 687 /* report an error and close channel */ 688 TLOGE("failed (%d) to handle event on channel %d\n", 689 rc, ev->handle); 690 close(ev->handle); 691 } 692 return; 693 } 694 if (ev->event & IPC_HANDLE_POLL_HUP) { 695 /* closed by peer. */ 696 close(ev->handle); 697 return; 698 } 699 } 700 701 /* 702 * Port event handler 703 */ 704 static void handle_port_event(const uevent_t *ev) 705 { 706 uuid_t peer_uuid; 707 708 if ((ev->event & IPC_HANDLE_POLL_ERROR) || 709 (ev->event & IPC_HANDLE_POLL_HUP) || 710 (ev->event & IPC_HANDLE_POLL_MSG) || 711 (ev->event & IPC_HANDLE_POLL_SEND_UNBLOCKED)) { 712 /* should never happen with port handles */ 713 TLOGE("error event (0x%x) for port (%d)\n", 714 ev->event, ev->handle); 715 abort(); 716 } 717 if (ev->event & IPC_HANDLE_POLL_READY) { 718 /* incoming connection: accept it */ 719 int rc = accept(ev->handle, &peer_uuid); 720 if (rc < 0) { 721 TLOGE("failed (%d) to accept on port %d\n", 722 rc, ev->handle); 723 return; 724 } 725 } 726 } 727 728 /* 729 * Main application entry point 730 */ 731 int main(void) 732 { 733 int rc; 734 handle_t port; 735 736 /* Initialize service */ 737 rc = port_create(srv_name, 1, MAX_ECHO_MSG_SIZE, 738 IPC_PORT_ALLOW_NS_CONNECT | 739 IPC_PORT_ALLOW_TA_CONNECT ); 740 if (rc < 0) { 741 TLOGE("Failed (%d) to create port %s\n", 742 rc, srv_name); 743 abort(); 744 } 745 port = (handle_t)rc; 746 747 /* enter main event loop */ 748 while (true) { 749 uevent_t ev; 750 751 ev.handle = INVALID_IPC_HANDLE; 752 ev.event = 0; 753 ev.cookie = NULL; 754 755 /* wait forever */ 756 rc = wait_any(&ev, -1); 757 if (rc == NO_ERROR) { 758 /* got an event */ 759 if (ev.handle == port) { 760 handle_port_event(&ev); 761 } else { 762 handle_channel_event(&ev); 763 } 764 } else { 765 TLOGE("wait_any returned (%d)\n", rc); 766 abort(); 767 } 768 } 769 return 0; 770 } 771 </pre> 772 773 <h2 id=example_of_a_trusted_application_client>Example of a trusted application client</h2> 774 775 <p>The following code snippets show the use of the Trusty messaging APIs to 776 implement a client of an "echo" service (shown in the code above). The <code>sync_connect()</code> 777 method shows an implementation of a synchronous connect with a timeout on top 778 of an asynchronous <code>connect()</code> call.</p> 779 780 <pre> 781 /* 782 * Local wrapper on top of an async connect that provides a 783 * synchronous connect with timeout. 784 */ 785 int sync_connect(const char *path, uint timeout) 786 { 787 int rc; 788 uevent_t evt; 789 handle_t chan; 790 791 rc = connect(path, IPC_CONNECT_ASYNC | IPC_CONNECT_WAIT_FOR_PORT); 792 if (rc >= 0) { 793 chan = (handle_t) rc; 794 rc = wait(chan, &evt, timeout); 795 if (rc == 0) { 796 rc = ERR_BAD_STATE; 797 if (evt.handle == chan) { 798 if (evt.event & IPC_HANDLE_POLL_READY) 799 return chan; 800 if (evt.event & IPC_HANDLE_POLL_HUP) 801 rc = ERR_CHANNEL_CLOSED; 802 } 803 } 804 close(chan); 805 } 806 return rc; 807 } 808 </pre> 809 810 <p>The <code>run_end_to_end_msg_test()</code> method sends 10,000 messages asynchronously 811 to the "echo" service and handles 812 replies.</p> 813 814 <pre> 815 static int run_echo_test(void) 816 { 817 int rc; 818 handle_t chan; 819 uevent_t uevt; 820 uint8_t tx_buf[64]; 821 uint8_t rx_buf[64]; 822 ipc_msg_info_t inf; 823 ipc_msg_t tx_msg; 824 iovec_t tx_iov; 825 ipc_msg_t rx_msg; 826 iovec_t rx_iov; 827 828 /* prepare tx message buffer */ 829 tx_iov.base = tx_buf; 830 tx_iov.len = sizeof(tx_buf); 831 tx_msg.num_iov = 1; 832 tx_msg.iov = &tx_iov; 833 tx_msg.num_handles = 0; 834 tx_msg.handles = NULL; 835 836 memset (tx_buf, 0x55, sizeof(tx_buf)); 837 838 /* prepare rx message buffer */ 839 rx_iov.base = rx_buf; 840 rx_iov.len = sizeof(rx_buf); 841 rx_msg.num_iov = 1; 842 rx_msg.iov = &rx_iov; 843 rx_msg.num_handles = 0; 844 rx_msg.handles = NULL; 845 846 /* open connection to echo service */ 847 rc = sync_connect(srv_name, 1000); 848 if(rc < 0) 849 return rc; 850 851 /* got channel */ 852 chan = (handle_t)rc; 853 854 /* send/receive 10000 messages asynchronously. */ 855 uint tx_cnt = 10000; 856 uint rx_cnt = 10000; 857 858 while (tx_cnt || rx_cnt) { 859 /* send messages until all buffers are full */ 860 while (tx_cnt) { 861 rc = send_msg(chan, &tx_msg); 862 if (rc == ERR_NOT_ENOUGH_BUFFER) 863 break; /* no more space */ 864 if (rc != 64) { 865 if (rc > 0) { 866 /* incomplete send */ 867 rc = ERR_NOT_VALID; 868 } 869 goto abort_test; 870 } 871 tx_cnt--; 872 } 873 874 /* wait for reply msg or room */ 875 rc = wait(chan, &uevt, 1000); 876 if (rc != NO_ERROR) 877 goto abort_test; 878 879 /* drain all messages */ 880 while (rx_cnt) { 881 /* get a reply */ 882 rc = get_msg(chan, &inf); 883 if (rc == ERR_NO_MSG) 884 break; /* no more messages */ 885 if (rc != NO_ERROR) 886 goto abort_test; 887 888 /* read reply data */ 889 rc = read_msg(chan, inf.id, 0, &rx_msg); 890 if (rc != 64) { 891 /* unexpected reply length */ 892 rc = ERR_NOT_VALID; 893 goto abort_test; 894 } 895 896 /* discard reply */ 897 rc = put_msg(chan, inf.id); 898 if (rc != NO_ERROR) 899 goto abort_test; 900 rx_cnt--; 901 } 902 } 903 904 abort_test: 905 close(chan); 906 return rc; 907 } 908 </pre> 909 910 <h2 id=non-secure_world_apis_and_applications>Non-secure world APIs and applications</h2> 911 912 <p>A set of Trusty services, published from the secure side and marked with 913 the <code>IPC_PORT_ALLOW_NS_CONNECT</code> attribute, are accessible to kernel 914 and user space programs running on the 915 non-secure side.</p> 916 917 <p>The execution environment on the non-secure side (kernel and user space) is 918 drastically different from the execution environment on the secure-side. 919 Therefore, rather than a single library for both environments, there are two 920 different sets of APIs. In the kernel, the Client API is provided by the 921 trusty-ipc kernel driver and registers a character device node that can be used 922 by user space processes to communicate with services running on the secure 923 side.</p> 924 925 <h3 id=user_space_trusty_ipc_client_api>User space Trusty IPC Client API</h3> 926 927 <p>The user space Trusty IPC Client API library is a thin layer on top of the 928 device node <code>fd</code>.</p> 929 930 <p>A user space program starts a communication session 931 by calling <code>tipc_connect()</code>, 932 initializing a connection to a specified Trusty service. Internally, 933 the <code>tipc_connect()</code> call opens a specified device node to 934 obtain a file descriptor and invokes a <code>TIPC_IOC_CONNECT ioctl()</code> 935 call with the <code>argp</code> parameter pointing to a string containing a 936 service name to which to connect.</p> 937 938 <pre> 939 #define TIPC_IOC_MAGIC 'r' 940 #define TIPC_IOC_CONNECT _IOW(TIPC_IOC_MAGIC, 0x80, char *) 941 </pre> 942 943 <p>The resulting file descriptor can only be used to communicate with the service 944 for which it was created. The file descriptor should be closed by 945 calling <code>tipc_close()</code> when the connection is not required anymore.</p> 946 947 <p>The file descriptor obtained by the <code>tipc_connect()</code> call 948 behaves as a typical character device node; the file descriptor:</p> 949 950 <ul> 951 <li>Can be switched to non-blocking mode if needed 952 <li>Can be written to using a standard <code>write()</code> 953 call to send messages to the other side 954 <li>Can be polled (using <code>poll()</code> calls or <code>select()</code> calls) 955 for availability of incoming messages as a regular file descriptor 956 <li>Can be read to retrieve incoming messages 957 </ul> 958 959 <p>A caller sends a message to the Trusty service by executing a write call for 960 the specified <code>fd</code>. All data passed to the above <code>write()</code> call 961 is transformed into a message by the trusty-ipc driver. The message is 962 delivered to the secure side where the data is handled by the IPC subsystem in 963 the Trusty kernel and routed to the proper destination and delivered to an app 964 event loop as an <code>IPC_HANDLE_POLL_MSG</code> event on a particular channel 965 handle. Depending on the particular, 966 service-specific protocol, the Trusty service may send one or more reply 967 messages that are delivered back to the non-secure side and placed in the 968 appropriate channel file descriptor message queue to be retrieved by the user 969 space application <code>read()</code> call.</p> 970 971 <h4 id=tipc_connect>tipc_connect()</h4> 972 973 <p>Opens a specified <code>tipc</code> device node and initiates a 974 connection to a specified Trusty service.</p> 975 976 <pre> 977 int tipc_connect(const char *dev_name, const char *srv_name); 978 </pre> 979 980 <p>[in] <code>dev_name</code>: Path to the Trusty IPC device node to open</p> 981 982 <p>[in] <code>srv_name</code>: Name of a published Trusty service to which to connect</p> 983 984 <p>[retval]: Valid file descriptor on success, -1 otherwise.</p> 985 986 <h4 id=tipc_close>tipc_close()</h4> 987 988 <p>Closes the connection to the Trusty service specified by a file descriptor.</p> 989 990 <pre> 991 int tipc_close(int fd); 992 </pre> 993 994 <p>[in] <code>fd</code>: File descriptor previously opened by 995 a <code>tipc_connect()</code> call</p> 996 997 <h2 id=kernel_trusty_ipc_client_api>Kernel Trusty IPC Client API</h2> 998 999 <p>The kernel Trusty IPC Client API is available for kernel drivers. The user 1000 space Trusty IPC API is implemented on top of this API.</p> 1001 1002 <p>In general, typical usage of this API consists of a caller creating 1003 a <code>struct tipc_chan</code> object by using the <code>tipc_create_channel()</code> 1004 function and then using the <code>tipc_chan_connect()</code> call to initiate a 1005 connection to the Trusty IPC service running on the secure 1006 side. The connection to the remote side can be terminated by 1007 calling <code>tipc_chan_shutdown()</code> followed by 1008 <code>tipc_chan_destroy()</code> to clean up resources.</p> 1009 1010 <p>Upon receiving a notification (through the <code>handle_event()</code> callback) 1011 that a connection has been successfully established, a caller does 1012 the following:</p> 1013 1014 <ul> 1015 <li>Obtains a message buffer using the <code>tipc_chan_get_txbuf_timeout()</code> call 1016 <li>Composes a message, and 1017 <li>Queues the message using the <code>tipc_chan_queue_msg()</code> 1018 method for delivery to a Trusty service (on the secure side), to which the 1019 channel is connected 1020 </ul> 1021 1022 <p>After queueing is successful, the caller should forget the message buffer 1023 because the message buffer eventually returns to the free buffer pool after 1024 processing by the remote side (for reuse later, for other messages). The user 1025 only needs to call <code>tipc_chan_put_txbuf()</code> if it fails to 1026 queue such buffer or it is not required anymore.</p> 1027 1028 <p>An API user receives messages from the remote side by handling a 1029 <code>handle_msg()</code> notification callback (which is called in 1030 the context of the trusty-ipc <code>rx</code> workqueue) that 1031 provides a pointer to an <code>rx</code> buffer containing an 1032 incoming message to be handled.</p> 1033 1034 <p>It is expected that the <code>handle_msg()</code> callback 1035 implementation will return a pointer to a valid <code>struct tipc_msg_buf</code>. 1036 It can be the same as the incoming message buffer if it is handled locally 1037 and not required anymore. Alternatively, it can be a new buffer obtained by 1038 a <code>tipc_chan_get_rxbuf()</code> call if the incoming buffer is queued 1039 for further processing. A detached <code>rx</code> buffer must be tracked 1040 and eventually released using a <code>tipc_chan_put_rxbuf()</code> call when 1041 it is no longer needed.</p> 1042 1043 <h3 id=methods_ktic_api>Methods in the Kernel Trusty IPC Client API</h3> 1044 1045 <h4 id=tipc_create_channel>tipc_create_channel()</h4> 1046 1047 <p>Creates and configures an instance of a Trusty IPC channel for a particular 1048 trusty-ipc device.</p> 1049 1050 <pre> 1051 struct tipc_chan *tipc_create_channel(struct device *dev, 1052 const struct tipc_chan_ops *ops, 1053 void *cb_arg); 1054 </pre> 1055 1056 <p>[in] <code>dev</code>: Pointer to the trusty-ipc for which the device 1057 channel is created</p> 1058 1059 <p>[in] <code>ops</code>: Pointer to a <code>struct tipc_chan_ops</code>, 1060 with caller-specific 1061 callbacks filled in</p> 1062 1063 <p>[in] <code>cb_arg</code>: Pointer to data that will be passed 1064 to <code>tipc_chan_ops</code> callbacks</p> 1065 1066 <p>[retval]: Pointer to a newly-created instance of 1067 <code>struct tipc_chan</code> on success, 1068 <code>ERR_PTR(err)</code> otherwise</p> 1069 1070 <p>In general, a caller must provide two callbacks that are asynchronously invoked 1071 when the corresponding activity is occurring.</p> 1072 1073 <p>The <code>void (*handle_event)(void *cb_arg, int event)</code>event is invoked 1074 to notify a caller about a channel state change.</p> 1075 1076 <p>[in] <code>cb_arg</code>: Pointer to data passed to a 1077 <code>tipc_create_channel()</code> call</p> 1078 1079 <p>[in] <code>event</code>: An event that can be one of the following values:</p> 1080 1081 <ul> 1082 <li><code>TIPC_CHANNEL_CONNECTED</code> - indicates a successful connection 1083 to the remote side 1084 <li><code>TIPC_CHANNEL_DISCONNECTED</code> - indicates the remote side denied the 1085 new connection request or requested 1086 disconnection for the previously connected channel 1087 <li><code>TIPC_CHANNEL_SHUTDOWN</code> - indicates the remote side is shutting down, 1088 permanently terminating all connections 1089 </ul> 1090 1091 <p>The <code>struct tipc_msg_buf *(*handle_msg)(void *cb_arg, struct tipc_msg_buf *mb)</code> 1092 callback is invoked to provide notification that a new message has been 1093 received over a specified channel:</p> 1094 1095 <ul> 1096 <li>[in] <code>cb_arg</code>: Pointer to data passed to the 1097 <code>tipc_create_channel()</code> call 1098 <li>[in] <code>mb</code>: Pointer to a <code>struct tipc_msg_buf</code> 1099 describing an incoming message 1100 <li>[retval]: The callback implementation is expected to return a pointer to a 1101 <code>struct tipc_msg_buf</code> that can be the same pointer received 1102 as an 1103 <code>mb</code> parameter if the message is handled locally and is not 1104 required anymore (or it 1105 can be a new buffer obtained by the <code>tipc_chan_get_rxbuf()</code> call) 1106 </ul> 1107 1108 <h4 id=tipc_chan_connect>tipc_chan_connect()</h4> 1109 1110 <p>Initiates a connection to the specified Trusty IPC service.</p> 1111 1112 <pre> 1113 int tipc_chan_connect(struct tipc_chan *chan, const char *port); 1114 </pre> 1115 1116 <p>[in] <code>chan</code>: Pointer to a channel returned by the 1117 <code>tipc_create_chan()</code> call</p> 1118 1119 <p>[in] <code>port</code>: Pointer to a string containing the 1120 service name to which to connect</p> 1121 1122 <p>[retval]: 0 on success, a negative error otherwise</p> 1123 1124 <p>The caller is notified when a connection is established by receiving a 1125 <code>handle_event</code> callback.</p> 1126 1127 <h4 id=tipc_chan_shutdown>tipc_chan_shutdown()</h4> 1128 1129 <p>Terminates a connection to the Trusty IPC service previously initiated 1130 by a <code>tipc_chan_connect()</code> call.</p> 1131 1132 <pre> 1133 int tipc_chan_shutdown(struct tipc_chan *chan); 1134 </pre> 1135 1136 <p>[in] <code>chan</code>: Pointer to a channel returned by 1137 a <code>tipc_create_chan()</code> call</p> 1138 1139 <h4 id=tipc_chan_destroy>tipc_chan_destroy()</h4> 1140 1141 <p>Destroys a specified Trusty IPC channel.</p> 1142 1143 <pre> 1144 void tipc_chan_destroy(struct tipc_chan *chan); 1145 </pre> 1146 1147 <p>[in] <code>chan</code>: Pointer to a channel returned by the 1148 <code>tipc_create_chan()</code> call</p> 1149 1150 <h4 id=tipc_chan_get_txbuf_timeout>tipc_chan_get_txbuf_timeout()</h4> 1151 1152 <p>Obtains a message buffer that can be used to send data over a specified 1153 channel. If the buffer is not immediately available the caller may be blocked 1154 for the specified timeout (in milliseconds).</p> 1155 1156 <pre> 1157 struct tipc_msg_buf * 1158 tipc_chan_get_txbuf_timeout(struct tipc_chan *chan, long timeout); 1159 </pre> 1160 1161 <p>[in] <code>chan</code>: Pointer to the channel to which to queue a message</p> 1162 1163 <p>[in] <code>chan</code>: Maximum timeout to wait until the 1164 <code>tx</code> buffer becomes available </p> 1165 1166 <p>[retval]: A valid message buffer on success, 1167 <code>ERR_PTR(err)</code> on error</p> 1168 1169 <h4 id=tipc_chan_queue_msg>tipc_chan_queue_msg()</h4> 1170 1171 <p>Queues a message to be sent over the specified 1172 Trusty IPC channels.</p> 1173 1174 <pre> 1175 int tipc_chan_queue_msg(struct tipc_chan *chan, struct tipc_msg_buf *mb); 1176 </pre> 1177 1178 <p>[in] <code>chan</code>: Pointer to the channel to which to queue the message</p> 1179 1180 <p>[in] <code>mb:</code> Pointer to the message to queue 1181 (obtained by a <code>tipc_chan_get_txbuf_timeout()</code> call)</p> 1182 1183 <p>[retval]: 0 on success, a negative error otherwise</p> 1184 1185 <h4 id=tipc_chan_put_txbuf>tipc_chan_put_txbuf()</h4> 1186 1187 <p>Releases the specified <code>Tx</code> message buffer 1188 previously obtained by a <code>tipc_chan_get_txbuf_timeout()</code> call.</p> 1189 1190 <pre> 1191 void tipc_chan_put_txbuf(struct tipc_chan *chan, 1192 struct tipc_msg_buf *mb); 1193 </pre> 1194 1195 <p>[in] <code>chan</code>: Pointer to the channel to which 1196 this message buffer belongs</p> 1197 1198 <p>[in] <code>mb</code>: Pointer to the message buffer to release</p> 1199 1200 <p>[retval]: None</p> 1201 1202 <h4 id=tipc_chan_get_rxbuf>tipc_chan_get_rxbuf()</h4> 1203 1204 <p>Obtains a new message buffer that can be used to receive messages over the 1205 specified channel.</p> 1206 1207 <pre> 1208 struct tipc_msg_buf *tipc_chan_get_rxbuf(struct tipc_chan *chan); 1209 </pre> 1210 1211 <p>[in] <code>chan</code>: Pointer to a channel to which this message buffer belongs</p> 1212 1213 <p>[retval]: A valid message buffer on success, <code>ERR_PTR(err)</code> on error</p> 1214 1215 <h4 id=tipc_chan_put_rxbuf>tipc_chan_put_rxbuf()</h4> 1216 1217 <p>Releases a specified message buffer previously obtained by a 1218 <code>tipc_chan_get_rxbuf()</code> call.</p> 1219 1220 <pre> 1221 void tipc_chan_put_rxbuf(struct tipc_chan *chan, 1222 struct tipc_msg_buf *mb); 1223 </pre> 1224 1225 <p>[in] <code>chan</code>: Pointer to a channel to which this message buffer belongs</p> 1226 1227 <p>[in] <code>mb</code>: Pointer to a message buffer to release</p> 1228 1229 <p>[retval]: None</p> 1230