blob: 2144f01ecfbba6b1434ce1db67e76db522bddf61 [file] [log] [blame]
Darin Petkov41c0e0a2012-01-09 16:38:53 +01001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Darin Petkov887f2982011-07-14 16:10:17 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/modem_manager.h"
6
Eric Shienbrood3e20a232012-02-16 11:35:56 -05007#include <base/stl_util.h>
David Rochbergfa1d31d2012-03-20 10:38:07 -04008#include <mm/mm-modem.h>
Darin Petkov887f2982011-07-14 16:10:17 -07009
Eric Shienbrood9a245532012-03-07 14:20:39 -050010#include "shill/error.h"
Christopher Wileyb691efd2012-08-09 13:51:51 -070011#include "shill/logging.h"
Darin Petkov5c97ac52011-07-19 16:30:49 -070012#include "shill/modem.h"
Darin Petkovc90fe522011-07-15 13:59:47 -070013#include "shill/modem_manager_proxy.h"
14#include "shill/proxy_factory.h"
15
Darin Petkov887f2982011-07-14 16:10:17 -070016using std::string;
Darin Petkov5c97ac52011-07-19 16:30:49 -070017using std::tr1::shared_ptr;
18using std::vector;
Darin Petkov887f2982011-07-14 16:10:17 -070019
20namespace shill {
Ben Chan5c853ef2012-10-05 00:05:37 -070021
Darin Petkov887f2982011-07-14 16:10:17 -070022ModemManager::ModemManager(const string &service,
23 const string &path,
24 ControlInterface *control_interface,
25 EventDispatcher *dispatcher,
Thieu Le3426c8f2012-01-11 17:35:11 -080026 Metrics *metrics,
Darin Petkov887f2982011-07-14 16:10:17 -070027 Manager *manager,
Darin Petkov137884a2011-10-26 18:52:47 +020028 GLib *glib,
29 mobile_provider_db *provider_db)
Darin Petkovab565bb2011-10-06 02:55:51 -070030 : proxy_factory_(ProxyFactory::GetInstance()),
31 service_(service),
Darin Petkov887f2982011-07-14 16:10:17 -070032 path_(path),
33 watcher_id_(0),
34 control_interface_(control_interface),
35 dispatcher_(dispatcher),
Thieu Le3426c8f2012-01-11 17:35:11 -080036 metrics_(metrics),
Darin Petkov67d8ecf2011-07-26 16:03:30 -070037 manager_(manager),
Darin Petkov137884a2011-10-26 18:52:47 +020038 glib_(glib),
39 provider_db_(provider_db) {}
Darin Petkov887f2982011-07-14 16:10:17 -070040
41ModemManager::~ModemManager() {
42 Stop();
43}
44
45void ModemManager::Start() {
46 LOG(INFO) << "Start watching modem manager service: " << service_;
Eric Shienbroodc74cf9c2012-03-02 15:00:35 -050047 CHECK_EQ(0U, watcher_id_);
Darin Petkovc90fe522011-07-15 13:59:47 -070048 // TODO(petkov): Implement DBus name watching through dbus-c++.
Darin Petkov887f2982011-07-14 16:10:17 -070049 watcher_id_ = glib_->BusWatchName(G_BUS_TYPE_SYSTEM,
50 service_.c_str(),
51 G_BUS_NAME_WATCHER_FLAGS_NONE,
52 OnAppear,
53 OnVanish,
54 this,
55 NULL);
56}
57
58void ModemManager::Stop() {
59 LOG(INFO) << "Stop watching modem manager service: " << service_;
60 if (watcher_id_) {
61 glib_->BusUnwatchName(watcher_id_);
62 watcher_id_ = 0;
63 }
64 Disconnect();
65}
66
67void ModemManager::Connect(const string &owner) {
David Rochberg81030ea2012-03-02 15:44:25 -050068 // Inheriting classes call this superclass method.
Darin Petkov887f2982011-07-14 16:10:17 -070069 owner_ = owner;
Darin Petkov887f2982011-07-14 16:10:17 -070070}
71
72void ModemManager::Disconnect() {
David Rochberg81030ea2012-03-02 15:44:25 -050073 // Inheriting classes call this superclass method.
Darin Petkov5c97ac52011-07-19 16:30:49 -070074 modems_.clear();
Darin Petkov887f2982011-07-14 16:10:17 -070075 owner_.clear();
Darin Petkov887f2982011-07-14 16:10:17 -070076}
77
mukesh agrawal1830fa12011-09-26 14:31:40 -070078void ModemManager::OnAppear(GDBusConnection */*connection*/,
Darin Petkov887f2982011-07-14 16:10:17 -070079 const gchar *name,
80 const gchar *name_owner,
81 gpointer user_data) {
82 LOG(INFO) << "Modem manager " << name << " appeared. Owner: " << name_owner;
83 ModemManager *manager = reinterpret_cast<ModemManager *>(user_data);
84 manager->Connect(name_owner);
85}
86
mukesh agrawal1830fa12011-09-26 14:31:40 -070087void ModemManager::OnVanish(GDBusConnection */*connection*/,
Darin Petkov887f2982011-07-14 16:10:17 -070088 const gchar *name,
89 gpointer user_data) {
90 LOG(INFO) << "Modem manager " << name << " vanished.";
91 ModemManager *manager = reinterpret_cast<ModemManager *>(user_data);
92 manager->Disconnect();
93}
94
David Rochbergfa1d31d2012-03-20 10:38:07 -040095bool ModemManager::ModemExists(const std::string &path) const {
Darin Petkov5c97ac52011-07-19 16:30:49 -070096 CHECK(!owner_.empty());
97 if (ContainsKey(modems_, path)) {
David Rochbergfa1d31d2012-03-20 10:38:07 -040098 LOG(INFO) << "ModemExists: " << path << " already exists.";
99 return true;
100 } else {
101 return false;
Darin Petkov5c97ac52011-07-19 16:30:49 -0700102 }
David Rochbergfa1d31d2012-03-20 10:38:07 -0400103}
104
105void ModemManager::RecordAddedModem(shared_ptr<Modem> modem) {
106 modems_[modem->path()] = modem;
Darin Petkov5c97ac52011-07-19 16:30:49 -0700107}
108
Darin Petkov41c0e0a2012-01-09 16:38:53 +0100109void ModemManager::RemoveModem(const string &path) {
Darin Petkov5c97ac52011-07-19 16:30:49 -0700110 LOG(INFO) << "Remove modem: " << path;
111 CHECK(!owner_.empty());
112 modems_.erase(path);
113}
114
Darin Petkov41c0e0a2012-01-09 16:38:53 +0100115void ModemManager::OnDeviceInfoAvailable(const string &link_name) {
David Rochberg81030ea2012-03-02 15:44:25 -0500116 for (Modems::const_iterator it = modems_.begin(); it != modems_.end(); ++it) {
Darin Petkov41c0e0a2012-01-09 16:38:53 +0100117 it->second->OnDeviceInfoAvailable(link_name);
118 }
119}
120
David Rochberg81030ea2012-03-02 15:44:25 -0500121// ModemManagerClassic
David Rochberg7cb06f62012-03-05 11:23:44 -0500122ModemManagerClassic::ModemManagerClassic(const string &service,
123 const string &path,
David Rochberg81030ea2012-03-02 15:44:25 -0500124 ControlInterface *control_interface,
125 EventDispatcher *dispatcher,
126 Metrics *metrics,
127 Manager *manager,
128 GLib *glib,
129 mobile_provider_db *provider_db) :
130 ModemManager(service,
131 path,
132 control_interface,
133 dispatcher,
134 metrics,
135 manager,
136 glib,
137 provider_db) {}
138
139ModemManagerClassic::~ModemManagerClassic() {}
140
141void ModemManagerClassic::Connect(const string &supplied_owner) {
142 ModemManager::Connect(supplied_owner);
143 proxy_.reset(proxy_factory()->CreateModemManagerProxy(this, path(), owner()));
David Rochberg81030ea2012-03-02 15:44:25 -0500144 // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583).
145 vector<DBus::Path> devices = proxy_->EnumerateDevices();
David Rochbergfa1d31d2012-03-20 10:38:07 -0400146
David Rochberg81030ea2012-03-02 15:44:25 -0500147 for (vector<DBus::Path>::const_iterator it = devices.begin();
148 it != devices.end(); ++it) {
David Rochbergfa1d31d2012-03-20 10:38:07 -0400149 AddModemClassic(*it);
David Rochberg81030ea2012-03-02 15:44:25 -0500150 }
151}
152
David Rochbergfa1d31d2012-03-20 10:38:07 -0400153void ModemManagerClassic::AddModemClassic(const string &path) {
154 if (ModemExists(path)) {
155 return;
156 }
157 shared_ptr<ModemClassic> modem(new ModemClassic(owner(),
Jason Glasgowa585fc32012-06-06 11:04:09 -0400158 service(),
David Rochbergfa1d31d2012-03-20 10:38:07 -0400159 path,
160 control_interface(),
161 dispatcher(),
162 metrics(),
163 manager(),
164 provider_db()));
165 RecordAddedModem(modem);
166 InitModemClassic(modem);
167}
168
David Rochberg81030ea2012-03-02 15:44:25 -0500169void ModemManagerClassic::Disconnect() {
170 ModemManager::Disconnect();
171 proxy_.reset();
172}
173
David Rochbergfa1d31d2012-03-20 10:38:07 -0400174void ModemManagerClassic::InitModemClassic(shared_ptr<ModemClassic> modem) {
175 // TODO(rochberg): Switch to asynchronous calls (crosbug.com/17583).
176 if (modem == NULL) {
177 return;
178 }
179
180 scoped_ptr<DBusPropertiesProxyInterface> properties_proxy(
Jason Glasgow9c09e362012-04-18 15:16:29 -0400181 proxy_factory()->CreateDBusPropertiesProxy(modem->path(),
David Rochbergfa1d31d2012-03-20 10:38:07 -0400182 modem->owner()));
183 DBusPropertiesMap properties =
184 properties_proxy->GetAll(MM_MODEM_INTERFACE);
185
186 modem->CreateDeviceClassic(properties);
David Rochberg81030ea2012-03-02 15:44:25 -0500187}
188
David Rochbergfa1d31d2012-03-20 10:38:07 -0400189void ModemManagerClassic::OnDeviceAdded(const string &path) {
190 AddModemClassic(path);
191}
192
193void ModemManagerClassic::OnDeviceRemoved(const string &path) {
194 RemoveModem(path);
195}
David Rochberg7cb06f62012-03-05 11:23:44 -0500196
Darin Petkov887f2982011-07-14 16:10:17 -0700197} // namespace shill