[BLE Refactor] Implement iOS Platform BLEV2 api with No-Op for advertising and discovery

PiperOrigin-RevId: 451844375
This commit is contained in:
edwinwu
2022-05-30 03:54:55 -07:00
committed by Copybara-Service
parent fe27ea822a
commit 01ec55de58
15 changed files with 753 additions and 2 deletions
@@ -21,6 +21,8 @@ package(default_visibility = [
objc_library(
name = "Platform",
srcs = [
"ble.mm",
"bluetooth_adapter.mm",
"crypto.mm",
"log_message.mm",
"multi_thread_executor.mm",
@@ -30,6 +32,8 @@ objc_library(
"wifi_lan.mm",
],
hdrs = [
"ble.h",
"bluetooth_adapter.h",
"log_message.h",
"multi_thread_executor.h",
"scheduled_executor.h",
@@ -20,6 +20,8 @@ package(default_visibility = ["//internal/platform/implementation/ios:__subpacka
objc_library(
name = "Mediums",
srcs = [
"Ble/GNCMBleCentral.m",
"Ble/GNCMBlePeripheral.m",
"GNCLeaks.m",
"GNCMConnection.m",
"WifiLan/GNCMBonjourBrowser.m",
@@ -28,6 +30,8 @@ objc_library(
"WifiLan/GNCMBonjourUtils.m",
],
hdrs = [
"Ble/GNCMBleCentral.h",
"Ble/GNCMBlePeripheral.h",
"GNCLeaks.h",
"GNCMConnection.h",
"WifiLan/GNCMBonjourBrowser.h",
@@ -0,0 +1,51 @@
// Copyright 2022 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.
#import "internal/platform/implementation/ios/Mediums/GNCMConnection.h"
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
* This handler is called on a discover when a nearby advertising endpoint is discovered.
*/
typedef void (^GNCMScanResultHandler)(NSString *serviceUUID, NSData *serviceData);
/**
* GNCMBleCentral discovers devices advertising the specified service UUID via BLE (using the
* GNCMBlePeripheral class) and calls the specififed scanning result handler when one is found.
*
* This class is thread-safe. Any calls made to it (and to the objects/closures it passes back via
* callbacks) can be made from any thread/queue. Callbacks made from this class are called on the
* specified queue.
*/
@interface GNCMBleCentral : NSObject
- (instancetype)init NS_UNAVAILABLE;
/**
* Initializes an `GNCMBleCentral` object.
*
* @param serviceUUID A string that uniquely identifies the scanning services to search for.
* @param scanResultHandler The handler that is called when an endpoint advertising the service
* UUID is discovered.
*/
- (instancetype)initWithServiceUUID:(NSString *)serviceUUID
scanResultHandler:(GNCMScanResultHandler)scanResultHandler
NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,80 @@
// Copyright 2022 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.
#import "internal/platform/implementation/ios/Mediums/Ble/GNCMBleCentral.h"
#include <CoreBluetooth/CoreBluetooth.h>
#import "internal/platform/implementation/ios/Mediums/GNCMConnection.h"
NS_ASSUME_NONNULL_BEGIN
@interface GNCMBleCentral () <CBCentralManagerDelegate, CBPeripheralDelegate>
@end
@implementation GNCMBleCentral {
/** Service UUID the central is scanning for. */
CBUUID *_serviceUUID;
/** The scan result callback handler. */
GNCMScanResultHandler _scanResultHandler;
/** Central manager used to scan or connect to peripherals. */
CBCentralManager *_centralManager;
/** Serial background queue for |centralManager|. */
dispatch_queue_t _selfQueue;
}
- (instancetype)initWithServiceUUID:(NSString *)serviceUUID
scanResultHandler:(GNCMScanResultHandler)scanResultHandler {
self = [super init];
if (self) {
_serviceUUID = [CBUUID UUIDWithString:serviceUUID];
_scanResultHandler = scanResultHandler;
// To make this class thread-safe, use a serial queue for all state changes, and have Core
// Bluetooth also use this queue.
_selfQueue = dispatch_queue_create("GNCCentralManagerQueue", DISPATCH_QUEUE_SERIAL);
_centralManager = [[CBCentralManager alloc]
initWithDelegate:self
queue:_selfQueue
options:@{CBCentralManagerOptionShowPowerAlertKey : @NO}];
}
return self;
}
- (void)dealloc {
// These calls must be made on |selfQueue|. Can't capture |self| in an async block, so must use
// dispatch_sync. This means dealloc must be called from an external queue, which means |self|
// must never be captured by any escaping block used in this class.
dispatch_sync(_selfQueue, ^{
[_centralManager stopScan];
});
}
#pragma mark CBCentralManagerDelegate
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
if (central.state == CBManagerStatePoweredOn) {
NSLog(@"[NEARBY] CBCentralManager powered on; starting scan");
[_centralManager
scanForPeripheralsWithServices:@[ _serviceUUID ]
options:@{CBCentralManagerScanOptionAllowDuplicatesKey : @YES}];
} else {
NSLog(@"[NEARBY] CBCentralManager not powered on; stopping scan");
[_centralManager stopScan];
}
}
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,42 @@
// Copyright 2022 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.
#include <CoreBluetooth/CoreBluetooth.h>
NS_ASSUME_NONNULL_BEGIN
/**
* GNCMBlePeripheral advertises the specified service UUID via Ble for the purpose of being
* discovered by a central using the GNCMBleCentral class.
*
* This class is thread-safe. Any calls made to it (and to the objects/closures it passes back via
* callbacks) can be made from any thread/queue. Callbacks made from this class are called on the
* specified queue.
*/
@interface GNCMBlePeripheral : NSObject
- (instancetype)init NS_UNAVAILABLE;
/**
* Initializes an `GNCMBlePeripheral` object.
*
* @param serviceUUID A string that uniquely identifies the advertised service to search for.
* @param advertisementData The data to advertise.
*/
- (instancetype)initWithServiceUUID:(NSString *)serviceUUID
advertisementData:(NSData *)advertisementData NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,105 @@
// Copyright 2022 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.
#import "internal/platform/implementation/ios/Mediums/Ble/GNCMBlePeripheral.h"
#include <CoreBluetooth/CoreBluetooth.h>
#import "internal/platform/implementation/ios/GNCUtils.h"
NS_ASSUME_NONNULL_BEGIN
@interface GNCMBlePeripheral () <CBPeripheralManagerDelegate>
@end
@implementation GNCMBlePeripheral {
/** GATT service for advertisement. */
CBMutableService *_advertisementService;
/** Data to be advertised. */
NSData *_advertisementData;
/** Peripheral manager used to advertise or connect to peripherals. */
CBPeripheralManager *_peripheralManager;
/** Serial background queue for |peripheralManager|. */
dispatch_queue_t _selfQueue;
}
- (instancetype)initWithServiceUUID:(NSString *)serviceUUID
advertisementData:(NSData *)advertisementData {
self = [super init];
if (self) {
_advertisementService =
[[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:serviceUUID] primary:YES];
_advertisementData = [advertisementData copy];
// To make this class thread-safe, use a serial queue for all state changes, and have Core
// Bluetooth also use this queue.
_selfQueue = dispatch_queue_create("GNCPeripheralManagerQueue", DISPATCH_QUEUE_SERIAL);
// Set up the peripheral manager for the advertisement data.
_peripheralManager = [[CBPeripheralManager alloc]
initWithDelegate:self
queue:_selfQueue
options:@{CBPeripheralManagerOptionShowPowerAlertKey : @NO}];
}
return self;
}
- (void)dealloc {
// These calls must be made on |selfQueue|. Can't capture |self| in an async block, so must use
// dispatch_sync. This means delloc must be called from an external queue, which means |self|
// must never be captured by any escaping block used in this class.
dispatch_sync(_selfQueue, ^{
[self stopAdvertising];
});
}
#pragma mark CBPeripheralManagerDelegate
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral {
if (peripheral.state == CBManagerStatePoweredOn) {
NSLog(@"[NEARBY] CBPeripheralManager powered on; starting advertising");
[_peripheralManager startAdvertising:@{
CBAdvertisementDataServiceUUIDsKey : @[ _advertisementService.UUID ],
CBAdvertisementDataLocalNameKey : _advertisementData
}];
} else {
NSLog(@"[NEARBY] CBPeripheralManager not powered on; stopping advertising");
[self stopAdvertising];
}
}
- (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral
error:(nullable NSError *)error {
if (error) {
NSLog(@"[NEARBY] Error starting advertising: %@,", [error localizedDescription]);
return;
}
if (_peripheralManager.state != CBPeripheralManagerStatePoweredOn) {
NSLog(@"[NEARBY] Error starting advertising: peripheral manager not on!");
return;
}
NSLog(@"[NEARBY] Peripheral manager started advertising");
}
#pragma mark Private
/** Signals the peripheral manager to stop advertising. Must be called on _selfQueue */
- (void)stopAdvertising {
[_peripheralManager stopAdvertising];
}
@end
NS_ASSUME_NONNULL_END
@@ -21,6 +21,8 @@ objc_library(
name = "PlatformTestslib",
testonly = 1,
srcs = [
"GNCBleTest.mm",
"GNCBluetoothAdapterTest.mm",
"GNCCryptoTest.mm",
"GNCMultiThreadExecutorTest.mm",
"GNCScheduledExecutorTest.mm",
@@ -0,0 +1,22 @@
#import "internal/platform/implementation/ios/Tests/GNCBLEA.h"
#import <XCTest/XCTest.h>
@interface GNCBLEATest : XCTestCase
@end
@implementation GNCBLEATest
- (void)setUp {
[super setUp];
// Remove if not used.
}
- (void)tearDown {
// Remove if not used.
[super tearDown];
}
- (void)testFoo {
XCTAssertTrue(YES, @"A true test");
}
@end
@@ -0,0 +1,72 @@
// Copyright 2022 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.
#import <XCTest/XCTest.h>
#include <string>
#include <utility>
#include "internal/platform/byte_array.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
#include "internal/platform/implementation/platform.h"
using ::location::nearby::ByteArray;
using ::location::nearby::Uuid;
using ::location::nearby::api::BluetoothAdapter;
using ::location::nearby::api::ImplementationPlatform;
using ::location::nearby::api::ble_v2::BleAdvertisementData;
using ::location::nearby::api::ble_v2::BleMedium;
using ::location::nearby::api::ble_v2::TxPowerLevel;
static const char *const kAdvertisementString = "\x0a\x0b\x0c\x0d";
static const TxPowerLevel kTxPowerLevel = TxPowerLevel::kHigh;
@interface GNCBleTest : XCTestCase
@end
@implementation GNCBleTest {
std::unique_ptr<BluetoothAdapter> _adapter;
std::unique_ptr<BleMedium> _ble;
}
- (void)setUp {
[super setUp];
_adapter = ImplementationPlatform::CreateBluetoothAdapter();
_ble = ImplementationPlatform::CreateBleV2Medium(*_adapter);
}
- (void)testStartandStopAdvertising {
Uuid service_uuid(1234, 5678);
ByteArray advertisement_bytes{std::string(kAdvertisementString)};
// Assemble regular advertisement data.
BleAdvertisementData advertising_data;
advertising_data.is_extended_advertisement = false;
advertising_data.service_data = {{service_uuid, advertisement_bytes}};
XCTAssertTrue(_ble->StartAdvertising(advertising_data,
{.tx_power_level = kTxPowerLevel, .is_connectable = true}));
XCTAssertTrue(_ble->StopAdvertising());
}
- (void)testStartandStopScanning {
Uuid service_uuid(1234, 5678);
XCTAssertTrue(_ble->StartScanning(service_uuid, kTxPowerLevel, {}));
XCTAssertTrue(_ble->StopScanning());
}
@end
@@ -0,0 +1,87 @@
// Copyright 2022 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.
#import <XCTest/XCTest.h>
#include <string>
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
#include "internal/platform/implementation/ios/bluetooth_adapter.h"
using ::location::nearby::ios::BlePeripheral;
using ::location::nearby::ios::BluetoothAdapter;
using ScanMode = ::location::nearby::api::BluetoothAdapter::ScanMode;
using Status = ::location::nearby::api::BluetoothAdapter::Status;
static const char kAdapterName[] = "MyBtAdapter";
static const char kMacAddress[] = "4C:8B:1D:CE:BA:D1";
@interface GNCBluetoothAdapterTest : XCTestCase
@end
@implementation GNCBluetoothAdapterTest
- (void)testName {
BluetoothAdapter adapter;
XCTAssertTrue(adapter.SetName(kAdapterName));
XCTAssertEqual(adapter.GetName(), std::string(kAdapterName));
}
- (void)testGetScanMode {
BluetoothAdapter adapter;
// Always return kNone as ScanMode is not supported .
XCTAssertEqual(adapter.GetScanMode(), ScanMode::kNone);
}
- (void)testSetScanMode_DefaultUnsupported {
BluetoothAdapter adapter;
XCTAssertFalse(adapter.SetScanMode(ScanMode::kNone));
XCTAssertFalse(adapter.SetScanMode(ScanMode::kConnectable));
XCTAssertFalse(adapter.SetScanMode(ScanMode::kConnectableDiscoverable));
}
- (void)testSetStatus {
BluetoothAdapter adapter;
XCTAssertTrue(adapter.SetStatus(Status::kDisabled));
XCTAssertFalse(adapter.IsEnabled());
XCTAssertTrue(adapter.SetStatus(Status::kEnabled));
XCTAssertTrue(adapter.IsEnabled());
}
- (void)testMacAddress {
BluetoothAdapter adapter;
adapter.SetMacAddress(kMacAddress);
XCTAssertEqual(adapter.GetMacAddress(), std::string(kMacAddress));
}
- (void)testGetPeripheral {
BluetoothAdapter adapter;
adapter.SetMacAddress(kMacAddress);
// The peripheral from adapter, the MAC address is the same.
BlePeripheral& peripheral = adapter.GetPeripheral();
XCTAssertEqual(adapter.GetMacAddress(), peripheral.GetAddress());
}
@end
@@ -0,0 +1,69 @@
// Copyright 2022 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 THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_IOS_BLE_H_
#define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_IOS_BLE_H_
#import <Foundation/Foundation.h>
#include <string>
#include "internal/platform/cancellation_flag.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
#include "internal/platform/implementation/ios/bluetooth_adapter.h"
@class GNCMBlePeripheral, GNCMBleCentral;
namespace location {
namespace nearby {
namespace ios {
/** Concrete BleMedium implementation. */
class BleMedium : public api::ble_v2::BleMedium {
public:
explicit BleMedium(api::BluetoothAdapter& adapter);
// api::BleMedium:
bool StartAdvertising(const api::ble_v2::BleAdvertisementData& advertising_data,
api::ble_v2::AdvertiseParameters advertise_set_parameters) override;
bool StopAdvertising() override;
bool StartScanning(const Uuid& service_uuid, api::ble_v2::TxPowerLevel tx_power_level,
api::ble_v2::BleMedium::ScanCallback scan_callback) override;
bool StopScanning() override;
std::unique_ptr<api::ble_v2::GattServer> StartGattServer(
api::ble_v2::ServerGattConnectionCallback callback) override;
std::unique_ptr<api::ble_v2::GattClient> ConnectToGattServer(
api::ble_v2::BlePeripheral& peripheral, api::ble_v2::TxPowerLevel tx_power_level,
api::ble_v2::ClientGattConnectionCallback callback) override;
std::unique_ptr<api::ble_v2::BleServerSocket> OpenServerSocket(
const std::string& service_id) override;
std::unique_ptr<api::ble_v2::BleSocket> Connect(const std::string& service_id,
api::ble_v2::TxPowerLevel tx_power_level,
api::ble_v2::BlePeripheral& peripheral,
CancellationFlag* cancellation_flag) override;
bool IsExtendedAdvertisementsAvailable() override;
private:
BluetoothAdapter* adapter_;
GNCMBlePeripheral* peripheral_;
GNCMBleCentral* central_;
dispatch_queue_t callback_queue_;
};
} // namespace ios
} // namespace nearby
} // namespace location
#endif // THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_IOS_BLE_H_
+100
View File
@@ -0,0 +1,100 @@
// Copyright 2022 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.
#import "internal/platform/implementation/ios/ble.h"
#include <CoreBluetooth/CoreBluetooth.h>
#include <string>
#include "internal/platform/implementation/ble_v2.h"
#import "internal/platform/implementation/ios/Mediums/Ble/GNCMBleCentral.h"
#import "internal/platform/implementation/ios/Mediums/Ble/GNCMBlePeripheral.h"
#include "internal/platform/implementation/ios/bluetooth_adapter.h"
#include "internal/platform/implementation/ios/utils.h"
namespace location {
namespace nearby {
namespace ios {
using ::location::nearby::api::ble_v2::BleAdvertisementData;
using ::location::nearby::api::ble_v2::TxPowerLevel;
using ScanCallback = ::location::nearby::api::ble_v2::BleMedium::ScanCallback;
BleMedium::BleMedium(::location::nearby::api::BluetoothAdapter& adapter)
: adapter_(static_cast<BluetoothAdapter*>(&adapter)) {}
bool BleMedium::StartAdvertising(
const BleAdvertisementData& advertising_data,
::location::nearby::api::ble_v2::AdvertiseParameters advertise_set_parameters) {
if (advertising_data.service_data.empty()) {
return false;
}
const std::string& service_uuid = advertising_data.service_data.begin()->first.Get16BitAsString();
const ByteArray& service_data_bytes = advertising_data.service_data.begin()->second;
peripheral_ =
[[GNCMBlePeripheral alloc] initWithServiceUUID:ObjCStringFromCppString(service_uuid)
advertisementData:NSDataFromByteArray(service_data_bytes)];
return true;
}
bool BleMedium::StopAdvertising() {
peripheral_ = nil;
return true;
}
bool BleMedium::StartScanning(const Uuid& service_uuid, TxPowerLevel tx_power_level,
ScanCallback scan_callback) {
central_ = [[GNCMBleCentral alloc]
initWithServiceUUID:ObjCStringFromCppString(service_uuid.Get16BitAsString())
scanResultHandler:^(NSString* serviceUUID, NSData* serviceData){
// TODO(b/228751356): Add scan callback implementation.
}];
return true;
}
bool BleMedium::StopScanning() {
central_ = nil;
return true;
}
std::unique_ptr<api::ble_v2::GattServer> BleMedium::StartGattServer(
api::ble_v2::ServerGattConnectionCallback callback) {
return nullptr;
}
std::unique_ptr<api::ble_v2::GattClient> BleMedium::ConnectToGattServer(
api::ble_v2::BlePeripheral& peripheral, TxPowerLevel tx_power_level,
api::ble_v2::ClientGattConnectionCallback callback) {
return nullptr;
}
std::unique_ptr<api::ble_v2::BleServerSocket> BleMedium::OpenServerSocket(
const std::string& service_id) {
return nullptr;
}
std::unique_ptr<api::ble_v2::BleSocket> BleMedium::Connect(const std::string& service_id,
TxPowerLevel tx_power_level,
api::ble_v2::BlePeripheral& peripheral,
CancellationFlag* cancellation_flag) {
return nullptr;
}
bool BleMedium::IsExtendedAdvertisementsAvailable() { return false; }
} // namespace ios
} // namespace nearby
} // namespace location
@@ -0,0 +1,82 @@
// Copyright 2022 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 THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_IOS_BLUETOOTH_ADAPTER_H_
#define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_IOS_BLUETOOTH_ADAPTER_H_
#include <string>
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
namespace location {
namespace nearby {
namespace ios {
class BluetoothAdapter;
// Concrete BlePeripheral implementation.
class BlePeripheral : public api::ble_v2::BlePeripheral {
public:
std::string GetAddress() const override;
private:
// Only BluetoothAdapter may instantiate BlePeripheral.
friend class BluetoothAdapter;
explicit BlePeripheral(BluetoothAdapter* adapter) : adapter_(*adapter) {}
BluetoothAdapter& adapter_;
};
// Concrete BluetoothAdapter implementation.
class BluetoothAdapter : public api::BluetoothAdapter {
public:
using Status = api::BluetoothAdapter::Status;
using ScanMode = api::BluetoothAdapter::ScanMode;
~BluetoothAdapter() override { SetStatus(Status::kDisabled); }
bool SetStatus(Status status) override {
enabled_ = status == Status::kEnabled;
return true;
}
bool IsEnabled() const override { return enabled_; }
ScanMode GetScanMode() const override { return mode_; }
bool SetScanMode(ScanMode mode) override { return false; }
std::string GetName() const override { return name_; }
bool SetName(absl::string_view name) override {
name_ = std::string(name);
return true;
}
std::string GetMacAddress() const override { return mac_address_; }
void SetMacAddress(absl::string_view mac_address) {
mac_address_ = std::string(mac_address);
}
BlePeripheral& GetPeripheral() { return peripheral_; }
private:
BlePeripheral peripheral_{this};
ScanMode mode_ = ScanMode::kNone;
std::string name_;
std::string mac_address_;
bool enabled_ = true;
};
} // namespace ios
} // namespace nearby
} // namespace location
#endif // THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_IOS_BLUETOOTH_ADAPTER_H_
@@ -0,0 +1,30 @@
// Copyright 2022 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.
#include "internal/platform/implementation/ios/bluetooth_adapter.h"
#include <string>
#include "absl/strings/string_view.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
namespace location {
namespace nearby {
namespace ios {
std::string BlePeripheral::GetAddress() const { return adapter_.GetMacAddress(); }
} // namespace ios
} // namespace nearby
} // namespace location
@@ -18,6 +18,7 @@
#include "internal/platform/implementation/ios/atomic_boolean.h"
#include "internal/platform/implementation/ios/atomic_uint32.h"
#include "internal/platform/implementation/ios/ble.h"
#include "internal/platform/implementation/ios/condition_variable.h"
#include "internal/platform/implementation/ios/count_down_latch.h"
#import "internal/platform/implementation/ios/log_message.h"
@@ -118,7 +119,7 @@ std::unique_ptr<ScheduledExecutor> ImplementationPlatform::CreateScheduledExecut
// Mediums
std::unique_ptr<BluetoothAdapter> ImplementationPlatform::CreateBluetoothAdapter() {
return nullptr;
return std::make_unique<ios::BluetoothAdapter>();
}
std::unique_ptr<BluetoothClassicMedium> ImplementationPlatform::CreateBluetoothClassicMedium(
@@ -132,7 +133,7 @@ std::unique_ptr<BleMedium> ImplementationPlatform::CreateBleMedium(api::Bluetoot
std::unique_ptr<ble_v2::BleMedium>
ImplementationPlatform::CreateBleV2Medium(api::BluetoothAdapter& adapter) {
return nullptr;
return std::make_unique<ios::BleMedium>(adapter);
}
std::unique_ptr<ServerSyncMedium> ImplementationPlatform::CreateServerSyncMedium() {