1// Copyright (c) 2012 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 "remoting/host/server_log_entry.h"
6
7#include "base/logging.h"
8#include "base/strings/stringize_macros.h"
9#include "base/sys_info.h"
10#include "remoting/base/constants.h"
11#include "remoting/protocol/session.h"
12#include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
13
14using base::SysInfo;
15using buzz::QName;
16using buzz::XmlElement;
17using remoting::protocol::Session;
18
19namespace remoting {
20
21namespace {
22const char kLogCommand[] = "log";
23
24const char kLogEntry[] = "entry";
25
26const char kKeyEventName[] = "event-name";
27const char kValueEventNameSessionState[] = "session-state";
28const char kValueEventNameHeartbeat[] = "heartbeat";
29const char kValueEventNameHostStatus[] = "host-status";
30
31const char kKeyRole[] = "role";
32const char kValueRoleHost[] = "host";
33
34const char kKeyMode[] = "mode";
35const char kValueModeIt2Me[] = "it2me";
36const char kValueModeMe2Me[] = "me2me";
37
38const char kKeySessionState[] = "session-state";
39const char kValueSessionStateConnected[] = "connected";
40const char kValueSessionStateClosed[] = "closed";
41
42const char kStatusName[] = "status";
43const char kExitCodeName[] = "exit-code";
44
45const char kKeyOsName[] = "os-name";
46
47#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS)
48const char kKeyOsVersion[] = "os-version";
49#endif
50
51const char kKeyHostVersion[] = "host-version";
52
53const char kKeyCpu[] = "cpu";
54
55const char kKeyConnectionType[] = "connection-type";
56
57}  // namespace
58
59ServerLogEntry::ServerLogEntry() {
60}
61
62ServerLogEntry::~ServerLogEntry() {
63}
64
65// static
66scoped_ptr<buzz::XmlElement> ServerLogEntry::MakeStanza() {
67  return scoped_ptr<buzz::XmlElement>(
68      new XmlElement(QName(kChromotingXmlNamespace, kLogCommand)));
69}
70
71// static
72scoped_ptr<ServerLogEntry> ServerLogEntry::MakeForSessionStateChange(
73    bool connected) {
74  scoped_ptr<ServerLogEntry> entry(new ServerLogEntry());
75  entry->Set(kKeyRole, kValueRoleHost);
76  entry->Set(kKeyEventName, kValueEventNameSessionState);
77  entry->Set(kKeySessionState, GetValueSessionState(connected));
78  return entry.Pass();
79}
80
81// static
82scoped_ptr<ServerLogEntry> ServerLogEntry::MakeForHeartbeat() {
83  scoped_ptr<ServerLogEntry> entry(new ServerLogEntry());
84  entry->Set(kKeyRole, kValueRoleHost);
85  entry->Set(kKeyEventName, kValueEventNameHeartbeat);
86  return entry.Pass();
87}
88
89// static
90scoped_ptr<ServerLogEntry> ServerLogEntry::MakeForHostStatus(
91    HostStatusSender::HostStatus host_status, HostExitCodes exit_code) {
92  scoped_ptr<ServerLogEntry> entry(new ServerLogEntry());
93  entry->Set(kKeyRole, kValueRoleHost);
94  entry->Set(kKeyEventName, kValueEventNameHostStatus);
95  entry->Set(kStatusName, HostStatusSender::HostStatusToString(host_status));
96  if (host_status == HostStatusSender::OFFLINE)
97    entry->Set(kExitCodeName, ExitCodeToString(exit_code));
98  return entry.Pass();
99}
100
101void ServerLogEntry::AddHostFields() {
102#if defined(OS_WIN)
103  Set(kKeyOsName, "Windows");
104#elif defined(OS_MACOSX)
105  Set(kKeyOsName, "Mac");
106#elif defined(OS_CHROMEOS)
107  Set(kKeyOsName, "ChromeOS");
108#elif defined(OS_LINUX)
109  Set(kKeyOsName, "Linux");
110#endif
111
112  // SysInfo::OperatingSystemVersionNumbers is only defined for the following
113  // OSes: see base/sys_info_unittest.cc.
114#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS)
115  std::stringstream os_version;
116  int32 os_major_version = 0;
117  int32 os_minor_version = 0;
118  int32 os_bugfix_version = 0;
119  SysInfo::OperatingSystemVersionNumbers(&os_major_version, &os_minor_version,
120                                         &os_bugfix_version);
121  os_version << os_major_version << "." << os_minor_version << "."
122             << os_bugfix_version;
123  Set(kKeyOsVersion, os_version.str());
124#endif
125
126  Set(kKeyHostVersion, STRINGIZE(VERSION));
127  Set(kKeyCpu, SysInfo::OperatingSystemArchitecture());
128};
129
130void ServerLogEntry::AddModeField(ServerLogEntry::Mode mode) {
131  Set(kKeyMode, GetValueMode(mode));
132}
133
134void ServerLogEntry::AddConnectionTypeField(
135    protocol::TransportRoute::RouteType type) {
136  Set(kKeyConnectionType, protocol::TransportRoute::GetTypeString(type));
137}
138
139// static
140const char* ServerLogEntry::GetValueMode(ServerLogEntry::Mode mode) {
141  switch (mode) {
142    case IT2ME:
143      return kValueModeIt2Me;
144    case ME2ME:
145      return kValueModeMe2Me;
146    default:
147      NOTREACHED();
148      return NULL;
149  }
150}
151
152scoped_ptr<XmlElement> ServerLogEntry::ToStanza() const {
153  scoped_ptr<XmlElement> stanza(new XmlElement(QName(
154      kChromotingXmlNamespace, kLogEntry)));
155  ValuesMap::const_iterator iter;
156  for (iter = values_map_.begin(); iter != values_map_.end(); ++iter) {
157    stanza->AddAttr(QName(std::string(), iter->first), iter->second);
158  }
159  return stanza.Pass();
160}
161
162// static
163const char* ServerLogEntry::GetValueSessionState(bool connected) {
164  return connected ? kValueSessionStateConnected : kValueSessionStateClosed;
165}
166
167void ServerLogEntry::Set(const std::string& key, const std::string& value) {
168  values_map_[key] = value;
169}
170
171}  // namespace remoting
172