mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 15:36:12 -04:00
Try to fix Bluetooth issue to get service
PiperOrigin-RevId: 570475245
This commit is contained in:
committed by
Copybara-Service
parent
3fdcbe4ddc
commit
7dea977b74
@@ -89,6 +89,7 @@ using ::winrt::Windows::Devices::Bluetooth::Advertisement::
|
||||
BluetoothLEScanningMode;
|
||||
using ::winrt::Windows::Foundation::TimeSpan;
|
||||
using ::winrt::Windows::Storage::Streams::Buffer;
|
||||
using ::winrt::Windows::Storage::Streams::DataReader;
|
||||
using ::winrt::Windows::Storage::Streams::DataWriter;
|
||||
|
||||
template <typename T>
|
||||
|
||||
@@ -16,12 +16,15 @@
|
||||
|
||||
#include <winstring.h>
|
||||
|
||||
#include <chrono> // NOLINT(build/c++11)
|
||||
#include <codecvt>
|
||||
#include <exception>
|
||||
#include <locale>
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/clock.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.Bluetooth.Rfcomm.h"
|
||||
#include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.Bluetooth.h"
|
||||
#include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.Enumeration.h"
|
||||
@@ -34,9 +37,11 @@
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
namespace {
|
||||
constexpr int kBluetoothTimeoutInSeconds = 10;
|
||||
|
||||
using ::winrt::Windows::Foundation::TimeSpan;
|
||||
|
||||
constexpr int kBluetoothTimeoutInSeconds = 10;
|
||||
constexpr int kCheckBluetoothServiceMaxTimes = 3;
|
||||
constexpr absl::Duration kCheckBluetoothServiceInterval = absl::Seconds(1);
|
||||
} // namespace
|
||||
|
||||
BluetoothDevice::~BluetoothDevice() {}
|
||||
@@ -72,67 +77,74 @@ std::string BluetoothDevice::GetMacAddress() const { return mac_address_; }
|
||||
// Checks cache first, will check uncached if no result.
|
||||
RfcommDeviceService BluetoothDevice::GetRfcommServiceForIdAsync(
|
||||
const RfcommServiceId serviceId) {
|
||||
try {
|
||||
NEARBY_LOGS(INFO) << __func__ << ": Get RF services for service id:"
|
||||
<< winrt::to_string(serviceId.AsString());
|
||||
int check_service_count = 0;
|
||||
while (check_service_count < kCheckBluetoothServiceMaxTimes) {
|
||||
try {
|
||||
NEARBY_LOGS(INFO) << __func__ << ": Get RF services for service id:"
|
||||
<< winrt::to_string(serviceId.AsString());
|
||||
|
||||
RfcommDeviceServicesResult rfcomm_device_services = nullptr;
|
||||
// Try to get service from un cached mode.
|
||||
auto rfcomm_device_services_async =
|
||||
windows_bluetooth_device_.GetRfcommServicesForIdAsync(
|
||||
serviceId, BluetoothCacheMode::Uncached);
|
||||
RfcommDeviceServicesResult rfcomm_device_services = nullptr;
|
||||
// Try to get service from un cached mode.
|
||||
auto rfcomm_device_services_async =
|
||||
windows_bluetooth_device_.GetRfcommServicesForIdAsync(
|
||||
serviceId, BluetoothCacheMode::Uncached);
|
||||
|
||||
switch (rfcomm_device_services_async.wait_for(
|
||||
TimeSpan(std::chrono::seconds(kBluetoothTimeoutInSeconds)))) {
|
||||
case winrt::Windows::Foundation::AsyncStatus::Completed:
|
||||
rfcomm_device_services = rfcomm_device_services_async.GetResults();
|
||||
break;
|
||||
case winrt::Windows::Foundation::AsyncStatus::Started:
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__
|
||||
<< ": Failed to get RfcommDeviceService due to timeout.";
|
||||
rfcomm_device_services_async.Cancel();
|
||||
return nullptr;
|
||||
default:
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__
|
||||
<< ": Failed to get RfcommDeviceService due to unknown reasons.";
|
||||
return nullptr;
|
||||
}
|
||||
switch (rfcomm_device_services_async.wait_for(
|
||||
TimeSpan(std::chrono::seconds(kBluetoothTimeoutInSeconds)))) {
|
||||
case winrt::Windows::Foundation::AsyncStatus::Completed:
|
||||
rfcomm_device_services = rfcomm_device_services_async.GetResults();
|
||||
break;
|
||||
case winrt::Windows::Foundation::AsyncStatus::Started:
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__
|
||||
<< ": Failed to get RfcommDeviceService due to timeout.";
|
||||
rfcomm_device_services_async.Cancel();
|
||||
return nullptr;
|
||||
default:
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__
|
||||
<< ": Failed to get RfcommDeviceService due to unknown reasons.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (rfcomm_device_services != nullptr &&
|
||||
rfcomm_device_services.Services().Size() > 0) {
|
||||
NEARBY_LOGS(INFO) << __func__ << ": Get "
|
||||
<< rfcomm_device_services.Services().Size()
|
||||
<< " services without cache.";
|
||||
// found the matched service.
|
||||
for (auto rfcomm_device_service : rfcomm_device_services.Services()) {
|
||||
if (rfcomm_device_service.Device() != nullptr &&
|
||||
winrt::to_string(rfcomm_device_service.Device().DeviceId()) ==
|
||||
id_) {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< __func__ << ": Found service from no-cache mode.";
|
||||
return rfcomm_device_service;
|
||||
if (rfcomm_device_services != nullptr &&
|
||||
rfcomm_device_services.Services().Size() > 0) {
|
||||
NEARBY_LOGS(INFO) << __func__ << ": Get "
|
||||
<< rfcomm_device_services.Services().Size()
|
||||
<< " services without cache.";
|
||||
// found the matched service.
|
||||
for (auto rfcomm_device_service : rfcomm_device_services.Services()) {
|
||||
if (rfcomm_device_service.Device() != nullptr &&
|
||||
winrt::to_string(rfcomm_device_service.Device().DeviceId()) ==
|
||||
id_) {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< __func__ << ": Found service from no-cache mode.";
|
||||
return rfcomm_device_service;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__
|
||||
<< ": Failed to get RfcommDeviceService due to no any services.";
|
||||
return nullptr;
|
||||
} catch (std::exception exception) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Failed to get RfcommDeviceService: "
|
||||
<< exception.what();
|
||||
return nullptr;
|
||||
} catch (const winrt::hresult_error& ex) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": RfcommDeviceService: " << ex.code()
|
||||
<< ", error message: " << winrt::to_string(ex.message());
|
||||
return nullptr;
|
||||
} catch (...) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Unknown exception.";
|
||||
return nullptr;
|
||||
++check_service_count;
|
||||
absl::SleepFor(kCheckBluetoothServiceInterval);
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": No any services at "
|
||||
<< check_service_count << "th check.";
|
||||
} catch (std::exception exception) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Failed to get RfcommDeviceService: "
|
||||
<< exception.what();
|
||||
return nullptr;
|
||||
} catch (const winrt::hresult_error& ex) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": RfcommDeviceService: " << ex.code()
|
||||
<< ", error message: "
|
||||
<< winrt::to_string(ex.message());
|
||||
return nullptr;
|
||||
} catch (...) {
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Unknown exception.";
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Failed to get RfcommDeviceService.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace windows
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 Google LLC
|
||||
// Copyright 2020-2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -26,6 +26,14 @@
|
||||
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
namespace {
|
||||
using ::winrt::Windows::Networking::Sockets::StreamSocket;
|
||||
using ::winrt::Windows::Networking::Sockets::SocketProtectionLevel;
|
||||
using ::winrt::Windows::Networking::Sockets::SocketQualityOfService;
|
||||
using ::winrt::Windows::Networking::Sockets::StreamSocketListener;
|
||||
using ::winrt::Windows::Networking::Sockets::
|
||||
StreamSocketListenerConnectionReceivedEventArgs;
|
||||
} // namespace
|
||||
|
||||
BluetoothServerSocket::BluetoothServerSocket(absl::string_view service_name)
|
||||
: service_name_(service_name) {}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 Google LLC
|
||||
// Copyright 2020-2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/implementation/bluetooth_classic.h"
|
||||
#include "internal/platform/implementation/windows/bluetooth_classic_socket.h"
|
||||
#include "internal/platform/implementation/windows/generated/winrt/base.h"
|
||||
@@ -30,28 +31,9 @@
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
|
||||
// Supports listening for an incoming network connection using Bluetooth RFCOMM.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.networking.sockets.streamsocketlistener?view=winrt-20348
|
||||
using winrt::Windows::Networking::Sockets::StreamSocketListener;
|
||||
|
||||
// Provides data for a ConnectionReceived event on a StreamSocketListener
|
||||
// object.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.networking.sockets.streamsocketlistenerconnectionreceivedeventargs?view=winrt-20348
|
||||
using winrt::Windows::Networking::Sockets::
|
||||
StreamSocketListenerConnectionReceivedEventArgs;
|
||||
|
||||
// Specifies the quality of service for a StreamSocket object.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.networking.sockets.socketqualityofservice?view=winrt-20348
|
||||
using winrt::Windows::Networking::Sockets::SocketQualityOfService;
|
||||
|
||||
// Specifies the level of encryption to use on a StreamSocket object.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.networking.sockets.socketprotectionlevel?view=winrt-22000
|
||||
using winrt::Windows::Networking::Sockets::SocketProtectionLevel;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html.
|
||||
class BluetoothServerSocket : public api::BluetoothServerSocket {
|
||||
public:
|
||||
BluetoothServerSocket(absl::string_view service_name);
|
||||
explicit BluetoothServerSocket(absl::string_view service_name);
|
||||
|
||||
~BluetoothServerSocket() override;
|
||||
|
||||
@@ -77,24 +59,28 @@ class BluetoothServerSocket : public api::BluetoothServerSocket {
|
||||
|
||||
bool listen();
|
||||
|
||||
const StreamSocketListener& stream_socket_listener() const {
|
||||
const ::winrt::Windows::Networking::Sockets::StreamSocketListener&
|
||||
stream_socket_listener() const {
|
||||
return stream_socket_listener_;
|
||||
}
|
||||
|
||||
private:
|
||||
// The listener is accepting incoming connections
|
||||
::winrt::fire_and_forget Listener_ConnectionReceived(
|
||||
StreamSocketListener listener,
|
||||
StreamSocketListenerConnectionReceivedEventArgs const& args);
|
||||
::winrt::Windows::Networking::Sockets::StreamSocketListener listener,
|
||||
::winrt::Windows::Networking::Sockets::
|
||||
StreamSocketListenerConnectionReceivedEventArgs const& args);
|
||||
|
||||
// Retrieves IP addresses from local machine
|
||||
std::vector<std::string> GetIpAddresses() const;
|
||||
|
||||
mutable absl::Mutex mutex_;
|
||||
absl::CondVar cond_;
|
||||
std::deque<StreamSocket> pending_sockets_ ABSL_GUARDED_BY(mutex_);
|
||||
StreamSocketListener stream_socket_listener_{nullptr};
|
||||
winrt::event_token listener_event_token_{};
|
||||
std::deque<::winrt::Windows::Networking::Sockets::StreamSocket>
|
||||
pending_sockets_ ABSL_GUARDED_BY(mutex_);
|
||||
::winrt::Windows::Networking::Sockets::StreamSocketListener
|
||||
stream_socket_listener_{nullptr};
|
||||
::winrt::event_token listener_event_token_{};
|
||||
|
||||
// Close notifier
|
||||
absl::AnyInvocable<void()> close_notifier_ = nullptr;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 Google LLC
|
||||
// Copyright 2020-2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -14,32 +14,41 @@
|
||||
|
||||
#include "internal/platform/implementation/windows/bluetooth_classic_socket.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/time/clock.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/feature_flags.h"
|
||||
#include "internal/platform/implementation/bluetooth_classic.h"
|
||||
#include "internal/platform/implementation/windows/bluetooth_classic_device.h"
|
||||
#include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.Bluetooth.h"
|
||||
#include "internal/platform/implementation/windows/generated/winrt/Windows.Networking.Sockets.h"
|
||||
#include "internal/platform/implementation/windows/generated/winrt/base.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "winrt/Windows.Devices.Bluetooth.h"
|
||||
#include "winrt/Windows.Networking.Sockets.h"
|
||||
#include "winrt/base.h"
|
||||
#include "internal/platform/output_stream.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
namespace {
|
||||
using ::winrt::Windows::Devices::Bluetooth::BluetoothConnectionStatus;
|
||||
constexpr int kMaxConnectRetryCount = 3;
|
||||
constexpr absl::Duration kConnectInterval = absl::Seconds(3);
|
||||
using ::winrt::Windows::Networking::HostName;
|
||||
using ::winrt::Windows::Networking::Sockets::StreamSocket;
|
||||
using ::winrt::Windows::Storage::Streams::Buffer;
|
||||
using ::winrt::Windows::Storage::Streams::IInputStream;
|
||||
using ::winrt::Windows::Storage::Streams::InputStreamOptions;
|
||||
using ::winrt::Windows::Storage::Streams::IOutputStream;
|
||||
} // namespace
|
||||
|
||||
BluetoothSocket::BluetoothSocket(StreamSocket streamSocket)
|
||||
: windows_socket_(streamSocket) {
|
||||
BluetoothSocket::BluetoothSocket(StreamSocket stream_socket)
|
||||
: windows_socket_(stream_socket) {
|
||||
NEARBY_LOGS(INFO) << __func__ << ": Initialize bluetooth socket.";
|
||||
native_bluetooth_device_ =
|
||||
winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromHostNameAsync(
|
||||
::winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromHostNameAsync(
|
||||
windows_socket_.Information().RemoteHostName())
|
||||
.get();
|
||||
if (FeatureFlags::GetInstance()
|
||||
@@ -125,26 +134,18 @@ api::BluetoothDevice* BluetoothSocket::GetRemoteDevice() {
|
||||
// Starts an asynchronous operation on a StreamSocket object to connect to a
|
||||
// remote network destination specified by a remote hostname and a remote
|
||||
// service name.
|
||||
bool BluetoothSocket::Connect(HostName connectionHostName,
|
||||
winrt::hstring connectionServiceName) {
|
||||
bool BluetoothSocket::Connect(HostName connection_host_name,
|
||||
::winrt::hstring connection_service_name) {
|
||||
NEARBY_LOGS(INFO) << __func__ << ": start to connect to bluetooth service:"
|
||||
<< winrt::to_string(connectionServiceName);
|
||||
<< winrt::to_string(connection_service_name);
|
||||
|
||||
connect_called_count_ = 0;
|
||||
while (connect_called_count_ < kMaxConnectRetryCount) {
|
||||
connect_called_count_ += 1;
|
||||
bool connect_result =
|
||||
InternalConnect(connectionHostName, connectionServiceName);
|
||||
if (connect_result) {
|
||||
return connect_result;
|
||||
}
|
||||
|
||||
NEARBY_LOGS(WARNING) << __func__ << ": Failed to connect bluetooth at the "
|
||||
<< connect_called_count_ << "th call.";
|
||||
|
||||
absl::SleepFor(kConnectInterval);
|
||||
bool connect_result =
|
||||
InternalConnect(connection_host_name, connection_service_name);
|
||||
if (connect_result) {
|
||||
return connect_result;
|
||||
}
|
||||
|
||||
NEARBY_LOGS(WARNING) << __func__ << ": Failed to connect bluetooth";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -164,7 +165,8 @@ ExceptionOr<ByteArray> BluetoothSocket::BluetoothInputStream::Read(
|
||||
|
||||
if (size > read_buffer_.Capacity()) {
|
||||
NEARBY_LOGS(WARNING) << __func__
|
||||
<< ": resize receive buffer to packet size: " << size;
|
||||
<< ": resize receive buffer to packet size: "
|
||||
<< size;
|
||||
read_buffer_ = Buffer(size);
|
||||
}
|
||||
|
||||
@@ -225,8 +227,8 @@ Exception BluetoothSocket::BluetoothOutputStream::Write(const ByteArray& data) {
|
||||
try {
|
||||
if (data.size() > write_buffer_.Capacity()) {
|
||||
NEARBY_LOGS(WARNING) << __func__
|
||||
<< ": resize write buffer to packet size: "
|
||||
<< data.size();
|
||||
<< ": resize write buffer to packet size: "
|
||||
<< data.size();
|
||||
write_buffer_ = Buffer(data.size());
|
||||
}
|
||||
|
||||
@@ -290,10 +292,10 @@ Exception BluetoothSocket::BluetoothOutputStream::Close() {
|
||||
}
|
||||
}
|
||||
|
||||
bool BluetoothSocket::InternalConnect(HostName connectionHostName,
|
||||
winrt::hstring connectionServiceName) {
|
||||
bool BluetoothSocket::InternalConnect(HostName connection_host_name,
|
||||
winrt::hstring connection_service_name) {
|
||||
try {
|
||||
if (connectionHostName == nullptr || connectionServiceName.empty()) {
|
||||
if (connection_host_name == nullptr || connection_service_name.empty()) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< __func__
|
||||
<< ": Bluetooth socket connection failed. Attempting to "
|
||||
@@ -303,14 +305,14 @@ bool BluetoothSocket::InternalConnect(HostName connectionHostName,
|
||||
|
||||
NEARBY_LOGS(INFO) << __func__
|
||||
<< ": Bluetooth socket connection to host name:"
|
||||
<< winrt::to_string(connectionHostName.DisplayName())
|
||||
<< winrt::to_string(connection_host_name.DisplayName())
|
||||
<< ", service name:"
|
||||
<< winrt::to_string(connectionServiceName);
|
||||
<< winrt::to_string(connection_service_name);
|
||||
|
||||
windows_socket_ = winrt::Windows::Networking::Sockets::StreamSocket();
|
||||
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.networking.sockets.streamsocket.connectasync?view=winrt-20348
|
||||
windows_socket_.ConnectAsync(connectionHostName, connectionServiceName)
|
||||
windows_socket_.ConnectAsync(connection_host_name, connection_service_name)
|
||||
.get();
|
||||
|
||||
auto info = windows_socket_.Information();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 Google LLC
|
||||
// Copyright 2020-2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -15,60 +15,29 @@
|
||||
#ifndef PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_SOCKET_H_
|
||||
#define PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_SOCKET_H_
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/implementation/bluetooth_classic.h"
|
||||
#include "internal/platform/implementation/windows/bluetooth_classic_device.h"
|
||||
#include "winrt/Windows.Foundation.h"
|
||||
#include "winrt/Windows.Networking.Sockets.h"
|
||||
#include "winrt/Windows.Storage.Streams.h"
|
||||
#include "internal/platform/implementation/windows/generated/winrt/Windows.Foundation.h"
|
||||
#include "internal/platform/implementation/windows/generated/winrt/Windows.Networking.Sockets.h"
|
||||
#include "internal/platform/implementation/windows/generated/winrt/Windows.Storage.Streams.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/output_stream.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
|
||||
// Provides data for a hostname or an IP address.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.networking.hostname?view=winrt-20348
|
||||
using winrt::Windows::Networking::HostName;
|
||||
|
||||
// Supports network communication using a stream socket over Bluetooth RFCOMM.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.networking.sockets.streamsocket?view=winrt-20348
|
||||
using winrt::Windows::Networking::Sockets::IStreamSocket;
|
||||
using winrt::Windows::Networking::Sockets::StreamSocket;
|
||||
|
||||
// Provides a default implementation of the IBuffer interface and its related
|
||||
// interfaces.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.buffer?view=winrt-20348
|
||||
using winrt::Windows::Storage::Streams::Buffer;
|
||||
|
||||
// Represents a sequential stream of bytes to be read.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.iinputstream?view=winrt-20348
|
||||
using winrt::Windows::Storage::Streams::IInputStream;
|
||||
|
||||
// Represents a sequential stream of bytes to be written.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.ioutputstream?view=winrt-20348
|
||||
using winrt::Windows::Storage::Streams::IOutputStream;
|
||||
|
||||
// Specifies the read options for an input stream.
|
||||
// This enumeration has a FlagsAttribute attribute that allows a bitwise
|
||||
// combination of its member values.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.inputstreamoptions?view=winrt-20348
|
||||
using winrt::Windows::Storage::Streams::InputStreamOptions;
|
||||
|
||||
// Reads data from an input stream.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.datareader?view=winrt-20348
|
||||
using winrt::Windows::Storage::Streams::DataReader;
|
||||
|
||||
// Represents an asynchronous action.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.foundation.iasyncaction?view=winrt-20348
|
||||
using winrt::Windows::Foundation::IAsyncAction;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html.
|
||||
class BluetoothSocket : public api::BluetoothSocket {
|
||||
public:
|
||||
BluetoothSocket();
|
||||
|
||||
explicit BluetoothSocket(StreamSocket streamSocket);
|
||||
|
||||
explicit BluetoothSocket(
|
||||
::winrt::Windows::Networking::Sockets::StreamSocket stream_socket);
|
||||
~BluetoothSocket() override;
|
||||
|
||||
// NOTE:
|
||||
@@ -95,28 +64,32 @@ class BluetoothSocket : public api::BluetoothSocket {
|
||||
|
||||
// Connect asynchronously to the target remote device
|
||||
// Returns true if successful, false otherwise
|
||||
bool Connect(HostName connectionHostName,
|
||||
winrt::hstring connectionServiceName);
|
||||
bool Connect(::winrt::Windows::Networking::HostName connection_host_name,
|
||||
::winrt::hstring connection_service_name);
|
||||
|
||||
private:
|
||||
static constexpr int kInitialTransmitPacketSize = 4096;
|
||||
|
||||
class BluetoothInputStream : public InputStream {
|
||||
public:
|
||||
explicit BluetoothInputStream(IInputStream stream);
|
||||
explicit BluetoothInputStream(
|
||||
::winrt::Windows::Storage::Streams::IInputStream stream);
|
||||
~BluetoothInputStream() override = default;
|
||||
|
||||
ExceptionOr<ByteArray> Read(std::int64_t size) override;
|
||||
Exception Close() override;
|
||||
|
||||
private:
|
||||
IInputStream winrt_input_stream_{nullptr};
|
||||
Buffer read_buffer_{kInitialTransmitPacketSize};
|
||||
::winrt::Windows::Storage::Streams::IInputStream winrt_input_stream_{
|
||||
nullptr};
|
||||
::winrt::Windows::Storage::Streams::Buffer read_buffer_{
|
||||
kInitialTransmitPacketSize};
|
||||
};
|
||||
|
||||
class BluetoothOutputStream : public OutputStream {
|
||||
public:
|
||||
explicit BluetoothOutputStream(IOutputStream stream);
|
||||
explicit BluetoothOutputStream(
|
||||
::winrt::Windows::Storage::Streams::IOutputStream stream);
|
||||
~BluetoothOutputStream() override = default;
|
||||
|
||||
Exception Write(const ByteArray& data) override;
|
||||
@@ -125,26 +98,28 @@ class BluetoothSocket : public api::BluetoothSocket {
|
||||
Exception Close() override;
|
||||
|
||||
private:
|
||||
IOutputStream winrt_output_stream_{nullptr};
|
||||
Buffer write_buffer_{kInitialTransmitPacketSize};
|
||||
::winrt::Windows::Storage::Streams::IOutputStream winrt_output_stream_{
|
||||
nullptr};
|
||||
::winrt::Windows::Storage::Streams::Buffer write_buffer_{
|
||||
kInitialTransmitPacketSize};
|
||||
};
|
||||
|
||||
bool InternalConnect(HostName connectionHostName,
|
||||
winrt::hstring connectionServiceName);
|
||||
bool InternalConnect(
|
||||
::winrt::Windows::Networking::HostName connection_host_name,
|
||||
::winrt::hstring connection_service_name);
|
||||
|
||||
winrt::fire_and_forget Listener_ConnectionStatusChanged(
|
||||
winrt::Windows::Devices::Bluetooth::BluetoothDevice device,
|
||||
winrt::Windows::Foundation::IInspectable const& args);
|
||||
::winrt::fire_and_forget Listener_ConnectionStatusChanged(
|
||||
::winrt::Windows::Devices::Bluetooth::BluetoothDevice device,
|
||||
::winrt::Windows::Foundation::IInspectable const& args);
|
||||
|
||||
StreamSocket windows_socket_{nullptr};
|
||||
::winrt::Windows::Networking::Sockets::StreamSocket windows_socket_{nullptr};
|
||||
bool is_bluetooth_socket_closed_ = false;
|
||||
BluetoothInputStream input_stream_{nullptr};
|
||||
BluetoothOutputStream output_stream_{nullptr};
|
||||
std::unique_ptr<BluetoothDevice> bluetooth_device_ = nullptr;
|
||||
winrt::Windows::Devices::Bluetooth::BluetoothDevice native_bluetooth_device_{
|
||||
nullptr};
|
||||
winrt::event_token connection_status_changed_token_{};
|
||||
int connect_called_count_ = 0;
|
||||
::winrt::Windows::Devices::Bluetooth::BluetoothDevice
|
||||
native_bluetooth_device_{nullptr};
|
||||
::winrt::event_token connection_status_changed_token_{};
|
||||
};
|
||||
|
||||
} // namespace windows
|
||||
|
||||
Reference in New Issue
Block a user