summaryrefslogtreecommitdiffstats
path: root/cloud_print/gcp20/prototype/printer.cc
blob: 4d39fe83633baa3d63db21cd6ab8fff3b5811f85 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright 2013 The Chromium 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 "cloud_print/gcp20/prototype/printer.h"

#include <string>
#include <vector>

#include "base/command_line.h"
#include "base/strings/string_number_conversions.h"
#include "cloud_print/gcp20/prototype/service_parameters.h"
#include "net/base/net_util.h"

namespace {

const char* kServiceType = "_privet._tcp.local";
const char* kServiceNamePrefix = "first_gcp20_device";
const char* kServiceDomainName = "my-privet-device.local";

const uint16 kDefaultTTL = 60*60;
const uint16 kDefaultHttpPort = 10101;

uint16 ReadHttpPortFromCommandLine() {
  uint32 http_port_tmp = kDefaultHttpPort;

  std::string http_port_string_tmp =
      CommandLine::ForCurrentProcess()->GetSwitchValueASCII("http-port");
  base::StringToUint(http_port_string_tmp, &http_port_tmp);

  if (http_port_tmp > kuint16max) {
    LOG(ERROR) << "Port " << http_port_tmp << " is too large (maximum is " <<
        kDefaultHttpPort << "). Using default port.";

    http_port_tmp = kDefaultHttpPort;
  }

  VLOG(1) << "HTTP port for responses: " << http_port_tmp;
  return static_cast<uint16>(http_port_tmp);
}

uint16 ReadTtlFromCommandLine() {
  uint32 ttl = kDefaultTTL;

  base::StringToUint(
      CommandLine::ForCurrentProcess()->GetSwitchValueASCII("ttl"), &ttl);

  VLOG(1) << "TTL for announcements: " << ttl;
  return ttl;
}

// Returns local IP address number of first interface found (except loopback).
// Return value is empty if no interface found. Possible interfaces names are
// "eth0", "wlan0" etc. If interface name is empty, function will return IP
// address of first interface found.
net::IPAddressNumber GetLocalIp(const std::string& interface_name,
                                bool return_ipv6_number) {
  net::NetworkInterfaceList interfaces;
  bool success = net::GetNetworkList(&interfaces);
  DCHECK(success);

  size_t expected_address_size = return_ipv6_number ? net::kIPv6AddressSize
                                                    : net::kIPv4AddressSize;

  for (net::NetworkInterfaceList::iterator iter = interfaces.begin();
       iter != interfaces.end(); ++iter) {
    if (iter->address.size() == expected_address_size &&
        (interface_name.empty() || interface_name == iter->name)) {
      LOG(INFO) << net::IPAddressToString(iter->address);
      return iter->address;
    }
  }

  return net::IPAddressNumber();
}

}  // namespace

Printer::Printer() : initialized_(false) {
}

Printer::~Printer() {
  Stop();
}

bool Printer::Start() {
  if (initialized_)
    return true;

  // TODO(maksymb): Add switch for command line to control interface name.
  net::IPAddressNumber ip = GetLocalIp("", false);
  if (ip.empty()) {
    LOG(ERROR) << "No local IP found. Cannot start printer.";
    return false;
  }
  VLOG(1) << "Local address: " << net::IPAddressToString(ip);

  // Starting DNS-SD server.
  initialized_ = dns_server_.Start(
      ServiceParameters(kServiceType,
                        kServiceNamePrefix,
                        kServiceDomainName,
                        ip,
                        ReadHttpPortFromCommandLine()),
      ReadTtlFromCommandLine(),
      CreateTxt());

  return initialized_;
}

void Printer::Stop() {
  if (!initialized_)
    return;

  dns_server_.Shutdown();
}

std::vector<std::string> Printer::CreateTxt() const {
  std::vector<std::string> txt;

  txt.push_back("txtvers=1");
  txt.push_back("ty=Google Cloud Ready Printer GCP2.0 Prototype");
  txt.push_back("note=Virtual printer");
  txt.push_back("url=https://www.google.com/cloudprint");
  txt.push_back("type=printer");
  txt.push_back("id=");
  txt.push_back("cs=offline");

  return txt;
}