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 #include <fuchsia/device/manager/c/fidl.h>
6 #include <lib/fidl/cpp/builder.h>
7 #include <lib/fidl/cpp/message.h>
8 #include <lib/fidl/cpp/message_part.h>
9
10 #include "coordinator.h"
11 #include "../shared/log.h"
12
13 namespace devmgr {
14
dh_send_remove_device(const Device * dev)15 zx_status_t dh_send_remove_device(const Device* dev) {
16 FIDL_ALIGNDECL char wr_bytes[sizeof(fuchsia_device_manager_ControllerRemoveDeviceRequest)];
17 fidl::Builder builder(wr_bytes, sizeof(wr_bytes));
18
19 auto req = builder.New<fuchsia_device_manager_ControllerRemoveDeviceRequest>();
20 ZX_ASSERT(req != nullptr);
21 req->hdr.ordinal = fuchsia_device_manager_ControllerRemoveDeviceOrdinal;
22 // TODO(teisenbe): Allocate and track txids
23 req->hdr.txid = 1;
24
25 fidl::Message msg(builder.Finalize(), fidl::HandlePart(nullptr, 0));
26 return msg.Write(dev->hrpc.get(), 0);
27 }
28
dh_send_create_device(Device * dev,Devhost * dh,zx::channel rpc,zx::vmo driver,const char * args,zx::handle rpc_proxy)29 zx_status_t dh_send_create_device(Device* dev, Devhost* dh, zx::channel rpc, zx::vmo driver,
30 const char* args, zx::handle rpc_proxy) {
31 size_t driver_path_size = strlen(dev->libname);
32 size_t args_size = strlen(args);
33 uint32_t wr_num_bytes = static_cast<uint32_t>(
34 sizeof(fuchsia_device_manager_ControllerCreateDeviceRequest) +
35 FIDL_ALIGN(driver_path_size) + FIDL_ALIGN(args_size));
36 FIDL_ALIGNDECL char wr_bytes[wr_num_bytes];
37 fidl::Builder builder(wr_bytes, wr_num_bytes);
38
39 auto req = builder.New<fuchsia_device_manager_ControllerCreateDeviceRequest>();
40 char* driver_path_data = builder.NewArray<char>(static_cast<uint32_t>(driver_path_size));
41 char* args_data = builder.NewArray<char>(static_cast<uint32_t>(args_size));
42 ZX_ASSERT(req != nullptr && driver_path_data != nullptr && args_data != nullptr);
43 req->hdr.ordinal = fuchsia_device_manager_ControllerCreateDeviceOrdinal;
44 // TODO(teisenbe): Allocate and track txids
45 req->hdr.txid = 1;
46
47 req->rpc = FIDL_HANDLE_PRESENT;
48
49 req->driver_path.size = driver_path_size;
50 req->driver_path.data = reinterpret_cast<char*>(FIDL_ALLOC_PRESENT);
51 memcpy(driver_path_data, dev->libname, driver_path_size);
52
53 req->driver = FIDL_HANDLE_PRESENT;
54 req->parent_proxy = rpc_proxy.is_valid() ? FIDL_HANDLE_PRESENT : FIDL_HANDLE_ABSENT;
55
56 req->proxy_args.size = args_size;
57 req->proxy_args.data = reinterpret_cast<char*>(FIDL_ALLOC_PRESENT);
58 memcpy(args_data, args, args_size);
59
60 zx_handle_t handles[3] = { rpc.release(), driver.release() };
61 uint32_t num_handles = 2;
62
63 if (rpc_proxy.is_valid()) {
64 handles[num_handles++] = rpc_proxy.release();
65 }
66
67 fidl::Message msg(builder.Finalize(), fidl::HandlePart(handles, num_handles, num_handles));
68 return msg.Write(dh->hrpc(), 0);
69 }
70
dh_send_create_device_stub(Devhost * dh,zx::channel rpc,uint32_t protocol_id)71 zx_status_t dh_send_create_device_stub(Devhost* dh, zx::channel rpc, uint32_t protocol_id) {
72 FIDL_ALIGNDECL char wr_bytes[sizeof(fuchsia_device_manager_ControllerCreateDeviceStubRequest)];
73 fidl::Builder builder(wr_bytes, sizeof(wr_bytes));
74
75 auto req = builder.New<fuchsia_device_manager_ControllerCreateDeviceStubRequest>();
76 ZX_ASSERT(req != nullptr);
77 req->hdr.ordinal = fuchsia_device_manager_ControllerCreateDeviceStubOrdinal;
78 // TODO(teisenbe): Allocate and track txids
79 req->hdr.txid = 1;
80
81 req->rpc = FIDL_HANDLE_PRESENT;
82 req->protocol_id = protocol_id;
83
84 zx_handle_t handles[] = { rpc.release() };
85 fidl::Message msg(builder.Finalize(),
86 fidl::HandlePart(handles, fbl::count_of(handles), fbl::count_of(handles)));
87 return msg.Write(dh->hrpc(), 0);
88 }
89
dh_send_bind_driver(Device * dev,const char * libname,zx::vmo driver)90 zx_status_t dh_send_bind_driver(Device* dev, const char* libname, zx::vmo driver) {
91 size_t libname_size = strlen(libname);
92 uint32_t wr_num_bytes = static_cast<uint32_t>(
93 sizeof(fuchsia_device_manager_ControllerBindDriverRequest) + FIDL_ALIGN(libname_size));
94 FIDL_ALIGNDECL char wr_bytes[wr_num_bytes];
95 fidl::Builder builder(wr_bytes, wr_num_bytes);
96
97 auto req = builder.New<fuchsia_device_manager_ControllerBindDriverRequest>();
98 char* libname_data = builder.NewArray<char>(static_cast<uint32_t>(libname_size));
99 ZX_ASSERT(req != nullptr && libname_data != nullptr);
100 req->hdr.ordinal = fuchsia_device_manager_ControllerBindDriverOrdinal;
101 // TODO(teisenbe): Allocate and track txids
102 req->hdr.txid = 1;
103
104 req->driver_path.size = libname_size;
105 req->driver_path.data = reinterpret_cast<char*>(FIDL_ALLOC_PRESENT);
106 memcpy(libname_data, libname, libname_size);
107
108 req->driver = FIDL_HANDLE_PRESENT;
109
110 zx_handle_t handles[] = { driver.release() };
111 fidl::Message msg(builder.Finalize(),
112 fidl::HandlePart(handles, fbl::count_of(handles), fbl::count_of(handles)));
113 return msg.Write(dev->hrpc.get(), 0);
114 }
115
dh_send_connect_proxy(const Device * dev,zx::channel proxy)116 zx_status_t dh_send_connect_proxy(const Device* dev, zx::channel proxy) {
117 FIDL_ALIGNDECL char wr_bytes[sizeof(fuchsia_device_manager_ControllerConnectProxyRequest)];
118 fidl::Builder builder(wr_bytes, sizeof(wr_bytes));
119
120 auto req = builder.New<fuchsia_device_manager_ControllerConnectProxyRequest>();
121 ZX_ASSERT(req != nullptr);
122 req->hdr.ordinal = fuchsia_device_manager_ControllerConnectProxyOrdinal;
123 // TODO(teisenbe): Allocate and track txids
124 req->hdr.txid = 1;
125
126 req->shadow = FIDL_HANDLE_PRESENT;
127
128 zx_handle_t handles[] = { proxy.release() };
129 fidl::Message msg(builder.Finalize(),
130 fidl::HandlePart(handles, fbl::count_of(handles), fbl::count_of(handles)));
131 return msg.Write(dev->hrpc.get(), 0);
132 }
133
dh_send_suspend(const Device * dev,uint32_t flags)134 zx_status_t dh_send_suspend(const Device* dev, uint32_t flags) {
135 FIDL_ALIGNDECL char wr_bytes[sizeof(fuchsia_device_manager_ControllerSuspendRequest)];
136 fidl::Builder builder(wr_bytes, sizeof(wr_bytes));
137
138 auto req = builder.New<fuchsia_device_manager_ControllerSuspendRequest>();
139 ZX_ASSERT(req != nullptr);
140 req->hdr.ordinal = fuchsia_device_manager_ControllerSuspendOrdinal;
141 // TODO(teisenbe): Allocate and track txids
142 req->hdr.txid = 1;
143 req->flags = flags;
144
145 fidl::Message msg(builder.Finalize(), fidl::HandlePart(nullptr, 0));
146 return msg.Write(dev->hrpc.get(), 0);
147 }
148
149
150 } // namespace devmgr
151