diff --git a/adb/pairing_connection/Android.bp b/adb/pairing_connection/Android.bp
new file mode 100644
index 0000000..c053854
--- /dev/null
+++ b/adb/pairing_connection/Android.bp
@@ -0,0 +1,185 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_defaults {
+    name: "libadb_pairing_connection_defaults",
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Wthread-safety",
+        "-Werror",
+    ],
+
+    compile_multilib: "both",
+
+    srcs: [
+        "pairing_connection.cpp",
+    ],
+    target: {
+        android: {
+            version_script: "libadb_pairing_connection.map.txt",
+        },
+        windows: {
+            compile_multilib: "first",
+            enabled: true,
+        },
+    },
+    export_include_dirs: ["include"],
+
+    visibility: [
+        "//art:__subpackages__",
+        "//system/core/adb:__subpackages__",
+        "//frameworks/base/services:__subpackages__",
+    ],
+    apex_available: [
+        "com.android.adbd",
+    ],
+
+    // libadb_pairing_connection doesn't need an embedded build number.
+    use_version_lib: false,
+
+    stl: "libc++_static",
+
+    host_supported: true,
+    recovery_available: true,
+
+    static_libs: [
+        "libbase",
+        "libssl",
+    ],
+    shared_libs: [
+        "libcrypto",
+        "liblog",
+        "libadb_pairing_auth",
+    ],
+}
+
+cc_library {
+    name: "libadb_pairing_connection",
+    defaults: ["libadb_pairing_connection_defaults"],
+
+    apex_available: [
+        "com.android.adbd",
+    ],
+
+    stubs: {
+        symbol_file: "libadb_pairing_connection.map.txt",
+        versions: ["30"],
+    },
+
+    static_libs: [
+        "libadb_protos",
+        // Statically link libadb_tls_connection because it is not
+	// ABI-stable.
+        "libadb_tls_connection",
+        "libprotobuf-cpp-lite",
+    ],
+}
+
+// For running atest (b/147158681)
+cc_library_static {
+    name: "libadb_pairing_connection_static",
+    defaults: ["libadb_pairing_connection_defaults"],
+
+    apex_available: [
+        "//apex_available:platform",
+    ],
+
+    static_libs: [
+        "libadb_protos_static",
+        "libprotobuf-cpp-lite",
+        "libadb_tls_connection_static",
+    ],
+}
+
+cc_defaults {
+    name: "libadb_pairing_server_defaults",
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Wthread-safety",
+        "-Werror",
+    ],
+
+    compile_multilib: "both",
+
+    srcs: [
+        "pairing_server.cpp",
+    ],
+    target: {
+        android: {
+            version_script: "libadb_pairing_server.map.txt",
+        },
+    },
+    export_include_dirs: ["include"],
+
+    visibility: [
+        "//art:__subpackages__",
+        "//system/core/adb:__subpackages__",
+        "//frameworks/base/services:__subpackages__",
+    ],
+
+    host_supported: true,
+    recovery_available: true,
+
+    stl: "libc++_static",
+
+    static_libs: [
+        "libbase",
+    ],
+    shared_libs: [
+        "libcrypto",
+        "libcrypto_utils",
+        "libcutils",
+        "liblog",
+        "libadb_pairing_auth",
+        "libadb_pairing_connection",
+    ],
+}
+
+cc_library {
+    name: "libadb_pairing_server",
+    defaults: ["libadb_pairing_server_defaults"],
+
+    apex_available: [
+        "com.android.adbd",
+    ],
+
+    stubs: {
+        symbol_file: "libadb_pairing_server.map.txt",
+        versions: ["30"],
+    },
+
+    static_libs: [
+        // Statically link libadb_crypto because it is not
+	// ABI-stable.
+        "libadb_crypto",
+        "libadb_protos",
+    ],
+}
+
+// For running atest (b/147158681)
+cc_library_static {
+    name: "libadb_pairing_server_static",
+    defaults: ["libadb_pairing_server_defaults"],
+
+    apex_available: [
+        "//apex_available:platform",
+    ],
+
+    static_libs: [
+        "libadb_crypto_static",
+        "libadb_protos_static",
+    ],
+}
diff --git a/adb/pairing_connection/include/adb/pairing/pairing_connection.h b/adb/pairing_connection/include/adb/pairing/pairing_connection.h
new file mode 100644
index 0000000..3543b87
--- /dev/null
+++ b/adb/pairing_connection/include/adb/pairing/pairing_connection.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/cdefs.h>
+
+#if !defined(__INTRODUCED_IN)
+#define __INTRODUCED_IN(__api_level) /* nothing */
+#endif
+
+// These APIs are for the Adb pairing protocol. This protocol requires both
+// sides to possess a shared secret to authenticate each other. The connection
+// is over TLS, and requires that both the client and server have a valid
+// certificate.
+//
+// This protocol is one-to-one, i.e., one PairingConnectionCtx server instance
+// interacts with only one PairingConnectionCtx client instance. In other words,
+// every new client instance must be bound to a new server instance.
+//
+// If both sides have authenticated, they will exchange their peer information
+// (see #PeerInfo).
+__BEGIN_DECLS
+#if !defined(__ANDROID__) || __ANDROID_API__ >= 30
+
+const uint32_t kMaxPeerInfoSize = 8192;
+struct PeerInfo {
+    uint8_t type;
+    uint8_t data[kMaxPeerInfoSize - 1];
+} __attribute__((packed));
+typedef struct PeerInfo PeerInfo;
+static_assert(sizeof(PeerInfo) == kMaxPeerInfoSize, "PeerInfo has weird size");
+
+enum PeerInfoType : uint8_t {
+    ADB_RSA_PUB_KEY = 0,
+    ADB_DEVICE_GUID = 1,
+};
+
+struct PairingConnectionCtx;
+typedef struct PairingConnectionCtx PairingConnectionCtx;
+typedef void (*pairing_result_cb)(const PeerInfo*, int, void*);
+
+// Starts the pairing connection on a separate thread.
+//
+// Upon completion, if the pairing was successful,
+// |cb| will be called with the peer information and certificate.
+// Otherwise, |cb| will be called with empty data. |fd| should already
+// be opened. PairingConnectionCtx will take ownership of the |fd|.
+//
+// Pairing is successful if both server/client uses the same non-empty
+// |pswd|, and they are able to exchange the information. |pswd| and
+// |certificate| must be non-empty. start() can only be called once in the
+// lifetime of this object.
+//
+// @param ctx the PairingConnectionCtx instance. Will abort if null.
+// @param fd the fd connecting the peers. This will take ownership of fd.
+// @param cb the user-provided callback that is called with the result of the
+//        pairing. The callback will be called on a different thread from the
+//        caller.
+// @param opaque opaque userdata.
+// @return true if the thread was successfully started, false otherwise. To stop
+//         the connection process, destroy the instance (see
+//         #pairing_connection_destroy). If false is returned, cb will not be
+//         invoked. Otherwise, cb is guaranteed to be invoked, even if you
+//         destroy the ctx while in the pairing process.
+bool pairing_connection_start(PairingConnectionCtx* ctx, int fd, pairing_result_cb cb, void* opaque)
+        __INTRODUCED_IN(30);
+
+// Creates a new PairingConnectionCtx instance as the client.
+//
+// @param pswd the password to authenticate both peers. Will abort if null.
+// @param pswd_len the length of pswd. Will abort if 0.
+// @param peer_info the PeerInfo struct that is exchanged between peers if the
+//                  pairing was successful. Will abort if null.
+// @param x509_cert_pem the X.509 certificate in PEM format. Will abort if null.
+// @param x509_size the size of x509_cert_pem. Will abort if 0.
+// @param priv_key_pem the private key corresponding to the given X.509
+//                     certificate, in PEM format. Will abort if null.
+// @param priv_size the size of priv_key_pem. Will abort if 0.
+// @return a new PairingConnectionCtx client instance. The caller is responsible
+//         for destroying the context via #pairing_connection_destroy.
+PairingConnectionCtx* pairing_connection_client_new(const uint8_t* pswd, size_t pswd_len,
+                                                    const PeerInfo* peer_info,
+                                                    const uint8_t* x509_cert_pem, size_t x509_size,
+                                                    const uint8_t* priv_key_pem, size_t priv_size)
+        __INTRODUCED_IN(30);
+
+// Creates a new PairingConnectionCtx instance as the server.
+//
+// @param pswd the password to authenticate both peers. Will abort if null.
+// @param pswd_len the length of pswd. Will abort if 0.
+// @param peer_info the PeerInfo struct that is exchanged between peers if the
+//                  pairing was successful. Will abort if null.
+// @param x509_cert_pem the X.509 certificate in PEM format. Will abort if null.
+// @param x509_size the size of x509_cert_pem. Will abort if 0.
+// @param priv_key_pem the private key corresponding to the given X.509
+//                     certificate, in PEM format. Will abort if null.
+// @param priv_size the size of priv_key_pem. Will abort if 0.
+// @return a new PairingConnectionCtx server instance. The caller is responsible
+//         for destroying the context via #pairing_connection_destroy.
+PairingConnectionCtx* pairing_connection_server_new(const uint8_t* pswd, size_t pswd_len,
+                                                    const PeerInfo* peer_info,
+                                                    const uint8_t* x509_cert_pem, size_t x509_size,
+                                                    const uint8_t* priv_key_pem, size_t priv_size)
+        __INTRODUCED_IN(30);
+
+// Destroys the PairingConnectionCtx instance.
+//
+// It is safe to destroy the instance at any point in the pairing process.
+//
+// @param ctx the PairingConnectionCtx instance to destroy. Will abort if null.
+void pairing_connection_destroy(PairingConnectionCtx* ctx) __INTRODUCED_IN(30);
+
+#endif  //!__ANDROID__ || __ANDROID_API__ >= 30
+__END_DECLS
diff --git a/adb/pairing_connection/include/adb/pairing/pairing_server.h b/adb/pairing_connection/include/adb/pairing/pairing_server.h
new file mode 100644
index 0000000..178a174
--- /dev/null
+++ b/adb/pairing_connection/include/adb/pairing/pairing_server.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/cdefs.h>
+
+#include <functional>
+#include <memory>
+#include <string_view>
+#include <vector>
+
+#include "adb/pairing/pairing_connection.h"
+
+#if !defined(__INTRODUCED_IN)
+#define __INTRODUCED_IN(__api_level) /* nothing */
+#endif
+
+__BEGIN_DECLS
+#if !defined(__ANDROID__) || __ANDROID_API__ >= 30
+
+// PairingServerCtx is a wrapper around the #PairingConnectionCtx APIs,
+// which handles multiple client connections.
+//
+// See pairing_connection_test.cpp for example usage.
+//
+struct PairingServerCtx;
+typedef struct PairingServerCtx PairingServerCtx;
+
+// Callback containing the result of the pairing. If #PeerInfo is null,
+// then the pairing failed. Otherwise, pairing succeeded and #PeerInfo
+// contains information about the peer.
+typedef void (*pairing_server_result_cb)(const PeerInfo*, void*) __INTRODUCED_IN(30);
+
+// Starts the pairing server.
+//
+// This call is non-blocking. Upon completion, if the pairing was successful,
+// then |cb| will be called with the PeerInfo
+// containing the info of the trusted peer. Otherwise, |cb| will be
+// called with an empty value. Start can only be called once in the lifetime
+// of this object.
+//
+// @param ctx the PairingServerCtx instance.
+// @param cb the user-provided callback to notify the result of the pairing. See
+//           #pairing_server_result_cb.
+// @param opaque the opaque userdata.
+// @return the port number the server is listening on. Returns 0 on failure.
+uint16_t pairing_server_start(PairingServerCtx* ctx, pairing_server_result_cb cb, void* opaque)
+        __INTRODUCED_IN(30);
+
+// Creates a new PairingServerCtx instance.
+//
+// @param pswd the password used to authenticate the client and server.
+// @param pswd_len the length of pswd.
+// @param peer_info the #PeerInfo struct passed to the client on successful
+//                  pairing.
+// @param x509_cert_pem the X.509 certificate in PEM format. Cannot be empty.
+// @param x509_size the size of x509_cert_pem.
+// @param priv_key_pem the private key corresponding to the given X.509
+//                     certificate, in PEM format. Cannot be empty.
+// @param priv_size the size of priv_key_pem.
+// @param port the port number the server should listen on. Must be within the
+//             valid port range [0, 65535]. If port is 0, then the server will
+//             find an open port to listen on. See #pairing_server_start to
+//             obtain the port used.
+// @return a new PairingServerCtx instance The caller is responsible
+//         for destroying the context via #pairing_server_destroy.
+PairingServerCtx* pairing_server_new(const uint8_t* pswd, size_t pswd_len,
+                                     const PeerInfo* peer_info, const uint8_t* x509_cert_pem,
+                                     size_t x509_size, const uint8_t* priv_key_pem,
+                                     size_t priv_size, uint16_t port) __INTRODUCED_IN(30);
+
+// Same as #pairing_server_new, except that the x509 certificate and private key
+// is generated internally.
+//
+// @param pswd the password used to authenticate the client and server.
+// @param pswd_len the length of pswd.
+// @param peer_info the #PeerInfo struct passed to the client on successful
+//                  pairing.
+// @param port the port number the server should listen on. Must be within the
+//             valid port range [0, 65535]. If port is 0, then the server will
+//             find an open port to listen on. See #pairing_server_start to
+//             obtain the port used.
+// @return a new PairingServerCtx instance The caller is responsible
+//         for destroying the context via #pairing_server_destroy.
+PairingServerCtx* pairing_server_new_no_cert(const uint8_t* pswd, size_t pswd_len,
+                                             const PeerInfo* peer_info, uint16_t port)
+        __INTRODUCED_IN(30);
+
+// Destroys the PairingServerCtx instance.
+//
+// @param ctx the PairingServerCtx instance to destroy.
+void pairing_server_destroy(PairingServerCtx* ctx) __INTRODUCED_IN(30);
+
+#endif  //!__ANDROID__ || __ANDROID_API__ >= 30
+__END_DECLS
diff --git a/adb/pairing_connection/internal/constants.h b/adb/pairing_connection/internal/constants.h
new file mode 100644
index 0000000..9a04f17
--- /dev/null
+++ b/adb/pairing_connection/internal/constants.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+// This file contains constants that can be used both in the pairing_connection
+// code and tested in the pairing_connection_test code.
+namespace adb {
+namespace pairing {
+namespace internal {
+
+// The maximum number of connections the PairingServer can handle at once.
+constexpr int kMaxConnections = 10;
+// The maximum number of attempts the PairingServer will take before quitting.
+// This is to prevent someone malicious from quickly brute-forcing every
+// combination.
+constexpr int kMaxPairingAttempts = 20;
+
+}  // namespace internal
+}  // namespace pairing
+}  // namespace adb
diff --git a/adb/pairing_connection/libadb_pairing_connection.map.txt b/adb/pairing_connection/libadb_pairing_connection.map.txt
new file mode 100644
index 0000000..abd5f16
--- /dev/null
+++ b/adb/pairing_connection/libadb_pairing_connection.map.txt
@@ -0,0 +1,10 @@
+LIBADB_PAIRING_CONNECTION {
+  global:
+    pairing_connection_client_new; # apex introduced=30
+    pairing_connection_server_new; # apex introduced=30
+    pairing_connection_start; # apex introduced=30
+    pairing_connection_destroy; # apex introduced=30
+
+  local:
+    *;
+};
diff --git a/adb/pairing_connection/libadb_pairing_server.map.txt b/adb/pairing_connection/libadb_pairing_server.map.txt
new file mode 100644
index 0000000..dc0dc89
--- /dev/null
+++ b/adb/pairing_connection/libadb_pairing_server.map.txt
@@ -0,0 +1,10 @@
+LIBADB_PAIRING_SERVER {
+  global:
+    pairing_server_start; # apex introduced=30
+    pairing_server_new; # apex introduced=30
+    pairing_server_new_no_cert; # apex introduced=30
+    pairing_server_destroy; # apex introduced=30
+
+  local:
+    *;
+};
diff --git a/adb/pairing_connection/pairing_connection.cpp b/adb/pairing_connection/pairing_connection.cpp
new file mode 100644
index 0000000..a26a6b4
--- /dev/null
+++ b/adb/pairing_connection/pairing_connection.cpp
@@ -0,0 +1,491 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "adb/pairing/pairing_connection.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <functional>
+#include <memory>
+#include <string_view>
+#include <thread>
+#include <vector>
+
+#include <adb/pairing/pairing_auth.h>
+#include <adb/tls/tls_connection.h>
+#include <android-base/endian.h>
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <android-base/unique_fd.h>
+
+#include "pairing.pb.h"
+
+using namespace adb;
+using android::base::unique_fd;
+using TlsError = tls::TlsConnection::TlsError;
+
+const uint8_t kCurrentKeyHeaderVersion = 1;
+const uint8_t kMinSupportedKeyHeaderVersion = 1;
+const uint8_t kMaxSupportedKeyHeaderVersion = 1;
+const uint32_t kMaxPayloadSize = kMaxPeerInfoSize * 2;
+
+struct PairingPacketHeader {
+    uint8_t version;   // PairingPacket version
+    uint8_t type;      // the type of packet (PairingPacket.Type)
+    uint32_t payload;  // Size of the payload in bytes
+} __attribute__((packed));
+
+struct PairingAuthDeleter {
+    void operator()(PairingAuthCtx* p) { pairing_auth_destroy(p); }
+};  // PairingAuthDeleter
+using PairingAuthPtr = std::unique_ptr<PairingAuthCtx, PairingAuthDeleter>;
+
+// PairingConnectionCtx encapsulates the protocol to authenticate two peers with
+// each other. This class will open the tcp sockets and handle the pairing
+// process. On completion, both sides will have each other's public key
+// (certificate) if successful, otherwise, the pairing failed. The tcp port
+// number is hardcoded (see pairing_connection.cpp).
+//
+// Each PairingConnectionCtx instance represents a different device trying to
+// pair. So for the device, we can have multiple PairingConnectionCtxs while the
+// host may have only one (unless host has a PairingServer).
+//
+// See pairing_connection_test.cpp for example usage.
+//
+struct PairingConnectionCtx {
+  public:
+    using Data = std::vector<uint8_t>;
+    using ResultCallback = pairing_result_cb;
+    enum class Role {
+        Client,
+        Server,
+    };
+
+    explicit PairingConnectionCtx(Role role, const Data& pswd, const PeerInfo& peer_info,
+                                  const Data& certificate, const Data& priv_key);
+    virtual ~PairingConnectionCtx();
+
+    // Starts the pairing connection on a separate thread.
+    // Upon completion, if the pairing was successful,
+    // |cb| will be called with the peer information and certificate.
+    // Otherwise, |cb| will be called with empty data. |fd| should already
+    // be opened. PairingConnectionCtx will take ownership of the |fd|.
+    //
+    // Pairing is successful if both server/client uses the same non-empty
+    // |pswd|, and they are able to exchange the information. |pswd| and
+    // |certificate| must be non-empty. Start() can only be called once in the
+    // lifetime of this object.
+    //
+    // Returns true if the thread was successfully started, false otherwise.
+    bool Start(int fd, ResultCallback cb, void* opaque);
+
+  private:
+    // Setup the tls connection.
+    bool SetupTlsConnection();
+
+    /************ PairingPacketHeader methods ****************/
+    // Tries to write out the header and payload.
+    bool WriteHeader(const PairingPacketHeader* header, std::string_view payload);
+    // Tries to parse incoming data into the |header|. Returns true if header
+    // is valid and header version is supported. |header| is filled on success.
+    // |header| may contain garbage if unsuccessful.
+    bool ReadHeader(PairingPacketHeader* header);
+    // Creates a PairingPacketHeader.
+    void CreateHeader(PairingPacketHeader* header, adb::proto::PairingPacket::Type type,
+                      uint32_t payload_size);
+    // Checks if actual matches expected.
+    bool CheckHeaderType(adb::proto::PairingPacket::Type expected, uint8_t actual);
+
+    /*********** State related methods **************/
+    // Handles the State::ExchangingMsgs state.
+    bool DoExchangeMsgs();
+    // Handles the State::ExchangingPeerInfo state.
+    bool DoExchangePeerInfo();
+
+    // The background task to do the pairing.
+    void StartWorker();
+
+    // Calls |cb_| and sets the state to Stopped.
+    void NotifyResult(const PeerInfo* p);
+
+    static PairingAuthPtr CreatePairingAuthPtr(Role role, const Data& pswd);
+
+    enum class State {
+        Ready,
+        ExchangingMsgs,
+        ExchangingPeerInfo,
+        Stopped,
+    };
+
+    std::atomic<State> state_{State::Ready};
+    Role role_;
+    Data pswd_;
+    PeerInfo peer_info_;
+    Data cert_;
+    Data priv_key_;
+
+    // Peer's info
+    PeerInfo their_info_;
+
+    ResultCallback cb_;
+    void* opaque_ = nullptr;
+    std::unique_ptr<tls::TlsConnection> tls_;
+    PairingAuthPtr auth_;
+    unique_fd fd_;
+    std::thread thread_;
+    static constexpr size_t kExportedKeySize = 64;
+};  // PairingConnectionCtx
+
+PairingConnectionCtx::PairingConnectionCtx(Role role, const Data& pswd, const PeerInfo& peer_info,
+                                           const Data& cert, const Data& priv_key)
+    : role_(role), pswd_(pswd), peer_info_(peer_info), cert_(cert), priv_key_(priv_key) {
+    CHECK(!pswd_.empty() && !cert_.empty() && !priv_key_.empty());
+}
+
+PairingConnectionCtx::~PairingConnectionCtx() {
+    // Force close the fd and wait for the worker thread to finish.
+    fd_.reset();
+    if (thread_.joinable()) {
+        thread_.join();
+    }
+}
+
+bool PairingConnectionCtx::SetupTlsConnection() {
+    tls_ = tls::TlsConnection::Create(
+            role_ == Role::Server ? tls::TlsConnection::Role::Server
+                                  : tls::TlsConnection::Role::Client,
+            std::string_view(reinterpret_cast<const char*>(cert_.data()), cert_.size()),
+            std::string_view(reinterpret_cast<const char*>(priv_key_.data()), priv_key_.size()),
+            fd_);
+
+    if (tls_ == nullptr) {
+        LOG(ERROR) << "Unable to start TlsConnection. Unable to pair fd=" << fd_.get();
+        return false;
+    }
+
+    // Allow any peer certificate
+    tls_->SetCertVerifyCallback([](X509_STORE_CTX*) { return 1; });
+
+    // SSL doesn't seem to behave correctly with fdevents so just do a blocking
+    // read for the pairing data.
+    if (tls_->DoHandshake() != TlsError::Success) {
+        LOG(ERROR) << "Failed to handshake with the peer fd=" << fd_.get();
+        return false;
+    }
+
+    // To ensure the connection is not stolen while we do the PAKE, append the
+    // exported key material from the tls connection to the password.
+    std::vector<uint8_t> exportedKeyMaterial = tls_->ExportKeyingMaterial(kExportedKeySize);
+    if (exportedKeyMaterial.empty()) {
+        LOG(ERROR) << "Failed to export key material";
+        return false;
+    }
+    pswd_.insert(pswd_.end(), std::make_move_iterator(exportedKeyMaterial.begin()),
+                 std::make_move_iterator(exportedKeyMaterial.end()));
+    auth_ = CreatePairingAuthPtr(role_, pswd_);
+
+    return true;
+}
+
+bool PairingConnectionCtx::WriteHeader(const PairingPacketHeader* header,
+                                       std::string_view payload) {
+    PairingPacketHeader network_header = *header;
+    network_header.payload = htonl(network_header.payload);
+    if (!tls_->WriteFully(std::string_view(reinterpret_cast<const char*>(&network_header),
+                                           sizeof(PairingPacketHeader))) ||
+        !tls_->WriteFully(payload)) {
+        LOG(ERROR) << "Failed to write out PairingPacketHeader";
+        state_ = State::Stopped;
+        return false;
+    }
+    return true;
+}
+
+bool PairingConnectionCtx::ReadHeader(PairingPacketHeader* header) {
+    auto data = tls_->ReadFully(sizeof(PairingPacketHeader));
+    if (data.empty()) {
+        return false;
+    }
+
+    uint8_t* p = data.data();
+    // First byte is always PairingPacketHeader version
+    header->version = *p;
+    ++p;
+    if (header->version < kMinSupportedKeyHeaderVersion ||
+        header->version > kMaxSupportedKeyHeaderVersion) {
+        LOG(ERROR) << "PairingPacketHeader version mismatch (us=" << kCurrentKeyHeaderVersion
+                   << " them=" << header->version << ")";
+        return false;
+    }
+    // Next byte is the PairingPacket::Type
+    if (!adb::proto::PairingPacket::Type_IsValid(*p)) {
+        LOG(ERROR) << "Unknown PairingPacket type=" << static_cast<uint32_t>(*p);
+        return false;
+    }
+    header->type = *p;
+    ++p;
+    // Last, the payload size
+    header->payload = ntohl(*(reinterpret_cast<uint32_t*>(p)));
+    if (header->payload == 0 || header->payload > kMaxPayloadSize) {
+        LOG(ERROR) << "header payload not within a safe payload size (size=" << header->payload
+                   << ")";
+        return false;
+    }
+
+    return true;
+}
+
+void PairingConnectionCtx::CreateHeader(PairingPacketHeader* header,
+                                        adb::proto::PairingPacket::Type type,
+                                        uint32_t payload_size) {
+    header->version = kCurrentKeyHeaderVersion;
+    uint8_t type8 = static_cast<uint8_t>(static_cast<int>(type));
+    header->type = type8;
+    header->payload = payload_size;
+}
+
+bool PairingConnectionCtx::CheckHeaderType(adb::proto::PairingPacket::Type expected_type,
+                                           uint8_t actual) {
+    uint8_t expected = *reinterpret_cast<uint8_t*>(&expected_type);
+    if (actual != expected) {
+        LOG(ERROR) << "Unexpected header type (expected=" << static_cast<uint32_t>(expected)
+                   << " actual=" << static_cast<uint32_t>(actual) << ")";
+        return false;
+    }
+    return true;
+}
+
+void PairingConnectionCtx::NotifyResult(const PeerInfo* p) {
+    cb_(p, fd_.get(), opaque_);
+    state_ = State::Stopped;
+}
+
+bool PairingConnectionCtx::Start(int fd, ResultCallback cb, void* opaque) {
+    if (fd < 0) {
+        return false;
+    }
+
+    State expected = State::Ready;
+    if (!state_.compare_exchange_strong(expected, State::ExchangingMsgs)) {
+        return false;
+    }
+
+    fd_.reset(fd);
+    cb_ = cb;
+    opaque_ = opaque;
+
+    thread_ = std::thread([this] { StartWorker(); });
+    return true;
+}
+
+bool PairingConnectionCtx::DoExchangeMsgs() {
+    uint32_t payload = pairing_auth_msg_size(auth_.get());
+    std::vector<uint8_t> msg(payload);
+    pairing_auth_get_spake2_msg(auth_.get(), msg.data());
+
+    PairingPacketHeader header;
+    CreateHeader(&header, adb::proto::PairingPacket::SPAKE2_MSG, payload);
+
+    // Write our SPAKE2 msg
+    if (!WriteHeader(&header,
+                     std::string_view(reinterpret_cast<const char*>(msg.data()), msg.size()))) {
+        LOG(ERROR) << "Failed to write SPAKE2 msg.";
+        return false;
+    }
+
+    // Read the peer's SPAKE2 msg header
+    if (!ReadHeader(&header)) {
+        LOG(ERROR) << "Invalid PairingPacketHeader.";
+        return false;
+    }
+    if (!CheckHeaderType(adb::proto::PairingPacket::SPAKE2_MSG, header.type)) {
+        return false;
+    }
+
+    // Read the SPAKE2 msg payload and initialize the cipher for
+    // encrypting the PeerInfo and certificate.
+    auto their_msg = tls_->ReadFully(header.payload);
+    if (their_msg.empty() ||
+        !pairing_auth_init_cipher(auth_.get(), their_msg.data(), their_msg.size())) {
+        LOG(ERROR) << "Unable to initialize pairing cipher [their_msg.size=" << their_msg.size()
+                   << "]";
+        return false;
+    }
+
+    return true;
+}
+
+bool PairingConnectionCtx::DoExchangePeerInfo() {
+    // Encrypt PeerInfo
+    std::vector<uint8_t> buf;
+    uint8_t* p = reinterpret_cast<uint8_t*>(&peer_info_);
+    buf.assign(p, p + sizeof(peer_info_));
+    std::vector<uint8_t> outbuf(pairing_auth_safe_encrypted_size(auth_.get(), buf.size()));
+    CHECK(!outbuf.empty());
+    size_t outsize;
+    if (!pairing_auth_encrypt(auth_.get(), buf.data(), buf.size(), outbuf.data(), &outsize)) {
+        LOG(ERROR) << "Failed to encrypt peer info";
+        return false;
+    }
+    outbuf.resize(outsize);
+
+    // Write out the packet header
+    PairingPacketHeader out_header;
+    out_header.version = kCurrentKeyHeaderVersion;
+    out_header.type = static_cast<uint8_t>(static_cast<int>(adb::proto::PairingPacket::PEER_INFO));
+    out_header.payload = htonl(outbuf.size());
+    if (!tls_->WriteFully(
+                std::string_view(reinterpret_cast<const char*>(&out_header), sizeof(out_header)))) {
+        LOG(ERROR) << "Unable to write PairingPacketHeader";
+        return false;
+    }
+
+    // Write out the encrypted payload
+    if (!tls_->WriteFully(
+                std::string_view(reinterpret_cast<const char*>(outbuf.data()), outbuf.size()))) {
+        LOG(ERROR) << "Unable to write encrypted peer info";
+        return false;
+    }
+
+    // Read in the peer's packet header
+    PairingPacketHeader header;
+    if (!ReadHeader(&header)) {
+        LOG(ERROR) << "Invalid PairingPacketHeader.";
+        return false;
+    }
+
+    if (!CheckHeaderType(adb::proto::PairingPacket::PEER_INFO, header.type)) {
+        return false;
+    }
+
+    // Read in the encrypted peer certificate
+    buf = tls_->ReadFully(header.payload);
+    if (buf.empty()) {
+        return false;
+    }
+
+    // Try to decrypt the certificate
+    outbuf.resize(pairing_auth_safe_decrypted_size(auth_.get(), buf.data(), buf.size()));
+    if (outbuf.empty()) {
+        LOG(ERROR) << "Unsupported payload while decrypting peer info.";
+        return false;
+    }
+
+    if (!pairing_auth_decrypt(auth_.get(), buf.data(), buf.size(), outbuf.data(), &outsize)) {
+        LOG(ERROR) << "Failed to decrypt";
+        return false;
+    }
+    outbuf.resize(outsize);
+
+    // The decrypted message should contain the PeerInfo.
+    if (outbuf.size() != sizeof(PeerInfo)) {
+        LOG(ERROR) << "Got size=" << outbuf.size() << "PeerInfo.size=" << sizeof(PeerInfo);
+        return false;
+    }
+
+    p = outbuf.data();
+    ::memcpy(&their_info_, p, sizeof(PeerInfo));
+    p += sizeof(PeerInfo);
+
+    return true;
+}
+
+void PairingConnectionCtx::StartWorker() {
+    // Setup the secure transport
+    if (!SetupTlsConnection()) {
+        NotifyResult(nullptr);
+        return;
+    }
+
+    for (;;) {
+        switch (state_) {
+            case State::ExchangingMsgs:
+                if (!DoExchangeMsgs()) {
+                    NotifyResult(nullptr);
+                    return;
+                }
+                state_ = State::ExchangingPeerInfo;
+                break;
+            case State::ExchangingPeerInfo:
+                if (!DoExchangePeerInfo()) {
+                    NotifyResult(nullptr);
+                    return;
+                }
+                NotifyResult(&their_info_);
+                return;
+            case State::Ready:
+            case State::Stopped:
+                LOG(FATAL) << __func__ << ": Got invalid state";
+                return;
+        }
+    }
+}
+
+// static
+PairingAuthPtr PairingConnectionCtx::CreatePairingAuthPtr(Role role, const Data& pswd) {
+    switch (role) {
+        case Role::Client:
+            return PairingAuthPtr(pairing_auth_client_new(pswd.data(), pswd.size()));
+            break;
+        case Role::Server:
+            return PairingAuthPtr(pairing_auth_server_new(pswd.data(), pswd.size()));
+            break;
+    }
+}
+
+static PairingConnectionCtx* CreateConnection(PairingConnectionCtx::Role role, const uint8_t* pswd,
+                                              size_t pswd_len, const PeerInfo* peer_info,
+                                              const uint8_t* x509_cert_pem, size_t x509_size,
+                                              const uint8_t* priv_key_pem, size_t priv_size) {
+    CHECK(pswd);
+    CHECK_GT(pswd_len, 0U);
+    CHECK(x509_cert_pem);
+    CHECK_GT(x509_size, 0U);
+    CHECK(priv_key_pem);
+    CHECK_GT(priv_size, 0U);
+    CHECK(peer_info);
+    std::vector<uint8_t> vec_pswd(pswd, pswd + pswd_len);
+    std::vector<uint8_t> vec_x509_cert(x509_cert_pem, x509_cert_pem + x509_size);
+    std::vector<uint8_t> vec_priv_key(priv_key_pem, priv_key_pem + priv_size);
+    return new PairingConnectionCtx(role, vec_pswd, *peer_info, vec_x509_cert, vec_priv_key);
+}
+
+PairingConnectionCtx* pairing_connection_client_new(const uint8_t* pswd, size_t pswd_len,
+                                                    const PeerInfo* peer_info,
+                                                    const uint8_t* x509_cert_pem, size_t x509_size,
+                                                    const uint8_t* priv_key_pem, size_t priv_size) {
+    return CreateConnection(PairingConnectionCtx::Role::Client, pswd, pswd_len, peer_info,
+                            x509_cert_pem, x509_size, priv_key_pem, priv_size);
+}
+
+PairingConnectionCtx* pairing_connection_server_new(const uint8_t* pswd, size_t pswd_len,
+                                                    const PeerInfo* peer_info,
+                                                    const uint8_t* x509_cert_pem, size_t x509_size,
+                                                    const uint8_t* priv_key_pem, size_t priv_size) {
+    return CreateConnection(PairingConnectionCtx::Role::Server, pswd, pswd_len, peer_info,
+                            x509_cert_pem, x509_size, priv_key_pem, priv_size);
+}
+
+void pairing_connection_destroy(PairingConnectionCtx* ctx) {
+    CHECK(ctx);
+    delete ctx;
+}
+
+bool pairing_connection_start(PairingConnectionCtx* ctx, int fd, pairing_result_cb cb,
+                              void* opaque) {
+    return ctx->Start(fd, cb, opaque);
+}
diff --git a/adb/pairing_connection/pairing_server.cpp b/adb/pairing_connection/pairing_server.cpp
new file mode 100644
index 0000000..7218eac
--- /dev/null
+++ b/adb/pairing_connection/pairing_server.cpp
@@ -0,0 +1,466 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "adb/pairing/pairing_server.h"
+
+#include <sys/epoll.h>
+#include <sys/eventfd.h>
+
+#include <atomic>
+#include <deque>
+#include <iomanip>
+#include <mutex>
+#include <sstream>
+#include <thread>
+#include <tuple>
+#include <unordered_map>
+#include <variant>
+#include <vector>
+
+#include <adb/crypto/rsa_2048_key.h>
+#include <adb/crypto/x509_generator.h>
+#include <adb/pairing/pairing_connection.h>
+#include <android-base/logging.h>
+#include <android-base/parsenetaddress.h>
+#include <android-base/thread_annotations.h>
+#include <android-base/unique_fd.h>
+#include <cutils/sockets.h>
+
+#include "internal/constants.h"
+
+using android::base::ScopedLockAssertion;
+using android::base::unique_fd;
+using namespace adb::crypto;
+using namespace adb::pairing;
+
+// The implementation has two background threads running: one to handle and
+// accept any new pairing connection requests (socket accept), and the other to
+// handle connection events (connection started, connection finished).
+struct PairingServerCtx {
+  public:
+    using Data = std::vector<uint8_t>;
+
+    virtual ~PairingServerCtx();
+
+    // All parameters must be non-empty.
+    explicit PairingServerCtx(const Data& pswd, const PeerInfo& peer_info, const Data& cert,
+                              const Data& priv_key, uint16_t port);
+
+    // Starts the pairing server. This call is non-blocking. Upon completion,
+    // if the pairing was successful, then |cb| will be called with the PublicKeyHeader
+    // containing the info of the trusted peer. Otherwise, |cb| will be
+    // called with an empty value. Start can only be called once in the lifetime
+    // of this object.
+    //
+    // Returns the port number if PairingServerCtx was successfully started. Otherwise,
+    // returns 0.
+    uint16_t Start(pairing_server_result_cb cb, void* opaque);
+
+  private:
+    // Setup the server socket to accept incoming connections. Returns the
+    // server port number (> 0 on success).
+    uint16_t SetupServer();
+    // Force stop the server thread.
+    void StopServer();
+
+    // handles a new pairing client connection
+    bool HandleNewClientConnection(int fd) EXCLUDES(conn_mutex_);
+
+    // ======== connection events thread =============
+    std::mutex conn_mutex_;
+    std::condition_variable conn_cv_;
+
+    using FdVal = int;
+    struct ConnectionDeleter {
+        void operator()(PairingConnectionCtx* p) { pairing_connection_destroy(p); }
+    };
+    using ConnectionPtr = std::unique_ptr<PairingConnectionCtx, ConnectionDeleter>;
+    static ConnectionPtr CreatePairingConnection(const Data& pswd, const PeerInfo& peer_info,
+                                                 const Data& cert, const Data& priv_key);
+    using NewConnectionEvent = std::tuple<unique_fd, ConnectionPtr>;
+    // <fd, PeerInfo.type, PeerInfo.data>
+    using ConnectionFinishedEvent = std::tuple<FdVal, uint8_t, std::optional<std::string>>;
+    using ConnectionEvent = std::variant<NewConnectionEvent, ConnectionFinishedEvent>;
+    // Queue for connections to write into. We have a separate queue to read
+    // from, in order to minimize the time the server thread is blocked.
+    std::deque<ConnectionEvent> conn_write_queue_ GUARDED_BY(conn_mutex_);
+    std::deque<ConnectionEvent> conn_read_queue_;
+    // Map of fds to their PairingConnections currently running.
+    std::unordered_map<FdVal, ConnectionPtr> connections_;
+
+    // Two threads launched when starting the pairing server:
+    // 1) A server thread that waits for incoming client connections, and
+    // 2) A connection events thread that synchonizes events from all of the
+    //    clients, since each PairingConnection is running in it's own thread.
+    void StartConnectionEventsThread();
+    void StartServerThread();
+
+    static void PairingConnectionCallback(const PeerInfo* peer_info, int fd, void* opaque);
+
+    std::thread conn_events_thread_;
+    void ConnectionEventsWorker();
+    std::thread server_thread_;
+    void ServerWorker();
+    bool is_terminate_ GUARDED_BY(conn_mutex_) = false;
+
+    enum class State {
+        Ready,
+        Running,
+        Stopped,
+    };
+    State state_ = State::Ready;
+    Data pswd_;
+    PeerInfo peer_info_;
+    Data cert_;
+    Data priv_key_;
+    uint16_t port_;
+
+    pairing_server_result_cb cb_;
+    void* opaque_ = nullptr;
+    bool got_valid_pairing_ = false;
+
+    static const int kEpollConstSocket = 0;
+    // Used to break the server thread from epoll_wait
+    static const int kEpollConstEventFd = 1;
+    unique_fd epoll_fd_;
+    unique_fd server_fd_;
+    unique_fd event_fd_;
+};  // PairingServerCtx
+
+// static
+PairingServerCtx::ConnectionPtr PairingServerCtx::CreatePairingConnection(const Data& pswd,
+                                                                          const PeerInfo& peer_info,
+                                                                          const Data& cert,
+                                                                          const Data& priv_key) {
+    return ConnectionPtr(pairing_connection_server_new(pswd.data(), pswd.size(), &peer_info,
+                                                       cert.data(), cert.size(), priv_key.data(),
+                                                       priv_key.size()));
+}
+
+PairingServerCtx::PairingServerCtx(const Data& pswd, const PeerInfo& peer_info, const Data& cert,
+                                   const Data& priv_key, uint16_t port)
+    : pswd_(pswd), peer_info_(peer_info), cert_(cert), priv_key_(priv_key), port_(port) {
+    CHECK(!pswd_.empty() && !cert_.empty() && !priv_key_.empty());
+}
+
+PairingServerCtx::~PairingServerCtx() {
+    // Since these connections have references to us, let's make sure they
+    // destruct before us.
+    if (server_thread_.joinable()) {
+        StopServer();
+        server_thread_.join();
+    }
+
+    {
+        std::lock_guard<std::mutex> lock(conn_mutex_);
+        is_terminate_ = true;
+    }
+    conn_cv_.notify_one();
+    if (conn_events_thread_.joinable()) {
+        conn_events_thread_.join();
+    }
+
+    // Notify the cb_ if it hasn't already.
+    if (!got_valid_pairing_ && cb_ != nullptr) {
+        cb_(nullptr, opaque_);
+    }
+}
+
+uint16_t PairingServerCtx::Start(pairing_server_result_cb cb, void* opaque) {
+    cb_ = cb;
+    opaque_ = opaque;
+
+    if (state_ != State::Ready) {
+        LOG(ERROR) << "PairingServerCtx already running or stopped";
+        return 0;
+    }
+
+    port_ = SetupServer();
+    if (port_ == 0) {
+        LOG(ERROR) << "Unable to start PairingServer";
+        state_ = State::Stopped;
+        return 0;
+    }
+    LOG(INFO) << "Pairing server started on port " << port_;
+
+    state_ = State::Running;
+    return port_;
+}
+
+void PairingServerCtx::StopServer() {
+    if (event_fd_.get() == -1) {
+        return;
+    }
+    uint64_t value = 1;
+    ssize_t rc = write(event_fd_.get(), &value, sizeof(value));
+    if (rc == -1) {
+        // This can happen if the server didn't start.
+        PLOG(ERROR) << "write to eventfd failed";
+    } else if (rc != sizeof(value)) {
+        LOG(FATAL) << "write to event returned short (" << rc << ")";
+    }
+}
+
+uint16_t PairingServerCtx::SetupServer() {
+    epoll_fd_.reset(epoll_create1(EPOLL_CLOEXEC));
+    if (epoll_fd_ == -1) {
+        PLOG(ERROR) << "failed to create epoll fd";
+        return 0;
+    }
+
+    event_fd_.reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
+    if (event_fd_ == -1) {
+        PLOG(ERROR) << "failed to create eventfd";
+        return 0;
+    }
+
+    server_fd_.reset(socket_inaddr_any_server(port_, SOCK_STREAM));
+    if (server_fd_.get() == -1) {
+        PLOG(ERROR) << "Failed to start pairing connection server";
+        return 0;
+    } else if (fcntl(server_fd_.get(), F_SETFD, FD_CLOEXEC) != 0) {
+        PLOG(ERROR) << "Failed to make server socket cloexec";
+        return 0;
+    } else if (fcntl(server_fd_.get(), F_SETFD, O_NONBLOCK) != 0) {
+        PLOG(ERROR) << "Failed to make server socket nonblocking";
+        return 0;
+    }
+
+    StartConnectionEventsThread();
+    StartServerThread();
+    int port = socket_get_local_port(server_fd_.get());
+    return (port <= 0 ? 0 : port);
+}
+
+void PairingServerCtx::StartServerThread() {
+    server_thread_ = std::thread([this]() { ServerWorker(); });
+}
+
+void PairingServerCtx::StartConnectionEventsThread() {
+    conn_events_thread_ = std::thread([this]() { ConnectionEventsWorker(); });
+}
+
+void PairingServerCtx::ServerWorker() {
+    {
+        struct epoll_event event;
+        event.events = EPOLLIN;
+        event.data.u64 = kEpollConstSocket;
+        CHECK_EQ(0, epoll_ctl(epoll_fd_.get(), EPOLL_CTL_ADD, server_fd_.get(), &event));
+    }
+
+    {
+        struct epoll_event event;
+        event.events = EPOLLIN;
+        event.data.u64 = kEpollConstEventFd;
+        CHECK_EQ(0, epoll_ctl(epoll_fd_.get(), EPOLL_CTL_ADD, event_fd_.get(), &event));
+    }
+
+    while (true) {
+        struct epoll_event events[2];
+        int rc = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd_.get(), events, 2, -1));
+        if (rc == -1) {
+            PLOG(ERROR) << "epoll_wait failed";
+            return;
+        } else if (rc == 0) {
+            LOG(ERROR) << "epoll_wait returned 0";
+            return;
+        }
+
+        for (int i = 0; i < rc; ++i) {
+            struct epoll_event& event = events[i];
+            switch (event.data.u64) {
+                case kEpollConstSocket:
+                    HandleNewClientConnection(server_fd_.get());
+                    break;
+                case kEpollConstEventFd:
+                    uint64_t dummy;
+                    int rc = TEMP_FAILURE_RETRY(read(event_fd_.get(), &dummy, sizeof(dummy)));
+                    if (rc != sizeof(dummy)) {
+                        PLOG(FATAL) << "failed to read from eventfd (rc=" << rc << ")";
+                    }
+                    return;
+            }
+        }
+    }
+}
+
+// static
+void PairingServerCtx::PairingConnectionCallback(const PeerInfo* peer_info, int fd, void* opaque) {
+    auto* p = reinterpret_cast<PairingServerCtx*>(opaque);
+
+    ConnectionFinishedEvent event;
+    if (peer_info != nullptr) {
+        if (peer_info->type == ADB_RSA_PUB_KEY) {
+            event = std::make_tuple(fd, peer_info->type,
+                                    std::string(reinterpret_cast<const char*>(peer_info->data)));
+        } else {
+            LOG(WARNING) << "Ignoring successful pairing because of unknown "
+                         << "PeerInfo type=" << peer_info->type;
+        }
+    } else {
+        event = std::make_tuple(fd, 0, std::nullopt);
+    }
+    {
+        std::lock_guard<std::mutex> lock(p->conn_mutex_);
+        p->conn_write_queue_.push_back(std::move(event));
+    }
+    p->conn_cv_.notify_one();
+}
+
+void PairingServerCtx::ConnectionEventsWorker() {
+    uint8_t num_tries = 0;
+    for (;;) {
+        // Transfer the write queue to the read queue.
+        {
+            std::unique_lock<std::mutex> lock(conn_mutex_);
+            ScopedLockAssertion assume_locked(conn_mutex_);
+
+            if (is_terminate_) {
+                // We check |is_terminate_| twice because condition_variable's
+                // notify() only wakes up a thread if it is in the wait state
+                // prior to notify(). Furthermore, we aren't holding the mutex
+                // when processing the events in |conn_read_queue_|.
+                return;
+            }
+            if (conn_write_queue_.empty()) {
+                // We need to wait for new events, or the termination signal.
+                conn_cv_.wait(lock, [this]() REQUIRES(conn_mutex_) {
+                    return (is_terminate_ || !conn_write_queue_.empty());
+                });
+            }
+            if (is_terminate_) {
+                // We're done.
+                return;
+            }
+            // Move all events into the read queue.
+            conn_read_queue_ = std::move(conn_write_queue_);
+            conn_write_queue_.clear();
+        }
+
+        // Process all events in the read queue.
+        while (conn_read_queue_.size() > 0) {
+            auto& event = conn_read_queue_.front();
+            if (auto* p = std::get_if<NewConnectionEvent>(&event)) {
+                // Ignore if we are already at the max number of connections
+                if (connections_.size() >= internal::kMaxConnections) {
+                    conn_read_queue_.pop_front();
+                    continue;
+                }
+                auto [ufd, connection] = std::move(*p);
+                int fd = ufd.release();
+                bool started = pairing_connection_start(connection.get(), fd,
+                                                        PairingConnectionCallback, this);
+                if (!started) {
+                    LOG(ERROR) << "PairingServer unable to start a PairingConnection fd=" << fd;
+                    ufd.reset(fd);
+                } else {
+                    connections_[fd] = std::move(connection);
+                }
+            } else if (auto* p = std::get_if<ConnectionFinishedEvent>(&event)) {
+                auto [fd, info_type, public_key] = std::move(*p);
+                if (public_key.has_value() && !public_key->empty()) {
+                    // Valid pairing. Let's shutdown the server and close any
+                    // pairing connections in progress.
+                    StopServer();
+                    connections_.clear();
+
+                    PeerInfo info = {};
+                    info.type = info_type;
+                    strncpy(reinterpret_cast<char*>(info.data), public_key->data(),
+                            public_key->size());
+
+                    cb_(&info, opaque_);
+
+                    got_valid_pairing_ = true;
+                    return;
+                }
+                // Invalid pairing. Close the invalid connection.
+                if (connections_.find(fd) != connections_.end()) {
+                    connections_.erase(fd);
+                }
+
+                if (++num_tries >= internal::kMaxPairingAttempts) {
+                    cb_(nullptr, opaque_);
+                    // To prevent the destructor from calling it again.
+                    cb_ = nullptr;
+                    return;
+                }
+            }
+            conn_read_queue_.pop_front();
+        }
+    }
+}
+
+bool PairingServerCtx::HandleNewClientConnection(int fd) {
+    unique_fd ufd(TEMP_FAILURE_RETRY(accept4(fd, nullptr, nullptr, SOCK_CLOEXEC)));
+    if (ufd == -1) {
+        PLOG(WARNING) << "adb_socket_accept failed fd=" << fd;
+        return false;
+    }
+    auto connection = CreatePairingConnection(pswd_, peer_info_, cert_, priv_key_);
+    if (connection == nullptr) {
+        LOG(ERROR) << "PairingServer unable to create a PairingConnection fd=" << fd;
+        return false;
+    }
+    // send the new connection to the connection thread for further processing
+    NewConnectionEvent event = std::make_tuple(std::move(ufd), std::move(connection));
+    {
+        std::lock_guard<std::mutex> lock(conn_mutex_);
+        conn_write_queue_.push_back(std::move(event));
+    }
+    conn_cv_.notify_one();
+
+    return true;
+}
+
+uint16_t pairing_server_start(PairingServerCtx* ctx, pairing_server_result_cb cb, void* opaque) {
+    return ctx->Start(cb, opaque);
+}
+
+PairingServerCtx* pairing_server_new(const uint8_t* pswd, size_t pswd_len,
+                                     const PeerInfo* peer_info, const uint8_t* x509_cert_pem,
+                                     size_t x509_size, const uint8_t* priv_key_pem,
+                                     size_t priv_size, uint16_t port) {
+    CHECK(pswd);
+    CHECK_GT(pswd_len, 0U);
+    CHECK(x509_cert_pem);
+    CHECK_GT(x509_size, 0U);
+    CHECK(priv_key_pem);
+    CHECK_GT(priv_size, 0U);
+    CHECK(peer_info);
+    std::vector<uint8_t> vec_pswd(pswd, pswd + pswd_len);
+    std::vector<uint8_t> vec_x509_cert(x509_cert_pem, x509_cert_pem + x509_size);
+    std::vector<uint8_t> vec_priv_key(priv_key_pem, priv_key_pem + priv_size);
+    return new PairingServerCtx(vec_pswd, *peer_info, vec_x509_cert, vec_priv_key, port);
+}
+
+PairingServerCtx* pairing_server_new_no_cert(const uint8_t* pswd, size_t pswd_len,
+                                             const PeerInfo* peer_info, uint16_t port) {
+    auto rsa_2048 = CreateRSA2048Key();
+    auto x509_cert = GenerateX509Certificate(rsa_2048->GetEvpPkey());
+    std::string pkey_pem = Key::ToPEMString(rsa_2048->GetEvpPkey());
+    std::string cert_pem = X509ToPEMString(x509_cert.get());
+
+    return pairing_server_new(pswd, pswd_len, peer_info,
+                              reinterpret_cast<const uint8_t*>(cert_pem.data()), cert_pem.size(),
+                              reinterpret_cast<const uint8_t*>(pkey_pem.data()), pkey_pem.size(),
+                              port);
+}
+
+void pairing_server_destroy(PairingServerCtx* ctx) {
+    CHECK(ctx);
+    delete ctx;
+}
diff --git a/adb/pairing_connection/tests/Android.bp b/adb/pairing_connection/tests/Android.bp
new file mode 100644
index 0000000..bf075bc
--- /dev/null
+++ b/adb/pairing_connection/tests/Android.bp
@@ -0,0 +1,47 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+    name: "adb_pairing_connection_test",
+    srcs: [
+        "pairing_client.cpp",
+        "pairing_connection_test.cpp",
+    ],
+
+    compile_multilib: "first",
+
+    shared_libs: [
+        "libbase",
+        "libcutils",
+        "libcrypto",
+        "libcrypto_utils",
+        "libprotobuf-cpp-lite",
+        "libssl",
+    ],
+
+    // Let's statically link them so we don't have to install it onto the
+    // system image for testing.
+    static_libs: [
+        "libadb_pairing_auth_static",
+        "libadb_pairing_connection_static",
+        "libadb_pairing_server_static",
+        "libadb_crypto_static",
+        "libadb_protos_static",
+        "libadb_tls_connection_static",
+    ],
+
+    test_suites: ["device-tests"],
+}
diff --git a/adb/pairing_connection/tests/pairing_client.cpp b/adb/pairing_connection/tests/pairing_client.cpp
new file mode 100644
index 0000000..1f3ef5a
--- /dev/null
+++ b/adb/pairing_connection/tests/pairing_client.cpp
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "pairing_client.h"
+
+#include <netdb.h>
+#include <netinet/tcp.h>
+
+#include <atomic>
+#include <iomanip>
+#include <mutex>
+#include <sstream>
+#include <thread>
+#include <vector>
+
+#include <android-base/logging.h>
+#include <android-base/parsenetaddress.h>
+#include <android-base/stringprintf.h>
+#include <android-base/thread_annotations.h>
+#include <android-base/unique_fd.h>
+#include <cutils/sockets.h>
+
+namespace adb {
+namespace pairing {
+
+using android::base::unique_fd;
+
+static void ConnectionDeleter(PairingConnectionCtx* p) {
+    pairing_connection_destroy(p);
+}
+using ConnectionPtr = std::unique_ptr<PairingConnectionCtx, decltype(&ConnectionDeleter)>;
+
+namespace {
+
+class PairingClientImpl : public PairingClient {
+  public:
+    explicit PairingClientImpl(const Data& pswd, const PeerInfo& peer_info, const Data& cert,
+                               const Data& priv_key);
+
+    // Starts the pairing client. This call is non-blocking. Upon pairing
+    // completion, |cb| will be called with the PeerInfo on success,
+    // or an empty value on failure.
+    //
+    // Returns true if PairingClient was successfully started. Otherwise,
+    // return false.
+    virtual bool Start(std::string_view ip_addr, pairing_client_result_cb cb,
+                       void* opaque) override;
+
+  private:
+    static ConnectionPtr CreatePairingConnection(const Data& pswd, const PeerInfo& peer_info,
+                                                 const Data& cert, const Data& priv_key);
+
+    static void PairingResultCallback(const PeerInfo* peer_info, int fd, void* opaque);
+    // Setup and start the PairingConnection
+    bool StartConnection();
+
+    enum class State {
+        Ready,
+        Running,
+        Stopped,
+    };
+
+    State state_ = State::Ready;
+    Data pswd_;
+    PeerInfo peer_info_;
+    Data cert_;
+    Data priv_key_;
+    std::string host_;
+    int port_;
+
+    ConnectionPtr connection_;
+    pairing_client_result_cb cb_;
+    void* opaque_ = nullptr;
+};  // PairingClientImpl
+
+// static
+ConnectionPtr PairingClientImpl::CreatePairingConnection(const Data& pswd,
+                                                         const PeerInfo& peer_info,
+                                                         const Data& cert, const Data& priv_key) {
+    return ConnectionPtr(
+            pairing_connection_client_new(pswd.data(), pswd.size(), &peer_info, cert.data(),
+                                          cert.size(), priv_key.data(), priv_key.size()),
+            ConnectionDeleter);
+}
+
+PairingClientImpl::PairingClientImpl(const Data& pswd, const PeerInfo& peer_info, const Data& cert,
+                                     const Data& priv_key)
+    : pswd_(pswd),
+      peer_info_(peer_info),
+      cert_(cert),
+      priv_key_(priv_key),
+      connection_(nullptr, ConnectionDeleter) {
+    CHECK(!pswd_.empty() && !cert_.empty() && !priv_key_.empty());
+
+    state_ = State::Ready;
+}
+
+bool PairingClientImpl::Start(std::string_view ip_addr, pairing_client_result_cb cb, void* opaque) {
+    CHECK(!ip_addr.empty());
+    cb_ = cb;
+    opaque_ = opaque;
+
+    if (state_ != State::Ready) {
+        LOG(ERROR) << "PairingClient already running or finished";
+        return false;
+    }
+
+    // Try to parse the host address
+    std::string err;
+    CHECK(android::base::ParseNetAddress(std::string(ip_addr), &host_, &port_, nullptr, &err));
+    CHECK(port_ > 0 && port_ <= 65535);
+
+    if (!StartConnection()) {
+        LOG(ERROR) << "Unable to start PairingClient connection";
+        state_ = State::Stopped;
+        return false;
+    }
+
+    state_ = State::Running;
+    return true;
+}
+
+static int network_connect(const std::string& host, int port, int type, int timeout,
+                           std::string* error) {
+    int getaddrinfo_error = 0;
+    int fd = socket_network_client_timeout(host.c_str(), port, type, timeout, &getaddrinfo_error);
+    if (fd != -1) {
+        return fd;
+    }
+    if (getaddrinfo_error != 0) {
+        *error = android::base::StringPrintf("failed to resolve host: '%s': %s", host.c_str(),
+                                             gai_strerror(getaddrinfo_error));
+        LOG(WARNING) << *error;
+    } else {
+        *error = android::base::StringPrintf("failed to connect to '%s:%d': %s", host.c_str(), port,
+                                             strerror(errno));
+        LOG(WARNING) << *error;
+    }
+    return -1;
+}
+
+// static
+void PairingClientImpl::PairingResultCallback(const PeerInfo* peer_info, int /* fd */,
+                                              void* opaque) {
+    auto* p = reinterpret_cast<PairingClientImpl*>(opaque);
+    p->cb_(peer_info, p->opaque_);
+}
+
+bool PairingClientImpl::StartConnection() {
+    std::string err;
+    const int timeout = 10;  // seconds
+    unique_fd fd(network_connect(host_, port_, SOCK_STREAM, timeout, &err));
+    if (fd.get() == -1) {
+        LOG(ERROR) << "Failed to start pairing connection client [" << err << "]";
+        return false;
+    }
+    int off = 1;
+    setsockopt(fd.get(), IPPROTO_TCP, TCP_NODELAY, &off, sizeof(off));
+
+    connection_ = CreatePairingConnection(pswd_, peer_info_, cert_, priv_key_);
+    if (connection_ == nullptr) {
+        LOG(ERROR) << "PairingClient unable to create a PairingConnection";
+        return false;
+    }
+
+    if (!pairing_connection_start(connection_.get(), fd.release(), PairingResultCallback, this)) {
+        LOG(ERROR) << "PairingClient failed to start the PairingConnection";
+        state_ = State::Stopped;
+        return false;
+    }
+
+    return true;
+}
+
+}  // namespace
+
+// static
+std::unique_ptr<PairingClient> PairingClient::Create(const Data& pswd, const PeerInfo& peer_info,
+                                                     const Data& cert, const Data& priv_key) {
+    CHECK(!pswd.empty());
+    CHECK(!cert.empty());
+    CHECK(!priv_key.empty());
+
+    return std::unique_ptr<PairingClient>(new PairingClientImpl(pswd, peer_info, cert, priv_key));
+}
+
+}  // namespace pairing
+}  // namespace adb
diff --git a/adb/pairing_connection/tests/pairing_client.h b/adb/pairing_connection/tests/pairing_client.h
new file mode 100644
index 0000000..be0db5c
--- /dev/null
+++ b/adb/pairing_connection/tests/pairing_client.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <functional>
+#include <memory>
+#include <string_view>
+#include <vector>
+
+#include "adb/pairing/pairing_connection.h"
+
+typedef void (*pairing_client_result_cb)(const PeerInfo*, void*);
+
+namespace adb {
+namespace pairing {
+
+// PairingClient is the client side of the PairingConnection protocol. It will
+// attempt to connect to a PairingServer specified at |host| and |port|, and
+// allocate a new PairingConnection for processing.
+//
+// See pairing_connection_test.cpp for example usage.
+//
+class PairingClient {
+  public:
+    using Data = std::vector<uint8_t>;
+
+    virtual ~PairingClient() = default;
+
+    // Starts the pairing client. This call is non-blocking. Upon completion,
+    // if the pairing was successful, then |cb| will be called with the PeerInfo
+    // containing the info of the trusted peer. Otherwise, |cb| will be
+    // called with an empty value. Start can only be called once in the lifetime
+    // of this object. |ip_addr| requires a port to be specified.
+    //
+    // Returns true if PairingClient was successfully started. Otherwise,
+    // returns false.
+    virtual bool Start(std::string_view ip_addr, pairing_client_result_cb cb, void* opaque) = 0;
+
+    // Creates a new PairingClient instance. May return null if unable
+    // to create an instance. |pswd|, |certificate|, |priv_key| and
+    // |ip_addr| cannot be empty. |peer_info| must contain non-empty strings for
+    // the guid and name fields.
+    static std::unique_ptr<PairingClient> Create(const Data& pswd, const PeerInfo& peer_info,
+                                                 const Data& certificate, const Data& priv_key);
+
+  protected:
+    PairingClient() = default;
+};  // class PairingClient
+
+}  // namespace pairing
+}  // namespace adb
diff --git a/adb/pairing_connection/tests/pairing_connection_test.cpp b/adb/pairing_connection/tests/pairing_connection_test.cpp
new file mode 100644
index 0000000..b6e09f1
--- /dev/null
+++ b/adb/pairing_connection/tests/pairing_connection_test.cpp
@@ -0,0 +1,500 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AdbPairingConnectionTest"
+
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+
+#include <adb/pairing/pairing_server.h>
+#include <android-base/logging.h>
+#include <android-base/strings.h>
+#include <gtest/gtest.h>
+
+#include "../internal/constants.h"
+#include "pairing_client.h"
+
+using namespace std::chrono_literals;
+
+namespace adb {
+namespace pairing {
+
+// Test X.509 certificates (RSA 2048)
+static const std::string kTestRsa2048ServerCert =
+        "-----BEGIN CERTIFICATE-----\n"
+        "MIIDFzCCAf+gAwIBAgIBATANBgkqhkiG9w0BAQsFADAtMQswCQYDVQQGEwJVUzEQ\n"
+        "MA4GA1UECgwHQW5kcm9pZDEMMAoGA1UEAwwDQWRiMB4XDTIwMDEyMTIyMjU1NVoX\n"
+        "DTMwMDExODIyMjU1NVowLTELMAkGA1UEBhMCVVMxEDAOBgNVBAoMB0FuZHJvaWQx\n"
+        "DDAKBgNVBAMMA0FkYjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK8E\n"
+        "2Ck9TfuKlz7wqWdMfknjZ1luFDp2IHxAUZzh/F6jeI2dOFGAjpeloSnGOE86FIaT\n"
+        "d1EvpyTh7nBwbrLZAA6XFZTo7Bl6BdNOQdqb2d2+cLEN0inFxqUIycevRtohUE1Y\n"
+        "FHM9fg442X1jOTWXjDZWeiqFWo95paAPhzm6pWqfJK1+YKfT1LsWZpYqJGGQE5pi\n"
+        "C3qOBYYgFpoXMxTYJNoZo3uOYEdM6upc8/vh15nMgIxX/ymJxEY5BHPpZPPWjXLg\n"
+        "BfzVaV9fUfv0JT4HQ4t2WvxC3cD/UsjWp2a6p454uUp2ENrANa+jRdRJepepg9D2\n"
+        "DKsx9L8zjc5Obqexrt0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B\n"
+        "Af8EBAMCAYYwHQYDVR0OBBYEFDFW+8GTErwoZN5Uu9KyY4QdGYKpMA0GCSqGSIb3\n"
+        "DQEBCwUAA4IBAQBCDEn6SHXGlq5TU7J8cg1kRPd9bsJW+0hDuKSq0REXDkl0PcBf\n"
+        "fy282Agg9enKPPKmnpeQjM1dmnxdM8tT8LIUbMl779i3fn6v9HJVB+yG4gmRFThW\n"
+        "c+AGlBnrIT820cX/gU3h3R3FTahfsq+1rrSJkEgHyuC0HYeRyveSckBdaEOLvx0S\n"
+        "toun+32JJl5hWydpUUZhE9Mbb3KHBRM2YYZZU9JeJ08Apjl+3lRUeMAUwI5fkAAu\n"
+        "z/1SqnuGL96bd8P5ixdkA1+rF8FPhodGcq9mQOuUGP9g5HOXjaNoJYvwVRUdLeGh\n"
+        "cP/ReOTwQIzM1K5a83p8cX8AGGYmM7dQp7ec\n"
+        "-----END CERTIFICATE-----\n";
+
+static const std::string kTestRsa2048ServerPrivKey =
+        "-----BEGIN PRIVATE KEY-----\n"
+        "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCvBNgpPU37ipc+\n"
+        "8KlnTH5J42dZbhQ6diB8QFGc4fxeo3iNnThRgI6XpaEpxjhPOhSGk3dRL6ck4e5w\n"
+        "cG6y2QAOlxWU6OwZegXTTkHam9ndvnCxDdIpxcalCMnHr0baIVBNWBRzPX4OONl9\n"
+        "Yzk1l4w2VnoqhVqPeaWgD4c5uqVqnyStfmCn09S7FmaWKiRhkBOaYgt6jgWGIBaa\n"
+        "FzMU2CTaGaN7jmBHTOrqXPP74deZzICMV/8picRGOQRz6WTz1o1y4AX81WlfX1H7\n"
+        "9CU+B0OLdlr8Qt3A/1LI1qdmuqeOeLlKdhDawDWvo0XUSXqXqYPQ9gyrMfS/M43O\n"
+        "Tm6nsa7dAgMBAAECggEAFCS2bPdUKIgjbzLgtHW+hT+J2hD20rcHdyAp+dNH/2vI\n"
+        "yLfDJHJA4chGMRondKA704oDw2bSJxxlG9t83326lB35yxPhye7cM8fqgWrK8PVl\n"
+        "tU22FhO1ZgeJvb9OeXWNxKZyDW9oOOJ8eazNXVMuEo+dFj7B6l3MXQyHJPL2mJDm\n"
+        "u9ofFLdypX+gJncVO0oW0FNJnEUn2MMwHDNlo7gc4WdQuidPkuZItKRGcB8TTGF3\n"
+        "Ka1/2taYdTQ4Aq//Z84LlFvE0zD3T4c8LwYYzOzD4gGGTXvft7vSHzIun1S8YLRS\n"
+        "dEKXdVjtaFhgH3uUe4j+1b/vMvSHeoGBNX/G88GD+wKBgQDWUYVlMVqc9HD2IeYi\n"
+        "EfBcNwAJFJkh51yAl5QbUBgFYgFJVkkS/EDxEGFPvEmI3/pAeQFHFY13BI466EPs\n"
+        "o8Z8UUwWDp+Z1MFHHKQKnFakbsZbZlbqjJ9VJsqpezbpWhMHTOmcG0dmE7rf0lyM\n"
+        "eQv9slBB8qp2NEUs5Of7f2C2bwKBgQDRDq4nUuMQF1hbjM05tGKSIwkobmGsLspv\n"
+        "TMhkM7fq4RpbFHmbNgsFqMhcqYZ8gY6/scv5KCuAZ4yHUkbqwf5h+QCwrJ4uJeUJ\n"
+        "ZgJfHus2mmcNSo8FwSkNoojIQtzcbJav7bs2K9VTuertk/i7IJLApU4FOZZ5pghN\n"
+        "EXu0CZF1cwKBgDWFGhjRIF29tU/h20R60llU6s9Zs3wB+NmsALJpZ/ZAKS4VPB5f\n"
+        "nCAXBRYSYRKrTCU5kpYbzb4BBzuysPOxWmnFK4j+keCqfrGxd02nCQP7HdHJVr8v\n"
+        "6sIq88UrHeVcNxBFprjzHvtgxfQK5k22FMZ/9wbhAKyQFQ5HA5+MiaxFAoGAIcZZ\n"
+        "ZIkDninnYIMS9OursShv5lRO+15j3i9tgKLKZ+wOMgDQ1L6acUOfezj4PU1BHr8+\n"
+        "0PYocQpJreMhCfRlgLaV4fVBaPs+UZJld7CrF5tCYudUy/01ALrtlk0XGZWBktK5\n"
+        "mDrksC4tQkzRtonAq9cJD9cJ9IVaefkFH0UcdvkCgYBpZj50VLeGhnHHBnkJRlV1\n"
+        "fV+/P6PAq6RtqjA6O9Qdaoj5V3w2d63aQcQXQLJjH2BBmtCIy47r04rFvZpbCxP7\n"
+        "NH/OnK9NHpk2ucRTe8TAnVbvF/TZzPJoIxAO/D3OWaW6df4R8en8u6GYzWFglAyT\n"
+        "sydGT8yfWD1FYUWgfrVRbg==\n"
+        "-----END PRIVATE KEY-----\n";
+
+static const std::string kTestRsa2048ClientCert =
+        "-----BEGIN CERTIFICATE-----\n"
+        "MIIDFzCCAf+gAwIBAgIBATANBgkqhkiG9w0BAQsFADAtMQswCQYDVQQGEwJVUzEQ\n"
+        "MA4GA1UECgwHQW5kcm9pZDEMMAoGA1UEAwwDQWRiMB4XDTIwMDEyMTIyMjU1NloX\n"
+        "DTMwMDExODIyMjU1NlowLTELMAkGA1UEBhMCVVMxEDAOBgNVBAoMB0FuZHJvaWQx\n"
+        "DDAKBgNVBAMMA0FkYjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAI3a\n"
+        "EXh1S5FTbet7JVONswffRPaekdIK53cb8SnAbSO9X5OLA4zGwdkrBvDTsd96SKrp\n"
+        "JxmoNOE1DhbZh05KPlWAPkGKacjGWaz+S7biDOL0I6aaLbTlU/il1Ub9olPSBVUx\n"
+        "0nhdtEFgIOzddnP6/1KmyIIeRxS5lTKeg4avqUkZNXkz/wL1dHBFL7FNFf0SCcbo\n"
+        "tsub/deFbjZ27LTDN+SIBgFttTNqC5NTvoBAoMdyCOAgNYwaHO+fKiK3edfJieaw\n"
+        "7HD8qqmQxcpCtRlA8CUPj7GfR+WHiCJmlevhnkFXCo56R1BS0F4wuD4KPdSWt8gc\n"
+        "27ejH/9/z2cKo/6SLJMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B\n"
+        "Af8EBAMCAYYwHQYDVR0OBBYEFO/Mr5ygqqpyU/EHM9v7RDvcqaOkMA0GCSqGSIb3\n"
+        "DQEBCwUAA4IBAQAH33KMouzF2DYbjg90KDrDQr4rq3WfNb6P743knxdUFuvb+40U\n"
+        "QjC2OJZHkSexH7wfG/y6ic7vfCfF4clNs3QvU1lEjOZC57St8Fk7mdNdsWLwxEMD\n"
+        "uePFz0dvclSxNUHyCVMqNxddzQYzxiDWQRmXWrUBliMduQqEQelcxW2yDtg8bj+s\n"
+        "aMpR1ra9scaD4jzIZIIxLoOS9zBMuNRbgP217sZrniyGMhzoI1pZ/izN4oXpyH7O\n"
+        "THuaCzzRT3ph2f8EgmHSodz3ttgSf2DHzi/Ez1xUkk7NOlgNtmsxEdrM47+cC5ae\n"
+        "fIf2V+1o1JW8J7D11RmRbNPh3vfisueB4f88\n"
+        "-----END CERTIFICATE-----\n";
+
+static const std::string kTestRsa2048ClientPrivKey =
+        "-----BEGIN PRIVATE KEY-----\n"
+        "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCN2hF4dUuRU23r\n"
+        "eyVTjbMH30T2npHSCud3G/EpwG0jvV+TiwOMxsHZKwbw07Hfekiq6ScZqDThNQ4W\n"
+        "2YdOSj5VgD5BimnIxlms/ku24gzi9COmmi205VP4pdVG/aJT0gVVMdJ4XbRBYCDs\n"
+        "3XZz+v9SpsiCHkcUuZUynoOGr6lJGTV5M/8C9XRwRS+xTRX9EgnG6LbLm/3XhW42\n"
+        "duy0wzfkiAYBbbUzaguTU76AQKDHcgjgIDWMGhzvnyoit3nXyYnmsOxw/KqpkMXK\n"
+        "QrUZQPAlD4+xn0flh4giZpXr4Z5BVwqOekdQUtBeMLg+Cj3UlrfIHNu3ox//f89n\n"
+        "CqP+kiyTAgMBAAECggEAAa64eP6ggCob1P3c73oayYPIbvRqiQdAFOrr7Vwu7zbr\n"
+        "z0rde+n6RU0mrpc+4NuzyPMtrOGQiatLbidJB5Cx3z8U00ovqbCl7PtcgorOhFKe\n"
+        "VEzihebCcYyQqbWQcKtpDMhOgBxRwFoXieJb6VGXfa96FAZalCWvXgOrTl7/BF2X\n"
+        "qMqIm9nJi+yS5tIO8VdOsOmrMWRH/b/ENUcef4WpLoxTXr0EEgyKWraeZ/hhXo1e\n"
+        "z29dZKqdr9wMsq11NPsRddwS94jnDkXTo+EQyWVTfB7gb6yyp07s8jysaDb21tVv\n"
+        "UXB9MRhDV1mOv0ncXfXZ4/+4A2UahmZaLDAVLaat4QKBgQDAVRredhGRGl2Nkic3\n"
+        "KvZCAfyxug788CgasBdEiouz19iCCwcgMIDwnq0s3/WM7h/laCamT2x38riYDnpq\n"
+        "rkYMfuVtU9CjEL9pTrdfwbIRhTwYNqADaPz2mXwQUhRXutE5TIdgxxC/a+ZTh0qN\n"
+        "S+vhTj/4hf0IZhMh5Nqj7IPExQKBgQC8zxEzhmSGjys0GuE6Wl6Doo2TpiR6vwvi\n"
+        "xPLU9lmIz5eca/Rd/eERioFQqeoIWDLzx52DXuz6rUoQhbJWz9hP3yqCwXD+pbNP\n"
+        "oDJqDDbCC4IMYEb0IK/PEPH+gIpnTjoFcW+ecKDFG7W5Lt05J8WsJsfOaJvMrOU+\n"
+        "dLXq3IgxdwKBgQC5RAFq0v6e8G+3hFaEHL0z3igkpt3zJf7rnj37hx2FMmDa+3Z0\n"
+        "umQp5B9af61PgL12xLmeMBmC/Wp1BlVDV/Yf6Uhk5Hyv5t0KuomHEtTNbbLyfAPs\n"
+        "5P/vJu/L5NS1oT4S3LX3MineyjgGs+bLbpub3z1dzutrYLADUSiPCK/xJQKBgBQt\n"
+        "nQ0Ao+Wtj1R2OvPdjJRM3wyUiPmFSWPm4HzaBx+T8AQLlYYmB9O0FbXlMtnJc0iS\n"
+        "YMcVcgYoVu4FG9YjSF7g3s4yljzgwJUV7c1fmMqMKE3iTDLy+1cJ3JLycdgwiArk\n"
+        "4KTyLHxkRbuQwpvFIF8RlfD9RQlOwQE3v+llwDhpAoGBAL6XG6Rp6mBoD2Ds5c9R\n"
+        "943yYgSUes3ji1SI9zFqeJtj8Ml/enuK1xu+8E/BxB0//+vgZsH6i3i8GFwygKey\n"
+        "CGJF8CbiHc3EJc3NQIIRXcni/CGacf0HwC6m+PGFDBIpA4H2iDpVvCSofxttQiq0\n"
+        "/Z7HXmXUvZHVyYi/QzX2Gahj\n"
+        "-----END PRIVATE KEY-----\n";
+
+struct ServerDeleter {
+    void operator()(PairingServerCtx* p) { pairing_server_destroy(p); }
+};
+using ServerPtr = std::unique_ptr<PairingServerCtx, ServerDeleter>;
+
+struct ResultWaiter {
+    std::mutex mutex_;
+    std::condition_variable cv_;
+    std::optional<bool> is_valid_;
+    PeerInfo peer_info_;
+
+    static void ResultCallback(const PeerInfo* peer_info, void* opaque) {
+        auto* p = reinterpret_cast<ResultWaiter*>(opaque);
+        {
+            std::unique_lock<std::mutex> lock(p->mutex_);
+            if (peer_info) {
+                memcpy(&(p->peer_info_), peer_info, sizeof(PeerInfo));
+            }
+            p->is_valid_ = (peer_info != nullptr);
+        }
+        p->cv_.notify_one();
+    }
+};
+
+class AdbPairingConnectionTest : public testing::Test {
+  protected:
+    virtual void SetUp() override {}
+
+    virtual void TearDown() override {}
+
+    void InitPairing(const std::vector<uint8_t>& server_pswd,
+                     const std::vector<uint8_t>& client_pswd) {
+        server_ = CreateServer(server_pswd);
+        client_ = CreateClient(client_pswd);
+    }
+
+    ServerPtr CreateServer(const std::vector<uint8_t>& pswd) {
+        return CreateServer(pswd, &server_info_, kTestRsa2048ServerCert, kTestRsa2048ServerPrivKey,
+                            0);
+    }
+
+    std::unique_ptr<PairingClient> CreateClient(const std::vector<uint8_t> pswd) {
+        std::vector<uint8_t> cert;
+        std::vector<uint8_t> key;
+        // Include the null-byte as well.
+        cert.assign(reinterpret_cast<const uint8_t*>(kTestRsa2048ClientCert.data()),
+                    reinterpret_cast<const uint8_t*>(kTestRsa2048ClientCert.data()) +
+                            kTestRsa2048ClientCert.size() + 1);
+        key.assign(reinterpret_cast<const uint8_t*>(kTestRsa2048ClientPrivKey.data()),
+                   reinterpret_cast<const uint8_t*>(kTestRsa2048ClientPrivKey.data()) +
+                           kTestRsa2048ClientPrivKey.size() + 1);
+        return PairingClient::Create(pswd, client_info_, cert, key);
+    }
+
+    static ServerPtr CreateServer(const std::vector<uint8_t>& pswd, const PeerInfo* peer_info,
+                                  const std::string_view cert, const std::string_view priv_key,
+                                  int port) {
+        return ServerPtr(pairing_server_new(
+                pswd.data(), pswd.size(), peer_info, reinterpret_cast<const uint8_t*>(cert.data()),
+                cert.size(), reinterpret_cast<const uint8_t*>(priv_key.data()), priv_key.size(),
+                port));
+    }
+
+    ServerPtr server_;
+    const PeerInfo server_info_ = {
+            .type = ADB_DEVICE_GUID,
+            .data = "my_server_info",
+    };
+    std::unique_ptr<PairingClient> client_;
+    const PeerInfo client_info_ = {
+            .type = ADB_RSA_PUB_KEY,
+            .data = "my_client_info",
+    };
+    std::string ip_addr_ = "127.0.0.1:";
+};
+
+TEST_F(AdbPairingConnectionTest, ServerCreation) {
+    // All parameters bad
+    ASSERT_DEATH({ auto server = CreateServer({}, nullptr, "", "", 0); }, "");
+    // Bad password
+    ASSERT_DEATH(
+            {
+                auto server = CreateServer({}, &server_info_, kTestRsa2048ServerCert,
+                                           kTestRsa2048ServerPrivKey, 0);
+            },
+            "");
+    // Bad peer_info
+    ASSERT_DEATH(
+            {
+                auto server = CreateServer({0x01}, nullptr, kTestRsa2048ServerCert,
+                                           kTestRsa2048ServerPrivKey, 0);
+            },
+            "");
+    // Bad certificate
+    ASSERT_DEATH(
+            {
+                auto server = CreateServer({0x01}, &server_info_, "", kTestRsa2048ServerPrivKey, 0);
+            },
+            "");
+    // Bad private key
+    ASSERT_DEATH(
+            { auto server = CreateServer({0x01}, &server_info_, kTestRsa2048ServerCert, "", 0); },
+            "");
+    // Valid params
+    auto server = CreateServer({0x01}, &server_info_, kTestRsa2048ServerCert,
+                               kTestRsa2048ServerPrivKey, 0);
+    EXPECT_NE(nullptr, server);
+}
+
+TEST_F(AdbPairingConnectionTest, ClientCreation) {
+    std::vector<uint8_t> pswd{0x01, 0x03, 0x05, 0x07};
+    // Bad password
+    ASSERT_DEATH(
+            {
+                pairing_connection_client_new(
+                        nullptr, pswd.size(), &client_info_,
+                        reinterpret_cast<const uint8_t*>(kTestRsa2048ClientCert.data()),
+                        kTestRsa2048ClientCert.size(),
+                        reinterpret_cast<const uint8_t*>(kTestRsa2048ClientPrivKey.data()),
+                        kTestRsa2048ClientPrivKey.size());
+            },
+            "");
+    ASSERT_DEATH(
+            {
+                pairing_connection_client_new(
+                        pswd.data(), 0, &client_info_,
+                        reinterpret_cast<const uint8_t*>(kTestRsa2048ClientCert.data()),
+                        kTestRsa2048ClientCert.size(),
+                        reinterpret_cast<const uint8_t*>(kTestRsa2048ClientPrivKey.data()),
+                        kTestRsa2048ClientPrivKey.size());
+            },
+            "");
+
+    // Bad peer_info
+    ASSERT_DEATH(
+            {
+                pairing_connection_client_new(
+                        pswd.data(), pswd.size(), nullptr,
+                        reinterpret_cast<const uint8_t*>(kTestRsa2048ClientCert.data()),
+                        kTestRsa2048ClientCert.size(),
+                        reinterpret_cast<const uint8_t*>(kTestRsa2048ClientPrivKey.data()),
+                        kTestRsa2048ClientPrivKey.size());
+            },
+            "");
+
+    // Bad certificate
+    ASSERT_DEATH(
+            {
+                pairing_connection_client_new(
+                        pswd.data(), pswd.size(), &client_info_, nullptr,
+                        kTestRsa2048ClientCert.size(),
+                        reinterpret_cast<const uint8_t*>(kTestRsa2048ClientPrivKey.data()),
+                        kTestRsa2048ClientPrivKey.size());
+            },
+            "");
+    ASSERT_DEATH(
+            {
+                pairing_connection_client_new(
+                        pswd.data(), pswd.size(), &client_info_,
+                        reinterpret_cast<const uint8_t*>(kTestRsa2048ClientCert.data()), 0,
+                        reinterpret_cast<const uint8_t*>(kTestRsa2048ClientPrivKey.data()),
+                        kTestRsa2048ClientPrivKey.size());
+            },
+            "");
+
+    // Bad private key
+    ASSERT_DEATH(
+            {
+                pairing_connection_client_new(
+                        pswd.data(), pswd.size(), &client_info_,
+                        reinterpret_cast<const uint8_t*>(kTestRsa2048ClientCert.data()),
+                        kTestRsa2048ClientCert.size(), nullptr, kTestRsa2048ClientPrivKey.size());
+            },
+            "");
+    ASSERT_DEATH(
+            {
+                pairing_connection_client_new(
+                        pswd.data(), pswd.size(), &client_info_,
+                        reinterpret_cast<const uint8_t*>(kTestRsa2048ClientCert.data()),
+                        kTestRsa2048ClientCert.size(),
+                        reinterpret_cast<const uint8_t*>(kTestRsa2048ClientPrivKey.data()), 0);
+            },
+            "");
+
+    // Valid params
+    auto client = pairing_connection_client_new(
+            pswd.data(), pswd.size(), &client_info_,
+            reinterpret_cast<const uint8_t*>(kTestRsa2048ClientCert.data()),
+            kTestRsa2048ClientCert.size(),
+            reinterpret_cast<const uint8_t*>(kTestRsa2048ClientPrivKey.data()),
+            kTestRsa2048ClientPrivKey.size());
+    EXPECT_NE(nullptr, client);
+}
+
+TEST_F(AdbPairingConnectionTest, SmokeValidPairing) {
+    std::vector<uint8_t> pswd{0x01, 0x03, 0x05, 0x07};
+    InitPairing(pswd, pswd);
+
+    // Start the server
+    ResultWaiter server_waiter;
+    std::unique_lock<std::mutex> server_lock(server_waiter.mutex_);
+    auto port = pairing_server_start(server_.get(), server_waiter.ResultCallback, &server_waiter);
+    ASSERT_GT(port, 0);
+    ip_addr_ += std::to_string(port);
+
+    // Start the client
+    ResultWaiter client_waiter;
+    std::unique_lock<std::mutex> client_lock(client_waiter.mutex_);
+    ASSERT_TRUE(client_->Start(ip_addr_, client_waiter.ResultCallback, &client_waiter));
+    client_waiter.cv_.wait(client_lock, [&]() { return client_waiter.is_valid_.has_value(); });
+    ASSERT_TRUE(*(client_waiter.is_valid_));
+    ASSERT_EQ(strlen(reinterpret_cast<const char*>(client_waiter.peer_info_.data)),
+              strlen(reinterpret_cast<const char*>(server_info_.data)));
+    EXPECT_EQ(memcmp(client_waiter.peer_info_.data, server_info_.data, sizeof(server_info_.data)),
+              0);
+
+    // Kill server if the pairing failed, since server only shuts down when
+    // it gets a valid pairing.
+    if (!client_waiter.is_valid_) {
+        server_lock.unlock();
+        server_.reset();
+    } else {
+        server_waiter.cv_.wait(server_lock, [&]() { return server_waiter.is_valid_.has_value(); });
+        ASSERT_TRUE(*(server_waiter.is_valid_));
+        ASSERT_EQ(strlen(reinterpret_cast<const char*>(server_waiter.peer_info_.data)),
+                  strlen(reinterpret_cast<const char*>(client_info_.data)));
+        EXPECT_EQ(
+                memcmp(server_waiter.peer_info_.data, client_info_.data, sizeof(client_info_.data)),
+                0);
+    }
+}
+
+TEST_F(AdbPairingConnectionTest, CancelPairing) {
+    std::vector<uint8_t> pswd{0x01, 0x03, 0x05, 0x07};
+    std::vector<uint8_t> pswd2{0x01, 0x03, 0x05, 0x06};
+    InitPairing(pswd, pswd2);
+
+    // Start the server
+    ResultWaiter server_waiter;
+    std::unique_lock<std::mutex> server_lock(server_waiter.mutex_);
+    auto port = pairing_server_start(server_.get(), server_waiter.ResultCallback, &server_waiter);
+    ASSERT_GT(port, 0);
+    ip_addr_ += std::to_string(port);
+
+    // Start the client. Client should fail to pair
+    ResultWaiter client_waiter;
+    std::unique_lock<std::mutex> client_lock(client_waiter.mutex_);
+    ASSERT_TRUE(client_->Start(ip_addr_, client_waiter.ResultCallback, &client_waiter));
+    client_waiter.cv_.wait(client_lock, [&]() { return client_waiter.is_valid_.has_value(); });
+    ASSERT_FALSE(*(client_waiter.is_valid_));
+
+    // Kill the server. We should still receive the callback with no valid
+    // pairing.
+    server_lock.unlock();
+    server_.reset();
+    server_lock.lock();
+    ASSERT_TRUE(server_waiter.is_valid_.has_value());
+    EXPECT_FALSE(*(server_waiter.is_valid_));
+}
+
+TEST_F(AdbPairingConnectionTest, MultipleClientsAllFail) {
+    std::vector<uint8_t> pswd{0x01, 0x03, 0x05, 0x07};
+    std::vector<uint8_t> pswd2{0x01, 0x03, 0x05, 0x06};
+
+    // Start the server
+    auto server = CreateServer(pswd);
+    ResultWaiter server_waiter;
+    std::unique_lock<std::mutex> server_lock(server_waiter.mutex_);
+    auto port = pairing_server_start(server.get(), server_waiter.ResultCallback, &server_waiter);
+    ASSERT_GT(port, 0);
+    ip_addr_ += std::to_string(port);
+
+    // Start multiple clients, all with bad passwords
+    int test_num_clients = 5;
+    int num_clients_done = 0;
+    std::mutex global_clients_mutex;
+    std::unique_lock<std::mutex> global_clients_lock(global_clients_mutex);
+    std::condition_variable global_cv_;
+    for (int i = 0; i < test_num_clients; ++i) {
+        std::thread([&]() {
+            auto client = CreateClient(pswd2);
+            ResultWaiter client_waiter;
+            std::unique_lock<std::mutex> client_lock(client_waiter.mutex_);
+            ASSERT_TRUE(client->Start(ip_addr_, client_waiter.ResultCallback, &client_waiter));
+            client_waiter.cv_.wait(client_lock,
+                                   [&]() { return client_waiter.is_valid_.has_value(); });
+            ASSERT_FALSE(*(client_waiter.is_valid_));
+            {
+                std::lock_guard<std::mutex> global_lock(global_clients_mutex);
+                ++num_clients_done;
+            }
+            global_cv_.notify_one();
+        }).detach();
+    }
+
+    global_cv_.wait(global_clients_lock, [&]() { return num_clients_done == test_num_clients; });
+    server_lock.unlock();
+    server.reset();
+    server_lock.lock();
+    ASSERT_TRUE(server_waiter.is_valid_.has_value());
+    EXPECT_FALSE(*(server_waiter.is_valid_));
+}
+
+TEST_F(AdbPairingConnectionTest, MultipleClientsOnePass) {
+    // Send multiple clients with bad passwords, but send the last one with the
+    // correct password.
+    std::vector<uint8_t> pswd{0x01, 0x03, 0x05, 0x07};
+    std::vector<uint8_t> pswd2{0x01, 0x03, 0x05, 0x06};
+
+    // Start the server
+    auto server = CreateServer(pswd);
+    ResultWaiter server_waiter;
+    std::unique_lock<std::mutex> server_lock(server_waiter.mutex_);
+    auto port = pairing_server_start(server.get(), server_waiter.ResultCallback, &server_waiter);
+    ASSERT_GT(port, 0);
+    ip_addr_ += std::to_string(port);
+
+    // Start multiple clients, all with bad passwords
+    int test_num_clients = 5;
+    int num_clients_done = 0;
+    std::mutex global_clients_mutex;
+    std::unique_lock<std::mutex> global_clients_lock(global_clients_mutex);
+    std::condition_variable global_cv_;
+    for (int i = 0; i < test_num_clients; ++i) {
+        std::thread([&, i]() {
+            bool good_client = (i == (test_num_clients - 1));
+            auto client = CreateClient((good_client ? pswd : pswd2));
+            ResultWaiter client_waiter;
+            std::unique_lock<std::mutex> client_lock(client_waiter.mutex_);
+            ASSERT_TRUE(client->Start(ip_addr_, client_waiter.ResultCallback, &client_waiter));
+            client_waiter.cv_.wait(client_lock,
+                                   [&]() { return client_waiter.is_valid_.has_value(); });
+            if (good_client) {
+                ASSERT_TRUE(*(client_waiter.is_valid_));
+                ASSERT_EQ(strlen(reinterpret_cast<const char*>(client_waiter.peer_info_.data)),
+                          strlen(reinterpret_cast<const char*>(server_info_.data)));
+                EXPECT_EQ(memcmp(client_waiter.peer_info_.data, server_info_.data,
+                                 sizeof(server_info_.data)),
+                          0);
+            } else {
+                ASSERT_FALSE(*(client_waiter.is_valid_));
+            }
+            {
+                std::lock_guard<std::mutex> global_lock(global_clients_mutex);
+                ++num_clients_done;
+            }
+            global_cv_.notify_one();
+        }).detach();
+    }
+
+    global_cv_.wait(global_clients_lock, [&]() { return num_clients_done == test_num_clients; });
+    server_waiter.cv_.wait(server_lock, [&]() { return server_waiter.is_valid_.has_value(); });
+    ASSERT_TRUE(*(server_waiter.is_valid_));
+    ASSERT_EQ(strlen(reinterpret_cast<const char*>(server_waiter.peer_info_.data)),
+              strlen(reinterpret_cast<const char*>(client_info_.data)));
+    EXPECT_EQ(memcmp(server_waiter.peer_info_.data, client_info_.data, sizeof(client_info_.data)),
+              0);
+}
+
+}  // namespace pairing
+}  // namespace adb
