blob: 4e22cb62f23f8a21fd141afc5c95997dc2b53595 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <stdint.h>
#include <zircon/compiler.h>
#include <zircon/fidl.h>
#include <zircon/types.h>
// In principle, this header should be generated by the FIDL compiler, but this
// protocol is used at such a low level (e.g., in userboot and in libc) that we
// have a hand-written implementation available.
__BEGIN_CDECLS
// See system/fidl/fuchsia-ldsvc/ldsvc.fidl for the definition of these message ordinals.
#define LDMSG_OP_DONE 1u
#define LDMSG_OP_LOAD_OBJECT 2u
#define LDMSG_OP_LOAD_SCRIPT_INTERPRETER 3u
#define LDMSG_OP_CONFIG 4u
#define LDMSG_OP_CLONE 5u
#define LDMSG_OP_DEBUG_PUBLISH_DATA_SINK 7u
#define LDMSG_OP_DEBUG_LOAD_CONFIG 8u
// The payload format used for all the requests other than LDMSG_OP_CLONE.
typedef struct ldmsg_common ldmsg_common_t;
struct ldmsg_common {
alignas(FIDL_ALIGNMENT) fidl_string_t string;
alignas(FIDL_ALIGNMENT) zx_handle_t object;
};
// The payload format used for LDMSG_OP_CLONE.
typedef struct ldmsg_clone ldmsg_clone_t;
struct ldmsg_clone {
alignas(FIDL_ALIGNMENT) zx_handle_t object;
};
// The maximum size of a ldmsg_req_t payload.
#define LDMSG_MAX_PAYLOAD (1024 - sizeof(fidl_message_header_t))
// The message format used for requests.
//
// This struct contains 1024 bytes. After the message header, the data varies
// according to the ordinal. The space after the fix-size portion of the message
// is used to contain string data.
//
// The |ldmsg_req_encode| function will encode a message of at most 1023 bytes
// so that a server that uses this struct will always have one byte remaining to
// null-terminate the string data. The client does not necessarily include a
// null terminator.
typedef struct ldmsg_req ldmsg_req_t;
struct ldmsg_req {
fidl_message_header_t header;
union {
ldmsg_common_t common;
ldmsg_clone_t clone;
char data[LDMSG_MAX_PAYLOAD];
};
};
// The message format used for responses.
//
// Depending on the ordinal in the message header, the |object| field might or
// might not be part of the message.
//
// Consider using |ldmsg_rsp_get_size| to determine how much of this structure
// is used for a given ordinal.
typedef struct ldmsg_rsp ldmsg_rsp_t;
struct ldmsg_rsp {
fidl_message_header_t header;
zx_status_t rv;
zx_handle_t object;
};
// Encode the message in |req|.
//
// The format of the message will be determined by the ordinal in the message's
// header. If the ordinal is invalid, this function will return
// ZX_ERR_INVALID_ARGS.
//
// The given |data| will be copied into |*req| at the appropriate location if
// the message format contains a string. If |len| is too large, this function
// will return ZX_ERR_OUT_OF_RANGE.
//
// Otherwise, this function will return ZX_OK.
zx_status_t ldmsg_req_encode(ldmsg_req_t* req, size_t* req_len_out,
const char* data, size_t len);
// Decode the message in |req|.
//
// The format of the message will be determined by the ordinal in the message's
// header. If the ordinal is invalid, this function will return
// ZX_ERR_INVALID_ARGS.
//
// Returns whether the message could be correctly decoded. Upon success, if the
// ordinal specifies a message that includes a string, |*data_out| will point to
// the string within the |req|, which is of length |*len_out|. The byte after
// the string is guaranteed to be zero.
//
// If the message is not of the correct size or the content of the message fails
// validation, this function will return ZX_ERR_INVALID_ARGS.
//
// Otherwise, this function will return ZX_OK.
zx_status_t ldmsg_req_decode(ldmsg_req_t* req, size_t req_len,
const char** data_out, size_t* len_out);
// The appropriate size message to send for the given |rsp|.
//
// The size of the message depends on the ordinal in the message's
// header. If the ordinal is invalid, this function will return 0.
size_t ldmsg_rsp_get_size(ldmsg_rsp_t* rsp);
__END_CDECLS