1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file. 4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <vector> 6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/at_exit.h" 8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/bind.h" 9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/memory/scoped_ptr.h" 109ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/tools/service_discovery_sniffer/service_discovery_sniffer.h" 127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/utility/local_discovery/service_discovery_client_impl.h" 13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/dns/mdns_client.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace local_discovery { 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochServicePrinter::ServicePrinter(ServiceDiscoveryClient* client, 18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& service_name) 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : changed_(false) { 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch service_resolver_ = 21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch client->CreateServiceResolver( 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch service_name, 23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(&ServicePrinter::OnServiceResolved, 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Unretained(this))); 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochServicePrinter::~ServicePrinter() { 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ServicePrinter::Added() { 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch changed_ = false; 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch service_resolver_->StartResolving(); 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ServicePrinter::Changed() { 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch changed_ = true; 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch service_resolver_->StartResolving(); 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ServicePrinter::Removed() { 417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch printf("Service Removed: %s\n", service_resolver_->GetName().c_str()); 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ServicePrinter::OnServiceResolved(ServiceResolver::RequestStatus status, 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const ServiceDescription& service) { 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (changed_) { 47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch printf("Service Updated: %s\n", service.instance_name().c_str()); 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else { 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch printf("Service Added: %s\n", service.instance_name().c_str()); 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch printf("\tAddress: %s:%d\n", service.address.host().c_str(), 53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch service.address.port()); 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch printf("\tMetadata: \n"); 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (std::vector<std::string>::const_iterator i = service.metadata.begin(); 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch i != service.metadata.end(); i++) { 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch printf("\t\t%s\n", i->c_str()); 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (service.ip_address != net::IPAddressNumber()) { 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch printf("\tIP Address: %s\n", net::IPAddressToString( 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch service.ip_address).c_str()); 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochServiceTypePrinter::ServiceTypePrinter(ServiceDiscoveryClient* client, 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& service_type) 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : client_(client) { 697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch watcher_ = client_->CreateServiceWatcher( 707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch service_type, base::Bind(&ServiceTypePrinter::OnServiceUpdated, 717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Unretained(this))); 72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ServiceTypePrinter::Start() { 757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch watcher_->Start(); 76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch watcher_->DiscoverNewServices(false); 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochServiceTypePrinter::~ServiceTypePrinter() { 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ServiceTypePrinter::OnServiceUpdated(ServiceWatcher::UpdateType update, 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& service_name) { 84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (update == ServiceWatcher::UPDATE_ADDED) { 85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch services_[service_name].reset(new ServicePrinter(client_, service_name)); 86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch services_[service_name]->Added(); 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else if (update == ServiceWatcher::UPDATE_CHANGED) { 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch services_[service_name]->Changed(); 89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else if (update == ServiceWatcher::UPDATE_REMOVED) { 90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch services_[service_name]->Removed(); 91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch services_.erase(service_name); 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace local_discovery 96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint main(int argc, char** argv) { 98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::AtExitManager at_exit_manager; 99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::MessageLoopForIO message_loop; 100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (argc != 2) { 102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch printf("Please provide exactly 1 argument.\n"); 103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 1; 104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<net::MDnsClient> mdns_client = net::MDnsClient::CreateDefault(); 107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch mdns_client->StartListening(); 108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<local_discovery::ServiceDiscoveryClient> service_discovery_client; 109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch service_discovery_client.reset( 110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new local_discovery::ServiceDiscoveryClientImpl(mdns_client.get())); 111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { 112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // To guarantee/make explicit the ordering constraint. 113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch local_discovery::ServiceTypePrinter print_changes( 114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch service_discovery_client.get(), 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string(argv[1]) + "._tcp.local"); 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch print_changes.Start(); 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch message_loop.Run(); 119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 121