# Passing metadata between drivers tutorial

This guide explains how to pass metadata from one driver to another using the
[metadata](/sdk/lib/driver/metadata) library. Metadata is any arbitrary data
created by a driver that should be accessible to drivers bound to its child
nodes. Normally, drivers can create their own FIDL protocol in order to pass
metadata, however, the [metadata](/sdk/lib/driver/metadata) library offers
functionality to pass metadata between drivers with less code.

You can find an example of drivers sending, retrieving and forwarding metadata
[here](/examples/drivers/metadata).

## Metadata definition
First, the type of metadata must be defined as a FIDL type and annotated with
`@serializable`:

```
library fuchsia.examples.metadata;

// Type of the metadata to be passed.
// Make sure to annotate it with `@serializable`.
@serializable
type Metadata = table {
    1: test_property string:MAX;
};
```

This metadata will be served in the driver's outgoing namespace using the
[fuchsia.driver.metadata/Service](/sdk/fidl/fuchsia.driver.metadata/fuchsia.driver.metadata.fidl)
FIDL service. The name of the FIDL service within the driver's outgoing
namespace will not be `fuchsia.driver.metadata.Service`. Instead, it will be the
serializable name of the FIDL type. The serializable name is only created if the
FIDL type is annotated with `@serializable`.

The FIDL library's build target will be defined as the following:

```
fidl("fuchsia.examples.metadata") {
  sources = [ "fuchsia.examples.metadata.fidl" ]
}
```

## Sending metadata
### Initial setup
Let's say we have a driver that wants to send metadata to its children:

```cpp
#include <lib/driver/component/cpp/driver_export.h>

class Sender : public fdf::DriverBase {
 public:
  Sender(fdf::DriverStartArgs start_args, fdf::UnownedSynchronizedDispatcher driver_dispatcher)
      : DriverBase("sender", std::move(start_args), std::move(driver_dispatcher)) {}
};

FUCHSIA_DRIVER_EXPORT(Sender);
```

It's component manifest is the following:

```
{
    include: [
        "inspect/client.shard.cml",
        "syslog/client.shard.cml",
    ],
    program: {
        runner: "driver",
        binary: "driver/sender.so",
        bind: "meta/bind/sender.bindbc",
    },
}
```

It's build targets are defined as follows:

```
fuchsia_cc_driver("driver") {
  testonly = true
  output_name = "sender"
  sources = [
    "sender.cc",
  ]
  deps = [
    "//src/devices/lib/driver:driver_runtime",
  ]
}

fuchsia_driver_component("component") {
  testonly = true
  component_name = "sender"
  manifest = "meta/sender.cml"
  deps = [
    ":driver",
    ":bind", # Bind rules not specified in this tutorial.
  ]
  info = "sender.json" # Info not specified in this tutorial.
}
```

### Send process
In order for this driver to send metadata to its child drivers, it will need to
create an instance of the
[fdf_metadata::MetadataServer](/sdk/lib/driver/metadata/cpp/metadata_server.h)
class, call `fdf_metadata::MetadataServer::Serve()` in order to serve the
metadata, and pass the metadata server's offer created by
`fdf_metadata::MetadataServer::CreateOffer()` to the child node:

```cpp
{% verbatim %}
// Defines the fuchsia.examples.metadata types in C++.
#include <fidl/fuchsia.examples.metadata/cpp/fidl.h>

// Defines fdf::MetadataServer.
#include <lib/driver/metadata/cpp/metadata_server.h>

class Sender : public fdf::DriverBase {
 public:
  zx::result<> Start() override {
    // Serve the metadata to the driver's outgoing directory.
    fuchsia_examples_metadata::Metadata metadata({.test_property = "test value"});
    ZX_ASSERT(metadata_server_.Serve(*outgoing(), dispatcher(), metadata).is_ok());

    std::vector<fuchsia_driver_framework::Offer> offers;

    std::optional<fuchsia_driver_framework::Offer> metadata_offer =
      metadata_server.CreateOffer();

    // The metadata server should create an offer because it is serving
    // metadata.
    ZX_ASSERT(metadata_offer.has_value());

    // The metadata server's offer must be provided to the child node.
    offers.push_back(metadata_offer);

    zx::result child = AddChild("child", {}, offers);
    if (child.is_error()) {
      return child.take_error();
    }

    return zx::ok();
  }

 private:
  // Responsible for serving metadata.
  fdf_metadata::MetadataServer<fuchsia_examples_metadata::Metadata> metadata_server_;
};
{% endverbatim %}
```

`fdf_metadata::MetadataServer::Serve()` may be called multiple times and the
metadata server will serve the latest metadata instance.

The `driver` build target will need to be updated to include the metadata
library and the FIDL library that defines the metadata type:

```
fuchsia_cc_driver("driver") {
  testonly = true
  output_name = "sender"
  sources = [
    "sender.cc",
  ]
  deps = [
    "//src/devices/lib/driver:driver_runtime",

    # This should be the fuchsia.examples.metadata FIDL library's C++ target.
    ":fuchsia.examples.metadata_cpp",

    # This library contains `fdf::MetadataServer`.
    "//sdk/lib/driver/metadata/cpp",
  ]
}
```

### Exposing the metadata service
Finally, the driver needs to declare and expose the
`fuchsia.examples.metadata.Metadata` FIDL service in its component manifest:

```
{
    include: [
        "inspect/client.shard.cml",
        "syslog/client.shard.cml",
    ],
    program: {
        runner: "driver",
        binary: "driver/sender.so",
        bind: "meta/bind/sender.bindbc",
    },
    capabilities: [
        { service: "fuchsia.examples.metadata.Metadata" },
    ],
    expose: [
        {
            service: "fuchsia.examples.metadata.Metadata",
            from: "self",
        },
    ],
}
```

Technically, there is no `fuchsia.examples.metadata.Metadata` FIDL service.
Under the hood,
[fdf_metadata::MetadataServer](/sdk/lib/driver/metadata/cpp/metadata_server.h)
serves the
[fuchsia.driver.metadata/Service](/sdk/fidl/fuchsia.driver.metadata/fuchsia.driver.metadata.fidl)
FIDL service in order to send metadata. However,
[fdf_metadata::MetadataServer](/sdk/lib/driver/metadata/cpp/metadata_server.h)
does not serve this service under the name `fuchsia.driver.metadata.Service`
like a normal FIDL service would. Instead, the service is served under the
metadata type's serializable name. In this case that is
`fuchsia.examples.metadata.Metadata`. This name can be found in the C++ field
`fuchsia_examples_metadata::Metadata::kSerializableName`. This allows the
receiving driver to identify which type of metadata is being passed. This means
that the driver needs to declare and expose the
`fuchsia.examples.metadata.Metadata` FIDL service even though that service
doesn't exist.

## Retrieving metadata
### Initial setup
Let's say we have a driver that wants to retrieve metadata from its parent
driver:

```cpp
#include <lib/driver/component/cpp/driver_export.h>

class Retriever : public fdf::DriverBase {
 public:
  Retriever(fdf::DriverStartArgs start_args, fdf::UnownedSynchronizedDispatcher driver_dispatcher)
      : DriverBase("retriever", std::move(start_args), std::move(driver_dispatcher)) {}
};

FUCHSIA_DRIVER_EXPORT(Retriever);
```

It's component manifest is the following:

```
{
    include: [
        "inspect/client.shard.cml",
        "syslog/client.shard.cml",
    ],
    program: {
        runner: "driver",
        binary: "driver/retriever.so",
        bind: "meta/bind/retriever.bindbc",
    },
}
```

It's build targets are defined as follows:

```
fuchsia_cc_driver("driver") {
  testonly = true
  output_name = "retriever"
  sources = [
    "retriever.cc",
  ]
  deps = [
    "//src/devices/lib/driver:driver_runtime",
  ]
}

fuchsia_driver_component("component") {
  testonly = true
  component_name = "retriever"
  manifest = "meta/retriever.cml"
  deps = [
    ":driver",
    ":bind", # Bind rules not specified in this tutorial.
  ]
  info = "retriever.json" # Info not specified in this tutorial.
}
```

### Retrieval process
In order for the driver to retrieve metadata from its parent driver, the driver
needs to call `fdf_metadata::GetMetadata()`:

```cpp
// Defines the fuchsia.examples.metadata types in C++.
#include <fidl/fuchsia.examples.metadata/cpp/fidl.h>

// Defines fdf::GetMetadata().
#include <lib/driver/metadata/cpp/metadata.h>

class Retriever : public fdf::DriverBase {
 public:
  zx::result<> Start() override {
    zx::result<fuchsia_examples_metadata::Metadata> metadata =
      fdf_metadata::GetMetadata<fuchsia_examples_metadata::Metadata>(incoming());
    ZX_ASSERT(!metadata.is_error());

    return zx::ok();
  }
};
```

The `driver` build target will need to be updated to depend on the metadata
library and the FIDL library that defines the metadata type:

```
fuchsia_cc_driver("driver") {
  testonly = true
  output_name = "retriever"
  sources = [
    "retriever.cc",
  ]
  deps = [
    "//src/devices/lib/driver:driver_runtime",

    # This should be the fuchsia.examples.metadata FIDL library's C++ target.
    ":fuchsia.examples.metadata_cpp",

    # This library contains `fdf::GetMetadata()`.
    "//sdk/lib/driver/metadata/cpp",
  ]
}
```

### Using the metadata service
Finally, the driver will need to declare its usage of the
`fuchsia.examples.metadata.Metadata` FIDL service in its component manifest:

```
{
    include: [
        "inspect/client.shard.cml",
        "syslog/client.shard.cml",
    ],
    program: {
        runner: "driver",
        binary: "driver/retriever.so",
        bind: "meta/bind/retriever.bindbc",
    },
    use: [
        { service: "fuchsia.examples.metadata.Metadata" },
    ],
}
```

## Forwarding metadata
### Initial setup
Let's say we have a driver that wants to retrieve metadata from its parent
driver and forward that metadata to its child drivers:

```cpp
#include <lib/driver/component/cpp/driver_export.h>

class Forwarder : public fdf::DriverBase {
 public:
  Forwarder(fdf::DriverStartArgs start_args, fdf::UnownedSynchronizedDispatcher driver_dispatcher)
      : DriverBase("forwarder", std::move(start_args), std::move(driver_dispatcher)) {}
};

FUCHSIA_DRIVER_EXPORT(Forwarder);
```

It's component manifest is the following:

```
{
    include: [
        "inspect/client.shard.cml",
        "syslog/client.shard.cml",
    ],
    program: {
        runner: "driver",
        binary: "driver/forwarder.so",
        bind: "meta/bind/forwarder.bindbc",
    },
}
```

It's build targets are defined as follows:

```
fuchsia_cc_driver("driver") {
  testonly = true
  output_name = "forwarder"
  sources = [
    "forwarder.cc",
  ]
  deps = [
    "//src/devices/lib/driver:driver_runtime",
  ]
}

fuchsia_driver_component("component") {
  testonly = true
  component_name = "forward"
  manifest = "meta/forward.cml"
  deps = [
    ":driver",
    ":bind", # Bind rules not specified in this tutorial.
  ]
  info = "forward.json" # Info not specified in this tutorial.
}
```

### Forward process
In order for the driver to forward metadata from its parent driver to its child
drivers, it will need to create an instance of the
[fdf_metadata::MetadataServer](/sdk/lib/driver/metadata/cpp/metadata_server.h)
class, call `fdf_metadata::MetadataServer::ForwardAndServe()` in order to
retrieve the metadata from its parent and serve it to the driver's outgoing
directory, and pass the metadata server's offer created by
`fdf_metadata::MetadataServer::CreateOffer()` to the child node.

`fdf_metadata::MetadataServer::ForwardAndServe()` will not return an error if it
is unable to retrieve metadata from its parent. Instead, it will return
`zx::ok(false)` and not serve anything.
```cpp
// Defines the fuchsia.examples.metadata types in C++.
#include <fidl/fuchsia.examples.metadata/cpp/fidl.h>

// Defines fdf::MetadataServer.
#include <lib/driver/metadata/cpp/metadata_server.h>

class Forwarder : public fdf::DriverBase {
 public:
  zx::result<> Start() override {
    // Retrieve the metadata from the driver's parent and serve it to the
    // driver's outgoing directory.
    zx::result is_serving = metadata_server_.ForwardAndServe(
      *outgoing(),
      dispatcher(),
      incoming()).is_ok();
    ZX_ASSERT(is_serving.is_ok());

    std::vector<fuchsia_driver_framework::Offer> offers;
    std::optional<fuchsia_driver_framework::Offer> metadata_offer =
      metadata_server_.CreateOffer();

    // The metadata server may not be serving metadata if the driver failed to
    // retrieve it from the driver's parent. In that case, the metadata server
    // will not have an offer.
    if (metadata_offer.has_value()) {
      // The metadata server's offer must be provided to the child node.
      offers.push_back(metadata_offer.value());
    }

    zx::result child = AddChild("child", {}, offers);
    if (child.is_error()) {
      return child.take_error();
    }

    return zx::ok();
  }

 private:
  // Responsible for serving metadata.
  fdf_metadata::MetadataServer<fuchsia_examples_metadata::Metadata> metadata_server_;
};
```

It should be noted that `fdf_metadata::MetadataServer::ForwardAndServe()` does
not check if the parent driver has changed what metadata it provides after
`fdf_metadata::MetadataServer::ForwardAndServe()` has been called. The driver
will have to call `fdf_metadata::MetadataServer::ForwardAndServe()` again in
order to incorporate the change.

The `driver` build target will need to be updated to depend on the metadata
library and FIDL library that defines the metadata type:

```
fuchsia_cc_driver("driver") {
  testonly = true
  output_name = "forwarder"
  sources = [
    "forwarder.cc",
  ]
  deps = [
    "//src/devices/lib/driver:driver_runtime",

    # This should be the fuchsia.examples.metadata FIDL library's C++ target.
    ":fuchsia.examples.metadata_cpp",

    # This library contains `fdf::MetadataServer`.
    "//sdk/lib/driver/metadata/cpp",
  ]
}
```

### Exposing and using the metadata service
Finally, the driver will need to declare, use, and expose the
`fuchsia.examples.metadata.Metadata` FIDL service in its component manifest:

```
{
    include: [
        "inspect/client.shard.cml",
        "syslog/client.shard.cml",
    ],
    program: {
        runner: "driver",
        binary: "driver/forwarder.so",
        bind: "meta/bind/forwarder.bindbc",
    },
    capabilities: [
        { service: "fuchsia.examples.metadata.Metadata" },
    ],
    expose: [
        {
            service: "fuchsia.examples.metadata.Metadata",
            from: "self",
        },
    ],
    use: [
        { service: "fuchsia.examples.metadata.Metadata" },
    ],
}
```
