blob: b0b48d5f208d0757d26e9457b13927338befcc7f [file] [log] [blame] [edit]
// Copyright 2022 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 <lib/driver_compat/context.h>
namespace compat {
void Context::ConnectAndCreate(driver::DriverContext* driver_context,
async_dispatcher_t* dispatcher,
fit::callback<void(zx::status<std::unique_ptr<Context>>)> callback) {
auto context = std::make_unique<Context>();
// Connect to our parent.
auto result = component::ConnectAt<fuchsia_driver_compat::Service::Device>(
driver_context->incoming()->svc_dir());
if (result.is_error()) {
return callback(result.take_error());
}
context->parent_device_.Bind(std::move(result.value()), dispatcher);
// Connect to DevfsExporter.
auto endpoints = fidl::CreateEndpoints<fuchsia_io::Directory>();
if (endpoints.is_error()) {
return callback(endpoints.take_error());
}
auto status = driver_context->outgoing()->Serve(std::move(endpoints->server));
if (status.is_error()) {
return callback(status.take_error());
}
auto svc_endpoints = fidl::CreateEndpoints<fuchsia_io::Directory>();
if (svc_endpoints.is_error()) {
return callback(svc_endpoints.take_error());
}
auto response =
fidl::WireCall(endpoints->client)
->Open(fuchsia_io::wire::OpenFlags::kRightReadable |
fuchsia_io::wire::OpenFlags::kRightWritable,
0, "svc/", fidl::ServerEnd<fuchsia_io::Node>(svc_endpoints->server.TakeHandle()));
if (response.status() != ZX_OK) {
return callback(zx::error(response.status()));
}
auto exporter = driver::DevfsExporter::Create(
*driver_context->incoming(), dispatcher,
fidl::WireSharedClient(std::move(svc_endpoints->client), dispatcher));
if (exporter.is_error()) {
return callback(zx::error(exporter.error_value()));
}
context->devfs_exporter_ = std::move(*exporter);
// Get the topological path.
auto context_ptr = context.get();
context_ptr->parent_device_->GetTopologicalPath().Then(
[context = std::move(context), callback = std::move(callback)](auto& result) mutable {
context->parent_topological_path_ = std::move(result->path());
callback(zx::ok(std::move(context)));
});
}
std::string Context::TopologicalPath(std::string_view relative_child_path) const {
std::string path = parent_topological_path_;
path.append("/").append(relative_child_path);
return path;
}
} // namespace compat