| // Copyright 2020 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 <fuchsia/driverhost/test/llcpp/fidl.h> |
| #include <lib/fdio/directory.h> |
| #include <lib/fidl/epitaph.h> |
| #include <lib/service/llcpp/service.h> |
| #include <lib/svc/outgoing.h> |
| |
| #include "src/devices/lib/driver2/record.h" |
| #include "src/devices/lib/driver2/start_args.h" |
| |
| namespace fdf = fuchsia_driver_framework; |
| namespace ftest = fuchsia_driverhost_test; |
| |
| class TestDriver { |
| public: |
| explicit TestDriver(async_dispatcher_t* dispatcher) : outgoing_(dispatcher) {} |
| |
| zx::status<> Init(fdf::wire::DriverStartArgs* start_args) { |
| // Call the "func" driver symbol. |
| auto func = start_args::SymbolValue<void (*)()>(start_args->symbols(), "func"); |
| if (func.is_ok()) { |
| func.value()(); |
| } |
| |
| // Connect to the incoming service. |
| auto svc_dir = start_args::NsValue(start_args->ns(), "/svc"); |
| if (svc_dir.is_error()) { |
| return svc_dir.take_error(); |
| } |
| auto client_end = service::ConnectAt<ftest::Incoming>(svc_dir.value()); |
| if (!client_end.is_ok()) { |
| return client_end.take_error(); |
| } |
| |
| // Setup the outgoing service. |
| zx_status_t status = outgoing_.svc_dir()->AddEntry( |
| ftest::Outgoing::Name, fbl::MakeRefCounted<fs::Service>([](zx::channel request) { |
| return fidl_epitaph_write(request.get(), ZX_ERR_STOP); |
| })); |
| if (status != ZX_OK) { |
| return zx::error(status); |
| } |
| status = outgoing_.Serve(std::move(start_args->outgoing_dir())); |
| return zx::make_status(status); |
| } |
| |
| private: |
| svc::Outgoing outgoing_; |
| }; |
| |
| zx_status_t test_driver_start(fidl_incoming_msg_t* msg, async_dispatcher_t* dispatcher, |
| void** driver) { |
| fdf::wire::DriverStartArgs::DecodedMessage decoded(msg); |
| if (!decoded.ok()) { |
| return decoded.status(); |
| } |
| |
| auto test_driver = new TestDriver(dispatcher); |
| *driver = test_driver; |
| return test_driver->Init(decoded.PrimaryObject()).status_value(); |
| } |
| |
| zx_status_t test_driver_stop(void* driver) { |
| delete static_cast<TestDriver*>(driver); |
| return ZX_OK; |
| } |
| |
| FUCHSIA_DRIVER_RECORD_V1(.start = test_driver_start, .stop = test_driver_stop); |