blob: 226693151710e0f4a5e0a9606989f8a98821d7c2 [file] [log] [blame]
// Copyright 2021 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.
#ifndef LIB_DRIVER2_RECORD_CPP_H_
#define LIB_DRIVER2_RECORD_CPP_H_
#include <fidl/fuchsia.driver.framework/cpp/wire.h>
#include <lib/driver2/logger.h>
#include <lib/driver2/record.h>
#include <lib/fdf/cpp/dispatcher.h>
namespace driver::internal {
// Starts a driver `T` from `msg` and `dispatcher`, and stores the result in
// `driver`.
//
// This function expects `T` to contain:
// 1. A static function `T::Name` that returns the name to use for the logger.
// 2. A member function `T::Start` with the signature:
// zx::status<std::unique_ptr<T>> Start(
// fuchsia_driver_framework::wire::DriverStartArgs& start_args,
// fdf::UnownedDispatcher dispatcher,
// fidl::WireSharedClient<fuchsia_driver_framework::Node> node,
// driver::Namespace ns,
// driver::Logger logger)
template <typename T>
zx_status_t Start(EncodedDriverStartArgs encoded_start_args, fdf_dispatcher_t* dispatcher,
void** driver) {
// Decode the incoming `msg`.
// TODO(fxbug.dev/45252): Use FIDL at rest.
auto wire_format_metadata =
fidl::WireFormatMetadata::FromOpaque(encoded_start_args.wire_format_metadata);
fidl::unstable::DecodedMessage<fuchsia_driver_framework::wire::DriverStartArgs> decoded(
wire_format_metadata.wire_format_version(), encoded_start_args.msg);
if (!decoded.ok()) {
return decoded.status();
}
auto start_args = decoded.PrimaryObject();
// Bind the node.
fidl::WireSharedClient<fuchsia_driver_framework::Node> node(
std::move(start_args->node()), fdf_dispatcher_get_async_dispatcher(dispatcher));
// Create the namespace.
auto ns = driver::Namespace::Create(start_args->ns());
if (ns.is_error()) {
return ns.status_value();
}
// Create the logger.
auto logger =
driver::Logger::Create(*ns, fdf_dispatcher_get_async_dispatcher(dispatcher), T::Name());
if (logger.is_error()) {
return logger.status_value();
}
// Create the driver.
auto self = T::Start(*start_args, fdf::UnownedDispatcher(dispatcher), std::move(node),
std::move(*ns), std::move(*logger));
if (self.is_error()) {
return self.status_value();
}
// Store `driver` pointer.
*driver = (*self).release();
return ZX_OK;
}
// Stops a driver `T` by deleting it.
template <typename T>
zx_status_t Stop(void* driver) {
delete static_cast<T*>(driver);
return ZX_OK;
}
} // namespace driver::internal
#define FUCHSIA_DRIVER_RECORD_CPP_V1(T) \
FUCHSIA_DRIVER_RECORD_V1(.start = driver::internal::Start<T>, .stop = driver::internal::Stop<T>)
#endif // LIB_DRIVER2_RECORD_CPP_H_