~thomas-voss/location-service/fix-1347887

« back to all changes in this revision

Viewing changes to src/location_service/com/ubuntu/location/providers/gps/provider.cpp

This MP consolidates multiple related changes together, with the goal of:

(1.) Make the service instance accessible via a cli. Useful for testing scenarios.
(2.) To cut down time-to-first-fix (ttff) by:
  (2.1) Leveraging SUPL and other supplementary data downloaded over ordinary data connections.
  (2.2) Enabling network-based positioning providers to acquire fast position estimates.

In more detail:

* Added tests for daemon and cli.
* Unified daemon and cli header and implementation files.
* Add a command-line interface to the service.
* Split up provider selection policy to rely on an interface ProviderEnumerator to ease in testing.
* Trimmed down on types.
* Removed connectivity API draft to prepare for simpler approach.
* Refactored includes.
* Added a configuration option to handle cell and wifi ID reporting.
* Add a mock for a connectivity API exposed to providers and reporters.
* Add units for connectivity api.
* Refactor cell class into namespace radio. Fixes: 1226204, 1248973, 1281817

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 *
16
16
 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17
17
 */
18
 
#include "com/ubuntu/location/providers/gps/provider.h"
19
 
 
20
 
#include "com/ubuntu/location/logging.h"
 
18
 
 
19
#include "provider.h"
 
20
 
 
21
#include "hardware_abstraction_layer.h"
 
22
 
 
23
#include <com/ubuntu/location/logging.h>
 
24
#include <com/ubuntu/location/connectivity/manager.h>
21
25
 
22
26
#include <ubuntu/hardware/gps.h>
23
27
 
24
28
namespace cul = com::ubuntu::location;
25
29
namespace culg = com::ubuntu::location::providers::gps;
26
30
 
27
 
namespace
28
 
{
29
 
static const std::map<uint16_t, std::string> status_lut = 
30
 
{
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"}
36
 
};
37
 
}
38
 
 
39
31
struct culg::Provider::Private
40
32
{
41
 
 
42
 
static void on_location_update(UHardwareGpsLocation* location, void* context)
43
 
{
44
 
    auto thiz = static_cast<culg::Provider*>(context);
45
 
        
46
 
    if (location->flags & U_HARDWARE_GPS_LOCATION_HAS_LAT_LONG)
47
 
    {
48
 
        VLOG(1) << "location->flags & U_HARDWARE_GPS_LOCATION_HAS_LAT_LONG";
49
 
 
50
 
        cul::Position pos;
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});
55
 
        
56
 
        thiz->deliver_position_updates(cul::Update<cul::Position>{pos, cul::Clock::now()});
57
 
    }
58
 
    
59
 
    if (location->flags & U_HARDWARE_GPS_LOCATION_HAS_SPEED)
60
 
    {
61
 
        VLOG(1) << "location->flags & U_HARDWARE_GPS_LOCATION_HAS_SPEED";
62
 
        
63
 
        cul::Velocity v{location->speed * cul::units::MetersPerSecond};
64
 
        thiz->deliver_velocity_updates(cul::Update<cul::Velocity>{v, cul::Clock::now()});
65
 
    }
66
 
 
67
 
    if (location->flags & U_HARDWARE_GPS_LOCATION_HAS_BEARING)
68
 
    {
69
 
        VLOG(1) << "location->flags & U_HARDWARE_GPS_LOCATION_HAS_BEARING";
70
 
        
71
 
        cul::Heading h{location->bearing * cul::units::Degrees};
72
 
        thiz->deliver_heading_updates(cul::Update<cul::Heading>{h, cul::Clock::now()});
73
 
    }
74
 
}
75
 
 
76
 
static void on_status_update(uint16_t status, void* /*context*/)
77
 
{
78
 
    SYSLOG(INFO) << "Status = " << status_lut.at(status);
79
 
}
80
 
 
81
 
static void on_sv_status_update(UHardwareGpsSvStatus* sv_info, void* /*context*/)
82
 
{
83
 
    SYSLOG_EVERY_N(INFO, 20) << "SV status update: [#svs: " << sv_info->num_svs << "]";
84
 
}
85
 
    
86
 
static void on_nmea_update(int64_t /*timestamp*/, const char* /*nmea*/, int /*length*/, void* /*context*/)
87
 
{
88
 
}
89
 
 
90
 
static void on_set_capabilities(uint32_t capabilities, void* /*context*/)
91
 
{
92
 
    VLOG(1) << __PRETTY_FUNCTION__ << ": " << capabilities;
93
 
}
94
 
 
95
 
static void on_request_utc_time(void* /*context*/)
96
 
{
97
 
    VLOG(1) << __PRETTY_FUNCTION__;
98
 
}
99
 
 
100
 
static void on_agps_status_update(UHardwareGpsAGpsStatus* /*status*/, void* /*context*/)
101
 
{
102
 
    VLOG(1) << __PRETTY_FUNCTION__;
103
 
}
104
 
 
105
 
static void on_gps_ni_notification(UHardwareGpsNiNotification* /*notification*/, void* /*context*/)
106
 
{
107
 
    VLOG(1) << __PRETTY_FUNCTION__;
108
 
}
109
 
    
110
 
static void on_agps_ril_request_set_id(uint32_t /*flags*/, void* /*context*/)
111
 
{
112
 
    VLOG(1) << __PRETTY_FUNCTION__;
113
 
}
114
 
 
115
 
static void on_agps_ril_request_ref_lock(uint32_t /*flags*/, void* /*context*/)
116
 
{
117
 
    VLOG(1) << __PRETTY_FUNCTION__;
118
 
}
119
 
 
120
 
    static void on_gps_xtra_download_request(void*)
121
 
    {
122
 
        VLOG(1) << __PRETTY_FUNCTION__;
123
 
    }
124
 
 
125
 
    void start() 
126
 
    { 
127
 
        u_hardware_gps_start(gps_handle);
128
 
    }
129
 
    
130
 
    void stop() 
131
 
    { 
132
 
        u_hardware_gps_stop(gps_handle);
133
 
    }
134
 
 
135
 
    UHardwareGpsParams gps_params;
136
 
    UHardwareGps gps_handle;
 
33
    std::shared_ptr<HardwareAbstractionLayer> hal;
137
34
};
138
35
 
139
 
 
140
 
 
141
36
std::string culg::Provider::class_name()
142
37
{
143
38
    return "gps::Provider";
145
40
 
146
41
cul::Provider::Ptr culg::Provider::create_instance(const cul::ProviderFactory::Configuration&)
147
42
{
148
 
    return cul::Provider::Ptr{new culg::Provider{}};
149
 
}
150
 
 
151
 
const cul::Provider::FeatureFlags& culg::Provider::default_feature_flags()
152
 
{
153
 
    static const cul::Provider::FeatureFlags flags{"001"};
154
 
    return flags;
155
 
}
156
 
 
157
 
const cul::Provider::RequirementFlags& culg::Provider::default_requirement_flags()
158
 
{
159
 
    static const cul::Provider::RequirementFlags flags{"1010"};
160
 
    return flags;
161
 
}
162
 
 
163
 
culg::Provider::Provider()
164
 
        : cul::Provider(
165
 
              culg::Provider::default_feature_flags(), 
166
 
              culg::Provider::default_requirement_flags()),
167
 
          d(new Private())
168
 
{
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;
176
 
    
177
 
    d->gps_params.agps_status_cb = culg::Provider::Private::on_agps_status_update;
178
 
    
179
 
    d->gps_params.gps_ni_notify_cb = culg::Provider::Private::on_gps_ni_notification;
180
 
    
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;
184
 
    
185
 
    d->gps_handle = u_hardware_gps_new(std::addressof(d->gps_params));
186
 
 
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};
190
 
 
191
 
    u_hardware_gps_set_position_mode(
192
 
                d->gps_handle,
193
 
                U_HARDWARE_GPS_POSITION_MODE_MS_BASED,
194
 
                U_HARDWARE_GPS_POSITION_RECURRENCE_PERIODIC,
195
 
                minimum_interval.count(),
196
 
                preferred_accuracy,
197
 
                preferred_time_to_first_fix
198
 
                );
 
43
    return cul::Provider::Ptr{new culg::Provider{culg::HardwareAbstractionLayer::create_default_instance()}};
 
44
}
 
45
 
 
46
culg::Provider::Provider(const std::shared_ptr<HardwareAbstractionLayer>& hal)
 
47
    : cul::Provider(
 
48
          cul::Provider::Features::position | cul::Provider::Features::velocity | cul::Provider::Features::heading,
 
49
          cul::Provider::Requirements::satellites),
 
50
      d(new Private())
 
51
{
 
52
    d->hal = hal;
 
53
 
 
54
    d->hal->position_updates().connect([this](const location::Position& pos)
 
55
    {
 
56
        mutable_updates().position(Update<Position>(pos));
 
57
    });
 
58
 
 
59
    d->hal->heading_updates().connect([this](const location::Heading& heading)
 
60
    {
 
61
        mutable_updates().heading(Update<Heading>(heading));
 
62
    });
 
63
 
 
64
    d->hal->velocity_updates().connect([this](const location::Velocity& velocity)
 
65
    {
 
66
        mutable_updates().velocity(Update<Velocity>(velocity));
 
67
    });
 
68
 
 
69
    d->hal->space_vehicle_updates().connect([this](const std::set<location::SpaceVehicle>& svs)
 
70
    {
 
71
        mutable_updates().svs(Update<std::set<location::SpaceVehicle>>(svs));
 
72
    });
199
73
}
200
74
 
201
75
culg::Provider::~Provider() noexcept
202
76
{
203
 
    d->stop();
204
 
    u_hardware_gps_delete(d->gps_handle);
 
77
    d->hal->stop_positioning();
205
78
}
206
79
 
207
80
bool culg::Provider::matches_criteria(const cul::Criteria&)
211
84
 
212
85
void culg::Provider::start_position_updates()
213
86
{
214
 
    d->start();
 
87
    d->hal->start_positioning();
215
88
}
216
89
 
217
90
void culg::Provider::stop_position_updates()
218
91
{
219
 
    d->stop();
 
92
    d->hal->stop_positioning();
220
93
}
221
94
 
222
95
void culg::Provider::start_velocity_updates()
223
96
{
224
 
    d->start();
 
97
    d->hal->start_positioning();
225
98
}
226
99
 
227
100
void culg::Provider::stop_velocity_updates()
228
101
{
229
 
    d->stop();
 
102
    d->hal->stop_positioning();
230
103
}    
231
104
 
232
105
void culg::Provider::start_heading_updates()
233
106
{
234
 
    d->start();
 
107
    d->hal->start_positioning();
235
108
}
236
109
 
237
110
void culg::Provider::stop_heading_updates()
238
111
{
239
 
    d->stop();
240
 
}
 
112
    d->hal->stop_positioning();
 
113
}
 
114
 
 
115
void culg::Provider::on_reference_location_updated(const cul::Update<cul::Position>& position)
 
116
{
 
117
    d->hal->inject_reference_position(position.value);
 
118
}
 
119