Home | History | Annotate | Download | only in cellular
      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