summaryrefslogtreecommitdiffstats
path: root/cloud_print/gcp20/prototype/printer.cc
diff options
context:
space:
mode:
authormaksymb@chromium.org <maksymb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-23 15:39:15 +0000
committermaksymb@chromium.org <maksymb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-23 15:39:15 +0000
commita20b019ab8ee1eeba45257d9c8774e88b1a665e4 (patch)
tree8b62906129a1a89134c3a9447026fcdf885da71b /cloud_print/gcp20/prototype/printer.cc
parent73f6d0a7200a072972d4c8dd774f6f5cd341ff47 (diff)
downloadchromium_src-a20b019ab8ee1eeba45257d9c8774e88b1a665e4.zip
chromium_src-a20b019ab8ee1eeba45257d9c8774e88b1a665e4.tar.gz
chromium_src-a20b019ab8ee1eeba45257d9c8774e88b1a665e4.tar.bz2
XPrivetToken, saving to file, little extend for /privet/info.
Review URL: https://chromiumcodereview.appspot.com/18703004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@213129 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cloud_print/gcp20/prototype/printer.cc')
-rw-r--r--cloud_print/gcp20/prototype/printer.cc228
1 files changed, 151 insertions, 77 deletions
diff --git a/cloud_print/gcp20/prototype/printer.cc b/cloud_print/gcp20/prototype/printer.cc
index dcbef5a..aa6bcd5 100644
--- a/cloud_print/gcp20/prototype/printer.cc
+++ b/cloud_print/gcp20/prototype/printer.cc
@@ -10,11 +10,17 @@
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/guid.h"
+#include "base/json/json_reader.h"
+#include "base/json/json_writer.h"
#include "base/strings/string_number_conversions.h"
+#include "cloud_print/gcp20/prototype/command_line_reader.h"
#include "cloud_print/gcp20/prototype/service_parameters.h"
#include "net/base/net_util.h"
#include "net/base/url_util.h"
+const base::FilePath::CharType kPrinterStatePath[] =
+ FILE_PATH_LITERAL("printer_state.json");
+
namespace {
const char* kServiceType = "_privet._tcp.local";
@@ -22,9 +28,7 @@ const char* kServiceNamePrefix = "first_gcp20_device";
const char* kServiceDomainName = "my-privet-device.local";
const char* kPrinterName = "Google GCP2.0 Prototype";
-
-const uint16 kDefaultTTL = 60*60;
-const uint16 kDefaultHttpPort = 10101;
+const char* kPrinterDescription = "Printer emulator";
const char* kCdd =
"{\n"
@@ -55,38 +59,6 @@ const char* kCdd =
" }\n"
"}\n";
-std::string GenerateProxyId() {
- return "{" + base::GenerateGUID() + "}";
-}
-
-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
@@ -139,27 +111,24 @@ bool Printer::Start() {
}
VLOG(1) << "Local address: " << net::IPAddressToString(ip);
- uint16 port = ReadHttpPortFromCommandLine();
+ uint16 port = command_line_reader::ReadHttpPort();
- // TODO(maksymb): Add loading state from drive.
- reg_info_ = RegistrationInfo();
+ // Starting HTTP server.
+ if (!http_server_.Start(port))
+ return false;
+
+ if (!LoadFromFile(base::FilePath(kPrinterStatePath)))
+ reg_info_ = RegistrationInfo();
// Starting DNS-SD server.
- bool success = dns_server_.Start(
+ if (!dns_server_.Start(
ServiceParameters(kServiceType, kServiceNamePrefix, kServiceDomainName,
ip, port),
- ReadTtlFromCommandLine(),
- CreateTxt());
-
- if (!success)
+ command_line_reader::ReadTtl(),
+ CreateTxt())) {
+ http_server_.Shutdown();
return false;
-
- // Starting HTTP server.
- success = http_server_.Start(port);
- if (!success)
- return false;
- // TODO(maksymb): Check what happened if DNS server will start but HTTP
- // server won't.
+ }
// Creating Cloud Requester.
requester_.reset(
@@ -167,6 +136,9 @@ bool Printer::Start() {
base::MessageLoop::current()->message_loop_proxy(),
this));
+ xtoken_ = XPrivetToken();
+ starttime_ = base::Time::Now();
+
return true;
}
@@ -182,8 +154,8 @@ void Printer::Stop() {
PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationStart(
const std::string& user) {
- PrivetHttpServer::RegistrationErrorStatus status;
- if (!CheckRegistrationState(user, false, &status))
+ PrivetHttpServer::RegistrationErrorStatus status = CheckCommonRegErrors(user);
+ if (status != PrivetHttpServer::REG_ERROR_OK)
return status;
if (reg_info_.state != RegistrationInfo::DEV_REG_UNREGISTERED)
@@ -198,12 +170,16 @@ PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationStart(
return PrivetHttpServer::REG_ERROR_OK;
}
+bool Printer::CheckXPrivetTokenHeader(const std::string& token) const {
+ return xtoken_.CheckValidXToken(token);
+}
+
PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationGetClaimToken(
const std::string& user,
std::string* token,
std::string* claim_url) {
- PrivetHttpServer::RegistrationErrorStatus status;
- if (!CheckRegistrationState(user, false, &status))
+ PrivetHttpServer::RegistrationErrorStatus status = CheckCommonRegErrors(user);
+ if (status != PrivetHttpServer::REG_ERROR_OK)
return status;
// TODO(maksymb): Add user confirmation.
@@ -224,13 +200,14 @@ PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationGetClaimToken(
PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationComplete(
const std::string& user,
std::string* device_id) {
- PrivetHttpServer::RegistrationErrorStatus status;
- if (!CheckRegistrationState(user, false, &status))
+ PrivetHttpServer::RegistrationErrorStatus status = CheckCommonRegErrors(user);
+ if (status != PrivetHttpServer::REG_ERROR_OK)
return status;
if (reg_info_.state !=
- RegistrationInfo::DEV_REG_REGISTRATION_CLAIM_TOKEN_READY)
+ RegistrationInfo::DEV_REG_REGISTRATION_CLAIM_TOKEN_READY) {
return PrivetHttpServer::REG_ERROR_INVALID_ACTION;
+ }
reg_info_.state = RegistrationInfo::DEV_REG_REGISTRATION_COMPLETING;
requester_->CompleteRegistration();
@@ -242,9 +219,11 @@ PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationComplete(
PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationCancel(
const std::string& user) {
- PrivetHttpServer::RegistrationErrorStatus status;
- if (!CheckRegistrationState(user, true, &status))
+ PrivetHttpServer::RegistrationErrorStatus status = CheckCommonRegErrors(user);
+ if (status != PrivetHttpServer::REG_ERROR_OK &&
+ status != PrivetHttpServer::REG_ERROR_SERVER_ERROR) {
return status;
+ }
if (reg_info_.state == RegistrationInfo::DEV_REG_UNREGISTERED)
return PrivetHttpServer::REG_ERROR_INVALID_ACTION;
@@ -261,11 +240,28 @@ void Printer::GetRegistrationServerError(std::string* description) {
}
void Printer::CreateInfo(PrivetHttpServer::DeviceInfo* info) {
+ // TODO(maksymb): Replace "text" with constants.
+
*info = PrivetHttpServer::DeviceInfo();
info->version = "1.0";
+ info->name = kPrinterName;
+ info->description = kPrinterDescription;
+ info->url = kCloudPrintUrl;
+ info->id = reg_info_.device_id;
+ info->device_state = "idle";
+ info->connection_state = "offline";
info->manufacturer = "Google";
+ info->model = "Prototype";
+ info->serial_number = "2.3.5.7.13.17.19.31.61.89.107.127.521.607.1279.2203";
+ info->firmware = "3.7.31.127.8191.131071.524287.2147483647";
+ info->uptime = static_cast<int>((base::Time::Now() - starttime_).InSeconds());
+
+ info->x_privet_token = xtoken_.GenerateXToken();
+
if (reg_info_.state == RegistrationInfo::DEV_REG_UNREGISTERED)
info->api.push_back("/privet/register");
+
+ info->type.push_back("printer");
}
void Printer::OnRegistrationStartResponseParsed(
@@ -281,6 +277,7 @@ void Printer::OnRegistrationStartResponseParsed(
void Printer::OnGetAuthCodeResponseParsed(const std::string& refresh_token) {
reg_info_.state = RegistrationInfo::DEV_REG_REGISTERED;
reg_info_.refresh_token = refresh_token;
+ SaveToFile(base::FilePath(kPrinterStatePath));
}
void Printer::OnRegistrationError(const std::string& description) {
@@ -291,36 +288,32 @@ void Printer::OnRegistrationError(const std::string& description) {
reg_info_.error_description = description;
}
-bool Printer::CheckRegistrationState(
- const std::string& user,
- bool ignore_error,
- PrivetHttpServer::RegistrationErrorStatus* status) const {
- if (reg_info_.state == RegistrationInfo::DEV_REG_REGISTERED) {
- *status = PrivetHttpServer::REG_ERROR_REGISTERED;
- return false;
- }
+PrivetHttpServer::RegistrationErrorStatus Printer::CheckCommonRegErrors(
+ const std::string& user) const {
+ if (reg_info_.state == RegistrationInfo::DEV_REG_REGISTERED)
+ return PrivetHttpServer::REG_ERROR_REGISTERED;
if (reg_info_.state != RegistrationInfo::DEV_REG_UNREGISTERED &&
user != reg_info_.user) {
- *status = PrivetHttpServer::REG_ERROR_DEVICE_BUSY;
- return false;
+ return PrivetHttpServer::REG_ERROR_DEVICE_BUSY;
}
- if (!ignore_error &&
- reg_info_.state == RegistrationInfo::DEV_REG_REGISTRATION_ERROR) {
- *status = PrivetHttpServer::REG_ERROR_SERVER_ERROR;
- return false;
- }
+ if (reg_info_.state == RegistrationInfo::DEV_REG_REGISTRATION_ERROR)
+ return PrivetHttpServer::REG_ERROR_SERVER_ERROR;
- return true;
+ return PrivetHttpServer::REG_ERROR_OK;
+}
+
+std::string Printer::GenerateProxyId() const {
+ return "{" + base::GenerateGUID() +"}";
}
std::vector<std::string> Printer::CreateTxt() const {
std::vector<std::string> txt;
txt.push_back("txtvers=1");
txt.push_back("ty=" + std::string(kPrinterName));
- txt.push_back("note=");
- txt.push_back("url=https://www.google.com/cloudprint");
+ txt.push_back("note=" + std::string(kPrinterDescription));
+ txt.push_back("url=" + std::string(kCloudPrintUrl));
txt.push_back("type=printer");
txt.push_back("id=" + reg_info_.device_id);
txt.push_back("cs=offline");
@@ -328,3 +321,84 @@ std::vector<std::string> Printer::CreateTxt() const {
return txt;
}
+void Printer::SaveToFile(const base::FilePath& file_path) const {
+ base::DictionaryValue json;
+ // TODO(maksymb): Get rid of in-place constants.
+ if (reg_info_.state == RegistrationInfo::DEV_REG_REGISTERED) {
+ json.SetBoolean("registered", true);
+ json.SetString("user", reg_info_.user);
+ json.SetString("device_id", reg_info_.device_id);
+ json.SetString("refresh_token", reg_info_.refresh_token);
+ } else {
+ json.SetBoolean("registered", false);
+ }
+
+ std::string json_str;
+ base::JSONWriter::WriteWithOptions(&json,
+ base::JSONWriter::OPTIONS_PRETTY_PRINT,
+ &json_str);
+ if (!file_util::WriteFile(file_path, json_str.data(),
+ static_cast<int>(json_str.size()))) {
+ LOG(ERROR) << "Cannot write state.";
+ }
+ LOG(INFO) << "State written to file.";
+}
+
+bool Printer::LoadFromFile(const base::FilePath& file_path) {
+ if (!base::PathExists(file_path)) {
+ LOG(INFO) << "Registration info is not found. Printer is unregistered.";
+ return false;
+ }
+
+ LOG(INFO) << "Loading registration info from file.";
+ std::string json_str;
+ if (!file_util::ReadFileToString(file_path, &json_str)) {
+ LOG(ERROR) << "Cannot open file.";
+ return false;
+ }
+
+ scoped_ptr<base::Value> json_val(base::JSONReader::Read(json_str));
+ base::DictionaryValue* json = NULL;
+ if (!json_val || !json_val->GetAsDictionary(&json)) {
+ LOG(ERROR) << "Cannot read JSON dictionary from file.";
+ return false;
+ }
+
+ bool registered = false;
+ if (!json->GetBoolean("registered", &registered)) {
+ LOG(ERROR) << "Cannot parse |registered| state.";
+ return false;
+ }
+
+ if (!registered) {
+ reg_info_ = RegistrationInfo();
+ return true;
+ }
+
+ std::string user;
+ if (!json->GetString("user", &user)) {
+ LOG(ERROR) << "Cannot parse |user|.";
+ return false;
+ }
+
+ std::string device_id;
+ if (!json->GetString("device_id", &device_id)) {
+ LOG(ERROR) << "Cannot parse |device_id|.";
+ return false;
+ }
+
+ std::string refresh_token;
+ if (!json->GetString("refresh_token", &refresh_token)) {
+ LOG(ERROR) << "Cannot parse |refresh_token|.";
+ return false;
+ }
+
+ reg_info_ = RegistrationInfo();
+ reg_info_.state = RegistrationInfo::DEV_REG_REGISTERED;
+ reg_info_.user = user;
+ reg_info_.device_id = device_id;
+ reg_info_.refresh_token = refresh_token;
+
+ return true;
+}
+