1 // Copyright 2015 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef BUFFET_SHILL_CLIENT_H_
16 #define BUFFET_SHILL_CLIENT_H_
17 
18 #include <map>
19 #include <set>
20 #include <string>
21 #include <vector>
22 
23 #include <base/callback.h>
24 #include <base/cancelable_callback.h>
25 #include <base/macros.h>
26 #include <base/memory/ref_counted.h>
27 #include <base/memory/weak_ptr.h>
28 #include <dbus/bus.h>
29 #include <shill/dbus-proxies.h>
30 #include <weave/provider/network.h>
31 #include <weave/provider/wifi.h>
32 
33 namespace buffet {
34 
35 class ApManagerClient;
36 
37 class ShillClient final : public weave::provider::Network,
38                           public weave::provider::Wifi {
39  public:
40   ShillClient(const scoped_refptr<dbus::Bus>& bus,
41               const std::set<std::string>& device_whitelist,
42               bool disable_xmpp);
43   ~ShillClient();
44 
45   // NetworkProvider implementation.
46   void AddConnectionChangedCallback(
47       const ConnectionChangedCallback& listener) override;
48   State GetConnectionState() const override;
49   void OpenSslSocket(const std::string& host,
50                      uint16_t port,
51                      const OpenSslSocketCallback& callback) override;
52 
53   // WifiProvider implementation.
54   void Connect(const std::string& ssid,
55                const std::string& passphrase,
56                const weave::DoneCallback& callback) override;
57   void StartAccessPoint(const std::string& ssid) override;
58   void StopAccessPoint() override;
IsWifi24Supported()59   bool IsWifi24Supported() const override { return true; }
60   // TODO(avakulenko): See if we can get appropriate information from Shill
61   // regarding 5.0 GHz support.
IsWifi50Supported()62   bool IsWifi50Supported() const override { return false; }
63 
64  private:
65   struct DeviceState {
66     std::unique_ptr<org::chromium::flimflam::DeviceProxy> device;
67     // ServiceProxy objects are shared because the connecting service will
68     // also be the selected service for a device, but is not always the selected
69     // service (for instance, in the period between configuring a WiFi service
70     // with credentials, and when Connect() is called.)
71     std::shared_ptr<org::chromium::flimflam::ServiceProxy> selected_service;
72     State service_state{State::kOffline};
73   };
74 
75   void Init();
76 
77   bool IsMonitoredDevice(org::chromium::flimflam::DeviceProxy* device);
78   void OnShillServiceOwnerChange(const std::string& old_owner,
79                                  const std::string& new_owner);
80   void OnManagerPropertyChangeRegistration(const std::string& interface,
81                                            const std::string& signal_name,
82                                            bool success);
83   void OnManagerPropertyChange(const std::string& property_name,
84                                const brillo::Any& property_value);
85   void OnDevicePropertyChangeRegistration(const dbus::ObjectPath& device_path,
86                                           const std::string& interface,
87                                           const std::string& signal_name,
88                                           bool success);
89   void OnDevicePropertyChange(const dbus::ObjectPath& device_path,
90                               const std::string& property_name,
91                               const brillo::Any& property_value);
92   void OnServicePropertyChangeRegistration(const dbus::ObjectPath& path,
93                                            const std::string& interface,
94                                            const std::string& signal_name,
95                                            bool success);
96   void OnServicePropertyChange(const dbus::ObjectPath& service_path,
97                                const std::string& property_name,
98                                const brillo::Any& property_value);
99 
100   void OnStateChangeForConnectingService(const std::string& state);
101   void OnErrorChangeForConnectingService(const std::string& error);
102   void OnStrengthChangeForConnectingService(uint8_t signal_strength);
103   void OnStateChangeForSelectedService(const dbus::ObjectPath& service_path,
104                                        const std::string& state);
105   void UpdateConnectivityState();
106   void NotifyConnectivityListeners(bool am_online);
107   // Clean up state related to a connecting service.
108   void CleanupConnectingService();
109 
110   void ConnectToServiceError(
111       std::shared_ptr<org::chromium::flimflam::ServiceProxy>
112           connecting_service);
113 
114   const scoped_refptr<dbus::Bus> bus_;
115   org::chromium::flimflam::ManagerProxy manager_proxy_;
116   // There is logic that assumes we will never change this device list
117   // in OnManagerPropertyChange.  Do not be tempted to remove this const.
118   const std::set<std::string> device_whitelist_;
119   bool disable_xmpp_{false};
120   std::vector<ConnectionChangedCallback> connectivity_listeners_;
121 
122   // State for tracking where we are in our attempts to connect to a service.
123   bool have_called_connect_{false};
124   std::shared_ptr<org::chromium::flimflam::ServiceProxy> connecting_service_;
125   std::string connecting_service_error_;
126   weave::DoneCallback connect_done_callback_;
127 
128   // State for tracking our online connectivity.
129   std::map<dbus::ObjectPath, DeviceState> devices_;
130   State connectivity_state_{State::kOffline};
131 
132   std::unique_ptr<ApManagerClient> ap_manager_client_;
133 
134   base::WeakPtrFactory<ShillClient> weak_factory_{this};
135 
136   DISALLOW_COPY_AND_ASSIGN(ShillClient);
137 };
138 
139 }  // namespace buffet
140 
141 #endif  // BUFFET_SHILL_CLIENT_H_
142