blob: 3ebb830c1560b33559a3993ec0cb7b86a2a0c380 [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.
#include <fuchsia/device/manager/c/fidl.h>
#include <lib/fidl/cpp/builder.h>
#include <lib/fidl/cpp/message.h>
#include <lib/fidl/cpp/message_part.h>
#include "coordinator.h"
#include "log.h"
namespace devmgr {
zx_status_t dh_send_remove_device(const Device* dev) {
FIDL_ALIGNDECL char wr_bytes[sizeof(fuchsia_device_manager_DeviceControllerRemoveDeviceRequest)];
fidl::Builder builder(wr_bytes, sizeof(wr_bytes));
auto req = builder.New<fuchsia_device_manager_DeviceControllerRemoveDeviceRequest>();
ZX_ASSERT(req != nullptr);
req->hdr.ordinal = fuchsia_device_manager_DeviceControllerRemoveDeviceOrdinal;
// TODO(teisenbe): Allocate and track txids
req->hdr.txid = 1;
fidl::Message msg(builder.Finalize(), fidl::HandlePart(nullptr, 0));
return msg.Write(dev->channel()->get(), 0);
}
zx_status_t dh_send_create_device(Device* dev, Devhost* dh, zx::channel rpc, zx::vmo driver,
const char* args, zx::handle rpc_proxy) {
size_t driver_path_size = dev->libname().size();
size_t args_size = strlen(args);
uint32_t wr_num_bytes =
static_cast<uint32_t>(sizeof(fuchsia_device_manager_DevhostControllerCreateDeviceRequest) +
FIDL_ALIGN(driver_path_size) + FIDL_ALIGN(args_size));
FIDL_ALIGNDECL char wr_bytes[wr_num_bytes];
fidl::Builder builder(wr_bytes, wr_num_bytes);
auto req = builder.New<fuchsia_device_manager_DevhostControllerCreateDeviceRequest>();
char* driver_path_data = builder.NewArray<char>(static_cast<uint32_t>(driver_path_size));
char* args_data = builder.NewArray<char>(static_cast<uint32_t>(args_size));
ZX_ASSERT(req != nullptr && driver_path_data != nullptr && args_data != nullptr);
req->hdr.ordinal = fuchsia_device_manager_DevhostControllerCreateDeviceOrdinal;
// TODO(teisenbe): Allocate and track txids
req->hdr.txid = 1;
req->rpc = FIDL_HANDLE_PRESENT;
req->driver_path.size = driver_path_size;
req->driver_path.data = reinterpret_cast<char*>(FIDL_ALLOC_PRESENT);
memcpy(driver_path_data, dev->libname().data(), driver_path_size);
req->driver = FIDL_HANDLE_PRESENT;
req->parent_proxy = rpc_proxy.is_valid() ? FIDL_HANDLE_PRESENT : FIDL_HANDLE_ABSENT;
req->proxy_args.size = args_size;
req->proxy_args.data = reinterpret_cast<char*>(FIDL_ALLOC_PRESENT);
memcpy(args_data, args, args_size);
req->local_device_id = dev->local_id();
zx_handle_t handles[3] = {rpc.release(), driver.release()};
uint32_t num_handles = 2;
if (rpc_proxy.is_valid()) {
handles[num_handles++] = rpc_proxy.release();
}
fidl::Message msg(builder.Finalize(), fidl::HandlePart(handles, num_handles, num_handles));
return msg.Write(dh->hrpc(), 0);
}
zx_status_t dh_send_create_device_stub(Device* dev, Devhost* dh, zx::channel rpc,
uint32_t protocol_id) {
FIDL_ALIGNDECL char
wr_bytes[sizeof(fuchsia_device_manager_DevhostControllerCreateDeviceStubRequest)];
fidl::Builder builder(wr_bytes, sizeof(wr_bytes));
auto req = builder.New<fuchsia_device_manager_DevhostControllerCreateDeviceStubRequest>();
ZX_ASSERT(req != nullptr);
req->hdr.ordinal = fuchsia_device_manager_DevhostControllerCreateDeviceStubOrdinal;
// TODO(teisenbe): Allocate and track txids
req->hdr.txid = 1;
req->rpc = FIDL_HANDLE_PRESENT;
req->protocol_id = protocol_id;
req->local_device_id = dev->local_id();
zx_handle_t handles[] = {rpc.release()};
fidl::Message msg(builder.Finalize(),
fidl::HandlePart(handles, fbl::count_of(handles), fbl::count_of(handles)));
return msg.Write(dh->hrpc(), 0);
}
zx_status_t dh_send_bind_driver(const Device* dev, const char* libname, zx::vmo driver) {
size_t libname_size = strlen(libname);
uint32_t wr_num_bytes = static_cast<uint32_t>(
sizeof(fuchsia_device_manager_DeviceControllerBindDriverRequest) + FIDL_ALIGN(libname_size));
FIDL_ALIGNDECL char wr_bytes[wr_num_bytes];
fidl::Builder builder(wr_bytes, wr_num_bytes);
auto req = builder.New<fuchsia_device_manager_DeviceControllerBindDriverRequest>();
char* libname_data = builder.NewArray<char>(static_cast<uint32_t>(libname_size));
ZX_ASSERT(req != nullptr && libname_data != nullptr);
req->hdr.ordinal = fuchsia_device_manager_DeviceControllerBindDriverOrdinal;
// TODO(teisenbe): Allocate and track txids
req->hdr.txid = 1;
req->driver_path.size = libname_size;
req->driver_path.data = reinterpret_cast<char*>(FIDL_ALLOC_PRESENT);
memcpy(libname_data, libname, libname_size);
req->driver = FIDL_HANDLE_PRESENT;
zx_handle_t handles[] = {driver.release()};
fidl::Message msg(builder.Finalize(),
fidl::HandlePart(handles, fbl::count_of(handles), fbl::count_of(handles)));
return msg.Write(dev->channel()->get(), 0);
}
zx_status_t dh_send_connect_proxy(const Device* dev, zx::channel proxy) {
FIDL_ALIGNDECL char wr_bytes[sizeof(fuchsia_device_manager_DeviceControllerConnectProxyRequest)];
fidl::Builder builder(wr_bytes, sizeof(wr_bytes));
auto req = builder.New<fuchsia_device_manager_DeviceControllerConnectProxyRequest>();
ZX_ASSERT(req != nullptr);
req->hdr.ordinal = fuchsia_device_manager_DeviceControllerConnectProxyOrdinal;
// TODO(teisenbe): Allocate and track txids
req->hdr.txid = 1;
req->shadow = FIDL_HANDLE_PRESENT;
zx_handle_t handles[] = {proxy.release()};
fidl::Message msg(builder.Finalize(),
fidl::HandlePart(handles, fbl::count_of(handles), fbl::count_of(handles)));
return msg.Write(dev->channel()->get(), 0);
}
zx_status_t dh_send_suspend(const Device* dev, uint32_t flags) {
FIDL_ALIGNDECL char wr_bytes[sizeof(fuchsia_device_manager_DeviceControllerSuspendRequest)];
fidl::Builder builder(wr_bytes, sizeof(wr_bytes));
auto req = builder.New<fuchsia_device_manager_DeviceControllerSuspendRequest>();
ZX_ASSERT(req != nullptr);
req->hdr.ordinal = fuchsia_device_manager_DeviceControllerSuspendOrdinal;
// TODO(teisenbe): Allocate and track txids
req->hdr.txid = 1;
req->flags = flags;
fidl::Message msg(builder.Finalize(), fidl::HandlePart(nullptr, 0));
return msg.Write(dev->channel()->get(), 0);
}
zx_status_t dh_send_resume(const Device* dev, uint32_t target_system_state) {
FIDL_ALIGNDECL char wr_bytes[sizeof(fuchsia_device_manager_DeviceControllerResumeRequest)];
fidl::Builder builder(wr_bytes, sizeof(wr_bytes));
auto req = builder.New<fuchsia_device_manager_DeviceControllerResumeRequest>();
ZX_ASSERT(req != nullptr);
req->hdr.ordinal = fuchsia_device_manager_DeviceControllerResumeOrdinal;
// TODO(teisenbe): Allocate and track txids
req->hdr.txid = 1;
req->target_system_state = target_system_state;
fidl::Message msg(builder.Finalize(), fidl::HandlePart(nullptr, 0));
return msg.Write(dev->channel()->get(), 0);
}
zx_status_t dh_send_complete_compatibility_tests(const Device* dev, zx_status_t status) {
FIDL_ALIGNDECL char
wr_bytes[sizeof(fuchsia_device_manager_DeviceControllerCompleteCompatibilityTestsRequest)];
fidl::Builder builder(wr_bytes, sizeof(wr_bytes));
auto req =
builder.New<fuchsia_device_manager_DeviceControllerCompleteCompatibilityTestsRequest>();
ZX_ASSERT(req != nullptr);
req->hdr.ordinal = fuchsia_device_manager_DeviceControllerCompleteCompatibilityTestsOrdinal;
// TODO(teisenbe): Allocate and track txids
req->hdr.txid = 1;
req->status = status;
fidl::Message msg(builder.Finalize(), fidl::HandlePart(nullptr, 0));
return msg.Write(dev->channel()->get(), 0);
}
zx_status_t dh_send_unbind(const Device* dev) {
FIDL_ALIGNDECL char wr_bytes[sizeof(fuchsia_device_manager_DeviceControllerUnbindRequest)];
fidl::Builder builder(wr_bytes, sizeof(wr_bytes));
auto req = builder.New<fuchsia_device_manager_DeviceControllerUnbindRequest>();
ZX_ASSERT(req != nullptr);
req->hdr.ordinal = fuchsia_device_manager_DeviceControllerUnbindOrdinal;
// TODO(teisenbe): Allocate and track txids
req->hdr.txid = 1;
fidl::Message msg(builder.Finalize(), fidl::HandlePart(nullptr, 0));
return msg.Write(dev->channel()->get(), 0);
}
zx_status_t dh_send_complete_removal(const Device* dev) {
FIDL_ALIGNDECL char
wr_bytes[sizeof(fuchsia_device_manager_DeviceControllerCompleteRemovalRequest)];
fidl::Builder builder(wr_bytes, sizeof(wr_bytes));
auto req = builder.New<fuchsia_device_manager_DeviceControllerCompleteRemovalRequest>();
ZX_ASSERT(req != nullptr);
req->hdr.ordinal = fuchsia_device_manager_DeviceControllerCompleteRemovalOrdinal;
// TODO(teisenbe): Allocate and track txids
req->hdr.txid = 1;
fidl::Message msg(builder.Finalize(), fidl::HandlePart(nullptr, 0));
return msg.Write(dev->channel()->get(), 0);
}
zx_status_t dh_send_create_composite_device(Devhost* dh, const Device* composite_dev,
const CompositeDevice& composite,
const uint64_t* component_local_ids, zx::channel rpc) {
size_t components_size = composite.components_count() * sizeof(uint64_t);
size_t name_size = composite.name().size();
uint32_t wr_num_bytes = static_cast<uint32_t>(
sizeof(fuchsia_device_manager_DevhostControllerCreateCompositeDeviceRequest) +
FIDL_ALIGN(components_size) + FIDL_ALIGN(name_size));
FIDL_ALIGNDECL char wr_bytes[wr_num_bytes];
fidl::Builder builder(wr_bytes, wr_num_bytes);
auto req = builder.New<fuchsia_device_manager_DevhostControllerCreateCompositeDeviceRequest>();
uint64_t* components_data =
builder.NewArray<uint64_t>(static_cast<uint32_t>(composite.components_count()));
char* name_data = builder.NewArray<char>(static_cast<uint32_t>(name_size));
ZX_ASSERT(req != nullptr && components_data != nullptr && name_data != nullptr);
req->hdr.ordinal = fuchsia_device_manager_DevhostControllerCreateCompositeDeviceOrdinal;
// TODO(teisenbe): Allocate and track txids
req->hdr.txid = 1;
req->rpc = FIDL_HANDLE_PRESENT;
req->components.count = composite.components_count();
req->components.data = reinterpret_cast<char*>(FIDL_ALLOC_PRESENT);
memcpy(components_data, component_local_ids, components_size);
req->name.size = name_size;
req->name.data = reinterpret_cast<char*>(FIDL_ALLOC_PRESENT);
memcpy(name_data, composite.name().data(), name_size);
req->local_device_id = composite_dev->local_id();
zx_handle_t handles[1] = {rpc.release()};
uint32_t num_handles = 1;
fidl::Message msg(builder.Finalize(), fidl::HandlePart(handles, num_handles, num_handles));
return msg.Write(dh->hrpc(), 0);
}
} // namespace devmgr