blob: 19fd66dbd252df73f20f49ba68341497aa506c8d [file] [log] [blame]
// Copyright 2022 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 <lib/component/incoming/cpp/directory.h>
#include <lib/component/incoming/cpp/protocol.h>
#include <lib/driver/compat/cpp/service_offers.h>
#include <lib/driver/component/cpp/node_add_args.h>
namespace compat {
std::vector<fuchsia_driver_framework::wire::Offer> ServiceOffersV1::CreateOffers2(
fidl::ArenaBase& arena) {
std::vector<fuchsia_driver_framework::wire::Offer> offers;
for (const auto& service_name : zircon_offers_) {
offers.push_back(fuchsia_driver_framework::wire::Offer::WithZirconTransport(
arena, fdf::MakeOffer(arena, service_name, name_)));
}
for (const auto& service_name : driver_offers_) {
offers.push_back(fuchsia_driver_framework::wire::Offer::WithDriverTransport(
arena, fdf::MakeOffer(arena, service_name, name_)));
}
return offers;
}
std::vector<fuchsia_driver_framework::Offer> ServiceOffersV1::CreateOffers2() {
std::vector<fuchsia_driver_framework::Offer> offers;
for (const auto& service_name : zircon_offers_) {
offers.push_back(
fuchsia_driver_framework::Offer::WithZirconTransport(fdf::MakeOffer(service_name, name_)));
}
for (const auto& service_name : driver_offers_) {
offers.push_back(
fuchsia_driver_framework::Offer::WithDriverTransport(fdf::MakeOffer(service_name, name_)));
}
return offers;
}
zx_status_t ServiceOffersV1::Serve(async_dispatcher_t* dispatcher,
component::OutgoingDirectory* outgoing) {
// Add each service in the device as an service in our outgoing directory.
// We rename each instance from "default" into the child name, and then rename it back to default
// via the offer.
for (const auto& service_name : zircon_offers_) {
const auto instance_path = std::string("svc/").append(service_name).append("/default");
auto client = component::OpenDirectoryAt(dir_, instance_path);
if (client.is_error()) {
return client.status_value();
}
const auto path = std::string("svc/").append(service_name);
auto result = outgoing->AddDirectoryAt(std::move(*client), path, name_);
if (result.is_error()) {
return result.error_value();
}
stop_serving_ = [this, outgoing, path]() { (void)outgoing->RemoveDirectoryAt(path, name_); };
}
for (const auto& service_name : driver_offers_) {
const auto instance_path = std::string("svc/").append(service_name).append("/default");
auto client = component::OpenDirectoryAt(dir_, instance_path);
if (client.is_error()) {
return client.status_value();
}
const auto path = std::string("svc/").append(service_name);
auto result = outgoing->AddDirectoryAt(std::move(*client), path, name_);
if (result.is_error()) {
return result.error_value();
}
stop_serving_ = [this, outgoing, path]() { (void)outgoing->RemoveDirectoryAt(path, name_); };
}
return ZX_OK;
}
zx_status_t ServiceOffersV1::Serve(async_dispatcher_t* dispatcher,
fdf::OutgoingDirectory* outgoing) {
// Add each service in the device as an service in our outgoing directory.
// We rename each instance from "default" into the child name, and then rename it back to default
// via the offer.
for (const auto& service_name : zircon_offers_) {
const auto instance_path = std::string("svc/").append(service_name).append("/default");
auto client = component::OpenDirectoryAt(dir_, instance_path);
if (client.is_error()) {
return client.status_value();
}
const auto path = std::string("svc/").append(service_name);
auto result = outgoing->AddDirectoryAt(std::move(*client), path, name_);
if (result.is_error()) {
return result.error_value();
}
stop_serving_ = [this, outgoing, path]() { (void)outgoing->RemoveDirectoryAt(path, name_); };
}
for (const auto& service_name : driver_offers_) {
const auto instance_path = std::string("svc/").append(service_name).append("/default");
auto client = component::OpenDirectoryAt(dir_, instance_path);
if (client.is_error()) {
return client.status_value();
}
const auto path = std::string("svc/").append(service_name);
auto result = outgoing->AddDirectoryAt(std::move(*client), path, name_);
if (result.is_error()) {
return result.error_value();
}
stop_serving_ = [this, outgoing, path]() { (void)outgoing->RemoveDirectoryAt(path, name_); };
}
return ZX_OK;
}
} // namespace compat