blob: 8db37bef96e265f5e1974e93524eb1406e61f677 [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"
Ben Chan66174a12014-01-08 21:27:00 -080011#include "shill/dbus_manager.h"
Eric Shienbrood9a245532012-03-07 14:20:39 -050012#include "shill/error.h"
Christopher Wileyb691efd2012-08-09 13:51:51 -070013#include "shill/logging.h"
Ben Chan66174a12014-01-08 21:27:00 -080014#include "shill/manager.h"
Darin Petkov5c97ac52011-07-19 16:30:49 -070015#include "shill/modem.h"
Darin Petkovc90fe522011-07-15 13:59:47 -070016#include "shill/modem_manager_proxy.h"
17#include "shill/proxy_factory.h"
18
Darin Petkov887f2982011-07-14 16:10:17 -070019using std::string;
Darin Petkov5c97ac52011-07-19 16:30:49 -070020using std::tr1::shared_ptr;
21using std::vector;
Darin Petkov887f2982011-07-14 16:10:17 -070022
23namespace shill {
Ben Chan5c853ef2012-10-05 00:05:37 -070024
Darin Petkov887f2982011-07-14 16:10:17 -070025ModemManager::ModemManager(const string &service,
26 const string &path,
Prathmesh Prabhu27526f12013-03-25 19:42:18 -070027 ModemInfo *modem_info)
Darin Petkovab565bb2011-10-06 02:55:51 -070028 : proxy_factory_(ProxyFactory::GetInstance()),
29 service_(service),
Darin Petkov887f2982011-07-14 16:10:17 -070030 path_(path),
Prathmesh Prabhu27526f12013-03-25 19:42:18 -070031 modem_info_(modem_info) {}
Darin Petkov887f2982011-07-14 16:10:17 -070032
33ModemManager::~ModemManager() {
34 Stop();
35}
36
37void ModemManager::Start() {
38 LOG(INFO) << "Start watching modem manager service: " << service_;
Ben Chan66174a12014-01-08 21:27:00 -080039 CHECK(!name_watcher_);
40 name_watcher_.reset(modem_info_->manager()->dbus_manager()->CreateNameWatcher(
41 service_,
42 base::Bind(&ModemManager::OnAppear, base::Unretained(this)),
43 base::Bind(&ModemManager::OnVanish, base::Unretained(this))));
Darin Petkov887f2982011-07-14 16:10:17 -070044}
45
46void ModemManager::Stop() {
47 LOG(INFO) << "Stop watching modem manager service: " << service_;
Ben Chan66174a12014-01-08 21:27:00 -080048 name_watcher_.reset();
Darin Petkov887f2982011-07-14 16:10:17 -070049 Disconnect();
50}
51
52void ModemManager::Connect(const string &owner) {
David Rochberg81030ea2012-03-02 15:44:25 -050053 // Inheriting classes call this superclass method.
Darin Petkov887f2982011-07-14 16:10:17 -070054 owner_ = owner;
Darin Petkov887f2982011-07-14 16:10:17 -070055}
56
57void ModemManager::Disconnect() {
David Rochberg81030ea2012-03-02 15:44:25 -050058 // Inheriting classes call this superclass method.
Darin Petkov5c97ac52011-07-19 16:30:49 -070059 modems_.clear();
Darin Petkov887f2982011-07-14 16:10:17 -070060 owner_.clear();
Darin Petkov887f2982011-07-14 16:10:17 -070061}
62
Ben Chan66174a12014-01-08 21:27:00 -080063void ModemManager::OnAppear(const string &name, const string &owner) {
64 LOG(INFO) << "Modem manager " << name << " appeared. Owner: " << owner;
65 Connect(owner);
Darin Petkov887f2982011-07-14 16:10:17 -070066}
67
Ben Chan66174a12014-01-08 21:27:00 -080068void ModemManager::OnVanish(const string &name) {
Darin Petkov887f2982011-07-14 16:10:17 -070069 LOG(INFO) << "Modem manager " << name << " vanished.";
Ben Chan66174a12014-01-08 21:27:00 -080070 Disconnect();
Darin Petkov887f2982011-07-14 16:10:17 -070071}
72
David Rochbergfa1d31d2012-03-20 10:38:07 -040073bool ModemManager::ModemExists(const std::string &path) const {
Darin Petkov5c97ac52011-07-19 16:30:49 -070074 CHECK(!owner_.empty());
75 if (ContainsKey(modems_, path)) {
David Rochbergfa1d31d2012-03-20 10:38:07 -040076 LOG(INFO) << "ModemExists: " << path << " already exists.";
77 return true;
78 } else {
79 return false;
Darin Petkov5c97ac52011-07-19 16:30:49 -070080 }
David Rochbergfa1d31d2012-03-20 10:38:07 -040081}
82
83void ModemManager::RecordAddedModem(shared_ptr<Modem> modem) {
84 modems_[modem->path()] = modem;
Darin Petkov5c97ac52011-07-19 16:30:49 -070085}
86
Darin Petkov41c0e0a2012-01-09 16:38:53 +010087void ModemManager::RemoveModem(const string &path) {
Darin Petkov5c97ac52011-07-19 16:30:49 -070088 LOG(INFO) << "Remove modem: " << path;
89 CHECK(!owner_.empty());
90 modems_.erase(path);
91}
92
Darin Petkov41c0e0a2012-01-09 16:38:53 +010093void ModemManager::OnDeviceInfoAvailable(const string &link_name) {
David Rochberg81030ea2012-03-02 15:44:25 -050094 for (Modems::const_iterator it = modems_.begin(); it != modems_.end(); ++it) {
Darin Petkov41c0e0a2012-01-09 16:38:53 +010095 it->second->OnDeviceInfoAvailable(link_name);
96 }
97}
98
David Rochberg81030ea2012-03-02 15:44:25 -050099// ModemManagerClassic
Ben Chan62028b22012-11-05 11:20:02 -0800100ModemManagerClassic::ModemManagerClassic(
101 const string &service,
102 const string &path,
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700103 ModemInfo *modem_info)
Ben Chan62028b22012-11-05 11:20:02 -0800104 : ModemManager(service,
105 path,
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700106 modem_info) {}
David Rochberg81030ea2012-03-02 15:44:25 -0500107
108ModemManagerClassic::~ModemManagerClassic() {}
109
110void ModemManagerClassic::Connect(const string &supplied_owner) {
111 ModemManager::Connect(supplied_owner);
112 proxy_.reset(proxy_factory()->CreateModemManagerProxy(this, path(), owner()));
Paul Stewartee6b3d72013-07-12 16:07:51 -0700113 // TODO(petkov): Switch to asynchronous calls (crbug.com/200687).
David Rochberg81030ea2012-03-02 15:44:25 -0500114 vector<DBus::Path> devices = proxy_->EnumerateDevices();
David Rochbergfa1d31d2012-03-20 10:38:07 -0400115
David Rochberg81030ea2012-03-02 15:44:25 -0500116 for (vector<DBus::Path>::const_iterator it = devices.begin();
117 it != devices.end(); ++it) {
David Rochbergfa1d31d2012-03-20 10:38:07 -0400118 AddModemClassic(*it);
David Rochberg81030ea2012-03-02 15:44:25 -0500119 }
120}
121
David Rochbergfa1d31d2012-03-20 10:38:07 -0400122void ModemManagerClassic::AddModemClassic(const string &path) {
123 if (ModemExists(path)) {
124 return;
125 }
126 shared_ptr<ModemClassic> modem(new ModemClassic(owner(),
Jason Glasgowa585fc32012-06-06 11:04:09 -0400127 service(),
David Rochbergfa1d31d2012-03-20 10:38:07 -0400128 path,
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700129 modem_info()));
David Rochbergfa1d31d2012-03-20 10:38:07 -0400130 RecordAddedModem(modem);
131 InitModemClassic(modem);
132}
133
David Rochberg81030ea2012-03-02 15:44:25 -0500134void ModemManagerClassic::Disconnect() {
135 ModemManager::Disconnect();
136 proxy_.reset();
137}
138
David Rochbergfa1d31d2012-03-20 10:38:07 -0400139void ModemManagerClassic::InitModemClassic(shared_ptr<ModemClassic> modem) {
Paul Stewartee6b3d72013-07-12 16:07:51 -0700140 // TODO(rochberg): Switch to asynchronous calls (crbug.com/200687).
David Rochbergfa1d31d2012-03-20 10:38:07 -0400141 if (modem == NULL) {
142 return;
143 }
144
145 scoped_ptr<DBusPropertiesProxyInterface> properties_proxy(
Jason Glasgow9c09e362012-04-18 15:16:29 -0400146 proxy_factory()->CreateDBusPropertiesProxy(modem->path(),
David Rochbergfa1d31d2012-03-20 10:38:07 -0400147 modem->owner()));
148 DBusPropertiesMap properties =
149 properties_proxy->GetAll(MM_MODEM_INTERFACE);
150
151 modem->CreateDeviceClassic(properties);
David Rochberg81030ea2012-03-02 15:44:25 -0500152}
153
David Rochbergfa1d31d2012-03-20 10:38:07 -0400154void ModemManagerClassic::OnDeviceAdded(const string &path) {
155 AddModemClassic(path);
156}
157
158void ModemManagerClassic::OnDeviceRemoved(const string &path) {
159 RemoveModem(path);
160}
David Rochberg7cb06f62012-03-05 11:23:44 -0500161
Darin Petkov887f2982011-07-14 16:10:17 -0700162} // namespace shill