1 //
2 // Copyright (C) 2012 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "shill/cellular/modem_manager.h"
18
19 #include <base/stl_util.h>
20 #include <mm/mm-modem.h>
21
22 #include "shill/cellular/modem.h"
23 #include "shill/cellular/modem_manager_proxy_interface.h"
24 #include "shill/control_interface.h"
25 #include "shill/error.h"
26 #include "shill/logging.h"
27 #include "shill/manager.h"
28
29 using std::string;
30 using std::shared_ptr;
31 using std::vector;
32
33 namespace shill {
34
ModemManager(ControlInterface * control_interface,const string & service,const string & path,ModemInfo * modem_info)35 ModemManager::ModemManager(ControlInterface* control_interface,
36 const string& service,
37 const string& path,
38 ModemInfo* modem_info)
39 : control_interface_(control_interface),
40 service_(service),
41 path_(path),
42 service_connected_(false),
43 modem_info_(modem_info) {}
44
~ModemManager()45 ModemManager::~ModemManager() {}
46
Connect()47 void ModemManager::Connect() {
48 // Inheriting classes call this superclass method.
49 service_connected_ = true;
50 }
51
Disconnect()52 void ModemManager::Disconnect() {
53 // Inheriting classes call this superclass method.
54 modems_.clear();
55 service_connected_ = false;
56 }
57
OnAppeared()58 void ModemManager::OnAppeared() {
59 LOG(INFO) << "Modem manager " << service_ << " appeared.";
60 Connect();
61 }
62
OnVanished()63 void ModemManager::OnVanished() {
64 LOG(INFO) << "Modem manager " << service_ << " vanished.";
65 Disconnect();
66 }
67
ModemExists(const std::string & path) const68 bool ModemManager::ModemExists(const std::string& path) const {
69 CHECK(service_connected_);
70 if (ContainsKey(modems_, path)) {
71 LOG(INFO) << "ModemExists: " << path << " already exists.";
72 return true;
73 } else {
74 return false;
75 }
76 }
77
RecordAddedModem(shared_ptr<Modem> modem)78 void ModemManager::RecordAddedModem(shared_ptr<Modem> modem) {
79 modems_[modem->path()] = modem;
80 }
81
RemoveModem(const string & path)82 void ModemManager::RemoveModem(const string& path) {
83 LOG(INFO) << "Remove modem: " << path;
84 CHECK(service_connected_);
85 modems_.erase(path);
86 }
87
OnDeviceInfoAvailable(const string & link_name)88 void ModemManager::OnDeviceInfoAvailable(const string& link_name) {
89 for (Modems::const_iterator it = modems_.begin(); it != modems_.end(); ++it) {
90 it->second->OnDeviceInfoAvailable(link_name);
91 }
92 }
93
94 // ModemManagerClassic
ModemManagerClassic(ControlInterface * control_interface,const string & service,const string & path,ModemInfo * modem_info)95 ModemManagerClassic::ModemManagerClassic(
96 ControlInterface* control_interface,
97 const string& service,
98 const string& path,
99 ModemInfo* modem_info)
100 : ModemManager(control_interface, service, path, modem_info) {}
101
~ModemManagerClassic()102 ModemManagerClassic::~ModemManagerClassic() {
103 Stop();
104 }
105
Start()106 void ModemManagerClassic::Start() {
107 LOG(INFO) << "Start watching modem manager service: " << service();
108 CHECK(!proxy_);
109 proxy_.reset(
110 control_interface()->CreateModemManagerProxy(
111 this,
112 path(),
113 service(),
114 base::Bind(&ModemManagerClassic::OnAppeared, base::Unretained(this)),
115 base::Bind(&ModemManagerClassic::OnVanished,
116 base::Unretained(this))));
117 }
118
Stop()119 void ModemManagerClassic::Stop() {
120 LOG(INFO) << "Stop watching modem manager service: " << service();
121 proxy_.reset();
122 Disconnect();
123 }
124
Connect()125 void ModemManagerClassic::Connect() {
126 ModemManager::Connect();
127 // TODO(petkov): Switch to asynchronous calls (crbug.com/200687).
128 vector<string> devices = proxy_->EnumerateDevices();
129
130 for (vector<string>::const_iterator it = devices.begin();
131 it != devices.end(); ++it) {
132 AddModemClassic(*it);
133 }
134 }
135
AddModemClassic(const string & path)136 void ModemManagerClassic::AddModemClassic(const string& path) {
137 if (ModemExists(path)) {
138 return;
139 }
140 shared_ptr<ModemClassic> modem(new ModemClassic(service(),
141 path,
142 modem_info(),
143 control_interface()));
144 RecordAddedModem(modem);
145 InitModemClassic(modem);
146 }
147
Disconnect()148 void ModemManagerClassic::Disconnect() {
149 ModemManager::Disconnect();
150 }
151
InitModemClassic(shared_ptr<ModemClassic> modem)152 void ModemManagerClassic::InitModemClassic(shared_ptr<ModemClassic> modem) {
153 // TODO(rochberg): Switch to asynchronous calls (crbug.com/200687).
154 if (modem == nullptr) {
155 return;
156 }
157
158 std::unique_ptr<DBusPropertiesProxyInterface> properties_proxy(
159 control_interface()->CreateDBusPropertiesProxy(modem->path(),
160 modem->service()));
161 KeyValueStore properties =
162 properties_proxy->GetAll(MM_MODEM_INTERFACE);
163
164 modem->CreateDeviceClassic(properties);
165 }
166
OnDeviceAdded(const string & path)167 void ModemManagerClassic::OnDeviceAdded(const string& path) {
168 AddModemClassic(path);
169 }
170
OnDeviceRemoved(const string & path)171 void ModemManagerClassic::OnDeviceRemoved(const string& path) {
172 RemoveModem(path);
173 }
174
175 } // namespace shill
176