Fix -bootstrapping option Option was broken when event network was extracted from wifi manager. Also fixed connectivity prober lifetime. Existing code was able to call callback test by bufferevent_setcb even after EventNetworkImpl was destroyed. Change-Id: I774f37a55f0126fe384317ab69f077fa7817e923 Reviewed-on: https://weave-review.googlesource.com/1432 Reviewed-by: Vitaly Buka <vitalybuka@google.com>
diff --git a/libweave/examples/daemon/main.cc b/libweave/examples/daemon/main.cc index 3a4efe7..a4ec366 100644 --- a/libweave/examples/daemon/main.cc +++ b/libweave/examples/daemon/main.cc
@@ -103,11 +103,12 @@ std::unique_ptr<weave::examples::WifiImpl> wifi; if (!disable_privet) { + network.SetSimulateOffline(force_bootstrapping); + dns_sd.reset(new weave::examples::AvahiClient); http_server.reset(new weave::examples::HttpServerImpl{&task_runner}); if (weave::examples::WifiImpl::HasWifiCapability()) - wifi.reset( - new weave::examples::WifiImpl{&task_runner, force_bootstrapping}); + wifi.reset(new weave::examples::WifiImpl{&task_runner, &network}); } std::unique_ptr<weave::Device> device{weave::Device::Create( &config_store, &task_runner, &http_client, &network, dns_sd.get(),
diff --git a/libweave/examples/provider/event_network.cc b/libweave/examples/provider/event_network.cc index d86db69..ba03e8f 100644 --- a/libweave/examples/provider/event_network.cc +++ b/libweave/examples/provider/event_network.cc
@@ -41,22 +41,27 @@ } void EventNetworkImpl::UpdateNetworkState() { - std::unique_ptr<bufferevent, Deleter> bev{ + if (simulate_offline_) { + LOG(INFO) << "Simulating offline state"; + connectivity_probe_.reset(); + return UpdateNetworkStateCallback(State::kOffline); + } + + connectivity_probe_.reset( bufferevent_socket_new(task_runner_->GetEventBase(), -1, - BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS)}; + BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS)); timeval timeout{kNetworkProbeTimeoutS, 0}; - bufferevent_set_timeouts(bev.get(), &timeout, &timeout); + bufferevent_set_timeouts(connectivity_probe_.get(), &timeout, &timeout); bufferevent_setcb( - bev.get(), nullptr, nullptr, + connectivity_probe_.get(), nullptr, nullptr, [](struct bufferevent* buf, short events, void* ctx) { EventNetworkImpl* network = static_cast<EventNetworkImpl*>(ctx); - std::unique_ptr<bufferevent, Deleter> bev{buf}; if (events & BEV_EVENT_CONNECTED) { network->UpdateNetworkStateCallback(State::kOnline); return; } if (events & (BEV_EVENT_ERROR | BEV_EVENT_EOF | BEV_EVENT_TIMEOUT)) { - int err = bufferevent_socket_get_dns_error(bev.get()); + int err = bufferevent_socket_get_dns_error(buf); if (err) { LOG(ERROR) << "network connect dns error: " << evutil_gai_strerror(err); @@ -66,16 +71,13 @@ } }, this); - int err = bufferevent_socket_connect_hostname(bev.get(), dns_base_.get(), - AF_INET, kNetworkProbeHostname, - kNetworkProbePort); + int err = bufferevent_socket_connect_hostname( + connectivity_probe_.get(), dns_base_.get(), AF_INET, + kNetworkProbeHostname, kNetworkProbePort); if (err) { LOG(ERROR) << " network connect socket error: " << evutil_gai_strerror(err); - UpdateNetworkStateCallback(State::kOffline); - return; + return UpdateNetworkStateCallback(State::kOffline); } - // release the bufferevent, so that the eventcallback can free it. - bev.release(); } void EventNetworkImpl::UpdateNetworkStateCallback( @@ -91,6 +93,9 @@ cb.Run(); } + // Reset current posted task. + weak_ptr_factory_.InvalidateWeakPtrs(); + // TODO(proppy): use netlink interface event instead of polling task_runner_->PostDelayedTask( FROM_HERE, base::Bind(&EventNetworkImpl::UpdateNetworkState,
diff --git a/libweave/examples/provider/event_network.h b/libweave/examples/provider/event_network.h index 79c458c..3aeac24 100644 --- a/libweave/examples/provider/event_network.h +++ b/libweave/examples/provider/event_network.h
@@ -33,13 +33,21 @@ uint16_t port, const OpenSslSocketCallback& callback) override; + void SetSimulateOffline(bool value) { + simulate_offline_ = value; + UpdateNetworkState(); + } + private: void UpdateNetworkState(); void UpdateNetworkStateCallback(provider::Network::State state); + bool simulate_offline_{false}; EventTaskRunner* task_runner_{nullptr}; std::unique_ptr<evdns_base, Deleter> dns_base_; std::vector<ConnectionChangedCallback> callbacks_; provider::Network::State network_state_{provider::Network::State::kOffline}; + std::unique_ptr<bufferevent, Deleter> connectivity_probe_; + base::WeakPtrFactory<EventNetworkImpl> weak_ptr_factory_{this}; };
diff --git a/libweave/examples/provider/wifi_manager.cc b/libweave/examples/provider/wifi_manager.cc index c70aad4..6e216e4 100644 --- a/libweave/examples/provider/wifi_manager.cc +++ b/libweave/examples/provider/wifi_manager.cc
@@ -14,6 +14,7 @@ #include <base/bind.h> #include <weave/provider/task_runner.h> +#include "examples/provider/event_network.h" #include "examples/provider/ssl_stream.h" namespace weave { @@ -39,8 +40,8 @@ } // namespace -WifiImpl::WifiImpl(provider::TaskRunner* task_runner, bool force_bootstrapping) - : force_bootstrapping_{force_bootstrapping}, task_runner_{task_runner} { +WifiImpl::WifiImpl(provider::TaskRunner* task_runner, EventNetworkImpl* network) + : task_runner_{task_runner}, network_{network} { CHECK_EQ(0, getuid()) << "WiFi manager expects root access to control WiFi capabilities"; StopAccessPoint(); @@ -100,7 +101,7 @@ void WifiImpl::Connect(const std::string& ssid, const std::string& passphrase, const DoneCallback& callback) { - force_bootstrapping_ = false; + network_->SetSimulateOffline(false); CHECK(!hostapd_started_); if (hostapd_started_) { ErrorPtr error;
diff --git a/libweave/examples/provider/wifi_manager.h b/libweave/examples/provider/wifi_manager.h index 849beef..c043523 100644 --- a/libweave/examples/provider/wifi_manager.h +++ b/libweave/examples/provider/wifi_manager.h
@@ -20,12 +20,13 @@ namespace examples { +class EventNetworkImpl; + // Basic weave::Wifi implementation. // Production version of SSL socket needs secure server certificate check. class WifiImpl : public provider::Wifi { public: - explicit WifiImpl(provider::TaskRunner* task_runner, - bool force_bootstrapping); + WifiImpl(provider::TaskRunner* task_runner, EventNetworkImpl* network); ~WifiImpl(); // Wifi implementation. @@ -43,9 +44,9 @@ int pid, base::Time until, const DoneCallback& callback); - bool force_bootstrapping_{false}; bool hostapd_started_{false}; provider::TaskRunner* task_runner_{nullptr}; + EventNetworkImpl* network_{nullptr}; base::WeakPtrFactory<WifiImpl> weak_ptr_factory_{this}; };