printer.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
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 "cloud_print/gcp20/prototype/printer.h" 6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <string> 8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <vector> 9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/command_line.h" 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/strings/string_number_conversions.h" 12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "cloud_print/gcp20/prototype/service_parameters.h" 13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/base/net_util.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace { 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst char* kServiceType = "_privet._tcp.local"; 18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst char* kServiceNamePrefix = "first_gcp20_device"; 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst char* kServiceDomainName = "my-privet-device.local"; 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst uint16 kDefaultTTL = 60*60; 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst uint16 kDefaultHttpPort = 10101; 23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochuint16 ReadHttpPortFromCommandLine() { 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uint32 http_port_tmp = kDefaultHttpPort; 26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string http_port_string_tmp = 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CommandLine::ForCurrentProcess()->GetSwitchValueASCII("http-port"); 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::StringToUint(http_port_string_tmp, &http_port_tmp); 30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (http_port_tmp > kuint16max) { 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOG(ERROR) << "Port " << http_port_tmp << " is too large (maximum is " << 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kDefaultHttpPort << "). Using default port."; 34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch http_port_tmp = kDefaultHttpPort; 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch VLOG(1) << "HTTP port for responses: " << http_port_tmp; 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return static_cast<uint16>(http_port_tmp); 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochuint16 ReadTtlFromCommandLine() { 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uint32 ttl = kDefaultTTL; 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::StringToUint( 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CommandLine::ForCurrentProcess()->GetSwitchValueASCII("ttl"), &ttl); 47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch VLOG(1) << "TTL for announcements: " << ttl; 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return ttl; 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Returns local IP address number of first interface found (except loopback). 53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Return value is empty if no interface found. Possible interfaces names are 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// "eth0", "wlan0" etc. If interface name is empty, function will return IP 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// address of first interface found. 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnet::IPAddressNumber GetLocalIp(const std::string& interface_name, 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool return_ipv6_number) { 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net::NetworkInterfaceList interfaces; 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool success = net::GetNetworkList(&interfaces); 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(success); 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size_t expected_address_size = return_ipv6_number ? net::kIPv6AddressSize 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : net::kIPv4AddressSize; 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (net::NetworkInterfaceList::iterator iter = interfaces.begin(); 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch iter != interfaces.end(); ++iter) { 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (iter->address.size() == expected_address_size && 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (interface_name.empty() || interface_name == iter->name)) { 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOG(INFO) << net::IPAddressToString(iter->address); 70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return iter->address; 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return net::IPAddressNumber(); 75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochPrinter::Printer() : initialized_(false) { 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochPrinter::~Printer() { 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Stop(); 84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool Printer::Start() { 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (initialized_) 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return true; 89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(maksymb): Add switch for command line to control interface name. 91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net::IPAddressNumber ip = GetLocalIp("", false); 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (ip.empty()) { 93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOG(ERROR) << "No local IP found. Cannot start printer."; 94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch VLOG(1) << "Local address: " << net::IPAddressToString(ip); 97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Starting DNS-SD server. 99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch initialized_ = dns_server_.Start( 100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ServiceParameters(kServiceType, 101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kServiceNamePrefix, 102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kServiceDomainName, 103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ip, 104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ReadHttpPortFromCommandLine()), 105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ReadTtlFromCommandLine(), 106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateTxt()); 107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return initialized_; 109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid Printer::Stop() { 112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!initialized_) 113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch dns_server_.Shutdown(); 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstd::vector<std::string> Printer::CreateTxt() const { 119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<std::string> txt; 120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch txt.push_back("txtvers=1"); 122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch txt.push_back("ty=Google Cloud Ready Printer GCP2.0 Prototype"); 123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch txt.push_back("note=Virtual printer"); 124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch txt.push_back("url=https://www.google.com/cloudprint"); 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch txt.push_back("type=printer"); 126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch txt.push_back("id="); 127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch txt.push_back("cs=offline"); 128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return txt; 130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 132