Merge lp:~thomas-voss/location-service/enable-ublox-protocol into lp:location-service

Proposed by Thomas Voß
Status: Merged
Approved by: Thomas Voß
Approved revision: 295
Merged at revision: 296
Proposed branch: lp:~thomas-voss/location-service/enable-ublox-protocol
Merge into: lp:location-service
Diff against target: 2663 lines (+2126/-176)
34 files modified
src/location/providers/ubx/CMakeLists.txt (+27/-0)
src/location/providers/ubx/_8/ack/ack.cpp (+35/-0)
src/location/providers/ubx/_8/ack/ack.h (+55/-0)
src/location/providers/ubx/_8/ack/nak.cpp (+35/-0)
src/location/providers/ubx/_8/ack/nak.h (+55/-0)
src/location/providers/ubx/_8/cfg/gnss.cpp (+253/-0)
src/location/providers/ubx/_8/cfg/gnss.h (+114/-0)
src/location/providers/ubx/_8/cfg/msg.cpp (+49/-0)
src/location/providers/ubx/_8/cfg/msg.h (+65/-0)
src/location/providers/ubx/_8/checksum.cpp (+34/-0)
src/location/providers/ubx/_8/checksum.h (+48/-0)
src/location/providers/ubx/_8/codec.h (+62/-19)
src/location/providers/ubx/_8/gnss_id.cpp (+36/-0)
src/location/providers/ubx/_8/gnss_id.h (+51/-0)
src/location/providers/ubx/_8/magic.h (+36/-0)
src/location/providers/ubx/_8/message.h (+28/-33)
src/location/providers/ubx/_8/nav/pvt.cpp (+132/-0)
src/location/providers/ubx/_8/nav/pvt.h (+114/-0)
src/location/providers/ubx/_8/nav/sat.cpp (+62/-0)
src/location/providers/ubx/_8/nav/sat.h (+71/-0)
src/location/providers/ubx/_8/nmea/scanner.cpp (+1/-0)
src/location/providers/ubx/_8/reader.cpp (+110/-0)
src/location/providers/ubx/_8/reader.h (+58/-0)
src/location/providers/ubx/_8/receiver.cpp (+36/-4)
src/location/providers/ubx/_8/receiver.h (+22/-8)
src/location/providers/ubx/_8/scanner.cpp (+166/-0)
src/location/providers/ubx/_8/scanner.h (+30/-96)
src/location/providers/ubx/_8/serial_port_receiver.cpp (+10/-3)
src/location/providers/ubx/_8/serial_port_receiver.h (+3/-0)
src/location/providers/ubx/_8/writer.cpp (+119/-0)
src/location/providers/ubx/_8/writer.h (+60/-0)
src/location/providers/ubx/bits.h (+41/-0)
src/location/providers/ubx/provider.cpp (+94/-11)
src/location/providers/ubx/provider.h (+14/-2)
To merge this branch: bzr merge lp:~thomas-voss/location-service/enable-ublox-protocol
Reviewer Review Type Date Requested Status
Simon Fels (community) Approve
Thomas Voß Pending
Review via email: mp+320395@code.launchpad.net

Commit message

Enable parsing and handling of ublox protocol messages.

By default, we are now using the ublox binary protocol for handling
input originating from a ublox receiver/chipset. More to this, we configure
the chipset to consider GPS, Galileo, GLONASS and SBAS by default.

Description of the change

Enable parsing and handling of ublox protocol messages.

By default, we are now using the ublox binary protocol for handling
input originating from a ublox receiver/chipset. More to this, we configure
the chipset to consider GPS, Galileo, GLONASS and SBAS by default.

To post a comment you must log in.
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/providers/ubx/CMakeLists.txt'
2--- src/location/providers/ubx/CMakeLists.txt 2016-10-10 09:15:40 +0000
3+++ src/location/providers/ubx/CMakeLists.txt 2017-03-20 16:54:12 +0000
4@@ -5,8 +5,35 @@
5
6 ${UBX_HEADERS}
7
8+ bits.h
9+
10+ _8/checksum.h
11+ _8/checksum.cpp
12+ _8/gnss_id.h
13+ _8/gnss_id.cpp
14+ _8/reader.h
15+ _8/reader.cpp
16+ _8/receiver.h
17 _8/receiver.cpp
18+ _8/scanner.h
19+ _8/scanner.cpp
20+ _8/serial_port_receiver.h
21 _8/serial_port_receiver.cpp
22+ _8/writer.h
23+ _8/writer.cpp
24+ _8/ack/ack.h
25+ _8/ack/ack.cpp
26+ _8/ack/nak.h
27+ _8/ack/nak.cpp
28+ _8/cfg/cfg.h
29+ _8/cfg/gnss.h
30+ _8/cfg/gnss.cpp
31+ _8/cfg/msg.h
32+ _8/cfg/msg.cpp
33+ _8/nav/pvt.h
34+ _8/nav/pvt.cpp
35+ _8/nav/sat.h
36+ _8/nav/sat.cpp
37 _8/nmea/scanner.cpp
38 _8/nmea/sentence.cpp
39
40
41=== added directory 'src/location/providers/ubx/_8/ack'
42=== added file 'src/location/providers/ubx/_8/ack/ack.cpp'
43--- src/location/providers/ubx/_8/ack/ack.cpp 1970-01-01 00:00:00 +0000
44+++ src/location/providers/ubx/_8/ack/ack.cpp 2017-03-20 16:54:12 +0000
45@@ -0,0 +1,35 @@
46+// Copyright (C) 2017 Thomas Voss <thomas.voss.bochum@gmail.com>
47+//
48+// This library is free software: you can redistribute it and/or modify
49+// it under the terms of the GNU Lesser General Public License as published
50+// by the Free Software Foundation, either version 3 of the License, or
51+// (at your option) any later version.
52+//
53+// This program is distributed in the hope that it will be useful,
54+// but WITHOUT ANY WARRANTY; without even the implied warranty of
55+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
56+// GNU General Public License for more details.
57+//
58+// You should have received a copy of the GNU Lesser General Public License
59+// along with this program. If not, see <http://www.gnu.org/licenses/>.
60+
61+#include <location/providers/ubx/_8/ack/ack.h>
62+
63+#include <location/providers/ubx/_8/reader.h>
64+
65+#include <iostream>
66+
67+namespace ack = location::providers::ubx::_8::ack;
68+
69+void ack::Ack::read(Reader& reader)
70+{
71+ ackd_class_id = reader.read_unsigned_char();
72+ ackd_message_id = reader.read_unsigned_char();
73+}
74+
75+std::ostream& ack::operator<<(std::ostream& out, const ack::Ack& a)
76+{
77+ return out << "ack-ack:" << std::endl
78+ << " class_id: " << a.ackd_class_id << std::endl
79+ << " message_id: " << a.ackd_message_id << std::endl;
80+}
81
82=== added file 'src/location/providers/ubx/_8/ack/ack.h'
83--- src/location/providers/ubx/_8/ack/ack.h 1970-01-01 00:00:00 +0000
84+++ src/location/providers/ubx/_8/ack/ack.h 2017-03-20 16:54:12 +0000
85@@ -0,0 +1,55 @@
86+// Copyright (C) 2017 Thomas Voss <thomas.voss.bochum@gmail.com>
87+//
88+// This library is free software: you can redistribute it and/or modify
89+// it under the terms of the GNU Lesser General Public License as published
90+// by the Free Software Foundation, either version 3 of the License, or
91+// (at your option) any later version.
92+//
93+// This program is distributed in the hope that it will be useful,
94+// but WITHOUT ANY WARRANTY; without even the implied warranty of
95+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
96+// GNU General Public License for more details.
97+//
98+// You should have received a copy of the GNU Lesser General Public License
99+// along with this program. If not, see <http://www.gnu.org/licenses/>.
100+
101+#ifndef UBX_8_ACK_ACK_H_
102+#define UBX_8_ACK_ACK_H_
103+
104+#include <cstdint>
105+#include <iosfwd>
106+
107+namespace location
108+{
109+namespace providers
110+{
111+namespace ubx
112+{
113+namespace _8
114+{
115+
116+class Reader;
117+
118+namespace ack
119+{
120+
121+struct Ack
122+{
123+ static constexpr std::uint8_t class_id{0x05};
124+ static constexpr std::uint8_t message_id{0x01};
125+
126+ void read(Reader& reader);
127+
128+ std::uint8_t ackd_class_id;
129+ std::uint8_t ackd_message_id;
130+};
131+
132+std::ostream& operator<<(std::ostream& out, const Ack& ack);
133+
134+} // namespace ack
135+} // namespace _8
136+} // namespace ubx
137+} // namespace providers
138+} // namespace location
139+
140+#endif // UBX_8_ACK_ACK_H_
141
142=== added file 'src/location/providers/ubx/_8/ack/nak.cpp'
143--- src/location/providers/ubx/_8/ack/nak.cpp 1970-01-01 00:00:00 +0000
144+++ src/location/providers/ubx/_8/ack/nak.cpp 2017-03-20 16:54:12 +0000
145@@ -0,0 +1,35 @@
146+// Copyright (C) 2017 Thomas Voss <thomas.voss.bochum@gmail.com>
147+//
148+// This library is free software: you can redistribute it and/or modify
149+// it under the terms of the GNU Lesser General Public License as published
150+// by the Free Software Foundation, either version 3 of the License, or
151+// (at your option) any later version.
152+//
153+// This program is distributed in the hope that it will be useful,
154+// but WITHOUT ANY WARRANTY; without even the implied warranty of
155+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
156+// GNU General Public License for more details.
157+//
158+// You should have received a copy of the GNU Lesser General Public License
159+// along with this program. If not, see <http://www.gnu.org/licenses/>.
160+
161+#include <location/providers/ubx/_8/ack/nak.h>
162+
163+#include <location/providers/ubx/_8/reader.h>
164+
165+#include <iostream>
166+
167+namespace ack = location::providers::ubx::_8::ack;
168+
169+void ack::Nak::read(Reader& reader)
170+{
171+ nakd_class_id = reader.read_unsigned_char();
172+ nakd_message_id = reader.read_unsigned_char();
173+}
174+
175+std::ostream& ack::operator<<(std::ostream& out, const ack::Nak& a)
176+{
177+ return out << "ack-ack:" << std::endl
178+ << " class_id: " << a.nakd_class_id << std::endl
179+ << " message_id: " << a.nakd_message_id << std::endl;
180+}
181
182=== added file 'src/location/providers/ubx/_8/ack/nak.h'
183--- src/location/providers/ubx/_8/ack/nak.h 1970-01-01 00:00:00 +0000
184+++ src/location/providers/ubx/_8/ack/nak.h 2017-03-20 16:54:12 +0000
185@@ -0,0 +1,55 @@
186+// Copyright (C) 2017 Thomas Voss <thomas.voss.bochum@gmail.com>
187+//
188+// This library is free software: you can redistribute it and/or modify
189+// it under the terms of the GNU Lesser General Public License as published
190+// by the Free Software Foundation, either version 3 of the License, or
191+// (at your option) any later version.
192+//
193+// This program is distributed in the hope that it will be useful,
194+// but WITHOUT ANY WARRANTY; without even the implied warranty of
195+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
196+// GNU General Public License for more details.
197+//
198+// You should have received a copy of the GNU Lesser General Public License
199+// along with this program. If not, see <http://www.gnu.org/licenses/>.
200+
201+#ifndef UBX_8_ACK_NAK_H_
202+#define UBX_8_ACK_NAK_H_
203+
204+#include <cstdint>
205+#include <iosfwd>
206+
207+namespace location
208+{
209+namespace providers
210+{
211+namespace ubx
212+{
213+namespace _8
214+{
215+
216+class Reader;
217+
218+namespace ack
219+{
220+
221+struct Nak
222+{
223+ static constexpr std::uint8_t class_id{0x05};
224+ static constexpr std::uint8_t message_id{0x00};
225+
226+ void read(Reader& reader);
227+
228+ std::uint8_t nakd_class_id;
229+ std::uint8_t nakd_message_id;
230+};
231+
232+std::ostream& operator<<(std::ostream& out, const Nak& nak);
233+
234+} // namespace ack
235+} // namespace _8
236+} // namespace ubx
237+} // namespace providers
238+} // namespace location
239+
240+#endif // UBX_8_ACK_NAK_H_
241
242=== added directory 'src/location/providers/ubx/_8/cfg'
243=== added file 'src/location/providers/ubx/_8/cfg/gnss.cpp'
244--- src/location/providers/ubx/_8/cfg/gnss.cpp 1970-01-01 00:00:00 +0000
245+++ src/location/providers/ubx/_8/cfg/gnss.cpp 2017-03-20 16:54:12 +0000
246@@ -0,0 +1,253 @@
247+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
248+//
249+// This library is free software: you can redistribute it and/or modify
250+// it under the terms of the GNU Lesser General Public License as published
251+// by the Free Software Foundation, either version 3 of the License, or
252+// (at your option) any later version.
253+//
254+// This program is distributed in the hope that it will be useful,
255+// but WITHOUT ANY WARRANTY; without even the implied warranty of
256+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
257+// GNU General Public License for more details.
258+//
259+// You should have received a copy of the GNU Lesser General Public License
260+// along with this program. If not, see <http://www.gnu.org/licenses/>.
261+
262+#include <location/providers/ubx/_8/cfg/gnss.h>
263+
264+#include <location/providers/ubx/bits.h>
265+#include <location/providers/ubx/_8/writer.h>
266+
267+#include <cstdint>
268+#include <iostream>
269+
270+namespace cfg = location::providers::ubx::_8::cfg;
271+
272+std::size_t cfg::Gnss::size() const
273+{
274+ std::size_t result = 4;
275+
276+ if (beidou)
277+ result += 8;
278+ if (glonass)
279+ result += 8;
280+ if (gps)
281+ result += 8;
282+ if (galileo)
283+ result += 8;
284+ if (imes)
285+ result += 8;
286+ if (qzss)
287+ result += 8;
288+ if (sbas)
289+ result += 8;
290+
291+ return result;
292+}
293+
294+bool cfg::Gnss::write(Writer& writer) const
295+{
296+ writer.write_unsigned_char(version);
297+ writer.write_unsigned_char(tracking_channels_hw);
298+ writer.write_unsigned_char(tracking_channels_used);
299+
300+ std::uint8_t num_configs = 0;
301+ if (beidou) num_configs++;
302+ if (glonass) num_configs++;
303+ if (gps) num_configs++;
304+ if (galileo) num_configs++;
305+ if (imes) num_configs++;
306+ if (qzss) num_configs++;
307+ if (sbas) num_configs++;
308+
309+ writer.write_unsigned_char(num_configs);
310+
311+ if (beidou)
312+ {
313+ writer.write_unsigned_char(BeiDou::id);
314+ writer.write_unsigned_char(beidou.get().min_tracking_channels);
315+ writer.write_unsigned_char(beidou.get().max_tracking_channels);
316+ writer.write_unsigned_char(0);
317+
318+ std::uint32_t flags{0};
319+ bits::set<0, 1>(flags, beidou.get().enable ? 1 : 0);
320+ bits::set<16, 23>(flags, beidou.get().b1l ? 0x01: 0x0);
321+
322+ writer.write_unsigned_long(flags);
323+ }
324+
325+ if (glonass)
326+ {
327+ writer.write_unsigned_char(Glonass::id);
328+ writer.write_unsigned_char(glonass.get().min_tracking_channels);
329+ writer.write_unsigned_char(glonass.get().max_tracking_channels);
330+ writer.write_unsigned_char(0);
331+
332+ std::uint32_t flags{0};
333+ bits::set<0, 1>(flags, glonass.get().enable ? 1 : 0);
334+ bits::set<16, 23>(flags, glonass.get().l1of ? 0x01: 0x0);
335+
336+ writer.write_unsigned_long(flags);
337+ }
338+
339+ if (gps)
340+ {
341+ writer.write_unsigned_char(Gps::id);
342+ writer.write_unsigned_char(gps.get().min_tracking_channels);
343+ writer.write_unsigned_char(gps.get().max_tracking_channels);
344+ writer.write_unsigned_char(0);
345+
346+ std::uint32_t flags{0};
347+ bits::set<0, 1>(flags, gps.get().enable ? 1 : 0);
348+ bits::set<16, 23>(flags, gps.get().l1ca ? 0x01: 0x0);
349+
350+ writer.write_unsigned_long(flags);
351+ }
352+
353+ if (galileo)
354+ {
355+ writer.write_unsigned_char(Galileo::id);
356+ writer.write_unsigned_char(galileo.get().min_tracking_channels);
357+ writer.write_unsigned_char(galileo.get().max_tracking_channels);
358+ writer.write_unsigned_char(0);
359+
360+ std::uint32_t flags{0};
361+ bits::set<0, 1>(flags, galileo.get().enable ? 1 : 0);
362+ bits::set<16, 23>(flags, galileo.get().e1os ? 0x01: 0x0);
363+
364+ writer.write_unsigned_long(flags);
365+ }
366+
367+ if (imes)
368+ {
369+ writer.write_unsigned_char(Imes::id);
370+ writer.write_unsigned_char(imes.get().min_tracking_channels);
371+ writer.write_unsigned_char(imes.get().max_tracking_channels);
372+ writer.write_unsigned_char(0);
373+
374+ std::uint32_t flags{0};
375+ bits::set<0, 1>(flags, imes.get().enable ? 1 : 0);
376+ bits::set<16, 23>(flags, imes.get().l1 ? 0x01: 0x0);
377+
378+ writer.write_unsigned_long(flags);
379+ }
380+
381+ if (imes)
382+ {
383+ writer.write_unsigned_char(Imes::id);
384+ writer.write_unsigned_char(imes.get().min_tracking_channels);
385+ writer.write_unsigned_char(imes.get().max_tracking_channels);
386+ writer.write_unsigned_char(0);
387+
388+ std::uint32_t flags{0};
389+ bits::set<0, 1>(flags, imes.get().enable ? 1 : 0);
390+ bits::set<16, 23>(flags, imes.get().l1 ? 0x01: 0x0);
391+
392+ writer.write_unsigned_long(flags);
393+ }
394+
395+ if (qzss)
396+ {
397+ writer.write_unsigned_char(Qzss::id);
398+ writer.write_unsigned_char(qzss.get().min_tracking_channels);
399+ writer.write_unsigned_char(qzss.get().max_tracking_channels);
400+ writer.write_unsigned_char(0);
401+
402+ std::uint32_t flags{0};
403+ bits::set<0, 1>(flags, qzss.get().enable ? 1 : 0);
404+ // TODO(tvoss): Consider l1saif here, too.
405+ bits::set<16, 23>(flags, qzss.get().l1ca ? 0x01: 0x0);
406+
407+ writer.write_unsigned_long(flags);
408+ }
409+
410+ if (sbas)
411+ {
412+ writer.write_unsigned_char(Sbas::id);
413+ writer.write_unsigned_char(sbas.get().min_tracking_channels);
414+ writer.write_unsigned_char(sbas.get().max_tracking_channels);
415+ writer.write_unsigned_char(0);
416+
417+ std::uint32_t flags{0};
418+ bits::set<0, 1>(flags, sbas.get().enable ? 1 : 0);
419+ bits::set<16, 23>(flags, sbas.get().l1ca ? 0x01: 0x0);
420+
421+ writer.write_unsigned_long(flags);
422+ }
423+
424+ return true;
425+}
426+
427+std::ostream& cfg::operator<<(std::ostream& out, const cfg::Gnss& gnss)
428+{
429+ out << "cfg-gnss:" << std::endl
430+ << " version: " << std::uint32_t(gnss.version) << std::endl
431+ << " tracking_channels_hw: " << std::uint32_t(gnss.tracking_channels_hw) << std::endl
432+ << " tracking_channels_used: " << std::uint32_t(gnss.tracking_channels_used);
433+
434+ if (gnss.beidou)
435+ {
436+ out << " beidou:" << std::endl
437+ << " enable: " << std::boolalpha << gnss.beidou.get().enable << std::endl
438+ << " min_tracking_channels: " << gnss.beidou.get().min_tracking_channels << std::endl
439+ << " max_tracking_channels: " << gnss.beidou.get().max_tracking_channels << std::endl
440+ << " b1l: " << gnss.beidou.get().b1l;
441+ }
442+
443+ if (gnss.glonass)
444+ {
445+ out << " glonass:" << std::endl
446+ << " enable: " << std::boolalpha << gnss.glonass.get().enable << std::endl
447+ << " min_tracking_channels: " << gnss.glonass.get().min_tracking_channels << std::endl
448+ << " max_tracking_channels: " << gnss.glonass.get().max_tracking_channels << std::endl
449+ << " l1of: " << gnss.glonass.get().l1of;
450+ }
451+
452+ if (gnss.gps)
453+ {
454+ out << " gps:" << std::endl
455+ << " enable: " << std::boolalpha << gnss.gps.get().enable << std::endl
456+ << " min_tracking_channels: " << gnss.gps.get().min_tracking_channels << std::endl
457+ << " max_tracking_channels: " << gnss.gps.get().max_tracking_channels << std::endl
458+ << " l1ca: " << gnss.gps.get().l1ca;
459+ }
460+
461+ if (gnss.galileo)
462+ {
463+ out << " galileo:" << std::endl
464+ << " enable: " << std::boolalpha << gnss.galileo.get().enable << std::endl
465+ << " min_tracking_channels: " << gnss.galileo.get().min_tracking_channels << std::endl
466+ << " max_tracking_channels: " << gnss.galileo.get().max_tracking_channels << std::endl
467+ << " e1os: " << gnss.galileo.get().e1os;
468+ }
469+
470+ if (gnss.imes)
471+ {
472+ out << " imes:" << std::endl
473+ << " enable: " << std::boolalpha << gnss.imes.get().enable << std::endl
474+ << " min_tracking_channels: " << gnss.imes.get().min_tracking_channels << std::endl
475+ << " max_tracking_channels: " << gnss.imes.get().max_tracking_channels << std::endl
476+ << " l1: " << gnss.imes.get().l1;
477+ }
478+
479+ if (gnss.qzss)
480+ {
481+ out << " qzss:" << std::endl
482+ << " enable: " << std::boolalpha << gnss.qzss.get().enable << std::endl
483+ << " min_tracking_channels: " << gnss.qzss.get().min_tracking_channels << std::endl
484+ << " max_tracking_channels: " << gnss.qzss.get().max_tracking_channels << std::endl
485+ << " l1ca: " << gnss.qzss.get().l1ca << std::endl
486+ << " l1saif: " << gnss.qzss.get().l1saif;
487+ }
488+
489+ if (gnss.sbas)
490+ {
491+ out << " sbas:" << std::endl
492+ << " enable: " << std::boolalpha << gnss.sbas.get().enable << std::endl
493+ << " min_tracking_channels: " << gnss.sbas.get().min_tracking_channels << std::endl
494+ << " max_tracking_channels: " << gnss.sbas.get().max_tracking_channels << std::endl
495+ << " l1ca: " << gnss.sbas.get().l1ca;
496+ }
497+
498+ return out;
499+}
500
501=== added file 'src/location/providers/ubx/_8/cfg/gnss.h'
502--- src/location/providers/ubx/_8/cfg/gnss.h 1970-01-01 00:00:00 +0000
503+++ src/location/providers/ubx/_8/cfg/gnss.h 2017-03-20 16:54:12 +0000
504@@ -0,0 +1,114 @@
505+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
506+//
507+// This library is free software: you can redistribute it and/or modify
508+// it under the terms of the GNU Lesser General Public License as published
509+// by the Free Software Foundation, either version 3 of the License, or
510+// (at your option) any later version.
511+//
512+// This program is distributed in the hope that it will be useful,
513+// but WITHOUT ANY WARRANTY; without even the implied warranty of
514+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
515+// GNU General Public License for more details.
516+//
517+// You should have received a copy of the GNU Lesser General Public License
518+// along with this program. If not, see <http://www.gnu.org/licenses/>.
519+
520+#ifndef UBX_8_CFG_GNSS_H_
521+#define UBX_8_CFG_GNSS_H_
522+
523+#include <location/optional.h>
524+
525+#include <cstdint>
526+
527+#include <iosfwd>
528+
529+namespace location
530+{
531+namespace providers
532+{
533+namespace ubx
534+{
535+namespace _8
536+{
537+
538+class Writer;
539+
540+namespace cfg
541+{
542+
543+struct Gnss
544+{
545+ template<std::uint8_t ID>
546+ struct Constellation
547+ {
548+ static constexpr const std::uint8_t id{ID};
549+
550+ bool enable;
551+ std::uint8_t min_tracking_channels = 0;
552+ std::uint8_t max_tracking_channels = 0;
553+ };
554+
555+ struct BeiDou : public Constellation<3>
556+ {
557+ bool b1l = false;
558+ };
559+
560+ struct Glonass : public Constellation<6>
561+ {
562+ bool l1of = false;
563+ };
564+
565+ struct Gps : public Constellation<0>
566+ {
567+ bool l1ca = false;
568+ };
569+
570+ struct Galileo : public Constellation<2>
571+ {
572+ bool e1os = false;
573+ };
574+
575+ struct Imes : public Constellation<4>
576+ {
577+ bool l1 = false;
578+ };
579+
580+ struct Qzss : public Constellation<5>
581+ {
582+ bool l1ca = false;
583+ bool l1saif = false;
584+ };
585+
586+ struct Sbas : public Constellation<1>
587+ {
588+ bool l1ca = false;
589+ };
590+
591+ static constexpr std::uint8_t class_id{0x06};
592+ static constexpr std::uint8_t message_id{0x3e};
593+
594+ std::size_t size() const;
595+ bool write(Writer& writer) const;
596+
597+ std::uint8_t version = 0;
598+ std::uint8_t tracking_channels_hw = 0;
599+ std::uint8_t tracking_channels_used = 0xff;
600+
601+ Optional<BeiDou> beidou;
602+ Optional<Glonass> glonass;
603+ Optional<Gps> gps;
604+ Optional<Galileo> galileo;
605+ Optional<Imes> imes;
606+ Optional<Qzss> qzss;
607+ Optional<Sbas> sbas;
608+};
609+
610+std::ostream& operator<<(std::ostream& out, const Gnss& gnss);
611+
612+} // namespace cfg
613+} // namespace _8
614+} // namespace ubx
615+} // namespace providers
616+} // namespace location
617+
618+#endif // UBX_8_CFG_GNSS_H_
619
620=== added file 'src/location/providers/ubx/_8/cfg/msg.cpp'
621--- src/location/providers/ubx/_8/cfg/msg.cpp 1970-01-01 00:00:00 +0000
622+++ src/location/providers/ubx/_8/cfg/msg.cpp 2017-03-20 16:54:12 +0000
623@@ -0,0 +1,49 @@
624+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
625+//
626+// This library is free software: you can redistribute it and/or modify
627+// it under the terms of the GNU Lesser General Public License as published
628+// by the Free Software Foundation, either version 3 of the License, or
629+// (at your option) any later version.
630+//
631+// This program is distributed in the hope that it will be useful,
632+// but WITHOUT ANY WARRANTY; without even the implied warranty of
633+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
634+// GNU General Public License for more details.
635+//
636+// You should have received a copy of the GNU Lesser General Public License
637+// along with this program. If not, see <http://www.gnu.org/licenses/>.
638+
639+#include <location/providers/ubx/_8/cfg/msg.h>
640+
641+#include <location/providers/ubx/bits.h>
642+#include <location/providers/ubx/_8/writer.h>
643+
644+#include <cstdint>
645+#include <iostream>
646+
647+namespace cfg = location::providers::ubx::_8::cfg;
648+
649+std::size_t cfg::Msg::size() const
650+{
651+ return 8;
652+}
653+
654+void cfg::Msg::write(Writer& writer) const
655+{
656+ writer.write_unsigned_char(configured_class_id);
657+ writer.write_unsigned_char(configured_message_id);
658+ writer.write_unsigned_char(rate[0]);
659+ writer.write_unsigned_char(rate[1]);
660+ writer.write_unsigned_char(rate[2]);
661+ writer.write_unsigned_char(rate[3]);
662+ writer.write_unsigned_char(rate[4]);
663+ writer.write_unsigned_char(rate[5]);
664+}
665+
666+std::ostream& cfg::operator<<(std::ostream& out, const cfg::Msg& msg)
667+{
668+ return out << "cfg-msg:" << std::endl
669+ << " configured class id: " << msg.configured_class_id << std::endl
670+ << " configured msg id: " << msg.configured_message_id << std::endl
671+ << " rates: " << "[" << msg.rate[0] << "," << msg.rate[1] << "," << msg.rate[2] << "," << msg.rate[3] << "," << msg.rate[4] << "," << msg.rate[5] << "]";
672+}
673
674=== added file 'src/location/providers/ubx/_8/cfg/msg.h'
675--- src/location/providers/ubx/_8/cfg/msg.h 1970-01-01 00:00:00 +0000
676+++ src/location/providers/ubx/_8/cfg/msg.h 2017-03-20 16:54:12 +0000
677@@ -0,0 +1,65 @@
678+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
679+//
680+// This library is free software: you can redistribute it and/or modify
681+// it under the terms of the GNU Lesser General Public License as published
682+// by the Free Software Foundation, either version 3 of the License, or
683+// (at your option) any later version.
684+//
685+// This program is distributed in the hope that it will be useful,
686+// but WITHOUT ANY WARRANTY; without even the implied warranty of
687+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
688+// GNU General Public License for more details.
689+//
690+// You should have received a copy of the GNU Lesser General Public License
691+// along with this program. If not, see <http://www.gnu.org/licenses/>.
692+
693+#ifndef UBX_8_CFG_MSG_H_
694+#define UBX_8_CFG_MSG_H_
695+
696+#include <cstdint>
697+#include <iosfwd>
698+
699+namespace location
700+{
701+namespace providers
702+{
703+namespace ubx
704+{
705+namespace _8
706+{
707+
708+class Writer;
709+
710+namespace cfg
711+{
712+
713+struct Msg
714+{
715+ static constexpr std::uint8_t class_id{0x06};
716+ static constexpr std::uint8_t message_id{0x01};
717+
718+ enum Port
719+ {
720+ ddc = 0,
721+ uart1 = 1,
722+ usb = 3,
723+ spi = 4
724+ };
725+
726+ std::size_t size() const;
727+ void write(Writer& writer) const;
728+
729+ std::uint8_t configured_class_id;
730+ std::uint8_t configured_message_id;
731+ std::uint8_t rate[6];
732+};
733+
734+std::ostream& operator<<(std::ostream& out, const Msg& msg);
735+
736+} // namespace cfg
737+} // namespace _8
738+} // namespace ubx
739+} // namespace providers
740+} // namespace location
741+
742+#endif // UBX_8_CFG_MSG_H_
743
744=== added file 'src/location/providers/ubx/_8/checksum.cpp'
745--- src/location/providers/ubx/_8/checksum.cpp 1970-01-01 00:00:00 +0000
746+++ src/location/providers/ubx/_8/checksum.cpp 2017-03-20 16:54:12 +0000
747@@ -0,0 +1,34 @@
748+// Copyright (C) 2017 Thomas Voss <thomas.voss.bochum@gmail.com>
749+//
750+// This library is free software: you can redistribute it and/or modify
751+// it under the terms of the GNU Lesser General Public License as published
752+// by the Free Software Foundation, either version 3 of the License, or
753+// (at your option) any later version.
754+//
755+// This program is distributed in the hope that it will be useful,
756+// but WITHOUT ANY WARRANTY; without even the implied warranty of
757+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
758+// GNU General Public License for more details.
759+//
760+// You should have received a copy of the GNU Lesser General Public License
761+// along with this program. If not, see <http://www.gnu.org/licenses/>.
762+
763+#include <location/providers/ubx/_8/checksum.h>
764+
765+namespace _8 = location::providers::ubx::_8;
766+
767+void _8::Checksum::operator()(std::uint8_t byte)
768+{
769+ ck_a_ += byte;
770+ ck_b_ += ck_a_;
771+}
772+
773+std::uint8_t _8::Checksum::ck_a() const
774+{
775+ return ck_a_;
776+}
777+
778+std::uint8_t _8::Checksum::ck_b() const
779+{
780+ return ck_b_;
781+}
782
783=== added file 'src/location/providers/ubx/_8/checksum.h'
784--- src/location/providers/ubx/_8/checksum.h 1970-01-01 00:00:00 +0000
785+++ src/location/providers/ubx/_8/checksum.h 2017-03-20 16:54:12 +0000
786@@ -0,0 +1,48 @@
787+// Copyright (C) 2017 Thomas Voss <thomas.voss.bochum@gmail.com>
788+//
789+// This library is free software: you can redistribute it and/or modify
790+// it under the terms of the GNU Lesser General Public License as published
791+// by the Free Software Foundation, either version 3 of the License, or
792+// (at your option) any later version.
793+//
794+// This program is distributed in the hope that it will be useful,
795+// but WITHOUT ANY WARRANTY; without even the implied warranty of
796+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
797+// GNU General Public License for more details.
798+//
799+// You should have received a copy of the GNU Lesser General Public License
800+// along with this program. If not, see <http://www.gnu.org/licenses/>.
801+
802+#ifndef UBX_8_CHECKSUM_H_
803+#define UBX_8_CHECKSUM_H_
804+
805+#include <cstdint>
806+
807+namespace location
808+{
809+namespace providers
810+{
811+namespace ubx
812+{
813+namespace _8
814+{
815+
816+class Checksum
817+{
818+public:
819+ void operator()(std::uint8_t byte);
820+
821+ std::uint8_t ck_a() const;
822+ std::uint8_t ck_b() const;
823+
824+private:
825+ std::uint8_t ck_a_{0};
826+ std::uint8_t ck_b_{0};
827+};
828+
829+} // namespace _8
830+} // namespace ubx
831+} // namespace providers
832+} // namepsace location
833+
834+#endif // UBX_8_CHECKSUM_H_
835
836=== renamed file 'src/location/providers/ubx/_8/marshaller.h' => 'src/location/providers/ubx/_8/codec.h'
837--- src/location/providers/ubx/_8/marshaller.h 2016-10-10 09:15:40 +0000
838+++ src/location/providers/ubx/_8/codec.h 2017-03-20 16:54:12 +0000
839@@ -12,8 +12,19 @@
840 //
841 // You should have received a copy of the GNU Lesser General Public License
842 // along with this program. If not, see <http://www.gnu.org/licenses/>.
843-#ifndef UBX_8_MARSHALLER_H_
844-#define UBX_8_MARSHALLER_H_
845+
846+#ifndef UBX_8_CODEC_H_
847+#define UBX_8_CODEC_H_
848+
849+#include <location/providers/ubx/_8/checksum.h>
850+#include <location/providers/ubx/_8/magic.h>
851+#include <location/providers/ubx/_8/reader.h>
852+#include <location/providers/ubx/_8/writer.h>
853+
854+#include <algorithm>
855+#include <cstdint>
856+#include <iostream>
857+#include <vector>
858
859 namespace location
860 {
861@@ -23,20 +34,52 @@
862 {
863 namespace _8
864 {
865-/// @brief Marshaller abstracts marshaling of arbitrary messages.
866-class Marshaller
867-{
868-public:
869- virtual ~Marshaller() = default;
870-
871- /// @brief marshal returns a message
872- /// ready to be sent over the wire to a ublox
873- /// receiver.
874- virtual Message marshal() const = 0;
875-};
876-}
877-}
878-}
879-}
880-
881-#endif // UBX_8_MARSHALLER_H_
882+
883+template<typename T>
884+inline T decode_message(const std::vector<std::uint8_t>& payload)
885+{
886+ T result;
887+ Reader reader{payload.begin(), payload.end()};
888+ result.read(reader);
889+
890+ return result;
891+}
892+
893+template<typename T>
894+inline std::vector<std::uint8_t> encode_message(const T& message)
895+{
896+ auto msg_size = message.size();
897+
898+ std::uint16_t size =
899+ sizeof(std::uint8_t) + sizeof(std::uint8_t) +
900+ sizeof(std::uint8_t) + sizeof(std::uint8_t) +
901+ sizeof(std::uint16_t) +
902+ msg_size +
903+ sizeof(std::uint8_t) + sizeof(std::uint8_t);
904+
905+ std::vector<std::uint8_t> result(size, 0);
906+
907+ Writer writer{result.begin(), result.end()};
908+ writer.write_unsigned_char(sync_char_1);
909+ writer.write_unsigned_char(sync_char_2);
910+ writer.write_unsigned_char(T::class_id);
911+ writer.write_unsigned_char(T::message_id);
912+ writer.write_unsigned_short(msg_size);
913+
914+ Writer payload = writer.slice(msg_size);
915+ message.write(payload);
916+
917+ auto checksum = std::for_each(result.begin() + 2, result.end() - 2, Checksum{});
918+
919+ writer.write_unsigned_char(checksum.ck_a());
920+ writer.write_unsigned_char(checksum.ck_b());
921+
922+ return result;
923+}
924+
925+} // namespace _8
926+} // namespace ubx
927+} // namespace providers
928+} // namespace location
929+
930+#endif // UBX_8_CODEC_H_
931
932=== added file 'src/location/providers/ubx/_8/gnss_id.cpp'
933--- src/location/providers/ubx/_8/gnss_id.cpp 1970-01-01 00:00:00 +0000
934+++ src/location/providers/ubx/_8/gnss_id.cpp 2017-03-20 16:54:12 +0000
935@@ -0,0 +1,36 @@
936+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
937+//
938+// This library is free software: you can redistribute it and/or modify
939+// it under the terms of the GNU Lesser General Public License as published
940+// by the Free Software Foundation, either version 3 of the License, or
941+// (at your option) any later version.
942+//
943+// This program is distributed in the hope that it will be useful,
944+// but WITHOUT ANY WARRANTY; without even the implied warranty of
945+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
946+// GNU General Public License for more details.
947+//
948+// You should have received a copy of the GNU Lesser General Public License
949+// along with this program. If not, see <http://www.gnu.org/licenses/>.
950+
951+#include <location/providers/ubx/_8/gnss_id.h>
952+
953+#include <iostream>
954+
955+namespace _8 = location::providers::ubx::_8;
956+
957+std::ostream& _8::operator<<(std::ostream& out, GnssId gnss_id)
958+{
959+ switch (gnss_id)
960+ {
961+ case GnssId::gps: out << "gps"; break;
962+ case GnssId::sbas: out << "sbas"; break;
963+ case GnssId::galileo: out << "galileo"; break;
964+ case GnssId::beidou: out << "beidou"; break;
965+ case GnssId::imes: out << "imes"; break;
966+ case GnssId::qzss: out << "qzss"; break;
967+ case GnssId::glonass: out << "glonass"; break;
968+ }
969+
970+ return out;
971+}
972
973=== added file 'src/location/providers/ubx/_8/gnss_id.h'
974--- src/location/providers/ubx/_8/gnss_id.h 1970-01-01 00:00:00 +0000
975+++ src/location/providers/ubx/_8/gnss_id.h 2017-03-20 16:54:12 +0000
976@@ -0,0 +1,51 @@
977+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
978+//
979+// This library is free software: you can redistribute it and/or modify
980+// it under the terms of the GNU Lesser General Public License as published
981+// by the Free Software Foundation, either version 3 of the License, or
982+// (at your option) any later version.
983+//
984+// This program is distributed in the hope that it will be useful,
985+// but WITHOUT ANY WARRANTY; without even the implied warranty of
986+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
987+// GNU General Public License for more details.
988+//
989+// You should have received a copy of the GNU Lesser General Public License
990+// along with this program. If not, see <http://www.gnu.org/licenses/>.
991+
992+#ifndef UBX_8_GNSS_ID_H_
993+#define UBX_8_GNSS_ID_H_
994+
995+#include <cstdint>
996+
997+#include <iosfwd>
998+
999+namespace location
1000+{
1001+namespace providers
1002+{
1003+namespace ubx
1004+{
1005+namespace _8
1006+{
1007+
1008+enum class GnssId : std::uint8_t
1009+{
1010+ gps = 0,
1011+ sbas = 1,
1012+ galileo = 2,
1013+ beidou = 3,
1014+ imes = 4,
1015+ qzss = 5,
1016+ glonass = 6
1017+
1018+};
1019+
1020+std::ostream& operator<<(std::ostream& out, GnssId gnss_id);
1021+
1022+} // namespace _8
1023+} // namespace ubx
1024+} // namespace providers
1025+} // namepsace location
1026+
1027+#endif // UBX_8_GNSS_ID_H_
1028
1029=== added file 'src/location/providers/ubx/_8/magic.h'
1030--- src/location/providers/ubx/_8/magic.h 1970-01-01 00:00:00 +0000
1031+++ src/location/providers/ubx/_8/magic.h 2017-03-20 16:54:12 +0000
1032@@ -0,0 +1,36 @@
1033+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
1034+//
1035+// This library is free software: you can redistribute it and/or modify
1036+// it under the terms of the GNU Lesser General Public License as published
1037+// by the Free Software Foundation, either version 3 of the License, or
1038+// (at your option) any later version.
1039+//
1040+// This program is distributed in the hope that it will be useful,
1041+// but WITHOUT ANY WARRANTY; without even the implied warranty of
1042+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1043+// GNU General Public License for more details.
1044+//
1045+// You should have received a copy of the GNU Lesser General Public License
1046+// along with this program. If not, see <http://www.gnu.org/licenses/>.
1047+
1048+#ifndef UBX_8_MAGIC_H_
1049+#define UBX_8_MAGIC_H_
1050+
1051+namespace location
1052+{
1053+namespace providers
1054+{
1055+namespace ubx
1056+{
1057+namespace _8
1058+{
1059+
1060+constexpr const std::uint8_t sync_char_1{0xb5};
1061+constexpr const std::uint8_t sync_char_2{0x62};
1062+
1063+} // namespace _8
1064+} // namespace ubx
1065+} // namespace providers
1066+} // namespace location
1067+
1068+#endif // UBX_8_MAGIC_H_
1069
1070=== modified file 'src/location/providers/ubx/_8/message.h'
1071--- src/location/providers/ubx/_8/message.h 2016-10-10 09:15:40 +0000
1072+++ src/location/providers/ubx/_8/message.h 2017-03-20 16:54:12 +0000
1073@@ -12,12 +12,18 @@
1074 //
1075 // You should have received a copy of the GNU Lesser General Public License
1076 // along with this program. If not, see <http://www.gnu.org/licenses/>.
1077-#ifndef UBX_8_SCANNER_H_
1078-#define UBX_8_SCANNER_H_
1079-
1080-#include <cstdint>
1081-
1082-#include <vector>
1083+
1084+#ifndef UBX_8_MESSAGE_H_
1085+#define UBX_8_MESSAGE_H_
1086+
1087+#include <location/providers/ubx/_8/ack/ack.h>
1088+#include <location/providers/ubx/_8/ack/nak.h>
1089+#include <location/providers/ubx/_8/cfg/gnss.h>
1090+#include <location/providers/ubx/_8/cfg/msg.h>
1091+#include <location/providers/ubx/_8/nav/pvt.h>
1092+#include <location/providers/ubx/_8/nav/sat.h>
1093+
1094+#include <boost/variant.hpp>
1095
1096 namespace location
1097 {
1098@@ -27,30 +33,19 @@
1099 {
1100 namespace _8
1101 {
1102-static constexpr const std::uint8_t sync_char_1{0xb5};
1103-static constexpr const std::uint8_t sync_char_2{62};
1104-
1105-enum class Class
1106-{
1107- cfg = 0x06
1108-};
1109-
1110-enum class Id
1111-{
1112-};
1113-
1114-struct Message
1115-{
1116- Class cls;
1117- Id id;
1118- std::uint16_t length;
1119- std::vector<std::uint8_t> payload;
1120- std::uint8_t ck_a;
1121- std::uint8_t ck_b;
1122-};
1123-}
1124-}
1125-}
1126-}
1127-
1128-#endif // UBX_8_SCANNER_H_
1129+
1130+using Message = boost::variant<
1131+ ack::Ack,
1132+ ack::Nak,
1133+ cfg::Gnss,
1134+ cfg::Msg,
1135+ nav::Pvt,
1136+ nav::Sat
1137+>;
1138+
1139+} // namespace _8
1140+} // namespace ubx
1141+} // namespace providers
1142+} // namespace location
1143+
1144+#endif // UBX_8_MESSAGE_H_
1145
1146=== added directory 'src/location/providers/ubx/_8/nav'
1147=== added file 'src/location/providers/ubx/_8/nav/pvt.cpp'
1148--- src/location/providers/ubx/_8/nav/pvt.cpp 1970-01-01 00:00:00 +0000
1149+++ src/location/providers/ubx/_8/nav/pvt.cpp 2017-03-20 16:54:12 +0000
1150@@ -0,0 +1,132 @@
1151+// Copyright (C) 2017 Thomas Voss <thomas.voss.bochum@gmail.com>
1152+//
1153+// This library is free software: you can redistribute it and/or modify
1154+// it under the terms of the GNU Lesser General Public License as published
1155+// by the Free Software Foundation, either version 3 of the License, or
1156+// (at your option) any later version.
1157+//
1158+// This program is distributed in the hope that it will be useful,
1159+// but WITHOUT ANY WARRANTY; without even the implied warranty of
1160+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1161+// GNU General Public License for more details.
1162+//
1163+// You should have received a copy of the GNU Lesser General Public License
1164+// along with this program. If not, see <http://www.gnu.org/licenses/>.
1165+
1166+#include <location/providers/ubx/_8/nav/pvt.h>
1167+
1168+#include <location/providers/ubx/_8/reader.h>
1169+
1170+#include <iostream>
1171+
1172+namespace nav = location::providers::ubx::_8::nav;
1173+
1174+void nav::Pvt::read(Reader& reader)
1175+{
1176+ itow = reader.read_unsigned_long();
1177+ year = reader.read_unsigned_short();
1178+ month = reader.read_unsigned_char();
1179+ day = reader.read_unsigned_char();
1180+ hour = reader.read_unsigned_char();
1181+ minute = reader.read_unsigned_char();
1182+ second = reader.read_unsigned_char();
1183+ date_time_validity = static_cast<DateTimeValidity>(reader.read_unsigned_char());
1184+ time_accuracy = reader.read_unsigned_long();
1185+ nanoseconds = reader.read_signed_long();
1186+ fix_type = static_cast<FixType>(reader.read_unsigned_char());
1187+ fix_status_flags = reader.read_unsigned_char();
1188+ additional_flags = reader.read_unsigned_char();
1189+ satellite_count = reader.read_unsigned_char();
1190+ longitude = reader.read_signed_long() * 1e-7;
1191+ latitude = reader.read_signed_long() * 1e-7;
1192+ height.above_ellipsoid = reader.read_signed_long();
1193+ height.above_msl = reader.read_signed_long();
1194+ accuracy.horizontal = reader.read_unsigned_long();
1195+ accuracy.vertical = reader.read_unsigned_long();
1196+ velocity.north = reader.read_signed_long();
1197+ velocity.east = reader.read_signed_long();
1198+ velocity.down = reader.read_signed_long();
1199+ speed_over_ground = reader.read_unsigned_long();
1200+ heading.motion = reader.read_signed_long() * 1e-5;
1201+ accuracy.speed = reader.read_unsigned_long();
1202+ accuracy.heading = reader.read_unsigned_long() * 1e-5;
1203+ pdop = reader.read_unsigned_short() * 0.01;
1204+
1205+ reader.read_unsigned_char();
1206+ reader.read_unsigned_char();
1207+ reader.read_unsigned_char();
1208+ reader.read_unsigned_char();
1209+ reader.read_unsigned_char();
1210+ reader.read_unsigned_char();
1211+
1212+ heading.vehicle = reader.read_signed_long() * 1e-5;
1213+
1214+ reader.read_unsigned_char();
1215+ reader.read_unsigned_char();
1216+ reader.read_unsigned_char();
1217+ reader.read_unsigned_char();
1218+}
1219+
1220+std::ostream& nav::operator<<(std::ostream& out, nav::Pvt::DateTimeValidity validity)
1221+{
1222+ return out
1223+ << "date valid=" << std::boolalpha << (0 != (validity & Pvt::DateTimeValidity::valid_date)) << " "
1224+ << "time valid=" << std::boolalpha << (0 != (validity & Pvt::DateTimeValidity::valid_time)) << " "
1225+ << "fully resolved=" << std::boolalpha << (0 != (validity & Pvt::DateTimeValidity::fully_resolved));
1226+}
1227+
1228+std::ostream& nav::operator<<(std::ostream& out, nav::Pvt::FixType fix_type)
1229+{
1230+ switch (fix_type)
1231+ {
1232+ case Pvt::FixType::no_fix:
1233+ out << "no fix";
1234+ break;
1235+ case Pvt::FixType::dead_reckoning:
1236+ out << "dead reckoning";
1237+ break;
1238+ case Pvt::FixType::fix_2d:
1239+ out << "2D fix";
1240+ break;
1241+ case Pvt::FixType::fix_3d:
1242+ out << "3D fix";
1243+ break;
1244+ case Pvt::FixType::gnss_and_dead_reckoning:
1245+ out << "gnss & dr";
1246+ break;
1247+ case Pvt::FixType::only_time_fix:
1248+ out << "only time";
1249+ break;
1250+ }
1251+
1252+ return out;
1253+}
1254+
1255+std::ostream& nav::operator<<(std::ostream& out, const nav::Pvt& pvt)
1256+{
1257+ out << "nav-pvt:" << std::endl
1258+ << " itow: " << std::uint32_t(pvt.itow) << std::endl
1259+ << " year: " << std::uint32_t(pvt.year) << std::endl
1260+ << " month: " << std::uint32_t(pvt.month) << std::endl
1261+ << " day: " << std::uint32_t(pvt.day) << std::endl
1262+ << " hour: " << std::uint32_t(pvt.hour) << std::endl
1263+ << " minute: " << std::uint32_t(pvt.minute) << std::endl
1264+ << " seconds: " << std::uint32_t(pvt.second) << std::endl
1265+ << " dtv: " << pvt.date_time_validity << std::endl
1266+ << " time_accuracy: " << pvt.time_accuracy << std::endl
1267+ << " nanoseconds: " << pvt.nanoseconds << std::endl
1268+ << " fix_type: " << pvt.fix_type << std::endl
1269+ << " fix_status_flags: " << std::uint32_t(pvt.fix_status_flags) << std::endl
1270+ << " additional_flags: " << std::uint32_t(pvt.additional_flags) << std::endl
1271+ << " satellite_count: " << std::uint32_t(pvt.satellite_count) << std::endl
1272+ << " longitude: " << pvt.longitude << std::endl
1273+ << " latitude: " << pvt.latitude << std::endl
1274+ << " height.Ellipsoid: " << pvt.height.above_ellipsoid << std::endl
1275+ << " height.MSL: " << pvt.height.above_msl << std::endl
1276+ << " accuracy.horizontal: " << pvt.accuracy.horizontal << std::endl
1277+ << " accuracy.vertical: " << pvt.accuracy.vertical << std::endl
1278+ << " accuracy.speed: " << pvt.accuracy.speed << std::endl
1279+ << " accuracy.heading: " << pvt.accuracy.heading << std::endl;
1280+
1281+ return out;
1282+}
1283
1284=== added file 'src/location/providers/ubx/_8/nav/pvt.h'
1285--- src/location/providers/ubx/_8/nav/pvt.h 1970-01-01 00:00:00 +0000
1286+++ src/location/providers/ubx/_8/nav/pvt.h 2017-03-20 16:54:12 +0000
1287@@ -0,0 +1,114 @@
1288+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
1289+//
1290+// This library is free software: you can redistribute it and/or modify
1291+// it under the terms of the GNU Lesser General Public License as published
1292+// by the Free Software Foundation, either version 3 of the License, or
1293+// (at your option) any later version.
1294+//
1295+// This program is distributed in the hope that it will be useful,
1296+// but WITHOUT ANY WARRANTY; without even the implied warranty of
1297+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1298+// GNU General Public License for more details.
1299+//
1300+// You should have received a copy of the GNU Lesser General Public License
1301+// along with this program. If not, see <http://www.gnu.org/licenses/>.
1302+
1303+#ifndef UBX_8_NAV_PVT_H_
1304+#define UBX_8_NAV_PVT_H_
1305+
1306+#include <location/providers/ubx/bits.h>
1307+
1308+#include <iosfwd>
1309+
1310+namespace location
1311+{
1312+namespace providers
1313+{
1314+namespace ubx
1315+{
1316+namespace _8
1317+{
1318+
1319+class Reader;
1320+
1321+namespace nav
1322+{
1323+
1324+struct Pvt
1325+{
1326+ static constexpr std::uint8_t class_id{0x01};
1327+ static constexpr std::uint8_t message_id{0x07};
1328+
1329+ enum DateTimeValidity
1330+ {
1331+ valid_date = 1 << 0,
1332+ valid_time = 1 << 1,
1333+ fully_resolved = 1 << 2
1334+ };
1335+
1336+ enum FixType
1337+ {
1338+ no_fix = 0,
1339+ dead_reckoning = 1,
1340+ fix_2d = 2,
1341+ fix_3d = 3,
1342+ gnss_and_dead_reckoning = 4,
1343+ only_time_fix = 5
1344+ };
1345+
1346+ void read(Reader& reader);
1347+
1348+ std::uint32_t itow;
1349+ std::uint16_t year;
1350+ std::uint8_t month;
1351+ std::uint8_t day;
1352+ std::uint8_t hour;
1353+ std::uint8_t minute;
1354+ std::uint8_t second;
1355+ DateTimeValidity date_time_validity;
1356+ std::uint32_t time_accuracy;
1357+ std::int32_t nanoseconds;
1358+ FixType fix_type;
1359+ std::uint8_t fix_status_flags;
1360+ std::uint8_t additional_flags;
1361+ std::uint8_t satellite_count;
1362+ double longitude;
1363+ double latitude;
1364+ struct
1365+ {
1366+ std::int32_t above_ellipsoid;
1367+ std::int32_t above_msl;
1368+ } height;
1369+ struct
1370+ {
1371+ std::uint32_t horizontal;
1372+ std::uint32_t vertical;
1373+ std::uint32_t speed;
1374+ double heading;
1375+ } accuracy;
1376+ struct
1377+ {
1378+ std::int32_t north;
1379+ std::int32_t east;
1380+ std::int32_t down;
1381+ } velocity;
1382+ std::int32_t speed_over_ground;
1383+ struct
1384+ {
1385+ double motion;
1386+ double vehicle;
1387+ } heading;
1388+ std::uint16_t pdop;
1389+};
1390+
1391+std::ostream& operator<<(std::ostream& out, Pvt::DateTimeValidity validity);
1392+std::ostream& operator<<(std::ostream& out, Pvt::FixType fix_type);
1393+std::ostream& operator<<(std::ostream& out, const Pvt& pvt);
1394+
1395+} // namespace nav
1396+} // namespace _8
1397+} // namespace ubx
1398+} // namespace providers
1399+} // namespace location
1400+
1401+#endif // UBX_8_NAV_PVT_H_
1402
1403=== added file 'src/location/providers/ubx/_8/nav/sat.cpp'
1404--- src/location/providers/ubx/_8/nav/sat.cpp 1970-01-01 00:00:00 +0000
1405+++ src/location/providers/ubx/_8/nav/sat.cpp 2017-03-20 16:54:12 +0000
1406@@ -0,0 +1,62 @@
1407+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
1408+//
1409+// This library is free software: you can redistribute it and/or modify
1410+// it under the terms of the GNU Lesser General Public License as published
1411+// by the Free Software Foundation, either version 3 of the License, or
1412+// (at your option) any later version.
1413+//
1414+// This program is distributed in the hope that it will be useful,
1415+// but WITHOUT ANY WARRANTY; without even the implied warranty of
1416+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1417+// GNU General Public License for more details.
1418+//
1419+// You should have received a copy of the GNU Lesser General Public License
1420+// along with this program. If not, see <http://www.gnu.org/licenses/>.
1421+
1422+#include <location/providers/ubx/_8/nav/sat.h>
1423+
1424+#include <location/providers/ubx/_8/reader.h>
1425+
1426+#include <iostream>
1427+
1428+namespace nav = location::providers::ubx::_8::nav;
1429+
1430+void nav::Sat::read(Reader& reader)
1431+{
1432+ itow = reader.read_unsigned_long();
1433+ version = reader.read_unsigned_char();
1434+ info.resize(reader.read_unsigned_char());
1435+
1436+ reader.read_unsigned_char();
1437+ reader.read_unsigned_char();
1438+
1439+ for (std::size_t i = 0; i < info.size(); i++)
1440+ {
1441+ info[i].gnss_id = static_cast<GnssId>(reader.read_unsigned_char());
1442+ info[i].satellite_id = reader.read_unsigned_char();
1443+ info[i].carrier_to_noise = reader.read_unsigned_char();
1444+ info[i].elevation = reader.read_signed_char();
1445+ info[i].azimuth = reader.read_signed_short();
1446+ info[i].pseudo_range_residual = reader.read_signed_short() * 0.1;
1447+ info[i].flags = reader.read_signed_long();
1448+ }
1449+}
1450+
1451+std::ostream& nav::operator<<(std::ostream& out, const Sat& sat)
1452+{
1453+ out << "nav-sat:" << std::endl
1454+ << " itow: " << sat.itow << std::endl
1455+ << " version: " << sat.version << std::endl
1456+ << " satellites: " << std::endl;
1457+ for (const auto& si : sat.info)
1458+ out << " gnss: " << si.gnss_id << std::endl
1459+ << " satellite: " << std::uint32_t(si.satellite_id) << std::endl
1460+ << " cno: " << std::uint32_t(si.carrier_to_noise) << std::endl
1461+ << " elevation: " << std::int32_t(si.elevation) << std::endl
1462+ << " azimuth: " << std::int32_t(si.azimuth) << std::endl
1463+ << " prr: " << si.pseudo_range_residual << std::endl
1464+ << " flags: " << si.flags << std::endl
1465+ << std::endl;
1466+
1467+ return out;
1468+}
1469
1470=== added file 'src/location/providers/ubx/_8/nav/sat.h'
1471--- src/location/providers/ubx/_8/nav/sat.h 1970-01-01 00:00:00 +0000
1472+++ src/location/providers/ubx/_8/nav/sat.h 2017-03-20 16:54:12 +0000
1473@@ -0,0 +1,71 @@
1474+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
1475+//
1476+// This library is free software: you can redistribute it and/or modify
1477+// it under the terms of the GNU Lesser General Public License as published
1478+// by the Free Software Foundation, either version 3 of the License, or
1479+// (at your option) any later version.
1480+//
1481+// This program is distributed in the hope that it will be useful,
1482+// but WITHOUT ANY WARRANTY; without even the implied warranty of
1483+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1484+// GNU General Public License for more details.
1485+//
1486+// You should have received a copy of the GNU Lesser General Public License
1487+// along with this program. If not, see <http://www.gnu.org/licenses/>.
1488+
1489+#ifndef UBX_8_NAV_SAT_H_
1490+#define UBX_8_NAV_SAT_H_
1491+
1492+#include <location/providers/ubx/_8/gnss_id.h>
1493+
1494+#include <cstdint>
1495+
1496+#include <iosfwd>
1497+#include <vector>
1498+
1499+namespace location
1500+{
1501+namespace providers
1502+{
1503+namespace ubx
1504+{
1505+namespace _8
1506+{
1507+
1508+class Reader;
1509+
1510+namespace nav
1511+{
1512+
1513+struct Sat
1514+{
1515+ static constexpr std::uint8_t class_id{0x01};
1516+ static constexpr std::uint8_t message_id{0x35};
1517+
1518+ struct Info
1519+ {
1520+ GnssId gnss_id;
1521+ std::uint8_t satellite_id;
1522+ std::uint8_t carrier_to_noise;
1523+ std::int8_t elevation;
1524+ std::int16_t azimuth;
1525+ float pseudo_range_residual;
1526+ std::uint32_t flags;
1527+ };
1528+
1529+ void read(Reader& reader);
1530+
1531+ std::uint32_t itow;
1532+ std::uint8_t version;
1533+ std::vector<Info> info;
1534+};
1535+
1536+std::ostream& operator<<(std::ostream& out, const Sat& sat);
1537+
1538+} // namespace nav
1539+} // namespace _8
1540+} // namespace ubx
1541+} // namespace providers
1542+} // namespace location
1543+
1544+#endif // UBX_8_NAV_SAT_H_
1545
1546=== modified file 'src/location/providers/ubx/_8/nmea/scanner.cpp'
1547--- src/location/providers/ubx/_8/nmea/scanner.cpp 2016-10-10 09:15:40 +0000
1548+++ src/location/providers/ubx/_8/nmea/scanner.cpp 2017-03-20 16:54:12 +0000
1549@@ -12,6 +12,7 @@
1550 //
1551 // You should have received a copy of the GNU Lesser General Public License
1552 // along with this program. If not, see <http://www.gnu.org/licenses/>.
1553+
1554 #include <location/providers/ubx/_8/nmea/scanner.h>
1555
1556 #include <stdexcept>
1557
1558=== added file 'src/location/providers/ubx/_8/reader.cpp'
1559--- src/location/providers/ubx/_8/reader.cpp 1970-01-01 00:00:00 +0000
1560+++ src/location/providers/ubx/_8/reader.cpp 2017-03-20 16:54:12 +0000
1561@@ -0,0 +1,110 @@
1562+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
1563+//
1564+// This library is free software: you can redistribute it and/or modify
1565+// it under the terms of the GNU Lesser General Public License as published
1566+// by the Free Software Foundation, either version 3 of the License, or
1567+// (at your option) any later version.
1568+//
1569+// This program is distributed in the hope that it will be useful,
1570+// but WITHOUT ANY WARRANTY; without even the implied warranty of
1571+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1572+// GNU General Public License for more details.
1573+//
1574+// You should have received a copy of the GNU Lesser General Public License
1575+// along with this program. If not, see <http://www.gnu.org/licenses/>.
1576+
1577+#include <location/providers/ubx/_8/reader.h>
1578+
1579+#include <cstring>
1580+#include <stdexcept>
1581+
1582+namespace ubx = location::providers::ubx;
1583+
1584+ubx::_8::Reader::Reader(std::vector<std::uint8_t>::const_iterator begin,
1585+ std::vector<std::uint8_t>::const_iterator end)
1586+ : begin{begin}, current{begin}, end{end} {}
1587+
1588+std::uint8_t ubx::_8::Reader::read_unsigned_char()
1589+{
1590+ if (current + sizeof(std::uint8_t) > end)
1591+ throw std::out_of_range{"Read buffer exhausted"};
1592+
1593+ auto result = *current;
1594+ ++current;
1595+ return result;
1596+}
1597+
1598+std::int8_t ubx::_8::Reader::read_signed_char()
1599+{
1600+ if (current + sizeof(std::int8_t) > end)
1601+ throw std::out_of_range{"Read buffer exhausted"};
1602+
1603+ auto result = reinterpret_cast<const std::int8_t*>(&(*current));
1604+ current += sizeof(std::int8_t);
1605+ return *result;
1606+}
1607+
1608+std::uint16_t ubx::_8::Reader::read_unsigned_short()
1609+{
1610+ if (current + sizeof(std::uint16_t) > end)
1611+ throw std::out_of_range{"Read buffer exhausted"};
1612+
1613+ auto result = reinterpret_cast<const std::uint16_t*>(&(*current));
1614+ current += sizeof(std::uint16_t);
1615+ return *result;
1616+}
1617+
1618+std::int16_t ubx::_8::Reader::read_signed_short()
1619+{
1620+ if (current + sizeof(std::int16_t) > end)
1621+ throw std::out_of_range{"Read buffer exhausted"};
1622+
1623+ auto result = reinterpret_cast<const std::int16_t*>(&(*current));
1624+ current += sizeof(std::int16_t);
1625+ return *result;
1626+}
1627+
1628+std::uint32_t ubx::_8::Reader::read_unsigned_long()
1629+{
1630+ if (current + sizeof(std::uint32_t) > end)
1631+ throw std::out_of_range{"Read buffer exhausted"};
1632+
1633+ auto result = reinterpret_cast<const std::uint32_t*>(&(*current));
1634+ current += sizeof(std::uint32_t);
1635+ return *result;
1636+}
1637+
1638+std::int32_t ubx::_8::Reader::read_signed_long()
1639+{
1640+ if (current + sizeof(std::int32_t) > end)
1641+ throw std::out_of_range{"Read buffer exhausted"};
1642+
1643+ auto result = reinterpret_cast<const std::int32_t*>(&(*current));
1644+ current += sizeof(std::int32_t);
1645+ return *result;
1646+}
1647+
1648+float ubx::_8::Reader::read_float()
1649+{
1650+ if (current + sizeof(float) > end)
1651+ throw std::out_of_range{"Read buffer exhausted"};
1652+
1653+ auto result = reinterpret_cast<const float*>(&(*current));
1654+ current += sizeof(float);
1655+ return *result;
1656+}
1657+
1658+double ubx::_8::Reader::read_double()
1659+{
1660+ if (current + sizeof(double) > end)
1661+ throw std::out_of_range{"Read buffer exhausted"};
1662+
1663+ auto result = reinterpret_cast<const double*>(&(*current));
1664+ current += sizeof(double);
1665+ return *result;
1666+}
1667+
1668+const char* ubx::_8::Reader::read_string(std::size_t size)
1669+{
1670+
1671+}
1672
1673=== added file 'src/location/providers/ubx/_8/reader.h'
1674--- src/location/providers/ubx/_8/reader.h 1970-01-01 00:00:00 +0000
1675+++ src/location/providers/ubx/_8/reader.h 2017-03-20 16:54:12 +0000
1676@@ -0,0 +1,58 @@
1677+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
1678+//
1679+// This library is free software: you can redistribute it and/or modify
1680+// it under the terms of the GNU Lesser General Public License as published
1681+// by the Free Software Foundation, either version 3 of the License, or
1682+// (at your option) any later version.
1683+//
1684+// This program is distributed in the hope that it will be useful,
1685+// but WITHOUT ANY WARRANTY; without even the implied warranty of
1686+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1687+// GNU General Public License for more details.
1688+//
1689+// You should have received a copy of the GNU Lesser General Public License
1690+// along with this program. If not, see <http://www.gnu.org/licenses/>.
1691+
1692+#ifndef UBX_8_READER_H_
1693+#define UBX_8_READER_H_
1694+
1695+#include <cstdint>
1696+#include <vector>
1697+
1698+namespace location
1699+{
1700+namespace providers
1701+{
1702+namespace ubx
1703+{
1704+namespace _8
1705+{
1706+
1707+class Reader
1708+{
1709+public:
1710+ explicit Reader(std::vector<std::uint8_t>::const_iterator begin,
1711+ std::vector<std::uint8_t>::const_iterator end);
1712+
1713+ std::uint8_t read_unsigned_char();
1714+ std::int8_t read_signed_char();
1715+ std::uint16_t read_unsigned_short();
1716+ std::int16_t read_signed_short();
1717+ std::uint32_t read_unsigned_long();
1718+ std::int32_t read_signed_long();
1719+ float read_float();
1720+ double read_double();
1721+ const char* read_string(std::size_t size);
1722+
1723+private:
1724+ std::vector<std::uint8_t>::const_iterator begin;
1725+ std::vector<std::uint8_t>::const_iterator current;
1726+ std::vector<std::uint8_t>::const_iterator end;
1727+};
1728+
1729+} // namespace _8
1730+} // namespace ubx
1731+} // namespace providers
1732+} // namespace location
1733+
1734+#endif // UBX_8_READER_H_
1735
1736=== modified file 'src/location/providers/ubx/_8/receiver.cpp'
1737--- src/location/providers/ubx/_8/receiver.cpp 2016-10-10 09:15:40 +0000
1738+++ src/location/providers/ubx/_8/receiver.cpp 2017-03-20 16:54:12 +0000
1739@@ -6,17 +6,49 @@
1740
1741 namespace ubx = location::providers::ubx;
1742
1743+namespace
1744+{
1745+
1746+struct EncodingVisitor : public boost::static_visitor<std::vector<std::uint8_t>>
1747+{
1748+ template<typename T>
1749+ std::vector<std::uint8_t> operator()(const T&) const
1750+ {
1751+ throw std::logic_error{"Encoding not supported"};
1752+ }
1753+
1754+ std::vector<std::uint8_t> operator()(const ubx::_8::cfg::Gnss& gnss) const
1755+ {
1756+ return ubx::_8::encode_message(gnss);
1757+ }
1758+
1759+ std::vector<std::uint8_t> operator()(const ubx::_8::cfg::Msg& msg) const
1760+ {
1761+ return ubx::_8::encode_message(msg);
1762+ }
1763+};
1764+
1765+} // namespace
1766+
1767 ubx::_8::Receiver::Receiver(const std::shared_ptr<Monitor>& monitor) : monitor{monitor} {}
1768
1769+void ubx::_8::Receiver::send_message(const Message& message)
1770+{
1771+ send_encoded_message(boost::apply_visitor(EncodingVisitor{}, message));
1772+}
1773+
1774 void ubx::_8::Receiver::process_chunk(Buffer::iterator it, Buffer::iterator itE)
1775 {
1776- monitor->on_new_chunk(it, itE);
1777-
1778 while (it != itE)
1779 {
1780- if (nmea::Scanner::Expect::nothing_more == nmea_scanner.update(*it))
1781+ auto result = ubx_scanner.update(*it);
1782+
1783+ if (std::get<0>(result) == Scanner::Expect::nothing_more)
1784+ monitor->on_new_ubx_message(ubx_scanner.finalize());
1785+ if (!std::get<1>(result))
1786 {
1787- monitor->on_new_nmea_sentence(nmea::parse_sentence(nmea_scanner.finalize()));
1788+ if (nmea::Scanner::Expect::nothing_more == nmea_scanner.update(*it))
1789+ monitor->on_new_nmea_sentence(nmea::parse_sentence(nmea_scanner.finalize()));
1790 }
1791 ++it;
1792 }
1793
1794=== modified file 'src/location/providers/ubx/_8/receiver.h'
1795--- src/location/providers/ubx/_8/receiver.h 2016-10-10 09:15:40 +0000
1796+++ src/location/providers/ubx/_8/receiver.h 2017-03-20 16:54:12 +0000
1797@@ -12,9 +12,14 @@
1798 //
1799 // You should have received a copy of the GNU Lesser General Public License
1800 // along with this program. If not, see <http://www.gnu.org/licenses/>.
1801+
1802 #ifndef UBX_8_RECEIVER_H_
1803 #define UBX_8_RECEIVER_H_
1804
1805+#include <location/providers/ubx/_8/codec.h>
1806+#include <location/providers/ubx/_8/message.h>
1807+#include <location/providers/ubx/_8/scanner.h>
1808+
1809 #include <location/providers/ubx/_8/nmea/scanner.h>
1810 #include <location/providers/ubx/_8/nmea/sentence.h>
1811
1812@@ -49,14 +54,18 @@
1813 Monitor& operator=(Monitor&&) = delete;
1814 /// @endcond
1815
1816- /// @brief on_new_chunk is invoked for every incoming chunk of raw data.
1817- virtual void on_new_chunk(Buffer::iterator it, Buffer::iterator itE) = 0;
1818+ /// @brief on_new_ubx_message is invoked for every complete and parsed
1819+ /// ubx message.
1820+ virtual void on_new_ubx_message(const ubx::_8::Message& message) = 0;
1821
1822 /// @brief on_new_nmea_sentence is invoked for every complete and parsed
1823 /// nmea sentence.
1824- virtual void on_new_nmea_sentence(const nmea::Sentence& sentence) = 0;
1825+ virtual void on_new_nmea_sentence(const ubx::_8::nmea::Sentence& sentence) = 0;
1826 };
1827
1828+ /// @brief send_message encodes and sends 'message' to the receiver.
1829+ void send_message(const Message& message);
1830+
1831 protected:
1832 /// @brief Receiver initializes a new instance with monitor
1833 ///
1834@@ -69,13 +78,18 @@
1835 /// Calls out to a configured monitor instance for announcing results.
1836 void process_chunk(Buffer::iterator it, Buffer::iterator itE);
1837
1838+ /// @brief send_encoded_message sends out data to the receiver.
1839+ virtual void send_encoded_message(const std::vector<std::uint8_t>& data) = 0;
1840+
1841 private:
1842 std::shared_ptr<Monitor> monitor;
1843- nmea::Scanner nmea_scanner;
1844+ ubx::_8::nmea::Scanner nmea_scanner;
1845+ ubx::_8::Scanner ubx_scanner;
1846 };
1847-}
1848-}
1849-}
1850-}
1851+
1852+} // namespace _8
1853+} // namespace ubx
1854+} // namespace providers
1855+} // namespace location
1856
1857 #endif // UBX_8_RECEIVER_H_
1858
1859=== added file 'src/location/providers/ubx/_8/scanner.cpp'
1860--- src/location/providers/ubx/_8/scanner.cpp 1970-01-01 00:00:00 +0000
1861+++ src/location/providers/ubx/_8/scanner.cpp 2017-03-20 16:54:12 +0000
1862@@ -0,0 +1,166 @@
1863+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
1864+//
1865+// This library is free software: you can redistribute it and/or modify
1866+// it under the terms of the GNU Lesser General Public License as published
1867+// by the Free Software Foundation, either version 3 of the License, or
1868+// (at your option) any later version.
1869+//
1870+// This program is distributed in the hope that it will be useful,
1871+// but WITHOUT ANY WARRANTY; without even the implied warranty of
1872+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1873+// GNU General Public License for more details.
1874+//
1875+// You should have received a copy of the GNU Lesser General Public License
1876+// along with this program. If not, see <http://www.gnu.org/licenses/>.
1877+
1878+#include <location/providers/ubx/_8/scanner.h>
1879+
1880+#include <location/providers/ubx/_8/codec.h>
1881+#include <location/providers/ubx/_8/magic.h>
1882+#include <location/providers/ubx/_8/message.h>
1883+
1884+#include <cstdint>
1885+#include <functional>
1886+#include <iostream>
1887+#include <map>
1888+#include <stdexcept>
1889+#include <tuple>
1890+#include <vector>
1891+
1892+namespace _8 = location::providers::ubx::_8;
1893+
1894+namespace
1895+{
1896+
1897+template<std::uint8_t class_id, std::uint8_t message_id>
1898+std::tuple<std::uint8_t, std::uint8_t> make_tuple()
1899+{
1900+ return std::make_tuple(class_id, message_id);
1901+}
1902+
1903+} // namespace
1904+
1905+_8::Scanner::Scanner()
1906+ : next{Expect::sync_char_1},
1907+ class_id{0},
1908+ message_id{0},
1909+ expected_size{0},
1910+ payload_iterator{payload.end()}
1911+{
1912+ factories[make_tuple<ack::Ack::class_id, ack::Ack::message_id>()] =
1913+ [](const std::vector<std::uint8_t>& payload) { return decode_message<ack::Ack>(payload); };
1914+ factories[make_tuple<ack::Nak::class_id, ack::Nak::message_id>()] =
1915+ [](const std::vector<std::uint8_t>& payload) { return decode_message<ack::Nak>(payload); };
1916+ factories[make_tuple<cfg::Gnss::class_id, cfg::Gnss::message_id>()] =
1917+ [](const std::vector<std::uint8_t>&) { return cfg::Gnss{}; };
1918+ factories[make_tuple<cfg::Msg::class_id, cfg::Msg::message_id>()] =
1919+ [](const std::vector<std::uint8_t>&) { return cfg::Msg{}; };
1920+ factories[make_tuple<nav::Pvt::class_id, nav::Pvt::message_id>()] =
1921+ [](const std::vector<std::uint8_t>& payload) { return decode_message<nav::Pvt>(payload); };
1922+ factories[make_tuple<nav::Sat::class_id, nav::Sat::message_id>()] =
1923+ [](const std::vector<std::uint8_t>& payload) { return decode_message<nav::Sat>(payload); };
1924+}
1925+
1926+std::tuple<_8::Scanner::Expect, bool> _8::Scanner::update(std::uint8_t c)
1927+{
1928+ bool consumed = false;
1929+
1930+ // TODO(tvoss): This lacks a lot of validiation and verification.
1931+ // UBX allows us to partially parse while we scan and carry out online
1932+ // checksum calculation. Ideally, we would have a common class State that
1933+ // captures behavior and transition logic.
1934+ switch (next)
1935+ {
1936+ case Expect::sync_char_1:
1937+ if (c == sync_char_1)
1938+ {
1939+ next = Expect::sync_char_2;
1940+ consumed = true;
1941+ }
1942+ break;
1943+ case Expect::sync_char_2:
1944+ if (c == sync_char_2)
1945+ {
1946+ next = Expect::class_;
1947+ consumed = true;
1948+ }
1949+ break;
1950+ case Expect::class_:
1951+ checksum(c);
1952+ class_id = c;
1953+ next = Expect::id;
1954+ consumed = true;
1955+ break;
1956+ case Expect::id:
1957+ checksum(c);
1958+ message_id = c;
1959+ next = Expect::length_1;
1960+ consumed = true;
1961+ break;
1962+ case Expect::length_1:
1963+ checksum(c);
1964+ expected_size = c;
1965+ next = Expect::length_2;
1966+ consumed = true;
1967+ break;
1968+ case Expect::length_2:
1969+ checksum(c);
1970+ expected_size |= (c << 8);
1971+ payload.resize(expected_size);
1972+ payload_iterator = payload.begin();
1973+ next = Expect::payload;
1974+ consumed = true;
1975+ break;
1976+ case Expect::payload:
1977+ checksum(c);
1978+ *payload_iterator = c;
1979+ ++payload_iterator;
1980+ next = payload_iterator == payload.end()
1981+ ? Expect::ck_a
1982+ : next;
1983+ consumed = true;
1984+ break;
1985+ case Expect::ck_a:
1986+ ck_a = c;
1987+ next = Expect::ck_b;
1988+ consumed = true;
1989+ break;
1990+ case Expect::ck_b:
1991+ ck_b = c;
1992+ next = Expect::nothing_more;
1993+ consumed = true;
1994+ break;
1995+ default:
1996+ consumed = false;
1997+ break;
1998+ }
1999+
2000+ return std::make_tuple(next, consumed);
2001+}
2002+
2003+_8::Message _8::Scanner::finalize()
2004+{
2005+ if (next != Expect::nothing_more)
2006+ throw std::logic_error{"Not ready for extraction."};
2007+
2008+ if (ck_a != checksum.ck_a() || ck_b != checksum.ck_b())
2009+ throw std::runtime_error{"Verification failed."};
2010+
2011+ auto it = factories.find(std::make_tuple(class_id, message_id));
2012+
2013+ if (it == factories.end())
2014+ throw std::runtime_error{"Could not decode message."};
2015+
2016+ auto result = it->second(payload);
2017+
2018+ checksum = Checksum{};
2019+ next = Expect::sync_char_1;
2020+ class_id = 0;
2021+ message_id = 0;
2022+ expected_size = 0;
2023+ payload.clear();
2024+ payload_iterator = payload.end();
2025+ ck_a = ck_b = 0;
2026+
2027+ return result;
2028+}
2029
2030=== modified file 'src/location/providers/ubx/_8/scanner.h'
2031--- src/location/providers/ubx/_8/scanner.h 2016-10-10 09:15:40 +0000
2032+++ src/location/providers/ubx/_8/scanner.h 2017-03-20 16:54:12 +0000
2033@@ -12,9 +12,18 @@
2034 //
2035 // You should have received a copy of the GNU Lesser General Public License
2036 // along with this program. If not, see <http://www.gnu.org/licenses/>.
2037+
2038 #ifndef UBX_8_SCANNER_H_
2039 #define UBX_8_SCANNER_H_
2040
2041+#include <location/providers/ubx/_8/checksum.h>
2042+#include <location/providers/ubx/_8/message.h>
2043+
2044+#include <cstdint>
2045+#include <map>
2046+#include <tuple>
2047+#include <vector>
2048+
2049 namespace location
2050 {
2051 namespace providers
2052@@ -23,33 +32,10 @@
2053 {
2054 namespace _8
2055 {
2056-class Checksum
2057-{
2058-public:
2059- struct VerificationFailed : public std::runtime_error
2060- {
2061- ValidationFailed() : std::runtime_error{"Checksum verification failed."} {}
2062- };
2063-
2064- void update(std::uint8_t c)
2065- {
2066- ck_a += c;
2067- ck_b += ck_a;
2068- }
2069-
2070- void verify_or_throw(std::uint8_t a, std::uint8_t b)
2071- {
2072- if (a != ck_a || b != ck_b)
2073- throw VerificationFailed{};
2074- }
2075-
2076-private:
2077- std::uint8_t ck_a{0};
2078- std::uint8_t ck_b{0};
2079-};
2080+
2081 class Scanner
2082 {
2083-public:
2084+public:
2085 /// @brief Expect enumerates the different states of the scanner/parser.
2086 enum class Expect
2087 {
2088@@ -63,80 +49,28 @@
2089 ck_a,
2090 ck_b,
2091 nothing_more
2092- };
2093-
2094- /// @brief finalize returns the complete message
2095- /// or throws in case of issues.
2096- Message finalize()
2097- {
2098- if (not message)
2099- throw std::runtime_error{"Too early"};
2100- if (next != Expect::nothing_more)
2101- throw std::runtime_error{"Too early"};
2102-
2103- auto result = *message;
2104-
2105- next = Expect::sync_char_1;
2106- message.reset();
2107-
2108- return result;
2109- }
2110-
2111- Expect update(std::uint8_t c)
2112- {
2113- // TODO(tvoss): This lacks a lot of validiation and verification.
2114- // UBX allows us to partially parse while we scan and carry out online
2115- // checksum calculation. Ideally, we would have a common class State that
2116- // captures behavior and transition logic.
2117-
2118- switch (next)
2119- {
2120- case Expect::sync_char_1:
2121- if (c == sync_char_1)
2122- next = Expect::sync_char_1;
2123- break;
2124- case Expect::sync_char_2:
2125- if (c == sync_char_2)
2126- next = Expect::class_;
2127- break;
2128- case Expect::class_:
2129- message->cls = static_cast<Class>(c);
2130- next = Expect::id;
2131- break;
2132- case Expect::id_:
2133- message->id = static_cast<Id>(c);
2134- next = Expect::length_1;
2135- break;
2136- case Expect::length_1:
2137- message->length = c;
2138- next = Expect::length_2;
2139- break;
2140- case Excpet::length_2:
2141- message->length |= c << 8;
2142- next = Expect::payload;
2143- case Expect::payload:
2144- message->payload.push_back(c);
2145- checksum.update(c);
2146- next = message->payload.size() == message->length() ? Expect::ck_a : next;
2147- break;
2148- case Expect::ck_a:
2149- message->ck_a = c;
2150- next = Expect::ck_b;
2151- break;
2152- case Expect::ck_b:
2153- message->ck_b |= c << 8;
2154- checksum.verify_or_throw(message->ck_a, message->ck_b);
2155- next = Expect::nothing_more;
2156- break;
2157- }
2158-
2159- return next;
2160- }
2161+ };
2162+
2163+ Scanner();
2164+
2165+ std::tuple<Expect, bool> update(std::uint8_t c);
2166+
2167+ Message finalize();
2168
2169 private:
2170- Expect next{Expect::sync_char_1};
2171+ Expect next;
2172 Checksum checksum;
2173- boost::optional<Message> message;
2174+ std::uint8_t class_id;
2175+ std::uint8_t message_id;
2176+ std::uint16_t expected_size;
2177+ std::vector<uint8_t> payload;
2178+ std::vector<uint8_t>::iterator payload_iterator;
2179+ std::uint8_t ck_a;
2180+ std::uint8_t ck_b;
2181+ std::map<
2182+ std::tuple<std::uint8_t, std::uint8_t>,
2183+ std::function<Message(const std::vector<std::uint8_t>&)>
2184+ > factories;
2185 };
2186 }
2187 }
2188
2189=== modified file 'src/location/providers/ubx/_8/serial_port_receiver.cpp'
2190--- src/location/providers/ubx/_8/serial_port_receiver.cpp 2017-03-04 21:52:34 +0000
2191+++ src/location/providers/ubx/_8/serial_port_receiver.cpp 2017-03-20 16:54:12 +0000
2192@@ -19,14 +19,21 @@
2193 {
2194 }
2195
2196+void ubx::_8::SerialPortReceiver::send_encoded_message(const std::vector<std::uint8_t>& data)
2197+{
2198+ ios.dispatch([this, data]()
2199+ {
2200+ boost::asio::write(sp, boost::asio::buffer(data), boost::asio::transfer_all());
2201+ });
2202+}
2203+
2204 void ubx::_8::SerialPortReceiver::start()
2205 {
2206- auto flush_rc = ::tcflush(sp.lowest_layer().native_handle(), TCIOFLUSH);
2207 start_read();
2208- if (flush_rc) throw std::system_error(errno, std::system_category());
2209 }
2210
2211-void ubx::_8::SerialPortReceiver::stop() {
2212+void ubx::_8::SerialPortReceiver::stop()
2213+{
2214 sp.cancel();
2215 }
2216
2217
2218=== modified file 'src/location/providers/ubx/_8/serial_port_receiver.h'
2219--- src/location/providers/ubx/_8/serial_port_receiver.h 2016-10-10 09:15:40 +0000
2220+++ src/location/providers/ubx/_8/serial_port_receiver.h 2017-03-20 16:54:12 +0000
2221@@ -44,6 +44,9 @@
2222 void start();
2223 void stop();
2224
2225+protected:
2226+ void send_encoded_message(const std::vector<std::uint8_t>& data) override;
2227+
2228 private:
2229 /// @brief Receiver initializes a new instance opening the serial port
2230 /// located at path.
2231
2232=== added file 'src/location/providers/ubx/_8/writer.cpp'
2233--- src/location/providers/ubx/_8/writer.cpp 1970-01-01 00:00:00 +0000
2234+++ src/location/providers/ubx/_8/writer.cpp 2017-03-20 16:54:12 +0000
2235@@ -0,0 +1,119 @@
2236+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
2237+//
2238+// This library is free software: you can redistribute it and/or modify
2239+// it under the terms of the GNU Lesser General Public License as published
2240+// by the Free Software Foundation, either version 3 of the License, or
2241+// (at your option) any later version.
2242+//
2243+// This program is distributed in the hope that it will be useful,
2244+// but WITHOUT ANY WARRANTY; without even the implied warranty of
2245+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2246+// GNU General Public License for more details.
2247+//
2248+// You should have received a copy of the GNU Lesser General Public License
2249+// along with this program. If not, see <http://www.gnu.org/licenses/>.
2250+
2251+#include <location/providers/ubx/_8/writer.h>
2252+
2253+#include <cstring>
2254+#include <stdexcept>
2255+
2256+namespace ubx = location::providers::ubx;
2257+
2258+ubx::_8::Writer::Writer(std::vector<std::uint8_t>::iterator begin,
2259+ std::vector<std::uint8_t>::iterator end)
2260+ : begin{begin}, current{begin}, end{end} {}
2261+
2262+void ubx::_8::Writer::write_unsigned_char(std::uint8_t value)
2263+{
2264+ if (current + sizeof(value) > end)
2265+ throw std::out_of_range{"Write buffer exhausted"};
2266+
2267+ *reinterpret_cast<std::uint8_t*>(&(*current)) = value;
2268+ current += sizeof(value);
2269+
2270+}
2271+
2272+void ubx::_8::Writer::write_signed_char(std::int8_t value)
2273+{
2274+ if (current + sizeof(value) > end)
2275+ throw std::out_of_range{"Write buffer exhausted"};
2276+
2277+ *reinterpret_cast<std::int8_t*>(&(*current)) = value;
2278+ current += sizeof(value);
2279+
2280+}
2281+
2282+void ubx::_8::Writer::write_unsigned_short(std::uint16_t value)
2283+{
2284+ if (current + sizeof(value) > end)
2285+ throw std::out_of_range{"Write buffer exhausted"};
2286+
2287+ *reinterpret_cast<std::uint16_t*>(&(*current)) = value;
2288+ current += sizeof(value);
2289+}
2290+
2291+void ubx::_8::Writer::write_signed_short(std::int16_t value)
2292+{
2293+ if (current + sizeof(value) > end)
2294+ throw std::out_of_range{"Write buffer exhausted"};
2295+
2296+ *reinterpret_cast<std::int16_t*>(&(*current)) = value;
2297+ current += sizeof(value);
2298+}
2299+
2300+void ubx::_8::Writer::write_unsigned_long(std::uint32_t value)
2301+{
2302+ if (current + sizeof(value) > end)
2303+ throw std::out_of_range{"Write buffer exhausted"};
2304+
2305+ *reinterpret_cast<std::uint32_t*>(&(*current)) = value;
2306+ current += sizeof(value);
2307+}
2308+
2309+void ubx::_8::Writer::write_signed_long(std::int32_t value)
2310+{
2311+ if (current + sizeof(value) > end)
2312+ throw std::out_of_range{"Write buffer exhausted"};
2313+
2314+ *reinterpret_cast<std::int32_t*>(&(*current)) = value;
2315+ current += sizeof(value);
2316+}
2317+
2318+void ubx::_8::Writer::write_float(float value)
2319+{
2320+ if (current + sizeof(value) > end)
2321+ throw std::out_of_range{"Write buffer exhausted"};
2322+
2323+ *reinterpret_cast<float*>(&(*current)) = value;
2324+ current += sizeof(value);
2325+}
2326+
2327+void ubx::_8::Writer::write_double(double value)
2328+{
2329+ if (current + sizeof(value) > end)
2330+ throw std::out_of_range{"Write buffer exhausted"};
2331+
2332+ *reinterpret_cast<double*>(&(*current)) = value;
2333+ current += sizeof(value);
2334+}
2335+
2336+void ubx::_8::Writer::write_string(const char* s, std::size_t size)
2337+{
2338+ if (current + size > end)
2339+ throw std::out_of_range{"Write buffer exhausted"};
2340+
2341+ memcpy(&(*current), s, size);
2342+ current += size;
2343+}
2344+
2345+ubx::_8::Writer ubx::_8::Writer::slice(std::size_t size)
2346+{
2347+ if (current + size > end)
2348+ throw std::out_of_range{"Write buffer exhausted"};
2349+
2350+ Writer result{current, current + size};
2351+ current += size;
2352+
2353+ return result;
2354+}
2355
2356=== added file 'src/location/providers/ubx/_8/writer.h'
2357--- src/location/providers/ubx/_8/writer.h 1970-01-01 00:00:00 +0000
2358+++ src/location/providers/ubx/_8/writer.h 2017-03-20 16:54:12 +0000
2359@@ -0,0 +1,60 @@
2360+// Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
2361+//
2362+// This library is free software: you can redistribute it and/or modify
2363+// it under the terms of the GNU Lesser General Public License as published
2364+// by the Free Software Foundation, either version 3 of the License, or
2365+// (at your option) any later version.
2366+//
2367+// This program is distributed in the hope that it will be useful,
2368+// but WITHOUT ANY WARRANTY; without even the implied warranty of
2369+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2370+// GNU General Public License for more details.
2371+//
2372+// You should have received a copy of the GNU Lesser General Public License
2373+// along with this program. If not, see <http://www.gnu.org/licenses/>.
2374+
2375+#ifndef UBX_8_WRITER_H_
2376+#define UBX_8_WRITER_H_
2377+
2378+#include <cstdint>
2379+#include <vector>
2380+
2381+namespace location
2382+{
2383+namespace providers
2384+{
2385+namespace ubx
2386+{
2387+namespace _8
2388+{
2389+
2390+class Writer
2391+{
2392+public:
2393+ explicit Writer(std::vector<std::uint8_t>::iterator begin,
2394+ std::vector<std::uint8_t>::iterator end);
2395+
2396+ void write_unsigned_char(std::uint8_t value);
2397+ void write_signed_char(std::int8_t value);
2398+ void write_unsigned_short(std::uint16_t value);
2399+ void write_signed_short(std::int16_t value);
2400+ void write_unsigned_long(std::uint32_t value);
2401+ void write_signed_long(std::int32_t value);
2402+ void write_float(float value);
2403+ void write_double(double value);
2404+ void write_string(const char* s, std::size_t size);
2405+
2406+ Writer slice(std::size_t size);
2407+
2408+private:
2409+ std::vector<std::uint8_t>::iterator begin;
2410+ std::vector<std::uint8_t>::iterator current;
2411+ std::vector<std::uint8_t>::iterator end;
2412+};
2413+
2414+} // namespace _8
2415+} // namespace ubx
2416+} // namespace providers
2417+} // namespace location
2418+
2419+#endif // UBX_8_WRITER_H_
2420
2421=== added file 'src/location/providers/ubx/bits.h'
2422--- src/location/providers/ubx/bits.h 1970-01-01 00:00:00 +0000
2423+++ src/location/providers/ubx/bits.h 2017-03-20 16:54:12 +0000
2424@@ -0,0 +1,41 @@
2425+// Copyright (C) 2017 Thomas Voss <thomas.voss.bochum@gmail.com>
2426+//
2427+// This library is free software: you can redistribute it and/or modify
2428+// it under the terms of the GNU Lesser General Public License as published
2429+// by the Free Software Foundation, either version 3 of the License, or
2430+// (at your option) any later version.
2431+//
2432+// This program is distributed in the hope that it will be useful,
2433+// but WITHOUT ANY WARRANTY; without even the implied warranty of
2434+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2435+// GNU General Public License for more details.
2436+//
2437+// You should have received a copy of the GNU Lesser General Public License
2438+// along with this program. If not, see <http://www.gnu.org/licenses/>.
2439+
2440+#ifndef UBX_BITS_H_
2441+#define UBX_BITS_H_
2442+
2443+#include <cstdint>
2444+
2445+namespace location
2446+{
2447+namespace providers
2448+{
2449+namespace ubx
2450+{
2451+namespace bits
2452+{
2453+
2454+template<std::size_t begin, std::size_t end, typename T, typename U>
2455+void set(T& bitfield, U value)
2456+{
2457+ bitfield |= (value << begin);
2458+}
2459+
2460+} // namespace bits
2461+} // namespace ubx
2462+} // namespace providers
2463+} // namespace location
2464+
2465+#endif // UBX_BITS_H_
2466
2467=== modified file 'src/location/providers/ubx/provider.cpp'
2468--- src/location/providers/ubx/provider.cpp 2017-03-09 10:07:56 +0000
2469+++ src/location/providers/ubx/provider.cpp 2017-03-20 16:54:12 +0000
2470@@ -22,9 +22,16 @@
2471 #include <location/runtime.h>
2472 #include <location/glib/runtime.h>
2473
2474+#include <location/providers/ubx/_8/cfg/gnss.h>
2475+#include <location/providers/ubx/_8/cfg/msg.h>
2476+#include <location/providers/ubx/_8/nav/pvt.h>
2477+#include <location/providers/ubx/_8/nav/sat.h>
2478+
2479 #include <core/posix/this_process.h>
2480
2481 #include <fstream>
2482+#include <iostream>
2483+#include <iterator>
2484 #include <thread>
2485
2486 namespace env = core::posix::this_process::env;
2487@@ -39,17 +46,19 @@
2488 {
2489 }
2490
2491-void ubx::Provider::Monitor::on_new_chunk(_8::Receiver::Buffer::iterator, _8::Receiver::Buffer::iterator)
2492+void ubx::Provider::Monitor::on_new_ubx_message(const _8::Message& message)
2493 {
2494- // We drop the chunk on purpose.
2495+ VLOG(1) << message;
2496+ if (provider->protocol == Provider::Protocol::ubx)
2497+ boost::apply_visitor(*this, message);
2498 }
2499
2500+
2501 void ubx::Provider::Monitor::on_new_nmea_sentence(const _8::nmea::Sentence& sentence)
2502 {
2503- // TODO(tvoss): This is a little verbose and we should remove it
2504- // for production scenarios.
2505- LOG(INFO) << sentence;
2506- boost::apply_visitor(*this, sentence);
2507+ VLOG(1) << sentence;
2508+ if (provider->protocol == Provider::Protocol::nmea)
2509+ boost::apply_visitor(*this, sentence);
2510 }
2511
2512 void ubx::Provider::Monitor::operator()(const _8::nmea::Gga& gga) const
2513@@ -80,6 +89,35 @@
2514 }
2515 }
2516
2517+void ubx::Provider::Monitor::operator()(const _8::nav::Pvt& pvt) const
2518+{
2519+ if (pvt.fix_type == _8::nav::Pvt::FixType::no_fix)
2520+ return;
2521+
2522+ Position position
2523+ {
2524+ pvt.latitude * units::degrees,
2525+ pvt.longitude * units::degrees
2526+ };
2527+ position.accuracy().horizontal(pvt.accuracy.horizontal * 1e-3 * units::meters);
2528+
2529+ if (pvt.fix_type == _8::nav::Pvt::FixType::fix_3d)
2530+ {
2531+ position.altitude(pvt.height.above_msl * 1e-3 * units::meters);
2532+ position.accuracy().vertical(pvt.accuracy.vertical * 1e-3 * units::meters);
2533+ }
2534+
2535+ units::Degrees heading = pvt.heading.vehicle * units::degrees;
2536+ units::MetersPerSecond speed = pvt.speed_over_ground * 1e-3 * units::meters_per_second;
2537+
2538+ glib::Runtime::instance()->dispatch([this, position, heading, speed]()
2539+ {
2540+ provider->updates.position(location::Update<location::Position>{position});
2541+ provider->updates.heading(location::Update<units::Degrees>{heading});
2542+ provider->updates.velocity(location::Update<units::MetersPerSecond>{speed});
2543+ });
2544+}
2545+
2546 void ubx::Provider::Monitor::operator()(const _8::nmea::Gsa&) const
2547 {
2548 // Empty on purpose
2549@@ -122,20 +160,65 @@
2550
2551 location::Provider::Ptr ubx::Provider::create_instance(const location::ProviderFactory::Configuration& config)
2552 {
2553- std::string device_path;
2554+ std::string device_path = "/dev/ttyACM0";
2555 std::ifstream in(env::get("SNAP_DATA") + "/ubx/provider/path");
2556-
2557 in >> device_path;
2558
2559- return location::Provider::Ptr{new ubx::Provider{config.get<std::string>("device", device_path.empty() ? "/dev/ttyACM0" : device_path)}};
2560+ return location::Provider::Ptr{new ubx::Provider{
2561+ Protocol::ubx, config.get<std::string>("device", device_path)}};
2562 }
2563
2564-ubx::Provider::Provider(const boost::filesystem::path& device)
2565- : runtime{location::Runtime::create(1)},
2566+ubx::Provider::Provider(Protocol protocol, const boost::filesystem::path& device)
2567+ : protocol{protocol},
2568+ runtime{location::Runtime::create(1)},
2569 monitor{std::make_shared<Monitor>(this)},
2570 receiver{_8::SerialPortReceiver::create(runtime->service(), device, monitor)}
2571 {
2572 runtime->start();
2573+
2574+ _8::cfg::Gnss::Gps gps;
2575+ gps.l1ca = true;
2576+ gps.enable = true;
2577+ gps.min_tracking_channels = 4;
2578+ gps.max_tracking_channels = 8;
2579+
2580+ _8::cfg::Gnss::Galileo galileo;
2581+ galileo.e1os = true;
2582+ galileo.enable = true;
2583+ galileo.min_tracking_channels = 4;
2584+ galileo.max_tracking_channels = 8;
2585+
2586+ _8::cfg::Gnss::Glonass glonass;
2587+ glonass.l1of = true;
2588+ glonass.enable = true;
2589+ glonass.min_tracking_channels = 4;
2590+ glonass.max_tracking_channels = 8;
2591+
2592+ _8::cfg::Gnss::Sbas sbas;
2593+ sbas.l1ca = true;
2594+ sbas.enable = true;
2595+ sbas.min_tracking_channels = 4;
2596+ sbas.max_tracking_channels = 8;
2597+
2598+ _8::cfg::Gnss gnss;
2599+ gnss.gps = gps;
2600+ gnss.galileo = galileo;
2601+ gnss.glonass = glonass;
2602+ gnss.sbas = sbas;
2603+
2604+ receiver->send_message(gnss);
2605+
2606+ if (protocol == Protocol::ubx)
2607+ {
2608+ _8::cfg::Msg cfg_msg{ubx::_8::nav::Pvt::class_id, ubx::_8::nav::Pvt::message_id, { 0 }};
2609+ cfg_msg.rate[_8::cfg::Msg::Port::usb] = 1;
2610+ cfg_msg.rate[_8::cfg::Msg::Port::uart1] = 1;
2611+ receiver->send_message(cfg_msg);
2612+
2613+ cfg_msg.configured_class_id = _8::nav::Sat::class_id;
2614+ cfg_msg.configured_message_id = _8::nav::Sat::message_id;
2615+ receiver->send_message(cfg_msg);
2616+ }
2617 }
2618
2619 ubx::Provider::~Provider() noexcept
2620
2621=== modified file 'src/location/providers/ubx/provider.h'
2622--- src/location/providers/ubx/provider.h 2016-10-10 09:15:40 +0000
2623+++ src/location/providers/ubx/provider.h 2017-03-20 16:54:12 +0000
2624@@ -53,8 +53,14 @@
2625 // for the list of known options.
2626 static Provider::Ptr create_instance(const ProviderFactory::Configuration&);
2627
2628+ enum class Protocol
2629+ {
2630+ ubx, // Rely on ubx.
2631+ nmea // Rely on nmea.
2632+ };
2633+
2634 // Creates a new provider instance talking via device to the ubx chipset.
2635- Provider(const boost::filesystem::path& device);
2636+ Provider(Protocol protocol, const boost::filesystem::path& device);
2637 // Cleans up all resources and stops the updates.
2638 ~Provider() noexcept;
2639
2640@@ -79,9 +85,14 @@
2641 explicit Monitor(Provider* provider);
2642
2643 // From Receiver::Monitor
2644- void on_new_chunk(_8::Receiver::Buffer::iterator it, _8::Receiver::Buffer::iterator itE) override;
2645+ void on_new_ubx_message(const _8::Message& message) override;
2646 void on_new_nmea_sentence(const _8::nmea::Sentence& sentence) override;
2647
2648+ template<typename T>
2649+ void operator()(const T&) const {}
2650+
2651+ void operator()(const _8::nav::Pvt& pvt) const;
2652+
2653 void operator()(const _8::nmea::Gga& gga) const;
2654 void operator()(const _8::nmea::Gsa& gsa) const;
2655 void operator()(const _8::nmea::Gll& gll) const;
2656@@ -93,6 +104,7 @@
2657 Provider* provider;
2658 };
2659
2660+ Protocol protocol;
2661 std::shared_ptr<location::Runtime> runtime;
2662 std::shared_ptr<Monitor> monitor;
2663 std::shared_ptr<_8::SerialPortReceiver> receiver;

Subscribers

People subscribed via source and target branches

to all changes: