1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file.
4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/extensions/api/diagnostics/diagnostics_api.h"
6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/bind.h"
8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/callback.h"
9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/json/json_reader.h"
10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/strings/string_number_conversions.h"
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/values.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chromeos/dbus/dbus_thread_manager.h"
13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chromeos/dbus/debug_daemon_client.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace extensions {
16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace {
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst char kCount[] = "count";
20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst char kDefaultCount[] = "1";
21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst char kTTL[] = "ttl";
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst char kTimeout[] = "timeout";
23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst char kSize[] = "size";
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochtypedef base::Callback<void(
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    DiagnosticsSendPacketFunction::SendPacketResultCode result_code,
27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::string& ip,
28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    double latency)>
29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    SendPacketCallback;
30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool ParseResult(const std::string& status,
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 std::string* ip,
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 double* latency) {
3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Parses the result and returns IP and latency.
3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  scoped_ptr<base::Value> parsed_value(base::JSONReader::Read(status));
3668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!parsed_value)
3768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return false;
38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::DictionaryValue* result = NULL;
4068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!parsed_value->GetAsDictionary(&result) || result->size() != 1)
4168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return false;
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
4368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Returns the first item.
4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::DictionaryValue::Iterator iterator(*result);
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
4668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  const base::DictionaryValue* info;
4768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!iterator.value().GetAsDictionary(&info))
4868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return false;
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
5068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!info->GetDouble("avg", latency))
5168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return false;
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
5368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  *ip = iterator.key();
5468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return true;
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid OnTestICMPCompleted(
58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const SendPacketCallback& callback,
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    bool succeeded,
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::string& status) {
61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string ip;
62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  double latency;
63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!succeeded || !ParseResult(status, &ip, &latency)) {
64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    callback.Run(DiagnosticsSendPacketFunction::SEND_PACKET_FAILED, "", 0.0);
65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  } else {
66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    callback.Run(DiagnosticsSendPacketFunction::SEND_PACKET_OK,
67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 ip,
68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 latency);
69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace
73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid DiagnosticsSendPacketFunction::AsyncWorkStart() {
75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::map<std::string, std::string> config;
76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  config[kCount] = kDefaultCount;
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (parameters_->options.ttl)
78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    config[kTTL] = base::IntToString(*parameters_->options.ttl);
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (parameters_->options.timeout)
80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    config[kTimeout] = base::IntToString(*parameters_->options.timeout);
81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (parameters_->options.size)
82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    config[kSize] = base::IntToString(*parameters_->options.size);
83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()->
85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      TestICMPWithOptions(
86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          parameters_->options.ip, config,
87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Bind(
88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              OnTestICMPCompleted,
89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              base::Bind(&DiagnosticsSendPacketFunction::OnCompleted, this)));
90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace extensions
93