16
16
* Authored by: Thomas Voß <thomas.voss@canonical.com>
18
#include "com/ubuntu/location/providers/gps/provider.h"
20
#include "com/ubuntu/location/logging.h"
21
#include "hardware_abstraction_layer.h"
23
#include <com/ubuntu/location/logging.h>
24
#include <com/ubuntu/location/connectivity/manager.h>
22
26
#include <ubuntu/hardware/gps.h>
24
28
namespace cul = com::ubuntu::location;
25
29
namespace culg = com::ubuntu::location::providers::gps;
29
static const std::map<uint16_t, std::string> status_lut =
31
{U_HARDWARE_GPS_STATUS_NONE, "U_HARDWARE_GPS_STATUS_NONE"},
32
{U_HARDWARE_GPS_STATUS_SESSION_BEGIN, "U_HARDWARE_GPS_STATUS_SESSION_BEGIN"},
33
{U_HARDWARE_GPS_STATUS_SESSION_END, "U_HARDWARE_GPS_STATUS_SESSION_END"},
34
{U_HARDWARE_GPS_STATUS_ENGINE_ON, "U_HARDWARE_GPS_STATUS_ENGINE_ON"},
35
{U_HARDWARE_GPS_STATUS_ENGINE_OFF, "U_HARDWARE_GPS_STATUS_ENGINE_OFF"}
39
31
struct culg::Provider::Private
42
static void on_location_update(UHardwareGpsLocation* location, void* context)
44
auto thiz = static_cast<culg::Provider*>(context);
46
if (location->flags & U_HARDWARE_GPS_LOCATION_HAS_LAT_LONG)
48
VLOG(1) << "location->flags & U_HARDWARE_GPS_LOCATION_HAS_LAT_LONG";
51
pos.latitude(cul::wgs84::Latitude{location->latitude * cul::units::Degrees});
52
pos.longitude(cul::wgs84::Longitude{location->longitude * cul::units::Degrees});
53
if(location->flags & U_HARDWARE_GPS_LOCATION_HAS_ALTITUDE)
54
pos.altitude(cul::wgs84::Altitude{location->altitude * cul::units::Meters});
56
thiz->deliver_position_updates(cul::Update<cul::Position>{pos, cul::Clock::now()});
59
if (location->flags & U_HARDWARE_GPS_LOCATION_HAS_SPEED)
61
VLOG(1) << "location->flags & U_HARDWARE_GPS_LOCATION_HAS_SPEED";
63
cul::Velocity v{location->speed * cul::units::MetersPerSecond};
64
thiz->deliver_velocity_updates(cul::Update<cul::Velocity>{v, cul::Clock::now()});
67
if (location->flags & U_HARDWARE_GPS_LOCATION_HAS_BEARING)
69
VLOG(1) << "location->flags & U_HARDWARE_GPS_LOCATION_HAS_BEARING";
71
cul::Heading h{location->bearing * cul::units::Degrees};
72
thiz->deliver_heading_updates(cul::Update<cul::Heading>{h, cul::Clock::now()});
76
static void on_status_update(uint16_t status, void* /*context*/)
78
SYSLOG(INFO) << "Status = " << status_lut.at(status);
81
static void on_sv_status_update(UHardwareGpsSvStatus* sv_info, void* /*context*/)
83
SYSLOG_EVERY_N(INFO, 20) << "SV status update: [#svs: " << sv_info->num_svs << "]";
86
static void on_nmea_update(int64_t /*timestamp*/, const char* /*nmea*/, int /*length*/, void* /*context*/)
90
static void on_set_capabilities(uint32_t capabilities, void* /*context*/)
92
VLOG(1) << __PRETTY_FUNCTION__ << ": " << capabilities;
95
static void on_request_utc_time(void* /*context*/)
97
VLOG(1) << __PRETTY_FUNCTION__;
100
static void on_agps_status_update(UHardwareGpsAGpsStatus* /*status*/, void* /*context*/)
102
VLOG(1) << __PRETTY_FUNCTION__;
105
static void on_gps_ni_notification(UHardwareGpsNiNotification* /*notification*/, void* /*context*/)
107
VLOG(1) << __PRETTY_FUNCTION__;
110
static void on_agps_ril_request_set_id(uint32_t /*flags*/, void* /*context*/)
112
VLOG(1) << __PRETTY_FUNCTION__;
115
static void on_agps_ril_request_ref_lock(uint32_t /*flags*/, void* /*context*/)
117
VLOG(1) << __PRETTY_FUNCTION__;
120
static void on_gps_xtra_download_request(void*)
122
VLOG(1) << __PRETTY_FUNCTION__;
127
u_hardware_gps_start(gps_handle);
132
u_hardware_gps_stop(gps_handle);
135
UHardwareGpsParams gps_params;
136
UHardwareGps gps_handle;
33
std::shared_ptr<HardwareAbstractionLayer> hal;
141
36
std::string culg::Provider::class_name()
143
38
return "gps::Provider";
146
41
cul::Provider::Ptr culg::Provider::create_instance(const cul::ProviderFactory::Configuration&)
148
return cul::Provider::Ptr{new culg::Provider{}};
151
const cul::Provider::FeatureFlags& culg::Provider::default_feature_flags()
153
static const cul::Provider::FeatureFlags flags{"001"};
157
const cul::Provider::RequirementFlags& culg::Provider::default_requirement_flags()
159
static const cul::Provider::RequirementFlags flags{"1010"};
163
culg::Provider::Provider()
165
culg::Provider::default_feature_flags(),
166
culg::Provider::default_requirement_flags()),
169
d->gps_params.location_cb = culg::Provider::Private::on_location_update;
170
d->gps_params.status_cb = culg::Provider::Private::on_status_update;
171
d->gps_params.sv_status_cb = culg::Provider::Private::on_sv_status_update;
172
d->gps_params.nmea_cb = culg::Provider::Private::on_nmea_update;
173
d->gps_params.set_capabilities_cb = culg::Provider::Private::on_set_capabilities;
174
d->gps_params.request_utc_time_cb = culg::Provider::Private::on_request_utc_time;
175
d->gps_params.xtra_download_request_cb = culg::Provider::Private::on_gps_xtra_download_request;
177
d->gps_params.agps_status_cb = culg::Provider::Private::on_agps_status_update;
179
d->gps_params.gps_ni_notify_cb = culg::Provider::Private::on_gps_ni_notification;
181
d->gps_params.request_setid_cb = culg::Provider::Private::on_agps_ril_request_set_id;
182
d->gps_params.request_refloc_cb = culg::Provider::Private::on_agps_ril_request_ref_lock;
183
d->gps_params.context = this;
185
d->gps_handle = u_hardware_gps_new(std::addressof(d->gps_params));
187
static const std::chrono::milliseconds minimum_interval{500};
188
static const uint32_t preferred_accuracy{0};
189
static const uint32_t preferred_time_to_first_fix{0};
191
u_hardware_gps_set_position_mode(
193
U_HARDWARE_GPS_POSITION_MODE_MS_BASED,
194
U_HARDWARE_GPS_POSITION_RECURRENCE_PERIODIC,
195
minimum_interval.count(),
197
preferred_time_to_first_fix
43
return cul::Provider::Ptr{new culg::Provider{culg::HardwareAbstractionLayer::create_default_instance()}};
46
culg::Provider::Provider(const std::shared_ptr<HardwareAbstractionLayer>& hal)
48
cul::Provider::Features::position | cul::Provider::Features::velocity | cul::Provider::Features::heading,
49
cul::Provider::Requirements::satellites),
54
d->hal->position_updates().connect([this](const location::Position& pos)
56
mutable_updates().position(Update<Position>(pos));
59
d->hal->heading_updates().connect([this](const location::Heading& heading)
61
mutable_updates().heading(Update<Heading>(heading));
64
d->hal->velocity_updates().connect([this](const location::Velocity& velocity)
66
mutable_updates().velocity(Update<Velocity>(velocity));
69
d->hal->space_vehicle_updates().connect([this](const std::set<location::SpaceVehicle>& svs)
71
mutable_updates().svs(Update<std::set<location::SpaceVehicle>>(svs));
201
75
culg::Provider::~Provider() noexcept
204
u_hardware_gps_delete(d->gps_handle);
77
d->hal->stop_positioning();
207
80
bool culg::Provider::matches_criteria(const cul::Criteria&)
212
85
void culg::Provider::start_position_updates()
87
d->hal->start_positioning();
217
90
void culg::Provider::stop_position_updates()
92
d->hal->stop_positioning();
222
95
void culg::Provider::start_velocity_updates()
97
d->hal->start_positioning();
227
100
void culg::Provider::stop_velocity_updates()
102
d->hal->stop_positioning();
232
105
void culg::Provider::start_heading_updates()
107
d->hal->start_positioning();
237
110
void culg::Provider::stop_heading_updates()
112
d->hal->stop_positioning();
115
void culg::Provider::on_reference_location_updated(const cul::Update<cul::Position>& position)
117
d->hal->inject_reference_position(position.value);