Home | History | Annotate | Download | only in trusty
      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>&lt; 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>&lt; 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>&lt; 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 &lt;assert.h>
    598 #include &lt;err.h>
    599 #include &lt;stddef.h>
    600 #include &lt;stdio.h>
    601 #include &lt;stdlib.h>
    602 #include &lt;string.h>
    603 #include &lt;trusty_std.h>
    604 
    605 #include &lt;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 &lt; 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 &lt; 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 &lt; 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 &lt; 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 &lt; 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