blob: 338d62d8732110f4e4818ed88dbaac2b44b494a6 [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,
Prathmesh Prabhu27526f12013-03-25 19:42:18 -070025 ModemInfo *modem_info)
Darin Petkovab565bb2011-10-06 02:55:51 -070026 : proxy_factory_(ProxyFactory::GetInstance()),
27 service_(service),
Darin Petkov887f2982011-07-14 16:10:17 -070028 path_(path),
29 watcher_id_(0),
Prathmesh Prabhu27526f12013-03-25 19:42:18 -070030 modem_info_(modem_info) {}
Darin Petkov887f2982011-07-14 16:10:17 -070031
32ModemManager::~ModemManager() {
33 Stop();
34}
35
36void ModemManager::Start() {
37 LOG(INFO) << "Start watching modem manager service: " << service_;
Eric Shienbroodc74cf9c2012-03-02 15:00:35 -050038 CHECK_EQ(0U, watcher_id_);
Darin Petkovc90fe522011-07-15 13:59:47 -070039 // TODO(petkov): Implement DBus name watching through dbus-c++.
Prathmesh Prabhu27526f12013-03-25 19:42:18 -070040 watcher_id_ = modem_info_->glib()->BusWatchName(G_BUS_TYPE_SYSTEM,
41 service_.c_str(),
42 G_BUS_NAME_WATCHER_FLAGS_NONE,
43 OnAppear,
44 OnVanish,
45 this,
46 NULL);
Darin Petkov887f2982011-07-14 16:10:17 -070047}
48
49void ModemManager::Stop() {
50 LOG(INFO) << "Stop watching modem manager service: " << service_;
51 if (watcher_id_) {
Prathmesh Prabhu27526f12013-03-25 19:42:18 -070052 modem_info_->glib()->BusUnwatchName(watcher_id_);
Darin Petkov887f2982011-07-14 16:10:17 -070053 watcher_id_ = 0;
54 }
55 Disconnect();
56}
57
58void ModemManager::Connect(const string &owner) {
David Rochberg81030ea2012-03-02 15:44:25 -050059 // Inheriting classes call this superclass method.
Darin Petkov887f2982011-07-14 16:10:17 -070060 owner_ = owner;
Darin Petkov887f2982011-07-14 16:10:17 -070061}
62
63void ModemManager::Disconnect() {
David Rochberg81030ea2012-03-02 15:44:25 -050064 // Inheriting classes call this superclass method.
Darin Petkov5c97ac52011-07-19 16:30:49 -070065 modems_.clear();
Darin Petkov887f2982011-07-14 16:10:17 -070066 owner_.clear();
Darin Petkov887f2982011-07-14 16:10:17 -070067}
68
mukesh agrawal1830fa12011-09-26 14:31:40 -070069void ModemManager::OnAppear(GDBusConnection */*connection*/,
Darin Petkov887f2982011-07-14 16:10:17 -070070 const gchar *name,
71 const gchar *name_owner,
72 gpointer user_data) {
73 LOG(INFO) << "Modem manager " << name << " appeared. Owner: " << name_owner;
74 ModemManager *manager = reinterpret_cast<ModemManager *>(user_data);
75 manager->Connect(name_owner);
76}
77
mukesh agrawal1830fa12011-09-26 14:31:40 -070078void ModemManager::OnVanish(GDBusConnection */*connection*/,
Darin Petkov887f2982011-07-14 16:10:17 -070079 const gchar *name,
80 gpointer user_data) {
81 LOG(INFO) << "Modem manager " << name << " vanished.";
82 ModemManager *manager = reinterpret_cast<ModemManager *>(user_data);
83 manager->Disconnect();
84}
85
David Rochbergfa1d31d2012-03-20 10:38:07 -040086bool ModemManager::ModemExists(const std::string &path) const {
Darin Petkov5c97ac52011-07-19 16:30:49 -070087 CHECK(!owner_.empty());
88 if (ContainsKey(modems_, path)) {
David Rochbergfa1d31d2012-03-20 10:38:07 -040089 LOG(INFO) << "ModemExists: " << path << " already exists.";
90 return true;
91 } else {
92 return false;
Darin Petkov5c97ac52011-07-19 16:30:49 -070093 }
David Rochbergfa1d31d2012-03-20 10:38:07 -040094}
95
96void ModemManager::RecordAddedModem(shared_ptr<Modem> modem) {
97 modems_[modem->path()] = modem;
Darin Petkov5c97ac52011-07-19 16:30:49 -070098}
99
Darin Petkov41c0e0a2012-01-09 16:38:53 +0100100void ModemManager::RemoveModem(const string &path) {
Darin Petkov5c97ac52011-07-19 16:30:49 -0700101 LOG(INFO) << "Remove modem: " << path;
102 CHECK(!owner_.empty());
103 modems_.erase(path);
104}
105
Darin Petkov41c0e0a2012-01-09 16:38:53 +0100106void ModemManager::OnDeviceInfoAvailable(const string &link_name) {
David Rochberg81030ea2012-03-02 15:44:25 -0500107 for (Modems::const_iterator it = modems_.begin(); it != modems_.end(); ++it) {
Darin Petkov41c0e0a2012-01-09 16:38:53 +0100108 it->second->OnDeviceInfoAvailable(link_name);
109 }
110}
111
David Rochberg81030ea2012-03-02 15:44:25 -0500112// ModemManagerClassic
Ben Chan62028b22012-11-05 11:20:02 -0800113ModemManagerClassic::ModemManagerClassic(
114 const string &service,
115 const string &path,
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700116 ModemInfo *modem_info)
Ben Chan62028b22012-11-05 11:20:02 -0800117 : ModemManager(service,
118 path,
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700119 modem_info) {}
David Rochberg81030ea2012-03-02 15:44:25 -0500120
121ModemManagerClassic::~ModemManagerClassic() {}
122
123void ModemManagerClassic::Connect(const string &supplied_owner) {
124 ModemManager::Connect(supplied_owner);
125 proxy_.reset(proxy_factory()->CreateModemManagerProxy(this, path(), owner()));
David Rochberg81030ea2012-03-02 15:44:25 -0500126 // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583).
127 vector<DBus::Path> devices = proxy_->EnumerateDevices();
David Rochbergfa1d31d2012-03-20 10:38:07 -0400128
David Rochberg81030ea2012-03-02 15:44:25 -0500129 for (vector<DBus::Path>::const_iterator it = devices.begin();
130 it != devices.end(); ++it) {
David Rochbergfa1d31d2012-03-20 10:38:07 -0400131 AddModemClassic(*it);
David Rochberg81030ea2012-03-02 15:44:25 -0500132 }
133}
134
David Rochbergfa1d31d2012-03-20 10:38:07 -0400135void ModemManagerClassic::AddModemClassic(const string &path) {
136 if (ModemExists(path)) {
137 return;
138 }
139 shared_ptr<ModemClassic> modem(new ModemClassic(owner(),
Jason Glasgowa585fc32012-06-06 11:04:09 -0400140 service(),
David Rochbergfa1d31d2012-03-20 10:38:07 -0400141 path,
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700142 modem_info()));
David Rochbergfa1d31d2012-03-20 10:38:07 -0400143 RecordAddedModem(modem);
144 InitModemClassic(modem);
145}
146
David Rochberg81030ea2012-03-02 15:44:25 -0500147void ModemManagerClassic::Disconnect() {
148 ModemManager::Disconnect();
149 proxy_.reset();
150}
151
David Rochbergfa1d31d2012-03-20 10:38:07 -0400152void ModemManagerClassic::InitModemClassic(shared_ptr<ModemClassic> modem) {
153 // TODO(rochberg): Switch to asynchronous calls (crosbug.com/17583).
154 if (modem == NULL) {
155 return;
156 }
157
158 scoped_ptr<DBusPropertiesProxyInterface> properties_proxy(
Jason Glasgow9c09e362012-04-18 15:16:29 -0400159 proxy_factory()->CreateDBusPropertiesProxy(modem->path(),
David Rochbergfa1d31d2012-03-20 10:38:07 -0400160 modem->owner()));
161 DBusPropertiesMap properties =
162 properties_proxy->GetAll(MM_MODEM_INTERFACE);
163
164 modem->CreateDeviceClassic(properties);
David Rochberg81030ea2012-03-02 15:44:25 -0500165}
166
David Rochbergfa1d31d2012-03-20 10:38:07 -0400167void ModemManagerClassic::OnDeviceAdded(const string &path) {
168 AddModemClassic(path);
169}
170
171void ModemManagerClassic::OnDeviceRemoved(const string &path) {
172 RemoveModem(path);
173}
David Rochberg7cb06f62012-03-05 11:23:44 -0500174
Darin Petkov887f2982011-07-14 16:10:17 -0700175} // namespace shill