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 29using std::string; 30using std::shared_ptr; 31using std::vector; 32 33namespace shill { 34 35ModemManager::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 45ModemManager::~ModemManager() {} 46 47void ModemManager::Connect() { 48 // Inheriting classes call this superclass method. 49 service_connected_ = true; 50} 51 52void ModemManager::Disconnect() { 53 // Inheriting classes call this superclass method. 54 modems_.clear(); 55 service_connected_ = false; 56} 57 58void ModemManager::OnAppeared() { 59 LOG(INFO) << "Modem manager " << service_ << " appeared."; 60 Connect(); 61} 62 63void ModemManager::OnVanished() { 64 LOG(INFO) << "Modem manager " << service_ << " vanished."; 65 Disconnect(); 66} 67 68bool 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 78void ModemManager::RecordAddedModem(shared_ptr<Modem> modem) { 79 modems_[modem->path()] = modem; 80} 81 82void ModemManager::RemoveModem(const string& path) { 83 LOG(INFO) << "Remove modem: " << path; 84 CHECK(service_connected_); 85 modems_.erase(path); 86} 87 88void 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 95ModemManagerClassic::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 102ModemManagerClassic::~ModemManagerClassic() { 103 Stop(); 104} 105 106void 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 119void ModemManagerClassic::Stop() { 120 LOG(INFO) << "Stop watching modem manager service: " << service(); 121 proxy_.reset(); 122 Disconnect(); 123} 124 125void 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 136void 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 148void ModemManagerClassic::Disconnect() { 149 ModemManager::Disconnect(); 150} 151 152void 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 167void ModemManagerClassic::OnDeviceAdded(const string& path) { 168 AddModemClassic(path); 169} 170 171void ModemManagerClassic::OnDeviceRemoved(const string& path) { 172 RemoveModem(path); 173} 174 175} // namespace shill 176