Revert "[fidl][netsvc] Port netsvc to typed channels."

This reverts commit 7a7a0868cb416d490a8018d9fc9e712cab871af4.

Original commit breaks paving of astro devices

BUG=b/185111728, b/185135062

Change-Id: Ib5a768dbf83f61d042d86f65db592e13c2b5ce73
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/514648
Reviewed-by: Suraj Malhotra <surajmalhotra@google.com>
Reviewed-by: James Robinson <jamesr@google.com>
Commit-Queue: Tom Robinson <robinsontom@google.com>
diff --git a/build/cpp/BUILD.gn b/build/cpp/BUILD.gn
index de3c542..03e4784 100644
--- a/build/cpp/BUILD.gn
+++ b/build/cpp/BUILD.gn
@@ -29,6 +29,11 @@
     "//src/bringup/bin/device-name-provider:device-name-provider",
     "//src/bringup/bin/device-name-provider/tests:device-name-provider-test",
     "//src/bringup/bin/device-name-provider/tests:integration-test",
+    "//src/bringup/bin/netsvc:args",
+    "//src/bringup/bin/netsvc:netsvc",
+    "//src/bringup/bin/netsvc:netsvc-stress-test",
+    "//src/bringup/bin/netsvc:netsvc-test",
+    "//src/bringup/bin/netsvc:netsvc_common",
     "//src/bringup/bin/pwrbtn-monitor:pwrbtn-monitor",
     "//src/bringup/bin/svchost:crashsvc",
     "//src/bringup/bin/svchost:crashsvc-test",
diff --git a/src/bringup/bin/netsvc/BUILD.gn b/src/bringup/bin/netsvc/BUILD.gn
index f48e751..6a80636 100644
--- a/src/bringup/bin/netsvc/BUILD.gn
+++ b/src/bringup/bin/netsvc/BUILD.gn
@@ -55,13 +55,17 @@
     "//zircon/public/lib/zx",
     "//zircon/system/ulib/fdio-caller",
     "//zircon/system/ulib/inet6",
-    "//zircon/system/ulib/service:service-llcpp",
   ]
   data_deps = [
     # netsvc launches /boot/bin/sh for netruncmd.
     "//zircon/third_party/uapp/dash",
   ]
   configs += [ ":netsvc_config" ]
+
+  # TODO(fxbug.dev/69585): This target uses raw zx::channel with LLCPP which is deprecated.
+  # Please migrate to typed channel APIs (fidl::ClientEnd<T>, fidl::ServerEnd<T>).
+  # See linked bug for details.
+  configs += [ "//build/cpp:fidl-llcpp-deprecated-raw-channels" ]
 }
 
 source_set("args") {
@@ -69,9 +73,13 @@
   deps = [
     "//sdk/fidl/fuchsia.boot:fuchsia.boot_llcpp",
     "//sdk/lib/fdio",
-    "//zircon/system/ulib/service:service-llcpp",
     "//zircon/system/ulib/zx",
   ]
+
+  # TODO(fxbug.dev/69585): This target uses raw zx::channel with LLCPP which is deprecated.
+  # Please migrate to typed channel APIs (fidl::ClientEnd<T>, fidl::ServerEnd<T>).
+  # See linked bug for details.
+  configs += [ "//build/cpp:fidl-llcpp-deprecated-raw-channels" ]
 }
 
 source_set("netsvc_common") {
@@ -102,7 +110,6 @@
     "//zircon/system/ulib/async-loop:async-loop-default",
     "//zircon/system/ulib/fdio-caller",
     "//zircon/system/ulib/fidl-async:fidl-async-cpp",
-    "//zircon/system/ulib/service:service-llcpp",
     "//zircon/system/ulib/sysconfig-client:sysconfig-sync-client",
     "//zircon/system/ulib/zbitl",
   ]
@@ -118,6 +125,11 @@
 
   # TODO(fxbug.dev/58162): delete the below and fix compiler warnings
   configs += [ "//build/config:Wno-conversion" ]
+
+  # TODO(fxbug.dev/69585): This target uses raw zx::channel with LLCPP which is deprecated.
+  # Please migrate to typed channel APIs (fidl::ClientEnd<T>, fidl::ServerEnd<T>).
+  # See linked bug for details.
+  configs += [ "//build/cpp:fidl-llcpp-deprecated-raw-channels" ]
 }
 
 test("netsvc-test") {
@@ -142,16 +154,19 @@
     "//zircon/system/ulib/async-loop:async-loop-default",
     "//zircon/system/ulib/devmgr-integration-test",
     "//zircon/system/ulib/driver-integration-test",
-    "//zircon/system/ulib/fdio-caller",
     "//zircon/system/ulib/fidl-async:fidl-async-cpp",
     "//zircon/system/ulib/mock-boot-arguments",
     "//zircon/system/ulib/ramdevice-client",
-    "//zircon/system/ulib/service:service-llcpp",
     "//zircon/system/ulib/zircon-internal",
   ]
 
   # TODO(fxbug.dev/58162): delete the below and fix compiler warnings
   configs += [ "//build/config:Wno-conversion" ]
+
+  # TODO(fxbug.dev/69585): This target uses raw zx::channel with LLCPP which is deprecated.
+  # Please migrate to typed channel APIs (fidl::ClientEnd<T>, fidl::ServerEnd<T>).
+  # See linked bug for details.
+  configs += [ "//build/cpp:fidl-llcpp-deprecated-raw-channels" ]
 }
 
 test("netsvc-stress-test") {
@@ -167,15 +182,18 @@
     "//zircon/system/ulib/async-loop:async-loop-cpp",
     "//zircon/system/ulib/devmgr-integration-test",
     "//zircon/system/ulib/driver-integration-test",
-    "//zircon/system/ulib/fdio-caller",
     "//zircon/system/ulib/fidl-async:fidl-async-cpp",
     "//zircon/system/ulib/ramdevice-client",
-    "//zircon/system/ulib/service:service-llcpp",
     "//zircon/system/ulib/zircon-internal",
   ]
 
   # TODO(fxbug.dev/58162): delete the below and fix compiler warnings
   configs += [ "//build/config:Wno-conversion" ]
+
+  # TODO(fxbug.dev/69585): This target uses raw zx::channel with LLCPP which is deprecated.
+  # Please migrate to typed channel APIs (fidl::ClientEnd<T>, fidl::ServerEnd<T>).
+  # See linked bug for details.
+  configs += [ "//build/cpp:fidl-llcpp-deprecated-raw-channels" ]
 }
 
 isolated_devmgr_unittest_component("netsvc-stress-test-component") {
diff --git a/src/bringup/bin/netsvc/args.cc b/src/bringup/bin/netsvc/args.cc
index 2c93e5f..059fb06 100644
--- a/src/bringup/bin/netsvc/args.cc
+++ b/src/bringup/bin/netsvc/args.cc
@@ -5,10 +5,7 @@
 #include "args.h"
 
 #include <fuchsia/boot/llcpp/fidl.h>
-#include <fuchsia/io/llcpp/fidl.h>
 #include <lib/fdio/directory.h>
-#include <lib/fidl/llcpp/client_end.h>
-#include <lib/service/llcpp/service.h>
 #include <stdlib.h>
 
 #include <cstring>
@@ -32,18 +29,26 @@
 }
 }  // namespace
 
-int ParseArgs(int argc, char** argv, fidl::UnownedClientEnd<fuchsia_io::Directory> svc_root,
-              const char** error, NetsvcArgs* out) {
+int ParseArgs(int argc, char** argv, const zx::channel& svc_root, const char** error,
+              NetsvcArgs* out) {
   // Reset the args.
   *out = NetsvcArgs();
 
-  auto client_end = service::ConnectAt<fuchsia_boot::Arguments>(svc_root);
-  if (client_end.is_error()) {
+  // First parse from kernel args, then use use cmdline args as overrides.
+  zx::channel local, remote;
+  zx_status_t status = zx::channel::create(0, &local, &remote);
+  if (status != ZX_OK) {
+    *error = "netsvc: unable to create channel";
+    return -1;
+  }
+
+  status = fdio_service_connect_at(svc_root.get(), fuchsia_boot::Arguments::Name, remote.release());
+  if (status != ZX_OK) {
     *error = "netsvc: unable to connect to fuchsia.boot.Arguments";
     return -1;
   }
 
-  fidl::WireSyncClient<fuchsia_boot::Arguments> client(std::move(*client_end));
+  fidl::WireSyncClient<fuchsia_boot::Arguments> client(std::move(local));
   auto string_resp = client.GetString(fidl::StringView{"netsvc.interface"});
   if (string_resp.ok()) {
     auto& value = string_resp->value;
diff --git a/src/bringup/bin/netsvc/args.h b/src/bringup/bin/netsvc/args.h
index 2fffe90..9999396 100644
--- a/src/bringup/bin/netsvc/args.h
+++ b/src/bringup/bin/netsvc/args.h
@@ -5,7 +5,6 @@
 #ifndef SRC_BRINGUP_BIN_NETSVC_ARGS_H_
 #define SRC_BRINGUP_BIN_NETSVC_ARGS_H_
 
-#include <fuchsia/io/llcpp/fidl.h>
 #include <lib/zx/channel.h>
 
 #include <string>
@@ -31,7 +30,7 @@
 
 // Parses NetsvcArgs via the kernel commandline and the binary commandline (argv).
 // If ParseArgs returns < 0, an error string will be returned in |error|.
-int ParseArgs(int argc, char** argv, fidl::UnownedClientEnd<fuchsia_io::Directory> svc_root,
-              const char** error, NetsvcArgs* out);
+int ParseArgs(int argc, char** argv, const zx::channel& svc_root, const char** error,
+              NetsvcArgs* out);
 
 #endif  // SRC_BRINGUP_BIN_NETSVC_ARGS_H_
diff --git a/src/bringup/bin/netsvc/board-info.cc b/src/bringup/bin/netsvc/board-info.cc
index 5024b24..a6acda1 100644
--- a/src/bringup/bin/netsvc/board-info.cc
+++ b/src/bringup/bin/netsvc/board-info.cc
@@ -34,9 +34,9 @@
 
 namespace {
 
-[[maybe_unused]] static bool IsChromebook(
-    fidl::UnownedClientEnd<fuchsia_sysinfo::SysInfo> sysinfo) {
-  auto result = fidl::WireCall(sysinfo).GetBootloaderVendor();
+[[maybe_unused]] static bool IsChromebook(const zx::channel& sysinfo) {
+  auto result =
+      fidl::WireCall<fuchsia_sysinfo::SysInfo>(zx::unowned(sysinfo)).GetBootloaderVendor();
   zx_status_t status = result.ok() ? result->status : result.status();
   if (status != ZX_OK) {
     return status;
@@ -44,9 +44,8 @@
   return strncmp(result->vendor.data(), "coreboot", result->vendor.size()) == 0;
 }
 
-zx_status_t GetBoardName(fidl::UnownedClientEnd<fuchsia_sysinfo::SysInfo> sysinfo,
-                         char* real_board_name) {
-  auto result = fidl::WireCall(sysinfo).GetBoardName();
+zx_status_t GetBoardName(const zx::channel& sysinfo, char* real_board_name) {
+  auto result = fidl::WireCall<fuchsia_sysinfo::SysInfo>(zx::unowned(sysinfo)).GetBoardName();
   if (!result.ok()) {
     return false;
   }
@@ -74,9 +73,8 @@
   return ZX_OK;
 }
 
-zx_status_t GetBoardRevision(fidl::UnownedClientEnd<fuchsia_sysinfo::SysInfo> sysinfo,
-                             uint32_t* board_revision) {
-  auto result = fidl::WireCall(sysinfo).GetBoardRevision();
+zx_status_t GetBoardRevision(const zx::channel& sysinfo, uint32_t* board_revision) {
+  auto result = fidl::WireCall<fuchsia_sysinfo::SysInfo>(zx::unowned(sysinfo)).GetBoardRevision();
   if (!result.ok()) {
     return false;
   }
@@ -90,8 +88,7 @@
 
 }  // namespace
 
-bool CheckBoardName(fidl::UnownedClientEnd<fuchsia_sysinfo::SysInfo> sysinfo, const char* name,
-                    size_t length) {
+bool CheckBoardName(const zx::channel& sysinfo, const char* name, size_t length) {
   if (!sysinfo) {
     return false;
   }
@@ -105,8 +102,7 @@
   return strncmp(real_board_name, name, length) == 0;
 }
 
-bool ReadBoardInfo(fidl::UnownedClientEnd<fuchsia_sysinfo::SysInfo> sysinfo, void* data,
-                   off_t offset, size_t* length) {
+bool ReadBoardInfo(const zx::channel& sysinfo, void* data, off_t offset, size_t* length) {
   if (!sysinfo) {
     return false;
   }
diff --git a/src/bringup/bin/netsvc/board-info.h b/src/bringup/bin/netsvc/board-info.h
index 3adf494..acd9589 100644
--- a/src/bringup/bin/netsvc/board-info.h
+++ b/src/bringup/bin/netsvc/board-info.h
@@ -5,15 +5,12 @@
 #ifndef SRC_BRINGUP_BIN_NETSVC_BOARD_INFO_H_
 #define SRC_BRINGUP_BIN_NETSVC_BOARD_INFO_H_
 
-#include <fuchsia/sysinfo/llcpp/fidl.h>
 #include <lib/zx/channel.h>
 #include <unistd.h>
 
-bool CheckBoardName(fidl::UnownedClientEnd<fuchsia_sysinfo::SysInfo> sysinfo, const char* name,
-                    size_t length);
+bool CheckBoardName(const zx::channel& sysinfo, const char* name, size_t length);
 
-bool ReadBoardInfo(fidl::UnownedClientEnd<fuchsia_sysinfo::SysInfo> sysinfo, void* data,
-                   off_t offset, size_t* length);
+bool ReadBoardInfo(const zx::channel& sysinfo, void* data, off_t offset, size_t* length);
 
 size_t BoardInfoSize();
 
diff --git a/src/bringup/bin/netsvc/debuglog.cc b/src/bringup/bin/netsvc/debuglog.cc
index 0f1219e..dad0ad9 100644
--- a/src/bringup/bin/netsvc/debuglog.cc
+++ b/src/bringup/bin/netsvc/debuglog.cc
@@ -8,7 +8,6 @@
 #include <inttypes.h>
 #include <lib/fdio/directory.h>
 #include <lib/fdio/fdio.h>
-#include <lib/service/llcpp/service.h>
 #include <lib/zx/clock.h>
 #include <lib/zx/debuglog.h>
 #include <stdio.h>
@@ -70,12 +69,16 @@
 }
 
 int debuglog_init() {
-  auto client_end = service::Connect<fuchsia_boot::ReadOnlyLog>();
-  if (client_end.is_error()) {
-    return client_end.error_value();
+  zx::channel local, remote;
+  zx_status_t status = zx::channel::create(0, &local, &remote);
+  if (status != ZX_OK) {
+    return status;
   }
-
-  fidl::WireSyncClient<fuchsia_boot::ReadOnlyLog> read_only_log(std::move(*client_end));
+  status = fdio_service_connect("/svc/fuchsia.boot.ReadOnlyLog", remote.release());
+  if (status != ZX_OK) {
+    return status;
+  }
+  fidl::WireSyncClient<fuchsia_boot::ReadOnlyLog> read_only_log(std::move(local));
   auto result = read_only_log.Get();
   if (result.status() != ZX_OK) {
     return result.status();
diff --git a/src/bringup/bin/netsvc/file-api.cc b/src/bringup/bin/netsvc/file-api.cc
index 46af6e0..91ee9b0 100644
--- a/src/bringup/bin/netsvc/file-api.cc
+++ b/src/bringup/bin/netsvc/file-api.cc
@@ -7,7 +7,6 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <lib/fdio/fdio.h>
-#include <lib/service/llcpp/service.h>
 #include <stdio.h>
 #include <zircon/boot/netboot.h>
 
@@ -24,8 +23,8 @@
 
 }  // namespace
 
-FileApi::FileApi(bool is_zedboot, std::unique_ptr<NetCopyInterface> netcp,
-                 fidl::UnownedClientEnd<fuchsia_sysinfo::SysInfo> sysinfo, PaverInterface* paver)
+FileApi::FileApi(bool is_zedboot, std::unique_ptr<NetCopyInterface> netcp, zx::channel sysinfo,
+                 PaverInterface* paver)
     : is_zedboot_(is_zedboot),
       sysinfo_(std::move(sysinfo)),
       netcp_(std::move(netcp)),
@@ -33,9 +32,10 @@
   ZX_ASSERT(paver_ != nullptr);
 
   if (!sysinfo_) {
-    auto sysinfo = service::Connect<fuchsia_sysinfo::SysInfo>("/dev/sys/platform");
-    if (sysinfo.is_ok()) {
-      sysinfo_ = std::move(*sysinfo);
+    constexpr char kSysInfoPath[] = "/dev/sys/platform";
+    fbl::unique_fd sysinfo_fd(open(kSysInfoPath, O_RDWR));
+    if (sysinfo_fd) {
+      fdio_get_service_handle(sysinfo_fd.release(), sysinfo_.reset_and_get_address());
     }
   }
 }
diff --git a/src/bringup/bin/netsvc/file-api.h b/src/bringup/bin/netsvc/file-api.h
index c8d21ebf..7d3384af 100644
--- a/src/bringup/bin/netsvc/file-api.h
+++ b/src/bringup/bin/netsvc/file-api.h
@@ -5,7 +5,6 @@
 #ifndef SRC_BRINGUP_BIN_NETSVC_FILE_API_H_
 #define SRC_BRINGUP_BIN_NETSVC_FILE_API_H_
 
-#include <fuchsia/sysinfo/llcpp/fidl.h>
 #include <zircon/boot/netboot.h>
 
 #include <tftp/tftp.h>
@@ -46,9 +45,7 @@
   // FileApi does *not* take ownership of |paver|.
   explicit FileApi(bool is_zedboot,
                    std::unique_ptr<NetCopyInterface> netcp = std::make_unique<NetCopy>(),
-                   fidl::UnownedClientEnd<fuchsia_sysinfo::SysInfo> sysinfo =
-                       fidl::UnownedClientEnd<fuchsia_sysinfo::SysInfo>({}),
-                   PaverInterface* paver = Paver::Get());
+                   zx::channel sysinfo = zx::channel(), PaverInterface* paver = Paver::Get());
 
   ssize_t OpenRead(const char* filename) final;
   tftp_status OpenWrite(const char* filename, size_t size) final;
@@ -80,7 +77,7 @@
   NetfileType type_ = NetfileType::kUnknown;
 
   // Use when type_ == NetfileType::kBoardName.
-  fidl::UnownedClientEnd<fuchsia_sysinfo::SysInfo> sysinfo_;
+  zx::channel sysinfo_;
 
   // Used when type_ == NetfileType::kNetCopy.
   std::unique_ptr<NetCopyInterface> netcp_;
diff --git a/src/bringup/bin/netsvc/netboot.cc b/src/bringup/bin/netsvc/netboot.cc
index ef37973..6f29c7e 100644
--- a/src/bringup/bin/netsvc/netboot.cc
+++ b/src/bringup/bin/netsvc/netboot.cc
@@ -13,7 +13,6 @@
 #include <lib/fdio/directory.h>
 #include <lib/fdio/fd.h>
 #include <lib/fdio/fdio.h>
-#include <lib/service/llcpp/service.h>
 #include <lib/zx/vmo.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -60,12 +59,29 @@
 
 namespace {
 
-bool GetMexecResource(zx::resource* resource) {
-  auto root_resource = service::Connect<fuchsia_boot::RootResource>();
-  if (root_resource.is_error()) {
+bool ConnectToService(const char* service, zx::channel& channel) {
+  zx::channel remote;
+  if (zx_status_t status = zx::channel::create(0, &channel, &remote); status != ZX_OK) {
+    printf("failed to create a channel: %s\n", zx_status_get_string(status));
     return false;
   }
-  if (auto result = WireCall(*root_resource).Get(); !result.ok()) {
+  std::string svc = "/svc/" + std::string(service);
+  if (zx_status_t status = fdio_service_connect(svc.c_str(), remote.release()); status != ZX_OK) {
+    printf("failed to connect to %s: %s\n", service, zx_status_get_string(status));
+    return false;
+  }
+  return true;
+};
+
+bool GetMexecResource(zx::resource* resource) {
+  using Resource = fuchsia_boot::RootResource;
+
+  zx::channel local;
+  if (!ConnectToService(Resource::Name, local)) {
+    return false;
+  }
+  fidl::WireSyncClient<Resource> client(std::move(local));
+  if (auto result = client.Get(); !result.ok()) {
     printf("failed to get root resource %s\n", result.status_string());
     return false;
   } else {
@@ -284,12 +300,12 @@
   if (!GetMexecResource(&resource)) {
     return ZX_ERR_INTERNAL;
   }
-  auto devmgr = service::Connect<fuchsia_device_manager::Administrator>();
-  if (devmgr.is_error()) {
+  zx::channel devmgr_channel;
+  if (!ConnectToService(fuchsia_device_manager::Administrator::Name, devmgr_channel)) {
     return ZX_ERR_INTERNAL;
   }
 
-  status = mexec::Boot(std::move(resource), std::move(*devmgr).TakeChannel(), std::move(kernel_zbi),
+  status = mexec::Boot(std::move(resource), std::move(devmgr_channel), std::move(kernel_zbi),
                        std::move(data_zbi));
   if (status != ZX_OK) {
     return ZX_ERR_INTERNAL;
@@ -303,12 +319,12 @@
 static zx_status_t reboot() {
   namespace statecontrol = fuchsia_hardware_power_statecontrol;
 
-  auto admin = service::Connect<statecontrol::Admin>();
-  if (admin.is_error()) {
+  zx::channel local;
+  if (!ConnectToService(statecontrol::Admin::Name, local)) {
     return ZX_ERR_INTERNAL;
   }
-
-  auto response = WireCall(*admin).Reboot(statecontrol::wire::RebootReason::USER_REQUEST);
+  auto response = fidl::WireCall<statecontrol::Admin>(local.borrow())
+                      .Reboot(statecontrol::wire::RebootReason::USER_REQUEST);
   if (response.status() != ZX_OK) {
     return response.status();
   }
diff --git a/src/bringup/bin/netsvc/netsvc.cc b/src/bringup/bin/netsvc/netsvc.cc
index 10bd8ac..6bfd6d5 100644
--- a/src/bringup/bin/netsvc/netsvc.cc
+++ b/src/bringup/bin/netsvc/netsvc.cc
@@ -103,7 +103,7 @@
 
   NetsvcArgs args;
   const char* error;
-  if (ParseArgs(argc, argv, caller.directory(), &error, &args) < 0) {
+  if (ParseArgs(argc, argv, *caller.channel(), &error, &args) < 0) {
     printf("netsvc: fatal error: %s\n", error);
     return -1;
   };
diff --git a/src/bringup/bin/netsvc/paver.cc b/src/bringup/bin/netsvc/paver.cc
index 7de1071..f76b475 100644
--- a/src/bringup/bin/netsvc/paver.cc
+++ b/src/bringup/bin/netsvc/paver.cc
@@ -5,15 +5,10 @@
 #include "paver.h"
 
 #include <fcntl.h>
-#include <fuchsia/paver/llcpp/fidl.h>
 #include <lib/async-loop/cpp/loop.h>
 #include <lib/async-loop/default.h>
-#include <lib/async-loop/loop.h>
-#include <lib/fdio/cpp/caller.h>
 #include <lib/fdio/directory.h>
-#include <lib/fidl/llcpp/connect_service.h>
 #include <lib/fit/defer.h>
-#include <lib/service/llcpp/service.h>
 #include <lib/sysconfig/sync-client.h>
 #include <lib/zx/clock.h>
 #include <stdio.h>
@@ -25,6 +20,8 @@
 #include <string>
 #include <string_view>
 
+#include "lib/async-loop/loop.h"
+#include "lib/fdio/cpp/caller.h"
 #include "payload-streamer.h"
 #include "zircon/errors.h"
 
@@ -33,16 +30,21 @@
 Paver* Paver::Get() {
   static Paver* instance_ = nullptr;
   if (instance_ == nullptr) {
-    auto svc_root = service::Connect<fuchsia_io::Directory>("/svc");
-    if (svc_root.is_error()) {
+    zx::channel local, remote;
+    auto status = zx::channel::create(0, &local, &remote);
+    if (status != ZX_OK) {
       return nullptr;
     }
-    auto devfs_root = service::Connect<fuchsia_io::Directory>("/dev");
-    if (devfs_root.is_error()) {
+    status = fdio_service_connect("/svc", remote.release());
+    if (status != ZX_OK) {
+      return nullptr;
+    }
+    fbl::unique_fd devfs_root(open("/dev", O_RDONLY));
+    if (!devfs_root) {
       return nullptr;
     }
 
-    instance_ = new Paver(std::move(*svc_root), std::move(*devfs_root));
+    instance_ = new Paver(std::move(local), std::move(devfs_root));
   }
   return instance_;
 }
@@ -120,34 +122,38 @@
     in_progress_.store(false);
   });
 
-  auto endpoints = fidl::CreateEndpoints<fuchsia_paver::DataSink>();
-  if (endpoints.is_error()) {
+  zx::channel data_sink, remote;
+  auto status = zx::channel::create(0, &data_sink, &remote);
+  if (status != ZX_OK) {
     fprintf(stderr, "netsvc: unable to create channel\n");
-    exit_code_.store(endpoints.status_value());
+    exit_code_.store(status);
     return 0;
   }
 
-  auto res = paver_svc_->FindDataSink(std::move(endpoints->server));
-  if (res.status() != ZX_OK) {
+  auto res = paver_svc_->FindDataSink(std::move(remote));
+  status = res.status();
+  if (status != ZX_OK) {
     fprintf(stderr, "netsvc: unable to find data sink\n");
-    exit_code_.store(res.status());
+    exit_code_.store(status);
     return 0;
   }
 
-  auto payload = fidl::CreateEndpoints<fuchsia_paver::PayloadStream>();
-  if (payload.is_error()) {
+  zx::channel client, server;
+  status = zx::channel::create(0, &client, &server);
+  if (status != ZX_OK) {
     fprintf(stderr, "netsvc: unable to create channel\n");
-    exit_code_.store(payload.error_value());
+    exit_code_.store(status);
     return 0;
   }
 
   async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
-  PayloadStreamer streamer(std::move(payload->server), std::move(callback));
+  PayloadStreamer streamer(std::move(server), std::move(callback));
   loop.StartThread("payload-streamer");
 
   // Blocks until paving is complete.
-  auto res2 = fidl::WireCall(endpoints->client).WriteVolumes(std::move(payload->client));
-  auto status = res2.status() == ZX_OK ? res2.value().status : res2.status();
+  auto res2 = fidl::WireCall<fuchsia_paver::DataSink>(zx::unowned(data_sink))
+                  .WriteVolumes(std::move(client));
+  status = res2.status() == ZX_OK ? res2.value().status : res2.status();
 
   exit_code_.store(status);
   return 0;
@@ -179,21 +185,23 @@
 
 zx_status_t Paver::WriteABImage(fidl::WireSyncClient<fuchsia_paver::DataSink> data_sink,
                                 fuchsia_mem::wire::Buffer buffer) {
-  auto endpoints = fidl::CreateEndpoints<fuchsia_paver::BootManager>();
-  if (endpoints.is_error()) {
+  zx::channel boot_manager_chan, remote;
+  auto status = zx::channel::create(0, &boot_manager_chan, &remote);
+  if (status != ZX_OK) {
     fprintf(stderr, "netsvc: unable to create channel\n");
-    exit_code_.store(endpoints.error_value());
+    exit_code_.store(status);
     return 0;
   }
 
-  auto res = paver_svc_->FindBootManager(std::move(endpoints->server));
-  if (res.status() != ZX_OK) {
+  auto res2 = paver_svc_->FindBootManager(std::move(remote));
+  status = res2.status();
+  if (status != ZX_OK) {
     fprintf(stderr, "netsvc: unable to find boot manager\n");
-    exit_code_.store(res.status());
+    exit_code_.store(status);
     return 0;
   }
   std::optional<fidl::WireSyncClient<fuchsia_paver::BootManager>> boot_manager;
-  boot_manager.emplace(std::move(endpoints->client));
+  boot_manager.emplace(std::move(boot_manager_chan));
 
   // First find out whether or not ABR is supported.
   {
@@ -290,19 +298,19 @@
 }
 
 zx_status_t Paver::ClearSysconfig() {
-  auto endpoints = fidl::CreateEndpoints<fuchsia_paver::Sysconfig>();
-  if (endpoints.is_error()) {
+  zx::channel sysconfig_local, sysconfig_remote;
+  if (auto status = zx::channel::create(0, &sysconfig_local, &sysconfig_remote); status != ZX_OK) {
     fprintf(stderr, "netsvc: unable to create channel\n");
-    return endpoints.error_value();
+    return status;
   }
 
-  auto status_find_sysconfig = paver_svc_->FindSysconfig(std::move(endpoints->server));
+  auto status_find_sysconfig = paver_svc_->FindSysconfig(std::move(sysconfig_remote));
   if (status_find_sysconfig.status() != ZX_OK) {
     fprintf(stderr, "netsvc: unable to find sysconfig\n");
     return status_find_sysconfig.status();
   }
 
-  fidl::WireSyncClient<fuchsia_paver::Sysconfig> client(std::move(endpoints->client));
+  fidl::WireSyncClient<fuchsia_paver::Sysconfig> client(std::move(sysconfig_local));
 
   auto wipe_result = client.Wipe();
   auto wipe_status =
@@ -348,28 +356,37 @@
     return ZX_ERR_INVALID_ARGS;
   }
 
-  auto block_dev = service::ConnectAt<fuchsia_hardware_block::Block>(
-      devfs_root_, &partition_info.block_device_path[5]);
+  zx::channel block_dev_chan, remote;
+  status = zx::channel::create(0, &block_dev_chan, &remote);
+  if (status != ZX_OK) {
+    fprintf(stderr, "netsvc: unable to create channel\n");
+    return status;
+  }
 
-  if (block_dev.is_error()) {
+  fdio_cpp::UnownedFdioCaller caller(devfs_root_.get());
+
+  status = fdio_service_connect_at(caller.borrow_channel(), &partition_info.block_device_path[5],
+                                   remote.release());
+  if (status != ZX_OK) {
     fprintf(stderr, "netsvc: Unable to open %s.\n", partition_info.block_device_path);
-    return block_dev.error_value();
+    return status;
   }
 
-  auto endpoints = fidl::CreateEndpoints<fuchsia_paver::DynamicDataSink>();
-  if (endpoints.is_error()) {
+  zx::channel data_sink_chan;
+  status = zx::channel::create(0, &data_sink_chan, &remote);
+  if (status != ZX_OK) {
     fprintf(stderr, "netsvc: unable to create channel.\n");
-    return endpoints.error_value();
+    return status;
   }
 
-  auto res = paver_svc_->UseBlockDevice(std::move(*block_dev), std::move(endpoints->server));
+  auto res = paver_svc_->UseBlockDevice(std::move(block_dev_chan), std::move(remote));
   status = res.status();
   if (status != ZX_OK) {
     fprintf(stderr, "netsvc: unable to use block device.\n");
     return status;
   }
 
-  data_sink->emplace(std::move(endpoints->client));
+  data_sink->emplace(std::move(data_sink_chan));
   return ZX_OK;
 }
 
@@ -467,21 +484,22 @@
       break;
   };
 
-  auto endpoints = fidl::CreateEndpoints<fuchsia_paver::DataSink>();
-  if (endpoints.is_error()) {
+  zx::channel remote, data_sink_chan;
+  status = zx::channel::create(0, &data_sink_chan, &remote);
+  if (status != ZX_OK) {
     fprintf(stderr, "netsvc: unable to create channel\n");
     exit_code_.store(status);
     return 0;
   }
 
-  auto res = paver_svc_->FindDataSink(std::move(endpoints->server));
+  auto res = paver_svc_->FindDataSink(std::move(remote));
   status = res.status();
   if (status != ZX_OK) {
     fprintf(stderr, "netsvc: unable to find data sink\n");
     exit_code_.store(status);
     return 0;
   }
-  auto data_sink = fidl::BindSyncClient(std::move(endpoints->client));
+  fidl::WireSyncClient<fuchsia_paver::DataSink> data_sink(std::move(data_sink_chan));
 
   // Blocks until paving is complete.
   switch (command_) {
@@ -640,13 +658,20 @@
   }
   auto buffer_cleanup = fit::defer([this]() { buffer_mapper_.Reset(); });
 
-  auto paver = service::ConnectAt<fuchsia_paver::Paver>(svc_root_);
-  if (paver.is_error()) {
+  zx::channel paver_local, paver_remote;
+  status = zx::channel::create(0, &paver_local, &paver_remote);
+  if (status != ZX_OK) {
+    fprintf(stderr, "netsvc: Unable to create channel pair.\n");
+    return TFTP_ERR_IO;
+  }
+  status =
+      fdio_service_connect_at(svc_root_.get(), fuchsia_paver::Paver::Name, paver_remote.release());
+  if (status != ZX_OK) {
     fprintf(stderr, "netsvc: Unable to open /svc/%s.\n", fuchsia_paver::Paver::Name);
     return TFTP_ERR_IO;
   }
 
-  paver_svc_.emplace(std::move(*paver));
+  paver_svc_.emplace(std::move(paver_local));
   auto svc_cleanup = fit::defer([&]() { paver_svc_.reset(); });
 
   size_ = size;
diff --git a/src/bringup/bin/netsvc/paver.h b/src/bringup/bin/netsvc/paver.h
index e56ebd0..d910a10 100644
--- a/src/bringup/bin/netsvc/paver.h
+++ b/src/bringup/bin/netsvc/paver.h
@@ -5,9 +5,7 @@
 #ifndef SRC_BRINGUP_BIN_NETSVC_PAVER_H_
 #define SRC_BRINGUP_BIN_NETSVC_PAVER_H_
 
-#include <fuchsia/io/llcpp/fidl.h>
 #include <fuchsia/paver/llcpp/fidl.h>
-#include <lib/fidl/llcpp/client_end.h>
 #include <lib/fzl/resizeable-vmo-mapper.h>
 #include <lib/sync/completion.h>
 #include <lib/zx/channel.h>
@@ -55,8 +53,7 @@
   void Close() final;
 
   // Visible for testing.
-  explicit Paver(fidl::ClientEnd<fuchsia_io::Directory> svc_root,
-                 fidl::ClientEnd<fuchsia_io::Directory> devfs_root)
+  explicit Paver(zx::channel svc_root, fbl::unique_fd devfs_root)
       : svc_root_(std::move(svc_root)), devfs_root_(std::move(devfs_root)) {}
 
   void set_timeout(zx::duration timeout) { timeout_ = timeout; }
@@ -106,10 +103,10 @@
   Command command_;
 
   // Channel to svc.
-  fidl::ClientEnd<fuchsia_io::Directory> svc_root_;
+  zx::channel svc_root_;
 
-  // Channel to dev.
-  fidl::ClientEnd<fuchsia_io::Directory> devfs_root_;
+  // File descriptor to dev.
+  fbl::unique_fd devfs_root_;
 
   std::optional<fidl::WireSyncClient<fuchsia_paver::Paver>> paver_svc_;
 
diff --git a/src/bringup/bin/netsvc/payload-streamer.cc b/src/bringup/bin/netsvc/payload-streamer.cc
index 6d3c735..35b1380 100644
--- a/src/bringup/bin/netsvc/payload-streamer.cc
+++ b/src/bringup/bin/netsvc/payload-streamer.cc
@@ -11,8 +11,7 @@
 
 namespace netsvc {
 
-PayloadStreamer::PayloadStreamer(fidl::ServerEnd<fuchsia_paver::PayloadStream> chan,
-                                 ReadCallback callback)
+PayloadStreamer::PayloadStreamer(zx::channel chan, ReadCallback callback)
     : read_(std::move(callback)) {
   fidl::BindSingleInFlightOnly(async_get_default_dispatcher(), std::move(chan), this);
 }
diff --git a/src/bringup/bin/netsvc/payload-streamer.h b/src/bringup/bin/netsvc/payload-streamer.h
index abb98e5..eb730b8e 100644
--- a/src/bringup/bin/netsvc/payload-streamer.h
+++ b/src/bringup/bin/netsvc/payload-streamer.h
@@ -22,7 +22,7 @@
 
 class PayloadStreamer : public fidl::WireInterface<fuchsia_paver::PayloadStream> {
  public:
-  PayloadStreamer(fidl::ServerEnd<fuchsia_paver::PayloadStream> chan, ReadCallback callback);
+  PayloadStreamer(zx::channel chan, ReadCallback callback);
 
   PayloadStreamer(const PayloadStreamer&) = delete;
   PayloadStreamer& operator=(const PayloadStreamer&) = delete;
diff --git a/src/bringup/bin/netsvc/test/args-test.cc b/src/bringup/bin/netsvc/test/args-test.cc
index d432d7e..ff3b958 100644
--- a/src/bringup/bin/netsvc/test/args-test.cc
+++ b/src/bringup/bin/netsvc/test/args-test.cc
@@ -5,7 +5,6 @@
 #include "src/bringup/bin/netsvc/args.h"
 
 #include <fuchsia/boot/llcpp/fidl.h>
-#include <fuchsia/io/llcpp/fidl.h>
 #include <lib/async-loop/cpp/loop.h>
 #include <lib/async-loop/default.h>
 #include <lib/async/dispatcher.h>
@@ -52,20 +51,20 @@
                              return ZX_OK;
                            }));
 
-    auto svc_remote = fidl::CreateEndpoints(&svc_local_);
-    ASSERT_OK(svc_remote.status_value());
+    zx::channel svc_remote;
+    ASSERT_OK(zx::channel::create(0, &svc_local_, &svc_remote));
 
-    vfs_.ServeDirectory(root_dir, std::move(*svc_remote));
+    vfs_.ServeDirectory(root_dir, std::move(svc_remote));
   }
 
   mock_boot_arguments::Server& mock_boot() { return mock_boot_; }
-  fidl::UnownedClientEnd<fuchsia_io::Directory> svc() { return svc_local_; }
+  zx::channel& svc_chan() { return svc_local_; }
 
  private:
   async_dispatcher_t* dispatcher_;
   fs::SynchronousVfs vfs_;
   mock_boot_arguments::Server mock_boot_;
-  fidl::ClientEnd<fuchsia_io::Directory> svc_local_;
+  zx::channel svc_local_;
 };
 
 class ArgsTest : public zxtest::Test {
@@ -77,7 +76,7 @@
   ~ArgsTest() { loop_.Shutdown(); }
 
   FakeSvc& fake_svc() { return fake_svc_; }
-  fidl::UnownedClientEnd<fuchsia_io::Directory> svc_root() { return fake_svc_.svc(); }
+  const zx::channel& svc_root() { return fake_svc_.svc_chan(); }
 
  private:
   async::Loop loop_;
diff --git a/src/bringup/bin/netsvc/test/file-api-test.cc b/src/bringup/bin/netsvc/test/file-api-test.cc
index 469587e..b0875d8 100644
--- a/src/bringup/bin/netsvc/test/file-api-test.cc
+++ b/src/bringup/bin/netsvc/test/file-api-test.cc
@@ -69,9 +69,9 @@
 class FakeSysinfo : public fidl::WireInterface<fuchsia_sysinfo::SysInfo> {
  public:
   FakeSysinfo(async_dispatcher_t* dispatcher) {
-    auto remote = fidl::CreateEndpoints(&svc_chan_);
-    ASSERT_OK(remote.status_value());
-    fidl::BindSingleInFlightOnly(dispatcher, std::move(*remote), this);
+    zx::channel remote;
+    ASSERT_OK(zx::channel::create(0, &remote, &svc_chan_));
+    fidl::BindSingleInFlightOnly(dispatcher, std::move(remote), this);
   }
 
   void GetBoardName(GetBoardNameCompleter::Sync& completer) {
@@ -88,13 +88,13 @@
     completer.Reply(ZX_ERR_NOT_SUPPORTED, nullptr);
   }
 
-  fidl::UnownedClientEnd<fuchsia_sysinfo::SysInfo> svc() { return svc_chan_; }
+  zx::channel& svc_chan() { return svc_chan_; }
 
   void set_board_name(const char* board) { strlcpy(board_, board, sizeof(board_)); }
   void set_bootloader_vendor(const char* vendor) { strlcpy(vendor_, vendor, sizeof(vendor_)); }
 
  private:
-  fidl::ClientEnd<fuchsia_sysinfo::SysInfo> svc_chan_;
+  zx::channel svc_chan_;
 
   char board_[32] = {};
   char vendor_[32] = {};
@@ -107,7 +107,8 @@
   FileApiTest()
       : loop_(&kAsyncLoopConfigNoAttachToCurrentThread),
         fake_sysinfo_(loop_.dispatcher()),
-        file_api_(true, std::make_unique<FakeNetCopy>(), fake_sysinfo_.svc(), &fake_paver_) {
+        file_api_(true, std::make_unique<FakeNetCopy>(), std::move(fake_sysinfo_.svc_chan()),
+                  &fake_paver_) {
     loop_.StartThread("file-api-test-loop");
   }
 
diff --git a/src/bringup/bin/netsvc/test/paver-test-common.h b/src/bringup/bin/netsvc/test/paver-test-common.h
index 1f85ae4..43dbaa2 100644
--- a/src/bringup/bin/netsvc/test/paver-test-common.h
+++ b/src/bringup/bin/netsvc/test/paver-test-common.h
@@ -5,17 +5,12 @@
 #define SRC_BRINGUP_BIN_NETSVC_TEST_PAVER_TEST_COMMON_H_
 
 #include <fuchsia/device/llcpp/fidl.h>
-#include <fuchsia/io/llcpp/fidl.h>
 #include <fuchsia/paver/llcpp/fidl.h>
 #include <lib/async-loop/cpp/loop.h>
 #include <lib/async-loop/default.h>
 #include <lib/async/dispatcher.h>
 #include <lib/driver-integration-test/fixture.h>
-#include <lib/fdio/cpp/caller.h>
 #include <lib/fidl-async/cpp/bind.h>
-#include <lib/fidl/llcpp/client_end.h>
-#include <lib/fidl/llcpp/connect_service.h>
-#include <lib/service/llcpp/service.h>
 #include <lib/sync/completion.h>
 #include <lib/zircon-internal/thread_annotations.h>
 #include <lib/zx/channel.h>
@@ -84,29 +79,25 @@
         },
 };
 
-class FakePaver : public fidl::WireInterface<fuchsia_paver::Paver>,
+class FakePaver : public fidl::WireRawChannelInterface<fuchsia_paver::Paver>,
                   public fidl::WireInterface<fuchsia_paver::BootManager>,
-                  public fidl::WireInterface<fuchsia_paver::DynamicDataSink> {
+                  public fidl::WireRawChannelInterface<fuchsia_paver::DynamicDataSink> {
  public:
-  zx_status_t Connect(async_dispatcher_t* dispatcher,
-                      fidl::ServerEnd<fuchsia_paver::Paver> request) {
+  zx_status_t Connect(async_dispatcher_t* dispatcher, zx::channel request) {
     dispatcher_ = dispatcher;
-    return fidl::BindSingleInFlightOnly<fidl::WireInterface<fuchsia_paver::Paver>>(
+    return fidl::BindSingleInFlightOnly<fidl::WireRawChannelInterface<fuchsia_paver::Paver>>(
         dispatcher, std::move(request), this);
   }
 
-  void FindDataSink(fidl::ServerEnd<fuchsia_paver::DataSink> data_sink,
-                    FindDataSinkCompleter::Sync& _completer) override {
-    fidl::BindSingleInFlightOnly<fidl::WireInterface<fuchsia_paver::DynamicDataSink>>(
-        dispatcher_, fidl::ServerEnd<fuchsia_paver::DynamicDataSink>(data_sink.TakeChannel()),
-        this);
+  void FindDataSink(zx::channel data_sink, FindDataSinkCompleter::Sync& _completer) override {
+    fidl::BindSingleInFlightOnly<fidl::WireRawChannelInterface<fuchsia_paver::DynamicDataSink>>(
+        dispatcher_, std::move(data_sink), this);
   }
 
-  void UseBlockDevice(fidl::ClientEnd<fuchsia_hardware_block::Block> block_device,
-                      fidl::ServerEnd<fuchsia_paver::DynamicDataSink> dynamic_data_sink,
+  void UseBlockDevice(zx::channel block_device, zx::channel dynamic_data_sink,
                       UseBlockDeviceCompleter::Sync& _completer) override {
-    fidl::UnownedClientEnd<fuchsia_device::Controller> controller(block_device.borrow().channel());
-    auto result = WireCall(controller).GetTopologicalPath();
+    auto result =
+        fidl::WireCall<fuchsia_device::Controller>(zx::unowned(block_device)).GetTopologicalPath();
     if (!result.ok() || result->result.is_err()) {
       return;
     }
@@ -117,11 +108,11 @@
         return;
       }
     }
-    fidl::BindSingleInFlightOnly<fidl::WireInterface<fuchsia_paver::DynamicDataSink>>(
+    fidl::BindSingleInFlightOnly<fidl::WireRawChannelInterface<fuchsia_paver::DynamicDataSink>>(
         dispatcher_, std::move(dynamic_data_sink), this);
   }
 
-  void FindBootManager(fidl::ServerEnd<fuchsia_paver::BootManager> boot_manager,
+  void FindBootManager(zx::channel boot_manager,
                        FindBootManagerCompleter::Sync& _completer) override {
     fbl::AutoLock al(&lock_);
     AppendCommand(Command::kInitializeAbr);
@@ -137,8 +128,7 @@
     completer.ReplySuccess(fuchsia_paver::wire::Configuration::A);
   }
 
-  void FindSysconfig(fidl::ServerEnd<fuchsia_paver::Sysconfig> sysconfig,
-                     FindSysconfigCompleter::Sync& _completer) override {}
+  void FindSysconfig(zx::channel sysconfig, FindSysconfigCompleter::Sync& _completer) override {}
 
   void QueryActiveConfiguration(QueryActiveConfigurationCompleter::Sync& completer) override {
     fbl::AutoLock al(&lock_);
@@ -208,8 +198,8 @@
     completer.Reply(ZX_OK);
   }
 
-  void Flush(fidl::WireInterface<fuchsia_paver::DynamicDataSink>::FlushCompleter::Sync& completer)
-      override {
+  void Flush(fidl::WireRawChannelInterface<fuchsia_paver::DynamicDataSink>::FlushCompleter::Sync&
+                 completer) override {
     fbl::AutoLock al(&lock_);
     AppendCommand(Command::kDataSinkFlush);
     completer.Reply(ZX_OK);
@@ -258,8 +248,7 @@
     }
   }
 
-  void WriteVolumes(fidl::ClientEnd<fuchsia_paver::PayloadStream> payload_stream,
-                    WriteVolumesCompleter::Sync& completer) override {
+  void WriteVolumes(zx::channel payload_stream, WriteVolumesCompleter::Sync& completer) override {
     {
       fbl::AutoLock al(&lock_);
       AppendCommand(Command::kWriteVolumes);
@@ -413,25 +402,25 @@
  public:
   explicit FakeSvc(async_dispatcher_t* dispatcher) : dispatcher_(dispatcher), vfs_(dispatcher) {
     auto root_dir = fbl::MakeRefCounted<fs::PseudoDir>();
-    root_dir->AddEntry(
-        fuchsia_paver::Paver::Name,
-        fbl::MakeRefCounted<fs::Service>([this](fidl::ServerEnd<fuchsia_paver::Paver> request) {
-          return fake_paver_.Connect(dispatcher_, std::move(request));
-        }));
+    root_dir->AddEntry(fuchsia_paver::Paver::Name,
+                       fbl::MakeRefCounted<fs::Service>([this](zx::channel request) {
+                         return fake_paver_.Connect(dispatcher_, std::move(request));
+                       }));
 
-    auto server_end = fidl::CreateEndpoints(&svc_local_);
-    ASSERT_OK(server_end.status_value());
-    vfs_.ServeDirectory(root_dir, std::move(*server_end));
+    zx::channel svc_remote;
+    ASSERT_OK(zx::channel::create(0, &svc_local_, &svc_remote));
+
+    vfs_.ServeDirectory(root_dir, std::move(svc_remote));
   }
 
   FakePaver& fake_paver() { return fake_paver_; }
-  fidl::ClientEnd<fuchsia_io::Directory> TakeDirectory() { return std::move(svc_local_); }
+  zx::channel& svc_chan() { return svc_local_; }
 
  private:
   async_dispatcher_t* dispatcher_;
   fs::SynchronousVfs vfs_;
   FakePaver fake_paver_;
-  fidl::ClientEnd<fuchsia_io::Directory> svc_local_;
+  zx::channel svc_local_;
 };
 
 class FakeDev {
@@ -446,13 +435,6 @@
         devmgr_integration_test::RecursiveWaitForFile(devmgr_.devfs_root(), "sys/platform", &fd));
   }
 
-  fidl::ClientEnd<fuchsia_io::Directory> TakeDirectory() {
-    auto caller = fdio_cpp::FdioCaller(devmgr_.devfs_root().duplicate());
-    auto directory = caller.take_directory();
-    EXPECT_OK(directory.status_value());  // Have to use EXPECT in functions that return a value.
-    return std::move(*directory);
-  }
-
   driver_integration_test::IsolatedDevmgr devmgr_;
 };
 
@@ -461,7 +443,7 @@
   PaverTest()
       : loop_(&kAsyncLoopConfigNoAttachToCurrentThread),
         fake_svc_(loop_.dispatcher()),
-        paver_(fake_svc_.TakeDirectory(), fake_dev_.TakeDirectory()) {
+        paver_(std::move(fake_svc_.svc_chan()), fake_dev_.devmgr_.devfs_root().duplicate()) {
     paver_.set_timeout(zx::msec(500));
     loop_.StartThread("paver-test-loop");
   }
diff --git a/src/bringup/bin/netsvc/test/paver-test.cc b/src/bringup/bin/netsvc/test/paver-test.cc
index 1a3aa04..26a80c1a 100644
--- a/src/bringup/bin/netsvc/test/paver-test.cc
+++ b/src/bringup/bin/netsvc/test/paver-test.cc
@@ -31,16 +31,16 @@
 }
 
 TEST(PaverTest, InitialInProgressFalse) {
-  fidl::ClientEnd<fuchsia_io::Directory> svc_root;
-  fidl::ClientEnd<fuchsia_io::Directory> devfs_root;
-  netsvc::Paver paver_(std::move(svc_root), std::move(devfs_root));
+  zx::channel chan;
+  fbl::unique_fd fd;
+  netsvc::Paver paver_(std::move(chan), std::move(fd));
   ASSERT_FALSE(paver_.InProgress());
 }
 
 TEST(PaverTest, InitialExitCodeValid) {
-  fidl::ClientEnd<fuchsia_io::Directory> svc_root;
-  fidl::ClientEnd<fuchsia_io::Directory> devfs_root;
-  netsvc::Paver paver_(std::move(svc_root), std::move(devfs_root));
+  zx::channel chan;
+  fbl::unique_fd fd;
+  netsvc::Paver paver_(std::move(chan), std::move(fd));
   ASSERT_OK(paver_.exit_code());
 }
 
diff --git a/src/bringup/bin/netsvc/test/payload-streamer-test.cc b/src/bringup/bin/netsvc/test/payload-streamer-test.cc
index 41cd82e..7f445bd 100644
--- a/src/bringup/bin/netsvc/test/payload-streamer-test.cc
+++ b/src/bringup/bin/netsvc/test/payload-streamer-test.cc
@@ -22,11 +22,11 @@
   }
 
   void StartStreamer(netsvc::ReadCallback callback = DefaultCallback) {
-    auto endpoints = fidl::CreateEndpoints<fuchsia_paver::PayloadStream>();
-    ASSERT_OK(endpoints.status_value());
+    zx::channel server, client;
+    ASSERT_OK(zx::channel::create(0, &client, &server));
 
-    client_.emplace(std::move(endpoints->client));
-    payload_streamer_.emplace(std::move(endpoints->server), std::move(callback));
+    client_.emplace(std::move(client));
+    payload_streamer_.emplace(std::move(server), std::move(callback));
     loop_.StartThread("payload-streamer-test-loop");
   }