Merge lp:~thomas-voss/location-service/add-sirf-support into lp:location-service

Proposed by Thomas Voß
Status: Merged
Approved by: Thomas Voß
Approved revision: 305
Merged at revision: 304
Proposed branch: lp:~thomas-voss/location-service/add-sirf-support
Merge into: lp:location-service
Diff against target: 3976 lines (+2602/-453)
58 files modified
src/location/CMakeLists.txt (+7/-1)
src/location/cmds/monitor.cpp (+72/-4)
src/location/cmds/monitor.h (+7/-0)
src/location/nmea/cardinal_direction.h (+3/-12)
src/location/nmea/date.h (+3/-12)
src/location/nmea/fusion_adapt.h (+61/-61)
src/location/nmea/generator.h (+12/-21)
src/location/nmea/gga.h (+15/-22)
src/location/nmea/gll.h (+11/-19)
src/location/nmea/gps/fix_mode.h (+9/-16)
src/location/nmea/grammar.h (+7/-17)
src/location/nmea/gsa.h (+10/-19)
src/location/nmea/gsv.h (+9/-16)
src/location/nmea/latitude.h (+8/-15)
src/location/nmea/longitude.h (+8/-15)
src/location/nmea/mode.h (+8/-15)
src/location/nmea/rmc.h (+16/-23)
src/location/nmea/scanner.cpp (+2/-2)
src/location/nmea/scanner.h (+8/-15)
src/location/nmea/sentence.cpp (+3/-3)
src/location/nmea/sentence.h (+14/-22)
src/location/nmea/status.h (+8/-15)
src/location/nmea/talker.h (+8/-15)
src/location/nmea/txt.h (+9/-16)
src/location/nmea/utc.h (+8/-15)
src/location/nmea/vtg.h (+10/-17)
src/location/providers/CMakeLists.txt (+1/-0)
src/location/providers/config.cpp (+7/-0)
src/location/providers/sirf/CMakeLists.txt (+33/-0)
src/location/providers/sirf/bits.h (+49/-0)
src/location/providers/sirf/checksum.cpp (+28/-0)
src/location/providers/sirf/checksum.h (+42/-0)
src/location/providers/sirf/codec.h (+81/-0)
src/location/providers/sirf/dop.h (+64/-0)
src/location/providers/sirf/geodetic_navigation_data.h (+213/-0)
src/location/providers/sirf/initialize_data_source.h (+93/-0)
src/location/providers/sirf/magic.h (+43/-0)
src/location/providers/sirf/message.h (+53/-0)
src/location/providers/sirf/provider.cpp (+353/-0)
src/location/providers/sirf/provider.h (+143/-0)
src/location/providers/sirf/reader.cpp (+87/-0)
src/location/providers/sirf/reader.h (+52/-0)
src/location/providers/sirf/receiver.cpp (+80/-0)
src/location/providers/sirf/receiver.h (+92/-0)
src/location/providers/sirf/scanner.cpp (+161/-0)
src/location/providers/sirf/scanner.h (+76/-0)
src/location/providers/sirf/serial_port_receiver.cpp (+80/-0)
src/location/providers/sirf/serial_port_receiver.h (+79/-0)
src/location/providers/sirf/set_protocol.h (+73/-0)
src/location/providers/sirf/writer.cpp (+94/-0)
src/location/providers/sirf/writer.h (+54/-0)
src/location/providers/ubx/CMakeLists.txt (+5/-2)
src/location/providers/ubx/_8/receiver.cpp (+1/-1)
src/location/providers/ubx/_8/receiver.h (+4/-4)
src/location/providers/ubx/_8/scanner.cpp (+1/-1)
src/location/providers/ubx/provider.cpp (+28/-28)
src/location/providers/ubx/provider.h (+9/-9)
src/location/runtime_tests.cpp (+87/-0)
To merge this branch: bzr merge lp:~thomas-voss/location-service/add-sirf-support
Reviewer Review Type Date Requested Status
Simon Fels (community) Approve
Thomas Voß Pending
Review via email: mp+323629@code.launchpad.net

Commit message

Add support for SiRF providers.

Description of the change

Add support for SiRF providers.

To post a comment you must log in.
305. By Thomas Voß

Adjust formatting of output for locationd.monitor.

Revision history for this message
Simon Fels (morphis) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/location/CMakeLists.txt'
2--- src/location/CMakeLists.txt 2017-04-26 19:58:19 +0000
3+++ src/location/CMakeLists.txt 2017-05-05 09:37:41 +0000
4@@ -35,6 +35,12 @@
5 COMMAND ${GDBUS_CODEGEN_EXECUTABLE} --generate-c-code "${CMAKE_CURRENT_BINARY_DIR}/connectivity/w11t_gen" "${CMAKE_CURRENT_SOURCE_DIR}/connectivity/w11t.xml")
6
7 add_library(
8+ nmea
9+
10+ nmea/scanner.cpp
11+ nmea/sentence.cpp)
12+
13+add_library(
14 ubuntu-location-service SHARED
15
16 ${UBUNTU_LOCATION_SERVICE_PUBLIC_HEADERS}
17@@ -88,7 +94,7 @@
18 cmds/status.cpp
19 cmds/test.h
20 cmds/test.cpp
21-
22+
23 util/benchmark.h
24 util/benchmark.cpp
25 util/cli.h
26
27=== modified file 'src/location/cmds/monitor.cpp'
28--- src/location/cmds/monitor.cpp 2017-04-26 19:58:19 +0000
29+++ src/location/cmds/monitor.cpp 2017-05-05 09:37:41 +0000
30@@ -20,6 +20,7 @@
31 #include <location/cmds/monitor.h>
32
33 #include <location/criteria.h>
34+#include <location/logging.h>
35 #include <location/dbus/stub/service.h>
36 #include <location/glib/runtime.h>
37 #include <location/runtime.h>
38@@ -34,17 +35,84 @@
39
40 void location::cmds::Monitor::PrintingDelegate::on_new_position(const Update<Position>& pos)
41 {
42- out << pos << std::endl;
43+ last_position_update = pos;
44+ print_row();
45 }
46
47 void location::cmds::Monitor::PrintingDelegate::on_new_heading(const Update<units::Degrees>& heading)
48 {
49- out << heading << std::endl;
50+ last_heading_update = heading;
51+ print_row();
52 }
53
54 void location::cmds::Monitor::PrintingDelegate::on_new_velocity(const Update<units::MetersPerSecond>& velocity)
55 {
56- out << velocity << std::endl;
57+ last_velocity_update = velocity;
58+ print_row();
59+}
60+
61+void location::cmds::Monitor::PrintingDelegate::print_header()
62+{
63+ out << std::left << std::setw(15) << std::setfill(' ') << "lat.[deg]"
64+ << std::left << std::setw(15) << std::setfill(' ') << "lon.[deg]"
65+ << std::left << std::setw(15) << std::setfill(' ') << "hor.acc.[m]"
66+ << std::left << std::setw(15) << std::setfill(' ') << "alt.[m]"
67+ << std::left << std::setw(15) << std::setfill(' ') << "ver.acc.[m]"
68+ << std::left << std::setw(15) << std::setfill(' ') << "heading[deg]"
69+ << std::left << std::setw(15) << std::setfill(' ') << "vel.[m/s]" << std::endl;
70+}
71+
72+void location::cmds::Monitor::PrintingDelegate::print_row()
73+{
74+ if (last_position_update)
75+ {
76+ out << std::left << std::setw(15) << std::setfill(' ') << std::fixed << std::setprecision(5) << last_position_update->value.latitude().value();
77+ out << std::left << std::setw(15) << std::setfill(' ') << std::fixed << std::setprecision(5) << last_position_update->value.longitude().value();
78+
79+ if (last_position_update->value.accuracy().horizontal())
80+ out << std::left << std::setw(15) << std::setfill(' ') << std::fixed << std::setprecision(2) << last_position_update->value.accuracy().horizontal()->value() ;
81+ else
82+ out << std::left << std::setw(15) << std::setfill(' ') << "n/a" ;
83+
84+ if (last_position_update->value.altitude())
85+ out << std::left << std::setw(15) << std::setfill(' ') << std::fixed << std::setprecision(2) << last_position_update->value.altitude()->value() ;
86+ else
87+ out << std::left << std::setw(15) << std::setfill(' ') << "n/a" ;
88+
89+ if (last_position_update->value.accuracy().vertical())
90+ out << std::left << std::setw(15) << std::setfill(' ') << std::fixed << std::setprecision(2) << last_position_update->value.accuracy().vertical()->value() ;
91+ else
92+ out << std::left << std::setw(15) << std::setfill(' ') << "n/a" ;
93+ }
94+ else
95+ {
96+ out << std::left << std::setw(15) << std::setfill(' ') << "n/a" // latitude
97+ << std::left << std::setw(15) << std::setfill(' ') << "n/a" // longitude
98+ << std::left << std::setw(15) << std::setfill(' ') << "n/a" // horizontal accuracy
99+ << std::left << std::setw(15) << std::setfill(' ') << "n/a" // altitude
100+ << std::left << std::setw(15) << std::setfill(' ') << "n/a" ; // vertical accuracy
101+ }
102+
103+ if (last_heading_update)
104+ {
105+ out << std::left << std::setw(15) << std::setfill(' ') << last_heading_update->value.value() ;
106+ }
107+ else
108+ {
109+ out << std::left << std::setw(15) << std::setfill(' ') << "n/a" ;
110+ }
111+
112+ if (last_velocity_update)
113+ {
114+ out << std::left << std::setw(15) << std::setfill(' ') << last_velocity_update->value.value();
115+ }
116+ else
117+ {
118+ out << std::left << std::setw(15) << std::setfill(' ') << "n/a";
119+ }
120+
121+ out << std::endl;
122+
123 }
124
125 location::cmds::Monitor::Monitor(const std::shared_ptr<Delegate>& delegate)
126@@ -96,7 +164,7 @@
127 session->updates().heading_status = location::Service::Session::Updates::Status::enabled;
128 session->updates().velocity_status = location::Service::Session::Updates::Status::enabled;
129
130- ctxt.cout << "Enabled position/heading/velocity updates..." << std::endl;
131+ LOG(INFO) << "Enabled position/heading/velocity updates..." << std::endl;
132 });
133 });
134
135
136=== modified file 'src/location/cmds/monitor.h'
137--- src/location/cmds/monitor.h 2017-03-07 10:01:34 +0000
138+++ src/location/cmds/monitor.h 2017-05-05 09:37:41 +0000
139@@ -61,8 +61,15 @@
140 void on_new_position(const Update<Position>& pos) override;
141 void on_new_heading(const Update<units::Degrees>& heading) override;
142 void on_new_velocity(const Update<units::MetersPerSecond>& velocity) override;
143+
144 private:
145+ void print_header();
146+ void print_row();
147+
148 std::ostream& out;
149+ Optional<Update<Position>> last_position_update;
150+ Optional<Update<units::Degrees>> last_heading_update;
151+ Optional<Update<units::MetersPerSecond>> last_velocity_update;
152 };
153
154 // Monitor initializes a new instance.
155
156=== renamed directory 'src/location/providers/ubx/_8/nmea' => 'src/location/nmea'
157=== modified file 'src/location/nmea/cardinal_direction.h'
158--- src/location/providers/ubx/_8/nmea/cardinal_direction.h 2016-10-10 09:15:40 +0000
159+++ src/location/nmea/cardinal_direction.h 2017-05-05 09:37:41 +0000
160@@ -12,17 +12,11 @@
161 //
162 // You should have received a copy of the GNU Lesser General Public License
163 // along with this program. If not, see <http://www.gnu.org/licenses/>.
164-#ifndef UBX_8_NMEA_CARDINAL_DIRECTION_H_
165-#define UBX_8_NMEA_CARDINAL_DIRECTION_H_
166+#ifndef LOCATION_NMEA_CARDINAL_DIRECTION_H_
167+#define LOCATION_NMEA_CARDINAL_DIRECTION_H_
168
169 namespace location
170 {
171-namespace providers
172-{
173-namespace ubx
174-{
175-namespace _8
176-{
177 namespace nmea
178 {
179 /// @brief CardinalDirection enumerates the main cardinal direction
180@@ -36,8 +30,5 @@
181 };
182 }
183 }
184-}
185-}
186-}
187
188-#endif // UBX_8_NMEA_CARDINAL_DIRECTION_H_
189+#endif // LOCATION_NMEA_CARDINAL_DIRECTION_H_
190
191=== modified file 'src/location/nmea/date.h'
192--- src/location/providers/ubx/_8/nmea/date.h 2016-10-10 09:15:40 +0000
193+++ src/location/nmea/date.h 2017-05-05 09:37:41 +0000
194@@ -12,19 +12,13 @@
195 //
196 // You should have received a copy of the GNU Lesser General Public License
197 // along with this program. If not, see <http://www.gnu.org/licenses/>.
198-#ifndef UBX_8_NMEA_DATE_H_
199-#define UBX_8_NMEA_DATE_H_
200+#ifndef LOCATION_NMEA_DATE_H_
201+#define LOCATION_NMEA_DATE_H_
202
203 #include <cstdint>
204
205 namespace location
206 {
207-namespace providers
208-{
209-namespace ubx
210-{
211-namespace _8
212-{
213 namespace nmea
214 {
215 /// @brief Date models a specific calendar day (Gregorian calendar).
216@@ -36,8 +30,5 @@
217 };
218 }
219 }
220-}
221-}
222-}
223
224-#endif // UBX_8_NMEA_DATE_H_
225+#endif // LOCATION_NMEA_DATE_H_
226
227=== modified file 'src/location/nmea/fusion_adapt.h'
228--- src/location/providers/ubx/_8/nmea/fusion_adapt.h 2016-10-10 09:15:40 +0000
229+++ src/location/nmea/fusion_adapt.h 2017-05-05 09:37:41 +0000
230@@ -12,123 +12,123 @@
231 //
232 // You should have received a copy of the GNU Lesser General Public License
233 // along with this program. If not, see <http://www.gnu.org/licenses/>.
234-#ifndef UBX_8_NMEA_FUSION_ADAPT_H_
235-#define UBX_8_NMEA_FUSION_ADAPT_H_
236+#ifndef LOCATION_NMEA_FUSION_ADAPT_H_
237+#define LOCATION_NMEA_FUSION_ADAPT_H_
238
239 #define BOOST_SPIRIT_DEBUG
240 #define FUSION_MAX_VECTOR_SIZE 15
241
242-#include <location/providers/ubx/_8/nmea/sentence.h>
243+#include <location/nmea/sentence.h>
244
245 #include <boost/fusion/adapted/struct.hpp>
246
247 // clang-format off
248 BOOST_FUSION_ADAPT_STRUCT(
249- location::providers::ubx::_8::nmea::Latitude,
250- (uint32_t, degrees)
251- (double, minutes))
252-
253-BOOST_FUSION_ADAPT_STRUCT(
254- location::providers::ubx::_8::nmea::Longitude,
255- (uint32_t, degrees)
256- (double, minutes))
257-
258-BOOST_FUSION_ADAPT_STRUCT(
259- location::providers::ubx::_8::nmea::Date,
260+ location::nmea::Latitude,
261+ (uint32_t, degrees)
262+ (double, minutes))
263+
264+BOOST_FUSION_ADAPT_STRUCT(
265+ location::nmea::Longitude,
266+ (uint32_t, degrees)
267+ (double, minutes))
268+
269+BOOST_FUSION_ADAPT_STRUCT(
270+ location::nmea::Date,
271 (std::uint8_t, day)
272 (std::uint8_t, month)
273 (std::uint8_t, year))
274
275 BOOST_FUSION_ADAPT_STRUCT(
276- location::providers::ubx::_8::nmea::Utc,
277+ location::nmea::Utc,
278 (std::uint8_t, hours)
279 (std::uint8_t, minutes)
280 (double, seconds))
281
282 BOOST_FUSION_ADAPT_STRUCT(
283- location::providers::ubx::_8::nmea::Gsa,
284- (location::providers::ubx::_8::nmea::Talker, talker)
285- (boost::optional<location::providers::ubx::_8::nmea::Gsa::OperationMode>, operation_mode)
286- (boost::optional<location::providers::ubx::_8::nmea::Gsa::FixMode>, fix_mode)
287+ location::nmea::Gsa,
288+ (location::nmea::Talker, talker)
289+ (boost::optional<location::nmea::Gsa::OperationMode>, operation_mode)
290+ (boost::optional<location::nmea::Gsa::FixMode>, fix_mode)
291 (std::vector<boost::optional<std::uint8_t>>, satellite_ids)
292- (boost::optional<location::providers::ubx::Dop<location::providers::ubx::tag::Positional>>, pdop)
293- (boost::optional<location::providers::ubx::Dop<location::providers::ubx::tag::Horizontal>>, hdop)
294- (boost::optional<location::providers::ubx::Dop<location::providers::ubx::tag::Vertical>>, vdop))
295+ (boost::optional<float>, pdop)
296+ (boost::optional<float>, hdop)
297+ (boost::optional<float>, vdop))
298
299 BOOST_FUSION_ADAPT_STRUCT(
300- location::providers::ubx::_8::nmea::Gga,
301- (location::providers::ubx::_8::nmea::Talker, talker)
302- (boost::optional<location::providers::ubx::_8::nmea::Utc>, utc)
303- (boost::optional<location::providers::ubx::_8::nmea::Latitude>, latitude)
304- (boost::optional<location::providers::ubx::_8::nmea::CardinalDirection>, latitude_direction)
305- (boost::optional<location::providers::ubx::_8::nmea::Longitude>, longitude)
306- (boost::optional<location::providers::ubx::_8::nmea::CardinalDirection>, longitude_direction)
307- (boost::optional<location::providers::ubx::_8::nmea::gps::FixMode>, fix_mode)
308+ location::nmea::Gga,
309+ (location::nmea::Talker, talker)
310+ (boost::optional<location::nmea::Utc>, utc)
311+ (boost::optional<location::nmea::Latitude>, latitude)
312+ (boost::optional<location::nmea::CardinalDirection>, latitude_direction)
313+ (boost::optional<location::nmea::Longitude>, longitude)
314+ (boost::optional<location::nmea::CardinalDirection>, longitude_direction)
315+ (boost::optional<location::nmea::gps::FixMode>, fix_mode)
316 (boost::optional<std::uint8_t>, satellites_in_use)
317- (boost::optional<location::providers::ubx::Dop<location::providers::ubx::tag::Horizontal>>, hdop)
318+ (boost::optional<float>, hdop)
319 (boost::optional<float>, altitude)
320 (boost::optional<float>, geoidal_separation)
321 (boost::optional<float>, age)
322 (boost::optional<std::uint16_t>, differential_reference_station))
323
324 BOOST_FUSION_ADAPT_STRUCT(
325- location::providers::ubx::_8::nmea::Gll,
326- (location::providers::ubx::_8::nmea::Talker, talker)
327- (boost::optional<location::providers::ubx::_8::nmea::Latitude>, latitude)
328- (boost::optional<location::providers::ubx::_8::nmea::CardinalDirection>, latitude_direction)
329- (boost::optional<location::providers::ubx::_8::nmea::Longitude>, longitude)
330- (boost::optional<location::providers::ubx::_8::nmea::CardinalDirection>, longitude_direction)
331- (boost::optional<location::providers::ubx::_8::nmea::Utc>, utc)
332- (boost::optional<location::providers::ubx::_8::nmea::Status>, status)
333- (boost::optional<location::providers::ubx::_8::nmea::Mode>, mode))
334+ location::nmea::Gll,
335+ (location::nmea::Talker, talker)
336+ (boost::optional<location::nmea::Latitude>, latitude)
337+ (boost::optional<location::nmea::CardinalDirection>, latitude_direction)
338+ (boost::optional<location::nmea::Longitude>, longitude)
339+ (boost::optional<location::nmea::CardinalDirection>, longitude_direction)
340+ (boost::optional<location::nmea::Utc>, utc)
341+ (boost::optional<location::nmea::Status>, status)
342+ (boost::optional<location::nmea::Mode>, mode))
343
344 BOOST_FUSION_ADAPT_STRUCT(
345- location::providers::ubx::_8::nmea::Gsv::Info,
346+ location::nmea::Gsv::Info,
347 (boost::optional<std::uint8_t>, satellite_id)
348 (boost::optional<std::uint8_t>, elevation)
349 (boost::optional<std::uint16_t>, azimuth)
350 (boost::optional<std::uint8_t>, snr))
351
352 BOOST_FUSION_ADAPT_STRUCT(
353- location::providers::ubx::_8::nmea::Gsv,
354- (location::providers::ubx::_8::nmea::Talker, talker)
355+ location::nmea::Gsv,
356+ (location::nmea::Talker, talker)
357 (boost::optional<std::uint8_t>, sentence_count)
358 (boost::optional<std::uint8_t>, sentence_number)
359 (boost::optional<std::uint8_t>, satellites_count)
360- (std::vector<location::providers::ubx::_8::nmea::Gsv::Info>, satellites_info))
361+ (std::vector<location::nmea::Gsv::Info>, satellites_info))
362
363 BOOST_FUSION_ADAPT_STRUCT(
364- location::providers::ubx::_8::nmea::Rmc,
365- (location::providers::ubx::_8::nmea::Talker, talker)
366- (boost::optional<location::providers::ubx::_8::nmea::Utc>, utc)
367- (boost::optional<location::providers::ubx::_8::nmea::Status>, status)
368- (boost::optional<location::providers::ubx::_8::nmea::Latitude>, latitude)
369- (boost::optional<location::providers::ubx::_8::nmea::CardinalDirection>, latitude_direction)
370- (boost::optional<location::providers::ubx::_8::nmea::Longitude>, longitude)
371- (boost::optional<location::providers::ubx::_8::nmea::CardinalDirection>, longitude_direction)
372+ location::nmea::Rmc,
373+ (location::nmea::Talker, talker)
374+ (boost::optional<location::nmea::Utc>, utc)
375+ (boost::optional<location::nmea::Status>, status)
376+ (boost::optional<location::nmea::Latitude>, latitude)
377+ (boost::optional<location::nmea::CardinalDirection>, latitude_direction)
378+ (boost::optional<location::nmea::Longitude>, longitude)
379+ (boost::optional<location::nmea::CardinalDirection>, longitude_direction)
380 (boost::optional<float>, speed_over_ground)(boost::optional<float>, course_over_ground)
381- (boost::optional<location::providers::ubx::_8::nmea::Date>, date)
382+ (boost::optional<location::nmea::Date>, date)
383 (boost::optional<float>, magnetic_variation)
384- (boost::optional<location::providers::ubx::_8::nmea::CardinalDirection>, cardinal_direction)
385- (boost::optional<location::providers::ubx::_8::nmea::Mode>, mode))
386+ (boost::optional<location::nmea::CardinalDirection>, cardinal_direction)
387+ (boost::optional<location::nmea::Mode>, mode))
388
389 BOOST_FUSION_ADAPT_STRUCT(
390- location::providers::ubx::_8::nmea::Txt,
391- (location::providers::ubx::_8::nmea::Talker, talker)
392+ location::nmea::Txt,
393+ (location::nmea::Talker, talker)
394 (boost::optional<std::uint8_t>, total_number_of_sentences)
395 (boost::optional<std::uint8_t>, sentence_number)
396 (boost::optional<std::uint8_t>, identifier)
397 (boost::optional<std::string>, message))
398
399 BOOST_FUSION_ADAPT_STRUCT(
400- location::providers::ubx::_8::nmea::Vtg,
401- (location::providers::ubx::_8::nmea::Talker, talker)
402+ location::nmea::Vtg,
403+ (location::nmea::Talker, talker)
404 (boost::optional<float>, cog_true)
405 (boost::optional<float>, cog_magnetic)
406 (boost::optional<float>, sog_knots)
407 (boost::optional<float>, sog_kmh)
408- (boost::optional<location::providers::ubx::_8::nmea::Mode>, mode))
409+ (boost::optional<location::nmea::Mode>, mode))
410
411 // clang-format on
412
413-#endif // UBX_8_NMEA_FUSION_ADAPT_H_
414+#endif // LOCATION_NMEA_FUSION_ADAPT_H_
415
416=== modified file 'src/location/nmea/generator.h'
417--- src/location/providers/ubx/_8/nmea/generator.h 2017-03-09 09:42:25 +0000
418+++ src/location/nmea/generator.h 2017-05-05 09:37:41 +0000
419@@ -12,15 +12,14 @@
420 //
421 // You should have received a copy of the GNU Lesser General Public License
422 // along with this program. If not, see <http://www.gnu.org/licenses/>.
423-#ifndef UBX_8_NMEA_GENERATOR_H_
424-#define UBX_8_NMEA_GENERATOR_H_
425+#ifndef LOCATION_NMEA_GENERATOR_H_
426+#define LOCATION_NMEA_GENERATOR_H_
427
428-#define BOOST_SPIRIT_DEBUG
429 #define FUSION_MAX_VECTOR_SIZE 15
430
431-#include <location/providers/ubx/_8/nmea/sentence.h>
432+#include <location/nmea/sentence.h>
433
434-#include <location/providers/ubx/_8/nmea/fusion_adapt.h>
435+#include <location/nmea/fusion_adapt.h>
436
437 #include <boost/spirit/include/classic.hpp>
438 #include <boost/spirit/include/karma.hpp>
439@@ -31,12 +30,6 @@
440
441 namespace location
442 {
443-namespace providers
444-{
445-namespace ubx
446-{
447-namespace _8
448-{
449 namespace nmea
450 {
451
452@@ -209,9 +202,9 @@
453 boost::spirit::karma::rule<Iterator, Longitude()> longitude;
454 boost::spirit::karma::rule<Iterator, Date()> date;
455 boost::spirit::karma::rule<Iterator, Utc()> utc;
456- boost::spirit::karma::rule<Iterator, Dop<tag::Positional>()> pdop;
457- boost::spirit::karma::rule<Iterator, Dop<tag::Horizontal>()> hdop;
458- boost::spirit::karma::rule<Iterator, Dop<tag::Vertical>()> vdop;
459+ boost::spirit::karma::rule<Iterator, float()> pdop;
460+ boost::spirit::karma::rule<Iterator, float()> hdop;
461+ boost::spirit::karma::rule<Iterator, float()> vdop;
462
463 boost::spirit::karma::rule<Iterator, Gsa()> gsa;
464 boost::spirit::karma::rule<Iterator, Gga()> gga;
465@@ -246,10 +239,8 @@
466 boost::spirit::karma::symbols<Gsa::FixMode, char> fix_mode;
467 } for_gsa;
468 };
469-}
470-}
471-}
472-}
473-}
474-
475-#endif // UBX_8_NMEA_GENERATOR_H_
476+
477+}
478+}
479+
480+#endif // LOCATION_NMEA_GENERATOR_H_
481
482=== modified file 'src/location/nmea/gga.h'
483--- src/location/providers/ubx/_8/nmea/gga.h 2016-10-10 09:15:40 +0000
484+++ src/location/nmea/gga.h 2017-05-05 09:37:41 +0000
485@@ -12,18 +12,18 @@
486 //
487 // You should have received a copy of the GNU Lesser General Public License
488 // along with this program. If not, see <http://www.gnu.org/licenses/>.
489-#ifndef UBX_8_NMEA_GGA_H_
490-#define UBX_8_NMEA_GGA_H_
491+#ifndef LOCATION_NMEA_GGA_H_
492+#define LOCATION_NMEA_GGA_H_
493
494 #include <location/providers/ubx/dop.h>
495
496-#include <location/providers/ubx/_8/nmea/cardinal_direction.h>
497-#include <location/providers/ubx/_8/nmea/latitude.h>
498-#include <location/providers/ubx/_8/nmea/longitude.h>
499-#include <location/providers/ubx/_8/nmea/talker.h>
500-#include <location/providers/ubx/_8/nmea/utc.h>
501+#include <location/nmea/cardinal_direction.h>
502+#include <location/nmea/latitude.h>
503+#include <location/nmea/longitude.h>
504+#include <location/nmea/talker.h>
505+#include <location/nmea/utc.h>
506
507-#include <location/providers/ubx/_8/nmea/gps/fix_mode.h>
508+#include <location/nmea/gps/fix_mode.h>
509
510 #include <boost/optional.hpp>
511
512@@ -31,14 +31,9 @@
513
514 namespace location
515 {
516-namespace providers
517-{
518-namespace ubx
519-{
520-namespace _8
521-{
522 namespace nmea
523 {
524+
525 /// @brief Global positioning system fix data.
526 ///
527 /// Time and position, together with GPS fixing related data (number of
528@@ -54,16 +49,14 @@
529 boost::optional<CardinalDirection> longitude_direction;
530 boost::optional<gps::FixMode> fix_mode;
531 boost::optional<std::uint8_t> satellites_in_use;
532- boost::optional<Dop<tag::Horizontal>> hdop;
533+ boost::optional<float> hdop;
534 boost::optional<float> altitude;
535 boost::optional<float> geoidal_separation;
536 boost::optional<float> age; // [s]
537 boost::optional<std::uint16_t> differential_reference_station;
538 };
539-}
540-}
541-}
542-}
543-}
544-
545-#endif // UBX_8_NMEA_GGA_H_
546+
547+}
548+}
549+
550+#endif // LOCATION_NMEA_GGA_H_
551
552=== modified file 'src/location/nmea/gll.h'
553--- src/location/providers/ubx/_8/nmea/gll.h 2016-10-10 09:15:40 +0000
554+++ src/location/nmea/gll.h 2017-05-05 09:37:41 +0000
555@@ -12,29 +12,24 @@
556 //
557 // You should have received a copy of the GNU Lesser General Public License
558 // along with this program. If not, see <http://www.gnu.org/licenses/>.
559-#ifndef UBX_8_NMEA_GLL_H_
560-#define UBX_8_NMEA_GLL_H_
561+#ifndef LOCATION_NMEA_GLL_H_
562+#define LOCATION_NMEA_GLL_H_
563
564-#include <location/providers/ubx/_8/nmea/cardinal_direction.h>
565-#include <location/providers/ubx/_8/nmea/latitude.h>
566-#include <location/providers/ubx/_8/nmea/longitude.h>
567-#include <location/providers/ubx/_8/nmea/mode.h>
568-#include <location/providers/ubx/_8/nmea/status.h>
569-#include <location/providers/ubx/_8/nmea/talker.h>
570-#include <location/providers/ubx/_8/nmea/utc.h>
571+#include <location/nmea/cardinal_direction.h>
572+#include <location/nmea/latitude.h>
573+#include <location/nmea/longitude.h>
574+#include <location/nmea/mode.h>
575+#include <location/nmea/status.h>
576+#include <location/nmea/talker.h>
577+#include <location/nmea/utc.h>
578
579 #include <boost/optional.hpp>
580
581 namespace location
582 {
583-namespace providers
584-{
585-namespace ubx
586-{
587-namespace _8
588-{
589 namespace nmea
590 {
591+
592 /// @brief Latitude and longitude, with time of position fix and status
593 struct Gll
594 {
595@@ -49,8 +44,5 @@
596 };
597 }
598 }
599-}
600-}
601-}
602
603-#endif // UBX_8_NMEA_GLL_H_
604+#endif // LOCATION_NMEA_GLL_H_
605
606=== modified file 'src/location/nmea/gps/fix_mode.h'
607--- src/location/providers/ubx/_8/nmea/gps/fix_mode.h 2016-10-10 09:15:40 +0000
608+++ src/location/nmea/gps/fix_mode.h 2017-05-05 09:37:41 +0000
609@@ -12,21 +12,16 @@
610 //
611 // You should have received a copy of the GNU Lesser General Public License
612 // along with this program. If not, see <http://www.gnu.org/licenses/>.
613-#ifndef UBX_8_NMEA_GPS_FIX_MODE_H_
614-#define UBX_8_NMEA_GPS_FIX_MODE_H_
615+#ifndef LOCATION_NMEA_GPS_FIX_MODE_H_
616+#define LOCATION_NMEA_GPS_FIX_MODE_H_
617
618 namespace location
619 {
620-namespace providers
621-{
622-namespace ubx
623-{
624-namespace _8
625-{
626 namespace nmea
627 {
628 namespace gps
629 {
630+
631 /// @brief FixMode enumerates all known, gps-specific fix modes.
632 enum class FixMode
633 {
634@@ -40,11 +35,9 @@
635 manual_input = 7,
636 simulator = 8
637 };
638-}
639-}
640-}
641-}
642-}
643-}
644-
645-#endif // UBX_8_NMEA_GPS_FIX_MODE_H_
646+
647+}
648+}
649+}
650+
651+#endif // LOCATION_NMEA_GPS_FIX_MODE_H_
652
653=== modified file 'src/location/nmea/grammar.h'
654--- src/location/providers/ubx/_8/nmea/grammar.h 2017-03-09 09:42:25 +0000
655+++ src/location/nmea/grammar.h 2017-05-05 09:37:41 +0000
656@@ -12,13 +12,12 @@
657 //
658 // You should have received a copy of the GNU Lesser General Public License
659 // along with this program. If not, see <http://www.gnu.org/licenses/>.
660-#ifndef UBX_8_NMEA_GRAMMAR_H_
661-#define UBX_8_NMEA_GRAMMAR_H_
662+#ifndef LOCATION_NMEA_GRAMMAR_H_
663+#define LOCATION_NMEA_GRAMMAR_H_
664
665-#define BOOST_SPIRIT_DEBUG
666 #define FUSION_MAX_VECTOR_SIZE 15
667
668-#include <location/providers/ubx/_8/nmea/fusion_adapt.h>
669+#include <location/nmea/fusion_adapt.h>
670
671 #include <boost/spirit/include/classic.hpp>
672 #include <boost/spirit/include/qi.hpp>
673@@ -29,12 +28,6 @@
674
675 namespace location
676 {
677-namespace providers
678-{
679-namespace ubx
680-{
681-namespace _8
682-{
683 namespace nmea
684 {
685
686@@ -206,9 +199,9 @@
687 boost::spirit::qi::rule<Iterator, Longitude()> longitude;
688 boost::spirit::qi::rule<Iterator, Date()> date;
689 boost::spirit::qi::rule<Iterator, Utc()> utc;
690- boost::spirit::qi::rule<Iterator, Dop<tag::Positional>()> pdop;
691- boost::spirit::qi::rule<Iterator, Dop<tag::Horizontal>()> hdop;
692- boost::spirit::qi::rule<Iterator, Dop<tag::Vertical>()> vdop;
693+ boost::spirit::qi::rule<Iterator, float()> pdop;
694+ boost::spirit::qi::rule<Iterator, float()> hdop;
695+ boost::spirit::qi::rule<Iterator, float()> vdop;
696
697 boost::spirit::qi::rule<Iterator, Gsa()> gsa;
698 boost::spirit::qi::rule<Iterator, Gga()> gga;
699@@ -245,8 +238,5 @@
700 };
701 }
702 }
703-}
704-}
705-}
706
707-#endif // UBX_8_NMEA_GRAMMAR_H_
708+#endif // LOCATION_NMEA_GRAMMAR_H_
709
710=== modified file 'src/location/nmea/gsa.h'
711--- src/location/providers/ubx/_8/nmea/gsa.h 2016-10-10 09:15:40 +0000
712+++ src/location/nmea/gsa.h 2017-05-05 09:37:41 +0000
713@@ -12,16 +12,16 @@
714 //
715 // You should have received a copy of the GNU Lesser General Public License
716 // along with this program. If not, see <http://www.gnu.org/licenses/>.
717-#ifndef UBX_8_NMEA_GSA_H_
718-#define UBX_8_NMEA_GSA_H_
719+#ifndef LOCATION_NMEA_GSA_H_
720+#define LOCATION_NMEA_GSA_H_
721
722 #include <location/providers/ubx/dop.h>
723
724-#include <location/providers/ubx/_8/nmea/latitude.h>
725-#include <location/providers/ubx/_8/nmea/longitude.h>
726-#include <location/providers/ubx/_8/nmea/talker.h>
727+#include <location/nmea/latitude.h>
728+#include <location/nmea/longitude.h>
729+#include <location/nmea/talker.h>
730
731-#include <location/providers/ubx/_8/nmea/gps/fix_mode.h>
732+#include <location/nmea/gps/fix_mode.h>
733
734 #include <boost/optional.hpp>
735
736@@ -30,12 +30,6 @@
737
738 namespace location
739 {
740-namespace providers
741-{
742-namespace ubx
743-{
744-namespace _8
745-{
746 namespace nmea
747 {
748 /// @brief GNSS DOP and Active Satellites.
749@@ -71,14 +65,11 @@
750 boost::optional<OperationMode> operation_mode;
751 boost::optional<FixMode> fix_mode;
752 std::vector<boost::optional<std::uint8_t>> satellite_ids;
753- boost::optional<Dop<tag::Positional>> pdop;
754- boost::optional<Dop<tag::Horizontal>> hdop;
755- boost::optional<Dop<tag::Vertical>> vdop;
756+ boost::optional<float> pdop;
757+ boost::optional<float> hdop;
758+ boost::optional<float> vdop;
759 };
760 }
761 }
762-}
763-}
764-}
765
766-#endif // UBX_8_NMEA_GSA_H_
767+#endif // LOCATION_NMEA_GSA_H_
768
769=== modified file 'src/location/nmea/gsv.h'
770--- src/location/providers/ubx/_8/nmea/gsv.h 2016-10-10 09:15:40 +0000
771+++ src/location/nmea/gsv.h 2017-05-05 09:37:41 +0000
772@@ -12,10 +12,10 @@
773 //
774 // You should have received a copy of the GNU Lesser General Public License
775 // along with this program. If not, see <http://www.gnu.org/licenses/>.
776-#ifndef UBX_8_NMEA_GSV_H_
777-#define UBX_8_NMEA_GSV_H_
778+#ifndef LOCATION_NMEA_GSV_H_
779+#define LOCATION_NMEA_GSV_H_
780
781-#include <location/providers/ubx/_8/nmea/talker.h>
782+#include <location/nmea/talker.h>
783
784 #include <boost/optional.hpp>
785
786@@ -25,14 +25,9 @@
787
788 namespace location
789 {
790-namespace providers
791-{
792-namespace ubx
793-{
794-namespace _8
795-{
796 namespace nmea
797 {
798+
799 /// @brief GNSS Satellites in View.
800 ///
801 /// The number of satellites in view, together with each SV ID, elevation
802@@ -57,10 +52,8 @@
803 boost::optional<std::uint8_t> satellites_count;
804 std::vector<Info> satellites_info;
805 };
806-}
807-}
808-}
809-}
810-}
811-
812-#endif // UBX_8_NMEA_GSV_H_
813+
814+}
815+}
816+
817+#endif // LOCATION_NMEA_GSV_H_
818
819=== modified file 'src/location/nmea/latitude.h'
820--- src/location/providers/ubx/_8/nmea/latitude.h 2016-10-10 09:15:40 +0000
821+++ src/location/nmea/latitude.h 2017-05-05 09:37:41 +0000
822@@ -12,31 +12,24 @@
823 //
824 // You should have received a copy of the GNU Lesser General Public License
825 // along with this program. If not, see <http://www.gnu.org/licenses/>.
826-#ifndef UBX_8_NMEA_LATITUDE_H_
827-#define UBX_8_NMEA_LATITUDE_H_
828+#ifndef LOCATION_NMEA_LATITUDE_H_
829+#define LOCATION_NMEA_LATITUDE_H_
830
831 #include <cstdint>
832
833 namespace location
834 {
835-namespace providers
836-{
837-namespace ubx
838-{
839-namespace _8
840-{
841 namespace nmea
842 {
843+
844 /// @brief Latitude as defined in wgs84.
845 struct Latitude
846 {
847 std::uint32_t degrees;
848 double minutes;
849 };
850-}
851-}
852-}
853-}
854-}
855-
856-#endif // UBX_8_NMEA_LATITUDE_H_
857+
858+}
859+}
860+
861+#endif // LOCATION_NMEA_LATITUDE_H_
862
863=== modified file 'src/location/nmea/longitude.h'
864--- src/location/providers/ubx/_8/nmea/longitude.h 2016-10-10 09:15:40 +0000
865+++ src/location/nmea/longitude.h 2017-05-05 09:37:41 +0000
866@@ -12,31 +12,24 @@
867 //
868 // You should have received a copy of the GNU Lesser General Public License
869 // along with this program. If not, see <http://www.gnu.org/licenses/>.
870-#ifndef UBX_8_NMEA_LONGITUDE_H_
871-#define UBX_8_NMEA_LONGITUDE_H_
872+#ifndef LOCATION_NMEA_LONGITUDE_H_
873+#define LOCATION_NMEA_LONGITUDE_H_
874
875 #include <cstdint>
876
877 namespace location
878 {
879-namespace providers
880-{
881-namespace ubx
882-{
883-namespace _8
884-{
885 namespace nmea
886 {
887+
888 /// @brief Longitude as defined in wgs84.
889 struct Longitude
890 {
891 std::uint32_t degrees;
892 double minutes;
893 };
894-}
895-}
896-}
897-}
898-}
899-
900-#endif // UBX_8_NMEA_LONGITUDE_H_
901+
902+}
903+}
904+
905+#endif // LOCATION_NMEA_LONGITUDE_H_
906
907=== modified file 'src/location/nmea/mode.h'
908--- src/location/providers/ubx/_8/nmea/mode.h 2016-10-10 09:15:40 +0000
909+++ src/location/nmea/mode.h 2017-05-05 09:37:41 +0000
910@@ -12,19 +12,14 @@
911 //
912 // You should have received a copy of the GNU Lesser General Public License
913 // along with this program. If not, see <http://www.gnu.org/licenses/>.
914-#ifndef UBX_8_NMEA_MODE_H_
915-#define UBX_8_NMEA_MODE_H_
916+#ifndef LOCATION_NMEA_MODE_H_
917+#define LOCATION_NMEA_MODE_H_
918
919 namespace location
920 {
921-namespace providers
922-{
923-namespace ubx
924-{
925-namespace _8
926-{
927 namespace nmea
928 {
929+
930 /// @brief Mode enumerates all known NMEA positioning modes.
931 enum class Mode
932 {
933@@ -35,10 +30,8 @@
934 simulator_mode = 'S',
935 data_not_valid = 'N'
936 };
937-}
938-}
939-}
940-}
941-}
942-
943-#endif // UBX_8_NMEA_MODE_H_
944+
945+}
946+}
947+
948+#endif // LOCATION_NMEA_MODE_H_
949
950=== modified file 'src/location/nmea/rmc.h'
951--- src/location/providers/ubx/_8/nmea/rmc.h 2016-10-10 09:15:40 +0000
952+++ src/location/nmea/rmc.h 2017-05-05 09:37:41 +0000
953@@ -12,17 +12,17 @@
954 //
955 // You should have received a copy of the GNU Lesser General Public License
956 // along with this program. If not, see <http://www.gnu.org/licenses/>.
957-#ifndef UBX_8_NMEA_RMC_H_
958-#define UBX_8_NMEA_RMC_H_
959+#ifndef LOCATION_NMEA_RMC_H_
960+#define LOCATION_NMEA_RMC_H_
961
962-#include <location/providers/ubx/_8/nmea/cardinal_direction.h>
963-#include <location/providers/ubx/_8/nmea/date.h>
964-#include <location/providers/ubx/_8/nmea/latitude.h>
965-#include <location/providers/ubx/_8/nmea/longitude.h>
966-#include <location/providers/ubx/_8/nmea/mode.h>
967-#include <location/providers/ubx/_8/nmea/status.h>
968-#include <location/providers/ubx/_8/nmea/talker.h>
969-#include <location/providers/ubx/_8/nmea/utc.h>
970+#include <location/nmea/cardinal_direction.h>
971+#include <location/nmea/date.h>
972+#include <location/nmea/latitude.h>
973+#include <location/nmea/longitude.h>
974+#include <location/nmea/mode.h>
975+#include <location/nmea/status.h>
976+#include <location/nmea/talker.h>
977+#include <location/nmea/utc.h>
978
979 #include <boost/optional.hpp>
980
981@@ -32,14 +32,9 @@
982
983 namespace location
984 {
985-namespace providers
986-{
987-namespace ubx
988-{
989-namespace _8
990-{
991 namespace nmea
992 {
993+
994 /// @brief Recommended Minimum data.
995 ///
996 /// The recommended minimum sentence defined by NMEA for GNSS system data.
997@@ -59,10 +54,8 @@
998 boost::optional<CardinalDirection> cardinal_direction;
999 boost::optional<Mode> mode;
1000 };
1001-}
1002-}
1003-}
1004-}
1005-}
1006-
1007-#endif // UBX_8_NMEA_RMC_H_
1008+
1009+}
1010+}
1011+
1012+#endif // LOCATION_NMEA_RMC_H_
1013
1014=== modified file 'src/location/nmea/scanner.cpp'
1015--- src/location/providers/ubx/_8/nmea/scanner.cpp 2017-03-23 12:32:38 +0000
1016+++ src/location/nmea/scanner.cpp 2017-05-05 09:37:41 +0000
1017@@ -13,11 +13,11 @@
1018 // You should have received a copy of the GNU Lesser General Public License
1019 // along with this program. If not, see <http://www.gnu.org/licenses/>.
1020
1021-#include <location/providers/ubx/_8/nmea/scanner.h>
1022+#include <location/nmea/scanner.h>
1023
1024 #include <stdexcept>
1025
1026-namespace nmea = location::providers::ubx::_8::nmea;
1027+namespace nmea = location::nmea;
1028
1029 nmea::Scanner::Expect nmea::Scanner::update(char c) {
1030 switch (state) {
1031
1032=== modified file 'src/location/nmea/scanner.h'
1033--- src/location/providers/ubx/_8/nmea/scanner.h 2016-10-10 09:15:40 +0000
1034+++ src/location/nmea/scanner.h 2017-05-05 09:37:41 +0000
1035@@ -12,22 +12,17 @@
1036 //
1037 // You should have received a copy of the GNU Lesser General Public License
1038 // along with this program. If not, see <http://www.gnu.org/licenses/>.
1039-#ifndef UBX_8_NMEA_SCANNER_H_
1040-#define UBX_8_NMEA_SCANNER_H_
1041+#ifndef LOCATION_NMEA_SCANNER_H_
1042+#define LOCATION_NMEA_SCANNER_H_
1043
1044 #include <sstream>
1045 #include <string>
1046
1047 namespace location
1048 {
1049-namespace providers
1050-{
1051-namespace ubx
1052-{
1053-namespace _8
1054-{
1055 namespace nmea
1056 {
1057+
1058 /// @brief Scanner inspects incoming characters and tries to identify beginning
1059 /// and end of
1060 /// NMEA messages.
1061@@ -58,10 +53,8 @@
1062 Expect state{Expect::dollar}; ///< The state of the Scanner.
1063 std::stringstream ss; ///< Buffer holding incomplete sentence data.
1064 };
1065-}
1066-}
1067-}
1068-}
1069-}
1070-
1071-#endif // UBX_8_NMEA_SCANNER_H_
1072+
1073+}
1074+}
1075+
1076+#endif // LOCATION_NMEA_SCANNER_H_
1077
1078=== modified file 'src/location/nmea/sentence.cpp'
1079--- src/location/providers/ubx/_8/nmea/sentence.cpp 2016-10-10 09:15:40 +0000
1080+++ src/location/nmea/sentence.cpp 2017-05-05 09:37:41 +0000
1081@@ -13,12 +13,12 @@
1082 // You should have received a copy of the GNU Lesser General Public License
1083 // along with this program. If not, see <http://www.gnu.org/licenses/>.
1084
1085-#include <location/providers/ubx/_8/nmea/generator.h>
1086-#include <location/providers/ubx/_8/nmea/grammar.h>
1087+#include <location/nmea/generator.h>
1088+#include <location/nmea/grammar.h>
1089
1090 #include <iterator>
1091
1092-namespace nmea = location::providers::ubx::_8::nmea;
1093+namespace nmea = location::nmea;
1094
1095 namespace {
1096 template <typename Iterator>
1097
1098=== modified file 'src/location/nmea/sentence.h'
1099--- src/location/providers/ubx/_8/nmea/sentence.h 2016-10-10 09:15:40 +0000
1100+++ src/location/nmea/sentence.h 2017-05-05 09:37:41 +0000
1101@@ -12,16 +12,16 @@
1102 //
1103 // You should have received a copy of the GNU Lesser General Public License
1104 // along with this program. If not, see <http://www.gnu.org/licenses/>.
1105-#ifndef UBX_8_NMEA_SENTENCE_H_
1106-#define UBX_8_NMEA_SENTENCE_H_
1107+#ifndef LOCATION_NMEA_SENTENCE_H_
1108+#define LOCATION_NMEA_SENTENCE_H_
1109
1110-#include <location/providers/ubx/_8/nmea/gga.h>
1111-#include <location/providers/ubx/_8/nmea/gll.h>
1112-#include <location/providers/ubx/_8/nmea/gsa.h>
1113-#include <location/providers/ubx/_8/nmea/gsv.h>
1114-#include <location/providers/ubx/_8/nmea/rmc.h>
1115-#include <location/providers/ubx/_8/nmea/txt.h>
1116-#include <location/providers/ubx/_8/nmea/vtg.h>
1117+#include <location/nmea/gga.h>
1118+#include <location/nmea/gll.h>
1119+#include <location/nmea/gsa.h>
1120+#include <location/nmea/gsv.h>
1121+#include <location/nmea/rmc.h>
1122+#include <location/nmea/txt.h>
1123+#include <location/nmea/vtg.h>
1124
1125 #include <boost/variant.hpp>
1126
1127@@ -29,12 +29,6 @@
1128
1129 namespace location
1130 {
1131-namespace providers
1132-{
1133-namespace ubx
1134-{
1135-namespace _8
1136-{
1137 namespace nmea
1138 {
1139
1140@@ -47,10 +41,8 @@
1141 std::string generate_sentence(const Sentence& sentence);
1142 /// @brief operator<< inserts sentence into out.
1143 std::ostream& operator<<(std::ostream& out, const Sentence& sentence);
1144-}
1145-}
1146-}
1147-}
1148-}
1149-
1150-#endif // UBX_8_NMEA_SENTENCE_H_
1151+
1152+}
1153+}
1154+
1155+#endif // LOCATION_NMEA_SENTENCE_H_
1156
1157=== modified file 'src/location/nmea/status.h'
1158--- src/location/providers/ubx/_8/nmea/status.h 2016-10-10 09:15:40 +0000
1159+++ src/location/nmea/status.h 2017-05-05 09:37:41 +0000
1160@@ -12,29 +12,22 @@
1161 //
1162 // You should have received a copy of the GNU Lesser General Public License
1163 // along with this program. If not, see <http://www.gnu.org/licenses/>.
1164-#ifndef UBX_8_NMEA_STATUS_H_
1165-#define UBX_8_NMEA_STATUS_H_
1166+#ifndef LOCATION_NMEA_STATUS_H_
1167+#define LOCATION_NMEA_STATUS_H_
1168
1169 namespace location
1170 {
1171-namespace providers
1172-{
1173-namespace ubx
1174-{
1175-namespace _8
1176-{
1177 namespace nmea
1178 {
1179+
1180 /// @brief Status enumerates all status codes known to NMEA messages.
1181 enum class Status
1182 {
1183 valid = 'A', ///< The referenced data is valid.
1184 not_valid = 'V' ///< The reference data is missing and thus not valid.
1185 };
1186-}
1187-}
1188-}
1189-}
1190-}
1191-
1192-#endif // UBX_8_NMEA_STATUS_H_
1193+
1194+}
1195+}
1196+
1197+#endif // LOCATION_NMEA_STATUS_H_
1198
1199=== modified file 'src/location/nmea/talker.h'
1200--- src/location/providers/ubx/_8/nmea/talker.h 2017-03-09 09:42:25 +0000
1201+++ src/location/nmea/talker.h 2017-05-05 09:37:41 +0000
1202@@ -12,19 +12,14 @@
1203 //
1204 // You should have received a copy of the GNU Lesser General Public License
1205 // along with this program. If not, see <http://www.gnu.org/licenses/>.
1206-#ifndef UBX_8_NMEA_TALKER_H_
1207-#define UBX_8_NMEA_TALKER_H_
1208+#ifndef LOCATION_NMEA_TALKER_H_
1209+#define LOCATION_NMEA_TALKER_H_
1210
1211 namespace location
1212 {
1213-namespace providers
1214-{
1215-namespace ubx
1216-{
1217-namespace _8
1218-{
1219 namespace nmea
1220 {
1221+
1222 /// @brief Talker enumerates well-known participants on an NMEA bus.
1223 enum class Talker
1224 {
1225@@ -33,10 +28,8 @@
1226 gn, ///< Global Navigation Satellite System (GNSS)
1227 gp ///< Global Positioning System (GPS)
1228 };
1229-}
1230-}
1231-}
1232-}
1233-}
1234-
1235-#endif // UBX_8_NMEA_TALKER_H_
1236+
1237+}
1238+}
1239+
1240+#endif // LOCATION_NMEA_TALKER_H_
1241
1242=== modified file 'src/location/nmea/txt.h'
1243--- src/location/providers/ubx/_8/nmea/txt.h 2016-10-10 09:15:40 +0000
1244+++ src/location/nmea/txt.h 2017-05-05 09:37:41 +0000
1245@@ -12,10 +12,10 @@
1246 //
1247 // You should have received a copy of the GNU Lesser General Public License
1248 // along with this program. If not, see <http://www.gnu.org/licenses/>.
1249-#ifndef UBX_8_NMEA_TXT_H_
1250-#define UBX_8_NMEA_TXT_H_
1251+#ifndef LOCATION_NMEA_TXT_H_
1252+#define LOCATION_NMEA_TXT_H_
1253
1254-#include <location/providers/ubx/_8/nmea/talker.h>
1255+#include <location/nmea/talker.h>
1256
1257 #include <boost/optional.hpp>
1258
1259@@ -25,14 +25,9 @@
1260
1261 namespace location
1262 {
1263-namespace providers
1264-{
1265-namespace ubx
1266-{
1267-namespace _8
1268-{
1269 namespace nmea
1270 {
1271+
1272 /// @brief Text Transmission.
1273 ///
1274 /// This message outputs various information on the receiver, such as power-up
1275@@ -46,10 +41,8 @@
1276 boost::optional<std::uint8_t> identifier;
1277 boost::optional<std::string> message;
1278 };
1279-}
1280-}
1281-}
1282-}
1283-}
1284-
1285-#endif // UBX_8_NMEA_TXT_H_
1286+
1287+}
1288+}
1289+
1290+#endif // LOCATION_NMEA_TXT_H_
1291
1292=== modified file 'src/location/nmea/utc.h'
1293--- src/location/providers/ubx/_8/nmea/utc.h 2016-10-10 09:15:40 +0000
1294+++ src/location/nmea/utc.h 2017-05-05 09:37:41 +0000
1295@@ -12,21 +12,16 @@
1296 //
1297 // You should have received a copy of the GNU Lesser General Public License
1298 // along with this program. If not, see <http://www.gnu.org/licenses/>.
1299-#ifndef UBX_8_NMEA_UTC_H_
1300-#define UBX_8_NMEA_UTC_H_
1301+#ifndef LOCATION_NMEA_UTC_H_
1302+#define LOCATION_NMEA_UTC_H_
1303
1304 #include <cstdint>
1305
1306 namespace location
1307 {
1308-namespace providers
1309-{
1310-namespace ubx
1311-{
1312-namespace _8
1313-{
1314 namespace nmea
1315 {
1316+
1317 /// @brief Time in UTC.
1318 struct Utc
1319 {
1320@@ -34,10 +29,8 @@
1321 std::uint8_t minutes;
1322 double seconds;
1323 };
1324-}
1325-}
1326-}
1327-}
1328-}
1329-
1330-#endif // UBX_8_NMEA_UTC_H_
1331+
1332+}
1333+}
1334+
1335+#endif // LOCATION_NMEA_UTC_H_
1336
1337=== modified file 'src/location/nmea/vtg.h'
1338--- src/location/providers/ubx/_8/nmea/vtg.h 2016-10-10 09:15:40 +0000
1339+++ src/location/nmea/vtg.h 2017-05-05 09:37:41 +0000
1340@@ -12,11 +12,11 @@
1341 //
1342 // You should have received a copy of the GNU Lesser General Public License
1343 // along with this program. If not, see <http://www.gnu.org/licenses/>.
1344-#ifndef UBX_8_NMEA_VTG_H_
1345-#define UBX_8_NMEA_VTG_H_
1346+#ifndef LOCATION_NMEA_VTG_H_
1347+#define LOCATION_NMEA_VTG_H_
1348
1349-#include <location/providers/ubx/_8/nmea/mode.h>
1350-#include <location/providers/ubx/_8/nmea/talker.h>
1351+#include <location/nmea/mode.h>
1352+#include <location/nmea/talker.h>
1353
1354 #include <boost/optional.hpp>
1355
1356@@ -24,14 +24,9 @@
1357
1358 namespace location
1359 {
1360-namespace providers
1361-{
1362-namespace ubx
1363-{
1364-namespace _8
1365-{
1366 namespace nmea
1367 {
1368+
1369 /// @brief Course over ground and Ground speed.
1370 ///
1371 /// Velocity is given as Course over Ground (COG) and Speed over Ground (SOG).
1372@@ -44,10 +39,8 @@
1373 boost::optional<float> sog_kmh;
1374 boost::optional<Mode> mode;
1375 };
1376-}
1377-}
1378-}
1379-}
1380-}
1381-
1382-#endif // UBX_8_NMEA_VTG_H_
1383+
1384+}
1385+}
1386+
1387+#endif // LOCATION_NMEA_VTG_H_
1388
1389=== modified file 'src/location/providers/CMakeLists.txt'
1390--- src/location/providers/CMakeLists.txt 2017-03-04 21:43:23 +0000
1391+++ src/location/providers/CMakeLists.txt 2017-05-05 09:37:41 +0000
1392@@ -3,6 +3,7 @@
1393 add_subdirectory(mls)
1394 # add_subdirectory(remote)
1395 add_subdirectory(gps)
1396+add_subdirectory(sirf)
1397 add_subdirectory(ubx)
1398
1399 set(
1400
1401=== modified file 'src/location/providers/config.cpp'
1402--- src/location/providers/config.cpp 2016-10-10 09:15:40 +0000
1403+++ src/location/providers/config.cpp 2017-05-05 09:37:41 +0000
1404@@ -20,6 +20,7 @@
1405
1406 #include "dummy/provider.h"
1407 #include "mls/provider.h"
1408+#include "sirf/provider.h"
1409 #include "ubx/provider.h"
1410
1411 #include <map>
1412@@ -47,6 +48,12 @@
1413 location::providers::mls::Provider::create_instance
1414 };
1415
1416+static FactoryInjector sirf_injector
1417+{
1418+ "sirf::Provider",
1419+ location::providers::sirf::Provider::create_instance
1420+};
1421+
1422 static FactoryInjector ubx_injector
1423 {
1424 "ubx::Provider",
1425
1426=== added directory 'src/location/providers/sirf'
1427=== added file 'src/location/providers/sirf/CMakeLists.txt'
1428--- src/location/providers/sirf/CMakeLists.txt 1970-01-01 00:00:00 +0000
1429+++ src/location/providers/sirf/CMakeLists.txt 2017-05-05 09:37:41 +0000
1430@@ -0,0 +1,33 @@
1431+file(GLOB_RECURSE SIRF_HEADERS*.h)
1432+
1433+add_library(
1434+ sirf
1435+
1436+ ${SIRF_HEADERS}
1437+
1438+ bits.h
1439+
1440+ checksum.h
1441+ checksum.cpp
1442+ reader.h
1443+ reader.cpp
1444+ receiver.h
1445+ receiver.cpp
1446+ scanner.h
1447+ scanner.cpp
1448+ serial_port_receiver.h
1449+ serial_port_receiver.cpp
1450+ writer.h
1451+ writer.cpp
1452+
1453+ provider.h provider.cpp)
1454+
1455+target_link_libraries(
1456+ sirf
1457+
1458+ nmea)
1459+
1460+set(
1461+ ENABLED_PROVIDER_TARGETS
1462+ ${ENABLED_PROVIDER_TARGETS} sirf
1463+ PARENT_SCOPE)
1464
1465=== added file 'src/location/providers/sirf/bits.h'
1466--- src/location/providers/sirf/bits.h 1970-01-01 00:00:00 +0000
1467+++ src/location/providers/sirf/bits.h 2017-05-05 09:37:41 +0000
1468@@ -0,0 +1,49 @@
1469+// Copyright (C) 2017 Thomas Voss <thomas.voss.bochum@gmail.com>
1470+//
1471+// This library is free software: you can redistribute it and/or modify
1472+// it under the terms of the GNU Lesser General Public License as published
1473+// by the Free Software Foundation, either version 3 of the License, or
1474+// (at your option) any later version.
1475+//
1476+// This program is distributed in the hope that it will be useful,
1477+// but WITHOUT ANY WARRANTY; without even the implied warranty of
1478+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1479+// GNU General Public License for more details.
1480+//
1481+// You should have received a copy of the GNU Lesser General Public License
1482+// along with this program. If not, see <http://www.gnu.org/licenses/>.
1483+
1484+#ifndef LOCATION_PROVIDERS_SIRF_BITS_H_
1485+#define LOCATION_PROVIDERS_SIRF_BITS_H_
1486+
1487+#include <cstdint>
1488+
1489+namespace location
1490+{
1491+namespace providers
1492+{
1493+namespace sirf
1494+{
1495+namespace bits
1496+{
1497+
1498+template<std::size_t begin, std::size_t end, typename T, typename U>
1499+void set(T& bitfield, U value)
1500+{
1501+ static_assert(begin < end, "begin >= end");
1502+ bitfield |= ((value & ((1 << (end - begin))-1)) << begin);
1503+}
1504+
1505+template<std::size_t begin, std::size_t end, typename T, typename U = T>
1506+U get(const T& bitfield)
1507+{
1508+ static_assert(begin < end, "begin >= end");
1509+ return (bitfield >> begin) & ((1 << (end - begin)) - 1);
1510+}
1511+
1512+} // namespace bits
1513+} // namespace sirf
1514+} // namespace providers
1515+} // namespace location
1516+
1517+#endif // LOCATION_PROVIDERS_SIRF_BITS_H_
1518
1519=== added file 'src/location/providers/sirf/checksum.cpp'
1520--- src/location/providers/sirf/checksum.cpp 1970-01-01 00:00:00 +0000
1521+++ src/location/providers/sirf/checksum.cpp 2017-05-05 09:37:41 +0000
1522@@ -0,0 +1,28 @@
1523+// Copyright (C) 2017 Thomas Voss <thomas.voss.bochum@gmail.com>
1524+//
1525+// This library is free software: you can redistribute it and/or modify
1526+// it under the terms of the GNU Lesser General Public License as published
1527+// by the Free Software Foundation, either version 3 of the License, or
1528+// (at your option) any later version.
1529+//
1530+// This program is distributed in the hope that it will be useful,
1531+// but WITHOUT ANY WARRANTY; without even the implied warranty of
1532+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1533+// GNU General Public License for more details.
1534+//
1535+// You should have received a copy of the GNU Lesser General Public License
1536+// along with this program. If not, see <http://www.gnu.org/licenses/>.
1537+
1538+#include <location/providers/sirf/checksum.h>
1539+
1540+namespace sirf = location::providers::sirf;
1541+
1542+void sirf::Checksum::operator()(std::uint8_t byte)
1543+{
1544+ checksum += byte;
1545+}
1546+
1547+std::uint16_t sirf::Checksum::operator()() const
1548+{
1549+ return checksum;
1550+}
1551
1552=== added file 'src/location/providers/sirf/checksum.h'
1553--- src/location/providers/sirf/checksum.h 1970-01-01 00:00:00 +0000
1554+++ src/location/providers/sirf/checksum.h 2017-05-05 09:37:41 +0000
1555@@ -0,0 +1,42 @@
1556+// Copyright (C) 2017 Thomas Voss <thomas.voss.bochum@gmail.com>
1557+//
1558+// This library is free software: you can redistribute it and/or modify
1559+// it under the terms of the GNU Lesser General Public License as published
1560+// by the Free Software Foundation, either version 3 of the License, or
1561+// (at your option) any later version.
1562+//
1563+// This program is distributed in the hope that it will be useful,
1564+// but WITHOUT ANY WARRANTY; without even the implied warranty of
1565+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1566+// GNU General Public License for more details.
1567+//
1568+// You should have received a copy of the GNU Lesser General Public License
1569+// along with this program. If not, see <http://www.gnu.org/licenses/>.
1570+
1571+#ifndef LOCATION_PROVIDERS_SIRF_CHECKSUM_H_
1572+#define LOCATION_PROVIDERS_SIRF_CHECKSUM_H_
1573+
1574+#include <cstdint>
1575+
1576+namespace location
1577+{
1578+namespace providers
1579+{
1580+namespace sirf
1581+{
1582+
1583+class Checksum
1584+{
1585+public:
1586+ void operator()(std::uint8_t byte);
1587+ std::uint16_t operator()() const;
1588+
1589+private:
1590+ std::uint16_t checksum{0};
1591+};
1592+
1593+} // namespace sirf
1594+} // namespace providers
1595+} // namepsace location
1596+
1597+#endif // LOCATION_PROVIDERS_SIRF_CHECKSUM_H_
1598
1599=== added file 'src/location/providers/sirf/codec.h'
1600--- src/location/providers/sirf/codec.h 1970-01-01 00:00:00 +0000
1601+++ src/location/providers/sirf/codec.h 2017-05-05 09:37:41 +0000
1602@@ -0,0 +1,81 @@
1603+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
1604+//
1605+// This library is free software: you can redistribute it and/or modify
1606+// it under the terms of the GNU Lesser General Public License as published
1607+// by the Free Software Foundation, either version 3 of the License, or
1608+// (at your option) any later version.
1609+//
1610+// This program is distributed in the hope that it will be useful,
1611+// but WITHOUT ANY WARRANTY; without even the implied warranty of
1612+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1613+// GNU General Public License for more details.
1614+//
1615+// You should have received a copy of the GNU Lesser General Public License
1616+// along with this program. If not, see <http://www.gnu.org/licenses/>.
1617+
1618+#ifndef LOCATION_PROVIDERS_SIRF_CODEC_H_
1619+#define LOCATION_PROVIDERS_SIRF_CODEC_H_
1620+
1621+#include <location/providers/sirf/checksum.h>
1622+#include <location/providers/sirf/magic.h>
1623+#include <location/providers/sirf/reader.h>
1624+#include <location/providers/sirf/writer.h>
1625+
1626+#include <algorithm>
1627+#include <cstdint>
1628+#include <iostream>
1629+#include <vector>
1630+
1631+namespace location
1632+{
1633+namespace providers
1634+{
1635+namespace sirf
1636+{
1637+
1638+template<typename T>
1639+inline T decode_message(const std::vector<std::uint8_t>& payload)
1640+{
1641+ T result;
1642+ Reader reader{payload.begin(), payload.end()};
1643+ result.read(reader);
1644+
1645+ return result;
1646+}
1647+
1648+template<typename T>
1649+inline std::vector<std::uint8_t> encode_message(const T& message)
1650+{
1651+ auto msg_size = message.size();
1652+
1653+ std::uint16_t size =
1654+ sizeof(std::uint8_t) + sizeof(std::uint8_t) +
1655+ sizeof(std::uint16_t) +
1656+ msg_size +
1657+ sizeof(std::uint16_t) +
1658+ sizeof(std::uint8_t) + sizeof(std::uint8_t);
1659+
1660+ std::vector<std::uint8_t> result(size, 0);
1661+
1662+ Writer writer{result.begin(), result.end()};
1663+ writer.write_unsigned_char(begin::sync_char_1);
1664+ writer.write_unsigned_char(begin::sync_char_2);
1665+ writer.write_unsigned_short(msg_size);
1666+
1667+ Writer payload = writer.slice(msg_size);
1668+ message.write(payload);
1669+
1670+ auto checksum = std::for_each(result.begin() + 4, result.end() - 4, Checksum{});
1671+
1672+ writer.write_unsigned_short(checksum());
1673+ writer.write_unsigned_char(end::sync_char_1);
1674+ writer.write_unsigned_char(end::sync_char_2);
1675+
1676+ return result;
1677+}
1678+
1679+} // namespace sirf
1680+} // namespace providers
1681+} // namespace location
1682+
1683+#endif // LOCATION_PROVIDERS_SIRF_CODEC_H_
1684
1685=== added file 'src/location/providers/sirf/dop.h'
1686--- src/location/providers/sirf/dop.h 1970-01-01 00:00:00 +0000
1687+++ src/location/providers/sirf/dop.h 2017-05-05 09:37:41 +0000
1688@@ -0,0 +1,64 @@
1689+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
1690+//
1691+// This library is free software: you can redistribute it and/or modify
1692+// it under the terms of the GNU Lesser General Public License as published
1693+// by the Free Software Foundation, either version 3 of the License, or
1694+// (at your option) any later version.
1695+//
1696+// This program is distributed in the hope that it will be useful,
1697+// but WITHOUT ANY WARRANTY; without even the implied warranty of
1698+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1699+// GNU General Public License for more details.
1700+//
1701+// You should have received a copy of the GNU Lesser General Public License
1702+// along with this program. If not, see <http://www.gnu.org/licenses/>.
1703+#ifndef LOCATION_PROVIDERS_SIRF_DOP_H_
1704+#define LOCATION_PROVIDERS_SIRF_DOP_H_
1705+
1706+namespace location
1707+{
1708+namespace providers
1709+{
1710+namespace sirf
1711+{
1712+namespace tag
1713+{
1714+
1715+struct Horizontal
1716+{
1717+};
1718+struct Positional
1719+{
1720+};
1721+struct Vertical
1722+{
1723+};
1724+
1725+} // namespace tag
1726+
1727+template <typename T>
1728+struct DillusionOfPrecision
1729+{
1730+ explicit DillusionOfPrecision(float value = -1) : value{value} {}
1731+
1732+ DillusionOfPrecision(const DillusionOfPrecision<T>& rhs) : value{rhs.value} {}
1733+
1734+ DillusionOfPrecision& operator=(const DillusionOfPrecision<T>& rhs)
1735+ {
1736+ value = rhs.value;
1737+ return *this;
1738+ }
1739+
1740+ operator float() const { return value; }
1741+
1742+ float value;
1743+};
1744+
1745+template <typename T>
1746+using Dop = DillusionOfPrecision<T>;
1747+
1748+} // namespace sirf
1749+} // namespace providers
1750+} // namespace location
1751+
1752+#endif // LOCATION_PROVIDERS_SIRF_DOP_H_
1753
1754=== added file 'src/location/providers/sirf/geodetic_navigation_data.h'
1755--- src/location/providers/sirf/geodetic_navigation_data.h 1970-01-01 00:00:00 +0000
1756+++ src/location/providers/sirf/geodetic_navigation_data.h 2017-05-05 09:37:41 +0000
1757@@ -0,0 +1,213 @@
1758+// Copyright (C) 2017 Thomas Voss <thomas.voss@canonical.com>
1759+//
1760+// This library is free software: you can redistribute it and/or modify
1761+// it under the terms of the GNU Lesser General Public License as published
1762+// by the Free Software Foundation, either version 3 of the License, or
1763+// (at your option) any later version.
1764+//
1765+// This program is distributed in the hope that it will be useful,
1766+// but WITHOUT ANY WARRANTY; without even the implied warranty of
1767+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1768+// GNU General Public License for more details.
1769+//
1770+// You should have received a copy of the GNU Lesser General Public License
1771+// along with this program. If not, see <http://www.gnu.org/licenses/>.
1772+
1773+#ifndef LOCATION_PROVIDERS_SIRF_GEODETIC_NAVIGATION_DATA_H_
1774+#define LOCATION_PROVIDERS_SIRF_GEODETIC_NAVIGATION_DATA_H_
1775+
1776+#include <location/providers/sirf/reader.h>
1777+
1778+#include <cstdint>
1779+#include <iostream>
1780+
1781+namespace location
1782+{
1783+namespace providers
1784+{
1785+namespace sirf
1786+{
1787+
1788+struct GeodeticNavigationData
1789+{
1790+ enum NavValid
1791+ {
1792+ valid_navigation = 0,
1793+ solution_not_overdetermined = 1 << 0,
1794+ invalid_dr_sensor_data = 1 << 3,
1795+ invalid_dr_calibration = 1 << 4,
1796+ unavailable_dr_gps_calibration = 1 << 5,
1797+ invalid_dr_position_fix = 1 << 6,
1798+ invalid_heading = 1 << 7,
1799+ no_tracker_data_available = 1 << 15
1800+ };
1801+
1802+ enum NavType
1803+ {
1804+ no_navigation_fix = 0,
1805+ one_sv_kf_solution = 1,
1806+ two_sv_kf_solution = 2,
1807+ three_sv_kf_solution = 3,
1808+ four_sv_kf_solution = 4,
1809+ two_dim_least_squares_solution = 5,
1810+ three_dim_least_squares_solution = 6,
1811+ dr_solution = 7,
1812+ trickle_power_in_use = 1 << 3,
1813+ altitude_hold_off = 0,
1814+ altitude_hold_kf = 1,
1815+ altitude_hold_user_input = 2,
1816+ altitude_hold_user_input_always = 3,
1817+ dop_limits_exceeded = 1 << 6,
1818+ dgps_corrections_applied = 1 << 7,
1819+ dr_solution_type_sensor = 1,
1820+ dr_solution_type_velocity = 0,
1821+ navigation_solution_overdetermined = 1 << 9,
1822+ velocity_dr_timeout_exceeded = 1 << 10,
1823+ fix_edited_by_mi_functions = 1 << 11,
1824+ invalid_velocity = 1 << 12,
1825+ altitude_hold_disabled = 1 << 13,
1826+
1827+ };
1828+
1829+ static constexpr std::uint8_t id{0x29};
1830+
1831+ std::size_t size() const
1832+ {
1833+ return 91;
1834+ }
1835+
1836+ void read(Reader& reader)
1837+ {
1838+ nav_valid = reader.read_unsigned_short();
1839+ nav_type = reader.read_unsigned_short();
1840+ extended_week_number = reader.read_unsigned_short();
1841+ time_of_week = reader.read_unsigned_long();
1842+ utc.year = reader.read_unsigned_short();
1843+ utc.month = reader.read_unsigned_char();
1844+ utc.day = reader.read_unsigned_char();
1845+ utc.hour = reader.read_unsigned_char();
1846+ utc.minute = reader.read_unsigned_char();
1847+ utc.seconds = reader.read_unsigned_short();
1848+ satellite_id_list = reader.read_unsigned_long();
1849+ latitude = reader.read_signed_long() * 1e-7;
1850+ longitude = reader.read_signed_long() * 1e-7;
1851+ altitude.above_ellipsoid = reader.read_signed_long() * 1e-2;
1852+ altitude.above_mean_sea_level = reader.read_signed_long() * 1e-2;
1853+ map_datum = reader.read_signed_char();
1854+ over_ground.speed = reader.read_unsigned_short() * 1e-2;
1855+ over_ground.course = reader.read_unsigned_short() * 1e-2;
1856+ magnetic_variation = reader.read_signed_short();
1857+ climb_rate = reader.read_signed_short() * 1e-2;
1858+ heading_rate = reader.read_signed_short() * 1e-2;
1859+ error.horizontal_position = reader.read_unsigned_long() * 1e-2;
1860+ error.vertical_position = reader.read_unsigned_long() * 1e-2;
1861+ error.time = reader.read_unsigned_long() * 1e-2;
1862+ error.horizontal_velocity = reader.read_unsigned_short() * 1e-2;
1863+ clock.bias = reader.read_signed_long() * 1e-2;
1864+ clock.bias_error = reader.read_unsigned_long() * 1e-2;
1865+ clock.drift = reader.read_signed_long() * 1e-2;
1866+ clock.drift_error = reader.read_unsigned_long() * 1e-2;
1867+ distance_traveled = reader.read_unsigned_long();
1868+ distance_traveled_error = reader.read_unsigned_short();
1869+ error.heading = reader.read_unsigned_short() * 1e-2;
1870+ svs_in_fix = reader.read_unsigned_char();
1871+ hdop = reader.read_unsigned_char() / 5.f;
1872+ mode_info = reader.read_unsigned_char();
1873+ }
1874+
1875+ std::uint16_t nav_valid;
1876+ std::uint16_t nav_type;
1877+ std::uint16_t extended_week_number;
1878+ std::uint32_t time_of_week;
1879+ struct
1880+ {
1881+ std::uint16_t year;
1882+ std::uint8_t month;
1883+ std::uint8_t day;
1884+ std::uint8_t hour;
1885+ std::uint8_t minute;
1886+ std::uint16_t seconds;
1887+ } utc;
1888+ std::uint32_t satellite_id_list;
1889+ float latitude;
1890+ float longitude;
1891+ struct
1892+ {
1893+ float above_ellipsoid;
1894+ float above_mean_sea_level;
1895+ } altitude;
1896+ std::int8_t map_datum;
1897+ struct
1898+ {
1899+ std::uint16_t speed;
1900+ std::uint16_t course;
1901+ } over_ground;
1902+ std::int16_t magnetic_variation;
1903+ float climb_rate;
1904+ float heading_rate;
1905+ struct
1906+ {
1907+ float horizontal_position;
1908+ float vertical_position;
1909+ float time;
1910+ float horizontal_velocity;
1911+ float heading;
1912+ } error;
1913+ struct
1914+ {
1915+ float bias;
1916+ float bias_error;
1917+ float drift;
1918+ float drift_error;
1919+ } clock;
1920+ std::uint32_t distance_traveled;
1921+ std::uint32_t distance_traveled_error;
1922+ std::uint8_t svs_in_fix;
1923+ std::uint8_t hdop;
1924+ std::uint8_t mode_info;
1925+};
1926+
1927+inline std::ostream& operator<<(std::ostream& out, const GeodeticNavigationData& gnd)
1928+{
1929+ return out << "GeodeticNavigationData:" << std::endl
1930+ << " nav-valid: " << gnd.nav_valid << std::endl
1931+ << " nav-type: " << gnd.nav_type << std::endl
1932+ << " extended-week-number: " << gnd.extended_week_number << std::endl
1933+ << " time-of-week: " << gnd.time_of_week << std::endl
1934+ << " utc.year: " << gnd.utc.year << std::endl
1935+ << " utc.month: " << std::uint32_t(gnd.utc.month) << std::endl
1936+ << " utc.day: " << std::uint32_t(gnd.utc.day) << std::endl
1937+ << " utc.hour: " << std::uint32_t(gnd.utc.hour) << std::endl
1938+ << " utc.minute: " << std::uint32_t(gnd.utc.minute) << std::endl
1939+ << " utc.seconds: " << gnd.utc.seconds << std::endl
1940+ << " satellite-id-list: " << gnd.satellite_id_list << std::endl
1941+ << " latitude: " << gnd.latitude << std::endl
1942+ << " longitude: " << gnd.longitude << std::endl
1943+ << " altitude.above-ellipsoid: " << gnd.altitude.above_ellipsoid << std::endl
1944+ << " altitude.above-msl: " << gnd.altitude.above_mean_sea_level << std::endl
1945+ << " map-datum: " << std::int32_t(gnd.map_datum) << std::endl
1946+ << " over-ground.speed: " << gnd.over_ground.speed << std::endl
1947+ << " over-ground.course: " << gnd.over_ground.course << std::endl
1948+ << " climb-rate: " << gnd.climb_rate << std::endl
1949+ << " heading-rate: " << gnd.heading_rate << std::endl
1950+ << " error.horizontal-position: " << gnd.error.horizontal_position << std::endl
1951+ << " error.vertical-position: " << gnd.error.vertical_position << std::endl
1952+ << " error.time: " << gnd.error.time << std::endl
1953+ << " error.horizontal-velocity: " << gnd.error.horizontal_velocity << std::endl
1954+ << " error.heading: " << gnd.error.heading << std::endl
1955+ << " clock.bias: " << gnd.clock.bias << std::endl
1956+ << " clock.bias-error: " << gnd.clock.bias_error << std::endl
1957+ << " clock.drift: " << gnd.clock.drift << std::endl
1958+ << " clock.drift-error: " << gnd.clock.drift_error << std::endl
1959+ << " distance-traveled: " << gnd.distance_traveled << std::endl
1960+ << " distance-traveled-error: " << gnd.distance_traveled_error << std::endl
1961+ << " svs-in-fix: " << std::uint32_t(gnd.svs_in_fix) << std::endl
1962+ << " hdop: " << std::uint32_t(gnd.hdop) << std::endl
1963+ << " mode-info: " << std::uint32_t(gnd.mode_info);
1964+}
1965+
1966+} // namespace sirf
1967+} // namespace providers
1968+} // namespace location
1969+
1970+#endif // LOCATION_PROVIDERS_SIRF_GEODETIC_NAVIGATION_DATA_H_
1971
1972=== added file 'src/location/providers/sirf/initialize_data_source.h'
1973--- src/location/providers/sirf/initialize_data_source.h 1970-01-01 00:00:00 +0000
1974+++ src/location/providers/sirf/initialize_data_source.h 2017-05-05 09:37:41 +0000
1975@@ -0,0 +1,93 @@
1976+// Copyright (C) 2017 Thomas Voss <thomas.voss@canonical.com>
1977+//
1978+// This library is free software: you can redistribute it and/or modify
1979+// it under the terms of the GNU Lesser General Public License as published
1980+// by the Free Software Foundation, either version 3 of the License, or
1981+// (at your option) any later version.
1982+//
1983+// This program is distributed in the hope that it will be useful,
1984+// but WITHOUT ANY WARRANTY; without even the implied warranty of
1985+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1986+// GNU General Public License for more details.
1987+//
1988+// You should have received a copy of the GNU Lesser General Public License
1989+// along with this program. If not, see <http://www.gnu.org/licenses/>.
1990+
1991+#ifndef LOCATION_PROVIDERS_SIRF_INITIALIZE_DATA_SOURCE_H_
1992+#define LOCATION_PROVIDERS_SIRF_INITIALIZE_DATA_SOURCE_H_
1993+
1994+#include <location/providers/sirf/writer.h>
1995+
1996+#include <cstdint>
1997+#include <iostream>
1998+
1999+namespace location
2000+{
2001+namespace providers
2002+{
2003+namespace sirf
2004+{
2005+
2006+struct InitializeDataSource
2007+{
2008+ enum ResetConfiguration
2009+ {
2010+ data_valid = 1 << 0,
2011+ clear_ephemeris_data = 1 << 1,
2012+ clear_all_history = 1 << 2,
2013+ factory_reset = 1 << 3,
2014+ enable_nav_lib_data = 1 << 4,
2015+ enable_debug_data = 1 << 5,
2016+ rtc_is_not_precise = 1 << 6,
2017+ reset = 1 << 7
2018+ };
2019+
2020+ static constexpr std::uint8_t id{128};
2021+ static constexpr std::uint8_t max_number_channels{12};
2022+
2023+ std::size_t size() const
2024+ {
2025+ return 25;
2026+ }
2027+
2028+ void write(Writer& writer) const
2029+ {
2030+ writer.write_unsigned_char(id);
2031+ writer.write_signed_long(ecef_x);
2032+ writer.write_signed_long(ecef_y);
2033+ writer.write_signed_long(ecef_z);
2034+ writer.write_signed_long(clock_drift);
2035+ writer.write_unsigned_long(ecef_x);
2036+ writer.write_unsigned_short(week_number);
2037+ writer.write_unsigned_char(channels);
2038+ writer.write_unsigned_char(reset_configuration);
2039+ }
2040+
2041+ std::int32_t ecef_x;
2042+ std::int32_t ecef_y;
2043+ std::int32_t ecef_z;
2044+ std::int32_t clock_drift;
2045+ std::uint32_t time_of_week;
2046+ std::uint16_t week_number;
2047+ std::uint8_t channels;
2048+ std::uint8_t reset_configuration;
2049+};
2050+
2051+inline std::ostream& operator<<(std::ostream& out, const InitializeDataSource& ids)
2052+{
2053+ return out << "InitializeDataSource:" << std::endl
2054+ << " ecef-x: " << ids.ecef_x << std::endl
2055+ << " ecef-y: " << ids.ecef_y << std::endl
2056+ << " ecef-z: " << ids.ecef_z << std::endl
2057+ << " clock-drift: " << ids.clock_drift << std::endl
2058+ << " time-of-week: " << ids.time_of_week << std::endl
2059+ << " week_number: " << ids.week_number << std::endl
2060+ << " channels: " << std::uint32_t(ids.channels) << std::endl
2061+ << " reset-config: " << std::uint32_t(ids.reset_configuration) << std::endl;
2062+}
2063+
2064+} // namespace sirf
2065+} // namespace providers
2066+} // namespace location
2067+
2068+#endif // LOCATION_PROVIDERS_SIRF_INITIALIZE_DATA_SOURCE_H_
2069
2070=== added file 'src/location/providers/sirf/magic.h'
2071--- src/location/providers/sirf/magic.h 1970-01-01 00:00:00 +0000
2072+++ src/location/providers/sirf/magic.h 2017-05-05 09:37:41 +0000
2073@@ -0,0 +1,43 @@
2074+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
2075+//
2076+// This library is free software: you can redistribute it and/or modify
2077+// it under the terms of the GNU Lesser General Public License as published
2078+// by the Free Software Foundation, either version 3 of the License, or
2079+// (at your option) any later version.
2080+//
2081+// This program is distributed in the hope that it will be useful,
2082+// but WITHOUT ANY WARRANTY; without even the implied warranty of
2083+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2084+// GNU General Public License for more details.
2085+//
2086+// You should have received a copy of the GNU Lesser General Public License
2087+// along with this program. If not, see <http://www.gnu.org/licenses/>.
2088+
2089+#ifndef LOCATION_PROVIDERS_SIRF_MAGIC_H_
2090+#define LOCATION_PROVIDERS_SIRF_MAGIC_H_
2091+
2092+namespace location
2093+{
2094+namespace providers
2095+{
2096+namespace sirf
2097+{
2098+namespace begin
2099+{
2100+
2101+constexpr const std::uint8_t sync_char_1{0xa0};
2102+constexpr const std::uint8_t sync_char_2{0xa2};
2103+
2104+} // namespace begin
2105+namespace end
2106+{
2107+
2108+constexpr const std::uint8_t sync_char_1{0xb0};
2109+constexpr const std::uint8_t sync_char_2{0xb3};
2110+
2111+} // namespace end
2112+} // namespace sirf
2113+} // namespace providers
2114+} // namespace location
2115+
2116+#endif // LOCATION_PROVIDERS_SIRF_MAGIC_H_
2117
2118=== added file 'src/location/providers/sirf/message.h'
2119--- src/location/providers/sirf/message.h 1970-01-01 00:00:00 +0000
2120+++ src/location/providers/sirf/message.h 2017-05-05 09:37:41 +0000
2121@@ -0,0 +1,53 @@
2122+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
2123+//
2124+// This library is free software: you can redistribute it and/or modify
2125+// it under the terms of the GNU Lesser General Public License as published
2126+// by the Free Software Foundation, either version 3 of the License, or
2127+// (at your option) any later version.
2128+//
2129+// This program is distributed in the hope that it will be useful,
2130+// but WITHOUT ANY WARRANTY; without even the implied warranty of
2131+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2132+// GNU General Public License for more details.
2133+//
2134+// You should have received a copy of the GNU Lesser General Public License
2135+// along with this program. If not, see <http://www.gnu.org/licenses/>.
2136+
2137+#ifndef LOCATION_PROVIDERS_SIRF_MESSAGE_H_
2138+#define LOCATION_PROVIDERS_SIRF_MESSAGE_H_
2139+
2140+#include <location/providers/sirf/geodetic_navigation_data.h>
2141+#include <location/providers/sirf/initialize_data_source.h>
2142+#include <location/providers/sirf/set_protocol.h>
2143+
2144+#include <boost/variant.hpp>
2145+
2146+#include <iostream>
2147+
2148+namespace location
2149+{
2150+namespace providers
2151+{
2152+namespace sirf
2153+{
2154+
2155+struct Null {};
2156+
2157+using Message = boost::variant<
2158+ Null,
2159+ InitializeDataSource,
2160+ GeodeticNavigationData,
2161+ SetProtocol
2162+>;
2163+
2164+inline std::ostream& operator<<(std::ostream& out, const Null&)
2165+{
2166+ return out << "Uninterpreted sirf message";
2167+}
2168+
2169+
2170+} // namespace sirf
2171+} // namespace providers
2172+} // namespace location
2173+
2174+#endif // LOCATION_PROVIDERS_SIRF_MESSAGE_H_
2175
2176=== added file 'src/location/providers/sirf/provider.cpp'
2177--- src/location/providers/sirf/provider.cpp 1970-01-01 00:00:00 +0000
2178+++ src/location/providers/sirf/provider.cpp 2017-05-05 09:37:41 +0000
2179@@ -0,0 +1,353 @@
2180+/*
2181+ * Copyright © 2016 Canonical Ltd.
2182+ *
2183+ * This program is free software: you can redistribute it and/or modify it
2184+ * under the terms of the GNU Lesser General Public License version 3,
2185+ * as published by the Free Software Foundation.
2186+ *
2187+ * This program is distributed in the hope that it will be useful,
2188+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2189+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2190+ * GNU Lesser General Public License for more details.
2191+ *
2192+ * You should have received a copy of the GNU Lesser General Public License
2193+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2194+ *
2195+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
2196+ */
2197+
2198+#include <location/providers/sirf/provider.h>
2199+
2200+#include <location/logging.h>
2201+#include <location/runtime.h>
2202+#include <location/events/reference_position_updated.h>
2203+#include <location/glib/runtime.h>
2204+
2205+#include <core/net/http/client.h>
2206+#include <core/posix/this_process.h>
2207+
2208+#include <boost/lexical_cast.hpp>
2209+
2210+#include <fstream>
2211+#include <iostream>
2212+#include <iterator>
2213+#include <thread>
2214+
2215+namespace env = core::posix::this_process::env;
2216+namespace sirf = location::providers::sirf;
2217+
2218+namespace
2219+{
2220+
2221+struct SettingsHelper
2222+{
2223+ template<typename T>
2224+ static T get_value(std::string key, T&& default_value)
2225+ {
2226+ static const std::string snap_path = env::get("SNAP_DATA");
2227+
2228+ boost::filesystem::path path{snap_path};
2229+ std::replace(key.begin(), key.end(), '.', '/');
2230+ path /= key;
2231+
2232+ LOG(INFO) << "Reading setting from " << path.string();
2233+
2234+ std::ifstream in{path.string().c_str()};
2235+ T value{default_value}; in >> value;
2236+
2237+ return value;
2238+ }
2239+};
2240+
2241+}
2242+
2243+std::string sirf::Provider::class_name()
2244+{
2245+ return "sirf::Provider";
2246+}
2247+
2248+void sirf::Provider::Monitor::on_new_sirf_message(const Message& message)
2249+{
2250+ VLOG(1) << message;
2251+ if (auto sp = provider.lock())
2252+ if (sp->configuration.protocol == Provider::Protocol::sirf)
2253+ boost::apply_visitor(*this, message);
2254+}
2255+
2256+
2257+void sirf::Provider::Monitor::on_new_nmea_sentence(const nmea::Sentence& sentence)
2258+{
2259+ VLOG(1) << sentence;
2260+ if (auto sp = provider.lock())
2261+ if (sp->configuration.protocol == Provider::Protocol::nmea)
2262+ boost::apply_visitor(*this, sentence);
2263+}
2264+
2265+void sirf::Provider::Monitor::operator()(const sirf::GeodeticNavigationData& gnd)
2266+{
2267+ auto thiz = shared_from_this();
2268+ std::weak_ptr<sirf::Provider::Monitor> wp{thiz};
2269+
2270+ glib::Runtime::instance()->dispatch([gnd, wp]()
2271+ {
2272+ if (auto sp = wp.lock())
2273+ {
2274+ if (auto spp = sp->provider.lock())
2275+ {
2276+ if (gnd.nav_valid == GeodeticNavigationData::valid_navigation)
2277+ {
2278+ Position position
2279+ {
2280+ gnd.latitude * units::degrees,
2281+ gnd.longitude * units::degrees
2282+ };
2283+ position.accuracy().horizontal(gnd.error.horizontal_position * units::meters);
2284+
2285+ position.altitude(gnd.altitude.above_mean_sea_level * units::meters);
2286+ position.accuracy().vertical(gnd.error.vertical_position * units::meters);
2287+
2288+ spp->updates.position(location::Update<location::Position>{position});
2289+ if (!(gnd.nav_type & GeodeticNavigationData::invalid_heading))
2290+ spp->updates.heading(location::Update<units::Degrees>{gnd.over_ground.course * units::degrees});
2291+ if (!(gnd.nav_type & GeodeticNavigationData::invalid_velocity))
2292+ spp->updates.velocity(location::Update<units::MetersPerSecond>{gnd.over_ground.speed * units::meters_per_second});
2293+ }
2294+ }
2295+ }
2296+ });
2297+}
2298+
2299+void sirf::Provider::Monitor::operator()(const nmea::Gga& gga)
2300+{
2301+ if (gga.latitude && gga.longitude)
2302+ {
2303+ auto lat = gga.latitude.get();
2304+ auto lon = gga.longitude.get();
2305+
2306+ Position position
2307+ {
2308+ (lat.degrees + lat.minutes / 60.f) * units::degrees,
2309+ (lon.degrees + lon.minutes / 60.f) * units::degrees
2310+ };
2311+
2312+ if (gga.altitude)
2313+ position.altitude(units::Meters::from_value(*gga.altitude));
2314+
2315+ // TODO(tvoss): Maximum accuracy should be reported by the receiver
2316+ // implementation rather than hardcoding 3 [m] here.
2317+ if (gga.hdop)
2318+ position.accuracy().horizontal(gga.hdop.get() * 3. * units::meters);
2319+
2320+ auto thiz = shared_from_this();
2321+ std::weak_ptr<sirf::Provider::Monitor> wp{thiz};
2322+
2323+ glib::Runtime::instance()->dispatch([position, wp]()
2324+ {
2325+ if (auto sp = wp.lock())
2326+ if (auto spp = sp->provider.lock())
2327+ spp->updates.position(location::Update<location::Position>{position});
2328+ });
2329+ }
2330+}
2331+
2332+void sirf::Provider::Monitor::operator()(const nmea::Gsa&)
2333+{
2334+ // Empty on purpose
2335+}
2336+
2337+void sirf::Provider::Monitor::operator()(const nmea::Gll&)
2338+{
2339+ // Empty on purpose
2340+}
2341+
2342+void sirf::Provider::Monitor::operator()(const nmea::Gsv&)
2343+{
2344+ // Empty on purpose
2345+}
2346+
2347+void sirf::Provider::Monitor::operator()(const nmea::Rmc&)
2348+{
2349+ // Empty on purpose
2350+}
2351+
2352+void sirf::Provider::Monitor::operator()(const nmea::Txt&)
2353+{
2354+ // Empty on purpose
2355+}
2356+
2357+void sirf::Provider::Monitor::operator()(const nmea::Vtg& vtg)
2358+{
2359+ auto thiz = shared_from_this();
2360+ std::weak_ptr<sirf::Provider::Monitor> wp{thiz};
2361+
2362+ glib::Runtime::instance()->dispatch([vtg, wp]()
2363+ {
2364+ if (auto sp = wp.lock())
2365+ {
2366+ if (vtg.cog_true)
2367+ if (auto spp = sp->provider.lock())
2368+ spp->updates.heading(
2369+ Update<units::Degrees>(
2370+ vtg.cog_true.get() * units::degrees));
2371+ if (vtg.sog_kmh)
2372+ if (auto spp = sp->provider.lock())
2373+ spp->updates.velocity(
2374+ Update<units::MetersPerSecond>(
2375+ vtg.sog_kmh.get() * 1000./3600. * units::meters_per_second));
2376+ }
2377+ });
2378+}
2379+
2380+location::Provider::Ptr sirf::Provider::create_instance(const location::ProviderFactory::Configuration& config)
2381+{
2382+ Configuration configuration
2383+ {
2384+ SettingsHelper::get_value<Protocol>(
2385+ "sirf.provider.protocol",
2386+ Protocol::sirf),
2387+ config.get<std::string>(
2388+ "device", SettingsHelper::get_value<std::string>(
2389+ "sirf.provider.path",
2390+ "/dev/ttyUSB1"
2391+ )
2392+ )
2393+ };
2394+
2395+ return sirf::Provider::create(configuration);
2396+}
2397+
2398+// Create a new instance with configuration.
2399+std::shared_ptr<sirf::Provider> sirf::Provider::create(const Configuration& configuration)
2400+{
2401+ auto sp = std::shared_ptr<Provider>{new Provider{configuration}};
2402+ return sp->finalize_construction();
2403+}
2404+
2405+
2406+sirf::Provider::Provider(const Configuration& configuration)
2407+ : configuration{configuration},
2408+ runtime{location::Runtime::create(1)},
2409+ monitor{std::make_shared<Monitor>()},
2410+ receiver{SerialPortReceiver::create(runtime->service(), configuration.device, monitor)}
2411+{
2412+ runtime->start();
2413+ configure_protocol();
2414+}
2415+
2416+sirf::Provider::~Provider() noexcept
2417+{
2418+ deactivate();
2419+ runtime->stop();
2420+}
2421+
2422+void sirf::Provider::reset()
2423+{
2424+ InitializeDataSource ids;
2425+ ids.channels = InitializeDataSource::max_number_channels;
2426+ ids.reset_configuration = InitializeDataSource::clear_ephemeris_data | InitializeDataSource::clear_all_history;
2427+ receiver->send_message(Message{ids});
2428+}
2429+
2430+void sirf::Provider::on_new_event(const Event&)
2431+{
2432+ // TODO(tvoss): Use incoming reference position updates
2433+ // to query assistance data.
2434+}
2435+
2436+location::Provider::Requirements sirf::Provider::requirements() const
2437+{
2438+ return Requirements::none;
2439+}
2440+
2441+bool sirf::Provider::satisfies(const location::Criteria&)
2442+{
2443+ return true;
2444+}
2445+
2446+void sirf::Provider::enable()
2447+{
2448+}
2449+
2450+void sirf::Provider::disable()
2451+{
2452+}
2453+
2454+void sirf::Provider::activate()
2455+{
2456+ receiver->start();
2457+}
2458+
2459+void sirf::Provider::deactivate()
2460+{
2461+ receiver->stop();
2462+}
2463+
2464+const core::Signal<location::Update<location::Position>>& sirf::Provider::position_updates() const
2465+{
2466+ return updates.position;
2467+}
2468+
2469+const core::Signal<location::Update<location::units::Degrees>>& sirf::Provider::heading_updates() const
2470+{
2471+ return updates.heading;
2472+}
2473+
2474+const core::Signal<location::Update<location::units::MetersPerSecond>>& sirf::Provider::velocity_updates() const
2475+{
2476+ return updates.velocity;
2477+}
2478+
2479+std::shared_ptr<sirf::Provider> sirf::Provider::finalize_construction()
2480+{
2481+ auto thiz = shared_from_this();
2482+ std::weak_ptr<sirf::Provider> wp{thiz};
2483+
2484+ monitor->provider = wp;
2485+ return thiz;
2486+}
2487+
2488+void sirf::Provider::configure_protocol()
2489+{
2490+ switch(configuration.protocol)
2491+ {
2492+ case Protocol::sirf:
2493+ {
2494+ static const std::string set_serial_port{"$PSRF100,0,4800,8,1,0*0F\r\n"};
2495+ receiver->send_encoded_message(std::vector<std::uint8_t>{set_serial_port.begin(), set_serial_port.end()});
2496+ break;
2497+ }
2498+ case Protocol::nmea:
2499+ receiver->send_message(Message{SetProtocol{SetProtocol::nmea}});
2500+ break;
2501+ default:
2502+ break;
2503+ }
2504+}
2505+
2506+std::istream& sirf::operator>>(std::istream& in, Provider::Protocol& protocol)
2507+{
2508+ std::string value;
2509+ in >> value;
2510+
2511+ if (value == "sirf")
2512+ protocol = Provider::Protocol::sirf;
2513+ if (value == "nmea")
2514+ protocol = Provider::Protocol::nmea;
2515+
2516+ return in;
2517+}
2518+
2519+std::ostream& sirf::operator<<(std::ostream& out, Provider::Protocol protocol)
2520+{
2521+ switch (protocol)
2522+ {
2523+ case Provider::Protocol::sirf:
2524+ out << "sirf";
2525+ break;
2526+ case Provider::Protocol::nmea:
2527+ out << "nmea";
2528+ break;
2529+ }
2530+
2531+ return out;
2532+}
2533
2534=== added file 'src/location/providers/sirf/provider.h'
2535--- src/location/providers/sirf/provider.h 1970-01-01 00:00:00 +0000
2536+++ src/location/providers/sirf/provider.h 2017-05-05 09:37:41 +0000
2537@@ -0,0 +1,143 @@
2538+/*
2539+ * Copyright © 2016 Canonical Ltd.
2540+ *
2541+ * This program is free software: you can redistribute it and/or modify it
2542+ * under the terms of the GNU Lesser General Public License version 3,
2543+ * as published by the Free Software Foundation.
2544+ *
2545+ * This program is distributed in the hope that it will be useful,
2546+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2547+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2548+ * GNU Lesser General Public License for more details.
2549+ *
2550+ * You should have received a copy of the GNU Lesser General Public License
2551+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2552+ *
2553+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
2554+ */
2555+#ifndef LOCATION_PROVIDERS_SIRF_PROVIDER_H_
2556+#define LOCATION_PROVIDERS_SIRF_PROVIDER_H_
2557+
2558+#include <location/provider.h>
2559+#include <location/provider_factory.h>
2560+#include <location/runtime.h>
2561+#include <location/nmea/sentence.h>
2562+#include <location/providers/sirf/serial_port_receiver.h>
2563+
2564+#include <boost/filesystem.hpp>
2565+
2566+#include <iosfwd>
2567+#include <thread>
2568+
2569+namespace location
2570+{
2571+namespace providers
2572+{
2573+namespace sirf
2574+{
2575+// sirf::Provider integrates GNSS receivers relying on
2576+// ublox chipsets with locationd.
2577+//
2578+// In this version, only receivers connected to a serial port
2579+// are supported. More to this, this version only reads NMEA sentences
2580+// and does not support the proprietary ublox protocol.
2581+//
2582+// Configuration parameters:
2583+// - device[=/dev/ttyUSB1] serial device connecting to the receiver.
2584+class Provider : public location::Provider, public std::enable_shared_from_this<Provider>
2585+{
2586+public:
2587+ enum class Protocol
2588+ {
2589+ sirf, // Rely on sirf.
2590+ nmea // Rely on nmea.
2591+ };
2592+
2593+ // Configuration bundles all construction time parameters.
2594+ struct Configuration
2595+ {
2596+ Protocol protocol; // The protocol used for communicating with the receiver.
2597+ boost::filesystem::path device; // Serial device used for communicating with the receiver.
2598+ };
2599+
2600+ // For integration with the Provider factory.
2601+ static std::string class_name();
2602+ // Instantiates a new provider instance, populating the configuration object
2603+ // from the provided property bundle. Please see dummy::Configuration::Keys
2604+ // for the list of known options.
2605+ static Provider::Ptr create_instance(const ProviderFactory::Configuration&);
2606+
2607+ // Create a new instance with configuration.
2608+ static std::shared_ptr<Provider> create(const Configuration& configuration);
2609+
2610+ // Cleans up all resources and stops the updates.
2611+ ~Provider() noexcept;
2612+
2613+ // Resets the chipset and drops all cached data.
2614+ // The next positioning request will be a cold start.
2615+ void reset();
2616+
2617+ // From Provider
2618+ void on_new_event(const Event& event) override;
2619+
2620+ void enable() override;
2621+ void disable() override;
2622+ void activate() override;
2623+ void deactivate() override;
2624+
2625+ Requirements requirements() const override;
2626+ bool satisfies(const Criteria& criteria) override;
2627+ const core::Signal<Update<Position>>& position_updates() const override;
2628+ const core::Signal<Update<units::Degrees>>& heading_updates() const override;
2629+ const core::Signal<Update<units::MetersPerSecond>>& velocity_updates() const override;
2630+
2631+private:
2632+ // Relays incoming sentences to a provider instance.
2633+ struct Monitor : public std::enable_shared_from_this<sirf::Provider::Monitor>, public sirf::Receiver::Monitor, public boost::static_visitor<>
2634+ {
2635+ // From Receiver::Monitor
2636+ void on_new_sirf_message(const Message& message) override;
2637+ void on_new_nmea_sentence(const nmea::Sentence& sentence) override;
2638+
2639+ template<typename T>
2640+ void operator()(const T&) const {}
2641+
2642+ void operator()(const GeodeticNavigationData& gnd);
2643+
2644+ void operator()(const nmea::Gga& gga);
2645+ void operator()(const nmea::Gsa& gsa);
2646+ void operator()(const nmea::Gll& gll);
2647+ void operator()(const nmea::Gsv& gsv);
2648+ void operator()(const nmea::Rmc& rmc);
2649+ void operator()(const nmea::Txt& txt);
2650+ void operator()(const nmea::Vtg& vtg);
2651+
2652+ std::weak_ptr<Provider> provider;
2653+ };
2654+
2655+ // Creates a new provider instance talking via device to the ubx chipset.
2656+ Provider(const Configuration& configuration);
2657+
2658+ std::shared_ptr<Provider> finalize_construction();
2659+ void configure_protocol();
2660+
2661+ Configuration configuration;
2662+ std::shared_ptr<location::Runtime> runtime;
2663+ std::shared_ptr<Monitor> monitor;
2664+ std::shared_ptr<SerialPortReceiver> receiver;
2665+ struct
2666+ {
2667+ core::Signal<Update<Position>> position;
2668+ core::Signal<Update<units::Degrees>> heading;
2669+ core::Signal<Update<units::MetersPerSecond>> velocity;
2670+ } updates;
2671+};
2672+
2673+std::istream& operator>>(std::istream&, Provider::Protocol&);
2674+std::ostream& operator<<(std::ostream&, Provider::Protocol);
2675+
2676+} // namespace sirf
2677+} // namespace providers
2678+} // namespace location
2679+
2680+#endif // LOCATION_PROVIDERS_SIRF_PROVIDER_H_
2681
2682=== added file 'src/location/providers/sirf/reader.cpp'
2683--- src/location/providers/sirf/reader.cpp 1970-01-01 00:00:00 +0000
2684+++ src/location/providers/sirf/reader.cpp 2017-05-05 09:37:41 +0000
2685@@ -0,0 +1,87 @@
2686+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
2687+//
2688+// This library is free software: you can redistribute it and/or modify
2689+// it under the terms of the GNU Lesser General Public License as published
2690+// by the Free Software Foundation, either version 3 of the License, or
2691+// (at your option) any later version.
2692+//
2693+// This program is distributed in the hope that it will be useful,
2694+// but WITHOUT ANY WARRANTY; without even the implied warranty of
2695+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2696+// GNU General Public License for more details.
2697+//
2698+// You should have received a copy of the GNU Lesser General Public License
2699+// along with this program. If not, see <http://www.gnu.org/licenses/>.
2700+
2701+#include <location/providers/sirf/reader.h>
2702+
2703+#include <arpa/inet.h>
2704+
2705+#include <cstring>
2706+#include <stdexcept>
2707+
2708+namespace sirf = location::providers::sirf;
2709+
2710+sirf::Reader::Reader(std::vector<std::uint8_t>::const_iterator begin,
2711+ std::vector<std::uint8_t>::const_iterator end)
2712+ : begin{begin}, current{begin}, end{end} {}
2713+
2714+std::uint8_t sirf::Reader::read_unsigned_char()
2715+{
2716+ if (current + sizeof(std::uint8_t) > end)
2717+ throw std::out_of_range{"Read buffer exhausted"};
2718+
2719+ auto result = *current;
2720+ ++current;
2721+ return result;
2722+}
2723+
2724+std::int8_t sirf::Reader::read_signed_char()
2725+{
2726+ if (current + sizeof(std::int8_t) > end)
2727+ throw std::out_of_range{"Read buffer exhausted"};
2728+
2729+ auto result = reinterpret_cast<const std::int8_t*>(&(*current));
2730+ current += sizeof(std::int8_t);
2731+ return *result;
2732+}
2733+
2734+std::uint16_t sirf::Reader::read_unsigned_short()
2735+{
2736+ if (current + sizeof(std::uint16_t) > end)
2737+ throw std::out_of_range{"Read buffer exhausted"};
2738+
2739+ auto result = reinterpret_cast<const std::uint16_t*>(&(*current));
2740+ current += sizeof(std::uint16_t);
2741+ return ::htons(*result);
2742+}
2743+
2744+std::int16_t sirf::Reader::read_signed_short()
2745+{
2746+ if (current + sizeof(std::int16_t) > end)
2747+ throw std::out_of_range{"Read buffer exhausted"};
2748+
2749+ auto result = reinterpret_cast<const std::int16_t*>(&(*current));
2750+ current += sizeof(std::int16_t);
2751+ return ::htons(*result);
2752+}
2753+
2754+std::uint32_t sirf::Reader::read_unsigned_long()
2755+{
2756+ if (current + sizeof(std::uint32_t) > end)
2757+ throw std::out_of_range{"Read buffer exhausted"};
2758+
2759+ auto result = reinterpret_cast<const std::uint32_t*>(&(*current));
2760+ current += sizeof(std::uint32_t);
2761+ return ::htonl(*result);
2762+}
2763+
2764+std::int32_t sirf::Reader::read_signed_long()
2765+{
2766+ if (current + sizeof(std::int32_t) > end)
2767+ throw std::out_of_range{"Read buffer exhausted"};
2768+
2769+ auto result = reinterpret_cast<const std::int32_t*>(&(*current));
2770+ current += sizeof(std::int32_t);
2771+ return ::htonl(*result);
2772+}
2773
2774=== added file 'src/location/providers/sirf/reader.h'
2775--- src/location/providers/sirf/reader.h 1970-01-01 00:00:00 +0000
2776+++ src/location/providers/sirf/reader.h 2017-05-05 09:37:41 +0000
2777@@ -0,0 +1,52 @@
2778+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
2779+//
2780+// This library is free software: you can redistribute it and/or modify
2781+// it under the terms of the GNU Lesser General Public License as published
2782+// by the Free Software Foundation, either version 3 of the License, or
2783+// (at your option) any later version.
2784+//
2785+// This program is distributed in the hope that it will be useful,
2786+// but WITHOUT ANY WARRANTY; without even the implied warranty of
2787+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2788+// GNU General Public License for more details.
2789+//
2790+// You should have received a copy of the GNU Lesser General Public License
2791+// along with this program. If not, see <http://www.gnu.org/licenses/>.
2792+
2793+#ifndef LOCATION_PROVIDERS_SIRF_READER_H_
2794+#define LOCATION_PROVIDERS_SIRF_READER_H_
2795+
2796+#include <cstdint>
2797+#include <vector>
2798+
2799+namespace location
2800+{
2801+namespace providers
2802+{
2803+namespace sirf
2804+{
2805+
2806+class Reader
2807+{
2808+public:
2809+ explicit Reader(std::vector<std::uint8_t>::const_iterator begin,
2810+ std::vector<std::uint8_t>::const_iterator end);
2811+
2812+ std::uint8_t read_unsigned_char();
2813+ std::int8_t read_signed_char();
2814+ std::uint16_t read_unsigned_short();
2815+ std::int16_t read_signed_short();
2816+ std::uint32_t read_unsigned_long();
2817+ std::int32_t read_signed_long();
2818+
2819+private:
2820+ std::vector<std::uint8_t>::const_iterator begin;
2821+ std::vector<std::uint8_t>::const_iterator current;
2822+ std::vector<std::uint8_t>::const_iterator end;
2823+};
2824+
2825+} // namespace sirf
2826+} // namespace providers
2827+} // namespace location
2828+
2829+#endif // LOCATION_PROVIDERS_SIRF_READER_H_
2830
2831=== added file 'src/location/providers/sirf/receiver.cpp'
2832--- src/location/providers/sirf/receiver.cpp 1970-01-01 00:00:00 +0000
2833+++ src/location/providers/sirf/receiver.cpp 2017-05-05 09:37:41 +0000
2834@@ -0,0 +1,80 @@
2835+#include <location/providers/sirf/receiver.h>
2836+
2837+#include <location/nmea/sentence.h>
2838+#include <location/providers/sirf/message.h>
2839+
2840+#include <iostream>
2841+
2842+namespace sirf = location::providers::sirf;
2843+
2844+namespace
2845+{
2846+
2847+struct EncodingVisitor : public boost::static_visitor<std::vector<std::uint8_t>>
2848+{
2849+ template<typename T>
2850+ std::vector<std::uint8_t> operator()(const T&) const
2851+ {
2852+ throw std::logic_error{"Encoding not supported"};
2853+ }
2854+
2855+ std::vector<std::uint8_t> operator()(const sirf::InitializeDataSource& ids) const
2856+ {
2857+ return sirf::encode_message(ids);
2858+ }
2859+
2860+ std::vector<std::uint8_t> operator()(const sirf::SetProtocol& sp) const
2861+ {
2862+ return sirf::encode_message(sp);
2863+ }
2864+};
2865+
2866+} // namespace
2867+
2868+sirf::Receiver::Receiver(const std::shared_ptr<Monitor>& monitor) : monitor{monitor} {}
2869+
2870+void sirf::Receiver::send_message(const Message& message)
2871+{
2872+ send_encoded_message(boost::apply_visitor(EncodingVisitor{}, message));
2873+}
2874+
2875+void sirf::Receiver::process_chunk(Buffer::iterator it, Buffer::iterator itE)
2876+{
2877+ while (it != itE)
2878+ {
2879+ auto result = sirf_scanner.update(*it);
2880+
2881+ if (std::get<0>(result) == Scanner::Expect::nothing_more)
2882+ {
2883+ try
2884+ {
2885+ monitor->on_new_sirf_message(sirf_scanner.finalize());
2886+ }
2887+ catch (...)
2888+ {
2889+ // Dropping the exception as there is hardly any reasonable measure
2890+ // we can take. Both scanners are designed to recover from issues, and we
2891+ // we just trap the exception here to guarantee that we keep on consuming the
2892+ // entire buffer.
2893+ }
2894+ }
2895+ else if (!std::get<1>(result))
2896+ {
2897+ if (nmea::Scanner::Expect::nothing_more == nmea_scanner.update(*it))
2898+ {
2899+ try
2900+ {
2901+ monitor->on_new_nmea_sentence(nmea::parse_sentence(nmea_scanner.finalize()));
2902+ }
2903+ catch (...)
2904+ {
2905+ // Dropping the exception as there is hardly any reasonable measure
2906+ // we can take. Both scanners are designed to recover from issues, and we
2907+ // we just trap the exception here to guarantee that we keep on consuming the
2908+ // entire buffer.
2909+ }
2910+ }
2911+ }
2912+ ++it;
2913+ }
2914+}
2915
2916=== added file 'src/location/providers/sirf/receiver.h'
2917--- src/location/providers/sirf/receiver.h 1970-01-01 00:00:00 +0000
2918+++ src/location/providers/sirf/receiver.h 2017-05-05 09:37:41 +0000
2919@@ -0,0 +1,92 @@
2920+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
2921+//
2922+// This library is free software: you can redistribute it and/or modify
2923+// it under the terms of the GNU Lesser General Public License as published
2924+// by the Free Software Foundation, either version 3 of the License, or
2925+// (at your option) any later version.
2926+//
2927+// This program is distributed in the hope that it will be useful,
2928+// but WITHOUT ANY WARRANTY; without even the implied warranty of
2929+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2930+// GNU General Public License for more details.
2931+//
2932+// You should have received a copy of the GNU Lesser General Public License
2933+// along with this program. If not, see <http://www.gnu.org/licenses/>.
2934+
2935+#ifndef LOCATION_PROVIDERS_SIRF_RECEIVER_H_
2936+#define LOCATION_PROVIDERS_SIRF_RECEIVER_H_
2937+
2938+#include <location/providers/sirf/codec.h>
2939+#include <location/providers/sirf/message.h>
2940+#include <location/providers/sirf/scanner.h>
2941+
2942+#include <location/nmea/scanner.h>
2943+#include <location/nmea/sentence.h>
2944+
2945+#include <memory>
2946+
2947+namespace location
2948+{
2949+namespace providers
2950+{
2951+namespace sirf
2952+{
2953+
2954+/// @brief Receiver connects to a ublox 8 GNSS receiver.
2955+class Receiver
2956+{
2957+public:
2958+ using Buffer = std::array<std::uint8_t, 4096>;
2959+
2960+ /// @brief Monitor provides calling code with means for monitoring
2961+ /// receiver operation.
2962+ class Monitor
2963+ {
2964+ public:
2965+ /// @cond
2966+ Monitor() = default;
2967+ Monitor(const Monitor&) = delete;
2968+ Monitor(Monitor&&) = delete;
2969+ virtual ~Monitor() = default;
2970+ Monitor& operator=(const Monitor&) = delete;
2971+ Monitor& operator=(Monitor&&) = delete;
2972+ /// @endcond
2973+
2974+ /// @brief on_new_ubx_message is invoked for every complete and parsed
2975+ /// ubx message.
2976+ virtual void on_new_sirf_message(const sirf::Message& message) = 0;
2977+
2978+ /// @brief on_new_nmea_sentence is invoked for every complete and parsed
2979+ /// nmea sentence.
2980+ virtual void on_new_nmea_sentence(const nmea::Sentence& sentence) = 0;
2981+ };
2982+
2983+ /// @brief send_message encodes and sends 'message' to the receiver.
2984+ void send_message(const Message& message);
2985+
2986+ /// @brief send_encoded_message sends out data to the receiver.
2987+ virtual void send_encoded_message(const std::vector<std::uint8_t> &data) = 0;
2988+
2989+protected:
2990+ /// @brief Receiver initializes a new instance with monitor
2991+ ///
2992+ /// Throws in case of issues.
2993+ Receiver(const std::shared_ptr<Monitor>& monitor);
2994+
2995+ /// @brief process_chunk iterates over the given range, updating scanners and
2996+ /// parsers.
2997+ ///
2998+ /// Calls out to a configured monitor instance for announcing results.
2999+ void process_chunk(Buffer::iterator it, Buffer::iterator itE);
3000+
3001+private:
3002+ std::shared_ptr<Monitor> monitor;
3003+ nmea::Scanner nmea_scanner;
3004+ sirf::Scanner sirf_scanner;
3005+};
3006+
3007+} // namespace sirf
3008+} // namespace providers
3009+} // namespace location
3010+
3011+#endif // LOCATION_PROVIDERS_SIRF_RECEIVER_H_
3012
3013=== added file 'src/location/providers/sirf/scanner.cpp'
3014--- src/location/providers/sirf/scanner.cpp 1970-01-01 00:00:00 +0000
3015+++ src/location/providers/sirf/scanner.cpp 2017-05-05 09:37:41 +0000
3016@@ -0,0 +1,161 @@
3017+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
3018+//
3019+// This library is free software: you can redistribute it and/or modify
3020+// it under the terms of the GNU Lesser General Public License as published
3021+// by the Free Software Foundation, either version 3 of the License, or
3022+// (at your option) any later version.
3023+//
3024+// This program is distributed in the hope that it will be useful,
3025+// but WITHOUT ANY WARRANTY; without even the implied warranty of
3026+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3027+// GNU General Public License for more details.
3028+//
3029+// You should have received a copy of the GNU Lesser General Public License
3030+// along with this program. If not, see <http://www.gnu.org/licenses/>.
3031+
3032+#include <location/providers/sirf/scanner.h>
3033+
3034+#include <location/providers/sirf/codec.h>
3035+#include <location/providers/sirf/magic.h>
3036+#include <location/providers/sirf/message.h>
3037+
3038+#include <cstdint>
3039+#include <functional>
3040+#include <iomanip>
3041+#include <iostream>
3042+#include <map>
3043+#include <stdexcept>
3044+#include <tuple>
3045+#include <vector>
3046+
3047+namespace sirf = location::providers::sirf;
3048+
3049+sirf::Scanner::Scanner()
3050+ : next{Expect::sync_char_begin_1},
3051+ expected_size{0},
3052+ message_id{0},
3053+ payload_iterator{payload.end()},
3054+ checksum_1{0},
3055+ checksum_2{0}
3056+{
3057+}
3058+
3059+std::tuple<sirf::Scanner::Expect, bool> sirf::Scanner::update(std::uint8_t c)
3060+{
3061+ bool consumed = false;
3062+
3063+ switch (next)
3064+ {
3065+ case Expect::sync_char_begin_1:
3066+ if (c == begin::sync_char_1)
3067+ {
3068+ reset();
3069+ next = Expect::sync_char_begin_2;
3070+ consumed = true;
3071+ }
3072+ break;
3073+ case Expect::sync_char_begin_2:
3074+ if (c == begin::sync_char_2)
3075+ {
3076+ next = Expect::length_1;
3077+ consumed = true;
3078+ }
3079+ break;
3080+ case Expect::length_1:
3081+ expected_size |= (c << 8);
3082+ next = Expect::length_2;
3083+ consumed = true;
3084+ break;
3085+ case Expect::length_2:
3086+ expected_size |= c;
3087+ if (expected_size > 0)
3088+ expected_size -= 1;
3089+ payload.resize(expected_size);
3090+ payload_iterator = payload.begin();
3091+ next = Expect::message_id;
3092+ consumed = true;
3093+ break;
3094+ case Expect::message_id:
3095+ checksum(c);
3096+ message_id = c;
3097+ next = expected_size > 0 ? Expect::payload : Expect::checksum_1;
3098+ consumed = true;
3099+ break;
3100+ case Expect::payload:
3101+ checksum(c);
3102+ *payload_iterator = c;
3103+ ++payload_iterator;
3104+ next = payload_iterator == payload.end()
3105+ ? Expect::checksum_1
3106+ : next;
3107+ consumed = true;
3108+ break;
3109+ case Expect::checksum_1:
3110+ checksum_1 = c;
3111+ next = Expect::checksum_2;
3112+ consumed = true;
3113+ break;
3114+ case Expect::checksum_2:
3115+ checksum_2 = c;
3116+ next = Expect::sync_char_end_1;
3117+ consumed = true;
3118+ break;
3119+ case Expect::sync_char_end_1:
3120+ if (c == end::sync_char_1)
3121+ {
3122+ next = Expect::sync_char_end_2;
3123+ consumed = true;
3124+ }
3125+ break;
3126+ case Expect::sync_char_end_2:
3127+ if (c == end::sync_char_2)
3128+ {
3129+ next = Expect::nothing_more;
3130+ consumed = true;
3131+ }
3132+ break;
3133+ default:
3134+ consumed = false;
3135+ break;
3136+ }
3137+
3138+ return std::make_tuple(next, consumed);
3139+}
3140+
3141+sirf::Message sirf::Scanner::finalize()
3142+{
3143+ if (next != Expect::nothing_more)
3144+ throw std::logic_error{"Not ready for extraction."};
3145+
3146+ struct Scope
3147+ {
3148+ Scope(Scanner& scanner) : scanner{scanner} {}
3149+ ~Scope() { scanner.reset(); }
3150+
3151+ Scanner& scanner;
3152+ } scope{*this};
3153+
3154+ if (checksum() != ((checksum_1 << 8) | checksum_2))
3155+ throw std::runtime_error("Failed to verify sirf protocol message integrity.");
3156+
3157+ switch (message_id)
3158+ {
3159+ case GeodeticNavigationData::id:
3160+ return decode_message<GeodeticNavigationData>(payload);
3161+ default:
3162+ break;
3163+ }
3164+
3165+ return Message{Null{}};
3166+}
3167+
3168+void sirf::Scanner::reset()
3169+{
3170+ checksum = Checksum{};
3171+ next = Expect::sync_char_begin_1;
3172+ expected_size = 0;
3173+ message_id = 0;
3174+ payload.clear();
3175+ payload_iterator = payload.end();
3176+ checksum_1 = checksum_2 = 0;
3177+}
3178
3179=== added file 'src/location/providers/sirf/scanner.h'
3180--- src/location/providers/sirf/scanner.h 1970-01-01 00:00:00 +0000
3181+++ src/location/providers/sirf/scanner.h 2017-05-05 09:37:41 +0000
3182@@ -0,0 +1,76 @@
3183+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
3184+//
3185+// This library is free software: you can redistribute it and/or modify
3186+// it under the terms of the GNU Lesser General Public License as published
3187+// by the Free Software Foundation, either version 3 of the License, or
3188+// (at your option) any later version.
3189+//
3190+// This program is distributed in the hope that it will be useful,
3191+// but WITHOUT ANY WARRANTY; without even the implied warranty of
3192+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3193+// GNU General Public License for more details.
3194+//
3195+// You should have received a copy of the GNU Lesser General Public License
3196+// along with this program. If not, see <http://www.gnu.org/licenses/>.
3197+
3198+#ifndef LOCATION_PROVIDERS_SIRF_SCANNER_H_
3199+#define LOCATION_PROVIDERS_SIRF_SCANNER_H_
3200+
3201+#include <location/providers/sirf/checksum.h>
3202+#include <location/providers/sirf/message.h>
3203+
3204+#include <cstdint>
3205+#include <tuple>
3206+#include <vector>
3207+
3208+namespace location
3209+{
3210+namespace providers
3211+{
3212+namespace sirf
3213+{
3214+
3215+class Scanner
3216+{
3217+public:
3218+ /// @brief Expect enumerates the different states of the scanner/parser.
3219+ enum class Expect
3220+ {
3221+ sync_char_begin_1,
3222+ sync_char_begin_2,
3223+ length_1,
3224+ length_2,
3225+ message_id,
3226+ payload,
3227+ checksum_1,
3228+ checksum_2,
3229+ sync_char_end_1,
3230+ sync_char_end_2,
3231+ nothing_more
3232+ };
3233+
3234+ Scanner();
3235+
3236+ std::tuple<Expect, bool> update(std::uint8_t c);
3237+
3238+ Message finalize();
3239+
3240+private:
3241+
3242+ void reset();
3243+
3244+ Expect next;
3245+ Checksum checksum;
3246+ std::uint16_t expected_size;
3247+ std::uint8_t message_id;
3248+ std::vector<uint8_t> payload;
3249+ std::vector<uint8_t>::iterator payload_iterator;
3250+ std::uint8_t checksum_1;
3251+ std::uint8_t checksum_2;
3252+};
3253+
3254+}
3255+}
3256+}
3257+
3258+#endif // LOCATION_PROVIDERS_SIRF_SCANNER_H_
3259
3260=== added file 'src/location/providers/sirf/serial_port_receiver.cpp'
3261--- src/location/providers/sirf/serial_port_receiver.cpp 1970-01-01 00:00:00 +0000
3262+++ src/location/providers/sirf/serial_port_receiver.cpp 2017-05-05 09:37:41 +0000
3263@@ -0,0 +1,80 @@
3264+#include <location/providers/sirf/serial_port_receiver.h>
3265+
3266+#include <location/logging.h>
3267+
3268+#include <iostream>
3269+#include <system_error>
3270+
3271+namespace sirf = location::providers::sirf;
3272+
3273+std::shared_ptr<sirf::SerialPortReceiver> sirf::SerialPortReceiver::create(
3274+ boost::asio::io_service& ios, const boost::filesystem::path& dev, const std::shared_ptr<Monitor>& monitor)
3275+{
3276+ return std::shared_ptr<SerialPortReceiver>{new SerialPortReceiver{ios, dev, monitor}};
3277+}
3278+
3279+sirf::SerialPortReceiver::SerialPortReceiver(boost::asio::io_service& ios, const boost::filesystem::path& dev,
3280+ const std::shared_ptr<Monitor>& monitor)
3281+ : Receiver{monitor}, ios{ios}, serial_port{ios, dev.string().c_str()}
3282+{
3283+ serial_port.set_option(boost::asio::serial_port::baud_rate(4800));
3284+ serial_port.set_option(boost::asio::serial_port::stop_bits(boost::asio::serial_port::stop_bits::one));
3285+ serial_port.set_option(boost::asio::serial_port::parity(boost::asio::serial_port::parity::none));
3286+ serial_port.set_option(boost::asio::serial_port::flow_control(boost::asio::serial_port::flow_control::none));
3287+}
3288+
3289+void sirf::SerialPortReceiver::send_encoded_message(const std::vector<std::uint8_t>& data)
3290+{
3291+ auto thiz = shared_from_this();
3292+ std::weak_ptr<SerialPortReceiver> wp{thiz};
3293+
3294+ ios.dispatch([this, wp, data]()
3295+ {
3296+ if (auto sp = wp.lock())
3297+ boost::asio::write(serial_port, boost::asio::buffer(data), boost::asio::transfer_all());
3298+ });
3299+}
3300+
3301+void sirf::SerialPortReceiver::start()
3302+{
3303+ ::tcflush(serial_port.lowest_layer().native_handle(), TCIFLUSH);
3304+ start_read();
3305+}
3306+
3307+void sirf::SerialPortReceiver::stop()
3308+{
3309+ serial_port.cancel();
3310+}
3311+
3312+void sirf::SerialPortReceiver::start_read()
3313+{
3314+ auto thiz = shared_from_this();
3315+ std::weak_ptr<SerialPortReceiver> wp{thiz};
3316+
3317+ boost::asio::async_read(serial_port, boost::asio::buffer(&buffer.front(), buffer.size()),
3318+ [this, wp](const boost::system::error_code& ec, std::size_t transferred) {
3319+ if (ec == boost::asio::error::operation_aborted)
3320+ return;
3321+
3322+ if (auto sp = wp.lock())
3323+ {
3324+ if (not ec)
3325+ {
3326+ try
3327+ {
3328+ process_chunk(buffer.begin(), buffer.begin() + transferred);
3329+ }
3330+ catch(const std::exception& e)
3331+ {
3332+ LOG(WARNING) << "Error processing data chunk: " << e.what();
3333+ }
3334+ catch(...)
3335+ {
3336+ LOG(WARNING) << "Error processing data chunk.";
3337+ }
3338+
3339+ start_read();
3340+ }
3341+ }
3342+ });
3343+}
3344
3345=== added file 'src/location/providers/sirf/serial_port_receiver.h'
3346--- src/location/providers/sirf/serial_port_receiver.h 1970-01-01 00:00:00 +0000
3347+++ src/location/providers/sirf/serial_port_receiver.h 2017-05-05 09:37:41 +0000
3348@@ -0,0 +1,79 @@
3349+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
3350+//
3351+// This library is free software: you can redistribute it and/or modify
3352+// it under the terms of the GNU Lesser General Public License as published
3353+// by the Free Software Foundation, either version 3 of the License, or
3354+// (at your option) any later version.
3355+//
3356+// This program is distributed in the hope that it will be useful,
3357+// but WITHOUT ANY WARRANTY; without even the implied warranty of
3358+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3359+// GNU General Public License for more details.
3360+//
3361+// You should have received a copy of the GNU Lesser General Public License
3362+// along with this program. If not, see <http://www.gnu.org/licenses/>.
3363+#ifndef LOCATION_PROVIDERS_SIRF_SERIAL_PORT_RECEIVER_H_
3364+#define LOCATION_PROVIDERS_SIRF_SERIAL_PORT_RECEIVER_H_
3365+
3366+#include <location/providers/sirf/receiver.h>
3367+
3368+#include <boost/asio.hpp>
3369+#include <boost/filesystem.hpp>
3370+
3371+#include <array>
3372+#include <atomic>
3373+
3374+namespace location
3375+{
3376+namespace providers
3377+{
3378+namespace sirf
3379+{
3380+
3381+/// @brief SerialPortReceiver connects to a ublox 8 GNSS receiver over a serial
3382+/// port.
3383+class SerialPortReceiver : public Receiver, public std::enable_shared_from_this<SerialPortReceiver>
3384+{
3385+public:
3386+ /// @brief create returns a new Receiver instance connected to the
3387+ /// serial port reachable under dev.
3388+ static std::shared_ptr<SerialPortReceiver> create(boost::asio::io_service& ios, const boost::filesystem::path& dev,
3389+ const std::shared_ptr<Receiver::Monitor>& monitor);
3390+
3391+ void start();
3392+ void stop();
3393+
3394+ void send_encoded_message(const std::vector<std::uint8_t>& data) override;
3395+
3396+private:
3397+ enum class State
3398+ {
3399+ running,
3400+ stopped
3401+ };
3402+
3403+ /// @brief Receiver initializes a new instance opening the serial port
3404+ /// located at path.
3405+ ///
3406+ /// Throws in case of issues.
3407+ SerialPortReceiver(boost::asio::io_service& ios, const boost::filesystem::path& dev,
3408+ const std::shared_ptr<Receiver::Monitor>& monitor);
3409+
3410+ /// @brief finalize returns a finalized reader instance reading from
3411+ /// the serial port.
3412+ std::shared_ptr<SerialPortReceiver> finalize();
3413+
3414+ /// @brief start_read starts an async read operation from the configured
3415+ /// serial port.
3416+ void start_read();
3417+
3418+ Receiver::Buffer buffer;
3419+ boost::asio::io_service& ios;
3420+ boost::asio::serial_port serial_port;
3421+};
3422+
3423+}
3424+}
3425+}
3426+
3427+#endif // LOCATION_PROVIDERS_SIRF_SERIAL_PORT_RECEIVER_H_
3428
3429=== added file 'src/location/providers/sirf/set_protocol.h'
3430--- src/location/providers/sirf/set_protocol.h 1970-01-01 00:00:00 +0000
3431+++ src/location/providers/sirf/set_protocol.h 2017-05-05 09:37:41 +0000
3432@@ -0,0 +1,73 @@
3433+// Copyright (C) 2017 Thomas Voss <thomas.voss@canonical.com>
3434+//
3435+// This library is free software: you can redistribute it and/or modify
3436+// it under the terms of the GNU Lesser General Public License as published
3437+// by the Free Software Foundation, either version 3 of the License, or
3438+// (at your option) any later version.
3439+//
3440+// This program is distributed in the hope that it will be useful,
3441+// but WITHOUT ANY WARRANTY; without even the implied warranty of
3442+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3443+// GNU General Public License for more details.
3444+//
3445+// You should have received a copy of the GNU Lesser General Public License
3446+// along with this program. If not, see <http://www.gnu.org/licenses/>.
3447+
3448+#ifndef LOCATION_PROVIDERS_SIRF_SET_PROTOCOL_H_
3449+#define LOCATION_PROVIDERS_SIRF_SET_PROTOCOL_H_
3450+
3451+#include <location/providers/sirf/writer.h>
3452+
3453+#include <cstdint>
3454+#include <iostream>
3455+
3456+namespace location
3457+{
3458+namespace providers
3459+{
3460+namespace sirf
3461+{
3462+
3463+// Switches the protocol to another protocol. For most software,
3464+// the default protocol is SiRF binary.
3465+struct SetProtocol
3466+{
3467+ enum
3468+ {
3469+ null = 0,
3470+ sirf_binary = 1,
3471+ nmea = 2,
3472+ ascii = 3,
3473+ rtcm = 4,
3474+ user1 = 5,
3475+ sirf_loc = 6,
3476+ statistic = 7
3477+ };
3478+
3479+ static constexpr std::uint8_t id{0x87};
3480+
3481+ std::size_t size() const
3482+ {
3483+ return sizeof(std::uint8_t) + sizeof(std::uint8_t);
3484+ }
3485+
3486+ void write(Writer& writer) const
3487+ {
3488+ writer.write_unsigned_char(id);
3489+ writer.write_unsigned_char(protocol);
3490+ }
3491+
3492+ std::uint8_t protocol;
3493+};
3494+
3495+inline std::ostream& operator<<(std::ostream& out, const SetProtocol& sp)
3496+{
3497+ return out << "SetProtocol:" << std::endl
3498+ << " protocol: " << sp.protocol;
3499+}
3500+
3501+} // namespace sirf
3502+} // namespace providers
3503+} // namespace location
3504+
3505+#endif // LOCATION_PROVIDERS_SIRF_SET_PROTOCOL_H_
3506
3507=== added file 'src/location/providers/sirf/writer.cpp'
3508--- src/location/providers/sirf/writer.cpp 1970-01-01 00:00:00 +0000
3509+++ src/location/providers/sirf/writer.cpp 2017-05-05 09:37:41 +0000
3510@@ -0,0 +1,94 @@
3511+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
3512+//
3513+// This library is free software: you can redistribute it and/or modify
3514+// it under the terms of the GNU Lesser General Public License as published
3515+// by the Free Software Foundation, either version 3 of the License, or
3516+// (at your option) any later version.
3517+//
3518+// This program is distributed in the hope that it will be useful,
3519+// but WITHOUT ANY WARRANTY; without even the implied warranty of
3520+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3521+// GNU General Public License for more details.
3522+//
3523+// You should have received a copy of the GNU Lesser General Public License
3524+// along with this program. If not, see <http://www.gnu.org/licenses/>.
3525+
3526+#include <location/providers/sirf/writer.h>
3527+
3528+#include <arpa/inet.h>
3529+
3530+#include <cstring>
3531+#include <stdexcept>
3532+
3533+namespace sirf = location::providers::sirf;
3534+
3535+sirf::Writer::Writer(std::vector<std::uint8_t>::iterator begin,
3536+ std::vector<std::uint8_t>::iterator end)
3537+ : begin{begin}, current{begin}, end{end} {}
3538+
3539+void sirf::Writer::write_unsigned_char(std::uint8_t value)
3540+{
3541+ if (current + sizeof(value) > end)
3542+ throw std::out_of_range{"Write buffer exhausted"};
3543+
3544+ *reinterpret_cast<std::uint8_t*>(&(*current)) = value;
3545+ current += sizeof(value);
3546+
3547+}
3548+
3549+void sirf::Writer::write_signed_char(std::int8_t value)
3550+{
3551+ if (current + sizeof(value) > end)
3552+ throw std::out_of_range{"Write buffer exhausted"};
3553+
3554+ *reinterpret_cast<std::int8_t*>(&(*current)) = value;
3555+ current += sizeof(value);
3556+
3557+}
3558+
3559+void sirf::Writer::write_unsigned_short(std::uint16_t value)
3560+{
3561+ if (current + sizeof(value) > end)
3562+ throw std::out_of_range{"Write buffer exhausted"};
3563+
3564+ *reinterpret_cast<std::uint16_t*>(&(*current)) = ::ntohs(value);
3565+ current += sizeof(value);
3566+}
3567+
3568+void sirf::Writer::write_signed_short(std::int16_t value)
3569+{
3570+ if (current + sizeof(value) > end)
3571+ throw std::out_of_range{"Write buffer exhausted"};
3572+
3573+ *reinterpret_cast<std::int16_t*>(&(*current)) = ::ntohs(value);
3574+ current += sizeof(value);
3575+}
3576+
3577+void sirf::Writer::write_unsigned_long(std::uint32_t value)
3578+{
3579+ if (current + sizeof(value) > end)
3580+ throw std::out_of_range{"Write buffer exhausted"};
3581+
3582+ *reinterpret_cast<std::uint32_t*>(&(*current)) = ::ntohl(value);
3583+ current += sizeof(value);
3584+}
3585+
3586+void sirf::Writer::write_signed_long(std::int32_t value)
3587+{
3588+ if (current + sizeof(value) > end)
3589+ throw std::out_of_range{"Write buffer exhausted"};
3590+
3591+ *reinterpret_cast<std::int32_t*>(&(*current)) = ::ntohl(value);
3592+ current += sizeof(value);
3593+}
3594+
3595+sirf::Writer sirf::Writer::slice(std::size_t size)
3596+{
3597+ if (current + size > end)
3598+ throw std::out_of_range{"Write buffer exhausted"};
3599+
3600+ Writer result{current, current + size};
3601+ current += size;
3602+
3603+ return result;
3604+}
3605
3606=== added file 'src/location/providers/sirf/writer.h'
3607--- src/location/providers/sirf/writer.h 1970-01-01 00:00:00 +0000
3608+++ src/location/providers/sirf/writer.h 2017-05-05 09:37:41 +0000
3609@@ -0,0 +1,54 @@
3610+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
3611+//
3612+// This library is free software: you can redistribute it and/or modify
3613+// it under the terms of the GNU Lesser General Public License as published
3614+// by the Free Software Foundation, either version 3 of the License, or
3615+// (at your option) any later version.
3616+//
3617+// This program is distributed in the hope that it will be useful,
3618+// but WITHOUT ANY WARRANTY; without even the implied warranty of
3619+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3620+// GNU General Public License for more details.
3621+//
3622+// You should have received a copy of the GNU Lesser General Public License
3623+// along with this program. If not, see <http://www.gnu.org/licenses/>.
3624+
3625+#ifndef LOCATION_PROVIDERS_SIRF_WRITER_H_
3626+#define LOCATION_PROVIDERS_SIRF_WRITER_H_
3627+
3628+#include <cstdint>
3629+#include <vector>
3630+
3631+namespace location
3632+{
3633+namespace providers
3634+{
3635+namespace sirf
3636+{
3637+
3638+class Writer
3639+{
3640+public:
3641+ explicit Writer(std::vector<std::uint8_t>::iterator begin,
3642+ std::vector<std::uint8_t>::iterator end);
3643+
3644+ void write_unsigned_char(std::uint8_t value);
3645+ void write_signed_char(std::int8_t value);
3646+ void write_unsigned_short(std::uint16_t value);
3647+ void write_signed_short(std::int16_t value);
3648+ void write_unsigned_long(std::uint32_t value);
3649+ void write_signed_long(std::int32_t value);
3650+
3651+ Writer slice(std::size_t size);
3652+
3653+private:
3654+ std::vector<std::uint8_t>::iterator begin;
3655+ std::vector<std::uint8_t>::iterator current;
3656+ std::vector<std::uint8_t>::iterator end;
3657+};
3658+
3659+} // namespace sirf
3660+} // namespace providers
3661+} // namespace location
3662+
3663+#endif // LOCATION_PROVIDERS_SIRF_WRITER_H_
3664
3665=== modified file 'src/location/providers/ubx/CMakeLists.txt'
3666--- src/location/providers/ubx/CMakeLists.txt 2017-03-23 12:32:38 +0000
3667+++ src/location/providers/ubx/CMakeLists.txt 2017-05-05 09:37:41 +0000
3668@@ -37,11 +37,14 @@
3669 _8/nav/pvt.cpp
3670 _8/nav/sat.h
3671 _8/nav/sat.cpp
3672- _8/nmea/scanner.cpp
3673- _8/nmea/sentence.cpp
3674
3675 provider.h provider.cpp)
3676
3677+target_link_libraries(
3678+ ubx
3679+
3680+ nmea)
3681+
3682 set(
3683 ENABLED_PROVIDER_TARGETS
3684 ${ENABLED_PROVIDER_TARGETS} ubx
3685
3686=== modified file 'src/location/providers/ubx/_8/receiver.cpp'
3687--- src/location/providers/ubx/_8/receiver.cpp 2017-03-23 15:47:38 +0000
3688+++ src/location/providers/ubx/_8/receiver.cpp 2017-05-05 09:37:41 +0000
3689@@ -1,6 +1,6 @@
3690 #include <location/providers/ubx/_8/receiver.h>
3691
3692-#include <location/providers/ubx/_8/nmea/sentence.h>
3693+#include <location/nmea/sentence.h>
3694
3695 #include <iostream>
3696
3697
3698=== modified file 'src/location/providers/ubx/_8/receiver.h'
3699--- src/location/providers/ubx/_8/receiver.h 2017-03-24 21:13:53 +0000
3700+++ src/location/providers/ubx/_8/receiver.h 2017-05-05 09:37:41 +0000
3701@@ -20,8 +20,8 @@
3702 #include <location/providers/ubx/_8/message.h>
3703 #include <location/providers/ubx/_8/scanner.h>
3704
3705-#include <location/providers/ubx/_8/nmea/scanner.h>
3706-#include <location/providers/ubx/_8/nmea/sentence.h>
3707+#include <location/nmea/scanner.h>
3708+#include <location/nmea/sentence.h>
3709
3710 #include <memory>
3711
3712@@ -60,7 +60,7 @@
3713
3714 /// @brief on_new_nmea_sentence is invoked for every complete and parsed
3715 /// nmea sentence.
3716- virtual void on_new_nmea_sentence(const ubx::_8::nmea::Sentence& sentence) = 0;
3717+ virtual void on_new_nmea_sentence(const nmea::Sentence& sentence) = 0;
3718 };
3719
3720 /// @brief send_message encodes and sends 'message' to the receiver.
3721@@ -83,7 +83,7 @@
3722
3723 private:
3724 std::shared_ptr<Monitor> monitor;
3725- ubx::_8::nmea::Scanner nmea_scanner;
3726+ nmea::Scanner nmea_scanner;
3727 ubx::_8::Scanner ubx_scanner;
3728 };
3729
3730
3731=== modified file 'src/location/providers/ubx/_8/scanner.cpp'
3732--- src/location/providers/ubx/_8/scanner.cpp 2017-03-23 12:32:38 +0000
3733+++ src/location/providers/ubx/_8/scanner.cpp 2017-05-05 09:37:41 +0000
3734@@ -105,7 +105,7 @@
3735 expected_size |= (c << 8);
3736 payload.resize(expected_size);
3737 payload_iterator = payload.begin();
3738- next = Expect::payload;
3739+ next = expected_size > 0 ? Expect::payload : Expect::ck_a;
3740 consumed = true;
3741 break;
3742 case Expect::payload:
3743
3744=== modified file 'src/location/providers/ubx/provider.cpp'
3745--- src/location/providers/ubx/provider.cpp 2017-04-21 07:16:45 +0000
3746+++ src/location/providers/ubx/provider.cpp 2017-05-05 09:37:41 +0000
3747@@ -80,7 +80,7 @@
3748 }
3749
3750
3751-void ubx::Provider::Monitor::on_new_nmea_sentence(const _8::nmea::Sentence& sentence)
3752+void ubx::Provider::Monitor::on_new_nmea_sentence(const nmea::Sentence& sentence)
3753 {
3754 VLOG(1) << sentence;
3755 if (auto sp = provider.lock())
3756@@ -88,7 +88,7 @@
3757 boost::apply_visitor(*this, sentence);
3758 }
3759
3760-void ubx::Provider::Monitor::operator()(const _8::nmea::Gga& gga)
3761+void ubx::Provider::Monitor::operator()(const nmea::Gga& gga)
3762 {
3763 if (gga.latitude && gga.longitude)
3764 {
3765@@ -159,32 +159,32 @@
3766 });
3767 }
3768
3769-void ubx::Provider::Monitor::operator()(const _8::nmea::Gsa&)
3770-{
3771- // Empty on purpose
3772-}
3773-
3774-void ubx::Provider::Monitor::operator()(const _8::nmea::Gll&)
3775-{
3776- // Empty on purpose
3777-}
3778-
3779-void ubx::Provider::Monitor::operator()(const _8::nmea::Gsv&)
3780-{
3781- // Empty on purpose
3782-}
3783-
3784-void ubx::Provider::Monitor::operator()(const _8::nmea::Rmc&)
3785-{
3786- // Empty on purpose
3787-}
3788-
3789-void ubx::Provider::Monitor::operator()(const _8::nmea::Txt&)
3790-{
3791- // Empty on purpose
3792-}
3793-
3794-void ubx::Provider::Monitor::operator()(const _8::nmea::Vtg& vtg)
3795+void ubx::Provider::Monitor::operator()(const nmea::Gsa&)
3796+{
3797+ // Empty on purpose
3798+}
3799+
3800+void ubx::Provider::Monitor::operator()(const nmea::Gll&)
3801+{
3802+ // Empty on purpose
3803+}
3804+
3805+void ubx::Provider::Monitor::operator()(const nmea::Gsv&)
3806+{
3807+ // Empty on purpose
3808+}
3809+
3810+void ubx::Provider::Monitor::operator()(const nmea::Rmc&)
3811+{
3812+ // Empty on purpose
3813+}
3814+
3815+void ubx::Provider::Monitor::operator()(const nmea::Txt&)
3816+{
3817+ // Empty on purpose
3818+}
3819+
3820+void ubx::Provider::Monitor::operator()(const nmea::Vtg& vtg)
3821 {
3822 auto thiz = shared_from_this();
3823 std::weak_ptr<ubx::Provider::Monitor> wp{thiz};
3824
3825=== modified file 'src/location/providers/ubx/provider.h'
3826--- src/location/providers/ubx/provider.h 2017-04-21 07:16:45 +0000
3827+++ src/location/providers/ubx/provider.h 2017-05-05 09:37:41 +0000
3828@@ -21,7 +21,7 @@
3829 #include <location/provider.h>
3830 #include <location/provider_factory.h>
3831 #include <location/runtime.h>
3832-
3833+#include <location/nmea/sentence.h>
3834 #include <location/providers/ubx/_8/assist_now_online_client.h>
3835 #include <location/providers/ubx/_8/serial_port_receiver.h>
3836
3837@@ -104,20 +104,20 @@
3838 {
3839 // From Receiver::Monitor
3840 void on_new_ubx_message(const _8::Message& message) override;
3841- void on_new_nmea_sentence(const _8::nmea::Sentence& sentence) override;
3842+ void on_new_nmea_sentence(const nmea::Sentence& sentence) override;
3843
3844 template<typename T>
3845 void operator()(const T&) const {}
3846
3847 void operator()(const _8::nav::Pvt& pvt);
3848
3849- void operator()(const _8::nmea::Gga& gga);
3850- void operator()(const _8::nmea::Gsa& gsa);
3851- void operator()(const _8::nmea::Gll& gll);
3852- void operator()(const _8::nmea::Gsv& gsv);
3853- void operator()(const _8::nmea::Rmc& rmc);
3854- void operator()(const _8::nmea::Txt& txt);
3855- void operator()(const _8::nmea::Vtg& vtg);
3856+ void operator()(const nmea::Gga& gga);
3857+ void operator()(const nmea::Gsa& gsa);
3858+ void operator()(const nmea::Gll& gll);
3859+ void operator()(const nmea::Gsv& gsv);
3860+ void operator()(const nmea::Rmc& rmc);
3861+ void operator()(const nmea::Txt& txt);
3862+ void operator()(const nmea::Vtg& vtg);
3863
3864 std::weak_ptr<Provider> provider;
3865 };
3866
3867=== modified file 'src/location/runtime_tests.cpp'
3868--- src/location/runtime_tests.cpp 2017-04-03 07:32:40 +0000
3869+++ src/location/runtime_tests.cpp 2017-05-05 09:37:41 +0000
3870@@ -22,6 +22,7 @@
3871 #include <location/clock.h>
3872 #include <location/glib/runtime.h>
3873 #include <location/providers/gps/hardware_abstraction_layer.h>
3874+#include <location/providers/sirf/provider.h>
3875 #include <location/providers/ubx/provider.h>
3876 #include <location/util/benchmark.h>
3877 #include <location/util/cli.h>
3878@@ -251,12 +252,98 @@
3879 return 0;
3880 }
3881
3882+int sirf(std::ostream& cout, std::ostream&)
3883+{
3884+ location::util::Benchmark benchmark{boost::lexical_cast<unsigned int>(env::get("SIRF_PROVIDER_TEST_TRIALS", "15")), "ttff in [µs]"};
3885+
3886+ auto test_device = env::get_or_throw("SIRF_PROVIDER_TEST_DEVICE");
3887+
3888+ location::providers::sirf::Provider::Configuration configuration
3889+ {
3890+ location::providers::sirf::Provider::Protocol::sirf, test_device
3891+ };
3892+
3893+ auto provider = location::providers::sirf::Provider::create(configuration);
3894+
3895+ struct State
3896+ {
3897+ State() : worker{[this]() { runtime.run(); }}, fix_received(false)
3898+ {
3899+ }
3900+
3901+ ~State()
3902+ {
3903+ runtime.stop();
3904+ if (worker.joinable())
3905+ worker.join();
3906+ }
3907+
3908+ bool wait_for_fix_for(const std::chrono::seconds& seconds)
3909+ {
3910+ std::unique_lock<std::mutex> ul(guard);
3911+ return wait_condition.wait_for(
3912+ ul,
3913+ seconds,
3914+ [this]() {return fix_received == true;});
3915+ }
3916+
3917+ void on_position_updated(const location::Position&)
3918+ {
3919+ fix_received = true;
3920+ wait_condition.notify_all();
3921+ }
3922+
3923+ void reset()
3924+ {
3925+ fix_received = false;
3926+ }
3927+
3928+ location::glib::Runtime runtime{location::glib::Runtime::WithOwnMainLoop{}};
3929+ std::thread worker;
3930+ std::mutex guard;
3931+ std::condition_variable wait_condition;
3932+ bool fix_received;
3933+ } state;
3934+
3935+ provider->position_updates().connect([&state](const location::Update<location::Position>& update)
3936+ {
3937+ state.on_position_updated(update.value);
3938+ });
3939+
3940+ {
3941+ cli::ProgressBar pb(cout, "sirf runtime test: ", 30);
3942+
3943+ benchmark.run(
3944+ [&](std::size_t)
3945+ {
3946+ provider->reset(); state.reset();
3947+ },
3948+ [&](std::size_t trial)
3949+ {
3950+ pb.update(trial / static_cast<double>(benchmark.trials()));
3951+
3952+ provider->activate();
3953+ // We expect a maximum cold start time of 15 minutes. The theoretical
3954+ // limit is 12.5 minutes, and we add up some grace period to make the
3955+ // test more robust (see http://en.wikipedia.org/wiki/Time_to_first_fix).
3956+ expect<true, std::runtime_error>(state.wait_for_fix_for(std::chrono::seconds{15 * 60}), "Wait for fix timed out.");
3957+ provider->deactivate();
3958+ });
3959+ }
3960+
3961+ cout << benchmark << std::endl;
3962+
3963+ return 0;
3964+}
3965+
3966 } // namespace
3967
3968 int location::execute_runtime_tests(const std::string& test_suite, std::ostream& cout, std::ostream& cerr)
3969 {
3970 if (test_suite == "android-gps")
3971 return snr_and_ttff(cout, cerr);
3972+ else if (test_suite == "sirf")
3973+ return sirf(cout, cerr);
3974 else if (test_suite == "ubx")
3975 return ubx(cout, cerr);
3976 return 0;

Subscribers

People subscribed via source and target branches

to all changes: