1 // Copyright 2014 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_session.h"
8 #include "device/bluetooth/bluetooth_adapter.h"
12 BluetoothDiscoveryFilter::BluetoothDiscoveryFilter(TransportMask transport
) {
13 SetTransport(transport
);
16 BluetoothDiscoveryFilter::~BluetoothDiscoveryFilter() {
19 bool BluetoothDiscoveryFilter::GetRSSI(int16_t* out_rssi
) const {
28 void BluetoothDiscoveryFilter::SetRSSI(int16_t rssi
) {
30 rssi_
.reset(new int16_t());
35 bool BluetoothDiscoveryFilter::GetPathloss(uint16_t* out_pathloss
) const {
40 *out_pathloss
= *pathloss_
;
44 void BluetoothDiscoveryFilter::SetPathloss(uint16_t pathloss
) {
46 pathloss_
.reset(new uint16_t());
48 *pathloss_
= pathloss
;
51 BluetoothDiscoveryFilter::TransportMask
BluetoothDiscoveryFilter::GetTransport()
56 void BluetoothDiscoveryFilter::SetTransport(TransportMask transport
) {
57 DCHECK(transport
> 0 && transport
< 4);
58 transport_
= transport
;
61 void BluetoothDiscoveryFilter::GetUUIDs(
62 std::set
<device::BluetoothUUID
>& out_uuids
) const {
65 for (auto& uuid
: uuids_
)
66 out_uuids
.insert(*uuid
);
69 void BluetoothDiscoveryFilter::AddUUID(const device::BluetoothUUID
& uuid
) {
70 DCHECK(uuid
.IsValid());
71 for (auto& uuid_it
: uuids_
) {
76 uuids_
.push_back(new device::BluetoothUUID(uuid
));
79 void BluetoothDiscoveryFilter::CopyFrom(
80 const BluetoothDiscoveryFilter
& filter
) {
81 transport_
= filter
.transport_
;
83 if (filter
.uuids_
.size()) {
84 for (auto& uuid
: filter
.uuids_
)
89 if (filter
.rssi_
.get()) {
90 SetRSSI(*filter
.rssi_
);
94 if (filter
.pathloss_
.get()) {
95 SetPathloss(*filter
.pathloss_
);
100 scoped_ptr
<device::BluetoothDiscoveryFilter
> BluetoothDiscoveryFilter::Merge(
101 const device::BluetoothDiscoveryFilter
* filter_a
,
102 const device::BluetoothDiscoveryFilter
* filter_b
) {
103 scoped_ptr
<BluetoothDiscoveryFilter
> result
;
105 if (!filter_a
&& !filter_b
) {
109 result
.reset(new BluetoothDiscoveryFilter(Transport::TRANSPORT_DUAL
));
111 if (!filter_a
|| !filter_b
|| filter_a
->IsDefault() ||
112 filter_b
->IsDefault()) {
116 // both filters are not empty, so they must have transport set.
117 result
->SetTransport(filter_a
->transport_
| filter_b
->transport_
);
119 // if both filters have uuids, them merge them. Otherwise uuids filter should
121 if (filter_a
->uuids_
.size() && filter_b
->uuids_
.size()) {
122 std::set
<device::BluetoothUUID
> uuids
;
123 filter_a
->GetUUIDs(uuids
);
124 for (auto& uuid
: uuids
)
125 result
->AddUUID(uuid
);
127 filter_b
->GetUUIDs(uuids
);
128 for (auto& uuid
: uuids
)
129 result
->AddUUID(uuid
);
132 if ((filter_a
->rssi_
.get() && filter_b
->pathloss_
.get()) ||
133 (filter_a
->pathloss_
.get() && filter_b
->rssi_
.get())) {
134 // if both rssi and pathloss filtering is enabled in two different
135 // filters, we can't tell which filter is more generic, and we don't set
136 // proximity filtering on merged filter.
140 if (filter_a
->rssi_
.get() && filter_b
->rssi_
.get()) {
141 result
->SetRSSI(std::min(*filter_a
->rssi_
, *filter_b
->rssi_
));
142 } else if (filter_a
->pathloss_
.get() && filter_b
->pathloss_
.get()) {
143 result
->SetPathloss(std::max(*filter_a
->pathloss_
, *filter_b
->pathloss_
));
149 bool BluetoothDiscoveryFilter::Equals(
150 const BluetoothDiscoveryFilter
& other
) const {
151 if (((!!rssi_
.get()) != (!!other
.rssi_
.get())) ||
152 (rssi_
.get() && other
.rssi_
.get() && *rssi_
!= *other
.rssi_
)) {
156 if (((!!pathloss_
.get()) != (!!other
.pathloss_
.get())) ||
157 (pathloss_
.get() && other
.pathloss_
.get() &&
158 *pathloss_
!= *other
.pathloss_
)) {
162 if (transport_
!= other
.transport_
)
165 std::set
<device::BluetoothUUID
> uuids_a
, uuids_b
;
167 other
.GetUUIDs(uuids_b
);
168 if (uuids_a
!= uuids_b
)
174 bool BluetoothDiscoveryFilter::IsDefault() const {
175 return !(rssi_
.get() || pathloss_
.get() || uuids_
.size() ||
176 transport_
!= Transport::TRANSPORT_DUAL
);
179 BluetoothDiscoverySession::BluetoothDiscoverySession(
180 scoped_refptr
<BluetoothAdapter
> adapter
,
181 scoped_ptr
<BluetoothDiscoveryFilter
> discovery_filter
)
184 discovery_filter_(discovery_filter
.release()),
185 weak_ptr_factory_(this) {
186 DCHECK(adapter_
.get());
189 BluetoothDiscoverySession::~BluetoothDiscoverySession() {
191 Stop(base::Bind(&base::DoNothing
), base::Bind(&base::DoNothing
));
196 bool BluetoothDiscoverySession::IsActive() const {
200 void BluetoothDiscoverySession::Stop(
201 const base::Closure
& callback
,
202 const ErrorCallback
& error_callback
) {
204 LOG(WARNING
) << "Discovery session not active. Cannot stop.";
205 error_callback
.Run();
208 VLOG(1) << "Stopping device discovery session.";
209 adapter_
->RemoveDiscoverySession(
210 discovery_filter_
.get(),
211 base::Bind(&BluetoothDiscoverySession::OnStop
,
212 weak_ptr_factory_
.GetWeakPtr(), callback
),
216 void BluetoothDiscoverySession::OnStop(const base::Closure
& callback
) {
218 discovery_filter_
.reset();
222 void BluetoothDiscoverySession::MarkAsInactive() {
226 adapter_
->DiscoverySessionBecameInactive(this);
229 void BluetoothDiscoverySession::SetDiscoveryFilter(
230 scoped_ptr
<BluetoothDiscoveryFilter
> discovery_filter
,
231 const base::Closure
& callback
,
232 const ErrorCallback
& error_callback
) {
233 discovery_filter_
.reset(discovery_filter
.release());
234 adapter_
->SetDiscoveryFilter(adapter_
->GetMergedDiscoveryFilter().Pass(),
235 callback
, error_callback
);
238 const BluetoothDiscoveryFilter
* BluetoothDiscoverySession::GetDiscoveryFilter()
240 return discovery_filter_
.get();
243 } // namespace device