blob: a5d9692689daadf1c8e971a611ef54db41c0aff3 [file] [log] [blame]
// Copyright 2020 Google LLC
// 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
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
#include "platform/api/bluetooth_classic.h"
#include "platform/impl/windows/bluetooth_adapter.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 {
namespace nearby {
namespace windows {
// Represents a device. This class allows access to well-known device properties
// as well as additional properties specified during device enumeration.
using winrt::Windows::Devices::Enumeration::DeviceInformation;
// Represents the kind of DeviceInformation object.
using winrt::Windows::Devices::Enumeration::DeviceInformationKind;
// Contains updated properties for a DeviceInformation object.
using winrt::Windows::Devices::Enumeration::DeviceInformationUpdate;
// Enumerates devices dynamically, so that the app receives notifications if
// devices are added, removed, or changed after the initial enumeration is
// complete.
using winrt::Windows::Devices::Enumeration::DeviceWatcher;
// Describes the state of a DeviceWatcher object.
using winrt::Windows::Devices::Enumeration::DeviceWatcherStatus;
// Represents an instance of a service on a Bluetooth basic rate device.
using winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommDeviceService;
// Indicates the status of the access to a device.
using winrt::Windows::Devices::Enumeration::DeviceAccessStatus;
// Contains the information about access to a device.
using winrt::Windows::Devices::Enumeration::DeviceAccessInformation;
// Represents an RFCOMM service ID.
using winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommServiceId;
// Reads data from an input stream.
using winrt::Windows::Storage::Streams::DataReader;
// Writes data to an output stream.
using winrt::Windows::Storage::Streams::DataWriter;
// Bluetooth protocol ID = \"{e0cbf06c-cd8b-4647-bb8a-263b43f0f974}\"
// Container of operations that can be performed over the Bluetooth Classic
// medium.
class BluetoothClassicMedium : public api::BluetoothClassicMedium {
BluetoothClassicMedium(api::BluetoothAdapter& bluetoothAdapter);
~BluetoothClassicMedium() override;
bool StartDiscovery(DiscoveryCallback discovery_callback) override;
// 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().
bool StopDiscovery() override;
// A combination of
// followed by
// service_uuid is the canonical textual representation
// ( of a
// type 3 name-based
// (
// UUID.
// On success, returns a new BluetoothSocket.
// On error, throw's an exception
std::unique_ptr<api::BluetoothSocket> ConnectToService(
api::BluetoothDevice& remote_device, const std::string& service_uuid,
CancellationFlag* cancellation_flag) override;
// service_uuid is the canonical textual representation
// ( of a
// type 3 name-based
// (
// UUID.
// Returns nullptr error.
std::unique_ptr<api::BluetoothServerSocket> ListenForService(
const std::string& service_name,
const std::string& service_uuid) override;
api::BluetoothDevice* GetRemoteDevice(
const std::string& mac_address) override;
bool StartScanning();
bool StopScanning();
bool IsWatcherStarted();
bool IsWatcherRunning();
void InitializeDeviceWatcher();
void OnScanModeChanged(BluetoothAdapter::ScanMode scanMode);
// This is for a coroutine whose return type is winrt::fire_and_forget, which
// handles async operations which don't have any dependencies.
winrt::fire_and_forget DeviceWatcher_Added(DeviceWatcher sender,
DeviceInformation deviceInfo);
winrt::fire_and_forget DeviceWatcher_Updated(
DeviceWatcher sender, DeviceInformationUpdate deviceInfo);
winrt::fire_and_forget DeviceWatcher_Removed(
DeviceWatcher sender, DeviceInformationUpdate deviceInfo);
// Check to make sure we can connect if we try
bool HaveAccess(winrt::hstring deviceId);
// Get the service requested
RfcommDeviceService GetRequestedService(BluetoothDevice* device,
winrt::guid service);
// Check to see that the device actually handles the requested service
bool CheckSdp(RfcommDeviceService requestedService);
BluetoothClassicMedium::DiscoveryCallback discovery_callback_;
DeviceWatcher device_watcher_ = nullptr;
std::unique_ptr<BluetoothSocket> bluetooth_socket_;
std::unique_ptr<BluetoothServerSocket> bluetooth_server_socket_;
std::string service_name_;
std::string service_uuid_;
// hstring is the only type of string winrt understands.
std::map<winrt::hstring, std::unique_ptr<BluetoothDevice>> devices_by_id_;
// CRITICAL_SECTION is a lightweight synchronization mechanism
CRITICAL_SECTION critical_section_;
BluetoothAdapter& bluetooth_adapter_;
BluetoothAdapter::ScanMode scan_mode_;
} // namespace windows
} // namespace nearby
} // namespace location