Initial implementation of BluetoothServerSocket

PiperOrigin-RevId: 390461649
This commit is contained in:
jfcarroll
2021-08-12 14:33:26 -07:00
committed by Copybara-Service
parent 512ba2af43
commit 07d33cfa9e
6 changed files with 300 additions and 63 deletions
@@ -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();
}