blob: f22a93ffd6a87b0aec757637e7bb7aef4ca2d8a9 [file] [log] [blame]
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "connections/implementation/mediums/ble_v2.h"
#include <string>
#include <string_view>
#include "absl/strings/str_cat.h"
#include "connections/implementation/mediums/ble_v2/ble_advertisement.h"
#include "connections/implementation/mediums/ble_v2/ble_advertisement_header.h"
#include "connections/implementation/mediums/ble_v2/bloom_filter.h"
#include "connections/implementation/mediums/utils.h"
#include "internal/platform/prng.h"
namespace location {
namespace nearby {
namespace connections {
namespace {
constexpr int kDummyServiceIdLength = 128;
ByteArray GenerateAdvertisementHash(const ByteArray& advertisement_bytes) {
return Utils::Sha256Hash(
advertisement_bytes,
mediums::BleAdvertisementHeader::kAdvertisementHashLength);
}
} // namespace
BleV2::BleV2(BluetoothRadio& radio)
: radio_(radio), adapter_(radio_.GetBluetoothAdapter()) {}
ByteArray BleV2::CreateAdvertisementHeader() {
// Create a randomized dummy service id to anonymize the header with.
ByteArray dummy_service_id_bytes =
Utils::GenerateRandomBytes(kDummyServiceIdLength);
std::string dummy_service_id{dummy_service_id_bytes};
mediums::BloomFilter<
mediums::BleAdvertisementHeader::kServiceIdBloomFilterLength>
bloom_filter;
bloom_filter.Add(dummy_service_id);
ByteArray advertisement_hash =
GenerateAdvertisementHash(dummy_service_id_bytes);
for (const auto& item : gatt_advertisements_) {
const std::string& service_id = item.second.first;
const ByteArray& gatt_advertisement = item.second.second;
bloom_filter.Add(service_id);
// Compute the next hash according to the algorithm in
// https://source.corp.google.com/piper///depot/google3/java/com/google/android/gmscore/integ/modules/nearby/src/com/google/android/gms/nearby/mediums/bluetooth/BluetoothLowEnergy.java;rcl=428397891;l=1043
ByteArray previous_advertisement_hash = advertisement_hash;
std::string advertisement_bodies =
absl::StrCat(previous_advertisement_hash.AsStringView(),
gatt_advertisement.AsStringView());
advertisement_hash =
GenerateAdvertisementHash(ByteArray(std::move(advertisement_bodies)));
}
return ByteArray(mediums::BleAdvertisementHeader(
mediums::BleAdvertisementHeader::Version::kV2,
/*extended_advertisement=*/false,
/*num_slots=*/gatt_advertisements_.size(), ByteArray(bloom_filter),
advertisement_hash, /*psm=*/0));
}
} // namespace connections
} // namespace nearby
} // namespace location