# FIDL tutorial

Caution: This page may contain information that is specific to the legacy
version of the driver framework (DFv1).

This guide explains how to go about adding exporting a FIDL protocol from a
driver and utilize it in another driver. This guide assumes familiarity with the
following concepts:

*   [FIDL](/docs/development/languages/fidl/README.md)
*   [Driver Binding](/docs/development/drivers/concepts/device_driver_model/driver-binding.md)
*   [DDKTL](/docs/development/drivers/concepts/driver_development/using-ddktl.md)
*   [New C++ FIDL Bindings](/docs/development/languages/fidl/tutorials/cpp/README.md)

## FIDL Protocol Definition

The following snippets will utilize this FIDL protocol:

```
library fidl.examples.echo;

const MAX_STRING_LENGTH uint64 = 32;

// The discoverable annotation is required, otherwise the protocol bindings
// will not have a name string generated.
@discoverable
protocol Echo {
    /// Returns the input.
    EchoString(struct {
        value string:<MAX_STRING_LENGTH, optional>;
    }) -> (struct {
        response string:<MAX_STRING_LENGTH, optional>;
    });
};

service EchoService {
    echo client_end:Echo;
};
```

## Parent Driver (The Server)

We approximate here how a parent driver which implements the protocol being
called into would be written. Although not shown, we assume this class is
utilizing the DDKTL.

```
// This class implement the fuchsia.examples.echo/Echo FIDL protocol using the
// new C++ FIDL bindings
class Device : public fidl::WireServer<fidl_examples_echo::Echo> {

  // This is the main entry point for the driver.
  static zx_status_t Bind(void* ctx, zx_device_t* parent) {
    // When creating the device, we initialize it with a dispatcher provided by
    // the driver framework. This dispatcher is allows us to schedule
    // asynchronous work on the same thread as other drivers. You may opt to
    // create your own dispatcher which is serviced on a thread you spawn if you
    // desire instead.
    auto* dispatcher = fdf::Dispatcher::GetCurrent()->async_dispatcher();
    auto device = std::make_unique<Device>(parent, dispatcher);

    // We add the FIDL protocol we wish to export to our child to our outgoing
    // directory. When a connection is attempted we will bind the server end of
    // the channel pair to our server implementation.
    zx::result = device->outgoing_.AddService<fidl_examples_echo::EchoService>(
        fidl_examples_echo::EchoService::InstanceHandler({
            .echo = device->bindings_.CreateHandler(device.get(), dispatcher,
                                                    fidl::kIgnoreBindingClosure),
            }));

    // Utilizing the server end of the endpoint pair we created above, we bind
    // it to our outgoing directory.
    result = device->outgoing_.Serve(std::move(endpoints->server));
    if (result.is_error()) {
      zxlogf(ERROR, "Failed to service the outgoing directory");
      return result.status_value();
    }

    // We declare our outgoing protocols here. These will be utilize to
    // help the framework populate node properties which can be used for
    // binding.
    std::array offers = {
        fidl_examples_echo::Service::Name,
    };

    status = device->DdkAdd(ddk::DeviceAddArgs("parent")
                                // The device must be spawned in a separate
                                // driver host.
                                .set_flags(DEVICE_ADD_MUST_ISOLATE)
                                .set_fidl_service_offers(offers)
                                // The client side of outgoing directory is
                                // provided to the framework. This will be
                                // forwarded to the new driver host that spawns to
                                // allow the child driver which binds the ability
                                // to connect to our outgoing FIDL protocols.
                                .set_outgoing_dir(endpoints->client.TakeChannel()));
    if (status == ZX_OK) {
      [[maybe_unused]] auto ptr = device.release();
    } else {
      zxlogf(ERROR, "Failed to add device");
    }

    return status;
  }

 private:
  // This is the implementation of the only method our FIDL protocol requires.
  void EchoString(EchoStringRequestView request, EchoStringCompleter::Sync& completer) override {
    completer.Reply(request->value);
  }

  // This is a helper class which we use to serve the outgoing directory.
  component::OutgoingDirectory outgoing_;
  // This ensures that the fidl connections don't outlive the device object.
  fidl::ServerBindingGroup<fidl_examples_echo::Echo> bindings_;
};
```

## Child Driver (The Client)

### Binding

The first important thing to discuss is how the child driver will bind. It can
bind due to any number of node properties, but if you wish to bind based
solely on the FIDL protocol the parent exports, you will need the bind library
that the build automatically generates for you from the FIDL library
(For more information, see [Generated bind libraries](#generated-bind-libraries)).

You will depend on and use this bind library in your driver's bind rules:

```
using fidl.examples.echo;

fidl.examples.echo.Echo == fidl.examples.echo.Echo.ZirconTransport;
```

ZirconTransport is the transport method that the parent driver uses to
provide the Echo FIDL protocol to the child.

You can addition additional bind constraints if you desire. Note that the
property which we describe here is only added if the parent driver declares
their FIDL protocol offers at the time of adding the device.

### Client Code

The follow code snippet would be found in a child driver which has successfully
bound to the parent driver described above.

```
zx_status_t CallEcho() {
  // The following method allows us to connect to the protocol we desire. This
  // works by providing the server end of our endpoint pair to the framework. It
  // will push this channel through the outgoing directory to our parent driver
  // which will then bind it to its server implementation. We do  not need to
  // name the protocol because the method is templated on the  channel type and
  // it is able to automatically derive the name from the type.
  zx::result client_end = DdkConnectFidlProtocol<fidl_examples_echo::EchoService::Echo>();
  if (client_end.is_error()) {
    zxlogf(ERROR, "Failed to connect fidl protocol: %s", client_end.status_string());
    return client_end.status_value();
  }

  // We turn the client side of the endpoint pair into a synchronous client.
  fidl::WireSyncClient client{std::move(client_end.value())};

  // We can now utilize our client to make calls!
  constexpr std::string_view kInput = "Test String";

  auto result = client->EchoString(fidl::StringView::FromExternal(std::string_view(kInput)));
  if (!result.ok()) {
    zxlogf(ERROR, "Failed to call EchoString");
    return result.status();
  }
  if (result->response.get() != kInput) {
    zxlogf(ERROR, "Unexpected response: Actual: \"%.*s\", Expected: \"%.*s\"",
           static_cast<int>(result->response.size()), result->response.data(),
           static_cast<int>(kInput.size()), kInput.data());
    return ZX_ERR_INTERNAL;
  }

  return ZX_OK;
}
```

## Generated bind libraries {:#generated-bind-libraries}

All FIDL libraries get an auto-generated bind library created from them. This is to help driver
authors create bind rules based on FIDL protocols and services provided by the parent, and the
transport method the parent uses to provide each one.

### The bind library

There are three possible transport methods put in these bind libraries: `Banjo`, `ZirconTransport`,
and `DriverTransport`. Currently it is safe to assume the value is either `ZirconTransport`
(which is just regular FIDL over Zircon channels), or `DriverTransport`
(which is an in-process communication stack for co-located drivers).
The bind library contains constants for protocols and these transport methods.

Each service and discoverable protocol defined in the FIDL library gets an enum in the
bind library with the values of the enum being the three transport methods.

Here is an example of one where the FIDL library contains a single discoverable protocol:

#### protocol.fidl {:#protocol-fidl}

```fidl {:.devsite-disable-click-to-copy}
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/drivers/bind/fidl_bindlib_codegen/protocol.fidl" region_tag="fidl" %}
```

#### Generated lib {:#generated-lib}

```none {:.devsite-disable-click-to-copy}
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/drivers/bind/fidl_bindlib_codegen/generated_lib.bind.golden" %}
```

### The build target

These generated bind libraries will be based on the FIDL library's
`library_name` and `target_name`. The bind library will have a target name of
`{fidl_target_name}_bindlib`, and its `library_name` will be the same as the FIDL's.

For example, if the FIDL library target is `//sdk/fidl/fidl.examples.echo:myecholibrary`,
then the auto-generated bind library target is
`//sdk/fidl/fidl.examples.echo:myecholibrary_bindlib`.

In practice, most FIDL libraries have the same `target_name` as the folder they are in, which
is usually the library name as well. So for example, if the FIDL library is
`//sdk/fidl/fidl.examples.echo`, the auto-generated bind library target is
`//sdk/fidl/fidl.examples.echo:fidl.examples.echo_bindlib`.

### The generated code targets

These generated bind libraries work exactly the same as if they were user-written
bind libraries. Code generation for user-written bind libraries is described in detail at
[Bind library code generation tutorial](/docs/development/drivers/tutorials/bind-libraries-codegen.md).

### Example

Lets take the FIDL library shown [above](#protocol-fidl) and use it in an example.


#### FIDL (BUILD.gn)

```gn {:.devsite-disable-click-to-copy}
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/drivers/bind/fidl_bindlib_codegen/BUILD.gn" region_tag="fidl" %}
```

This now gives us the generated bind library with the target name of `:my_fidl_target_bindlib`
and library name of `fuchsia.gizmo.protocol`. The generated source for the bind library was shown
[earlier](#generated-lib). We can use this to create bind rules for the child driver.

#### Child bind rules (BUILD.gn)

```gn {:.devsite-disable-click-to-copy}
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/drivers/bind/fidl_bindlib_codegen/BUILD.gn" region_tag="child_bind_rules" %}
```

#### child-driver.bind

```none {:.devsite-disable-click-to-copy}
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/drivers/bind/fidl_bindlib_codegen/meta/child_driver.bind" exclude_regexp="// Copyright.*|// Use of.*|// found in.*" %}
```

When a driver is creating children nodes, they are automatically assigned a property for each of
their `offers` in the `fuchsia_driver_framework::NodeAddArgs` table. Therefore parent drivers
don't need to manually specify this property.

For example if there is a driver transport based service capability offered to the node
called `fuchsia_hardware_gizmo::Service`, there will be a property added with the key
`fuchsia.hardware.gizmo.Service` and value of `fuchsia.hardware.gizmo.Service.DriverTransport`.
These values will match their corresponding generated bind library variables that the child driver
would use in its bind rules.

This generated code is still useful when creating a composite node specification,
which usually happens in the board driver. The specification's properties must be filled out
manually with the offer information if the specification wants to match with nodes based on those
offers.

We can use the auto-generated code targets to access constants for this bind library from
the composite node spec creation code.

#### composite-node-specification creator (BUILD.gn)

* {C++}

  ```gn {:.devsite-disable-click-to-copy}
  {% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/drivers/bind/fidl_bindlib_codegen/BUILD.gn" region_tag="example_cpp_target" %}
  ```

* {Rust}

  ```gn {:.devsite-disable-click-to-copy}
  {% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/drivers/bind/fidl_bindlib_codegen/BUILD.gn" region_tag="example_rust_target" %}
  ```



#### composite-node-specification creator code

* {C++}

  ```cpp {:.devsite-disable-click-to-copy}
  {% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/drivers/bind/fidl_bindlib_codegen/bindlib_usage.cc" region_tag="code" %}
  ```

* {Rust}

  ```rust {:.devsite-disable-click-to-copy}
  {% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/drivers/bind/fidl_bindlib_codegen/bindlib_usage.rs" region_tag="code" %}
  ```
