| // 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 |
| // |
| // https://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. |
| |
| #ifndef PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_MEDIUM_H_ |
| #define PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_MEDIUM_H_ |
| |
| #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. |
| // https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.deviceinformation?view=winrt-20348 |
| using winrt::Windows::Devices::Enumeration::DeviceInformation; |
| |
| // Represents the kind of DeviceInformation object. |
| // https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.deviceinformationkind?view=winrt-20348 |
| using winrt::Windows::Devices::Enumeration::DeviceInformationKind; |
| |
| // Contains updated properties for a DeviceInformation object. |
| // https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.deviceinformationupdate?view=winrt-20348 |
| 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. |
| // https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcher?view=winrt-20348 |
| using winrt::Windows::Devices::Enumeration::DeviceWatcher; |
| |
| // Describes the state of a DeviceWatcher object. |
| // https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcherstatus?view=winrt-20348 |
| using winrt::Windows::Devices::Enumeration::DeviceWatcherStatus; |
| |
| // Represents an instance of a service on a Bluetooth basic rate device. |
| // https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.rfcomm.rfcommdeviceservice?view=winrt-20348 |
| using winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommDeviceService; |
| |
| // Indicates the status of the access to a device. |
| // https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.deviceaccessstatus?view=winrt-20348 |
| using winrt::Windows::Devices::Enumeration::DeviceAccessStatus; |
| |
| // Contains the information about access to a device. |
| // https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.deviceaccessinformation?view=winrt-20348 |
| using winrt::Windows::Devices::Enumeration::DeviceAccessInformation; |
| |
| // 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; |
| |
| // 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; |
| |
| // 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 \ |
| L"System.Devices.Aep.ProtocolId:=\"{e0cbf06c-cd8b-4647-bb8a-263b43f0f974}\"" |
| |
| // Container of operations that can be performed over the Bluetooth Classic |
| // medium. |
| class BluetoothClassicMedium : public api::BluetoothClassicMedium { |
| public: |
| BluetoothClassicMedium(api::BluetoothAdapter& bluetoothAdapter); |
| |
| ~BluetoothClassicMedium() override; |
| |
| // https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#startDiscovery() |
| bool StartDiscovery(DiscoveryCallback discovery_callback) override; |
| |
| // https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#cancelDiscovery() |
| // |
| // 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 |
| // https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#createInsecureRfcommSocketToServiceRecord |
| // followed by |
| // https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html#connect(). |
| // |
| // service_uuid is the canonical textual representation |
| // (https://en.wikipedia.org/wiki/Universally_unique_identifier#Format) of a |
| // type 3 name-based |
| // (https://en.wikipedia.org/wiki/Universally_unique_identifier#Versions_3_and_5_(namespace_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; |
| |
| // https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#listenUsingInsecureRfcommWithServiceRecord |
| // |
| // service_uuid is the canonical textual representation |
| // (https://en.wikipedia.org/wiki/Universally_unique_identifier#Format) of a |
| // type 3 name-based |
| // (https://en.wikipedia.org/wiki/Universally_unique_identifier#Versions_3_and_5_(namespace_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; |
| |
| private: |
| 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. |
| // https://docs.microsoft.com/en-us/uwp/cpp-ref-for-winrt/fire-and-forget |
| 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. |
| // https://docs.microsoft.com/en-us/uwp/cpp-ref-for-winrt/hstring |
| std::map<winrt::hstring, std::unique_ptr<BluetoothDevice>> |
| discovered_devices_by_id_; |
| |
| // CRITICAL_SECTION is a lightweight synchronization mechanism |
| // https://docs.microsoft.com/en-us/windows/win32/sync/critical-section-objects |
| CRITICAL_SECTION critical_section_; |
| |
| BluetoothAdapter& bluetooth_adapter_; |
| |
| BluetoothAdapter::ScanMode scan_mode_; |
| }; |
| |
| } // namespace windows |
| } // namespace nearby |
| } // namespace location |
| |
| #endif // PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_MEDIUM_H_ |