blob: 3ddc2e7d2344f2cdcc162e6ea5164cac83c600f8 [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 SRC_DEVICES_LIB_DRIVER2_RECORD_CPP_H_
#define SRC_DEVICES_LIB_DRIVER2_RECORD_CPP_H_
#include <fidl/fuchsia.driver.framework/cpp/wire.h>
#include "src/devices/lib/driver2/logger.h"
#include "src/devices/lib/driver2/record.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,
// async_dispatcher_t* dispatcher,
// fidl::WireSharedClient<fuchsia_driver_framework::Node> node,
// driver::Namespace ns,
// driver::Logger logger)
template <typename T>
zx_status_t Start(fidl_incoming_msg_t* msg, async_dispatcher_t* dispatcher, void** driver) {
// Decode the incoming `msg`.
// TODO(fxbug.dev/45252): Use FIDL at rest.
fidl::unstable::DecodedMessage<fuchsia_driver_framework::wire::DriverStartArgs> decoded(
fidl::internal::WireFormatVersion::kV2, 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()),
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, dispatcher, T::Name());
if (logger.is_error()) {
return logger.status_value();
}
// Create the driver.
auto self =
T::Start(*start_args, 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 // SRC_DEVICES_LIB_DRIVER2_RECORD_CPP_H_