1
#include "com/ubuntu/location/providers/skyhook/provider.h"
3
#include "com/ubuntu/location/logging.h"
4
#include "com/ubuntu/location/provider_factory.h"
11
namespace cul = com::ubuntu::location;
12
namespace culs = com::ubuntu::location::providers::skyhook;
16
static const std::map<int, std::string> return_code_lut =
19
{WPS_ERROR_SCANNER_NOT_FOUND, "WPS_ERROR_SCANNER_NOT_FOUND"},
20
{WPS_ERROR_WIFI_NOT_AVAILABLE, "WPS_ERROR_WIFI_NOT_AVAILABLE"},
21
{WPS_ERROR_NO_WIFI_IN_RANGE, "WPS_ERROR_NO_WIFI_IN_RANGE"},
22
{WPS_ERROR_UNAUTHORIZED, "WPS_ERROR_UNAUTHORIZED"},
23
{WPS_ERROR_SERVER_UNAVAILABLE, "WPS_ERROR_SERVER_UNAVAILABLE"},
24
{WPS_ERROR_LOCATION_CANNOT_BE_DETERMINED, "WPS_ERROR_LOCATION_CANNOT_BE_DETERMINED"},
25
{WPS_ERROR_PROXY_UNAUTHORIZED, "WPS_ERROR_PROXY_UNAUTHORIZED"},
26
{WPS_ERROR_FILE_IO, "WPS_ERROR_FILE_IO"},
27
{WPS_ERROR_INVALID_FILE_FORMAT, "WPS_ERROR_INVALID_FILE_FORMAT"},
28
{WPS_ERROR_TIMEOUT, "WPS_ERROR_TIMEOUT"},
29
{WPS_NOT_APPLICABLE, "WPS_NOT_APPLICABLE"},
30
{WPS_GEOFENCE_ERROR, "WPS_GEOFENCE_ERROR"},
31
{WPS_ERROR_NOT_TUNED, "WPS_ERROR_NOT_TUNED"},
32
{WPS_NOMEM, "WPS_NOMEM"},
33
{WPS_ERROR, "WPS_ERROR"}
37
struct culs::Provider::Private
46
static WPS_Continuation periodic_callback(
49
const WPS_Location* location,
53
const culs::Provider::Configuration& config,
54
culs::Provider* parent)
63
if (state != State::stopped)
66
if (worker.joinable())
69
static const unsigned infinite_iterations = 0;
71
authentication.username = config.user_name.c_str();
72
authentication.realm = config.realm.c_str();
74
worker = std::move(std::thread([&]()
76
int rc = WPS_periodic_location(
78
WPS_NO_STREET_ADDRESS_LOOKUP,
79
config.period.count(),
81
culs::Provider::Private::periodic_callback,
85
LOG(ERROR) << return_code_lut.at(rc);
88
state = State::started;
93
state = State::stop_requested;
96
culs::Provider* parent;
99
WPS_SimpleAuthentication authentication;
103
WPS_Continuation culs::Provider::Private::periodic_callback(void* context,
105
const WPS_Location* location,
110
LOG(WARNING) << return_code_lut.at(code);
111
if (code == WPS_ERROR_WIFI_NOT_AVAILABLE)
117
auto thiz = static_cast<culs::Provider::Private*>(context);
119
if (thiz->state == culs::Provider::Private::State::stop_requested)
121
LOG(INFO) << "Stop requested";
122
thiz->state = culs::Provider::Private::State::stopped;
127
pos.latitude(cul::wgs84::Latitude{location->latitude * cul::units::Degrees})
128
.longitude(cul::wgs84::Longitude{location->longitude * cul::units::Degrees});
129
if (location->altitude >= 0.f)
130
pos.altitude(cul::wgs84::Altitude{location->altitude * cul::units::Meters});
134
thiz->parent->deliver_position_updates(cul::Update<cul::Position>{pos, cul::Clock::now()});
136
if (location->speed >= 0.f)
138
cul::Velocity v{location->speed * cul::units::MetersPerSecond};
140
thiz->parent->deliver_velocity_updates(cul::Update<cul::Velocity>{v, cul::Clock::now()});
143
if (location->bearing >= 0.f)
145
cul::Heading h{location->bearing * cul::units::Degrees};
147
thiz->parent->deliver_heading_updates(cul::Update<cul::Heading>{h, cul::Clock::now()});
153
cul::Provider::Ptr culs::Provider::create_instance(const cul::ProviderFactory::Configuration& config)
155
culs::Provider::Configuration configuration{"", "", std::chrono::milliseconds{100}};
156
configuration.user_name = config.count("username") > 0 ? config.at("username") : "";
157
configuration.realm = config.count("realm") > 0 ? config.at("realm") : "";
158
if (config.count("period"))
161
std::stringstream ss(config.at("period"));
162
ss >> value; configuration.period = std::chrono::milliseconds{value};
164
return cul::Provider::Ptr{new culs::Provider{configuration}};
167
const cul::Provider::FeatureFlags& culs::Provider::default_feature_flags()
169
static const cul::Provider::FeatureFlags flags{"001"};
173
const cul::Provider::RequirementFlags& culs::Provider::default_requirement_flags()
175
static const cul::Provider::RequirementFlags flags{"1010"};
179
culs::Provider::Provider(const culs::Provider::Configuration& config)
180
: com::ubuntu::location::Provider(culs::Provider::default_feature_flags(), culs::Provider::default_requirement_flags()),
181
d(new Private(config, this))
185
culs::Provider::~Provider() noexcept
190
bool culs::Provider::matches_criteria(const cul::Criteria&)
195
void culs::Provider::start_position_updates()
200
void culs::Provider::stop_position_updates()
205
void culs::Provider::start_velocity_updates()
210
void culs::Provider::stop_velocity_updates()
215
void culs::Provider::start_heading_updates()
220
void culs::Provider::stop_heading_updates()