mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 22:56:12 -04:00
[BLE Refactor] Implement iOS Platform BLEV2 api with No-Op for advertising and discovery
PiperOrigin-RevId: 451844375
This commit is contained in:
committed by
Copybara-Service
parent
fe27ea822a
commit
01ec55de58
@@ -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_
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user