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 #ifndef SHILL_CELLULAR_CELLULAR_CAPABILITY_H_
18 #define SHILL_CELLULAR_CELLULAR_CAPABILITY_H_
19 
20 #include <string>
21 #include <vector>
22 
23 #include <base/callback.h>
24 #include <base/macros.h>
25 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
26 
27 #include "shill/callbacks.h"
28 #include "shill/cellular/cellular.h"
29 #include "shill/metrics.h"
30 
31 namespace shill {
32 
33 class Cellular;
34 class CellularBearer;
35 class Error;
36 class ModemInfo;
37 
38 // Cellular devices instantiate subclasses of CellularCapability that
39 // handle the specific modem technologies and capabilities.
40 //
41 // The CellularCapability is directly subclassed by:
42 // *  CelllularCapabilityUniversal which handles all modems managed by
43 //    a modem manager using the the org.chromium.ModemManager1 DBUS
44 //    interface.
45 // *  CellularCapabilityClassic which handles all modems managed by a
46 //    modem manager using the older org.chromium.ModemManager DBUS
47 //    interface.  This class is further subclassed to represent CDMA
48 //    and GSM modems.
49 //
50 // Pictorially:
51 //
52 // CellularCapability
53 //       |
54 //       |-- CellularCapabilityUniversal
55 //       |            |
56 //       |            |-- CellularCapabilityUniversalCDMA
57 //       |
58 //       |-- CellularCapabilityClassic
59 //                    |
60 //                    |-- CellularCapabilityGSM
61 //                    |
62 //                    |-- CellularCapabilityCDMA
63 //
64 // TODO(armansito): Currently, 3GPP logic is handled by
65 // CellularCapabilityUniversal. Eventually CellularCapabilityUniversal will
66 // only serve as the abstract base class for ModemManager1 3GPP and CDMA
67 // capabilities.
68 class CellularCapability {
69  public:
70   static const int kTimeoutActivate;
71   static const int kTimeoutConnect;
72   static const int kTimeoutDefault;
73   static const int kTimeoutDisconnect;
74   static const int kTimeoutEnable;
75   static const int kTimeoutRegister;
76   static const int kTimeoutReset;
77   static const int kTimeoutScan;
78 
79   static const char kModemPropertyIMSI[];
80   static const char kModemPropertyState[];
81 
82   // |cellular| is the parent Cellular device.
83   CellularCapability(Cellular* cellular,
84                      ControlInterface* control_interface,
85                      ModemInfo* modem_info);
86   virtual ~CellularCapability();
87 
88   virtual std::string GetTypeString() const = 0;
89 
90   // Called when the modem manager has sent a property change notification
91   // signal.
92   virtual void OnPropertiesChanged(
93       const std::string& interface,
94       const KeyValueStore& changed_properties,
95       const std::vector<std::string>& invalidated_properties) = 0;
96 
97   // -------------------------------------------------------------------------
98   // Modem management
99   // -------------------------------------------------------------------------
100 
101   // StartModem attempts to put the modem in a state in which it is usable for
102   // creating services and establishing connections (if network conditions
103   // permit). It potentially consists of multiple non-blocking calls to the
104   // modem-manager server. After each call, control is passed back up to the
105   // main loop. Each time a reply to a non-blocking call is received, the
106   // operation advances to the next step, until either an error occurs in one of
107   // them, or all the steps have been completed, at which point StartModem() is
108   // finished.
109   virtual void StartModem(Error* error, const ResultCallback& callback) = 0;
110 
111   // StopModem disconnects and disables a modem asynchronously.  |callback| is
112   // invoked when this completes and the result is passed to the callback.
113   virtual void StopModem(Error* error, const ResultCallback& callback) = 0;
114 
115   // Resets the modem.
116   //
117   // The default implementation fails by returning kNotSupported via |error|.
118   virtual void Reset(Error* error, const ResultCallback& callback);
119 
120   // Checks to see if all proxies have been initialized.
121   virtual bool AreProxiesInitialized() const = 0;
122 
123   // -------------------------------------------------------------------------
124   // Activation
125   // -------------------------------------------------------------------------
126 
127   // Returns true if service activation is required.
128   //
129   // The default implementation returns false.
130   virtual bool IsServiceActivationRequired() const;
131 
132   // Returns true if the modem is being activated.
133   //
134   // The default implementation returns false.
135   virtual bool IsActivating() const;
136 
137   // Activates the modem.
138   //
139   // The default implementation fails by returning kNotSupported via |error|.
140   virtual void Activate(const std::string& carrier,
141                         Error* error, const ResultCallback& callback);
142 
143   // Initiates the necessary to steps to verify that the cellular service has
144   // been activated. Once these steps have been completed, the service should
145   // be marked as activated.
146   //
147   // The default implementation fails by returning kNotSupported via |error|.
148   virtual void CompleteActivation(Error* error);
149 
150   // -------------------------------------------------------------------------
151   // Network service and registration
152   // -------------------------------------------------------------------------
153 
154   // Configures the modem to support the |carrier|.
155   //
156   // The default implementation fails by returning kNotSupported via |error|.
157   virtual void SetCarrier(const std::string& carrier,
158                           Error* error,
159                           const ResultCallback& callback);
160 
161   // Asks the modem to scan for networks.
162   //
163   // The default implementation fails by returning kNotSupported via |error|.
164   //
165   // Subclasses should implement this by fetching scan results asynchronously.
166   // When the results are ready, update the kFoundNetworksProperty and send a
167   // property change notification.  Finally, callback must be invoked to inform
168   // the caller that the scan has completed.
169   //
170   // Errors are not generally reported, but on error the kFoundNetworksProperty
171   // should be cleared and a property change notification sent out.
172   //
173   // TODO(jglasgow): Refactor to reuse code by putting notification logic into
174   // Cellular or CellularCapability.
175   //
176   // TODO(jglasgow): Implement real error handling.
177   virtual void Scan(Error* error, const ResultStringmapsCallback& callback);
178 
179   // Registers on a network with |network_id|.
180   virtual void RegisterOnNetwork(const std::string& network_id,
181                                  Error* error,
182                                  const ResultCallback& callback);
183 
184   // Returns true if the modem is registered on a network, which can be a home
185   // or roaming network. It is possible that we cannot determine whether it is
186   // a home or roaming network, but we still consider the modem is registered.
187   virtual bool IsRegistered() const = 0;
188 
189   // If we are informed by means of something other than a signal indicating
190   // a registration state change that the modem has unregistered from the
191   // network, we need to update the network-type-specific capability object.
192   virtual void SetUnregistered(bool searching) = 0;
193 
194   // Invoked by the parent Cellular device when a new service is created.
195   virtual void OnServiceCreated() = 0;
196 
197   // Hook called by the Cellular device when either the Home Provider or the
198   // Serving Operator changes. Default implementation calls other hooks declared
199   // below. Overrides should chain up to this function.
200   // Note: This may be called before |CellularService| is created.
201   virtual void OnOperatorChanged();
202   virtual void UpdateServiceOLP();
203 
204   // Returns an empty string if the network technology is unknown.
205   virtual std::string GetNetworkTechnologyString() const = 0;
206 
207   virtual std::string GetRoamingStateString() const = 0;
208 
209   // Should this device allow roaming?
210   // The decision to allow roaming or not is based on the home provider as well
211   // as on the user modifiable "allow_roaming" property.
212   virtual bool AllowRoaming() = 0;
213 
214   // Returns true if the cellular device should initiate passive traffic
215   // monitoring to trigger active out-of-credit detection checks. The default
216   // implementation returns false by default.
217   virtual bool ShouldDetectOutOfCredit() const;
218 
219   // TODO(armansito): Remove this method once cromo is deprecated.
220   virtual void GetSignalQuality() = 0;
221 
222   // -------------------------------------------------------------------------
223   // Connection management
224   // -------------------------------------------------------------------------
225 
226   // Fills |properties| with properties for establishing a connection, which
227   // will be passed to Connect().
228   virtual void SetupConnectProperties(KeyValueStore* properties) = 0;
229 
230   // Connects the modem to a network based on the connection properties
231   // specified by |properties|.
232   virtual void Connect(const KeyValueStore& properties,
233                        Error* error,
234                        const ResultCallback& callback) = 0;
235 
236   // Disconnects the modem from a network.
237   virtual void Disconnect(Error* error, const ResultCallback& callback) = 0;
238 
239   // Called when a disconnect operation completes, successful or not.
240   //
241   // The default implementation does nothing.
242   virtual void DisconnectCleanup();
243 
244   // Returns a pointer to the current active bearer object or nullptr if no
245   // active bearer exists. The returned bearer object is managed by this
246   // capability object. This implementation returns nullptr by default.
247   virtual CellularBearer* GetActiveBearer() const;
248 
249   // -------------------------------------------------------------------------
250   // SIM PIN management
251   // -------------------------------------------------------------------------
252 
253   // The default implementation fails by returning kNotSupported via |error|.
254   virtual void RequirePIN(const std::string& pin,
255                           bool require,
256                           Error* error,
257                           const ResultCallback& callback);
258 
259   virtual void EnterPIN(const std::string& pin,
260                         Error* error,
261                         const ResultCallback& callback);
262 
263   virtual void UnblockPIN(const std::string& unblock_code,
264                           const std::string& pin,
265                           Error* error,
266                           const ResultCallback& callback);
267 
268   virtual void ChangePIN(const std::string& old_pin,
269                          const std::string& new_pin,
270                          Error* error,
271                          const ResultCallback& callback);
272 
273   // -------------------------------------------------------------------------
274 
cellular()275   Cellular* cellular() const { return cellular_; }
control_interface()276   ControlInterface* control_interface() const { return control_interface_; }
modem_info()277   ModemInfo* modem_info() const { return modem_info_; }
278 
279  protected:
280   // Releases all proxies held by the object. This is most useful during unit
281   // tests.
282   virtual void ReleaseProxies() = 0;
283 
284   static void OnUnsupportedOperation(const char* operation, Error* error);
285 
286   // Accessor for subclasses to read the 'allow roaming' property.
allow_roaming_property()287   bool allow_roaming_property() const {
288     return cellular_->allow_roaming_property();
289   }
290 
291  private:
292   friend class CellularCapabilityGSMTest;
293   friend class CellularCapabilityTest;
294   friend class CellularCapabilityUniversalTest;
295   friend class CellularCapabilityUniversalCDMATest;
296   friend class CellularTest;
297   FRIEND_TEST(CellularCapabilityTest, AllowRoaming);
298   FRIEND_TEST(CellularCapabilityUniversalMainTest, UpdateActiveBearer);
299   FRIEND_TEST(CellularTest, Connect);
300   FRIEND_TEST(CellularTest, TearDown);
301 
302   Cellular* cellular_;
303   ControlInterface* control_interface_;
304   ModemInfo* modem_info_;
305 
306   DISALLOW_COPY_AND_ASSIGN(CellularCapability);
307 };
308 
309 }  // namespace shill
310 
311 #endif  // SHILL_CELLULAR_CELLULAR_CAPABILITY_H_
312