summaryrefslogtreecommitdiff
path: root/modem_manager.cc
blob: 2540eae3252294a4a7d507ced7ae15f7034eb0df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "shill/modem_manager.h"

#include <base/stl_util.h>
#include <mm/mm-modem.h>

#include "shill/dbus_manager.h"
#include "shill/error.h"
#include "shill/logging.h"
#include "shill/manager.h"
#include "shill/modem.h"
#include "shill/modem_manager_proxy.h"
#include "shill/proxy_factory.h"

using std::string;
using std::tr1::shared_ptr;
using std::vector;

namespace shill {

ModemManager::ModemManager(const string &service,
                           const string &path,
                           ModemInfo *modem_info)
    : proxy_factory_(ProxyFactory::GetInstance()),
      service_(service),
      path_(path),
      modem_info_(modem_info) {}

ModemManager::~ModemManager() {
  Stop();
}

void ModemManager::Start() {
  LOG(INFO) << "Start watching modem manager service: " << service_;
  CHECK(!name_watcher_);
  name_watcher_.reset(modem_info_->manager()->dbus_manager()->CreateNameWatcher(
      service_,
      base::Bind(&ModemManager::OnAppear, base::Unretained(this)),
      base::Bind(&ModemManager::OnVanish, base::Unretained(this))));
}

void ModemManager::Stop() {
  LOG(INFO) << "Stop watching modem manager service: " << service_;
  name_watcher_.reset();
  Disconnect();
}

void ModemManager::Connect(const string &owner) {
  // Inheriting classes call this superclass method.
  owner_ = owner;
}

void ModemManager::Disconnect() {
  // Inheriting classes call this superclass method.
  modems_.clear();
  owner_.clear();
}

void ModemManager::OnAppear(const string &name, const string &owner) {
  LOG(INFO) << "Modem manager " << name << " appeared. Owner: " << owner;
  Connect(owner);
}

void ModemManager::OnVanish(const string &name) {
  LOG(INFO) << "Modem manager " << name << " vanished.";
  Disconnect();
}

bool ModemManager::ModemExists(const std::string &path) const {
  CHECK(!owner_.empty());
  if (ContainsKey(modems_, path)) {
    LOG(INFO) << "ModemExists: " << path << " already exists.";
    return true;
  } else {
    return false;
  }
}

void ModemManager::RecordAddedModem(shared_ptr<Modem> modem) {
  modems_[modem->path()] = modem;
}

void ModemManager::RemoveModem(const string &path) {
  LOG(INFO) << "Remove modem: " << path;
  CHECK(!owner_.empty());
  modems_.erase(path);
}

void ModemManager::OnDeviceInfoAvailable(const string &link_name) {
  for (Modems::const_iterator it = modems_.begin(); it != modems_.end(); ++it) {
    it->second->OnDeviceInfoAvailable(link_name);
  }
}

// ModemManagerClassic
ModemManagerClassic::ModemManagerClassic(
    const string &service,
    const string &path,
    ModemInfo *modem_info)
    : ModemManager(service,
                   path,
                   modem_info) {}

ModemManagerClassic::~ModemManagerClassic() {}

void ModemManagerClassic::Connect(const string &supplied_owner) {
  ModemManager::Connect(supplied_owner);
  proxy_.reset(proxy_factory()->CreateModemManagerProxy(this, path(), owner()));
  // TODO(petkov): Switch to asynchronous calls (crbug.com/200687).
  vector<DBus::Path> devices = proxy_->EnumerateDevices();

  for (vector<DBus::Path>::const_iterator it = devices.begin();
       it != devices.end(); ++it) {
    AddModemClassic(*it);
  }
}

void ModemManagerClassic::AddModemClassic(const string &path) {
  if (ModemExists(path)) {
    return;
  }
  shared_ptr<ModemClassic> modem(new ModemClassic(owner(),
                                                  service(),
                                                  path,
                                                  modem_info()));
  RecordAddedModem(modem);
  InitModemClassic(modem);
}

void ModemManagerClassic::Disconnect() {
  ModemManager::Disconnect();
  proxy_.reset();
}

void ModemManagerClassic::InitModemClassic(shared_ptr<ModemClassic> modem) {
  // TODO(rochberg): Switch to asynchronous calls (crbug.com/200687).
  if (modem == NULL) {
    return;
  }

  scoped_ptr<DBusPropertiesProxyInterface> properties_proxy(
      proxy_factory()->CreateDBusPropertiesProxy(modem->path(),
                                                 modem->owner()));
  DBusPropertiesMap properties =
      properties_proxy->GetAll(MM_MODEM_INTERFACE);

  modem->CreateDeviceClassic(properties);
}

void ModemManagerClassic::OnDeviceAdded(const string &path) {
  AddModemClassic(path);
}

void ModemManagerClassic::OnDeviceRemoved(const string &path) {
  RemoveModem(path);
}

}  // namespace shill