blob: a1e0f5ae58fc45d7572609f76e9d4b901df15057 [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 "third_party/nearby/cpp/core/internal/mediums/ble_v2.h"
#include <string>
#include "absl/strings/str_cat.h"
#include "third_party/nearby/cpp/core/internal/mediums/ble_v2/ble_advertisement.h"
#include "third_party/nearby/cpp/core/internal/mediums/ble_v2/ble_advertisement_header.h"
#include "third_party/nearby/cpp/core/internal/mediums/ble_v2/bloom_filter.h"
#include "third_party/nearby/cpp/core/internal/mediums/utils.h"
#include "third_party/nearby/cpp/platform/base/prng.h"
namespace location {
namespace nearby {
namespace connections {
ByteArray BleV2::GenerateAdvertisementHash(
const ByteArray& advertisement_bytes) {
return Utils::Sha256Hash(
advertisement_bytes,
mediums::BleAdvertisementHeader::kAdvertisementHashLength);
}
ByteArray BleV2::GenerateHash(const std::string& source, size_t size) {
return Utils::Sha256Hash(source, size);
}
ByteArray BleV2::GenerateDeviceToken() {
return Utils::Sha256Hash(std::to_string(Prng().NextUint32()),
mediums::BleAdvertisement::kDeviceTokenLength);
}
BleV2::BleV2(BluetoothRadio& radio) : radio_(radio) {}
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};
// Create a bloom filter with the dummy service id.
mediums::BloomFilter<
mediums::BleAdvertisementHeader::kServiceIdBloomFilterLength>
bloom_filter;
bloom_filter.Add(dummy_service_id);
// Add the service id for each GATT advertisement into the bloom filter, while
// also creating a hash of dummyServiceIdBytes + all GATT advertisements.
ByteArray advertisement_hash =
GenerateAdvertisementHash(dummy_service_id_bytes);
int num_slots = 0;
for (const auto& item : gatt_advertisement_info.gatt_advertisements) {
std::string service_id = item.second.first;
ByteArray gatt_advertisment = item.second.second;
bloom_filter.Add(service_id);
// Compute the next hash by taking the hash of [previous hash] + [next
// advertisement data].
ByteArray previous_advertisement_hash = advertisement_hash;
std::string advertisement_bodies =
absl::StrCat(std::string(previous_advertisement_hash),
std::string(gatt_advertisment));
advertisement_hash =
GenerateAdvertisementHash(ByteArray{std::move(advertisement_bodies)});
num_slots++;
}
return ByteArray(mediums::BleAdvertisementHeader(
mediums::BleAdvertisementHeader::Version::kV2,
/*extended_advertisement=*/false, num_slots, ByteArray(bloom_filter),
advertisement_hash, /*psm=*/0));
}
} // namespace connections
} // namespace nearby
} // namespace location