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#ifndef REMOTING_HOST_STATUS_SENDER_H_
6#define REMOTING_HOST_STATUS_SENDER_H_
7
8#include <string>
9
10#include "base/compiler_specific.h"
11#include "base/memory/ref_counted.h"
12#include "base/memory/scoped_ptr.h"
13#include "remoting/base/rsa_key_pair.h"
14#include "remoting/host/host_exit_codes.h"
15#include "remoting/signaling/signal_strategy.h"
16
17namespace base {
18class MessageLoopProxy;
19}  // namespace base
20
21namespace buzz {
22class XmlElement;
23}  // namespace buzz
24
25namespace remoting {
26
27class RsaKeyPair;
28class IqSender;
29
30// HostStatusSender sends the host status to the Chromoting Bot.
31// Each host status stanza looks as follows:
32//
33// <cli:iq type="set" to="user@gmail.com/chromoting123123"
34//     id="123" xmlns:cli="jabber:client">
35//   <rem:host-status rem:hostid="0"
36//       rem:status="OFFLINE" rem:exit-code="INVALID_HOST_CONFIGURATION"
37//       xmlns:rem="google:remoting">
38//     <rem:signature rem:time="1372878097">.signature.</rem:signature>
39//     <rem:host-version>30.0.1554.0</rem:host-version>
40//     <rem:log><rem:entry cpu="x86_64" event-name="host-status"
41//         host-version="30.0.1560.0" os-name="Linux" role="host"/>
42//     </rem:log>
43//   </rem:host-status>
44// </cli:iq>
45//
46// The signature is a base-64 encoded SHA-1 hash, signed with the host's
47// private RSA key. The message being signed contains the full Jid (e.g.
48// "user@gmail.com/chromoting123123"), the timestamp, the host status,
49// and the exit code.
50class HostStatusSender : SignalStrategy::Listener {
51 public:
52
53  enum HostStatus {
54    OFFLINE = 0,
55    ONLINE = 1
56  };
57
58  HostStatusSender(const std::string& host_id,
59                   SignalStrategy* signal_strategy,
60                   scoped_refptr<RsaKeyPair> key_pair,
61                   const std::string& directory_bot_jid);
62  virtual ~HostStatusSender();
63
64  // SignalStrategy::Listener interface.
65  virtual void OnSignalStrategyStateChange(
66      SignalStrategy::State state) OVERRIDE;
67  virtual bool OnSignalStrategyIncomingStanza(
68      const buzz::XmlElement* stanza) OVERRIDE;
69
70  // APIs for sending host status XMPP messages to the chromoting bot.
71  // status: the reason (exit code) why the host is offline.
72  void SendOnlineStatus();
73  void SendOfflineStatus(HostExitCodes exit_code);
74
75  inline static const char* HostStatusToString(HostStatus host_status) {
76    return host_status_strings_[host_status];
77  }
78
79 private:
80  // Helper method for sending either an online or an offline status message.
81  void SendHostStatus(HostStatus status, HostExitCodes exit_code);
82
83  // Helper method to compose host status stanzas.
84  scoped_ptr<buzz::XmlElement> CreateHostStatusMessage(
85      HostStatus status, HostExitCodes exit_code);
86
87  // Helper method to create the signature blob used in the host status stanza.
88  scoped_ptr<buzz::XmlElement> CreateSignature(
89      HostStatus status, HostExitCodes exit_code);
90
91  std::string host_id_;
92  SignalStrategy* signal_strategy_;
93  scoped_refptr<RsaKeyPair> key_pair_;
94  std::string directory_bot_jid_;
95  scoped_ptr<IqSender> iq_sender_;
96
97  // The string representation of the HostStatus values.
98  static const char* const host_status_strings_[2];
99
100  DISALLOW_COPY_AND_ASSIGN(HostStatusSender);
101};
102
103}  // namespace remoting
104
105#endif  // REMOTING_HOST_STATUS_SENDER_H_
106