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
33namespace buffet {
34
35class ApManagerClient;
36
37class 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;
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.
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