privet_device_lister_impl.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
17dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 27dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 37dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// found in the LICENSE file. 47dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 57dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/local_discovery/privet_device_lister_impl.h" 67dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include <string> 87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include <utility> 97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include <vector> 107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/bind.h" 127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/strings/string_util.h" 137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/strings/stringprintf.h" 147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/local_discovery/privet_constants.h" 157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace local_discovery { 177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 187dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochPrivetDeviceListerImpl::PrivetDeviceListerImpl( 197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ServiceDiscoveryClient* service_discovery_client, 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch PrivetDeviceLister::Delegate* delegate) 217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch : delegate_(delegate), 227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch service_discovery_client_(service_discovery_client), 237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch service_type_(kPrivetDefaultDeviceType) { 247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 267dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochPrivetDeviceListerImpl::PrivetDeviceListerImpl( 277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ServiceDiscoveryClient* service_discovery_client, 287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch PrivetDeviceLister::Delegate* delegate, 297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string subtype) : delegate_(delegate), 307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch service_discovery_client_(service_discovery_client), 317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch service_type_( 327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::StringPrintf(kPrivetSubtypeTemplate, 337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch subtype.c_str())) { 347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 367dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochPrivetDeviceListerImpl::~PrivetDeviceListerImpl() { 377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid PrivetDeviceListerImpl::Start() { 407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch service_watcher_ = 417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch service_discovery_client_->CreateServiceWatcher( 427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch service_type_, 437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(&PrivetDeviceListerImpl::OnServiceUpdated, 447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Unretained(this))); 457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch service_watcher_->Start(); 467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid PrivetDeviceListerImpl::DiscoverNewDevices(bool force_update) { 497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch service_watcher_->DiscoverNewServices(force_update); 507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid PrivetDeviceListerImpl::OnServiceUpdated( 537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ServiceWatcher::UpdateType update, 547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& service_name) { 557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (update != ServiceWatcher::UPDATE_REMOVED) { 567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bool added = (update == ServiceWatcher::UPDATE_ADDED); 577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::pair<ServiceResolverMap::iterator, bool> insert_result = 587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch resolvers_.insert(make_pair(service_name, 597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch linked_ptr<ServiceResolver>(NULL))); 607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // If there is already a resolver working on this service, don't add one. 627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (insert_result.second) { 637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<ServiceResolver> resolver = 647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch service_discovery_client_->CreateServiceResolver( 657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch service_name, base::Bind( 667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch &PrivetDeviceListerImpl::OnResolveComplete, 677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Unretained(this), 687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch added)); 697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch insert_result.first->second.reset(resolver.release()); 717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch insert_result.first->second->StartResolving(); 727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else { 747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch delegate_->DeviceRemoved(service_name); 757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid PrivetDeviceListerImpl::OnResolveComplete( 797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bool added, 807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ServiceResolver::RequestStatus status, 817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const ServiceDescription& service_description) { 827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (status != ServiceResolver::STATUS_SUCCESS) { 837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch resolvers_.erase(service_description.service_name); 847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // TODO(noamsml): Add retry logic. 867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DeviceDescription device_description; 907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FillDeviceDescription(service_description, &device_description); 917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string service_name = service_description.service_name; 937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch resolvers_.erase(service_name); 947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch delegate_->DeviceChanged(added, service_name, device_description); 957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid PrivetDeviceListerImpl::FillDeviceDescription( 987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const ServiceDescription& service_description, 997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DeviceDescription* device_description) { 1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch device_description->address = service_description.address; 1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch device_description->ip_address = service_description.ip_address; 1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch device_description->last_seen = service_description.last_seen; 1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (std::vector<std::string>::const_iterator i = 1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch service_description.metadata.begin(); 1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch i < service_description.metadata.end(); 1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch i++) { 1087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch size_t equals_pos = i->find_first_of('='); 1097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (equals_pos == std::string::npos) 1107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch continue; // We do not parse non key-value TXT records 1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string key = i->substr(0, equals_pos); 1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string value = i->substr(equals_pos + 1); 1147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (LowerCaseEqualsASCII(key, kPrivetTxtKeyName)) { 1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch device_description->name = value; 1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else if (LowerCaseEqualsASCII(key, kPrivetTxtKeyDescription)) { 1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch device_description->description = value; 1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else if (LowerCaseEqualsASCII(key, kPrivetTxtKeyURL)) { 1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch device_description->url = value; 1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else if (LowerCaseEqualsASCII(key, kPrivetTxtKeyType)) { 1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch device_description->type = value; 1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else if (LowerCaseEqualsASCII(key, kPrivetTxtKeyID)) { 1247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch device_description->id = value; 1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else if (LowerCaseEqualsASCII(key, kPrivetTxtKeyConnectionState)) { 1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch device_description->connection_state = ConnectionStateFromString(value); 1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochDeviceDescription::ConnectionState 1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochPrivetDeviceListerImpl::ConnectionStateFromString(const std::string& str) { 1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (LowerCaseEqualsASCII(str, kPrivetConnectionStatusOnline)) { 1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return DeviceDescription::ONLINE; 1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else if (LowerCaseEqualsASCII(str, kPrivetConnectionStatusOffline)) { 1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return DeviceDescription::OFFLINE; 1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else if (LowerCaseEqualsASCII(str, kPrivetConnectionStatusConnecting)) { 1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return DeviceDescription::CONNECTING; 1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else if (LowerCaseEqualsASCII(str, kPrivetConnectionStatusNotConfigured)) { 1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return DeviceDescription::NOT_CONFIGURED; 1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return DeviceDescription::UNKNOWN; 1447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} // namespace local_discovery 147