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