blob: 82c40bf4d6e2f9011869231469f0fd5e04c32c1e [file]
// Copyright 2026 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 <fidl/fuchsia.nodemanager.test/cpp/wire.h>
#include <lib/async/cpp/task.h>
#include <lib/driver/component/cpp/driver_base2.h>
#include <lib/driver/component/cpp/driver_export2.h>
#include <lib/driver/logging/cpp/logger.h>
namespace fdf {
using namespace fuchsia_driver_framework;
} // namespace fdf
namespace ft = fuchsia_nodemanager_test;
namespace {
class LeafDriver : public fdf::DriverBase2 {
public:
LeafDriver() : fdf::DriverBase2("leaf") {}
zx::result<> Start(fdf::DriverContext context) override {
incoming_ = context.take_incoming();
node_ = take_node();
auto result = async::PostTask(dispatcher(), [this]() { RunAsync(); });
if (result == ZX_OK) {
return zx::ok();
}
return zx::error(result);
}
void RunAsync() {
auto connect_result = incoming_->Connect<ft::Waiter>();
if (connect_result.is_error()) {
fdf::error("Failed to start leaf driver: {}", connect_result);
node_.reset();
return;
}
const fidl::WireSharedClient<ft::Waiter> client{std::move(connect_result.value()),
dispatcher()};
auto work_result = DoWork(client);
if (work_result.is_error()) {
fdf::error("DoWork was not successful: {}", work_result);
return;
}
fdf::info("Completed RunAsync successfully.");
}
private:
zx::result<uint32_t> GetNumber(std::string_view instance) {
auto device = incoming_->Connect<ft::Service::Device>(instance);
if (device.status_value() != ZX_OK) {
fdf::warn("Failed to connect to {}: {}", std::string(instance), device);
return device.take_error();
}
auto result = fidl::WireCall(*device)->GetNumber();
if (result.status() != ZX_OK) {
fdf::warn("Failed to call number on {}: {}", std::string(instance),
result.lossy_description());
return zx::error(result.status());
}
return zx::ok(result.value().number);
}
zx::result<> DoWork(const fidl::WireSharedClient<ft::Waiter>& waiter) {
// Check the left device (which is a provided resource).
auto number = GetNumber("left");
if (number.is_error()) {
fdf::error("Failed to get number for left: {}", number.status_string());
[[maybe_unused]] auto result = waiter->Ack(number.error_value());
return number.take_error();
}
if (*number != 1) {
fdf::error("Wrong number for left: expecting 1, saw {}", *number);
[[maybe_unused]] auto result = waiter->Ack(ZX_ERR_INTERNAL);
return zx::ok();
}
// Check the right device (which is a provided resource).
number = GetNumber("right");
if (number.is_error()) {
fdf::error("Failed to get number for right: {}", number.status_string());
[[maybe_unused]] auto result = waiter->Ack(number.error_value());
return number.take_error();
}
if (*number != 2) {
fdf::error("Wrong number for right: expecting 2, saw {}", *number);
[[maybe_unused]] auto result = waiter->Ack(ZX_ERR_INTERNAL);
return zx::ok();
}
// Check the default device (which is the left device).
number = GetNumber("default");
if (number.is_error()) {
[[maybe_unused]] auto result = waiter->Ack(number.error_value());
return zx::ok();
}
if (*number != 1) {
fdf::error("Wrong number for default: expecting 1, saw {}", *number);
[[maybe_unused]] auto result = waiter->Ack(ZX_ERR_INTERNAL);
return zx::ok();
}
[[maybe_unused]] auto result = waiter->Ack(ZX_OK);
return zx::ok();
}
std::unique_ptr<fdf::Namespace> incoming_;
fidl::ClientEnd<fuchsia_driver_framework::Node> node_;
};
} // namespace
FUCHSIA_DRIVER_EXPORT2(LeafDriver);