blob: 5b57febcf19bded48a974aff568fee91075d837c [file] [log] [blame] [edit]
// Copyright 2018 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "shill/geolocation_info.h"
#include <inttypes.h>
#include <base/check.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/stringprintf.h>
#include <chromeos/dbus/service_constants.h>
namespace {
// This key is special, because we will look for it and transform it into
// an up-to-date age property when D-Bus calls are made asking for geolocation
// objects. It should not be exported outside of shill.
constexpr char kLastSeenKey[] = "lastSeen";
base::TimeDelta LastSeenToAge(int64_t last_seen) {
return base::Time::Now() -
base::Time::FromDeltaSinceWindowsEpoch(base::Seconds(last_seen));
}
} // namespace
namespace shill {
void AddLastSeenTime(GeolocationInfo* info, const base::Time& time) {
DCHECK(info);
(*info)[kLastSeenKey] = base::StringPrintf(
"%" PRId64, time.ToDeltaSinceWindowsEpoch().InSeconds());
}
GeolocationInfo PrepareGeolocationInfoForExport(const GeolocationInfo& info) {
const auto& it = info.find(kLastSeenKey);
if (it == info.end())
return info;
int64_t last_seen;
if (!base::StringToInt64(it->second, &last_seen)) {
DLOG(ERROR) << "Invalid last seen time: " << it->second;
return GeolocationInfo();
}
// Calculate the age based on the current time. We have to reconstitute
// last_seen into base::Time so we can get a TimeDelta.
base::TimeDelta age = LastSeenToAge(last_seen);
GeolocationInfo new_info(info);
new_info.erase(kLastSeenKey);
new_info[kGeoAgeProperty] = base::StringPrintf("%" PRId64, age.InSeconds());
return new_info;
}
bool IsGeolocationInfoOlderThan(const GeolocationInfo& geoinfo,
base::TimeDelta expiration) {
int64_t last_seen;
auto it = geoinfo.find(kLastSeenKey);
if (it == geoinfo.end() || !base::StringToInt64(it->second, &last_seen)) {
return true;
}
return LastSeenToAge(last_seen) > expiration;
}
void GeolocationInfoAgeRange(const std::vector<GeolocationInfo>& geoinfos,
base::Time* oldest_timestamp,
base::Time* newest_timestamp) {
for (const auto& geoinfo : geoinfos) {
int64_t last_seen;
auto it = geoinfo.find(kLastSeenKey);
if (it == geoinfo.end() || !base::StringToInt64(it->second, &last_seen)) {
continue;
}
base::Time last_timestamp =
base::Time::FromDeltaSinceWindowsEpoch(base::Seconds(last_seen));
*oldest_timestamp =
*oldest_timestamp < last_timestamp ? *oldest_timestamp : last_timestamp;
*newest_timestamp =
*newest_timestamp > last_timestamp ? *newest_timestamp : last_timestamp;
}
}
std::string GeolocationInfoToString(const GeolocationInfo& geoinfo) {
std::string geoinfo_str = "WiFi endpoint OUI:";
auto it = geoinfo.find(kGeoMacAddressProperty);
if (it != geoinfo.end()) {
geoinfo_str += std::string(" ") + it->second.substr(0, 8);
}
for (auto key : {kGeoChannelProperty, kGeoAgeProperty, kLastSeenKey,
kGeoSignalStrengthProperty}) {
it = geoinfo.find(key);
if (it != geoinfo.end()) {
geoinfo_str += std::string(" ") + key + ": " + it->second;
}
}
return geoinfo_str;
}
} // namespace shill