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