blob: 2e151cd02a7595e1e0ea45641e8409511575a1d1 [file] [log] [blame]
Darin Petkov887f2982011-07-14 16:10:17 -07001// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2// 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
7#include <base/logging.h>
Darin Petkov5c97ac52011-07-19 16:30:49 -07008#include <base/stl_util-inl.h>
Darin Petkov887f2982011-07-14 16:10:17 -07009
Darin Petkov5c97ac52011-07-19 16:30:49 -070010#include "shill/modem.h"
Darin Petkovc90fe522011-07-15 13:59:47 -070011#include "shill/modem_manager_proxy.h"
12#include "shill/proxy_factory.h"
13
Darin Petkov887f2982011-07-14 16:10:17 -070014using std::string;
Darin Petkov5c97ac52011-07-19 16:30:49 -070015using std::tr1::shared_ptr;
16using std::vector;
Darin Petkov887f2982011-07-14 16:10:17 -070017
18namespace shill {
19
20ModemManager::ModemManager(const string &service,
21 const string &path,
22 ControlInterface *control_interface,
23 EventDispatcher *dispatcher,
24 Manager *manager,
25 GLib *glib)
26 : service_(service),
27 path_(path),
28 watcher_id_(0),
29 control_interface_(control_interface),
30 dispatcher_(dispatcher),
31 glib_(glib) {}
32
33ModemManager::~ModemManager() {
34 Stop();
35}
36
37void ModemManager::Start() {
38 LOG(INFO) << "Start watching modem manager service: " << service_;
39 CHECK_EQ(0, watcher_id_);
Darin Petkovc90fe522011-07-15 13:59:47 -070040 // TODO(petkov): Implement DBus name watching through dbus-c++.
Darin Petkov887f2982011-07-14 16:10:17 -070041 watcher_id_ = glib_->BusWatchName(G_BUS_TYPE_SYSTEM,
42 service_.c_str(),
43 G_BUS_NAME_WATCHER_FLAGS_NONE,
44 OnAppear,
45 OnVanish,
46 this,
47 NULL);
48}
49
50void ModemManager::Stop() {
51 LOG(INFO) << "Stop watching modem manager service: " << service_;
52 if (watcher_id_) {
53 glib_->BusUnwatchName(watcher_id_);
54 watcher_id_ = 0;
55 }
56 Disconnect();
57}
58
59void ModemManager::Connect(const string &owner) {
60 owner_ = owner;
Darin Petkovc90fe522011-07-15 13:59:47 -070061 proxy_.reset(
62 ProxyFactory::factory()->CreateModemManagerProxy(this, path_, owner_));
Darin Petkov5c97ac52011-07-19 16:30:49 -070063
64 // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583).
65 vector<DBus::Path> devices = proxy_->EnumerateDevices();
66 for (vector<DBus::Path>::const_iterator it = devices.begin();
67 it != devices.end(); ++it) {
68 AddModem(*it);
69 }
Darin Petkov887f2982011-07-14 16:10:17 -070070}
71
72void ModemManager::Disconnect() {
Darin Petkov5c97ac52011-07-19 16:30:49 -070073 modems_.clear();
Darin Petkov887f2982011-07-14 16:10:17 -070074 owner_.clear();
Darin Petkovc90fe522011-07-15 13:59:47 -070075 proxy_.reset();
Darin Petkov887f2982011-07-14 16:10:17 -070076}
77
78void ModemManager::OnAppear(GDBusConnection *connection,
79 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
87void ModemManager::OnVanish(GDBusConnection *connection,
88 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
Darin Petkov5c97ac52011-07-19 16:30:49 -070095void ModemManager::AddModem(const std::string &path) {
96 LOG(INFO) << "Add modem: " << path;
97 CHECK(!owner_.empty());
98 if (ContainsKey(modems_, path)) {
99 LOG(INFO) << "Modem already exists; ignored.";
100 return;
101 }
102 shared_ptr<Modem> modem(new Modem(owner_,
103 path,
104 control_interface_,
105 dispatcher_,
106 manager_));
107 modems_[path] = modem;
108}
109
110void ModemManager::RemoveModem(const std::string &path) {
111 LOG(INFO) << "Remove modem: " << path;
112 CHECK(!owner_.empty());
113 modems_.erase(path);
114}
115
Darin Petkov887f2982011-07-14 16:10:17 -0700116} // namespace shill