mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 22:56:12 -04:00
Add BlePeripheral discovery logic implementation
PiperOrigin-RevId: 452609641
This commit is contained in:
committed by
Copybara-Service
parent
28da839987
commit
926dcc28d4
@@ -15,10 +15,13 @@
|
||||
#include "internal/platform/implementation/windows/ble_medium.h"
|
||||
|
||||
#include <future> // NOLINT
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "internal/platform/implementation/ble.h"
|
||||
#include "internal/platform/implementation/windows/utils.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "winrt/Windows.Devices.Bluetooth.Advertisement.h"
|
||||
#include "winrt/Windows.Devices.Bluetooth.h"
|
||||
@@ -29,29 +32,80 @@ namespace location {
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
namespace {
|
||||
|
||||
// Specifies common Bluetooth error cases.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.bluetootherror?view=winrt-22621
|
||||
using ::winrt::Windows::Devices::Bluetooth::BluetoothError;
|
||||
|
||||
// Represents a Bluetooth LE advertisement payload.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisement?view=winrt-22621
|
||||
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
|
||||
BluetoothLEAdvertisement;
|
||||
|
||||
// Represents a Bluetooth LE advertisement section. A Bluetooth LE advertisement
|
||||
// packet can contain multiple instances of these
|
||||
// BluetoothLEAdvertisementDataSection objects.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementdatasection?view=winrt-22621
|
||||
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
|
||||
BluetoothLEAdvertisementDataSection;
|
||||
|
||||
// Represents the Bluetooth LE advertisement types defined in the Generic Access
|
||||
// Profile (GAP) by the Bluetooth Special Interest Group (SIG).
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementdatatypes?view=winrt-22621
|
||||
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
|
||||
BluetoothLEAdvertisementDataTypes;
|
||||
|
||||
// Represents an object to send Bluetooth Low Energy (LE) advertisements.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementpublisher?view=winrt-22621
|
||||
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
|
||||
BluetoothLEAdvertisementPublisher;
|
||||
|
||||
// Represents the possible states of the BluetoothLEAdvertisementPublisher.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementpublisherstatus?view=winrt-22621
|
||||
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
|
||||
BluetoothLEAdvertisementPublisherStatus;
|
||||
|
||||
// Provides data for a StatusChanged event on a
|
||||
// BluetoothLEAdvertisementPublisher.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementpublisherstatuschangedeventargs?view=winrt-22621
|
||||
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
|
||||
BluetoothLEAdvertisementPublisherStatusChangedEventArgs;
|
||||
|
||||
// Provides data for a Received event on a BluetoothLEAdvertisementWatcher. A
|
||||
// BluetoothLEAdvertisementReceivedEventArgs instance is created when the
|
||||
// Received event occurs on a BluetoothLEAdvertisementWatcher object.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementreceivedeventargs?view=winrt-22621
|
||||
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
|
||||
BluetoothLEAdvertisementReceivedEventArgs;
|
||||
|
||||
// Represents an object to receive Bluetooth Low Energy (LE) advertisements.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementwatcher?view=winrt-22621
|
||||
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
|
||||
BluetoothLEAdvertisementWatcher;
|
||||
|
||||
// Represents the possible states of the BluetoothLEAdvertisementWatcher.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementwatcherstatus?view=winrt-22621
|
||||
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
|
||||
BluetoothLEAdvertisementWatcherStatus;
|
||||
|
||||
// Provides data for a Stopped event on a BluetoothLEAdvertisementWatcher. A
|
||||
// BluetoothLEAdvertisementWatcherStoppedEventArgs instance is created when the
|
||||
// Stopped event occurs on a BluetoothLEAdvertisementWatcher object.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementwatcherstoppedeventargs?view=winrt-22621
|
||||
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
|
||||
BluetoothLEAdvertisementWatcherStoppedEventArgs;
|
||||
|
||||
// Defines constants that specify a Bluetooth LE scanning mode.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothlescanningmode?view=winrt-22621
|
||||
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
|
||||
BluetoothLEScanningMode;
|
||||
|
||||
// Reads data from an input stream.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.datareader?view=winrt-22621
|
||||
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-22621
|
||||
using ::winrt::Windows::Storage::Streams::DataWriter;
|
||||
|
||||
template <typename T>
|
||||
@@ -157,7 +211,6 @@ bool BleMedium::StopAdvertising(const std::string& service_id) {
|
||||
return publisher_state_future.get() == PublisherState::kStopped;
|
||||
}
|
||||
|
||||
// TODO(b/234229557): Add BlePeripheral discovery logic
|
||||
bool BleMedium::StartScanning(
|
||||
const std::string& service_id,
|
||||
const std::string& fast_advertisement_service_uuid,
|
||||
@@ -166,6 +219,7 @@ bool BleMedium::StartScanning(
|
||||
|
||||
NEARBY_LOGS(INFO) << "Windows Ble StartScanning: service_id=" << service_id;
|
||||
|
||||
service_id_ = service_id;
|
||||
advertisement_received_callback_ = std::move(callback);
|
||||
|
||||
watcher_token_ = watcher_.Stopped({this, &BleMedium::WatcherHandler});
|
||||
@@ -373,29 +427,43 @@ void BleMedium::AdvertisementReceivedHandler(
|
||||
BluetoothLEAdvertisementWatcher watcher,
|
||||
BluetoothLEAdvertisementReceivedEventArgs args) {
|
||||
// Handle all BLE advertisements and determine whether the BLE Medium
|
||||
// Advertisement Scan Response packet (containing Copresence UUID 0xFEF3) has
|
||||
// been received in the handler
|
||||
std::array<uint8_t, 8> bluetooth_base_array = {
|
||||
static_cast<uint8_t>(0x80), static_cast<uint8_t>(0x00),
|
||||
static_cast<uint8_t>(0x00), static_cast<uint8_t>(0x80),
|
||||
static_cast<uint8_t>(0x5F), static_cast<uint8_t>(0x9B),
|
||||
static_cast<uint8_t>(0x34), static_cast<uint8_t>(0xFB)};
|
||||
winrt::guid kCopresenceServiceUuid128bit(
|
||||
static_cast<uint32_t>(0x0000FEF3), static_cast<uint16_t>(0x0000),
|
||||
static_cast<uint16_t>(0x1000), bluetooth_base_array);
|
||||
// Advertisement Scan Response packet (containing Copresence UUID 0xFEF3 in
|
||||
// 0x16 Service Data) has been received in the handler
|
||||
|
||||
IVector<winrt::guid> guids = args.Advertisement().ServiceUuids();
|
||||
bool is_advertisement_found = false;
|
||||
for (const winrt::guid& uuid : guids) {
|
||||
if (uuid == kCopresenceServiceUuid128bit) {
|
||||
is_advertisement_found = true;
|
||||
BluetoothLEAdvertisement advertisement = args.Advertisement();
|
||||
|
||||
for (BluetoothLEAdvertisementDataSection service_data :
|
||||
advertisement.GetSectionsByType(0x16)) {
|
||||
// Parse Advertisement Data for Section 0x16 (Service Data)
|
||||
DataReader data_reader = DataReader::FromBuffer(service_data.Data());
|
||||
|
||||
// Discard the first 2 bytes of Service Uuid in Service Data
|
||||
uint8_t first_byte = data_reader.ReadByte(); // 0xf3
|
||||
uint8_t second_byte = data_reader.ReadByte(); // 0xfe
|
||||
|
||||
if (first_byte == 0xf3 && second_byte == 0xfe) {
|
||||
std::string data;
|
||||
|
||||
uint8_t unconsumed_buffer_length = data_reader.UnconsumedBufferLength();
|
||||
for (int i = 0; i < unconsumed_buffer_length; i++) {
|
||||
data.append(1, static_cast<unsigned char>(data_reader.ReadByte()));
|
||||
}
|
||||
|
||||
ByteArray advertisement_data(data);
|
||||
|
||||
std::string peripheral_name =
|
||||
uint64_to_mac_address_string(args.BluetoothAddress());
|
||||
std::unique_ptr<BlePeripheral> peripheral =
|
||||
std::make_unique<BlePeripheral>();
|
||||
peripheral->SetName(peripheral_name);
|
||||
peripheral->SetAdvertisementBytes(advertisement_data);
|
||||
|
||||
NEARBY_LOGS(INFO) << "Sending Fast Advertisement packet for processing.";
|
||||
advertisement_received_callback_.peripheral_discovered_cb(
|
||||
/*ble_peripheral*/ *(peripheral.get()), /*service_id*/ service_id_,
|
||||
/*is_fast_advertisement*/ true);
|
||||
}
|
||||
}
|
||||
if (is_advertisement_found == true) {
|
||||
BlePeripheral peripheral;
|
||||
advertisement_received_callback_.peripheral_discovered_cb(peripheral,
|
||||
"\xfe\xf3", true);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace windows
|
||||
|
||||
@@ -87,6 +87,7 @@ class BleMedium : public api::BleMedium {
|
||||
absl::Mutex mutex_;
|
||||
api::BluetoothAdapter* adapter_;
|
||||
ByteArray advertisement_byte_ ABSL_GUARDED_BY(mutex_);
|
||||
std::string service_id_;
|
||||
|
||||
DiscoveredPeripheralCallback advertisement_received_callback_;
|
||||
|
||||
|
||||
@@ -35,12 +35,24 @@ class BlePeripheral : public api::BlePeripheral {
|
||||
public:
|
||||
~BlePeripheral() override = default;
|
||||
|
||||
std::string GetName() const override { return ""; }
|
||||
std::string GetName() const override { return name_; }
|
||||
|
||||
ByteArray GetAdvertisementBytes(
|
||||
const std::string& service_id) const override {
|
||||
return ByteArray{};
|
||||
return advertisement_data_;
|
||||
}
|
||||
|
||||
void SetName(const std::string& name) {
|
||||
name_ = name;
|
||||
}
|
||||
|
||||
void SetAdvertisementBytes(ByteArray advertisement_bytes) {
|
||||
advertisement_data_ = advertisement_bytes;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
ByteArray advertisement_data_;
|
||||
};
|
||||
|
||||
} // namespace windows
|
||||
|
||||
Reference in New Issue
Block a user