blob: 6f4a4dd8050dc031814fb81bf7ac45dfdb228e61 [file] [log] [blame]
Alex Vakulenkof0f55342015-08-18 15:51:40 -07001/*
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 "buffet/brillo_network_client.h"
18
19#include <base/message_loop/message_loop.h>
20
Alex Vakulenkoe32375b2015-09-28 08:55:40 -070021using weave::provider::Network;
22
Alex Vakulenkof0f55342015-08-18 15:51:40 -070023namespace buffet {
24
25namespace {
Alex Vakulenko059c30d2015-09-22 14:09:16 -070026const char kErrorDomain[] = "brillo_network";
Alex Vakulenkof0f55342015-08-18 15:51:40 -070027const int kConnectionTimeoutSeconds = 30;
28const int kConnectionActivePollSeconds = 3;
29const int kConnectionInactivePollSeconds = 10;
30} // namespace
31
32BrilloNetworkClient::BrilloNetworkClient(
33 const std::set<std::string>& device_whitelist)
Alex Vakulenkoe32375b2015-09-28 08:55:40 -070034 : NetworkClient{device_whitelist} {
Alex Vakulenkof624d7d2015-09-16 12:28:41 -070035 UpdateConnectionState();
Alex Vakulenkof0f55342015-08-18 15:51:40 -070036}
37
38BrilloNetworkClient::~BrilloNetworkClient() {
39}
40
Alex Vakulenko0fef8152015-09-25 08:45:22 -070041void BrilloNetworkClient::AddConnectionChangedCallback(
42 const ConnectionChangedCallback& listener) {
Alex Vakulenkof0f55342015-08-18 15:51:40 -070043 connection_listeners_.push_back(listener);
44}
45
Alex Vakulenko0fef8152015-09-25 08:45:22 -070046void BrilloNetworkClient::Connect(const std::string& ssid,
47 const std::string& passphrase,
48 const weave::SuccessCallback& on_success,
49 const weave::ErrorCallback& on_error) {
Alex Vakulenkof0f55342015-08-18 15:51:40 -070050 if (!connectivity_client_.ConnectToAccessPoint(ssid, passphrase)) {
Alex Vakulenko059c30d2015-09-22 14:09:16 -070051 weave::ErrorPtr error;
52 weave::Error::AddTo(&error, FROM_HERE, kErrorDomain, "network_failure",
53 "Failed to connect to service");
54 base::MessageLoop::current()->PostDelayedTask(
55 FROM_HERE, base::Bind(on_error, base::Owned(error.release())), {});
56 return;
Alex Vakulenkof0f55342015-08-18 15:51:40 -070057 }
58
59 connection_success_closure_ = on_success;
Alex Vakulenkoe32375b2015-09-28 08:55:40 -070060 connectivity_state_ = State::kConnecting;
Alex Vakulenkof0f55342015-08-18 15:51:40 -070061
62 connection_timeout_closure_.Reset(
63 base::Bind(&BrilloNetworkClient::OnConnectionTimeout,
64 base::Unretained(this)));
65 base::MessageLoop::current()->PostDelayedTask(
66 FROM_HERE,
67 connection_timeout_closure_.callback(),
68 base::TimeDelta::FromSeconds(kConnectionTimeoutSeconds));
69
70 ScheduleNextStatePoll();
Alex Vakulenkof0f55342015-08-18 15:51:40 -070071}
72
Alex Vakulenkoe32375b2015-09-28 08:55:40 -070073Network::State BrilloNetworkClient::GetConnectionState() const {
74 return connectivity_state_;
Alex Vakulenkof0f55342015-08-18 15:51:40 -070075}
76
Alex Vakulenko0fef8152015-09-25 08:45:22 -070077void BrilloNetworkClient::StartAccessPoint(const std::string& ssid) {
Alex Vakulenkof0f55342015-08-18 15:51:40 -070078 connectivity_client_.EnableAccessPoint(ssid);
Alex Vakulenkoe32375b2015-09-28 08:55:40 -070079 connectivity_state_ = State::kOffline;
Alex Vakulenkof0f55342015-08-18 15:51:40 -070080}
81
Alex Vakulenko0fef8152015-09-25 08:45:22 -070082void BrilloNetworkClient::StopAccessPoint() {
Alex Vakulenkof0f55342015-08-18 15:51:40 -070083 connectivity_client_.DisableAccessPoint();
84}
85
86void BrilloNetworkClient::OnConnectionTimeout() {
Alex Vakulenkoe32375b2015-09-28 08:55:40 -070087 connectivity_state_ = State::kFailure;
Alex Vakulenkof0f55342015-08-18 15:51:40 -070088}
89
90void BrilloNetworkClient::ScheduleNextStatePoll() {
91 periodic_connection_state_closure_.Reset(
92 base::Bind(&BrilloNetworkClient::UpdateConnectionState,
93 base::Unretained(this)));
94 int poll_period_seconds;
Alex Vakulenkoe32375b2015-09-28 08:55:40 -070095 if (connectivity_state_ == State::kConnecting) {
Alex Vakulenkof0f55342015-08-18 15:51:40 -070096 poll_period_seconds = kConnectionActivePollSeconds;
97 } else {
98 poll_period_seconds = kConnectionInactivePollSeconds;
99 }
100 base::MessageLoop::current()->PostDelayedTask(
101 FROM_HERE,
102 periodic_connection_state_closure_.callback(),
103 base::TimeDelta::FromSeconds(poll_period_seconds));
104}
105
106void BrilloNetworkClient::UpdateConnectionState() {
Alex Vakulenkoe32375b2015-09-28 08:55:40 -0700107 bool was_connected = connectivity_state_ == State::kConnected;
Alex Vakulenkof0f55342015-08-18 15:51:40 -0700108 bool is_connected = connectivity_client_.IsConnected();
109
110 if (is_connected) {
Alex Vakulenkoe32375b2015-09-28 08:55:40 -0700111 if (connectivity_state_ == State::kConnecting)
Alex Vakulenkof0f55342015-08-18 15:51:40 -0700112 connection_success_closure_.Run();
Alex Vakulenkoe32375b2015-09-28 08:55:40 -0700113 connectivity_state_ = State::kConnected;
114 } else if (connectivity_state_ == State::kConnected) {
115 connectivity_state_ = State::kOffline;
Alex Vakulenkof0f55342015-08-18 15:51:40 -0700116 }
117 if (is_connected != was_connected) {
118 for (const auto& listener : connection_listeners_) {
Alex Vakulenko059c30d2015-09-22 14:09:16 -0700119 listener.Run();
Alex Vakulenkof0f55342015-08-18 15:51:40 -0700120 }
121 }
122 ScheduleNextStatePoll();
123}
124
125std::unique_ptr<NetworkClient> NetworkClient::CreateInstance(
126 const std::set<std::string>& device_whitelist) {
127 return std::unique_ptr<NetworkClient>{
128 new BrilloNetworkClient{device_whitelist}};
129}
130
131} // namespace buffet