1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #pragma once
6 
7 #include <stdint.h>
8 #include <zircon/compiler.h>
9 #include <zircon/fidl.h>
10 #include <zircon/types.h>
11 
12 // In principle, this header should be generated by the FIDL compiler, but this
13 // protocol is used at such a low level (e.g., in userboot and in libc) that we
14 // have a hand-written implementation available.
15 
16 __BEGIN_CDECLS
17 
18 // See system/fidl/fuchsia-ldsvc/ldsvc.fidl for the definition of these message ordinals.
19 #define LDMSG_OP_DONE                    1u
20 #define LDMSG_OP_LOAD_OBJECT             2u
21 #define LDMSG_OP_LOAD_SCRIPT_INTERPRETER 3u
22 #define LDMSG_OP_CONFIG                  4u
23 #define LDMSG_OP_CLONE                   5u
24 #define LDMSG_OP_DEBUG_PUBLISH_DATA_SINK 7u
25 #define LDMSG_OP_DEBUG_LOAD_CONFIG       8u
26 
27 // The payload format used for all the requests other than LDMSG_OP_CLONE.
28 typedef struct ldmsg_common ldmsg_common_t;
29 struct ldmsg_common {
30     alignas(FIDL_ALIGNMENT) fidl_string_t string;
31     alignas(FIDL_ALIGNMENT) zx_handle_t object;
32 };
33 
34 // The payload format used for LDMSG_OP_CLONE.
35 typedef struct ldmsg_clone ldmsg_clone_t;
36 struct ldmsg_clone {
37     alignas(FIDL_ALIGNMENT) zx_handle_t object;
38 };
39 
40 // The maximum size of a ldmsg_req_t payload.
41 #define LDMSG_MAX_PAYLOAD (1024 - sizeof(fidl_message_header_t))
42 
43 // The message format used for requests.
44 //
45 // This struct contains 1024 bytes. After the message header, the data varies
46 // according to the ordinal. The space after the fix-size portion of the message
47 // is used to contain string data.
48 //
49 // The |ldmsg_req_encode| function will encode a message of at most 1023 bytes
50 // so that a server that uses this struct will always have one byte remaining to
51 // null-terminate the string data. The client does not necessarily include a
52 // null terminator.
53 typedef struct ldmsg_req ldmsg_req_t;
54 struct ldmsg_req {
55     fidl_message_header_t header;
56     union {
57         ldmsg_common_t common;
58         ldmsg_clone_t clone;
59         char data[LDMSG_MAX_PAYLOAD];
60     };
61 };
62 
63 // The message format used for responses.
64 //
65 // Depending on the ordinal in the message header, the |object| field might or
66 // might not be part of the message.
67 //
68 // Consider using |ldmsg_rsp_get_size| to determine how much of this structure
69 // is used for a given ordinal.
70 typedef struct ldmsg_rsp ldmsg_rsp_t;
71 struct ldmsg_rsp {
72     fidl_message_header_t header;
73     zx_status_t rv;
74     zx_handle_t object;
75 };
76 
77 // Encode the message in |req|.
78 //
79 // The format of the message will be determined by the ordinal in the message's
80 // header. If the ordinal is invalid, this function will return
81 // ZX_ERR_INVALID_ARGS.
82 //
83 // The given |data| will be copied into |*req| at the appropriate location if
84 // the message format contains a string. If |len| is too large, this function
85 // will return ZX_ERR_OUT_OF_RANGE.
86 //
87 // Otherwise, this function will return ZX_OK.
88 zx_status_t ldmsg_req_encode(ldmsg_req_t* req, size_t* req_len_out,
89                              const char* data, size_t len);
90 
91 // Decode the message in |req|.
92 //
93 // The format of the message will be determined by the ordinal in the message's
94 // header. If the ordinal is invalid, this function will return
95 // ZX_ERR_INVALID_ARGS.
96 //
97 // Returns whether the message could be correctly decoded. Upon success, if the
98 // ordinal specifies a message that includes a string, |*data_out| will point to
99 // the string within the |req|, which is of length |*len_out|. The byte after
100 // the string is guaranteed to be zero.
101 //
102 // If the message is not of the correct size or the content of the message fails
103 // validation, this function will return ZX_ERR_INVALID_ARGS.
104 //
105 // Otherwise, this function will return ZX_OK.
106 zx_status_t ldmsg_req_decode(ldmsg_req_t* req, size_t req_len,
107                              const char** data_out, size_t* len_out);
108 
109 // The appropriate size message to send for the given |rsp|.
110 //
111 // The size of the message depends on the ordinal in the message's
112 // header. If the ordinal is invalid, this function will return 0.
113 size_t ldmsg_rsp_get_size(ldmsg_rsp_t* rsp);
114 
115 __END_CDECLS
116