1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "device/bluetooth/bluetooth_discovery_filter.h"
9 BluetoothDiscoveryFilter::BluetoothDiscoveryFilter(TransportMask transport
) {
10 SetTransport(transport
);
13 BluetoothDiscoveryFilter::~BluetoothDiscoveryFilter() {
16 bool BluetoothDiscoveryFilter::GetRSSI(int16_t* out_rssi
) const {
25 void BluetoothDiscoveryFilter::SetRSSI(int16_t rssi
) {
27 rssi_
.reset(new int16_t());
32 bool BluetoothDiscoveryFilter::GetPathloss(uint16_t* out_pathloss
) const {
37 *out_pathloss
= *pathloss_
;
41 void BluetoothDiscoveryFilter::SetPathloss(uint16_t pathloss
) {
43 pathloss_
.reset(new uint16_t());
45 *pathloss_
= pathloss
;
48 BluetoothDiscoveryFilter::TransportMask
BluetoothDiscoveryFilter::GetTransport()
53 void BluetoothDiscoveryFilter::SetTransport(TransportMask transport
) {
54 DCHECK(transport
> 0 && transport
< 4);
55 transport_
= transport
;
58 void BluetoothDiscoveryFilter::GetUUIDs(
59 std::set
<device::BluetoothUUID
>& out_uuids
) const {
62 for (auto& uuid
: uuids_
)
63 out_uuids
.insert(*uuid
);
66 void BluetoothDiscoveryFilter::AddUUID(const device::BluetoothUUID
& uuid
) {
67 DCHECK(uuid
.IsValid());
68 for (auto& uuid_it
: uuids_
) {
73 uuids_
.push_back(new device::BluetoothUUID(uuid
));
76 void BluetoothDiscoveryFilter::CopyFrom(
77 const BluetoothDiscoveryFilter
& filter
) {
78 transport_
= filter
.transport_
;
80 if (filter
.uuids_
.size()) {
81 for (auto& uuid
: filter
.uuids_
)
86 if (filter
.rssi_
.get()) {
87 SetRSSI(*filter
.rssi_
);
91 if (filter
.pathloss_
.get()) {
92 SetPathloss(*filter
.pathloss_
);
97 scoped_ptr
<device::BluetoothDiscoveryFilter
> BluetoothDiscoveryFilter::Merge(
98 const device::BluetoothDiscoveryFilter
* filter_a
,
99 const device::BluetoothDiscoveryFilter
* filter_b
) {
100 scoped_ptr
<BluetoothDiscoveryFilter
> result
;
102 if (!filter_a
&& !filter_b
) {
106 result
.reset(new BluetoothDiscoveryFilter(Transport::TRANSPORT_DUAL
));
108 if (!filter_a
|| !filter_b
|| filter_a
->IsDefault() ||
109 filter_b
->IsDefault()) {
113 // both filters are not empty, so they must have transport set.
114 result
->SetTransport(filter_a
->transport_
| filter_b
->transport_
);
116 // if both filters have uuids, them merge them. Otherwise uuids filter should
118 if (filter_a
->uuids_
.size() && filter_b
->uuids_
.size()) {
119 std::set
<device::BluetoothUUID
> uuids
;
120 filter_a
->GetUUIDs(uuids
);
121 for (auto& uuid
: uuids
)
122 result
->AddUUID(uuid
);
124 filter_b
->GetUUIDs(uuids
);
125 for (auto& uuid
: uuids
)
126 result
->AddUUID(uuid
);
129 if ((filter_a
->rssi_
.get() && filter_b
->pathloss_
.get()) ||
130 (filter_a
->pathloss_
.get() && filter_b
->rssi_
.get())) {
131 // if both rssi and pathloss filtering is enabled in two different
132 // filters, we can't tell which filter is more generic, and we don't set
133 // proximity filtering on merged filter.
137 if (filter_a
->rssi_
.get() && filter_b
->rssi_
.get()) {
138 result
->SetRSSI(std::min(*filter_a
->rssi_
, *filter_b
->rssi_
));
139 } else if (filter_a
->pathloss_
.get() && filter_b
->pathloss_
.get()) {
140 result
->SetPathloss(std::max(*filter_a
->pathloss_
, *filter_b
->pathloss_
));
146 bool BluetoothDiscoveryFilter::Equals(
147 const BluetoothDiscoveryFilter
& other
) const {
148 if (((!!rssi_
.get()) != (!!other
.rssi_
.get())) ||
149 (rssi_
.get() && other
.rssi_
.get() && *rssi_
!= *other
.rssi_
)) {
153 if (((!!pathloss_
.get()) != (!!other
.pathloss_
.get())) ||
154 (pathloss_
.get() && other
.pathloss_
.get() &&
155 *pathloss_
!= *other
.pathloss_
)) {
159 if (transport_
!= other
.transport_
)
162 std::set
<device::BluetoothUUID
> uuids_a
, uuids_b
;
164 other
.GetUUIDs(uuids_b
);
165 if (uuids_a
!= uuids_b
)
171 bool BluetoothDiscoveryFilter::IsDefault() const {
172 return !(rssi_
.get() || pathloss_
.get() || uuids_
.size() ||
173 transport_
!= Transport::TRANSPORT_DUAL
);
176 } // namespace device