1 //
2 // Copyright (C) 2015 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/dbus/chromeos_modem_gsm_network_proxy.h"
18 
19 #include <memory>
20 
21 #if defined(__ANDROID__)
22 #include <dbus/service_constants.h>
23 #else
24 #include <chromeos/dbus/service_constants.h>
25 #endif  // __ANDROID__
26 
27 #include "shill/cellular/cellular_error.h"
28 #include "shill/error.h"
29 #include "shill/logging.h"
30 
31 using std::string;
32 
33 namespace shill {
34 
35 namespace Logging {
36 static auto kModuleLogScope = ScopeLogger::kDBus;
ObjectID(const dbus::ObjectPath * p)37 static string ObjectID(const dbus::ObjectPath* p) { return p->value(); }
38 }  // namespace Logging
39 
40 // static.
41 const char ChromeosModemGSMNetworkProxy::kPropertyAccessTechnology[] =
42     "AccessTechnology";
43 
PropertySet(dbus::ObjectProxy * object_proxy,const std::string & interface_name,const PropertyChangedCallback & callback)44 ChromeosModemGSMNetworkProxy::PropertySet::PropertySet(
45     dbus::ObjectProxy* object_proxy,
46     const std::string& interface_name,
47     const PropertyChangedCallback& callback)
48     : dbus::PropertySet(object_proxy, interface_name, callback) {
49   RegisterProperty(kPropertyAccessTechnology, &access_technology);
50 }
51 
ChromeosModemGSMNetworkProxy(const scoped_refptr<dbus::Bus> & bus,const string & path,const string & service)52 ChromeosModemGSMNetworkProxy::ChromeosModemGSMNetworkProxy(
53     const scoped_refptr<dbus::Bus>& bus,
54     const string& path,
55     const string& service)
56     : proxy_(
57         new org::freedesktop::ModemManager::Modem::Gsm::NetworkProxy(
58             bus, service, dbus::ObjectPath(path))) {
59   // Register signal handlers.
60   proxy_->RegisterSignalQualitySignalHandler(
61       base::Bind(&ChromeosModemGSMNetworkProxy::SignalQuality,
62                  weak_factory_.GetWeakPtr()),
63       base::Bind(&ChromeosModemGSMNetworkProxy::OnSignalConnected,
64                  weak_factory_.GetWeakPtr()));
65   proxy_->RegisterRegistrationInfoSignalHandler(
66       base::Bind(&ChromeosModemGSMNetworkProxy::RegistrationInfo,
67                  weak_factory_.GetWeakPtr()),
68       base::Bind(&ChromeosModemGSMNetworkProxy::OnSignalConnected,
69                  weak_factory_.GetWeakPtr()));
70   proxy_->RegisterNetworkModeSignalHandler(
71       base::Bind(&ChromeosModemGSMNetworkProxy::NetworkMode,
72                  weak_factory_.GetWeakPtr()),
73       base::Bind(&ChromeosModemGSMNetworkProxy::OnSignalConnected,
74                  weak_factory_.GetWeakPtr()));
75 
76   // Register properties.
77   properties_.reset(
78       new PropertySet(
79           proxy_->GetObjectProxy(),
80           cromo::kModemGsmNetworkInterface,
81           base::Bind(&ChromeosModemGSMNetworkProxy::OnPropertyChanged,
82                      weak_factory_.GetWeakPtr())));
83 
84   // Connect property signals and initialize cached values. Based on
85   // recommendations from src/dbus/property.h.
86   properties_->ConnectSignals();
87   properties_->GetAll();
88 }
89 
~ChromeosModemGSMNetworkProxy()90 ChromeosModemGSMNetworkProxy::~ChromeosModemGSMNetworkProxy() {}
91 
GetRegistrationInfo(Error * error,const RegistrationInfoCallback & callback,int timeout)92 void ChromeosModemGSMNetworkProxy::GetRegistrationInfo(
93     Error* error,
94     const RegistrationInfoCallback& callback,
95     int timeout) {
96   SLOG(&proxy_->GetObjectPath(), 2) << __func__;
97   proxy_->GetRegistrationInfoAsync(
98       base::Bind(&ChromeosModemGSMNetworkProxy::OnGetRegistrationInfoSuccess,
99                  weak_factory_.GetWeakPtr(),
100                  callback),
101       base::Bind(&ChromeosModemGSMNetworkProxy::OnGetRegistrationInfoFailure,
102                  weak_factory_.GetWeakPtr(),
103                  callback));
104 }
105 
GetSignalQuality(Error * error,const SignalQualityCallback & callback,int timeout)106 void ChromeosModemGSMNetworkProxy::GetSignalQuality(
107     Error* error,
108     const SignalQualityCallback& callback,
109     int timeout) {
110   SLOG(&proxy_->GetObjectPath(), 2) << __func__;
111   proxy_->GetSignalQualityAsync(
112       base::Bind(&ChromeosModemGSMNetworkProxy::OnGetSignalQualitySuccess,
113                  weak_factory_.GetWeakPtr(),
114                  callback),
115       base::Bind(&ChromeosModemGSMNetworkProxy::OnGetSignalQualityFailure,
116                  weak_factory_.GetWeakPtr(),
117                  callback));
118 }
119 
Register(const string & network_id,Error * error,const ResultCallback & callback,int timeout)120 void ChromeosModemGSMNetworkProxy::Register(const string& network_id,
121                                             Error* error,
122                                             const ResultCallback& callback,
123                                             int timeout) {
124   SLOG(&proxy_->GetObjectPath(), 2) << __func__ << ": " << network_id;
125   proxy_->RegisterAsync(
126       network_id,
127       base::Bind(&ChromeosModemGSMNetworkProxy::OnRegisterSuccess,
128                  weak_factory_.GetWeakPtr(),
129                  callback),
130       base::Bind(&ChromeosModemGSMNetworkProxy::OnRegisterFailure,
131                  weak_factory_.GetWeakPtr(),
132                  callback));
133 }
134 
Scan(Error * error,const ScanResultsCallback & callback,int timeout)135 void ChromeosModemGSMNetworkProxy::Scan(Error* error,
136                                         const ScanResultsCallback& callback,
137                                         int timeout) {
138   SLOG(&proxy_->GetObjectPath(), 2) << __func__;
139   proxy_->ScanAsync(
140       base::Bind(&ChromeosModemGSMNetworkProxy::OnScanSuccess,
141                  weak_factory_.GetWeakPtr(),
142                  callback),
143       base::Bind(&ChromeosModemGSMNetworkProxy::OnScanFailure,
144                  weak_factory_.GetWeakPtr(),
145                  callback));
146 }
147 
AccessTechnology()148 uint32_t ChromeosModemGSMNetworkProxy::AccessTechnology() {
149   SLOG(&proxy_->GetObjectPath(), 2) << __func__;
150   if (!properties_->access_technology.GetAndBlock()) {
151     LOG(ERROR) << "Failed to get AccessTechnology";
152     return 0;
153   }
154   return properties_->access_technology.value();
155 }
156 
SignalQuality(uint32_t quality)157 void ChromeosModemGSMNetworkProxy::SignalQuality(uint32_t quality) {
158   SLOG(&proxy_->GetObjectPath(), 2) << __func__ << "(" << quality << ")";
159   if (signal_quality_callback_.is_null()) {
160     return;
161   }
162   signal_quality_callback_.Run(quality);
163 }
164 
RegistrationInfo(uint32_t status,const string & operator_code,const string & operator_name)165 void ChromeosModemGSMNetworkProxy::RegistrationInfo(
166     uint32_t status, const string& operator_code, const string& operator_name) {
167   SLOG(&proxy_->GetObjectPath(), 2) << __func__ << "(" << status << ", "
168       << operator_code << ", " << operator_name << ")";
169   if (registration_info_callback_.is_null()) {
170     return;
171   }
172   registration_info_callback_.Run(status, operator_code, operator_name);
173 }
174 
NetworkMode(uint32_t mode)175 void ChromeosModemGSMNetworkProxy::NetworkMode(uint32_t mode) {
176   SLOG(&proxy_->GetObjectPath(), 2) << __func__ << "(" << mode << ")";
177   if (network_mode_callback_.is_null()) {
178     return;
179   }
180   network_mode_callback_.Run(mode);
181 }
182 
OnRegisterSuccess(const ResultCallback & callback)183 void ChromeosModemGSMNetworkProxy::OnRegisterSuccess(
184     const ResultCallback& callback) {
185   SLOG(&proxy_->GetObjectPath(), 2) << __func__;
186   callback.Run(Error());
187 }
188 
OnRegisterFailure(const ResultCallback & callback,brillo::Error * dbus_error)189 void ChromeosModemGSMNetworkProxy::OnRegisterFailure(
190     const ResultCallback& callback, brillo::Error* dbus_error) {
191   SLOG(&proxy_->GetObjectPath(), 2) << __func__;
192   Error error;
193   CellularError::FromChromeosDBusError(dbus_error, &error);
194   callback.Run(error);
195 }
196 
OnGetRegistrationInfoSuccess(const RegistrationInfoCallback & callback,const GSMRegistrationInfo & info)197 void ChromeosModemGSMNetworkProxy::OnGetRegistrationInfoSuccess(
198     const RegistrationInfoCallback& callback,
199     const GSMRegistrationInfo& info) {
200   SLOG(&proxy_->GetObjectPath(), 2) << __func__;
201   callback.Run(
202       std::get<0>(info), std::get<1>(info), std::get<2>(info), Error());
203 }
204 
OnGetRegistrationInfoFailure(const RegistrationInfoCallback & callback,brillo::Error * dbus_error)205 void ChromeosModemGSMNetworkProxy::OnGetRegistrationInfoFailure(
206     const RegistrationInfoCallback& callback,
207     brillo::Error* dbus_error) {
208   SLOG(&proxy_->GetObjectPath(), 2) << __func__;
209   Error error;
210   CellularError::FromChromeosDBusError(dbus_error, &error);
211   callback.Run(0, "", "", error);
212 }
213 
OnGetSignalQualitySuccess(const SignalQualityCallback & callback,uint32_t quality)214 void ChromeosModemGSMNetworkProxy::OnGetSignalQualitySuccess(
215     const SignalQualityCallback& callback, uint32_t quality) {
216   SLOG(&proxy_->GetObjectPath(), 2) << __func__ << "(" << quality << ")";
217   callback.Run(quality, Error());
218 }
219 
OnGetSignalQualityFailure(const SignalQualityCallback & callback,brillo::Error * dbus_error)220 void ChromeosModemGSMNetworkProxy::OnGetSignalQualityFailure(
221     const SignalQualityCallback& callback, brillo::Error* dbus_error) {
222   SLOG(&proxy_->GetObjectPath(), 2) << __func__;
223   Error error;
224   CellularError::FromChromeosDBusError(dbus_error, &error);
225   callback.Run(0, error);
226 }
227 
OnScanSuccess(const ScanResultsCallback & callback,const GSMScanResults & results)228 void ChromeosModemGSMNetworkProxy::OnScanSuccess(
229     const ScanResultsCallback& callback, const GSMScanResults& results) {
230   SLOG(&proxy_->GetObjectPath(), 2) << __func__;
231   callback.Run(results, Error());
232 }
233 
OnScanFailure(const ScanResultsCallback & callback,brillo::Error * dbus_error)234 void ChromeosModemGSMNetworkProxy::OnScanFailure(
235     const ScanResultsCallback& callback, brillo::Error* dbus_error) {
236   SLOG(&proxy_->GetObjectPath(), 2) << __func__;
237   Error error;
238   CellularError::FromChromeosDBusError(dbus_error, &error);
239   callback.Run(GSMScanResults(), error);
240 }
241 
OnSignalConnected(const string & interface_name,const string & signal_name,bool success)242 void ChromeosModemGSMNetworkProxy::OnSignalConnected(
243     const string& interface_name, const string& signal_name, bool success) {
244   SLOG(&proxy_->GetObjectPath(), 2) << __func__
245       << "interface: " << interface_name
246              << " signal: " << signal_name << "success: " << success;
247   if (!success) {
248     LOG(ERROR) << "Failed to connect signal " << signal_name
249         << " to interface " << interface_name;
250   }
251 }
252 
OnPropertyChanged(const string & property_name)253 void ChromeosModemGSMNetworkProxy::OnPropertyChanged(
254     const string& property_name) {
255   SLOG(&proxy_->GetObjectPath(), 2) << __func__ << ": " << property_name;
256 }
257 
258 }  // namespace shill
259