blob: 89a5ea3d51792e451cfbb2d364bb78dda963a0f1 [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
Ben Chan62028b22012-11-05 11:20:02 -080010#include "shill/cellular_operator_info.h"
Eric Shienbrood9a245532012-03-07 14:20:39 -050011#include "shill/error.h"
Christopher Wileyb691efd2012-08-09 13:51:51 -070012#include "shill/logging.h"
Darin Petkov5c97ac52011-07-19 16:30:49 -070013#include "shill/modem.h"
Darin Petkovc90fe522011-07-15 13:59:47 -070014#include "shill/modem_manager_proxy.h"
15#include "shill/proxy_factory.h"
16
Darin Petkov887f2982011-07-14 16:10:17 -070017using std::string;
Darin Petkov5c97ac52011-07-19 16:30:49 -070018using std::tr1::shared_ptr;
19using std::vector;
Darin Petkov887f2982011-07-14 16:10:17 -070020
21namespace shill {
Ben Chan5c853ef2012-10-05 00:05:37 -070022
Darin Petkov887f2982011-07-14 16:10:17 -070023ModemManager::ModemManager(const string &service,
24 const string &path,
25 ControlInterface *control_interface,
26 EventDispatcher *dispatcher,
Thieu Le3426c8f2012-01-11 17:35:11 -080027 Metrics *metrics,
Darin Petkov887f2982011-07-14 16:10:17 -070028 Manager *manager,
Darin Petkov137884a2011-10-26 18:52:47 +020029 GLib *glib,
Ben Chan62028b22012-11-05 11:20:02 -080030 CellularOperatorInfo *cellular_operator_info,
Darin Petkov137884a2011-10-26 18:52:47 +020031 mobile_provider_db *provider_db)
Darin Petkovab565bb2011-10-06 02:55:51 -070032 : proxy_factory_(ProxyFactory::GetInstance()),
33 service_(service),
Darin Petkov887f2982011-07-14 16:10:17 -070034 path_(path),
35 watcher_id_(0),
36 control_interface_(control_interface),
37 dispatcher_(dispatcher),
Thieu Le3426c8f2012-01-11 17:35:11 -080038 metrics_(metrics),
Darin Petkov67d8ecf2011-07-26 16:03:30 -070039 manager_(manager),
Darin Petkov137884a2011-10-26 18:52:47 +020040 glib_(glib),
Ben Chan62028b22012-11-05 11:20:02 -080041 cellular_operator_info_(cellular_operator_info),
Darin Petkov137884a2011-10-26 18:52:47 +020042 provider_db_(provider_db) {}
Darin Petkov887f2982011-07-14 16:10:17 -070043
44ModemManager::~ModemManager() {
45 Stop();
46}
47
48void ModemManager::Start() {
49 LOG(INFO) << "Start watching modem manager service: " << service_;
Eric Shienbroodc74cf9c2012-03-02 15:00:35 -050050 CHECK_EQ(0U, watcher_id_);
Darin Petkovc90fe522011-07-15 13:59:47 -070051 // TODO(petkov): Implement DBus name watching through dbus-c++.
Darin Petkov887f2982011-07-14 16:10:17 -070052 watcher_id_ = glib_->BusWatchName(G_BUS_TYPE_SYSTEM,
53 service_.c_str(),
54 G_BUS_NAME_WATCHER_FLAGS_NONE,
55 OnAppear,
56 OnVanish,
57 this,
58 NULL);
59}
60
61void ModemManager::Stop() {
62 LOG(INFO) << "Stop watching modem manager service: " << service_;
63 if (watcher_id_) {
64 glib_->BusUnwatchName(watcher_id_);
65 watcher_id_ = 0;
66 }
67 Disconnect();
68}
69
70void ModemManager::Connect(const string &owner) {
David Rochberg81030ea2012-03-02 15:44:25 -050071 // Inheriting classes call this superclass method.
Darin Petkov887f2982011-07-14 16:10:17 -070072 owner_ = owner;
Darin Petkov887f2982011-07-14 16:10:17 -070073}
74
75void ModemManager::Disconnect() {
David Rochberg81030ea2012-03-02 15:44:25 -050076 // Inheriting classes call this superclass method.
Darin Petkov5c97ac52011-07-19 16:30:49 -070077 modems_.clear();
Darin Petkov887f2982011-07-14 16:10:17 -070078 owner_.clear();
Darin Petkov887f2982011-07-14 16:10:17 -070079}
80
mukesh agrawal1830fa12011-09-26 14:31:40 -070081void ModemManager::OnAppear(GDBusConnection */*connection*/,
Darin Petkov887f2982011-07-14 16:10:17 -070082 const gchar *name,
83 const gchar *name_owner,
84 gpointer user_data) {
85 LOG(INFO) << "Modem manager " << name << " appeared. Owner: " << name_owner;
86 ModemManager *manager = reinterpret_cast<ModemManager *>(user_data);
87 manager->Connect(name_owner);
88}
89
mukesh agrawal1830fa12011-09-26 14:31:40 -070090void ModemManager::OnVanish(GDBusConnection */*connection*/,
Darin Petkov887f2982011-07-14 16:10:17 -070091 const gchar *name,
92 gpointer user_data) {
93 LOG(INFO) << "Modem manager " << name << " vanished.";
94 ModemManager *manager = reinterpret_cast<ModemManager *>(user_data);
95 manager->Disconnect();
96}
97
David Rochbergfa1d31d2012-03-20 10:38:07 -040098bool ModemManager::ModemExists(const std::string &path) const {
Darin Petkov5c97ac52011-07-19 16:30:49 -070099 CHECK(!owner_.empty());
100 if (ContainsKey(modems_, path)) {
David Rochbergfa1d31d2012-03-20 10:38:07 -0400101 LOG(INFO) << "ModemExists: " << path << " already exists.";
102 return true;
103 } else {
104 return false;
Darin Petkov5c97ac52011-07-19 16:30:49 -0700105 }
David Rochbergfa1d31d2012-03-20 10:38:07 -0400106}
107
108void ModemManager::RecordAddedModem(shared_ptr<Modem> modem) {
109 modems_[modem->path()] = modem;
Darin Petkov5c97ac52011-07-19 16:30:49 -0700110}
111
Darin Petkov41c0e0a2012-01-09 16:38:53 +0100112void ModemManager::RemoveModem(const string &path) {
Darin Petkov5c97ac52011-07-19 16:30:49 -0700113 LOG(INFO) << "Remove modem: " << path;
114 CHECK(!owner_.empty());
115 modems_.erase(path);
116}
117
Darin Petkov41c0e0a2012-01-09 16:38:53 +0100118void ModemManager::OnDeviceInfoAvailable(const string &link_name) {
David Rochberg81030ea2012-03-02 15:44:25 -0500119 for (Modems::const_iterator it = modems_.begin(); it != modems_.end(); ++it) {
Darin Petkov41c0e0a2012-01-09 16:38:53 +0100120 it->second->OnDeviceInfoAvailable(link_name);
121 }
122}
123
David Rochberg81030ea2012-03-02 15:44:25 -0500124// ModemManagerClassic
Ben Chan62028b22012-11-05 11:20:02 -0800125ModemManagerClassic::ModemManagerClassic(
126 const string &service,
127 const string &path,
128 ControlInterface *control_interface,
129 EventDispatcher *dispatcher,
130 Metrics *metrics,
131 Manager *manager,
132 GLib *glib,
133 CellularOperatorInfo *cellular_operator_info,
134 mobile_provider_db *provider_db)
135 : ModemManager(service,
136 path,
137 control_interface,
138 dispatcher,
139 metrics,
140 manager,
141 glib,
142 cellular_operator_info,
143 provider_db) {}
David Rochberg81030ea2012-03-02 15:44:25 -0500144
145ModemManagerClassic::~ModemManagerClassic() {}
146
147void ModemManagerClassic::Connect(const string &supplied_owner) {
148 ModemManager::Connect(supplied_owner);
149 proxy_.reset(proxy_factory()->CreateModemManagerProxy(this, path(), owner()));
David Rochberg81030ea2012-03-02 15:44:25 -0500150 // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583).
151 vector<DBus::Path> devices = proxy_->EnumerateDevices();
David Rochbergfa1d31d2012-03-20 10:38:07 -0400152
David Rochberg81030ea2012-03-02 15:44:25 -0500153 for (vector<DBus::Path>::const_iterator it = devices.begin();
154 it != devices.end(); ++it) {
David Rochbergfa1d31d2012-03-20 10:38:07 -0400155 AddModemClassic(*it);
David Rochberg81030ea2012-03-02 15:44:25 -0500156 }
157}
158
David Rochbergfa1d31d2012-03-20 10:38:07 -0400159void ModemManagerClassic::AddModemClassic(const string &path) {
160 if (ModemExists(path)) {
161 return;
162 }
163 shared_ptr<ModemClassic> modem(new ModemClassic(owner(),
Jason Glasgowa585fc32012-06-06 11:04:09 -0400164 service(),
David Rochbergfa1d31d2012-03-20 10:38:07 -0400165 path,
166 control_interface(),
167 dispatcher(),
168 metrics(),
169 manager(),
Ben Chan62028b22012-11-05 11:20:02 -0800170 cellular_operator_info(),
David Rochbergfa1d31d2012-03-20 10:38:07 -0400171 provider_db()));
172 RecordAddedModem(modem);
173 InitModemClassic(modem);
174}
175
David Rochberg81030ea2012-03-02 15:44:25 -0500176void ModemManagerClassic::Disconnect() {
177 ModemManager::Disconnect();
178 proxy_.reset();
179}
180
David Rochbergfa1d31d2012-03-20 10:38:07 -0400181void ModemManagerClassic::InitModemClassic(shared_ptr<ModemClassic> modem) {
182 // TODO(rochberg): Switch to asynchronous calls (crosbug.com/17583).
183 if (modem == NULL) {
184 return;
185 }
186
187 scoped_ptr<DBusPropertiesProxyInterface> properties_proxy(
Jason Glasgow9c09e362012-04-18 15:16:29 -0400188 proxy_factory()->CreateDBusPropertiesProxy(modem->path(),
David Rochbergfa1d31d2012-03-20 10:38:07 -0400189 modem->owner()));
190 DBusPropertiesMap properties =
191 properties_proxy->GetAll(MM_MODEM_INTERFACE);
192
193 modem->CreateDeviceClassic(properties);
David Rochberg81030ea2012-03-02 15:44:25 -0500194}
195
David Rochbergfa1d31d2012-03-20 10:38:07 -0400196void ModemManagerClassic::OnDeviceAdded(const string &path) {
197 AddModemClassic(path);
198}
199
200void ModemManagerClassic::OnDeviceRemoved(const string &path) {
201 RemoveModem(path);
202}
David Rochberg7cb06f62012-03-05 11:23:44 -0500203
Darin Petkov887f2982011-07-14 16:10:17 -0700204} // namespace shill