1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef DEVICE_BLUETOOTH_BLUETOOTH_ADVERTISEMENT_H_
#define DEVICE_BLUETOOTH_BLUETOOTH_ADVERTISEMENT_H_
#include <stdint.h>
#include <map>
#include <optional>
#include <string>
#include <utility>
#include <vector>
#include "base/functional/callback.h"
#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
#include "build/build_config.h"
#include "device/bluetooth/bluetooth_export.h"
namespace device {
// BluetoothAdvertisement represents an advertisement which advertises over the
// LE channel during its lifetime.
class DEVICE_BLUETOOTH_EXPORT BluetoothAdvertisement
: public base::RefCounted<BluetoothAdvertisement> {
public:
// Possible types of error raised while registering or unregistering
// advertisements.
enum ErrorCode {
ERROR_UNSUPPORTED_PLATFORM, // Bluetooth advertisement not supported on
// current platform.
ERROR_ADVERTISEMENT_ALREADY_EXISTS, // An advertisement is already
// registered.
ERROR_ADVERTISEMENT_DOES_NOT_EXIST, // Unregistering an advertisement which
// is not registered.
ERROR_ADVERTISEMENT_INVALID_LENGTH, // Advertisement is not of a valid
// length.
ERROR_STARTING_ADVERTISEMENT, // Error when starting the advertisement
// through a platform API.
ERROR_RESET_ADVERTISING, // Error while resetting advertising.
ERROR_ADAPTER_POWERED_OFF, // Error because the adapter is off
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
ERROR_INVALID_ADVERTISEMENT_INTERVAL, // Advertisement interval specified
// is out of valid range.
#endif
INVALID_ADVERTISEMENT_ERROR_CODE
};
// Type of advertisement.
enum AdvertisementType {
// This advertises with the type set to ADV_NONCONN_IND, which indicates
// to receivers that our device is not connectable.
ADVERTISEMENT_TYPE_BROADCAST,
// This advertises with the type set to ADV_IND or ADV_SCAN_IND, which
// indicates to receivers that our device is connectable.
ADVERTISEMENT_TYPE_PERIPHERAL
};
using UUIDList = std::vector<std::string>;
using ManufacturerData = std::map<uint16_t, std::vector<uint8_t>>;
using ServiceData = std::map<std::string, std::vector<uint8_t>>;
using ScanResponseData = std::map<uint8_t, std::vector<uint8_t>>;
// Structure that holds the data for an advertisement.
class DEVICE_BLUETOOTH_EXPORT Data {
public:
explicit Data(AdvertisementType type);
Data(const Data&) = delete;
Data& operator=(const Data&) = delete;
~Data();
AdvertisementType type() { return type_; }
std::optional<UUIDList> service_uuids() {
return pass_value(service_uuids_);
}
std::optional<ManufacturerData> manufacturer_data() {
return pass_value(manufacturer_data_);
}
std::optional<UUIDList> solicit_uuids() {
return pass_value(solicit_uuids_);
}
std::optional<ServiceData> service_data() {
return pass_value(service_data_);
}
std::optional<ScanResponseData> scan_response_data() {
return pass_value(scan_response_data_);
}
void set_service_uuids(std::optional<UUIDList> service_uuids) {
service_uuids_ = std::move(service_uuids);
}
void set_manufacturer_data(
std::optional<ManufacturerData> manufacturer_data) {
manufacturer_data_ = std::move(manufacturer_data);
}
void set_solicit_uuids(std::optional<UUIDList> solicit_uuids) {
solicit_uuids_ = std::move(solicit_uuids);
}
void set_service_data(std::optional<ServiceData> service_data) {
service_data_ = std::move(service_data);
}
void set_scan_response_data(
std::optional<ScanResponseData> scan_response_data) {
scan_response_data_ = std::move(scan_response_data);
}
void set_include_tx_power(bool include_tx_power) {
include_tx_power_ = include_tx_power;
}
private:
Data();
// Passes the value along held by |from|, and restore the optional moved
// from to nullopt.
template <typename T>
static std::optional<T> pass_value(std::optional<T>& from) {
std::optional<T> value = std::move(from);
from = std::nullopt;
return value;
}
AdvertisementType type_;
std::optional<UUIDList> service_uuids_;
std::optional<ManufacturerData> manufacturer_data_;
std::optional<UUIDList> solicit_uuids_;
std::optional<ServiceData> service_data_;
std::optional<ScanResponseData> scan_response_data_;
bool include_tx_power_;
};
// Interface for observing changes to this advertisement.
class Observer {
public:
virtual ~Observer() {}
// Called when this advertisement is released and is no longer advertising.
virtual void AdvertisementReleased(
BluetoothAdvertisement* advertisement) = 0;
};
BluetoothAdvertisement(const BluetoothAdvertisement&) = delete;
BluetoothAdvertisement& operator=(const BluetoothAdvertisement&) = delete;
// Adds and removes observers for events for this advertisement.
void AddObserver(BluetoothAdvertisement::Observer* observer);
void RemoveObserver(BluetoothAdvertisement::Observer* observer);
// Unregisters this advertisement. Called on destruction of this object
// automatically but can be called directly to explicitly unregister this
// object.
using SuccessCallback = base::OnceClosure;
using ErrorCallback = base::OnceCallback<void(ErrorCode)>;
virtual void Unregister(SuccessCallback success_callback,
ErrorCallback error_callback) = 0;
protected:
friend class base::RefCounted<BluetoothAdvertisement>;
BluetoothAdvertisement();
// The destructor will unregister this advertisement.
virtual ~BluetoothAdvertisement();
// List of observers interested in event notifications from us. Objects in
// |observers_| are expected to outlive a BluetoothAdvertisement object.
base::ObserverList<BluetoothAdvertisement::Observer>::Unchecked observers_;
};
} // namespace device
#endif // DEVICE_BLUETOOTH_BLUETOOTH_ADVERTISEMENT_H_
|