OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/host/heartbeat_sender.h" | 5 #include "remoting/host/heartbeat_sender.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/string_number_conversions.h" | 9 #include "base/string_number_conversions.h" |
10 #include "base/time.h" | 10 #include "base/time.h" |
11 #include "remoting/base/constants.h" | 11 #include "remoting/base/constants.h" |
12 #include "remoting/host/host_config.h" | 12 #include "remoting/host/host_config.h" |
13 #include "remoting/jingle_glue/iq_request.h" | 13 #include "remoting/jingle_glue/iq_request.h" |
14 #include "remoting/jingle_glue/jingle_client.h" | 14 #include "remoting/jingle_glue/jingle_client.h" |
15 #include "remoting/jingle_glue/jingle_thread.h" | 15 #include "remoting/jingle_glue/jingle_thread.h" |
16 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" | 16 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" |
17 #include "third_party/libjingle/source/talk/xmpp/constants.h" | 17 #include "third_party/libjingle/source/talk/xmpp/constants.h" |
18 | 18 |
| 19 using buzz::QName; |
| 20 using buzz::XmlElement; |
| 21 |
19 namespace remoting { | 22 namespace remoting { |
20 | 23 |
21 namespace { | 24 namespace { |
22 const char kHeartbeatQueryTag[] = "heartbeat"; | 25 const char kHeartbeatQueryTag[] = "heartbeat"; |
23 const char kHostIdAttr[] = "hostid"; | 26 const char kHostIdAttr[] = "hostid"; |
24 const char kHeartbeatSignatureTag[] = "signature"; | 27 const char kHeartbeatSignatureTag[] = "signature"; |
25 const char kSignatureTimeAttr[] = "time"; | 28 const char kSignatureTimeAttr[] = "time"; |
26 | 29 |
27 // TODO(sergeyu): Make this configurable by the cloud. | 30 const char kHeartbeatResultTag[] = "heartbeat-result"; |
28 const int64 kHeartbeatPeriodMs = 5 * 60 * 1000; // 5 minutes. | 31 const char kSetIntervalTag[] = "set-interval"; |
| 32 |
| 33 const int64 kDefaultHeartbeatIntervalMs = 5 * 60 * 1000; // 5 minutes. |
29 } | 34 } |
30 | 35 |
31 HeartbeatSender::HeartbeatSender() | 36 HeartbeatSender::HeartbeatSender() |
32 : state_(CREATED) { | 37 : state_(CREATED), |
| 38 interval_ms_(kDefaultHeartbeatIntervalMs) { |
33 } | 39 } |
34 | 40 |
35 HeartbeatSender::~HeartbeatSender() { | 41 HeartbeatSender::~HeartbeatSender() { |
36 DCHECK(state_ == CREATED || state_ == INITIALIZED || state_ == STOPPED); | 42 DCHECK(state_ == CREATED || state_ == INITIALIZED || state_ == STOPPED); |
37 } | 43 } |
38 | 44 |
39 bool HeartbeatSender::Init(MutableHostConfig* config, | 45 bool HeartbeatSender::Init(MutableHostConfig* config, |
40 JingleClient* jingle_client) { | 46 JingleClient* jingle_client) { |
41 DCHECK(jingle_client); | 47 DCHECK(jingle_client); |
42 DCHECK(state_ == CREATED); | 48 DCHECK(state_ == CREATED); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 DCHECK(MessageLoop::current() == jingle_client_->message_loop()); | 102 DCHECK(MessageLoop::current() == jingle_client_->message_loop()); |
97 | 103 |
98 VLOG(1) << "Sending heartbeat stanza to " << kChromotingBotJid; | 104 VLOG(1) << "Sending heartbeat stanza to " << kChromotingBotJid; |
99 | 105 |
100 request_->SendIq(buzz::STR_SET, kChromotingBotJid, | 106 request_->SendIq(buzz::STR_SET, kChromotingBotJid, |
101 CreateHeartbeatMessage()); | 107 CreateHeartbeatMessage()); |
102 | 108 |
103 // Schedule next heartbeat. | 109 // Schedule next heartbeat. |
104 jingle_client_->message_loop()->PostDelayedTask( | 110 jingle_client_->message_loop()->PostDelayedTask( |
105 FROM_HERE, NewRunnableMethod(this, &HeartbeatSender::DoSendStanza), | 111 FROM_HERE, NewRunnableMethod(this, &HeartbeatSender::DoSendStanza), |
106 kHeartbeatPeriodMs); | 112 interval_ms_); |
107 } | 113 } |
108 } | 114 } |
109 | 115 |
110 void HeartbeatSender::ProcessResponse(const buzz::XmlElement* response) { | 116 void HeartbeatSender::ProcessResponse(const XmlElement* response) { |
111 if (response->Attr(buzz::QN_TYPE) == buzz::STR_ERROR) { | 117 std::string type = response->Attr(buzz::QN_TYPE); |
| 118 if (type == buzz::STR_ERROR) { |
112 LOG(ERROR) << "Received error in response to heartbeat: " | 119 LOG(ERROR) << "Received error in response to heartbeat: " |
113 << response->Str(); | 120 << response->Str(); |
| 121 return; |
| 122 } |
| 123 |
| 124 // This method must only be called for error or result stanzas. |
| 125 DCHECK_EQ(buzz::STR_RESULT, type); |
| 126 |
| 127 const XmlElement* result_element = |
| 128 response->FirstNamed(QName(kChromotingXmlNamespace, kHeartbeatResultTag)); |
| 129 if (result_element) { |
| 130 const XmlElement* set_interval_element = |
| 131 result_element->FirstNamed(QName(kChromotingXmlNamespace, |
| 132 kSetIntervalTag)); |
| 133 if (set_interval_element) { |
| 134 const std::string& interval_str = set_interval_element->BodyText(); |
| 135 int interval; |
| 136 if (!base::StringToInt(interval_str, &interval) || interval <= 0) { |
| 137 LOG(ERROR) << "Received invalid set-interval: " |
| 138 << set_interval_element->Str(); |
| 139 } else { |
| 140 interval_ms_ = interval * base::Time::kMillisecondsPerSecond; |
| 141 } |
| 142 } |
114 } | 143 } |
115 } | 144 } |
116 | 145 |
117 buzz::XmlElement* HeartbeatSender::CreateHeartbeatMessage() { | 146 XmlElement* HeartbeatSender::CreateHeartbeatMessage() { |
118 buzz::XmlElement* query = new buzz::XmlElement( | 147 XmlElement* query = new XmlElement( |
119 buzz::QName(kChromotingXmlNamespace, kHeartbeatQueryTag)); | 148 QName(kChromotingXmlNamespace, kHeartbeatQueryTag)); |
120 query->AddAttr(buzz::QName(kChromotingXmlNamespace, kHostIdAttr), host_id_); | 149 query->AddAttr(QName(kChromotingXmlNamespace, kHostIdAttr), host_id_); |
121 query->AddElement(CreateSignature()); | 150 query->AddElement(CreateSignature()); |
122 return query; | 151 return query; |
123 } | 152 } |
124 | 153 |
125 buzz::XmlElement* HeartbeatSender::CreateSignature() { | 154 XmlElement* HeartbeatSender::CreateSignature() { |
126 buzz::XmlElement* signature_tag = new buzz::XmlElement( | 155 XmlElement* signature_tag = new XmlElement( |
127 buzz::QName(kChromotingXmlNamespace, kHeartbeatSignatureTag)); | 156 QName(kChromotingXmlNamespace, kHeartbeatSignatureTag)); |
128 | 157 |
129 int64 time = static_cast<int64>(base::Time::Now().ToDoubleT()); | 158 int64 time = static_cast<int64>(base::Time::Now().ToDoubleT()); |
130 std::string time_str(base::Int64ToString(time)); | 159 std::string time_str(base::Int64ToString(time)); |
131 signature_tag->AddAttr( | 160 signature_tag->AddAttr( |
132 buzz::QName(kChromotingXmlNamespace, kSignatureTimeAttr), time_str); | 161 QName(kChromotingXmlNamespace, kSignatureTimeAttr), time_str); |
133 | 162 |
134 std::string message = jingle_client_->GetFullJid() + ' ' + time_str; | 163 std::string message = jingle_client_->GetFullJid() + ' ' + time_str; |
135 std::string signature(key_pair_.GetSignature(message)); | 164 std::string signature(key_pair_.GetSignature(message)); |
136 signature_tag->AddText(signature); | 165 signature_tag->AddText(signature); |
137 | 166 |
138 return signature_tag; | 167 return signature_tag; |
139 } | 168 } |
140 | 169 |
141 } // namespace remoting | 170 } // namespace remoting |
OLD | NEW |