| // 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 "../shared/log.h" |
| |
| namespace devmgr { |
| |
| zx_status_t dh_send_remove_device(const Device* dev) { |
| FIDL_ALIGNDECL char wr_bytes[sizeof(fuchsia_device_manager_ControllerRemoveDeviceRequest)]; |
| fidl::Builder builder(wr_bytes, sizeof(wr_bytes)); |
| |
| auto req = builder.New<fuchsia_device_manager_ControllerRemoveDeviceRequest>(); |
| ZX_ASSERT(req != nullptr); |
| req->hdr.ordinal = fuchsia_device_manager_ControllerRemoveDeviceOrdinal; |
| // TODO(teisenbe): Allocate and track txids |
| req->hdr.txid = 1; |
| |
| fidl::Message msg(builder.Finalize(), fidl::HandlePart(nullptr, 0)); |
| return msg.Write(dev->hrpc.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_ControllerCreateDeviceRequest) + |
| 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_ControllerCreateDeviceRequest>(); |
| 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_ControllerCreateDeviceOrdinal; |
| // 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); |
| |
| 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(Devhost* dh, zx::channel rpc, uint32_t protocol_id) { |
| FIDL_ALIGNDECL char wr_bytes[sizeof(fuchsia_device_manager_ControllerCreateDeviceStubRequest)]; |
| fidl::Builder builder(wr_bytes, sizeof(wr_bytes)); |
| |
| auto req = builder.New<fuchsia_device_manager_ControllerCreateDeviceStubRequest>(); |
| ZX_ASSERT(req != nullptr); |
| req->hdr.ordinal = fuchsia_device_manager_ControllerCreateDeviceStubOrdinal; |
| // TODO(teisenbe): Allocate and track txids |
| req->hdr.txid = 1; |
| |
| req->rpc = FIDL_HANDLE_PRESENT; |
| req->protocol_id = protocol_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(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_ControllerBindDriverRequest) + 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_ControllerBindDriverRequest>(); |
| 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_ControllerBindDriverOrdinal; |
| // 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->hrpc.get(), 0); |
| } |
| |
| zx_status_t dh_send_connect_proxy(const Device* dev, zx::channel proxy) { |
| FIDL_ALIGNDECL char wr_bytes[sizeof(fuchsia_device_manager_ControllerConnectProxyRequest)]; |
| fidl::Builder builder(wr_bytes, sizeof(wr_bytes)); |
| |
| auto req = builder.New<fuchsia_device_manager_ControllerConnectProxyRequest>(); |
| ZX_ASSERT(req != nullptr); |
| req->hdr.ordinal = fuchsia_device_manager_ControllerConnectProxyOrdinal; |
| // 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->hrpc.get(), 0); |
| } |
| |
| zx_status_t dh_send_suspend(const Device* dev, uint32_t flags) { |
| FIDL_ALIGNDECL char wr_bytes[sizeof(fuchsia_device_manager_ControllerSuspendRequest)]; |
| fidl::Builder builder(wr_bytes, sizeof(wr_bytes)); |
| |
| auto req = builder.New<fuchsia_device_manager_ControllerSuspendRequest>(); |
| ZX_ASSERT(req != nullptr); |
| req->hdr.ordinal = fuchsia_device_manager_ControllerSuspendOrdinal; |
| // 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->hrpc.get(), 0); |
| } |
| |
| |
| } // namespace devmgr |