| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chromeos/components/tether/ble_advertiser.h" | 5 #include "chromeos/components/tether/ble_advertiser.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "chromeos/components/tether/ble_constants.h" | 8 #include "chromeos/components/tether/ble_constants.h" |
| 9 #include "components/cryptauth/local_device_data_provider.h" | 9 #include "components/cryptauth/local_device_data_provider.h" |
| 10 #include "components/cryptauth/proto/cryptauth_api.pb.h" | 10 #include "components/cryptauth/proto/cryptauth_api.pb.h" |
| 11 #include "components/cryptauth/remote_beacon_seed_fetcher.h" | 11 #include "components/cryptauth/remote_beacon_seed_fetcher.h" |
| 12 #include "components/proximity_auth/logging/logging.h" | 12 #include "components/proximity_auth/logging/logging.h" |
| 13 #include "device/bluetooth/bluetooth_advertisement.h" | 13 #include "device/bluetooth/bluetooth_advertisement.h" |
| 14 | 14 |
| 15 namespace chromeos { | 15 namespace chromeos { |
| 16 | 16 |
| 17 namespace tether { | 17 namespace tether { |
| 18 | 18 |
| 19 namespace { | 19 namespace { |
| 20 | 20 |
| 21 uint8_t kInvertedConnectionFlag = 0x01; | 21 uint8_t kInvertedConnectionFlag = 0x01; |
| 22 | 22 |
| 23 } // namespace | 23 } // namespace |
| 24 | 24 |
| 25 BleAdvertiser::IndividualAdvertisement::IndividualAdvertisement( | 25 BleAdvertiser::IndividualAdvertisement::IndividualAdvertisement( |
| 26 const std::string& device_id, | 26 const std::string& device_id, |
| 27 scoped_refptr<device::BluetoothAdapter> adapter, | 27 scoped_refptr<device::BluetoothAdapter> adapter, |
| 28 std::unique_ptr<cryptauth::DataWithTimestamp> advertisement_data) | 28 std::unique_ptr<cryptauth::DataWithTimestamp> advertisement_data, |
| 29 const base::Closure& on_unregister_advertisement_success_callback, |
| 30 const base::Callback<void(device::BluetoothAdvertisement::ErrorCode)>& |
| 31 on_unregister_advertisement_error_callback, |
| 32 std::unordered_set<std::string>* active_advertisement_device_ids_set) |
| 29 : device_id_(device_id), | 33 : device_id_(device_id), |
| 30 adapter_(adapter), | 34 adapter_(adapter), |
| 31 advertisement_data_(std::move(advertisement_data)), | 35 advertisement_data_(std::move(advertisement_data)), |
| 32 is_initializing_advertising_(false), | 36 is_initializing_advertising_(false), |
| 33 advertisement_(nullptr), | 37 advertisement_(nullptr), |
| 38 on_unregister_advertisement_success_callback_( |
| 39 on_unregister_advertisement_success_callback), |
| 40 on_unregister_advertisement_error_callback_( |
| 41 on_unregister_advertisement_error_callback), |
| 42 active_advertisement_device_ids_set_(active_advertisement_device_ids_set), |
| 34 weak_ptr_factory_(this) { | 43 weak_ptr_factory_(this) { |
| 35 adapter_->AddObserver(this); | 44 adapter_->AddObserver(this); |
| 36 AdvertiseIfPossible(); | 45 AdvertiseIfPossible(); |
| 37 } | 46 } |
| 38 | 47 |
| 39 BleAdvertiser::IndividualAdvertisement::~IndividualAdvertisement() { | 48 BleAdvertiser::IndividualAdvertisement::~IndividualAdvertisement() { |
| 40 if (advertisement_) { | 49 if (advertisement_) { |
| 41 advertisement_->Unregister( | 50 advertisement_->Unregister(on_unregister_advertisement_success_callback_, |
| 42 base::Bind(&base::DoNothing), | 51 on_unregister_advertisement_error_callback_); |
| 43 base::Bind(&IndividualAdvertisement::OnAdvertisementUnregisterFailure, | |
| 44 weak_ptr_factory_.GetWeakPtr())); | |
| 45 } | 52 } |
| 46 | 53 |
| 47 adapter_->RemoveObserver(this); | 54 adapter_->RemoveObserver(this); |
| 48 } | 55 } |
| 49 | 56 |
| 57 void BleAdvertiser::IndividualAdvertisement:: |
| 58 OnPreviousAdvertisementUnregistered() { |
| 59 DCHECK(active_advertisement_device_ids_set_->find(device_id_) == |
| 60 active_advertisement_device_ids_set_->end()); |
| 61 AdvertiseIfPossible(); |
| 62 } |
| 63 |
| 50 void BleAdvertiser::IndividualAdvertisement::AdapterPoweredChanged( | 64 void BleAdvertiser::IndividualAdvertisement::AdapterPoweredChanged( |
| 51 device::BluetoothAdapter* adapter, | 65 device::BluetoothAdapter* adapter, |
| 52 bool powered) { | 66 bool powered) { |
| 53 DCHECK(adapter_.get() == adapter); | 67 DCHECK(adapter_.get() == adapter); |
| 54 AdvertiseIfPossible(); | 68 AdvertiseIfPossible(); |
| 55 } | 69 } |
| 56 | 70 |
| 57 void BleAdvertiser::IndividualAdvertisement::AdvertisementReleased( | 71 void BleAdvertiser::IndividualAdvertisement::AdvertisementReleased( |
| 58 device::BluetoothAdvertisement* advertisement) { | 72 device::BluetoothAdvertisement* advertisement) { |
| 59 DCHECK(advertisement_.get() == advertisement); | 73 DCHECK(advertisement_.get() == advertisement); |
| 60 | 74 |
| 61 // If the advertisement was released, delete it and try again. Note that this | 75 // If the advertisement was released, delete it and try again. Note that this |
| 62 // situation is not expected to occur under normal circumstances. | 76 // situation is not expected to occur under normal circumstances. |
| 77 advertisement_->RemoveObserver(this); |
| 63 advertisement_ = nullptr; | 78 advertisement_ = nullptr; |
| 79 active_advertisement_device_ids_set_->erase(device_id_); |
| 80 |
| 64 AdvertiseIfPossible(); | 81 AdvertiseIfPossible(); |
| 65 } | 82 } |
| 66 | 83 |
| 67 void BleAdvertiser::IndividualAdvertisement::AdvertiseIfPossible() { | 84 void BleAdvertiser::IndividualAdvertisement::AdvertiseIfPossible() { |
| 68 if (!adapter_->IsPowered() || is_initializing_advertising_ || | 85 if (!adapter_->IsPowered() || is_initializing_advertising_ || |
| 69 advertisement_) { | 86 advertisement_ || |
| 87 active_advertisement_device_ids_set_->find(device_id_) != |
| 88 active_advertisement_device_ids_set_->end()) { |
| 89 // It is not possible to advertise if the adapter is not powered. Likewise, |
| 90 // we should not try to advertise if there is an advertisement already in |
| 91 // progress. |
| 70 return; | 92 return; |
| 71 } | 93 } |
| 72 | 94 |
| 73 is_initializing_advertising_ = true; | 95 is_initializing_advertising_ = true; |
| 74 | 96 |
| 75 std::unique_ptr<device::BluetoothAdvertisement::Data> advertisement_data = | 97 std::unique_ptr<device::BluetoothAdvertisement::Data> advertisement_data = |
| 76 base::MakeUnique<device::BluetoothAdvertisement::Data>( | 98 base::MakeUnique<device::BluetoothAdvertisement::Data>( |
| 77 device::BluetoothAdvertisement::AdvertisementType:: | 99 device::BluetoothAdvertisement::AdvertisementType:: |
| 78 ADVERTISEMENT_TYPE_BROADCAST); | 100 ADVERTISEMENT_TYPE_BROADCAST); |
| 79 advertisement_data->set_service_uuids(CreateServiceUuids()); | 101 advertisement_data->set_service_uuids(CreateServiceUuids()); |
| 80 advertisement_data->set_service_data(CreateServiceData()); | 102 advertisement_data->set_service_data(CreateServiceData()); |
| 81 | 103 |
| 82 adapter_->RegisterAdvertisement( | 104 adapter_->RegisterAdvertisement( |
| 83 std::move(advertisement_data), | 105 std::move(advertisement_data), |
| 84 base::Bind(&IndividualAdvertisement::OnAdvertisementRegisteredCallback, | 106 base::Bind(&IndividualAdvertisement::OnAdvertisementRegisteredCallback, |
| 85 weak_ptr_factory_.GetWeakPtr()), | 107 weak_ptr_factory_.GetWeakPtr()), |
| 86 base::Bind(&IndividualAdvertisement::OnAdvertisementErrorCallback, | 108 base::Bind(&IndividualAdvertisement::OnAdvertisementErrorCallback, |
| 87 weak_ptr_factory_.GetWeakPtr())); | 109 weak_ptr_factory_.GetWeakPtr())); |
| 88 } | 110 } |
| 89 | 111 |
| 90 void BleAdvertiser::IndividualAdvertisement::OnAdvertisementRegisteredCallback( | 112 void BleAdvertiser::IndividualAdvertisement::OnAdvertisementRegisteredCallback( |
| 91 scoped_refptr<device::BluetoothAdvertisement> advertisement) { | 113 scoped_refptr<device::BluetoothAdvertisement> advertisement) { |
| 92 is_initializing_advertising_ = false; | 114 is_initializing_advertising_ = false; |
| 115 |
| 93 advertisement_ = advertisement; | 116 advertisement_ = advertisement; |
| 117 advertisement_->AddObserver(this); |
| 118 active_advertisement_device_ids_set_->insert(device_id_); |
| 119 |
| 94 PA_LOG(INFO) << "Advertisement registered. " | 120 PA_LOG(INFO) << "Advertisement registered. " |
| 95 << "Device ID: \"" | 121 << "Device ID: \"" |
| 96 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id_) | 122 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id_) |
| 97 << "\", Service data: " << advertisement_data_->DataInHex(); | 123 << "\", Service data: " << advertisement_data_->DataInHex(); |
| 98 } | 124 } |
| 99 | 125 |
| 100 void BleAdvertiser::IndividualAdvertisement::OnAdvertisementErrorCallback( | 126 void BleAdvertiser::IndividualAdvertisement::OnAdvertisementErrorCallback( |
| 101 device::BluetoothAdvertisement::ErrorCode error_code) { | 127 device::BluetoothAdvertisement::ErrorCode error_code) { |
| 102 is_initializing_advertising_ = false; | 128 is_initializing_advertising_ = false; |
| 103 PA_LOG(ERROR) << "Error registering advertisement. " | 129 PA_LOG(ERROR) << "Error registering advertisement. " |
| 104 << "Device ID: \"" | 130 << "Device ID: \"" |
| 105 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id_) | 131 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id_) |
| 106 << "\", Service data: " << advertisement_data_->DataInHex() | 132 << "\", Service data: " << advertisement_data_->DataInHex() |
| 107 << ", Error code: " << error_code; | 133 << ", Error code: " << error_code; |
| 108 } | 134 } |
| 109 | 135 |
| 110 void BleAdvertiser::IndividualAdvertisement::OnAdvertisementUnregisterFailure( | |
| 111 device::BluetoothAdvertisement::ErrorCode error_code) { | |
| 112 PA_LOG(ERROR) << "Error unregistering advertisement. " | |
| 113 << "Device ID: \"" | |
| 114 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id_) | |
| 115 << "\", Service data: " << advertisement_data_->DataInHex() | |
| 116 << " Error code: " << error_code; | |
| 117 } | |
| 118 | |
| 119 std::unique_ptr<device::BluetoothAdvertisement::UUIDList> | 136 std::unique_ptr<device::BluetoothAdvertisement::UUIDList> |
| 120 BleAdvertiser::IndividualAdvertisement::CreateServiceUuids() const { | 137 BleAdvertiser::IndividualAdvertisement::CreateServiceUuids() const { |
| 121 std::unique_ptr<device::BluetoothAdvertisement::UUIDList> list = | 138 std::unique_ptr<device::BluetoothAdvertisement::UUIDList> list = |
| 122 base::MakeUnique<device::BluetoothAdvertisement::UUIDList>(); | 139 base::MakeUnique<device::BluetoothAdvertisement::UUIDList>(); |
| 123 list->push_back(std::string(kAdvertisingServiceUuid)); | 140 list->push_back(std::string(kAdvertisingServiceUuid)); |
| 124 return list; | 141 return list; |
| 125 } | 142 } |
| 126 | 143 |
| 127 std::unique_ptr<device::BluetoothAdvertisement::ServiceData> | 144 std::unique_ptr<device::BluetoothAdvertisement::ServiceData> |
| 128 BleAdvertiser::IndividualAdvertisement::CreateServiceData() const { | 145 BleAdvertiser::IndividualAdvertisement::CreateServiceData() const { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 155 BleAdvertiser::~BleAdvertiser() {} | 172 BleAdvertiser::~BleAdvertiser() {} |
| 156 | 173 |
| 157 BleAdvertiser::BleAdvertiser( | 174 BleAdvertiser::BleAdvertiser( |
| 158 scoped_refptr<device::BluetoothAdapter> adapter, | 175 scoped_refptr<device::BluetoothAdapter> adapter, |
| 159 std::unique_ptr<cryptauth::ForegroundEidGenerator> eid_generator, | 176 std::unique_ptr<cryptauth::ForegroundEidGenerator> eid_generator, |
| 160 const cryptauth::RemoteBeaconSeedFetcher* remote_beacon_seed_fetcher, | 177 const cryptauth::RemoteBeaconSeedFetcher* remote_beacon_seed_fetcher, |
| 161 const cryptauth::LocalDeviceDataProvider* local_device_data_provider) | 178 const cryptauth::LocalDeviceDataProvider* local_device_data_provider) |
| 162 : adapter_(adapter), | 179 : adapter_(adapter), |
| 163 eid_generator_(std::move(eid_generator)), | 180 eid_generator_(std::move(eid_generator)), |
| 164 remote_beacon_seed_fetcher_(remote_beacon_seed_fetcher), | 181 remote_beacon_seed_fetcher_(remote_beacon_seed_fetcher), |
| 165 local_device_data_provider_(local_device_data_provider) {} | 182 local_device_data_provider_(local_device_data_provider), |
| 183 weak_ptr_factory_(this) {} |
| 166 | 184 |
| 167 bool BleAdvertiser::StartAdvertisingToDevice( | 185 bool BleAdvertiser::StartAdvertisingToDevice( |
| 168 const cryptauth::RemoteDevice& remote_device) { | 186 const cryptauth::RemoteDevice& remote_device) { |
| 169 if (device_id_to_advertisement_map_.size() >= kMaxConcurrentAdvertisements) { | 187 if (device_id_to_individual_advertisement_map_.size() >= |
| 188 kMaxConcurrentAdvertisements) { |
| 170 PA_LOG(ERROR) << "Attempted to register a device when the maximum number " | 189 PA_LOG(ERROR) << "Attempted to register a device when the maximum number " |
| 171 << "of devices have already been registered."; | 190 << "of devices have already been registered."; |
| 172 return false; | 191 return false; |
| 173 } | 192 } |
| 174 | 193 |
| 175 std::string local_device_public_key; | 194 std::string local_device_public_key; |
| 176 if (!local_device_data_provider_->GetLocalDeviceData(&local_device_public_key, | 195 if (!local_device_data_provider_->GetLocalDeviceData(&local_device_public_key, |
| 177 nullptr)) { | 196 nullptr)) { |
| 178 PA_LOG(WARNING) << "Error fetching the local device's public key. Cannot " | 197 PA_LOG(WARNING) << "Error fetching the local device's public key. Cannot " |
| 179 << "advertise without the public key."; | 198 << "advertise without the public key."; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 201 std::unique_ptr<cryptauth::DataWithTimestamp> advertisement = | 220 std::unique_ptr<cryptauth::DataWithTimestamp> advertisement = |
| 202 eid_generator_->GenerateAdvertisement(local_device_public_key, | 221 eid_generator_->GenerateAdvertisement(local_device_public_key, |
| 203 remote_beacon_seeds); | 222 remote_beacon_seeds); |
| 204 if (!advertisement) { | 223 if (!advertisement) { |
| 205 PA_LOG(WARNING) << "Error generating advertisement for device with ID " | 224 PA_LOG(WARNING) << "Error generating advertisement for device with ID " |
| 206 << remote_device.GetTruncatedDeviceIdForLogs() << ". " | 225 << remote_device.GetTruncatedDeviceIdForLogs() << ". " |
| 207 << "Cannot advertise."; | 226 << "Cannot advertise."; |
| 208 return false; | 227 return false; |
| 209 } | 228 } |
| 210 | 229 |
| 211 device_id_to_advertisement_map_[remote_device.GetDeviceId()] = | 230 std::string device_id = remote_device.GetDeviceId(); |
| 231 device_id_to_individual_advertisement_map_[device_id] = |
| 212 base::MakeUnique<IndividualAdvertisement>( | 232 base::MakeUnique<IndividualAdvertisement>( |
| 213 remote_device.GetDeviceId(), adapter_, std::move(advertisement)); | 233 remote_device.GetDeviceId(), adapter_, std::move(advertisement), |
| 234 base::Bind(&BleAdvertiser::OnUnregisterAdvertisementSuccess, |
| 235 weak_ptr_factory_.GetWeakPtr(), device_id), |
| 236 base::Bind(&BleAdvertiser::OnUnregisterAdvertisementError, |
| 237 weak_ptr_factory_.GetWeakPtr(), device_id), |
| 238 &active_advertisement_device_ids_set_); |
| 214 return true; | 239 return true; |
| 215 } | 240 } |
| 216 | 241 |
| 217 bool BleAdvertiser::StopAdvertisingToDevice( | 242 bool BleAdvertiser::StopAdvertisingToDevice( |
| 218 const cryptauth::RemoteDevice& remote_device) { | 243 const cryptauth::RemoteDevice& remote_device) { |
| 219 return device_id_to_advertisement_map_.erase(remote_device.GetDeviceId()) > 0; | 244 return device_id_to_individual_advertisement_map_.erase( |
| 245 remote_device.GetDeviceId()) > 0; |
| 246 } |
| 247 |
| 248 void BleAdvertiser::OnUnregisterAdvertisementSuccess( |
| 249 const std::string& associated_device_id) { |
| 250 RemoveAdvertisingDeviceIdAndRetry(associated_device_id); |
| 251 } |
| 252 |
| 253 void BleAdvertiser::OnUnregisterAdvertisementError( |
| 254 const std::string& associated_device_id, |
| 255 device::BluetoothAdvertisement::ErrorCode error_code) { |
| 256 PA_LOG(ERROR) << "Error unregistering advertisement. " |
| 257 << "Device ID: \"" |
| 258 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs( |
| 259 associated_device_id) |
| 260 << "\", Error code: " << error_code; |
| 261 |
| 262 // Even though there was an error unregistering the advertisement, remove it |
| 263 // from the set anyway so that it is possible to try registering the |
| 264 // advertisement again. Note that this situation is not expected to occur |
| 265 // since unregistering an active advertisement should always succeed. |
| 266 RemoveAdvertisingDeviceIdAndRetry(associated_device_id); |
| 267 } |
| 268 |
| 269 void BleAdvertiser::RemoveAdvertisingDeviceIdAndRetry( |
| 270 const std::string& device_id) { |
| 271 active_advertisement_device_ids_set_.erase(device_id); |
| 272 |
| 273 auto it = device_id_to_individual_advertisement_map_.find(device_id); |
| 274 if (it != device_id_to_individual_advertisement_map_.end()) |
| 275 it->second->OnPreviousAdvertisementUnregistered(); |
| 220 } | 276 } |
| 221 | 277 |
| 222 } // namespace tether | 278 } // namespace tether |
| 223 | 279 |
| 224 } // namespace chromeos | 280 } // namespace chromeos |
| OLD | NEW |