mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-15 07:06:11 -04:00
Initial implementation of BluetoothServerSocket
PiperOrigin-RevId: 390461649
This commit is contained in:
committed by
Copybara-Service
parent
512ba2af43
commit
07d33cfa9e
@@ -14,18 +14,23 @@
|
||||
|
||||
#include "platform/impl/windows/bluetooth_classic_medium.h"
|
||||
|
||||
#include <codecvt>
|
||||
#include <locale>
|
||||
#include <string>
|
||||
|
||||
#include "platform/base/cancellation_flag.h"
|
||||
#include "platform/base/cancellation_flag_listener.h"
|
||||
#include "platform/base/exception.h"
|
||||
#include "platform/impl/windows/bluetooth_classic_device.h"
|
||||
#include "platform/impl/windows/bluetooth_classic_server_socket.h"
|
||||
#include "platform/impl/windows/bluetooth_classic_socket.h"
|
||||
#include "platform/impl/windows/generated/winrt/Windows.Devices.Bluetooth.Rfcomm.h"
|
||||
#include "platform/impl/windows/generated/winrt/Windows.Devices.Bluetooth.h"
|
||||
#include "platform/impl/windows/generated/winrt/Windows.Devices.Enumeration.h"
|
||||
#include "platform/impl/windows/generated/winrt/Windows.Foundation.Collections.h"
|
||||
#include "platform/impl/windows/generated/winrt/base.h"
|
||||
|
||||
#include "platform/base/exception.h"
|
||||
#include "platform/impl/windows/bluetooth_classic_device.h"
|
||||
#include "platform/impl/windows/bluetooth_classic_socket.h"
|
||||
#include "platform/impl/windows/utils.h"
|
||||
#include "platform/public/logging.h"
|
||||
#include "platform/base/cancellation_flag.h"
|
||||
#include "platform/base/cancellation_flag_listener.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
@@ -34,32 +39,7 @@ namespace windows {
|
||||
BluetoothClassicMedium::BluetoothClassicMedium() {
|
||||
InitializeCriticalSection(&critical_section_);
|
||||
|
||||
// create watcher
|
||||
device_watcher_ = DeviceInformation::CreateWatcher(
|
||||
BLUETOOTH_SELECTOR, nullptr, DeviceInformationKind::AssociationEndpoint);
|
||||
|
||||
// An app must subscribe to all of the added, removed, and updated events to
|
||||
// be notified when there are device additions, removals or updates. If an app
|
||||
// handles only the added event, it will not receive an update if a device is
|
||||
// added to the system after the initial device enumeration completes.
|
||||
// register event handlers before starting the watcher
|
||||
//
|
||||
// Event that is raised when a device is added to the collection enumerated
|
||||
// by the DeviceWatcher.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcher.added?view=winrt-20348
|
||||
device_watcher_.Added({this, &BluetoothClassicMedium::DeviceWatcher_Added});
|
||||
|
||||
// Event that is raised when a device is updated in the collection of
|
||||
// enumerated devices.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcher.updated?view=winrt-20348
|
||||
device_watcher_.Updated(
|
||||
{this, &BluetoothClassicMedium::DeviceWatcher_Updated});
|
||||
|
||||
// Event that is raised when a device is removed from the collection of
|
||||
// enumerated devices.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcher.removed?view=winrt-20348
|
||||
device_watcher_.Removed(
|
||||
{this, &BluetoothClassicMedium::DeviceWatcher_Removed});
|
||||
InitializeDeviceWatcher();
|
||||
}
|
||||
|
||||
BluetoothClassicMedium::~BluetoothClassicMedium() {}
|
||||
@@ -99,6 +79,37 @@ bool BluetoothClassicMedium::StopDiscovery() {
|
||||
return result;
|
||||
}
|
||||
|
||||
void BluetoothClassicMedium::InitializeDeviceWatcher() {
|
||||
// create watcher
|
||||
device_watcher_ = DeviceInformation::CreateWatcher(
|
||||
BLUETOOTH_SELECTOR, // aqsFilter
|
||||
nullptr, // additionalProperties
|
||||
DeviceInformationKind::AssociationEndpoint); // kind
|
||||
|
||||
// An app must subscribe to all of the added, removed, and updated events to
|
||||
// be notified when there are device additions, removals or updates. If an app
|
||||
// handles only the added event, it will not receive an update if a device is
|
||||
// added to the system after the initial device enumeration completes.
|
||||
// register event handlers before starting the watcher
|
||||
//
|
||||
// Event that is raised when a device is added to the collection enumerated
|
||||
// by the DeviceWatcher.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcher.added?view=winrt-20348
|
||||
device_watcher_.Added({this, &BluetoothClassicMedium::DeviceWatcher_Added});
|
||||
|
||||
// Event that is raised when a device is updated in the collection of
|
||||
// enumerated devices.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcher.updated?view=winrt-20348
|
||||
device_watcher_.Updated(
|
||||
{this, &BluetoothClassicMedium::DeviceWatcher_Updated});
|
||||
|
||||
// Event that is raised when a device is removed from the collection of
|
||||
// enumerated devices.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcher.removed?view=winrt-20348
|
||||
device_watcher_.Removed(
|
||||
{this, &BluetoothClassicMedium::DeviceWatcher_Removed});
|
||||
}
|
||||
|
||||
std::unique_ptr<api::BluetoothSocket> BluetoothClassicMedium::ConnectToService(
|
||||
api::BluetoothDevice& remote_device, const std::string& service_uuid,
|
||||
CancellationFlag* cancellation_flag) {
|
||||
@@ -141,8 +152,7 @@ std::unique_ptr<api::BluetoothSocket> BluetoothClassicMedium::ConnectToService(
|
||||
|
||||
location::nearby::CancellationFlagListener cancellationFlagListener(
|
||||
cancellation_flag,
|
||||
[&rfcommSocket]() { rfcommSocket.get()->CancelIOAsync().get();
|
||||
});
|
||||
[&rfcommSocket]() { rfcommSocket.get()->CancelIOAsync().get(); });
|
||||
|
||||
try {
|
||||
rfcommSocket
|
||||
@@ -209,16 +219,16 @@ bool BluetoothClassicMedium::CheckSdp(RfcommDeviceService requestedService) {
|
||||
// device that actually supports the Bluetooth Rfcomm Service
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.rfcomm.rfcommdeviceservice.getsdprawattributesasync?view=winrt-20348
|
||||
auto attributes = /*await*/ requestedService.GetSdpRawAttributesAsync();
|
||||
if (!attributes.get().HasKey(SdpServiceNameAttributeId)) {
|
||||
if (!attributes.get().HasKey(Constants::SdpServiceNameAttributeId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto attributeReader = DataReader::FromBuffer(
|
||||
attributes.get().Lookup(SdpServiceNameAttributeId));
|
||||
attributes.get().Lookup(Constants::SdpServiceNameAttributeId));
|
||||
|
||||
auto attributeType = attributeReader.ReadByte();
|
||||
|
||||
if (attributeType != SdpServiceNameAttributeType) {
|
||||
if (attributeType != Constants::SdpServiceNameAttributeType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -237,7 +247,20 @@ bool BluetoothClassicMedium::CheckSdp(RfcommDeviceService requestedService) {
|
||||
std::unique_ptr<api::BluetoothServerSocket>
|
||||
BluetoothClassicMedium::ListenForService(const std::string& service_name,
|
||||
const std::string& service_uuid) {
|
||||
return nullptr;
|
||||
if (service_uuid.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (service_name.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto bluetooth_server_socket =
|
||||
std::make_unique<location::nearby::windows::BluetoothServerSocket>();
|
||||
|
||||
bluetooth_server_socket->StartListening(service_name, service_uuid);
|
||||
|
||||
return std::move(bluetooth_server_socket);
|
||||
}
|
||||
|
||||
// TODO(b/184975123): replace with real implementation.
|
||||
@@ -301,12 +324,12 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Added(
|
||||
|
||||
devices_by_id_[deviceInfo.Id()] = std::move(bluetoothDevice);
|
||||
|
||||
LeaveCriticalSection(&critical_section_);
|
||||
|
||||
if (discovery_callback_.device_discovered_cb != nullptr) {
|
||||
discovery_callback_.device_discovered_cb(
|
||||
*devices_by_id_[deviceInfo.Id()]);
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&critical_section_);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -326,6 +349,8 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Updated(
|
||||
winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Removed(
|
||||
DeviceWatcher sender, DeviceInformationUpdate deviceInfo) {
|
||||
if (IsWatcherStarted()) {
|
||||
EnterCriticalSection(&critical_section_);
|
||||
|
||||
if (discovery_callback_.device_lost_cb != nullptr) {
|
||||
discovery_callback_.device_lost_cb(*devices_by_id_[deviceInfo.Id()]);
|
||||
}
|
||||
@@ -333,6 +358,8 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Removed(
|
||||
devices_by_id_.erase(deviceInfo.Id());
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&critical_section_);
|
||||
|
||||
return winrt::fire_and_forget();
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,12 @@
|
||||
#include <Windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "platform/api/bluetooth_classic.h"
|
||||
#include "platform/impl/windows/bluetooth_classic_device.h"
|
||||
#include "platform/impl/windows/bluetooth_classic_server_socket.h"
|
||||
#include "platform/impl/windows/bluetooth_classic_socket.h"
|
||||
#include "platform/impl/windows/generated/winrt/Windows.Devices.Enumeration.h"
|
||||
#include "platform/impl/windows/generated/winrt/Windows.Networking.Sockets.h"
|
||||
#include "platform/impl/windows/generated/winrt/base.h"
|
||||
|
||||
namespace location {
|
||||
@@ -69,6 +73,10 @@ using winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommServiceId;
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.datareader?view=winrt-20348
|
||||
using winrt::Windows::Storage::Streams::DataReader;
|
||||
|
||||
// Writes data to an output stream.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.datawriter?view=winrt-20348
|
||||
using winrt::Windows::Storage::Streams::DataWriter;
|
||||
|
||||
// Bluetooth protocol ID = \"{e0cbf06c-cd8b-4647-bb8a-263b43f0f974}\"
|
||||
// https://docs.microsoft.com/en-us/windows/uwp/devices-sensors/aep-service-class-ids
|
||||
#define BLUETOOTH_SELECTOR \
|
||||
@@ -80,7 +88,6 @@ class BluetoothClassicMedium : public api::BluetoothClassicMedium {
|
||||
public:
|
||||
explicit BluetoothClassicMedium();
|
||||
|
||||
// TODO(b/184975123): replace with real implementation.
|
||||
~BluetoothClassicMedium() override;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#startDiscovery()
|
||||
@@ -91,7 +98,6 @@ class BluetoothClassicMedium : public api::BluetoothClassicMedium {
|
||||
// Returns true once discovery is well and truly stopped; after this returns,
|
||||
// there must be no more invocations of the DiscoveryCallback passed in to
|
||||
// StartDiscovery().
|
||||
// TODO(b/184975123): replace with real implementation.
|
||||
bool StopDiscovery() override;
|
||||
|
||||
// A combination of
|
||||
@@ -120,7 +126,6 @@ class BluetoothClassicMedium : public api::BluetoothClassicMedium {
|
||||
// UUID.
|
||||
//
|
||||
// Returns nullptr error.
|
||||
// TODO(b/184975123): replace with real implementation.
|
||||
std::unique_ptr<api::BluetoothServerSocket> ListenForService(
|
||||
const std::string& service_name,
|
||||
const std::string& service_uuid) override;
|
||||
@@ -134,6 +139,7 @@ class BluetoothClassicMedium : public api::BluetoothClassicMedium {
|
||||
bool StopScanning();
|
||||
bool IsWatcherStarted();
|
||||
bool IsWatcherRunning();
|
||||
void InitializeDeviceWatcher();
|
||||
|
||||
// This is for a coroutine whose return type is winrt::fire_and_forget, which
|
||||
// handles async operations which don't have any dependencies.
|
||||
@@ -151,27 +157,17 @@ class BluetoothClassicMedium : public api::BluetoothClassicMedium {
|
||||
bool HaveAccess(winrt::hstring deviceId);
|
||||
|
||||
// Get the service requested
|
||||
winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommDeviceService
|
||||
GetRequestedService(location::nearby::windows::BluetoothDevice* device,
|
||||
winrt::guid service);
|
||||
RfcommDeviceService GetRequestedService(BluetoothDevice* device,
|
||||
winrt::guid service);
|
||||
|
||||
// Check to see that the device actually handles the requested service
|
||||
bool CheckSdp(winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommDeviceService
|
||||
requestedService);
|
||||
bool CheckSdp(RfcommDeviceService requestedService);
|
||||
|
||||
BluetoothClassicMedium::DiscoveryCallback discovery_callback_;
|
||||
|
||||
DeviceWatcher device_watcher_ = nullptr;
|
||||
|
||||
// The Id of the Service Name SDP attribute
|
||||
const uint16 SdpServiceNameAttributeId = 0x100;
|
||||
|
||||
// The SDP Type of the Service Name SDP attribute.
|
||||
// The first byte in the SDP Attribute encodes the SDP Attribute Type as
|
||||
// follows :
|
||||
// - the Attribute Type size in the least significant 3 bits,
|
||||
// - the SDP Attribute Type value in the most significant 5 bits.
|
||||
const char SdpServiceNameAttributeType = (4 << 3) | 5;
|
||||
std::unique_ptr<BluetoothSocket> bluetooth_socket_;
|
||||
|
||||
// hstring is the only type of string winrt understands.
|
||||
// https://docs.microsoft.com/en-us/uwp/cpp-ref-for-winrt/hstring
|
||||
|
||||
@@ -14,9 +14,22 @@
|
||||
|
||||
#include "platform/impl/windows/bluetooth_classic_server_socket.h"
|
||||
|
||||
#include <codecvt>
|
||||
#include <locale>
|
||||
#include <string>
|
||||
|
||||
#include "platform/impl/windows/bluetooth_classic_socket.h"
|
||||
#include "platform/impl/windows/generated/winrt/Windows.Foundation.Collections.h"
|
||||
#include "platform/impl/windows/utils.h"
|
||||
#include "platform/public/logging.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
BluetoothServerSocket::BluetoothServerSocket() {
|
||||
InitializeCriticalSection(&critical_section_);
|
||||
}
|
||||
|
||||
BluetoothServerSocket::~BluetoothServerSocket() {}
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html#accept()
|
||||
@@ -27,17 +40,135 @@ BluetoothServerSocket::~BluetoothServerSocket() {}
|
||||
// On success, returns connected socket, ready to exchange data.
|
||||
// Returns nullptr on error.
|
||||
// Once error is reported, it is permanent, and ServerSocket has to be closed.
|
||||
// TODO(b/184975123): replace with real implementation.
|
||||
std::unique_ptr<api::BluetoothSocket> BluetoothServerSocket::Accept() {
|
||||
while (bluetooth_sockets_.empty() && !closed_) {
|
||||
Sleep(1000);
|
||||
}
|
||||
|
||||
EnterCriticalSection(&critical_section_);
|
||||
if (!closed_) {
|
||||
std::unique_ptr<BluetoothSocket> bluetoothSocket =
|
||||
std::move(bluetooth_sockets_.front());
|
||||
bluetooth_sockets_.pop();
|
||||
LeaveCriticalSection(&critical_section_);
|
||||
|
||||
return std::move(bluetoothSocket);
|
||||
} else {
|
||||
bluetooth_sockets_ = {};
|
||||
LeaveCriticalSection(&critical_section_);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Exception BluetoothServerSocket::StartListening(
|
||||
const std::string& service_name, const std::string& service_uuid) {
|
||||
EnterCriticalSection(&critical_section_);
|
||||
|
||||
winrt::guid service(service_uuid);
|
||||
|
||||
// Create the StreamSocketListener
|
||||
stream_socket_listener_ = StreamSocketListener();
|
||||
|
||||
// Configure control property
|
||||
stream_socket_listener_.Control().QualityOfService(
|
||||
SocketQualityOfService::LowLatency);
|
||||
|
||||
stream_socket_listener_.Control().KeepAlive(true);
|
||||
|
||||
// Note From the perspective of a StreamSocket, a Parallel Patterns Library
|
||||
// (PPL) completion handler is done executing (and the socket is eligible for
|
||||
// disposal) before the continuation body runs. So, to keep your socket from
|
||||
// being disposed if you want to use it inside a continuation, you'll need to
|
||||
// use one of the techniques described in References to StreamSockets in C++
|
||||
// PPL continuations.
|
||||
// Assign ConnectionReceived event to event handler on the server socket
|
||||
stream_socket_listener_.ConnectionReceived(
|
||||
[this](StreamSocketListener streamSocketListener,
|
||||
StreamSocketListenerConnectionReceivedEventArgs args) {
|
||||
EnterCriticalSection(&critical_section_);
|
||||
if (!closed_) {
|
||||
this->bluetooth_sockets_.push(
|
||||
std::make_unique<BluetoothSocket>(args.Socket()));
|
||||
}
|
||||
LeaveCriticalSection(&critical_section_);
|
||||
});
|
||||
|
||||
try {
|
||||
auto rfcommProviderRef =
|
||||
RfcommServiceProvider::CreateAsync(RfcommServiceId::FromUuid(service))
|
||||
.get();
|
||||
|
||||
rfcomm_provider_ = &rfcommProviderRef;
|
||||
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||
stream_socket_listener_
|
||||
.BindServiceNameAsync(winrt::to_hstring(service_name.c_str()))
|
||||
.get();
|
||||
|
||||
// Set the SDP attributes and start Bluetooth advertising
|
||||
InitializeServiceSdpAttributes(*rfcomm_provider_, service_name);
|
||||
} catch (std::exception exception) {
|
||||
// We will log and eat the exception since the caller
|
||||
// expects nullptr if it fails
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Exception setting up for listen: "
|
||||
<< exception.what();
|
||||
|
||||
LeaveCriticalSection(&critical_section_);
|
||||
|
||||
return {Exception::kFailed};
|
||||
}
|
||||
|
||||
try {
|
||||
rfcomm_provider_->StartAdvertising(
|
||||
stream_socket_listener_.as<StreamSocketListener>(), true);
|
||||
} catch (std::exception exception) {
|
||||
// We will log and eat the exception since the caller
|
||||
// expects nullptr if it fails
|
||||
NEARBY_LOGS(ERROR) << __func__ << ": Exception calling StartAdvertising: "
|
||||
<< exception.what();
|
||||
|
||||
LeaveCriticalSection(&critical_section_);
|
||||
|
||||
return {Exception::kFailed};
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&critical_section_);
|
||||
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
|
||||
void BluetoothServerSocket::InitializeServiceSdpAttributes(
|
||||
RfcommServiceProvider rfcommProvider, std::string service_name) {
|
||||
auto sdpWriter = DataWriter();
|
||||
|
||||
// Write the Service Name Attribute.
|
||||
sdpWriter.WriteByte(Constants::SdpServiceNameAttributeType);
|
||||
|
||||
// The length of the UTF-8 encoded Service Name SDP Attribute.
|
||||
sdpWriter.WriteByte(service_name.size());
|
||||
|
||||
// The UTF-8 encoded Service Name value.
|
||||
sdpWriter.UnicodeEncoding(UnicodeEncoding::Utf8);
|
||||
sdpWriter.WriteString(winrt::to_hstring(service_name));
|
||||
|
||||
// Set the SDP Attribute on the RFCOMM Service Provider.
|
||||
rfcommProvider.SdpRawAttributes().Insert(Constants::SdpServiceNameAttributeId,
|
||||
sdpWriter.DetachBuffer());
|
||||
}
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html#close()
|
||||
//
|
||||
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
|
||||
// TODO(b/184975123): replace with real implementation.
|
||||
Exception BluetoothServerSocket::Close() { return Exception(); }
|
||||
Exception BluetoothServerSocket::Close() {
|
||||
EnterCriticalSection(&critical_section_);
|
||||
closed_ = true;
|
||||
bluetooth_sockets_ = {};
|
||||
rfcomm_provider_->StopAdvertising();
|
||||
LeaveCriticalSection(&critical_section_);
|
||||
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
} // namespace windows
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
@@ -15,14 +15,60 @@
|
||||
#ifndef PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_SERVER_SOCKET_H_
|
||||
#define PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_SERVER_SOCKET_H_
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#include <queue>
|
||||
|
||||
#include "platform/api/bluetooth_classic.h"
|
||||
#include "platform/impl/windows/bluetooth_classic_socket.h"
|
||||
#include "platform/impl/windows/generated/winrt/Windows.Devices.Bluetooth.Rfcomm.h"
|
||||
#include "platform/impl/windows/generated/winrt/Windows.Foundation.h"
|
||||
#include "platform/impl/windows/generated/winrt/Windows.Networking.Sockets.h"
|
||||
#include "platform/impl/windows/generated/winrt/base.h"
|
||||
|
||||
namespace location {
|
||||
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;
|
||||
|
||||
// Represents an asynchronous action.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.foundation.iasyncaction?view=winrt-20348
|
||||
using winrt::Windows::Foundation::IAsyncAction;
|
||||
|
||||
// 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;
|
||||
|
||||
// Represents an instance of a local RFCOMM service.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.rfcomm.rfcommserviceprovider?view=winrt-20348
|
||||
using winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommServiceProvider;
|
||||
|
||||
// Represents an RFCOMM service ID.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.rfcomm.rfcommserviceid?view=winrt-20348
|
||||
using winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommServiceId;
|
||||
|
||||
// Writes data to an output stream.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.datawriter?view=winrt-20348
|
||||
using winrt::Windows::Storage::Streams::DataWriter;
|
||||
|
||||
// Specifies the type of character encoding for a stream.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.unicodeencoding?view=winrt-20348
|
||||
using winrt::Windows::Storage::Streams::UnicodeEncoding;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html.
|
||||
class BluetoothServerSocket : public api::BluetoothServerSocket {
|
||||
public:
|
||||
BluetoothServerSocket();
|
||||
|
||||
// TODO(b/184975123): replace with real implementation.
|
||||
~BluetoothServerSocket() override;
|
||||
|
||||
@@ -34,14 +80,31 @@ class BluetoothServerSocket : public api::BluetoothServerSocket {
|
||||
// On success, returns connected socket, ready to exchange data.
|
||||
// Returns nullptr on error.
|
||||
// Once error is reported, it is permanent, and ServerSocket has to be closed.
|
||||
// TODO(b/184975123): replace with real implementation.
|
||||
std::unique_ptr<api::BluetoothSocket> Accept() override;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html#close()
|
||||
//
|
||||
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
|
||||
// TODO(b/184975123): replace with real implementation.
|
||||
Exception Close() override;
|
||||
|
||||
Exception StartListening(const std::string& service_name,
|
||||
const std::string& service_uuid);
|
||||
|
||||
private:
|
||||
void InitializeServiceSdpAttributes(RfcommServiceProvider rfcommProvider,
|
||||
std::string service_name);
|
||||
|
||||
// This is used to store sockets in case Accept hasn't been called. Once
|
||||
// Accept has been called the socket is popped from the queue and returned to
|
||||
// the caller
|
||||
std::queue<std::unique_ptr<BluetoothSocket>> bluetooth_sockets_;
|
||||
|
||||
StreamSocketListener stream_socket_listener_;
|
||||
|
||||
CRITICAL_SECTION critical_section_;
|
||||
bool closed_ = false;
|
||||
|
||||
RfcommServiceProvider* rfcomm_provider_;
|
||||
};
|
||||
|
||||
} // namespace windows
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#define PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_SOCKET_H_
|
||||
|
||||
#include "platform/api/bluetooth_classic.h"
|
||||
|
||||
#include "platform/impl/windows/generated/winrt/Windows.Foundation.h"
|
||||
#include "platform/impl/windows/generated/winrt/Windows.Networking.Sockets.h"
|
||||
#include "platform/impl/windows/generated/winrt/Windows.Storage.Streams.h"
|
||||
@@ -65,6 +66,10 @@ class BluetoothSocket : public api::BluetoothSocket {
|
||||
public:
|
||||
BluetoothSocket();
|
||||
|
||||
BluetoothSocket(
|
||||
winrt::Windows::Networking::Sockets::StreamSocket streamSocket)
|
||||
: windows_socket_(streamSocket) {}
|
||||
|
||||
// TODO(b/184975123): replace with real implementation.
|
||||
~BluetoothSocket() override;
|
||||
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
#ifndef PLATFORM_IMPL_WINDOWS_UTILS_H_
|
||||
#define PLATFORM_IMPL_WINDOWS_UTILS_H_
|
||||
|
||||
#include <Windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace location {
|
||||
@@ -23,7 +26,19 @@ namespace windows {
|
||||
|
||||
std::string uint64_to_mac_address_string(uint64_t bluetoothAddress);
|
||||
|
||||
}
|
||||
namespace Constants {
|
||||
// The Id of the Service Name SDP attribute
|
||||
const uint16_t SdpServiceNameAttributeId = 0x100;
|
||||
|
||||
// The SDP Type of the Service Name SDP attribute.
|
||||
// The first byte in the SDP Attribute encodes the SDP Attribute Type as
|
||||
// follows:
|
||||
// - the Attribute Type size in the least significant 3 bits,
|
||||
// - the SDP Attribute Type value in the most significant 5 bits.
|
||||
const char SdpServiceNameAttributeType = (4 << 3) | 5;
|
||||
} // namespace Constants
|
||||
|
||||
} // namespace windows
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
|
||||
Reference in New Issue
Block a user