blob: 1502317115366954bf44ca8f1b77c04014ccec01 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "device/bluetooth/bluetooth_low_energy_advertisement_manager_mac.h"
#include "base/strings/sys_string_conversions.h"
#include "device/bluetooth/bluetooth_advertisement.h"
namespace device {
BluetoothLowEnergyAdvertisementManagerMac::
BluetoothLowEnergyAdvertisementManagerMac()
: active_advertisement_(nullptr) {}
BluetoothLowEnergyAdvertisementManagerMac::
~BluetoothLowEnergyAdvertisementManagerMac() {}
void BluetoothLowEnergyAdvertisementManagerMac::TryStartAdvertisement() {
if (!active_advertisement_ ||
active_advertisement_->status() !=
BluetoothAdvertisementMac::WAITING_FOR_PERIPHERAL_MANAGER) {
return;
}
if ([peripheral_manager_ state] < CBPeripheralManagerStatePoweredOn) {
return;
}
NSMutableArray* service_uuid_array = [[NSMutableArray alloc] init];
for (const std::string& service_uuid :
active_advertisement_->service_uuids()) {
NSString* uuid_string =
[NSString stringWithCString:service_uuid.c_str()
encoding:[NSString defaultCStringEncoding]];
[service_uuid_array addObject:[CBUUID UUIDWithString:uuid_string]];
}
active_advertisement_->OnAdvertisementPending();
[peripheral_manager_ startAdvertising:@{
CBAdvertisementDataServiceUUIDsKey : service_uuid_array
}];
}
void BluetoothLowEnergyAdvertisementManagerMac::RegisterAdvertisement(
std::unique_ptr<BluetoothAdvertisement::Data> advertisement_data,
const BluetoothAdapter::CreateAdvertisementCallback& callback,
const BluetoothAdapter::AdvertisementErrorCallback& error_callback) {
std::unique_ptr<BluetoothAdvertisement::UUIDList> service_uuids =
advertisement_data->service_uuids();
if (!service_uuids || advertisement_data->manufacturer_data() ||
advertisement_data->solicit_uuids() ||
advertisement_data->service_data()) {
LOG(ERROR) << "macOS only supports advertising service UUIDs.";
error_callback.Run(BluetoothAdvertisement::ERROR_UNSUPPORTED_PLATFORM);
return;
}
if (active_advertisement_ && active_advertisement_->status() !=
BluetoothAdvertisementMac::UNREGISTERED) {
LOG(ERROR) << "Only one active BLE advertisement is currently supported.";
error_callback.Run(
BluetoothAdvertisement::ERROR_ADVERTISEMENT_ALREADY_EXISTS);
return;
}
active_advertisement_ = new BluetoothAdvertisementMac(
std::move(service_uuids), callback, error_callback, this);
TryStartAdvertisement();
}
void BluetoothLowEnergyAdvertisementManagerMac::UnregisterAdvertisement(
BluetoothAdvertisementMac* advertisement,
const BluetoothAdvertisement::SuccessCallback& success_callback,
const BluetoothAdvertisement::ErrorCallback& error_callback) {
if (advertisement != active_advertisement_.get()) {
LOG(ERROR) << "Only one active advertisement is supported currently.";
error_callback.Run(BluetoothAdvertisement::ERROR_RESET_ADVERTISING);
return;
}
active_advertisement_ = nullptr;
[peripheral_manager_ stopAdvertising];
}
void BluetoothLowEnergyAdvertisementManagerMac::DidStartAdvertising(
NSError* error) {
if (!active_advertisement_ ||
active_advertisement_->status() !=
BluetoothAdvertisementMac::ADVERTISEMENT_PENDING) {
return;
}
if (error != nil) {
LOG(ERROR) << "Error advertising: "
<< base::SysNSStringToUTF8(error.localizedDescription);
active_advertisement_->OnAdvertisementError(
BluetoothAdvertisement::ERROR_STARTING_ADVERTISEMENT);
return;
}
active_advertisement_->OnAdvertisementSuccess();
}
void BluetoothLowEnergyAdvertisementManagerMac::SetPeripheralManager(
CBPeripheralManager* peripheral_manager) {
peripheral_manager_ = peripheral_manager;
}
} // device