Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "cloud_print/gcp20/prototype/printer.h" | |
| 6 | |
| 7 #include <ifaddrs.h> | |
| 8 #include <netdb.h> | |
| 9 | |
| 10 #include "base/command_line.h" | |
| 11 #include "base/strings/string_number_conversions.h" | |
| 12 | |
| 13 namespace { | |
| 14 | |
| 15 const char* kServiceNamePrefix = "first_privet_device"; | |
| 16 const char* kServiceDomainName = "my.privet.device.local"; | |
| 17 | |
| 18 const uint16 kDefaultTTL = 60*60; | |
| 19 const uint16 kDefaultHttpPort = 10101; | |
| 20 | |
| 21 uint16 ReadHttpPortFromCommandLine() { | |
| 22 uint32 http_port_tmp = kDefaultHttpPort; | |
| 23 | |
| 24 std::string http_port_string_tmp = | |
| 25 CommandLine::ForCurrentProcess()->GetSwitchValueASCII("http-port"); | |
| 26 base::StringToUint(http_port_string_tmp, &http_port_tmp); | |
| 27 | |
| 28 if (http_port_tmp > kuint32max) { | |
| 29 LOG(ERROR) << "Port " << http_port_tmp << " is too large (maximum is " << | |
| 30 kDefaultHttpPort << "). Using default port."; | |
| 31 | |
| 32 http_port_tmp = kDefaultHttpPort; | |
| 33 } | |
| 34 | |
| 35 VLOG(1) << "HTTP port for responses: " << http_port_tmp; | |
| 36 return static_cast<uint16>(http_port_tmp); | |
| 37 } | |
| 38 | |
| 39 uint16 ReadTtlFromCommandLine() { | |
| 40 uint32 ttl = kDefaultTTL; | |
| 41 | |
| 42 base::StringToUint( | |
| 43 CommandLine::ForCurrentProcess()->GetSwitchValueASCII("ttl"), &ttl); | |
| 44 | |
| 45 VLOG(1) << "TTL for announcements: " << ttl; | |
| 46 return ttl; | |
| 47 } | |
| 48 | |
| 49 // Returns pointer to local IP address number. Examples for interface name | |
| 50 // are: "wlan0", "eth0", NULL (find first acceptable except "lo"). | |
| 51 net::IPAddressNumber GetLocalIp(const char* interface_name) { | |
| 52 net::IPAddressNumber result; // |result| is empty if no interface found. | |
| 53 | |
| 54 ifaddrs* first_interface = NULL; | |
| 55 if (getifaddrs(&first_interface) == -1) { | |
| 56 LOG(ERROR) << "getifaddrs() failed"; | |
| 57 return result; | |
| 58 } | |
| 59 | |
| 60 // Browse all interfaces. | |
| 61 char host[NI_MAXHOST] = {0}; | |
| 62 for (ifaddrs* interface = first_interface; | |
|
Vitaly Buka (NO REVIEWS)
2013/06/15 01:20:58
interface fits on the first line
maksymb
2013/06/15 01:56:58
Done.
| |
| 63 interface; interface = interface->ifa_next) { | |
| 64 if (!interface->ifa_addr) | |
| 65 continue; | |
| 66 | |
| 67 // Get additional info about current interface. | |
| 68 int rv = getnameinfo(interface->ifa_addr, | |
| 69 sizeof(*interface->ifa_addr), | |
| 70 host, | |
| 71 NI_MAXHOST, | |
| 72 NULL, | |
| 73 0, | |
| 74 NI_NUMERICHOST); | |
| 75 | |
| 76 if (interface->ifa_addr->sa_family == AF_INET) { | |
| 77 // Find interface we need. | |
| 78 if (interface_name ? (strcmp(interface->ifa_name, interface_name) == 0) | |
| 79 : (strcmp(interface->ifa_name, "lo") != 0)) { | |
| 80 if (rv != 0) { | |
| 81 LOG(ERROR) << "getnameinfo() failed: " << gai_strerror(rv); | |
| 82 break; | |
| 83 } | |
| 84 | |
| 85 net::ParseIPLiteralToNumber(host, &result); | |
| 86 } | |
| 87 } | |
| 88 } | |
| 89 | |
| 90 // Erase memory under list of interfaces. | |
| 91 freeifaddrs(first_interface); | |
| 92 return result; | |
| 93 } | |
| 94 | |
| 95 } // namespace | |
| 96 | |
| 97 Printer::Printer() : initialized_(false) { | |
| 98 } | |
| 99 | |
| 100 Printer::~Printer() { | |
| 101 Stop(); | |
| 102 } | |
| 103 | |
| 104 bool Printer::Start() { | |
| 105 if (initialized_) | |
| 106 return true; | |
| 107 | |
| 108 // TODO(maksymb): Add possibility to control interface via command line args. | |
| 109 net::IPAddressNumber ip = GetLocalIp(NULL); | |
| 110 if (ip.empty()) { | |
| 111 LOG(ERROR) << "No local IP found. Cannot start printer."; | |
| 112 return false; | |
| 113 } | |
| 114 VLOG(1) << "Local address: " << net::IPAddressToString(ip); | |
| 115 | |
| 116 // Starting DNS-SD server. | |
| 117 initialized_ = dns_server_.Start( | |
| 118 new PrivetDnsResponseBuilderFactory(kServiceNamePrefix, | |
| 119 kServiceDomainName, | |
| 120 ip, | |
| 121 ReadHttpPortFromCommandLine()), | |
| 122 ReadTtlFromCommandLine()); | |
| 123 return initialized_; | |
| 124 } | |
| 125 | |
| 126 void Printer::Stop() { | |
| 127 if (!initialized_) | |
| 128 return; | |
| 129 | |
| 130 dns_server_.Shutdown(); | |
| 131 } | |
| 132 | |
| OLD | NEW |