2
* Copyright © 2012-2013 Canonical Ltd.
4
* This program is free software: you can redistribute it and/or modify it
5
* under the terms of the GNU Lesser General Public License version 3,
6
* as published by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU Lesser General Public License for more details.
13
* You should have received a copy of the GNU Lesser General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16
* Authored by: Thomas Voß <thomas.voss@canonical.com>
21
#include <location/logging.h>
23
#include <core/net/http/client.h>
27
namespace mls = location::providers::mls;
29
std::string mls::Provider::class_name()
31
return "mls::Provider";
34
location::Provider::Ptr mls::Provider::create_instance(const location::ProviderFactory::Configuration& config)
36
mls::Configuration configuration;
37
configuration.host = config.get("Host", ichnaea::Client::default_host);
38
configuration.api_key = config.get("ApiKey", "test");
40
return location::Provider::Ptr{new mls::Provider{configuration}};
43
mls::Provider::Provider(const mls::Configuration& config)
44
: connectivity_manager{com::ubuntu::location::connectivity::platform_default_manager()},
45
http_client{core::net::http::make_client()},
46
ichnaea_client{std::make_shared<ichnaea::Client>(config.host, config.api_key, http_client)},
47
stop_requested{false},
48
rt{location::Runtime::create(1)},
50
http_worker{[this]() { http_client->run(); }}
52
connectivity_manager->wireless_network_scan_finished().connect([this]()
54
VLOG(1) << "Wireless network scan finished.";
55
std::vector<com::ubuntu::location::connectivity::WirelessNetwork::Ptr> wifis;
57
connectivity_manager->enumerate_visible_wireless_networks([&wifis](const com::ubuntu::location::connectivity::WirelessNetwork::Ptr& wifi)
59
wifis.push_back(wifi);
62
ichnaea::geolocate::Parameters params;
63
params.consider_ip = true;
65
for (auto wifi : wifis)
67
ichnaea::WifiAccessPoint ap;
68
ap.bssid = wifi->bssid().get();
69
ap.ssid = wifi->ssid().get();
70
ap.frequency = wifi->frequency().get();
71
ap.signal_strength = wifi->signal_strength().get();
73
params.wifi_access_points.insert(ap);
78
ichnaea_client->geolocate(params, [this](const ichnaea::Response<ichnaea::geolocate::Result>& response)
80
if (not response.is_error())
82
Update<Position> update;
83
update.when = Clock::now();
84
update.value = Position
86
wgs84::Latitude{response.result().location.lat * units::Degrees},
87
wgs84::Longitude{response.result().location.lon * units::Degrees}
89
Position::Accuracy accuracy; accuracy.horizontal = response.result().accuracy * units::Meters;
90
update.value.accuracy = accuracy;
91
updates.position(update);
95
LOG(WARNING) << "Service returned error for location query: " << response.error();
99
catch (const std::runtime_error& e)
101
LOG(WARNING) << "Error querying location for new wifi readings: " << e.what();
108
mls::Provider::~Provider() noexcept
114
void mls::Provider::on_new_event(const Event&)
118
location::Provider::Requirements mls::Provider::requirements() const
120
return Requirements::none;
123
bool mls::Provider::satisfies(const location::Criteria&)
128
void mls::Provider::enable()
132
void mls::Provider::disable()
136
void mls::Provider::activate()
138
on_timeout(boost::system::error_code{});
141
void mls::Provider::deactivate()
143
boost::system::error_code ec; timer.cancel(ec);
146
const core::Signal<location::Update<location::Position>>& mls::Provider::position_updates() const
148
return updates.position;
151
const core::Signal<location::Update<location::Heading>>& mls::Provider::heading_updates() const
153
return updates.heading;
156
const core::Signal<location::Update<location::Velocity>>& mls::Provider::velocity_updates() const
158
return updates.velocity;
161
void mls::Provider::on_timeout(const boost::system::error_code& ec)
165
auto thiz = shared_from_this();
166
std::weak_ptr<Provider> wp{thiz};
168
connectivity_manager->request_scan_for_wireless_networks();
170
timer.expires_from_now(boost::posix_time::seconds{10});
171
timer.async_wait([wp](const boost::system::error_code& ec)
173
if (auto sp = wp.lock()) sp->on_timeout(ec);