blob: 1669cd7d36d72bfcaa324dd8803b4cf6c5c7c1d3 [file] [log] [blame]
// Copyright 2014 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "peerd/peer_manager_impl.h"
#include <string>
#include <dbus/object_path.h>
#include "peerd/dbus_constants.h"
using chromeos::dbus_utils::AsyncEventSequencer;
using chromeos::dbus_utils::ExportedObjectManager;
using peerd::technologies::Technology;
using std::string;
using std::to_string;
using std::unique_ptr;
namespace peerd {
PeerManagerImpl::PeerManagerImpl(const scoped_refptr<dbus::Bus> bus,
ExportedObjectManager* object_manager)
: bus_(bus),
object_manager_(object_manager) {
}
void PeerManagerImpl::OnPeerDiscovered(const string& peer_id,
const base::Time& last_seen,
Technology technology) {
VLOG(1) << "Discovered peer=" << peer_id;
auto it = peers_.find(peer_id);
if (it != peers_.end()) {
it->second->UpdateFromAdvertisement(last_seen, technology);
return;
}
dbus::ObjectPath path{
string(dbus_constants::kPeerPrefix) + to_string(++peers_discovered_)};
unique_ptr<DiscoveredPeer> peer{new DiscoveredPeer{
bus_, object_manager_, path, technology}};
scoped_refptr<AsyncEventSequencer> sequencer(new AsyncEventSequencer());
const bool registered = peer->RegisterAsync(
nullptr, peer_id, last_seen,
sequencer->GetHandler("Failed to expose DiscoveredPeer.", true));
sequencer->OnAllTasksCompletedCall({});
if (registered) {
peers_[peer_id].swap(peer);
} else {
LOG(INFO) << "Discovered corrupted peer advertisement; discarding it.";
}
}
void PeerManagerImpl::OnServiceDiscovered(const string& peer_id,
const string& service_id,
const Service::ServiceInfo& info,
const Service::IpAddresses& addresses,
const base::Time& last_seen,
Technology technology) {
auto it = peers_.find(peer_id);
if (it == peers_.end()) {
// A service was found that corresponds to no particular peer.
// We could just silently add a peer entry here, or we can discard the
// service. Lets discard the service until it is known that we need to
// support this case.
LOG(WARNING) << "Found service=" << service_id << " but had no peer="
<< peer_id;
return;
}
VLOG(1) << "Updating service=" << service_id
<< " from technology=" << technology;
it->second->UpdateService(service_id, addresses, info,
last_seen, technology);
}
void PeerManagerImpl::OnPeerRemoved(const string& peer_id,
Technology technology) {
auto it = peers_.find(peer_id);
if (it == peers_.end()) {
LOG(WARNING) << "Tried to remove technology=" << technology
<< " from peer=" << peer_id
<< " that was never discovered.";
return;
}
it->second->RemoveTechnology(technology);
if (it->second->GetTechnologyCount() == 0) {
peers_.erase(it);
}
}
void PeerManagerImpl::OnServiceRemoved(const string& peer_id,
const string& service_id,
Technology technology) {
auto it = peers_.find(peer_id);
if (it == peers_.end()) {
LOG(WARNING) << "Tried to remove service from peer that was "
<< "never discovered: " << peer_id;
return;
}
it->second->RemoveTechnologyFromService(service_id, technology);
}
void PeerManagerImpl::OnTechnologyShutdown(Technology technology) {
auto it = peers_.begin();
while (it != peers_.end()) {
it->second->RemoveTechnology(technology);
if (it->second->GetTechnologyCount() == 0) {
it = peers_.erase(it);
} else {
++it;
}
}
}
} // namespace peerd