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/bind.h>
20 #include <base/stl_util.h>
21 #include <ModemManager/ModemManager.h>
22
23 #include "shill/cellular/modem.h"
24 #include "shill/control_interface.h"
25 #include "shill/error.h"
26 #include "shill/logging.h"
27
28 using base::Bind;
29 using std::string;
30 using std::shared_ptr;
31 using std::vector;
32
33 namespace shill {
34
ModemManager1(ControlInterface * control_interface,const string & service,const string & path,ModemInfo * modem_info)35 ModemManager1::ModemManager1(ControlInterface* control_interface,
36 const string& service,
37 const string& path,
38 ModemInfo* modem_info)
39 : ModemManager(control_interface,
40 service,
41 path,
42 modem_info),
43 weak_ptr_factory_(this) {}
44
~ModemManager1()45 ModemManager1::~ModemManager1() {
46 Stop();
47 }
48
Start()49 void ModemManager1::Start() {
50 LOG(INFO) << "Start watching modem manager service: " << service();
51 CHECK(!proxy_);
52 proxy_.reset(
53 control_interface()->CreateDBusObjectManagerProxy(
54 path(),
55 service(),
56 base::Bind(&ModemManager1::OnAppeared, base::Unretained(this)),
57 base::Bind(&ModemManager1::OnVanished, base::Unretained(this))));
58 proxy_->set_interfaces_added_callback(
59 Bind(&ModemManager1::OnInterfacesAddedSignal,
60 weak_ptr_factory_.GetWeakPtr()));
61 proxy_->set_interfaces_removed_callback(
62 Bind(&ModemManager1::OnInterfacesRemovedSignal,
63 weak_ptr_factory_.GetWeakPtr()));
64 }
65
Stop()66 void ModemManager1::Stop() {
67 LOG(INFO) << "Stop watching modem manager service: " << service();
68 proxy_.reset();
69 Disconnect();
70 }
71
Connect()72 void ModemManager1::Connect() {
73 ModemManager::Connect();
74 // TODO(rochberg): Make global kDBusDefaultTimeout and use it here
75 Error error;
76 proxy_->GetManagedObjects(&error,
77 Bind(&ModemManager1::OnGetManagedObjectsReply,
78 weak_ptr_factory_.GetWeakPtr()),
79 5000);
80 }
81
Disconnect()82 void ModemManager1::Disconnect() {
83 ModemManager::Disconnect();
84 }
85
AddModem1(const string & path,const InterfaceToProperties & properties)86 void ModemManager1::AddModem1(const string& path,
87 const InterfaceToProperties& properties) {
88 if (ModemExists(path)) {
89 return;
90 }
91 shared_ptr<Modem1> modem1(new Modem1(service(),
92 path,
93 modem_info(),
94 control_interface()));
95 RecordAddedModem(modem1);
96 InitModem1(modem1, properties);
97 }
98
InitModem1(shared_ptr<Modem1> modem,const InterfaceToProperties & properties)99 void ModemManager1::InitModem1(shared_ptr<Modem1> modem,
100 const InterfaceToProperties& properties) {
101 if (modem == nullptr) {
102 return;
103 }
104 modem->CreateDeviceMM1(properties);
105 }
106
107 // signal methods
108 // Also called by OnGetManagedObjectsReply
OnInterfacesAddedSignal(const string & object_path,const InterfaceToProperties & properties)109 void ModemManager1::OnInterfacesAddedSignal(
110 const string& object_path,
111 const InterfaceToProperties& properties) {
112 if (ContainsKey(properties, MM_DBUS_INTERFACE_MODEM)) {
113 AddModem1(object_path, properties);
114 } else {
115 LOG(ERROR) << "Interfaces added, but not modem interface.";
116 }
117 }
118
OnInterfacesRemovedSignal(const string & object_path,const vector<string> & interfaces)119 void ModemManager1::OnInterfacesRemovedSignal(
120 const string& object_path,
121 const vector<string>& interfaces) {
122 LOG(INFO) << "MM1: Removing interfaces from " << object_path;
123 if (find(interfaces.begin(),
124 interfaces.end(),
125 MM_DBUS_INTERFACE_MODEM) != interfaces.end()) {
126 RemoveModem(object_path);
127 } else {
128 // In theory, a modem could drop, say, 3GPP, but not CDMA. In
129 // practice, we don't expect this
130 LOG(ERROR) << "Interfaces removed, but not modem interface";
131 }
132 }
133
134 // DBusObjectManagerProxy async method call
OnGetManagedObjectsReply(const ObjectsWithProperties & objects,const Error & error)135 void ModemManager1::OnGetManagedObjectsReply(
136 const ObjectsWithProperties& objects,
137 const Error& error) {
138 if (error.IsSuccess()) {
139 ObjectsWithProperties::const_iterator m;
140 for (m = objects.begin(); m != objects.end(); ++m) {
141 OnInterfacesAddedSignal(m->first, m->second);
142 }
143 }
144 }
145
146 } // namespace shill
147