Merge lp:~thomas-voss/location-service/cherry-pick-fwd into lp:location-service/trunk

Proposed by Thomas Voß
Status: Merged
Approved by: Alberto Mardegan
Approved revision: 217
Merged at revision: 225
Proposed branch: lp:~thomas-voss/location-service/cherry-pick-fwd
Merge into: lp:location-service/trunk
Diff against target: 6542 lines (+5190/-291)
73 files modified
3rd-party/boost/core/scoped_enum.hpp (+192/-0)
3rd-party/boost/endian/arithmetic.hpp (+413/-0)
3rd-party/boost/endian/buffers.hpp (+515/-0)
3rd-party/boost/endian/conversion.hpp (+487/-0)
3rd-party/boost/endian/detail/config.hpp (+62/-0)
3rd-party/boost/endian/detail/cover_operators.hpp (+142/-0)
3rd-party/boost/endian/detail/disable_warnings.hpp (+33/-0)
3rd-party/boost/endian/detail/disable_warnings_pop.hpp (+12/-0)
3rd-party/boost/endian/detail/intrinsic.hpp (+64/-0)
3rd-party/boost/endian/detail/lightweight_test.hpp (+223/-0)
3rd-party/boost/endian/endian.hpp (+19/-0)
3rd-party/boost/endian/std_pair.hpp (+38/-0)
CMakeLists.txt (+17/-0)
_clang-format (+56/-0)
astyle-config (+43/-0)
debian/changelog (+111/-0)
debian/source/format (+1/-1)
doc/Doxyfile.in (+2/-2)
doc/daemon_and_cli.md (+55/-0)
doc/debugging.md (+91/-0)
doc/hacking.md (+146/-0)
doc/intro.md (+67/-0)
doc/manual_testing.md (+174/-0)
doc/tips_n_tricks.md (+21/-0)
examples/service/service.cpp (+14/-15)
include/location_service/com/ubuntu/location/provider_factory.h (+3/-0)
po/ubuntu-location-service.pot (+7/-11)
src/location_service/com/ubuntu/location/CMakeLists.txt (+9/-0)
src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.cpp (+12/-6)
src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.h (+12/-0)
src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.cpp (+1/-1)
src/location_service/com/ubuntu/location/engine.cpp (+25/-28)
src/location_service/com/ubuntu/location/engine.h (+3/-3)
src/location_service/com/ubuntu/location/provider_factory.cpp (+14/-0)
src/location_service/com/ubuntu/location/providers/config.cpp (+7/-0)
src/location_service/com/ubuntu/location/providers/dummy/CMakeLists.txt (+3/-1)
src/location_service/com/ubuntu/location/providers/dummy/delayed_provider.cpp (+42/-0)
src/location_service/com/ubuntu/location/providers/dummy/delayed_provider.h (+62/-0)
src/location_service/com/ubuntu/location/providers/gps/CMakeLists.txt (+13/-10)
src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp (+43/-26)
src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h (+26/-6)
src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.cpp (+30/-0)
src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.h (+13/-4)
src/location_service/com/ubuntu/location/providers/gps/sntp_client.cpp (+210/-0)
src/location_service/com/ubuntu/location/providers/gps/sntp_client.h (+210/-0)
src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.cpp (+57/-0)
src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.h (+51/-0)
src/location_service/com/ubuntu/location/providers/remote/provider.cpp (+23/-0)
src/location_service/com/ubuntu/location/service/daemon.cpp (+42/-82)
src/location_service/com/ubuntu/location/service/daemon_main.cpp (+0/-31)
src/location_service/com/ubuntu/location/service/implementation.cpp (+25/-4)
src/location_service/com/ubuntu/location/service/provider_daemon.cpp (+17/-16)
src/location_service/com/ubuntu/location/service/runtime.cpp (+109/-0)
src/location_service/com/ubuntu/location/service/runtime.h (+90/-0)
src/location_service/com/ubuntu/location/service/runtime_tests.cpp (+1/-0)
src/location_service/com/ubuntu/location/service/session/skeleton.cpp (+21/-3)
src/location_service/com/ubuntu/location/service/trust_store_permission_manager.cpp (+1/-1)
src/location_service/com/ubuntu/location/time_based_update_policy.cpp (+4/-3)
src/location_service/com/ubuntu/location/time_since_boot.cpp (+140/-0)
src/location_service/com/ubuntu/location/time_since_boot.h (+35/-0)
tests/CMakeLists.txt (+5/-0)
tests/acceptance_tests.cpp (+114/-12)
tests/bug_1447110.cpp (+66/-0)
tests/delayed_service_test.cpp (+193/-0)
tests/engine_test.cpp (+4/-13)
tests/gps_provider_test.cpp (+119/-4)
tests/mock_event_receiver.h (+35/-0)
tests/position_test.cpp (+1/-1)
tests/remote_providerd_test.cpp (+1/-7)
tests/runtime_test.cpp (+118/-0)
tests/sntp_client_test.cpp (+104/-0)
tools/CMakeLists.txt (+1/-0)
tools/symbol_diff.in (+70/-0)
To merge this branch: bzr merge lp:~thomas-voss/location-service/cherry-pick-fwd
Reviewer Review Type Date Requested Status
Alberto Mardegan (community) Approve
Review via email: mp+277219@code.launchpad.net

Commit message

[ Alberto Mardegan ]
* Make sure that injected time is given in milliseconds
[ Thomas Voß ]
* Cherry-pick rev. 196 and 199 from lp:location-service. The changes
  got accidentally removed by merging the outstanding documentation
  branch.
* Handle responses of clients to updates asynchronously. Rely on
  dummy::ConnectivityManager as harvesting is disabled anyway. (LP:
  #1462664, #1387643)
[ Thomas Voß ]
* Add documentation for debugging, hacking and debugging the location
  service. Pull manual testing instructions over from the wiki. Add
  tools for formatting the source.
[ thomas-voss ]
* Add documentation for debugging, hacking and debugging the location
  service. Pull manual testing instructions over from the wiki. Add
  tools for formatting the source.

Description of the change

[ Alberto Mardegan ]
* Make sure that injected time is given in milliseconds
[ Thomas Voß ]
* Cherry-pick rev. 196 and 199 from lp:location-service. The changes
  got accidentally removed by merging the outstanding documentation
  branch.
* Handle responses of clients to updates asynchronously. Rely on
  dummy::ConnectivityManager as harvesting is disabled anyway. (LP:
  #1462664, #1387643)
[ Thomas Voß ]
* Add documentation for debugging, hacking and debugging the location
  service. Pull manual testing instructions over from the wiki. Add
  tools for formatting the source.
[ thomas-voss ]
* Add documentation for debugging, hacking and debugging the location
  service. Pull manual testing instructions over from the wiki. Add
  tools for formatting the source.

To post a comment you must log in.
Revision history for this message
Alberto Mardegan (mardy) wrote :

LGTM

review: Approve
218. By Thomas Voß

Adjust default timeout for downloading GPS XTRA data.

219. By Thomas Voß

[ Alberto Mardegan ]
* Set debian source format to "3.0 (native)"
[ Scott Sweeny ]
* Allow providers to register themselves asynchronously (LP: #1415029)
* Account for changes in trust-store w.r.t. assembling the description
  of a trust prompt.
* Fix settings not being applied correctly.
* Ensure that event connections are cleaned up on destruction. (LP:
  #1480877)
[ Alberto Mardegan ]
* Send last known position on session start
[ CI Train Bot ]
* New rebuild forced.
[ Thomas Voß ]
* Factor out service::Runtime from daemon.cpp into its own .h/.cpp
  pair of files. Add test cases around correct operation of
  service::Runtime. added:
  src/location_service/com/ubuntu/location/service/runtime.cpp
  src/location_service/com/ubuntu/location/service/runtime.h
  tests/runtime_test.cpp
[ thomas-voss ]
* Factor out service::Runtime from daemon.cpp into its own .h/.cpp
  pair of files. Add test cases around correct operation of
  service::Runtime. added:
  src/location_service/com/ubuntu/location/service/runtime.cpp
  src/location_service/com/ubuntu/location/service/runtime.h
  tests/runtime_test.cpp

220. By Thomas Voß

* Add SntpClient for querying reference time information.
* Remove explicit option to disable satellite-based positioning
  services.

221. By Thomas Voß

Resync to trunk.

222. By Thomas Voß

Log to stderr by default, relying on upstart to rotate logs
appropriately. (LP: #1447110)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory '3rd-party'
2=== added directory '3rd-party/boost'
3=== added directory '3rd-party/boost/core'
4=== added file '3rd-party/boost/core/scoped_enum.hpp'
5--- 3rd-party/boost/core/scoped_enum.hpp 1970-01-01 00:00:00 +0000
6+++ 3rd-party/boost/core/scoped_enum.hpp 2016-04-01 06:55:25 +0000
7@@ -0,0 +1,192 @@
8+// scoped_enum.hpp ---------------------------------------------------------//
9+
10+// Copyright Beman Dawes, 2009
11+// Copyright (C) 2011-2012 Vicente J. Botet Escriba
12+// Copyright (C) 2012 Anthony Williams
13+
14+// Distributed under the Boost Software License, Version 1.0.
15+// See http://www.boost.org/LICENSE_1_0.txt
16+
17+#ifndef BOOST_CORE_SCOPED_ENUM_HPP
18+#define BOOST_CORE_SCOPED_ENUM_HPP
19+
20+#include <boost/config.hpp>
21+
22+#ifdef BOOST_HAS_PRAGMA_ONCE
23+#pragma once
24+#endif
25+
26+namespace boost
27+{
28+
29+#ifdef BOOST_NO_CXX11_SCOPED_ENUMS
30+
31+ /**
32+ * Meta-function to get the native enum type associated to an enum class or its emulation.
33+ */
34+ template <typename EnumType>
35+ struct native_type
36+ {
37+ /**
38+ * The member typedef type names the native enum type associated to the scoped enum,
39+ * which is it self if the compiler supports scoped enums or EnumType::enum_type if it is an emulated scoped enum.
40+ */
41+ typedef typename EnumType::enum_type type;
42+ };
43+
44+ /**
45+ * Casts a scoped enum to its underlying type.
46+ *
47+ * This function is useful when working with scoped enum classes, which doens't implicitly convert to the underlying type.
48+ * @param v A scoped enum.
49+ * @returns The underlying type.
50+ * @throws No-throws.
51+ */
52+ template <typename UnderlyingType, typename EnumType>
53+ UnderlyingType underlying_cast(EnumType v)
54+ {
55+ return v.get_underlying_value_();
56+ }
57+
58+ /**
59+ * Casts a scoped enum to its native enum type.
60+ *
61+ * This function is useful to make programs portable when the scoped enum emulation can not be use where native enums can.
62+ *
63+ * EnumType the scoped enum type
64+ *
65+ * @param v A scoped enum.
66+ * @returns The native enum value.
67+ * @throws No-throws.
68+ */
69+ template <typename EnumType>
70+ inline
71+ typename EnumType::enum_type native_value(EnumType e)
72+ {
73+ return e.get_native_value_();
74+ }
75+
76+#else // BOOST_NO_CXX11_SCOPED_ENUMS
77+
78+ template <typename EnumType>
79+ struct native_type
80+ {
81+ typedef EnumType type;
82+ };
83+
84+ template <typename UnderlyingType, typename EnumType>
85+ UnderlyingType underlying_cast(EnumType v)
86+ {
87+ return static_cast<UnderlyingType>(v);
88+ }
89+
90+ template <typename EnumType>
91+ inline
92+ EnumType native_value(EnumType e)
93+ {
94+ return e;
95+ }
96+
97+#endif // BOOST_NO_CXX11_SCOPED_ENUMS
98+}
99+
100+
101+#ifdef BOOST_NO_CXX11_SCOPED_ENUMS
102+
103+#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
104+
105+#define BOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR \
106+ explicit operator underlying_type() const BOOST_NOEXCEPT { return get_underlying_value_(); }
107+
108+#else
109+
110+#define BOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR
111+
112+#endif
113+
114+/**
115+ * Start a declaration of a scoped enum.
116+ *
117+ * @param EnumType The new scoped enum.
118+ * @param UnderlyingType The underlying type.
119+ */
120+#define BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType, UnderlyingType) \
121+ struct EnumType { \
122+ typedef void is_boost_scoped_enum_tag; \
123+ typedef UnderlyingType underlying_type; \
124+ EnumType() BOOST_NOEXCEPT {} \
125+ explicit EnumType(underlying_type v) BOOST_NOEXCEPT : v_(v) {} \
126+ underlying_type get_underlying_value_() const BOOST_NOEXCEPT { return v_; } \
127+ BOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR \
128+ private: \
129+ underlying_type v_; \
130+ typedef EnumType self_type; \
131+ public: \
132+ enum enum_type
133+
134+#define BOOST_SCOPED_ENUM_DECLARE_END2() \
135+ enum_type get_native_value_() const BOOST_NOEXCEPT { return enum_type(v_); } \
136+ friend bool operator ==(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)==enum_type(rhs.v_); } \
137+ friend bool operator ==(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)==rhs; } \
138+ friend bool operator ==(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs==enum_type(rhs.v_); } \
139+ friend bool operator !=(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)!=enum_type(rhs.v_); } \
140+ friend bool operator !=(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)!=rhs; } \
141+ friend bool operator !=(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs!=enum_type(rhs.v_); } \
142+ friend bool operator <(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)<enum_type(rhs.v_); } \
143+ friend bool operator <(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)<rhs; } \
144+ friend bool operator <(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs<enum_type(rhs.v_); } \
145+ friend bool operator <=(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)<=enum_type(rhs.v_); } \
146+ friend bool operator <=(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)<=rhs; } \
147+ friend bool operator <=(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs<=enum_type(rhs.v_); } \
148+ friend bool operator >(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>enum_type(rhs.v_); } \
149+ friend bool operator >(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>rhs; } \
150+ friend bool operator >(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs>enum_type(rhs.v_); } \
151+ friend bool operator >=(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>=enum_type(rhs.v_); } \
152+ friend bool operator >=(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>=rhs; } \
153+ friend bool operator >=(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs>=enum_type(rhs.v_); } \
154+ };
155+
156+#define BOOST_SCOPED_ENUM_DECLARE_END(EnumType) \
157+ ; \
158+ EnumType(enum_type v) BOOST_NOEXCEPT : v_(v) {} \
159+ BOOST_SCOPED_ENUM_DECLARE_END2()
160+
161+/**
162+ * Starts a declaration of a scoped enum with the default int underlying type.
163+ *
164+ * @param EnumType The new scoped enum.
165+ */
166+#define BOOST_SCOPED_ENUM_DECLARE_BEGIN(EnumType) \
167+ BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType,int)
168+
169+/**
170+ * Name of the native enum type.
171+ *
172+ * @param EnumType The new scoped enum.
173+ */
174+#define BOOST_SCOPED_ENUM_NATIVE(EnumType) EnumType::enum_type
175+/**
176+ * Forward declares an scoped enum.
177+ *
178+ * @param EnumType The scoped enum.
179+ */
180+#define BOOST_SCOPED_ENUM_FORWARD_DECLARE(EnumType) struct EnumType
181+
182+#else // BOOST_NO_CXX11_SCOPED_ENUMS
183+
184+#define BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType,UnderlyingType) enum class EnumType : UnderlyingType
185+#define BOOST_SCOPED_ENUM_DECLARE_BEGIN(EnumType) enum class EnumType
186+#define BOOST_SCOPED_ENUM_DECLARE_END2()
187+#define BOOST_SCOPED_ENUM_DECLARE_END(EnumType) ;
188+
189+#define BOOST_SCOPED_ENUM_NATIVE(EnumType) EnumType
190+#define BOOST_SCOPED_ENUM_FORWARD_DECLARE(EnumType) enum class EnumType
191+
192+#endif // BOOST_NO_CXX11_SCOPED_ENUMS
193+
194+// Deprecated macros
195+#define BOOST_SCOPED_ENUM_START(name) BOOST_SCOPED_ENUM_DECLARE_BEGIN(name)
196+#define BOOST_SCOPED_ENUM_END BOOST_SCOPED_ENUM_DECLARE_END2()
197+#define BOOST_SCOPED_ENUM(name) BOOST_SCOPED_ENUM_NATIVE(name)
198+
199+#endif // BOOST_CORE_SCOPED_ENUM_HPP
200
201=== added directory '3rd-party/boost/endian'
202=== added file '3rd-party/boost/endian/arithmetic.hpp'
203--- 3rd-party/boost/endian/arithmetic.hpp 1970-01-01 00:00:00 +0000
204+++ 3rd-party/boost/endian/arithmetic.hpp 2016-04-01 06:55:25 +0000
205@@ -0,0 +1,413 @@
206+// boost/endian/arithmetic.hpp -------------------------------------------------------//
207+
208+// (C) Copyright Darin Adler 2000
209+// (C) Copyright Beman Dawes 2006, 2009, 2014
210+
211+// Distributed under the Boost Software License, Version 1.0.
212+// See http://www.boost.org/LICENSE_1_0.txt
213+
214+// See library home page at http://www.boost.org/libs/endian
215+
216+//--------------------------------------------------------------------------------------//
217+
218+// Original design developed by Darin Adler based on classes developed by Mark
219+// Borgerding. Four original class templates were combined into a single endian
220+// class template by Beman Dawes, who also added the unrolled_byte_loops sign
221+// partial specialization to correctly extend the sign when cover integer size
222+// differs from endian representation size.
223+
224+// TODO: When a compiler supporting constexpr becomes available, try possible uses.
225+
226+#ifndef BOOST_ENDIAN_ARITHMETIC_HPP
227+#define BOOST_ENDIAN_ARITHMETIC_HPP
228+
229+#if defined(_MSC_VER)
230+# pragma warning(push)
231+# pragma warning(disable:4365) // conversion ... signed/unsigned mismatch
232+#endif
233+
234+#ifdef BOOST_ENDIAN_LOG
235+# include <iostream>
236+#endif
237+
238+#if defined(__BORLANDC__) || defined( __CODEGEARC__)
239+# pragma pack(push, 1)
240+#endif
241+
242+#include <boost/config.hpp>
243+#include <boost/predef/detail/endian_compat.h>
244+#include <boost/endian/conversion.hpp>
245+#include <boost/endian/buffers.hpp>
246+#define BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
247+#include <boost/endian/detail/cover_operators.hpp>
248+#undef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
249+#include <boost/type_traits/is_signed.hpp>
250+#include <boost/cstdint.hpp>
251+#include <boost/static_assert.hpp>
252+#include <boost/core/scoped_enum.hpp>
253+#include <iosfwd>
254+#include <climits>
255+
256+# if CHAR_BIT != 8
257+# error Platforms with CHAR_BIT != 8 are not supported
258+# endif
259+
260+# ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
261+# define BOOST_ENDIAN_DEFAULT_CONSTRUCT {} // C++03
262+# else
263+# define BOOST_ENDIAN_DEFAULT_CONSTRUCT = default; // C++0x
264+# endif
265+
266+# if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && defined(BOOST_ENDIAN_FORCE_PODNESS)
267+# define BOOST_ENDIAN_NO_CTORS
268+# endif
269+
270+# ifndef BOOST_ENDIAN_EXPLICIT_CTORS
271+# define BOOST_ENDIAN_EXPLICIT_OPT
272+# else
273+# define BOOST_ENDIAN_EXPLICIT_OPT explicit
274+# endif
275+
276+//---------------------------------- synopsis ----------------------------------------//
277+
278+namespace boost
279+{
280+namespace endian
281+{
282+
283+ template <BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits,
284+ BOOST_SCOPED_ENUM(align) A = align::no>
285+ class endian_arithmetic;
286+
287+ // big endian signed integer aligned types
288+ typedef endian_arithmetic<order::big, int8_t, 8, align::yes> big_int8_at;
289+ typedef endian_arithmetic<order::big, int16_t, 16, align::yes> big_int16_at;
290+ typedef endian_arithmetic<order::big, int32_t, 32, align::yes> big_int32_at;
291+ typedef endian_arithmetic<order::big, int64_t, 64, align::yes> big_int64_at;
292+
293+ // big endian unsigned integer aligned types
294+ typedef endian_arithmetic<order::big, uint8_t, 8, align::yes> big_uint8_at;
295+ typedef endian_arithmetic<order::big, uint16_t, 16, align::yes> big_uint16_at;
296+ typedef endian_arithmetic<order::big, uint32_t, 32, align::yes> big_uint32_at;
297+ typedef endian_arithmetic<order::big, uint64_t, 64, align::yes> big_uint64_at;
298+
299+ // little endian signed integer aligned types
300+ typedef endian_arithmetic<order::little, int8_t, 8, align::yes> little_int8_at;
301+ typedef endian_arithmetic<order::little, int16_t, 16, align::yes> little_int16_at;
302+ typedef endian_arithmetic<order::little, int32_t, 32, align::yes> little_int32_at;
303+ typedef endian_arithmetic<order::little, int64_t, 64, align::yes> little_int64_at;
304+
305+ // little endian unsigned integer aligned types
306+ typedef endian_arithmetic<order::little, uint8_t, 8, align::yes> little_uint8_at;
307+ typedef endian_arithmetic<order::little, uint16_t, 16, align::yes> little_uint16_at;
308+ typedef endian_arithmetic<order::little, uint32_t, 32, align::yes> little_uint32_at;
309+ typedef endian_arithmetic<order::little, uint64_t, 64, align::yes> little_uint64_at;
310+
311+ // aligned native endian typedefs are not provided because
312+ // <cstdint> types are superior for this use case
313+
314+ // big endian signed integer unaligned types
315+ typedef endian_arithmetic<order::big, int_least8_t, 8> big_int8_t;
316+ typedef endian_arithmetic<order::big, int_least16_t, 16> big_int16_t;
317+ typedef endian_arithmetic<order::big, int_least32_t, 24> big_int24_t;
318+ typedef endian_arithmetic<order::big, int_least32_t, 32> big_int32_t;
319+ typedef endian_arithmetic<order::big, int_least64_t, 40> big_int40_t;
320+ typedef endian_arithmetic<order::big, int_least64_t, 48> big_int48_t;
321+ typedef endian_arithmetic<order::big, int_least64_t, 56> big_int56_t;
322+ typedef endian_arithmetic<order::big, int_least64_t, 64> big_int64_t;
323+
324+ // big endian unsigned integer unaligned types
325+ typedef endian_arithmetic<order::big, uint_least8_t, 8> big_uint8_t;
326+ typedef endian_arithmetic<order::big, uint_least16_t, 16> big_uint16_t;
327+ typedef endian_arithmetic<order::big, uint_least32_t, 24> big_uint24_t;
328+ typedef endian_arithmetic<order::big, uint_least32_t, 32> big_uint32_t;
329+ typedef endian_arithmetic<order::big, uint_least64_t, 40> big_uint40_t;
330+ typedef endian_arithmetic<order::big, uint_least64_t, 48> big_uint48_t;
331+ typedef endian_arithmetic<order::big, uint_least64_t, 56> big_uint56_t;
332+ typedef endian_arithmetic<order::big, uint_least64_t, 64> big_uint64_t;
333+
334+ // little endian signed integer unaligned types
335+ typedef endian_arithmetic<order::little, int_least8_t, 8> little_int8_t;
336+ typedef endian_arithmetic<order::little, int_least16_t, 16> little_int16_t;
337+ typedef endian_arithmetic<order::little, int_least32_t, 24> little_int24_t;
338+ typedef endian_arithmetic<order::little, int_least32_t, 32> little_int32_t;
339+ typedef endian_arithmetic<order::little, int_least64_t, 40> little_int40_t;
340+ typedef endian_arithmetic<order::little, int_least64_t, 48> little_int48_t;
341+ typedef endian_arithmetic<order::little, int_least64_t, 56> little_int56_t;
342+ typedef endian_arithmetic<order::little, int_least64_t, 64> little_int64_t;
343+
344+ // little endian unsigned integer unaligned types
345+ typedef endian_arithmetic<order::little, uint_least8_t, 8> little_uint8_t;
346+ typedef endian_arithmetic<order::little, uint_least16_t, 16> little_uint16_t;
347+ typedef endian_arithmetic<order::little, uint_least32_t, 24> little_uint24_t;
348+ typedef endian_arithmetic<order::little, uint_least32_t, 32> little_uint32_t;
349+ typedef endian_arithmetic<order::little, uint_least64_t, 40> little_uint40_t;
350+ typedef endian_arithmetic<order::little, uint_least64_t, 48> little_uint48_t;
351+ typedef endian_arithmetic<order::little, uint_least64_t, 56> little_uint56_t;
352+ typedef endian_arithmetic<order::little, uint_least64_t, 64> little_uint64_t;
353+
354+# ifdef BOOST_BIG_ENDIAN
355+ // native endian signed integer unaligned types
356+ typedef big_int8_t native_int8_t;
357+ typedef big_int16_t native_int16_t;
358+ typedef big_int24_t native_int24_t;
359+ typedef big_int32_t native_int32_t;
360+ typedef big_int40_t native_int40_t;
361+ typedef big_int48_t native_int48_t;
362+ typedef big_int56_t native_int56_t;
363+ typedef big_int64_t native_int64_t;
364+
365+ // native endian unsigned integer unaligned types
366+ typedef big_uint8_t native_uint8_t;
367+ typedef big_uint16_t native_uint16_t;
368+ typedef big_uint24_t native_uint24_t;
369+ typedef big_uint32_t native_uint32_t;
370+ typedef big_uint40_t native_uint40_t;
371+ typedef big_uint48_t native_uint48_t;
372+ typedef big_uint56_t native_uint56_t;
373+ typedef big_uint64_t native_uint64_t;
374+# else
375+ // native endian signed integer unaligned types
376+ typedef little_int8_t native_int8_t;
377+ typedef little_int16_t native_int16_t;
378+ typedef little_int24_t native_int24_t;
379+ typedef little_int32_t native_int32_t;
380+ typedef little_int40_t native_int40_t;
381+ typedef little_int48_t native_int48_t;
382+ typedef little_int56_t native_int56_t;
383+ typedef little_int64_t native_int64_t;
384+
385+ // native endian unsigned integer unaligned types
386+ typedef little_uint8_t native_uint8_t;
387+ typedef little_uint16_t native_uint16_t;
388+ typedef little_uint24_t native_uint24_t;
389+ typedef little_uint32_t native_uint32_t;
390+ typedef little_uint40_t native_uint40_t;
391+ typedef little_uint48_t native_uint48_t;
392+ typedef little_uint56_t native_uint56_t;
393+ typedef little_uint64_t native_uint64_t;
394+# endif
395+
396+# ifdef BOOST_ENDIAN_DEPRECATED_NAMES
397+
398+ typedef order endianness;
399+ typedef align alignment;
400+
401+# ifndef BOOST_NO_CXX11_TEMPLATE_ALIASES
402+ template <BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits,
403+ BOOST_SCOPED_ENUM(align) Align = align::no>
404+ using endian = endian_arithmetic<Order, T, n_bits, Align>;
405+# endif
406+
407+ // unaligned big endian signed integer types
408+ typedef endian_arithmetic< order::big, int_least8_t, 8 > big8_t;
409+ typedef endian_arithmetic< order::big, int_least16_t, 16 > big16_t;
410+ typedef endian_arithmetic< order::big, int_least32_t, 24 > big24_t;
411+ typedef endian_arithmetic< order::big, int_least32_t, 32 > big32_t;
412+ typedef endian_arithmetic< order::big, int_least64_t, 40 > big40_t;
413+ typedef endian_arithmetic< order::big, int_least64_t, 48 > big48_t;
414+ typedef endian_arithmetic< order::big, int_least64_t, 56 > big56_t;
415+ typedef endian_arithmetic< order::big, int_least64_t, 64 > big64_t;
416+
417+ // unaligned big endian_arithmetic unsigned integer types
418+ typedef endian_arithmetic< order::big, uint_least8_t, 8 > ubig8_t;
419+ typedef endian_arithmetic< order::big, uint_least16_t, 16 > ubig16_t;
420+ typedef endian_arithmetic< order::big, uint_least32_t, 24 > ubig24_t;
421+ typedef endian_arithmetic< order::big, uint_least32_t, 32 > ubig32_t;
422+ typedef endian_arithmetic< order::big, uint_least64_t, 40 > ubig40_t;
423+ typedef endian_arithmetic< order::big, uint_least64_t, 48 > ubig48_t;
424+ typedef endian_arithmetic< order::big, uint_least64_t, 56 > ubig56_t;
425+ typedef endian_arithmetic< order::big, uint_least64_t, 64 > ubig64_t;
426+
427+ // unaligned little endian_arithmetic signed integer types
428+ typedef endian_arithmetic< order::little, int_least8_t, 8 > little8_t;
429+ typedef endian_arithmetic< order::little, int_least16_t, 16 > little16_t;
430+ typedef endian_arithmetic< order::little, int_least32_t, 24 > little24_t;
431+ typedef endian_arithmetic< order::little, int_least32_t, 32 > little32_t;
432+ typedef endian_arithmetic< order::little, int_least64_t, 40 > little40_t;
433+ typedef endian_arithmetic< order::little, int_least64_t, 48 > little48_t;
434+ typedef endian_arithmetic< order::little, int_least64_t, 56 > little56_t;
435+ typedef endian_arithmetic< order::little, int_least64_t, 64 > little64_t;
436+
437+ // unaligned little endian_arithmetic unsigned integer types
438+ typedef endian_arithmetic< order::little, uint_least8_t, 8 > ulittle8_t;
439+ typedef endian_arithmetic< order::little, uint_least16_t, 16 > ulittle16_t;
440+ typedef endian_arithmetic< order::little, uint_least32_t, 24 > ulittle24_t;
441+ typedef endian_arithmetic< order::little, uint_least32_t, 32 > ulittle32_t;
442+ typedef endian_arithmetic< order::little, uint_least64_t, 40 > ulittle40_t;
443+ typedef endian_arithmetic< order::little, uint_least64_t, 48 > ulittle48_t;
444+ typedef endian_arithmetic< order::little, uint_least64_t, 56 > ulittle56_t;
445+ typedef endian_arithmetic< order::little, uint_least64_t, 64 > ulittle64_t;
446+
447+ // unaligned native endian_arithmetic signed integer types
448+ typedef endian_arithmetic< order::native, int_least8_t, 8 > native8_t;
449+ typedef endian_arithmetic< order::native, int_least16_t, 16 > native16_t;
450+ typedef endian_arithmetic< order::native, int_least32_t, 24 > native24_t;
451+ typedef endian_arithmetic< order::native, int_least32_t, 32 > native32_t;
452+ typedef endian_arithmetic< order::native, int_least64_t, 40 > native40_t;
453+ typedef endian_arithmetic< order::native, int_least64_t, 48 > native48_t;
454+ typedef endian_arithmetic< order::native, int_least64_t, 56 > native56_t;
455+ typedef endian_arithmetic< order::native, int_least64_t, 64 > native64_t;
456+
457+ // unaligned native endian_arithmetic unsigned integer types
458+ typedef endian_arithmetic< order::native, uint_least8_t, 8 > unative8_t;
459+ typedef endian_arithmetic< order::native, uint_least16_t, 16 > unative16_t;
460+ typedef endian_arithmetic< order::native, uint_least32_t, 24 > unative24_t;
461+ typedef endian_arithmetic< order::native, uint_least32_t, 32 > unative32_t;
462+ typedef endian_arithmetic< order::native, uint_least64_t, 40 > unative40_t;
463+ typedef endian_arithmetic< order::native, uint_least64_t, 48 > unative48_t;
464+ typedef endian_arithmetic< order::native, uint_least64_t, 56 > unative56_t;
465+ typedef endian_arithmetic< order::native, uint_least64_t, 64 > unative64_t;
466+
467+ // aligned native endian_arithmetic typedefs are not provided because
468+ // <cstdint> types are superior for this use case
469+
470+ typedef endian_arithmetic< order::big, int16_t, 16, align::yes > aligned_big16_t;
471+ typedef endian_arithmetic< order::big, uint16_t, 16, align::yes > aligned_ubig16_t;
472+ typedef endian_arithmetic< order::little, int16_t, 16, align::yes > aligned_little16_t;
473+ typedef endian_arithmetic< order::little, uint16_t, 16, align::yes > aligned_ulittle16_t;
474+
475+ typedef endian_arithmetic< order::big, int32_t, 32, align::yes > aligned_big32_t;
476+ typedef endian_arithmetic< order::big, uint32_t, 32, align::yes > aligned_ubig32_t;
477+ typedef endian_arithmetic< order::little, int32_t, 32, align::yes > aligned_little32_t;
478+ typedef endian_arithmetic< order::little, uint32_t, 32, align::yes > aligned_ulittle32_t;
479+
480+ typedef endian_arithmetic< order::big, int64_t, 64, align::yes > aligned_big64_t;
481+ typedef endian_arithmetic< order::big, uint64_t, 64, align::yes > aligned_ubig64_t;
482+ typedef endian_arithmetic< order::little, int64_t, 64, align::yes > aligned_little64_t;
483+ typedef endian_arithmetic< order::little, uint64_t, 64, align::yes > aligned_ulittle64_t;
484+
485+# endif
486+
487+//---------------------------------- end synopsis ------------------------------------//
488+
489+// endian class template specializations ---------------------------------------------//
490+
491+ // Specializations that represent unaligned bytes.
492+ // Taking an integer type as a parameter provides a nice way to pass both
493+ // the size and signness of the desired integer and get the appropriate
494+ // corresponding integer type for the interface.
495+
496+ // unaligned integer big endian specialization
497+ template <typename T, std::size_t n_bits>
498+ class endian_arithmetic< order::big, T, n_bits, align::no >
499+ : public endian_buffer< order::big, T, n_bits, align::no >,
500+ cover_operators<endian_arithmetic<order::big, T, n_bits>, T>
501+ {
502+ BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
503+ public:
504+ typedef T value_type;
505+# ifndef BOOST_ENDIAN_NO_CTORS
506+ endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT
507+ BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic(T val) BOOST_NOEXCEPT
508+ {
509+# ifdef BOOST_ENDIAN_LOG
510+ if ( endian_log )
511+ std::cout << "big, unaligned, " << n_bits << "-bits, construct(" << val << ")\n";
512+# endif
513+ detail::store_big_endian<T, n_bits/8>(this->m_value, val);
514+ }
515+# endif
516+ endian_arithmetic& operator=(T val) BOOST_NOEXCEPT
517+ { detail::store_big_endian<T, n_bits/8>(this->m_value, val); return *this; }
518+ operator value_type() const BOOST_NOEXCEPT { return this->value(); }
519+ };
520+
521+ // unaligned little endian specialization
522+ template <typename T, std::size_t n_bits>
523+ class endian_arithmetic< order::little, T, n_bits, align::no >
524+ : public endian_buffer< order::little, T, n_bits, align::no >,
525+ cover_operators< endian_arithmetic< order::little, T, n_bits >, T >
526+ {
527+ BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
528+ public:
529+ typedef T value_type;
530+# ifndef BOOST_ENDIAN_NO_CTORS
531+ endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT
532+ BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic(T val) BOOST_NOEXCEPT
533+ {
534+# ifdef BOOST_ENDIAN_LOG
535+ if ( endian_log )
536+ std::cout << "little, unaligned, " << n_bits << "-bits, construct(" << val << ")\n";
537+# endif
538+ detail::store_little_endian<T, n_bits/8>(this->m_value, val);
539+ }
540+# endif
541+ endian_arithmetic& operator=(T val) BOOST_NOEXCEPT
542+ { detail::store_little_endian<T, n_bits/8>(this->m_value, val); return *this; }
543+ operator value_type() const BOOST_NOEXCEPT { return this->value(); }
544+ };
545+
546+ // align::yes specializations; only n_bits == 16/32/64 supported
547+
548+ // aligned big endian specialization
549+ template <typename T, std::size_t n_bits>
550+ class endian_arithmetic<order::big, T, n_bits, align::yes>
551+ : public endian_buffer< order::big, T, n_bits, align::yes >,
552+ cover_operators<endian_arithmetic<order::big, T, n_bits, align::yes>, T>
553+ {
554+ BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
555+ BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
556+ public:
557+ typedef T value_type;
558+# ifndef BOOST_ENDIAN_NO_CTORS
559+ endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT
560+ BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic(T val) BOOST_NOEXCEPT
561+ {
562+# ifdef BOOST_ENDIAN_LOG
563+ if ( endian_log )
564+ std::cout << "big, aligned, " << n_bits << "-bits, construct(" << val << ")\n";
565+# endif
566+ this->m_value = ::boost::endian::native_to_big(val);
567+ }
568+
569+# endif
570+ endian_arithmetic& operator=(T val) BOOST_NOEXCEPT
571+ {
572+ this->m_value = ::boost::endian::native_to_big(val);
573+ return *this;
574+ }
575+ operator value_type() const BOOST_NOEXCEPT { return this->value(); }
576+ };
577+
578+ // aligned little endian specialization
579+ template <typename T, std::size_t n_bits>
580+ class endian_arithmetic<order::little, T, n_bits, align::yes>
581+ : public endian_buffer< order::little, T, n_bits, align::yes >,
582+ cover_operators<endian_arithmetic<order::little, T, n_bits, align::yes>, T>
583+ {
584+ BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
585+ BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
586+ public:
587+ typedef T value_type;
588+# ifndef BOOST_ENDIAN_NO_CTORS
589+ endian_arithmetic() BOOST_ENDIAN_DEFAULT_CONSTRUCT
590+ BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic(T val) BOOST_NOEXCEPT
591+ {
592+# ifdef BOOST_ENDIAN_LOG
593+ if ( endian_log )
594+ std::cout << "little, aligned, " << n_bits << "-bits, construct(" << val << ")\n";
595+# endif
596+ this->m_value = ::boost::endian::native_to_little(val);
597+ }
598+# endif
599+ endian_arithmetic& operator=(T val) BOOST_NOEXCEPT
600+ {
601+ this->m_value = ::boost::endian::native_to_little(val);
602+ return *this;
603+ }
604+ operator value_type() const BOOST_NOEXCEPT { return this->value(); }
605+ };
606+
607+} // namespace endian
608+} // namespace boost
609+
610+#if defined(__BORLANDC__) || defined( __CODEGEARC__)
611+# pragma pack(pop)
612+#endif
613+
614+#if defined(_MSC_VER)
615+# pragma warning(pop)
616+#endif
617+
618+#endif // BOOST_ENDIAN_ARITHMETIC_HPP
619
620=== added file '3rd-party/boost/endian/buffers.hpp'
621--- 3rd-party/boost/endian/buffers.hpp 1970-01-01 00:00:00 +0000
622+++ 3rd-party/boost/endian/buffers.hpp 2016-04-01 06:55:25 +0000
623@@ -0,0 +1,515 @@
624+// boost/endian/buffers.hpp ----------------------------------------------------------//
625+
626+// (C) Copyright Darin Adler 2000
627+// (C) Copyright Beman Dawes 2006, 2009, 2014
628+
629+// Distributed under the Boost Software License, Version 1.0.
630+// See http://www.boost.org/LICENSE_1_0.txt
631+
632+// See library home page at http://www.boost.org/libs/endian
633+
634+//--------------------------------------------------------------------------------------//
635+
636+// Original design developed by Darin Adler based on classes developed by Mark
637+// Borgerding. Four original class templates were combined into a single endian
638+// class template by Beman Dawes, who also added the unrolled_byte_loops sign
639+// partial specialization to correctly extend the sign when cover integer size
640+// differs from endian representation size.
641+
642+// TODO: When a compiler supporting constexpr becomes available, try possible uses.
643+
644+#ifndef BOOST_ENDIAN_BUFFERS_HPP
645+#define BOOST_ENDIAN_BUFFERS_HPP
646+
647+#if defined(_MSC_VER)
648+# pragma warning(push)
649+# pragma warning(disable:4365) // conversion ... signed/unsigned mismatch
650+#endif
651+
652+#ifdef BOOST_ENDIAN_LOG
653+# include <iostream>
654+#endif
655+
656+#if defined(__BORLANDC__) || defined( __CODEGEARC__)
657+# pragma pack(push, 1)
658+#endif
659+
660+#include <boost/config.hpp>
661+#include <boost/predef/detail/endian_compat.h>
662+#include <boost/endian/conversion.hpp>
663+#include <boost/type_traits/is_signed.hpp>
664+#include <boost/cstdint.hpp>
665+#include <boost/static_assert.hpp>
666+#include <boost/core/scoped_enum.hpp>
667+#include <iosfwd>
668+#include <climits>
669+
670+# if CHAR_BIT != 8
671+# error Platforms with CHAR_BIT != 8 are not supported
672+# endif
673+
674+# ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
675+# define BOOST_ENDIAN_DEFAULT_CONSTRUCT {} // C++03
676+# else
677+# define BOOST_ENDIAN_DEFAULT_CONSTRUCT = default; // C++0x
678+# endif
679+
680+# if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && defined(BOOST_ENDIAN_FORCE_PODNESS)
681+# define BOOST_ENDIAN_NO_CTORS
682+# endif
683+
684+//---------------------------------- synopsis ----------------------------------------//
685+
686+namespace boost
687+{
688+namespace endian
689+{
690+
691+ BOOST_SCOPED_ENUM_START(align)
692+ {no, yes
693+# ifdef BOOST_ENDIAN_DEPRECATED_NAMES
694+ , unaligned = no, aligned = yes
695+# endif
696+ }; BOOST_SCOPED_ENUM_END
697+
698+ template <BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits,
699+ BOOST_SCOPED_ENUM(align) A = align::no>
700+ class endian_buffer;
701+
702+ // aligned big endian signed integer buffers
703+ typedef endian_buffer<order::big, int8_t, 8, align::yes> big_int8_buf_at;
704+ typedef endian_buffer<order::big, int16_t, 16, align::yes> big_int16_buf_at;
705+ typedef endian_buffer<order::big, int32_t, 32, align::yes> big_int32_buf_at;
706+ typedef endian_buffer<order::big, int64_t, 64, align::yes> big_int64_buf_at;
707+
708+ // aligned big endian unsigned integer buffers
709+ typedef endian_buffer<order::big, uint8_t, 8, align::yes> big_uint8_buf_at;
710+ typedef endian_buffer<order::big, uint16_t, 16, align::yes> big_uint16_buf_at;
711+ typedef endian_buffer<order::big, uint32_t, 32, align::yes> big_uint32_buf_at;
712+ typedef endian_buffer<order::big, uint64_t, 64, align::yes> big_uint64_buf_at;
713+
714+ // aligned little endian signed integer buffers
715+ typedef endian_buffer<order::little, int8_t, 8, align::yes> little_int8_buf_at;
716+ typedef endian_buffer<order::little, int16_t, 16, align::yes> little_int16_buf_at;
717+ typedef endian_buffer<order::little, int32_t, 32, align::yes> little_int32_buf_at;
718+ typedef endian_buffer<order::little, int64_t, 64, align::yes> little_int64_buf_at;
719+
720+ // aligned little endian unsigned integer buffers
721+ typedef endian_buffer<order::little, uint8_t, 8, align::yes> little_uint8_buf_at;
722+ typedef endian_buffer<order::little, uint16_t, 16, align::yes> little_uint16_buf_at;
723+ typedef endian_buffer<order::little, uint32_t, 32, align::yes> little_uint32_buf_at;
724+ typedef endian_buffer<order::little, uint64_t, 64, align::yes> little_uint64_buf_at;
725+
726+ // aligned native endian typedefs are not provided because
727+ // <cstdint> types are superior for this use case
728+
729+ // unaligned big endian signed integer buffers
730+ typedef endian_buffer<order::big, int_least8_t, 8> big_int8_buf_t;
731+ typedef endian_buffer<order::big, int_least16_t, 16> big_int16_buf_t;
732+ typedef endian_buffer<order::big, int_least32_t, 24> big_int24_buf_t;
733+ typedef endian_buffer<order::big, int_least32_t, 32> big_int32_buf_t;
734+ typedef endian_buffer<order::big, int_least64_t, 40> big_int40_buf_t;
735+ typedef endian_buffer<order::big, int_least64_t, 48> big_int48_buf_t;
736+ typedef endian_buffer<order::big, int_least64_t, 56> big_int56_buf_t;
737+ typedef endian_buffer<order::big, int_least64_t, 64> big_int64_buf_t;
738+
739+ // unaligned big endian unsigned integer buffers
740+ typedef endian_buffer<order::big, uint_least8_t, 8> big_uint8_buf_t;
741+ typedef endian_buffer<order::big, uint_least16_t, 16> big_uint16_buf_t;
742+ typedef endian_buffer<order::big, uint_least32_t, 24> big_uint24_buf_t;
743+ typedef endian_buffer<order::big, uint_least32_t, 32> big_uint32_buf_t;
744+ typedef endian_buffer<order::big, uint_least64_t, 40> big_uint40_buf_t;
745+ typedef endian_buffer<order::big, uint_least64_t, 48> big_uint48_buf_t;
746+ typedef endian_buffer<order::big, uint_least64_t, 56> big_uint56_buf_t;
747+ typedef endian_buffer<order::big, uint_least64_t, 64> big_uint64_buf_t;
748+
749+ // unaligned little endian signed integer buffers
750+ typedef endian_buffer<order::little, int_least8_t, 8> little_int8_buf_t;
751+ typedef endian_buffer<order::little, int_least16_t, 16> little_int16_buf_t;
752+ typedef endian_buffer<order::little, int_least32_t, 24> little_int24_buf_t;
753+ typedef endian_buffer<order::little, int_least32_t, 32> little_int32_buf_t;
754+ typedef endian_buffer<order::little, int_least64_t, 40> little_int40_buf_t;
755+ typedef endian_buffer<order::little, int_least64_t, 48> little_int48_buf_t;
756+ typedef endian_buffer<order::little, int_least64_t, 56> little_int56_buf_t;
757+ typedef endian_buffer<order::little, int_least64_t, 64> little_int64_buf_t;
758+
759+ // unaligned little endian unsigned integer buffers
760+ typedef endian_buffer<order::little, uint_least8_t, 8> little_uint8_buf_t;
761+ typedef endian_buffer<order::little, uint_least16_t, 16> little_uint16_buf_t;
762+ typedef endian_buffer<order::little, uint_least32_t, 24> little_uint24_buf_t;
763+ typedef endian_buffer<order::little, uint_least32_t, 32> little_uint32_buf_t;
764+ typedef endian_buffer<order::little, uint_least64_t, 40> little_uint40_buf_t;
765+ typedef endian_buffer<order::little, uint_least64_t, 48> little_uint48_buf_t;
766+ typedef endian_buffer<order::little, uint_least64_t, 56> little_uint56_buf_t;
767+ typedef endian_buffer<order::little, uint_least64_t, 64> little_uint64_buf_t;
768+
769+# ifdef BOOST_BIG_ENDIAN
770+ // unaligned native endian signed integer buffers
771+ typedef big_int8_buf_t native_int8_buf_t;
772+ typedef big_int16_buf_t native_int16_buf_t;
773+ typedef big_int24_buf_t native_int24_buf_t;
774+ typedef big_int32_buf_t native_int32_buf_t;
775+ typedef big_int40_buf_t native_int40_buf_t;
776+ typedef big_int48_buf_t native_int48_buf_t;
777+ typedef big_int56_buf_t native_int56_buf_t;
778+ typedef big_int64_buf_t native_int64_buf_t;
779+
780+ // unaligned native endian unsigned integer buffers
781+ typedef big_uint8_buf_t native_uint8_buf_t;
782+ typedef big_uint16_buf_t native_uint16_buf_t;
783+ typedef big_uint24_buf_t native_uint24_buf_t;
784+ typedef big_uint32_buf_t native_uint32_buf_t;
785+ typedef big_uint40_buf_t native_uint40_buf_t;
786+ typedef big_uint48_buf_t native_uint48_buf_t;
787+ typedef big_uint56_buf_t native_uint56_buf_t;
788+ typedef big_uint64_buf_t native_uint64_buf_t;
789+# else
790+ // unaligned native endian signed integer buffers
791+ typedef little_int8_buf_t native_int8_buf_t;
792+ typedef little_int16_buf_t native_int16_buf_t;
793+ typedef little_int24_buf_t native_int24_buf_t;
794+ typedef little_int32_buf_t native_int32_buf_t;
795+ typedef little_int40_buf_t native_int40_buf_t;
796+ typedef little_int48_buf_t native_int48_buf_t;
797+ typedef little_int56_buf_t native_int56_buf_t;
798+ typedef little_int64_buf_t native_int64_buf_t;
799+
800+ // unaligned native endian unsigned integer buffers
801+ typedef little_uint8_buf_t native_uint8_buf_t;
802+ typedef little_uint16_buf_t native_uint16_buf_t;
803+ typedef little_uint24_buf_t native_uint24_buf_t;
804+ typedef little_uint32_buf_t native_uint32_buf_t;
805+ typedef little_uint40_buf_t native_uint40_buf_t;
806+ typedef little_uint48_buf_t native_uint48_buf_t;
807+ typedef little_uint56_buf_t native_uint56_buf_t;
808+ typedef little_uint64_buf_t native_uint64_buf_t;
809+# endif
810+
811+ // Stream inserter
812+ template <class charT, class traits, BOOST_SCOPED_ENUM(order) Order, class T,
813+ std::size_t n_bits, BOOST_SCOPED_ENUM(align) A>
814+ std::basic_ostream<charT, traits>&
815+ operator<<(std::basic_ostream<charT, traits>& os,
816+ const endian_buffer<Order, T, n_bits, A>& x)
817+ {
818+ return os << x.value();
819+ }
820+
821+ // Stream extractor
822+ template <class charT, class traits, BOOST_SCOPED_ENUM(order) Order, class T,
823+ std::size_t n_bits, BOOST_SCOPED_ENUM(align) A>
824+ std::basic_istream<charT, traits>&
825+ operator>>(std::basic_istream<charT, traits>& is,
826+ endian_buffer<Order, T, n_bits, A>& x)
827+ {
828+ T i;
829+ if (is >> i)
830+ x = i;
831+ return is;
832+ }
833+
834+//---------------------------------- end synopsis ------------------------------------//
835+
836+ namespace detail
837+ {
838+
839+ // Unrolled loops for loading and storing streams of bytes.
840+
841+ template <typename T, std::size_t n_bytes,
842+ bool sign=boost::is_signed<T>::value >
843+ struct unrolled_byte_loops
844+ {
845+ typedef unrolled_byte_loops<T, n_bytes - 1, sign> next;
846+
847+ static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT
848+ { return static_cast<T>(*(bytes - 1) | (next::load_big(bytes - 1) << 8)); }
849+ static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT
850+ { return static_cast<T>(*bytes | (next::load_little(bytes + 1) << 8)); }
851+
852+ static void store_big(char* bytes, T value) BOOST_NOEXCEPT
853+ {
854+ *(bytes - 1) = static_cast<char>(value);
855+ next::store_big(bytes - 1, static_cast<T>(value >> 8));
856+ }
857+ static void store_little(char* bytes, T value) BOOST_NOEXCEPT
858+ {
859+ *bytes = static_cast<char>(value);
860+ next::store_little(bytes + 1, static_cast<T>(value >> 8));
861+ }
862+ };
863+
864+ template <typename T>
865+ struct unrolled_byte_loops<T, 1, false>
866+ {
867+ static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT
868+ { return *(bytes - 1); }
869+ static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT
870+ { return *bytes; }
871+ static void store_big(char* bytes, T value) BOOST_NOEXCEPT
872+ { *(bytes - 1) = static_cast<char>(value); }
873+ static void store_little(char* bytes, T value) BOOST_NOEXCEPT
874+ { *bytes = static_cast<char>(value); }
875+
876+ };
877+
878+ template <typename T>
879+ struct unrolled_byte_loops<T, 1, true>
880+ {
881+ static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT
882+ { return *reinterpret_cast<const signed char*>(bytes - 1); }
883+ static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT
884+ { return *reinterpret_cast<const signed char*>(bytes); }
885+ static void store_big(char* bytes, T value) BOOST_NOEXCEPT
886+ { *(bytes - 1) = static_cast<char>(value); }
887+ static void store_little(char* bytes, T value) BOOST_NOEXCEPT
888+ { *bytes = static_cast<char>(value); }
889+ };
890+
891+ template <typename T, std::size_t n_bytes>
892+ inline
893+ T load_big_endian(const void* bytes) BOOST_NOEXCEPT
894+ {
895+ return unrolled_byte_loops<T, n_bytes>::load_big
896+ (static_cast<const unsigned char*>(bytes) + n_bytes);
897+ }
898+
899+ template <typename T, std::size_t n_bytes>
900+ inline
901+ T load_little_endian(const void* bytes) BOOST_NOEXCEPT
902+ {
903+# if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86)
904+ // On x86 (which is little endian), unaligned loads are permitted
905+ if (sizeof(T) == n_bytes) // GCC 4.9, VC++ 14.0, and probably others, elide this
906+ // test and generate code only for the applicable return
907+ // case since sizeof(T) and n_bytes are known at compile
908+ // time.
909+ {
910+ return *reinterpret_cast<T const *>(bytes);
911+ }
912+# endif
913+ return unrolled_byte_loops<T, n_bytes>::load_little
914+ (static_cast<const unsigned char*>(bytes));
915+ }
916+
917+ template <typename T, std::size_t n_bytes>
918+ inline
919+ void store_big_endian(void* bytes, T value) BOOST_NOEXCEPT
920+ {
921+ unrolled_byte_loops<T, n_bytes>::store_big
922+ (static_cast<char*>(bytes) + n_bytes, value);
923+ }
924+
925+ template <typename T, std::size_t n_bytes>
926+ inline
927+ void store_little_endian(void* bytes, T value) BOOST_NOEXCEPT
928+ {
929+# if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86)
930+ // On x86 (which is little endian), unaligned stores are permitted
931+ if (sizeof(T) == n_bytes) // GCC 4.9, VC++ 14.0, and probably others, elide this
932+ // test and generate code only for the applicable return
933+ // case since sizeof(T) and n_bytes are known at compile
934+ // time.
935+ {
936+ *reinterpret_cast<T *>(bytes) = value;
937+ return;
938+ }
939+# endif
940+ unrolled_byte_loops<T, n_bytes>::store_little
941+ (static_cast<char*>(bytes), value);
942+ }
943+
944+ } // namespace detail
945+
946+# ifdef BOOST_ENDIAN_LOG
947+ bool endian_log(true);
948+# endif
949+
950+// endian_buffer class template specializations --------------------------------------//
951+
952+ // Specializations that represent unaligned bytes.
953+ // Taking an integer type as a parameter provides a nice way to pass both
954+ // the size and signedness of the desired integer and get the appropriate
955+ // corresponding integer type for the interface.
956+
957+ // Q: Should endian_buffer supply "value_type operator value_type() const noexcept"?
958+ // A: No. The rationale for endian_buffers is to prevent high-cost hidden
959+ // conversions. If an implicit conversion operator is supplied, hidden conversions
960+ // can occur.
961+
962+ // unaligned big endian_buffer specialization
963+ template <typename T, std::size_t n_bits>
964+ class endian_buffer< order::big, T, n_bits, align::no >
965+ {
966+ BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
967+ public:
968+ typedef T value_type;
969+# ifndef BOOST_ENDIAN_NO_CTORS
970+ endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT
971+ explicit endian_buffer(T val) BOOST_NOEXCEPT
972+ {
973+# ifdef BOOST_ENDIAN_LOG
974+ if ( endian_log )
975+ std::cout << "big, unaligned, "
976+ << n_bits << "-bits, construct(" << val << ")\n";
977+# endif
978+ detail::store_big_endian<T, n_bits/8>(m_value, val);
979+ }
980+# endif
981+ endian_buffer & operator=(T val) BOOST_NOEXCEPT
982+ {
983+# ifdef BOOST_ENDIAN_LOG
984+ if (endian_log)
985+ std::cout << "big, unaligned, " << n_bits << "-bits, assign(" << val << ")\n";
986+# endif
987+ detail::store_big_endian<T, n_bits/8>(m_value, val);
988+ return *this;
989+ }
990+ value_type value() const BOOST_NOEXCEPT
991+ {
992+# ifdef BOOST_ENDIAN_LOG
993+ if ( endian_log )
994+ std::cout << "big, unaligned, " << n_bits << "-bits, convert("
995+ << detail::load_big_endian<T, n_bits/8>(m_value) << ")\n";
996+# endif
997+ return detail::load_big_endian<T, n_bits/8>(m_value);
998+ }
999+ const char* data() const BOOST_NOEXCEPT { return m_value; }
1000+ protected:
1001+ char m_value[n_bits/8];
1002+ };
1003+
1004+ // unaligned little endian_buffer specialization
1005+ template <typename T, std::size_t n_bits>
1006+ class endian_buffer< order::little, T, n_bits, align::no >
1007+ {
1008+ BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
1009+ public:
1010+ typedef T value_type;
1011+# ifndef BOOST_ENDIAN_NO_CTORS
1012+ endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT
1013+ explicit endian_buffer(T val) BOOST_NOEXCEPT
1014+ {
1015+# ifdef BOOST_ENDIAN_LOG
1016+ if ( endian_log )
1017+ std::cout << "little, unaligned, " << n_bits << "-bits, construct("
1018+ << val << ")\n";
1019+# endif
1020+ detail::store_little_endian<T, n_bits/8>(m_value, val);
1021+ }
1022+# endif
1023+ endian_buffer & operator=(T val) BOOST_NOEXCEPT
1024+ { detail::store_little_endian<T, n_bits/8>(m_value, val); return *this; }
1025+ value_type value() const BOOST_NOEXCEPT
1026+ {
1027+# ifdef BOOST_ENDIAN_LOG
1028+ if ( endian_log )
1029+ std::cout << "little, unaligned, " << n_bits << "-bits, convert("
1030+ << detail::load_little_endian<T, n_bits/8>(m_value) << ")\n";
1031+# endif
1032+ return detail::load_little_endian<T, n_bits/8>(m_value);
1033+ }
1034+ const char* data() const BOOST_NOEXCEPT { return m_value; }
1035+ protected:
1036+ char m_value[n_bits/8];
1037+ };
1038+
1039+ // align::yes specializations; only n_bits == 16/32/64 supported
1040+
1041+ // aligned big endian_buffer specialization
1042+ template <typename T, std::size_t n_bits>
1043+ class endian_buffer<order::big, T, n_bits, align::yes>
1044+ {
1045+ BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
1046+ BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
1047+ public:
1048+ typedef T value_type;
1049+# ifndef BOOST_ENDIAN_NO_CTORS
1050+ endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT
1051+ explicit endian_buffer(T val) BOOST_NOEXCEPT
1052+ {
1053+# ifdef BOOST_ENDIAN_LOG
1054+ if ( endian_log )
1055+ std::cout << "big, aligned, " << n_bits
1056+ << "-bits, construct(" << val << ")\n";
1057+# endif
1058+ m_value = ::boost::endian::native_to_big(val);
1059+ }
1060+
1061+# endif
1062+ endian_buffer& operator=(T val) BOOST_NOEXCEPT
1063+ {
1064+ m_value = ::boost::endian::native_to_big(val);
1065+ return *this;
1066+ }
1067+ //operator value_type() const BOOST_NOEXCEPT
1068+ //{
1069+ // return ::boost::endian::big_to_native(m_value);
1070+ //}
1071+ value_type value() const BOOST_NOEXCEPT
1072+ {
1073+# ifdef BOOST_ENDIAN_LOG
1074+ if ( endian_log )
1075+ std::cout << "big, aligned, " << n_bits << "-bits, convert("
1076+ << ::boost::endian::big_to_native(m_value) << ")\n";
1077+# endif
1078+ return ::boost::endian::big_to_native(m_value);
1079+ }
1080+ const char* data() const BOOST_NOEXCEPT
1081+ {return reinterpret_cast<const char*>(&m_value);}
1082+ protected:
1083+ T m_value;
1084+ };
1085+
1086+ // aligned little endian_buffer specialization
1087+ template <typename T, std::size_t n_bits>
1088+ class endian_buffer<order::little, T, n_bits, align::yes>
1089+ {
1090+ BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
1091+ BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
1092+ public:
1093+ typedef T value_type;
1094+# ifndef BOOST_ENDIAN_NO_CTORS
1095+ endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT
1096+ explicit endian_buffer(T val) BOOST_NOEXCEPT
1097+ {
1098+# ifdef BOOST_ENDIAN_LOG
1099+ if ( endian_log )
1100+ std::cout << "little, aligned, " << n_bits
1101+ << "-bits, construct(" << val << ")\n";
1102+# endif
1103+ m_value = ::boost::endian::native_to_little(val);
1104+ }
1105+
1106+# endif
1107+ endian_buffer& operator=(T val) BOOST_NOEXCEPT
1108+ {
1109+ m_value = ::boost::endian::native_to_little(val);
1110+ return *this;
1111+ }
1112+ value_type value() const BOOST_NOEXCEPT
1113+ {
1114+# ifdef BOOST_ENDIAN_LOG
1115+ if ( endian_log )
1116+ std::cout << "little, aligned, " << n_bits << "-bits, convert("
1117+ << ::boost::endian::little_to_native(m_value) << ")\n";
1118+# endif
1119+ return ::boost::endian::little_to_native(m_value);
1120+ }
1121+ const char* data() const BOOST_NOEXCEPT
1122+ {return reinterpret_cast<const char*>(&m_value);}
1123+ protected:
1124+ T m_value;
1125+ };
1126+
1127+} // namespace endian
1128+} // namespace boost
1129+
1130+#if defined(__BORLANDC__) || defined( __CODEGEARC__)
1131+# pragma pack(pop)
1132+#endif
1133+
1134+#if defined(_MSC_VER)
1135+# pragma warning(pop)
1136+#endif
1137+
1138+#endif // BOOST_ENDIAN_BUFFERS_HPP
1139
1140=== added file '3rd-party/boost/endian/conversion.hpp'
1141--- 3rd-party/boost/endian/conversion.hpp 1970-01-01 00:00:00 +0000
1142+++ 3rd-party/boost/endian/conversion.hpp 2016-04-01 06:55:25 +0000
1143@@ -0,0 +1,487 @@
1144+// boost/endian/conversion.hpp -------------------------------------------------------//
1145+
1146+// Copyright Beman Dawes 2010, 2011, 2014
1147+
1148+// Distributed under the Boost Software License, Version 1.0.
1149+// http://www.boost.org/LICENSE_1_0.txt
1150+
1151+#ifndef BOOST_ENDIAN_CONVERSION_HPP
1152+#define BOOST_ENDIAN_CONVERSION_HPP
1153+
1154+#include <boost/config.hpp>
1155+#include <boost/predef/detail/endian_compat.h>
1156+#include <boost/cstdint.hpp>
1157+#include <boost/endian/detail/intrinsic.hpp>
1158+#include <boost/core/scoped_enum.hpp>
1159+#include <boost/static_assert.hpp>
1160+#include <algorithm>
1161+#include <cstring> // for memcpy
1162+
1163+//------------------------------------- synopsis ---------------------------------------//
1164+
1165+namespace boost
1166+{
1167+namespace endian
1168+{
1169+#ifndef BOOST_ENDIAN_ORDER_ENUM_DEFINED
1170+ BOOST_SCOPED_ENUM_START(order)
1171+ {
1172+ big, little,
1173+# ifdef BOOST_BIG_ENDIAN
1174+ native = big
1175+# else
1176+ native = little
1177+# endif
1178+ }; BOOST_SCOPED_ENUM_END
1179+# define BOOST_ENDIAN_ORDER_ENUM_DEFINED
1180+#endif
1181+
1182+//--------------------------------------------------------------------------------------//
1183+// //
1184+// return-by-value interfaces //
1185+// suggested by Phil Endecott //
1186+// //
1187+// user-defined types (UDTs) //
1188+// //
1189+// All return-by-value conversion function templates are required to be implemented in //
1190+// terms of an unqualified call to "endian_reverse(x)", a function returning the //
1191+// value of x with endianness reversed. This provides a customization point for any //
1192+// UDT that provides a "endian_reverse" free-function meeting the requirements. //
1193+// It must be defined in the same namespace as the UDT itself so that it will be found //
1194+// by argument dependent lookup (ADL). //
1195+// //
1196+//--------------------------------------------------------------------------------------//
1197+
1198+ // customization for exact-length arithmetic types. See doc/conversion.html/#FAQ
1199+ inline int8_t endian_reverse(int8_t x) BOOST_NOEXCEPT;
1200+ inline int16_t endian_reverse(int16_t x) BOOST_NOEXCEPT;
1201+ inline int32_t endian_reverse(int32_t x) BOOST_NOEXCEPT;
1202+ inline int64_t endian_reverse(int64_t x) BOOST_NOEXCEPT;
1203+ inline uint8_t endian_reverse(uint8_t x) BOOST_NOEXCEPT;
1204+ inline uint16_t endian_reverse(uint16_t x) BOOST_NOEXCEPT;
1205+ inline uint32_t endian_reverse(uint32_t x) BOOST_NOEXCEPT;
1206+ inline uint64_t endian_reverse(uint64_t x) BOOST_NOEXCEPT;
1207+
1208+ // reverse byte order unless native endianness is big
1209+ template <class EndianReversible >
1210+ inline EndianReversible big_to_native(EndianReversible x) BOOST_NOEXCEPT;
1211+ // Returns: x if native endian order is big, otherwise endian_reverse(x)
1212+ template <class EndianReversible >
1213+ inline EndianReversible native_to_big(EndianReversible x) BOOST_NOEXCEPT;
1214+ // Returns: x if native endian order is big, otherwise endian_reverse(x)
1215+
1216+ // reverse byte order unless native endianness is little
1217+ template <class EndianReversible >
1218+ inline EndianReversible little_to_native(EndianReversible x) BOOST_NOEXCEPT;
1219+ // Returns: x if native endian order is little, otherwise endian_reverse(x)
1220+ template <class EndianReversible >
1221+ inline EndianReversible native_to_little(EndianReversible x) BOOST_NOEXCEPT;
1222+ // Returns: x if native endian order is little, otherwise endian_reverse(x)
1223+
1224+ // generic conditional reverse byte order
1225+ template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To,
1226+ class EndianReversible>
1227+ inline EndianReversible conditional_reverse(EndianReversible from) BOOST_NOEXCEPT;
1228+ // Returns: If From == To have different values, from.
1229+ // Otherwise endian_reverse(from).
1230+ // Remarks: The From == To test, and as a consequence which form the return takes, is
1231+ // is determined at compile time.
1232+
1233+ // runtime conditional reverse byte order
1234+ template <class EndianReversible >
1235+ inline EndianReversible conditional_reverse(EndianReversible from,
1236+ BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order)
1237+ BOOST_NOEXCEPT;
1238+ // Returns: from_order == to_order ? from : endian_reverse(from).
1239+
1240+ //------------------------------------------------------------------------------------//
1241+
1242+
1243+ // Q: What happended to bswap, htobe, and the other synonym functions based on names
1244+ // popularized by BSD, OS X, and Linux?
1245+ // A: Turned out these may be implemented as macros on some systems. Ditto POSIX names
1246+ // for such functionality. Since macros would cause endless problems with functions
1247+ // of the same names, and these functions are just synonyms anyhow, they have been
1248+ // removed.
1249+
1250+
1251+ //------------------------------------------------------------------------------------//
1252+ // //
1253+ // reverse in place interfaces //
1254+ // //
1255+ // user-defined types (UDTs) //
1256+ // //
1257+ // All reverse in place function templates are required to be implemented in terms //
1258+ // of an unqualified call to "endian_reverse_inplace(x)", a function reversing //
1259+ // the endianness of x, which is a non-const reference. This provides a //
1260+ // customization point for any UDT that provides a "reverse_inplace" free-function //
1261+ // meeting the requirements. The free-function must be declared in the same //
1262+ // namespace as the UDT itself so that it will be found by argument-dependent //
1263+ // lookup (ADL). //
1264+ // //
1265+ //------------------------------------------------------------------------------------//
1266+
1267+ // reverse in place
1268+ template <class EndianReversible>
1269+ inline void endian_reverse_inplace(EndianReversible& x) BOOST_NOEXCEPT;
1270+ // Effects: x = endian_reverse(x)
1271+
1272+ // reverse in place unless native endianness is big
1273+ template <class EndianReversibleInplace>
1274+ inline void big_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT;
1275+ // Effects: none if native byte-order is big, otherwise endian_reverse_inplace(x)
1276+ template <class EndianReversibleInplace>
1277+ inline void native_to_big_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT;
1278+ // Effects: none if native byte-order is big, otherwise endian_reverse_inplace(x)
1279+
1280+ // reverse in place unless native endianness is little
1281+ template <class EndianReversibleInplace>
1282+ inline void little_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT;
1283+ // Effects: none if native byte-order is little, otherwise endian_reverse_inplace(x);
1284+ template <class EndianReversibleInplace>
1285+ inline void native_to_little_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT;
1286+ // Effects: none if native byte-order is little, otherwise endian_reverse_inplace(x);
1287+
1288+ // generic conditional reverse in place
1289+ template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To,
1290+ class EndianReversibleInplace>
1291+ inline void conditional_reverse_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT;
1292+
1293+ // runtime reverse in place
1294+ template <class EndianReversibleInplace>
1295+ inline void conditional_reverse_inplace(EndianReversibleInplace& x,
1296+ BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order)
1297+ BOOST_NOEXCEPT;
1298+
1299+//----------------------------------- end synopsis -------------------------------------//
1300+
1301+ namespace detail
1302+ {
1303+ // generic reverse function template implementation approach using std::reverse
1304+ // suggested by Mathias Gaunard. Primary motivation for inclusion is to have an
1305+ // independent implementation to test against.
1306+
1307+ template <class T>
1308+ inline T std_endian_reverse(T x) BOOST_NOEXCEPT
1309+ {
1310+ T tmp(x);
1311+ std::reverse(
1312+ reinterpret_cast<unsigned char*>(&tmp),
1313+ reinterpret_cast<unsigned char*>(&tmp) + sizeof(T));
1314+ return tmp;
1315+ }
1316+
1317+ // conditional unaligned reverse copy, patterned after std::reverse_copy
1318+ template <class T>
1319+ inline void big_reverse_copy(T from, char* to) BOOST_NOEXCEPT;
1320+ template <class T>
1321+ inline void big_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT;
1322+ template <class T>
1323+ inline void little_reverse_copy(T from, char* to) BOOST_NOEXCEPT;
1324+ template <class T>
1325+ inline void little_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT;
1326+ } // namespace detail
1327+
1328+//--------------------------------------------------------------------------------------//
1329+// //
1330+// return-by-value implementation //
1331+// //
1332+// -- portable approach suggested by tymofey, with avoidance of undefined behavior //
1333+// as suggested by Giovanni Piero Deretta, with a further refinement suggested //
1334+// by Pyry Jahkola. //
1335+// -- intrinsic approach suggested by reviewers, and by David Stone, who provided //
1336+// his Boost licensed macro implementation (detail/intrinsic.hpp) //
1337+// //
1338+//--------------------------------------------------------------------------------------//
1339+
1340+ inline int8_t endian_reverse(int8_t x) BOOST_NOEXCEPT
1341+ {
1342+ return x;
1343+ }
1344+
1345+ inline int16_t endian_reverse(int16_t x) BOOST_NOEXCEPT
1346+ {
1347+# ifdef BOOST_ENDIAN_NO_INTRINSICS
1348+ return (static_cast<uint16_t>(x) << 8)
1349+ | (static_cast<uint16_t>(x) >> 8);
1350+# else
1351+ return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(static_cast<uint16_t>(x));
1352+# endif
1353+ }
1354+
1355+ inline int32_t endian_reverse(int32_t x) BOOST_NOEXCEPT
1356+ {
1357+# ifdef BOOST_ENDIAN_NO_INTRINSICS
1358+ uint32_t step16;
1359+ step16 = static_cast<uint32_t>(x) << 16 | static_cast<uint32_t>(x) >> 16;
1360+ return
1361+ ((static_cast<uint32_t>(step16) << 8) & 0xff00ff00)
1362+ | ((static_cast<uint32_t>(step16) >> 8) & 0x00ff00ff);
1363+# else
1364+ return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(static_cast<uint32_t>(x));
1365+# endif
1366+ }
1367+
1368+ inline int64_t endian_reverse(int64_t x) BOOST_NOEXCEPT
1369+ {
1370+# ifdef BOOST_ENDIAN_NO_INTRINSICS
1371+ uint64_t step32, step16;
1372+ step32 = static_cast<uint64_t>(x) << 32 | static_cast<uint64_t>(x) >> 32;
1373+ step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16
1374+ | (step32 & 0xFFFF0000FFFF0000ULL) >> 16;
1375+ return static_cast<int64_t>((step16 & 0x00FF00FF00FF00FFULL) << 8
1376+ | (step16 & 0xFF00FF00FF00FF00ULL) >> 8);
1377+# else
1378+ return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(static_cast<uint64_t>(x));
1379+# endif
1380+ }
1381+
1382+ inline uint8_t endian_reverse(uint8_t x) BOOST_NOEXCEPT
1383+ {
1384+ return x;
1385+ }
1386+
1387+ inline uint16_t endian_reverse(uint16_t x) BOOST_NOEXCEPT
1388+ {
1389+# ifdef BOOST_ENDIAN_NO_INTRINSICS
1390+ return (x << 8)
1391+ | (x >> 8);
1392+# else
1393+ return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x);
1394+# endif
1395+ }
1396+
1397+ inline uint32_t endian_reverse(uint32_t x) BOOST_NOEXCEPT
1398+ {
1399+# ifdef BOOST_ENDIAN_NO_INTRINSICS
1400+ uint32_t step16;
1401+ step16 = x << 16 | x >> 16;
1402+ return
1403+ ((step16 << 8) & 0xff00ff00)
1404+ | ((step16 >> 8) & 0x00ff00ff);
1405+# else
1406+ return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x);
1407+# endif
1408+ }
1409+
1410+ inline uint64_t endian_reverse(uint64_t x) BOOST_NOEXCEPT
1411+ {
1412+# ifdef BOOST_ENDIAN_NO_INTRINSICS
1413+ uint64_t step32, step16;
1414+ step32 = x << 32 | x >> 32;
1415+ step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16
1416+ | (step32 & 0xFFFF0000FFFF0000ULL) >> 16;
1417+ return (step16 & 0x00FF00FF00FF00FFULL) << 8
1418+ | (step16 & 0xFF00FF00FF00FF00ULL) >> 8;
1419+# else
1420+ return BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x);
1421+# endif
1422+ }
1423+
1424+ template <class EndianReversible >
1425+ inline EndianReversible big_to_native(EndianReversible x) BOOST_NOEXCEPT
1426+ {
1427+# ifdef BOOST_BIG_ENDIAN
1428+ return x;
1429+# else
1430+ return endian_reverse(x);
1431+# endif
1432+ }
1433+
1434+ template <class EndianReversible >
1435+ inline EndianReversible native_to_big(EndianReversible x) BOOST_NOEXCEPT
1436+ {
1437+# ifdef BOOST_BIG_ENDIAN
1438+ return x;
1439+# else
1440+ return endian_reverse(x);
1441+# endif
1442+ }
1443+
1444+ template <class EndianReversible >
1445+ inline EndianReversible little_to_native(EndianReversible x) BOOST_NOEXCEPT
1446+ {
1447+# ifdef BOOST_LITTLE_ENDIAN
1448+ return x;
1449+# else
1450+ return endian_reverse(x);
1451+# endif
1452+ }
1453+
1454+ template <class EndianReversible >
1455+ inline EndianReversible native_to_little(EndianReversible x) BOOST_NOEXCEPT
1456+ {
1457+# ifdef BOOST_LITTLE_ENDIAN
1458+ return x;
1459+# else
1460+ return endian_reverse(x);
1461+# endif
1462+ }
1463+
1464+ namespace detail
1465+ {
1466+ // Primary template and specializations to support endian_reverse().
1467+ // See rationale in endian_reverse() below.
1468+ template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To,
1469+ class EndianReversible>
1470+ class value_converter ; // primary template
1471+ template <class T> class value_converter <order::big, order::big, T>
1472+ {public: T operator()(T x) BOOST_NOEXCEPT {return x;}};
1473+ template <class T> class value_converter <order::little, order::little, T>
1474+ {public: T operator()(T x) BOOST_NOEXCEPT {return x;}};
1475+ template <class T> class value_converter <order::big, order::little, T>
1476+ {public: T operator()(T x) BOOST_NOEXCEPT {return endian_reverse(x);}};
1477+ template <class T> class value_converter <order::little, order::big, T>
1478+ {public: T operator()(T x) BOOST_NOEXCEPT {return endian_reverse(x);}};
1479+ }
1480+
1481+ // generic conditional reverse
1482+ template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To,
1483+ class EndianReversible>
1484+ inline EndianReversible conditional_reverse(EndianReversible from) BOOST_NOEXCEPT {
1485+ // work around lack of function template partial specialization by instantiating
1486+ // a function object of a class that is partially specialized on the two order
1487+ // template parameters, and then calling its operator().
1488+ detail::value_converter <From, To, EndianReversible> tmp;
1489+ return tmp(from);
1490+ }
1491+
1492+ // runtime conditional reverse
1493+ template <class EndianReversible >
1494+ inline EndianReversible conditional_reverse(EndianReversible from,
1495+ BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order) BOOST_NOEXCEPT
1496+ {
1497+ return from_order == to_order ? from : endian_reverse(from);
1498+ }
1499+
1500+//--------------------------------------------------------------------------------------//
1501+// reverse-in-place implementation //
1502+//--------------------------------------------------------------------------------------//
1503+
1504+ // reverse in place
1505+ template <class EndianReversible>
1506+ inline void endian_reverse_inplace(EndianReversible& x) BOOST_NOEXCEPT
1507+ {
1508+ x = endian_reverse(x);
1509+ }
1510+
1511+ template <class EndianReversibleInplace>
1512+# ifdef BOOST_BIG_ENDIAN
1513+ inline void big_to_native_inplace(EndianReversibleInplace&) BOOST_NOEXCEPT {}
1514+# else
1515+ inline void big_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT
1516+ { endian_reverse_inplace(x); }
1517+# endif
1518+ template <class EndianReversibleInplace>
1519+# ifdef BOOST_BIG_ENDIAN
1520+ inline void native_to_big_inplace(EndianReversibleInplace&) BOOST_NOEXCEPT {}
1521+# else
1522+ inline void native_to_big_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT
1523+ {
1524+ endian_reverse_inplace(x);
1525+ }
1526+# endif
1527+
1528+ template <class EndianReversibleInplace>
1529+# ifdef BOOST_LITTLE_ENDIAN
1530+ inline void little_to_native_inplace(EndianReversibleInplace&) BOOST_NOEXCEPT {}
1531+# else
1532+ inline void little_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT
1533+ { endian_reverse_inplace(x); }
1534+# endif
1535+ template <class EndianReversibleInplace>
1536+# ifdef BOOST_LITTLE_ENDIAN
1537+ inline void native_to_little_inplace(EndianReversibleInplace&) BOOST_NOEXCEPT {}
1538+# else
1539+ inline void native_to_little_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT
1540+ {
1541+ endian_reverse_inplace(x);
1542+ }
1543+# endif
1544+
1545+ namespace detail
1546+ {
1547+ // Primary template and specializations support generic
1548+ // endian_reverse_inplace().
1549+ // See rationale in endian_reverse_inplace() below.
1550+ template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To,
1551+ class EndianReversibleInplace>
1552+ class converter; // primary template
1553+ template <class T> class converter<order::big, order::big, T>
1554+ {public: void operator()(T&) BOOST_NOEXCEPT {/*no effect*/}};
1555+ template <class T> class converter<order::little, order::little, T>
1556+ {public: void operator()(T&) BOOST_NOEXCEPT {/*no effect*/}};
1557+ template <class T> class converter<order::big, order::little, T>
1558+ {public: void operator()(T& x) BOOST_NOEXCEPT { endian_reverse_inplace(x); }};
1559+ template <class T> class converter<order::little, order::big, T>
1560+ {public: void operator()(T& x) BOOST_NOEXCEPT { endian_reverse_inplace(x); }};
1561+ } // namespace detail
1562+
1563+ // generic conditional reverse in place
1564+ template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To,
1565+ class EndianReversibleInplace>
1566+ inline void conditional_reverse_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT
1567+ {
1568+ // work around lack of function template partial specialization by instantiating
1569+ // a function object of a class that is partially specialized on the two order
1570+ // template parameters, and then calling its operator().
1571+ detail::converter<From, To, EndianReversibleInplace> tmp;
1572+ tmp(x); // call operator ()
1573+ }
1574+
1575+ // runtime reverse in place
1576+ template <class EndianReversibleInplace>
1577+ inline void conditional_reverse_inplace(EndianReversibleInplace& x,
1578+ BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order)
1579+ BOOST_NOEXCEPT
1580+ {
1581+ if (from_order != to_order)
1582+ endian_reverse_inplace(x);
1583+ }
1584+
1585+
1586+ namespace detail
1587+ {
1588+ template <class T>
1589+ inline void big_reverse_copy(T from, char* to) BOOST_NOEXCEPT
1590+ {
1591+# ifdef BOOST_BIG_ENDIAN
1592+ std::memcpy(to, reinterpret_cast<const char*>(&from), sizeof(T));
1593+# else
1594+ std::reverse_copy(reinterpret_cast<const char*>(&from),
1595+ reinterpret_cast<const char*>(&from) + sizeof(T), to);
1596+# endif
1597+ }
1598+ template <class T>
1599+ inline void big_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT
1600+ {
1601+# ifdef BOOST_BIG_ENDIAN
1602+ std::memcpy(reinterpret_cast<char*>(&to), from, sizeof(T));
1603+# else
1604+ std::reverse_copy(from, from + sizeof(T), reinterpret_cast<char*>(&to));
1605+# endif
1606+ }
1607+ template <class T>
1608+ inline void little_reverse_copy(T from, char* to) BOOST_NOEXCEPT
1609+ {
1610+# ifdef BOOST_LITTLE_ENDIAN
1611+ std::memcpy(to, reinterpret_cast<const char*>(&from), sizeof(T));
1612+# else
1613+ std::reverse_copy(reinterpret_cast<const char*>(&from),
1614+ reinterpret_cast<const char*>(&from) + sizeof(T), to);
1615+# endif
1616+ }
1617+ template <class T>
1618+ inline void little_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT
1619+ {
1620+# ifdef BOOST_LITTLE_ENDIAN
1621+ std::memcpy(reinterpret_cast<char*>(&to), from, sizeof(T));
1622+# else
1623+ std::reverse_copy(from, from + sizeof(T), reinterpret_cast<char*>(&to));
1624+# endif
1625+ }
1626+ } // namespace detail
1627+} // namespace endian
1628+} // namespace boost
1629+
1630+#endif // BOOST_ENDIAN_CONVERSION_HPP
1631
1632=== added directory '3rd-party/boost/endian/detail'
1633=== added file '3rd-party/boost/endian/detail/config.hpp'
1634--- 3rd-party/boost/endian/detail/config.hpp 1970-01-01 00:00:00 +0000
1635+++ 3rd-party/boost/endian/detail/config.hpp 2016-04-01 06:55:25 +0000
1636@@ -0,0 +1,62 @@
1637+// boost/endian/detail/config.hpp ----------------------------------------------------//
1638+
1639+// Copyright Beman Dawes 2003, 2010
1640+
1641+// Distributed under the Boost Software License, Version 1.0.
1642+// See http://www.boost.org/LICENSE_1_0.txt
1643+
1644+//--------------------------------------------------------------------------------------//
1645+
1646+#ifndef BOOST_ENDIAN_CONFIG_HPP
1647+#define BOOST_ENDIAN_CONFIG_HPP
1648+
1649+// This header implements separate compilation features as described in
1650+// http://www.boost.org/more/separate_compilation.html
1651+
1652+#include <boost/config.hpp>
1653+#include <boost/system/api_config.hpp> // for BOOST_POSIX_API or BOOST_WINDOWS_API
1654+
1655+// throw an exception ----------------------------------------------------------------//
1656+//
1657+// Exceptions were originally thrown via boost::throw_exception().
1658+// As throw_exception() became more complex, it caused user error reporting
1659+// to be harder to interpret, since the exception reported became much more complex.
1660+// The immediate fix was to throw directly, wrapped in a macro to make any later change
1661+// easier.
1662+
1663+#define BOOST_ENDIAN_THROW(EX) throw EX
1664+
1665+// enable dynamic linking -------------------------------------------------------------//
1666+
1667+#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_ENDIAN_DYN_LINK)
1668+# if defined(BOOST_ENDIAN_SOURCE)
1669+# define BOOST_ENDIAN_DECL BOOST_SYMBOL_EXPORT
1670+# else
1671+# define BOOST_ENDIAN_DECL BOOST_SYMBOL_IMPORT
1672+# endif
1673+#else
1674+# define BOOST_ENDIAN_DECL
1675+#endif
1676+
1677+// enable automatic library variant selection ----------------------------------------//
1678+
1679+#if !defined(BOOST_ENDIAN_SOURCE) && !defined(BOOST_ALL_NO_LIB) \
1680+ && !defined(BOOST_ENDIAN_NO_LIB)
1681+//
1682+// Set the name of our library, this will get undef'ed by auto_link.hpp
1683+// once it's done with it:
1684+//
1685+#define BOOST_LIB_NAME boost_endian
1686+//
1687+// If we're importing code from a dll, then tell auto_link.hpp about it:
1688+//
1689+#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_ENDIAN_DYN_LINK)
1690+# define BOOST_DYN_LINK
1691+#endif
1692+//
1693+// And include the header that does the work:
1694+//
1695+#include <boost/config/auto_link.hpp>
1696+#endif // auto-linking disabled
1697+
1698+#endif // BOOST_ENDIAN_CONFIG_HPP
1699
1700=== added file '3rd-party/boost/endian/detail/cover_operators.hpp'
1701--- 3rd-party/boost/endian/detail/cover_operators.hpp 1970-01-01 00:00:00 +0000
1702+++ 3rd-party/boost/endian/detail/cover_operators.hpp 2016-04-01 06:55:25 +0000
1703@@ -0,0 +1,142 @@
1704+// boost/endian/detail/cover_operators.hpp ----------------------------------//
1705+
1706+// Copyright Darin Adler 2000
1707+// Copyright Beman Dawes 2008
1708+
1709+// Distributed under the Boost Software License, Version 1.0. (See accompanying
1710+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
1711+
1712+#ifndef BOOST_ENDIAN_COVER_OPERATORS_HPP
1713+#define BOOST_ENDIAN_COVER_OPERATORS_HPP
1714+
1715+#if defined(_MSC_VER)
1716+# pragma warning(push)
1717+# pragma warning(disable:4365) // conversion ... signed/unsigned mismatch
1718+#endif
1719+
1720+# ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
1721+# include <boost/operators.hpp>
1722+# endif
1723+
1724+#include <boost/config.hpp>
1725+#include <iosfwd>
1726+
1727+namespace boost
1728+{
1729+ namespace endian
1730+ {
1731+
1732+//--------------------------------------------------------------------------------------//
1733+
1734+// A class that adds arithmetic operators to an arithmetic cover class
1735+//
1736+// Uses the curiously recurring template pattern (CRTP).
1737+//
1738+// If the class being covered has a non-explicit conversion to an integer type
1739+// then a smaller number of cover operations are needed. Define the macro
1740+// BOOST_ENDIAN_MINIMAL_COVER_OPERATORS to indicate this.
1741+//
1742+// Define BOOST_NO_IO_COVER_OPERATORS if I/O cover operations are not desired.
1743+
1744+//--------------------------------------------------------------------------------------//
1745+
1746+ template <class D, // D is the CRTP derived type, i.e. the cover class
1747+ class ArithmeticT>
1748+ class cover_operators
1749+# ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
1750+ : boost::operators<D>
1751+# endif
1752+ {
1753+ // The other operations take advantage of the type conversion that's
1754+ // built into unary +.
1755+
1756+ // Unary operations.
1757+ friend ArithmeticT operator+(const D& x) BOOST_NOEXCEPT { return x; }
1758+# ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
1759+ friend ArithmeticT operator-(const D& x) BOOST_NOEXCEPT { return -+x; }
1760+ friend ArithmeticT operator~(const D& x) BOOST_NOEXCEPT { return ~+x; }
1761+ friend ArithmeticT operator!(const D& x) BOOST_NOEXCEPT { return !+x; }
1762+
1763+ // The basic ordering operations.
1764+ friend bool operator==(const D& x, ArithmeticT y) BOOST_NOEXCEPT { return +x == y; }
1765+ friend bool operator<(const D& x, ArithmeticT y) BOOST_NOEXCEPT { return +x < y; }
1766+# endif
1767+
1768+ // The basic arithmetic operations.
1769+ friend D& operator+=(D& x, ArithmeticT y) BOOST_NOEXCEPT
1770+ { return x = static_cast<ArithmeticT>(+x + y); }
1771+ friend D& operator-=(D& x, ArithmeticT y) BOOST_NOEXCEPT
1772+ { return x = static_cast<ArithmeticT>(+x - y); }
1773+ friend D& operator*=(D& x, ArithmeticT y) BOOST_NOEXCEPT
1774+ { return x = static_cast<ArithmeticT>(+x * y); }
1775+ friend D& operator/=(D& x, ArithmeticT y) BOOST_NOEXCEPT
1776+ { return x = static_cast<ArithmeticT>(+x / y); }
1777+ friend D& operator%=(D& x, ArithmeticT y) BOOST_NOEXCEPT
1778+ { return x = static_cast<ArithmeticT>(+x % y); }
1779+ friend D& operator&=(D& x, ArithmeticT y) BOOST_NOEXCEPT
1780+ { return x = static_cast<ArithmeticT>(+x & y); }
1781+ friend D& operator|=(D& x, ArithmeticT y) BOOST_NOEXCEPT
1782+ { return x = static_cast<ArithmeticT>(+x | y); }
1783+ friend D& operator^=(D& x, ArithmeticT y) BOOST_NOEXCEPT
1784+ { return x = static_cast<ArithmeticT>(+x ^ y); }
1785+ friend D& operator<<=(D& x, ArithmeticT y) BOOST_NOEXCEPT
1786+ { return x = static_cast<ArithmeticT>(+x << y); }
1787+ friend D& operator>>=(D& x, ArithmeticT y) BOOST_NOEXCEPT
1788+ { return x = static_cast<ArithmeticT>(+x >> y); }
1789+
1790+ // A few binary arithmetic operations not covered by operators base class.
1791+ friend ArithmeticT operator<<(const D& x, ArithmeticT y) BOOST_NOEXCEPT
1792+ { return static_cast<ArithmeticT>(+x << y); }
1793+ friend ArithmeticT operator>>(const D& x, ArithmeticT y) BOOST_NOEXCEPT
1794+ { return static_cast<ArithmeticT>(+x >> y); }
1795+
1796+ // Auto-increment and auto-decrement can be defined in terms of the
1797+ // arithmetic operations.
1798+ friend D& operator++(D& x) BOOST_NOEXCEPT { return x += 1; }
1799+ friend D& operator--(D& x) BOOST_NOEXCEPT { return x -= 1; }
1800+
1801+# ifdef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
1802+ friend D operator++(D& x, int) BOOST_NOEXCEPT
1803+ {
1804+ D tmp(x);
1805+ x += 1;
1806+ return tmp;
1807+ }
1808+ friend D operator--(D& x, int) BOOST_NOEXCEPT
1809+ {
1810+ D tmp(x);
1811+ x -= 1;
1812+ return tmp;
1813+ }
1814+# endif
1815+
1816+# ifndef BOOST_NO_IO_COVER_OPERATORS
1817+
1818+ // Stream inserter
1819+ template <class charT, class traits>
1820+ friend std::basic_ostream<charT, traits>&
1821+ operator<<(std::basic_ostream<charT, traits>& os, const D& x)
1822+ {
1823+ return os << +x;
1824+ }
1825+
1826+ // Stream extractor
1827+ template <class charT, class traits>
1828+ friend std::basic_istream<charT, traits>&
1829+ operator>>(std::basic_istream<charT, traits>& is, D& x)
1830+ {
1831+ ArithmeticT i;
1832+ if (is >> i)
1833+ x = i;
1834+ return is;
1835+ }
1836+# endif
1837+ };
1838+ } // namespace endian
1839+} // namespace boost
1840+
1841+#if defined(_MSC_VER)
1842+# pragma warning(pop)
1843+#endif
1844+
1845+#endif // BOOST_ENDIAN_COVER_OPERATORS_HPP
1846
1847=== added file '3rd-party/boost/endian/detail/disable_warnings.hpp'
1848--- 3rd-party/boost/endian/detail/disable_warnings.hpp 1970-01-01 00:00:00 +0000
1849+++ 3rd-party/boost/endian/detail/disable_warnings.hpp 2016-04-01 06:55:25 +0000
1850@@ -0,0 +1,33 @@
1851+// disable_warnings.hpp --------------------------------------------------------------//
1852+
1853+// Copyright Beman Dawes 2011
1854+
1855+// Distributed under the Boost Software License, Version 1.0.
1856+// See http://www.boost.org/LICENSE_1_0.txt
1857+
1858+//--------------------------------------------------------------------------------------//
1859+
1860+#ifdef _MSC_VER
1861+
1862+#ifndef _SCL_SECURE_NO_WARNINGS
1863+# define _SCL_SECURE_NO_WARNINGS
1864+#endif
1865+
1866+#ifndef _CRT_SECURE_NO_WARNINGS
1867+# define _CRT_SECURE_NO_WARNINGS
1868+#endif
1869+
1870+# pragma warning(push)
1871+
1872+// triggered by boost/detail/lightweight_test.hpp
1873+# pragma warning( disable : 4640 ) // ... construction of local static object is not thread-safe
1874+
1875+// triggered by Microsoft's own headers, so disable
1876+# pragma warning( disable : 4820 ) // padding added after data member
1877+# pragma warning( disable : 4548 ) // expression before comma has no effect
1878+# pragma warning( disable : 4668 ) // ... is not defined as a preprocessor macro
1879+# pragma warning( disable : 4514 ) // ... unreferenced inline function has been removed
1880+# pragma warning( disable : 4710 ) // ... function not inlined
1881+# pragma warning( disable : 4986 ) // ... exception specification does not match previous declaration
1882+# pragma warning( disable : 4711 ) // ... selected for automatic inline expansion
1883+#endif
1884
1885=== added file '3rd-party/boost/endian/detail/disable_warnings_pop.hpp'
1886--- 3rd-party/boost/endian/detail/disable_warnings_pop.hpp 1970-01-01 00:00:00 +0000
1887+++ 3rd-party/boost/endian/detail/disable_warnings_pop.hpp 2016-04-01 06:55:25 +0000
1888@@ -0,0 +1,12 @@
1889+// disable_warnings_pop.hpp ----------------------------------------------------------//
1890+
1891+// Copyright Beman Dawes 2011
1892+
1893+// Distributed under the Boost Software License, Version 1.0.
1894+// See http://www.boost.org/LICENSE_1_0.txt
1895+
1896+//--------------------------------------------------------------------------------------//
1897+
1898+#ifdef _MSC_VER
1899+# pragma warning(push)
1900+#endif
1901
1902=== added file '3rd-party/boost/endian/detail/intrinsic.hpp'
1903--- 3rd-party/boost/endian/detail/intrinsic.hpp 1970-01-01 00:00:00 +0000
1904+++ 3rd-party/boost/endian/detail/intrinsic.hpp 2016-04-01 06:55:25 +0000
1905@@ -0,0 +1,64 @@
1906+// endian/detail/intrinsic.hpp -------------------------------------------------------//
1907+
1908+// Copyright (C) 2012 David Stone
1909+// Copyright Beman Dawes 2013
1910+
1911+// Distributed under the Boost Software License, Version 1.0.
1912+// http://www.boost.org/LICENSE_1_0.txt
1913+
1914+#ifndef BOOST_ENDIAN_INTRINSIC_HPP
1915+#define BOOST_ENDIAN_INTRINSIC_HPP
1916+
1917+// Allow user to force BOOST_ENDIAN_NO_INTRINSICS in case they aren't available for a
1918+// particular platform/compiler combination. Please report such platform/compiler
1919+// combinations to the Boost mailing list.
1920+#ifndef BOOST_ENDIAN_NO_INTRINSICS
1921+
1922+#ifndef __has_builtin // Optional of course
1923+ #define __has_builtin(x) 0 // Compatibility with non-clang compilers
1924+#endif
1925+
1926+// GCC and Clang recent versions provide intrinsic byte swaps via builtins
1927+#if (defined(__clang__) && __has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64)) \
1928+ || (defined(__GNUC__ ) && \
1929+ (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
1930+# define BOOST_ENDIAN_INTRINSIC_MSG "__builtin_bswap16, etc."
1931+// prior to 4.8, gcc did not provide __builtin_bswap16 on some platforms so we emulate it
1932+// see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52624
1933+// Clang has a similar problem, but their feature test macros make it easier to detect
1934+# if (defined(__clang__) && __has_builtin(__builtin_bswap16)) \
1935+ || (defined(__GNUC__) &&(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))
1936+# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x) __builtin_bswap16(x)
1937+# else
1938+# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x) __builtin_bswap32((x) << 16)
1939+# endif
1940+# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x) __builtin_bswap32(x)
1941+# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x) __builtin_bswap64(x)
1942+
1943+// Linux systems provide the byteswap.h header, with
1944+#elif defined(__linux__)
1945+// don't check for obsolete forms defined(linux) and defined(__linux) on the theory that
1946+// compilers that predefine only these are so old that byteswap.h probably isn't present.
1947+# define BOOST_ENDIAN_INTRINSIC_MSG "byteswap.h bswap_16, etc."
1948+# include <byteswap.h>
1949+# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x) bswap_16(x)
1950+# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x) bswap_32(x)
1951+# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x) bswap_64(x)
1952+
1953+#elif defined(_MSC_VER)
1954+// Microsoft documents these as being compatible since Windows 95 and specificly
1955+// lists runtime library support since Visual Studio 2003 (aka 7.1).
1956+# define BOOST_ENDIAN_INTRINSIC_MSG "cstdlib _byteswap_ushort, etc."
1957+# include <cstdlib>
1958+# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_2(x) _byteswap_ushort(x)
1959+# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_4(x) _byteswap_ulong(x)
1960+# define BOOST_ENDIAN_INTRINSIC_BYTE_SWAP_8(x) _byteswap_uint64(x)
1961+#else
1962+# define BOOST_ENDIAN_NO_INTRINSICS
1963+# define BOOST_ENDIAN_INTRINSIC_MSG "no byte swap intrinsics"
1964+#endif
1965+
1966+#elif !defined(BOOST_ENDIAN_INTRINSIC_MSG)
1967+# define BOOST_ENDIAN_INTRINSIC_MSG "no byte swap intrinsics"
1968+#endif // BOOST_ENDIAN_NO_INTRINSICS
1969+#endif // BOOST_ENDIAN_INTRINSIC_HPP
1970
1971=== added file '3rd-party/boost/endian/detail/lightweight_test.hpp'
1972--- 3rd-party/boost/endian/detail/lightweight_test.hpp 1970-01-01 00:00:00 +0000
1973+++ 3rd-party/boost/endian/detail/lightweight_test.hpp 2016-04-01 06:55:25 +0000
1974@@ -0,0 +1,223 @@
1975+// boost/endian/detail/lightweight_test.hpp --------------------------------------------//
1976+
1977+#ifndef BOOST_ENDIAN_LIGHTWEIGHT_TEST_HPP
1978+#define BOOST_ENDIAN_LIGHTWEIGHT_TEST_HPP
1979+
1980+// MS compatible compilers support #pragma once
1981+
1982+#if defined(_MSC_VER)
1983+# pragma once
1984+#endif
1985+
1986+//
1987+// Copyright (c) 2002, 2009, 2014 Peter Dimov
1988+// Copyright (2) Beman Dawes 2010, 2011, 2015
1989+// Copyright (3) Ion Gaztanaga 2013
1990+//
1991+// Distributed under the Boost Software License, Version 1.0.
1992+// See http://www.boost.org/LICENSE_1_0.txt
1993+//
1994+
1995+#include <boost/assert.hpp>
1996+#include <boost/current_function.hpp>
1997+#include <boost/core/no_exceptions_support.hpp>
1998+#include <cstring> // for memcmp
1999+#include <iostream>
2000+
2001+// IDE's like Visual Studio perform better if output goes to std::cout or
2002+// some other stream, so allow user to configure output stream:
2003+#ifndef BOOST_LIGHTWEIGHT_TEST_OSTREAM
2004+# define BOOST_LIGHTWEIGHT_TEST_OSTREAM std::cerr
2005+#endif
2006+
2007+namespace boost
2008+{
2009+namespace endian
2010+{
2011+namespace detail
2012+{
2013+
2014+struct report_errors_reminder
2015+{
2016+ bool called_report_errors_function;
2017+
2018+ report_errors_reminder() : called_report_errors_function(false) {}
2019+
2020+ ~report_errors_reminder()
2021+ {
2022+ BOOST_ASSERT(called_report_errors_function); // verify report_errors() was called
2023+ }
2024+};
2025+
2026+inline report_errors_reminder& report_errors_remind()
2027+{
2028+ static report_errors_reminder r;
2029+ return r;
2030+}
2031+
2032+inline int & test_errors()
2033+{
2034+ static int x = 0;
2035+ report_errors_remind();
2036+ return x;
2037+}
2038+
2039+inline void test_failed_impl(char const * expr, char const * file, int line, char const * function)
2040+{
2041+ BOOST_LIGHTWEIGHT_TEST_OSTREAM
2042+ << file << "(" << line << "): test '" << expr << "' failed in function '"
2043+ << function << "'" << std::endl;
2044+ ++test_errors();
2045+}
2046+
2047+inline void error_impl(char const * msg, char const * file, int line, char const * function)
2048+{
2049+ BOOST_LIGHTWEIGHT_TEST_OSTREAM
2050+ << file << "(" << line << "): " << msg << " in function '"
2051+ << function << "'" << std::endl;
2052+ ++test_errors();
2053+}
2054+
2055+inline void throw_failed_impl(char const * excep, char const * file, int line, char const * function)
2056+{
2057+ BOOST_LIGHTWEIGHT_TEST_OSTREAM
2058+ << file << "(" << line << "): Exception '" << excep << "' not thrown in function '"
2059+ << function << "'" << std::endl;
2060+ ++test_errors();
2061+}
2062+
2063+template<class T, class U> inline void test_eq_impl( char const * expr1, char const * expr2,
2064+ char const * file, int line, char const * function, T const & t, U const & u )
2065+{
2066+ if( t == u )
2067+ {
2068+ report_errors_remind();
2069+ }
2070+ else
2071+ {
2072+ BOOST_LIGHTWEIGHT_TEST_OSTREAM
2073+ << file << "(" << line << "): test '" << expr1 << " == " << expr2
2074+ << "' failed in function '" << function << "': "
2075+ << "'" << t << "' != '" << u << "'" << std::endl;
2076+ ++test_errors();
2077+ }
2078+}
2079+
2080+template<class T, class U> inline void test_ne_impl( char const * expr1, char const * expr2,
2081+ char const * file, int line, char const * function, T const & t, U const & u )
2082+{
2083+ if( t != u )
2084+ {
2085+ report_errors_remind();
2086+ }
2087+ else
2088+ {
2089+ BOOST_LIGHTWEIGHT_TEST_OSTREAM
2090+ << file << "(" << line << "): test '" << expr1 << " != " << expr2
2091+ << "' failed in function '" << function << "': "
2092+ << "'" << t << "' == '" << u << "'" << std::endl;
2093+ ++test_errors();
2094+ }
2095+}
2096+
2097+template <class T>
2098+std::string to_hex(const T& x)
2099+{
2100+ const char hex[] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
2101+ std::string tmp;
2102+ const unsigned char* p = reinterpret_cast<const unsigned char*>(&x);
2103+ const unsigned char* e = p + sizeof(T);
2104+
2105+ for (; p < e; ++p)
2106+ {
2107+ tmp += hex[*p >> 4]; // high-order nibble
2108+ tmp += hex[*p & 0x0f]; // low-order nibble
2109+ }
2110+ return tmp;
2111+}
2112+
2113+template<class T, class U> inline bool test_memcmp_eq_impl(char const * expr1,
2114+ char const * expr2, char const * file, int line, char const * function, T const & t,
2115+ U const & u)
2116+{
2117+ BOOST_ASSERT(sizeof(T) == sizeof(U));
2118+ if (sizeof(T) == sizeof(U)
2119+ && std::memcmp(&t, &u, sizeof(T)) == 0)
2120+ {
2121+ report_errors_remind();
2122+ return true;
2123+ }
2124+ else
2125+ {
2126+ BOOST_LIGHTWEIGHT_TEST_OSTREAM
2127+ << file << "(" << line << "): test 'std::memcmp(" << expr1 << ", " << expr2
2128+ << ") == 0' fails in function '" << function << "': "
2129+ << " with values '" << to_hex(t) << "' and '" << to_hex(u) << "'" << std::endl;
2130+ ++test_errors();
2131+ return false;
2132+ }
2133+}
2134+
2135+} // namespace detail
2136+
2137+inline int report_errors()
2138+{
2139+ boost::endian::detail::report_errors_remind().called_report_errors_function = true;
2140+
2141+ int errors = boost::endian::detail::test_errors();
2142+
2143+ if( errors == 0 )
2144+ {
2145+ BOOST_LIGHTWEIGHT_TEST_OSTREAM
2146+ << "No errors detected." << std::endl;
2147+ return 0;
2148+ }
2149+ else
2150+ {
2151+ BOOST_LIGHTWEIGHT_TEST_OSTREAM
2152+ << errors << " error" << (errors == 1? "": "s") << " detected." << std::endl;
2153+ return 1;
2154+ }
2155+}
2156+
2157+} // namespace endian
2158+} // namespace boost
2159+
2160+//////////////////////////////////////////////////////////////////////////////////////////
2161+// TODO: Should all test macros return bool? See BOOST_TEST_MEM_EQ usage in fp_exaustive_test,cpp
2162+//////////////////////////////////////////////////////////////////////////////////////////
2163+
2164+
2165+#define BOOST_TEST(expr) \
2166+ ((expr)? (void)0: ::boost::endian::detail::test_failed_impl(#expr, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION))
2167+
2168+#define BOOST_ERROR(msg) \
2169+ ( ::boost::endian::detail::error_impl(msg, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) )
2170+
2171+#define BOOST_TEST_EQ(expr1,expr2) \
2172+ ( ::boost::endian::detail::test_eq_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
2173+#define BOOST_TEST_NE(expr1,expr2) \
2174+ ( ::boost::endian::detail::test_ne_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
2175+
2176+#define BOOST_TEST_MEM_EQ(expr1,expr2) \
2177+ (::boost::endian::detail::test_memcmp_eq_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2))
2178+
2179+#ifndef BOOST_NO_EXCEPTIONS
2180+ #define BOOST_TEST_THROWS( EXPR, EXCEP ) \
2181+ try { \
2182+ EXPR; \
2183+ ::boost::detail::throw_failed_impl \
2184+ (#EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \
2185+ } \
2186+ catch(EXCEP const&) { \
2187+ } \
2188+ catch(...) { \
2189+ ::boost::detail::throw_failed_impl \
2190+ (#EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \
2191+ } \
2192+ //
2193+#else
2194+ #define BOOST_TEST_THROWS( EXPR, EXCEP )
2195+#endif
2196+
2197+#endif // #ifndef BOOST_ENDIAN_LIGHTWEIGHT_TEST_HPP
2198
2199=== added file '3rd-party/boost/endian/endian.hpp'
2200--- 3rd-party/boost/endian/endian.hpp 1970-01-01 00:00:00 +0000
2201+++ 3rd-party/boost/endian/endian.hpp 2016-04-01 06:55:25 +0000
2202@@ -0,0 +1,19 @@
2203+// boost/endian/endian.hpp -----------------------------------------------------------//
2204+
2205+// Copyright Beman Dawes 2015
2206+
2207+// Distributed under the Boost Software License, Version 1.0.
2208+// See http://www.boost.org/LICENSE_1_0.txt
2209+
2210+// See library home page at http://www.boost.org/libs/endian
2211+
2212+#ifndef BOOST_ENDIAN_ENDIAN_HPP
2213+#define BOOST_ENDIAN_ENDIAN_HPP
2214+
2215+#ifndef BOOST_ENDIAN_DEPRECATED_NAMES
2216+# error "<boost/endian/endian.hpp> is deprecated. Define BOOST_ENDIAN_DEPRECATED_NAMES to use."
2217+#endif
2218+
2219+#include <boost/endian/arithmetic.hpp>
2220+
2221+#endif //BOOST_ENDIAN_ENDIAN_HPP
2222
2223=== added file '3rd-party/boost/endian/std_pair.hpp'
2224--- 3rd-party/boost/endian/std_pair.hpp 1970-01-01 00:00:00 +0000
2225+++ 3rd-party/boost/endian/std_pair.hpp 2016-04-01 06:55:25 +0000
2226@@ -0,0 +1,38 @@
2227+// boost/endian/std_pair.hpp ---------------------------------------------------------//
2228+
2229+// Copyright Beman Dawes 2013
2230+
2231+// Distributed under the Boost Software License, Version 1.0.
2232+// http://www.boost.org/LICENSE_1_0.txt
2233+
2234+//--------------------------------------------------------------------------------------//
2235+
2236+#ifndef BOOST_ENDIAN_STD_PAIR_HPP
2237+#define BOOST_ENDIAN_STD_PAIR_HPP
2238+
2239+#include <boost/endian/conversion.hpp>
2240+#include <utility>
2241+
2242+namespace boost
2243+{
2244+namespace endian
2245+{
2246+ template <class ReversibleValueT, class ReversibleValueU>
2247+ std::pair<ReversibleValueT, ReversibleValueU>
2248+ reverse_value(std::pair<ReversibleValueT, ReversibleValueU> x)
2249+ {
2250+ return std::pair<ReversibleValueT, ReversibleValueU>(reverse_value(x.first),
2251+ reverse_value(x.second));
2252+ }
2253+
2254+ template <class ReversibleT, class ReversibleU>
2255+ void reverse(std::pair<ReversibleT, ReversibleU>& x)
2256+ {
2257+ reverse(x.first);
2258+ reverse(x.second);
2259+ }
2260+
2261+}
2262+}
2263+
2264+#endif // BOOST_ENDIAN_STD_PAIR_HPP
2265
2266=== modified file 'CMakeLists.txt'
2267--- CMakeLists.txt 2014-09-18 23:06:08 +0000
2268+++ CMakeLists.txt 2016-04-01 06:55:25 +0000
2269@@ -34,6 +34,7 @@
2270 pkg_check_modules(PROCESS_CPP process-cpp REQUIRED)
2271 pkg_check_modules(PROPERTIES_CPP properties-cpp REQUIRED)
2272 pkg_check_modules(TRUST_STORE trust-store REQUIRED)
2273+pkg_check_modules(UBUNTU_PLATFORM_HARDWARE_API ubuntu-platform-hardware-api)
2274 #####################################################################
2275 # Enable code coverage calculation with gcov/gcovr/lcov
2276 # Usage:
2277@@ -54,7 +55,23 @@
2278 SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=unused-local-typedefs")
2279 endif (DISABLE_ERROR_ON_LOCAL_TYPEDEFS_WARNINGS)
2280
2281+#
2282+# Code style fixer. We rely on clang-format to adjust the formatting of source code.
2283+#
2284+find_program(CLANG_FORMAT_COMMAND NAMES clang-format-3.6 clang-format-3.5)
2285+if (NOT CLANG_FORMAT_COMMAND)
2286+ message(WARNING "Cannot find clang-format >= clang-format-3.5: formatcode target will not be available")
2287+endif()
2288+
2289+if (CLANG_FORMAT_COMMAND)
2290+ file(GLOB_RECURSE UBUNTU_LOCATION_SERVICE_INTERFACE_HEADER_FILES ${CMAKE_SOURCE_DIR}/include/*.h)
2291+ file(GLOB_RECURSE UBUNTU_LOCATION_SERVICE_IMPLEMENTATION_FILES ${CMAKE_SOURCE_DIR}/src/*.h ${CMAKE_SOURCE_DIR}/src/*.cpp)
2292+ add_custom_target(formatcode ${CLANG_FORMAT_COMMAND} -i ${UBUNTU_LOCATION_SERVICE_INTERFACE_HEADER_FILES} ${UBUNTU_LOCATION_SERVICE_IMPLEMENTATION_FILES} SOURCES _clang-format)
2293+endif()
2294+
2295 include_directories(
2296+ 3rd-party/
2297+
2298 ${Boost_INCLUDE_DIRS}
2299 ${DBUS_INCLUDE_DIRS}
2300 ${DBUS_CPP_INCLUDE_DIRS}
2301
2302=== added file '_clang-format'
2303--- _clang-format 1970-01-01 00:00:00 +0000
2304+++ _clang-format 2016-04-01 06:55:25 +0000
2305@@ -0,0 +1,56 @@
2306+---
2307+Language: Cpp
2308+AccessModifierOffset: -4
2309+ConstructorInitializerIndentWidth: 4
2310+AlignEscapedNewlinesLeft: false
2311+AlignTrailingComments: true
2312+AllowAllParametersOfDeclarationOnNextLine: true
2313+AllowShortBlocksOnASingleLine: false
2314+AllowShortIfStatementsOnASingleLine: false
2315+AllowShortLoopsOnASingleLine: false
2316+AllowShortFunctionsOnASingleLine: All
2317+AlwaysBreakTemplateDeclarations: false
2318+AlwaysBreakBeforeMultilineStrings: false
2319+BreakBeforeBinaryOperators: false
2320+BreakBeforeTernaryOperators: true
2321+BreakConstructorInitializersBeforeComma: false
2322+BinPackParameters: true
2323+ColumnLimit: 0
2324+ConstructorInitializerAllOnOneLineOrOnePerLine: false
2325+DerivePointerAlignment: false
2326+ExperimentalAutoDetectBinPacking: false
2327+IndentCaseLabels: false
2328+IndentWrappedFunctionNames: false
2329+IndentFunctionDeclarationAfterType: false
2330+MaxEmptyLinesToKeep: 1
2331+KeepEmptyLinesAtTheStartOfBlocks: true
2332+NamespaceIndentation: None
2333+ObjCSpaceAfterProperty: false
2334+ObjCSpaceBeforeProtocolList: true
2335+PenaltyBreakBeforeFirstCallParameter: 19
2336+PenaltyBreakComment: 300
2337+PenaltyBreakString: 1000
2338+PenaltyBreakFirstLessLess: 120
2339+PenaltyExcessCharacter: 1000000
2340+PenaltyReturnTypeOnItsOwnLine: 60
2341+PointerAlignment: Left
2342+SpacesBeforeTrailingComments: 1
2343+Cpp11BracedListStyle: true
2344+Standard: Cpp11
2345+IndentWidth: 4
2346+TabWidth: 8
2347+UseTab: Never
2348+BreakBeforeBraces: Allman
2349+SpacesInParentheses: false
2350+SpacesInAngles: false
2351+SpaceInEmptyParentheses: false
2352+SpacesInCStyleCastParentheses: false
2353+SpacesInContainerLiterals: true
2354+SpaceBeforeAssignmentOperators: true
2355+ContinuationIndentWidth: 4
2356+CommentPragmas: '^ IWYU pragma:'
2357+ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
2358+SpaceBeforeParens: ControlStatements
2359+DisableFormat: false
2360+...
2361+
2362
2363=== added file 'astyle-config'
2364--- astyle-config 1970-01-01 00:00:00 +0000
2365+++ astyle-config 2016-04-01 06:55:25 +0000
2366@@ -0,0 +1,43 @@
2367+# Options for formatting code with astyle.
2368+#
2369+# This helps to make code match the style guide.
2370+#
2371+# Use like this:
2372+#
2373+# astyle --options=astyle-config mfile.h myfile.cpp
2374+#
2375+# Occasionally, astyle does something silly (particularly with lambdas), so it's
2376+# still necessary to scan the changes for things that are wrong.
2377+# But, for most files, it does a good job.
2378+#
2379+# Please consider using this before checking code in for review. Code reviews shouldn't
2380+# have to deal with layout issues, they are just a distraction. It's better to be able
2381+# to focus on semantics in a code review, with style issues out of the way.
2382+
2383+--formatted
2384+--style=allman
2385+--min-conditional-indent=2
2386+--indent-switches
2387+--max-instatement-indent=120
2388+--pad-header
2389+--align-pointer=type
2390+--align-reference=type
2391+--convert-tabs
2392+--close-templates
2393+--max-code-length=120
2394+
2395+# --pad-oper
2396+#
2397+# Commented out for now. It changes
2398+#
2399+# for (int i=0; i<10; ++i)
2400+# to
2401+# for (int i = 0; i < 10; ++i)
2402+#
2403+# Unfortunately, it also messes with rvalue references:
2404+#
2405+# ResourcePtr& operator=(ResourcePtr&& r);
2406+#
2407+# becomes:
2408+#
2409+# ResourcePtr& operator=(ResourcePtr && r);
2410
2411=== modified file 'debian/changelog'
2412--- debian/changelog 2015-07-27 18:07:37 +0000
2413+++ debian/changelog 2016-04-01 06:55:25 +0000
2414@@ -36,6 +36,117 @@
2415
2416 -- CI Train Bot <ci-train-bot@canonical.com> Thu, 28 May 2015 11:40:58 +0000
2417
2418+location-service (2.1+15.04.20160331.2-0ubuntu1) vivid; urgency=medium
2419+
2420+ * Log to stderr by default, relying on upstart to rotate logs
2421+ appropriately. (LP: #1447110)
2422+
2423+ -- Thomas Voß <ci-train-bot@canonical.com> Thu, 31 Mar 2016 11:03:46 +0000
2424+
2425+location-service (2.1+15.04.20160308.1-0ubuntu1) vivid; urgency=medium
2426+
2427+ * Add SntpClient for querying reference time information.
2428+
2429+ -- Thomas Voß <ci-train-bot@canonical.com> Tue, 08 Mar 2016 08:54:07 +0000
2430+
2431+location-service (2.1+15.04.20160302.1-0ubuntu1) vivid; urgency=medium
2432+
2433+ * Remove explicit option to disable satellite-based positioning
2434+ services.
2435+
2436+ -- Thomas Voß <ci-train-bot@canonical.com> Wed, 02 Mar 2016 15:28:02 +0000
2437+
2438+location-service (2.1+15.04.20160106-0ubuntu1) vivid; urgency=medium
2439+
2440+ [ Alberto Mardegan ]
2441+ * Set debian source format to "3.0 (native)"
2442+
2443+ [ Scott Sweeny ]
2444+ * Allow providers to register themselves asynchronously (LP: #1415029)
2445+
2446+ -- Thomas Voß <ci-train-bot@canonical.com> Wed, 06 Jan 2016 16:15:29 +0000
2447+
2448+location-service (2.1+15.04.20151211-0ubuntu1) vivid; urgency=medium
2449+
2450+ * Account for changes in trust-store w.r.t. assembling the description
2451+ of a trust prompt.
2452+
2453+ -- Thomas Voß <ci-train-bot@canonical.com> Fri, 11 Dec 2015 08:57:44 +0000
2454+
2455+location-service (2.1+15.04.20151209-0ubuntu1) vivid; urgency=medium
2456+
2457+ * Fix settings not being applied correctly.
2458+
2459+ -- Thomas Voß <ci-train-bot@canonical.com> Wed, 09 Dec 2015 15:22:22 +0000
2460+
2461+location-service (2.1+15.04.20151202.1-0ubuntu1) vivid; urgency=medium
2462+
2463+ * Ensure that event connections are cleaned up on destruction. (LP:
2464+ #1480877)
2465+
2466+ -- Thomas Voß <ci-train-bot@canonical.com> Wed, 02 Dec 2015 12:12:21 +0000
2467+
2468+location-service (2.1+15.04.20151127-0ubuntu1) vivid; urgency=medium
2469+
2470+ [ Alberto Mardegan ]
2471+ * Send last known position on session start
2472+
2473+ [ CI Train Bot ]
2474+ * New rebuild forced.
2475+
2476+ [ Thomas Voß ]
2477+ * Factor out service::Runtime from daemon.cpp into its own .h/.cpp
2478+ pair of files. Add test cases around correct operation of
2479+ service::Runtime. added:
2480+ src/location_service/com/ubuntu/location/service/runtime.cpp
2481+ src/location_service/com/ubuntu/location/service/runtime.h
2482+ tests/runtime_test.cpp
2483+
2484+ [ thomas-voss ]
2485+ * Factor out service::Runtime from daemon.cpp into its own .h/.cpp
2486+ pair of files. Add test cases around correct operation of
2487+ service::Runtime. added:
2488+ src/location_service/com/ubuntu/location/service/runtime.cpp
2489+ src/location_service/com/ubuntu/location/service/runtime.h
2490+ tests/runtime_test.cpp
2491+
2492+ -- Thomas Voß <ci-train-bot@canonical.com> Fri, 27 Nov 2015 13:00:33 +0000
2493+
2494+location-service (2.1+15.04.20151113-0ubuntu1) vivid; urgency=medium
2495+
2496+ * Adjust default timeout for downloading GPS XTRA data.
2497+
2498+ -- Thomas Voß <ci-train-bot@canonical.com> Fri, 13 Nov 2015 10:33:56 +0000
2499+
2500+location-service (2.1+15.04.20151109.2-0ubuntu1) vivid; urgency=medium
2501+
2502+ [ Alberto Mardegan ]
2503+ * Make sure that injected time is given in milliseconds
2504+
2505+ [ Thomas Voß ]
2506+ * Cherry-pick rev. 196 and 199 from lp:location-service. The changes
2507+ got accidentally removed by merging the outstanding documentation
2508+ branch.
2509+ * Handle responses of clients to updates asynchronously. Rely on
2510+ dummy::ConnectivityManager as harvesting is disabled anyway. (LP:
2511+ #1462664, #1387643)
2512+
2513+ -- David Barth <david.barth@canonical.com> Mon, 09 Nov 2015 20:48:48 +0000
2514+
2515+location-service (2.1+15.04.20151022-0ubuntu1) vivid; urgency=medium
2516+
2517+ [ Thomas Voß ]
2518+ * Add documentation for debugging, hacking and debugging the location
2519+ service. Pull manual testing instructions over from the wiki. Add
2520+ tools for formatting the source.
2521+
2522+ [ thomas-voss ]
2523+ * Add documentation for debugging, hacking and debugging the location
2524+ service. Pull manual testing instructions over from the wiki. Add
2525+ tools for formatting the source.
2526+
2527+ -- Thomas Voß <ci-train-bot@canonical.com> Thu, 22 Oct 2015 07:16:50 +0000
2528+
2529 location-service (2.1+15.04.20150427.1-0ubuntu1) vivid; urgency=medium
2530
2531 [ CI Train Bot ]
2532
2533=== modified file 'debian/source/format'
2534--- debian/source/format 2014-07-30 14:15:06 +0000
2535+++ debian/source/format 2016-04-01 06:55:25 +0000
2536@@ -1,1 +1,1 @@
2537-3.0 (quilt)
2538+3.0 (native)
2539
2540=== modified file 'doc/Doxyfile.in'
2541--- doc/Doxyfile.in 2014-05-19 09:55:25 +0000
2542+++ doc/Doxyfile.in 2016-04-01 06:55:25 +0000
2543@@ -748,7 +748,7 @@
2544 # directories that contain image that are included in the documentation (see
2545 # the \image command).
2546
2547-IMAGE_PATH =
2548+IMAGE_PATH = @CMAKE_CURRENT_SOURCE_DIR@/images
2549
2550 # The INPUT_FILTER tag can be used to specify a program that doxygen should
2551 # invoke to filter for each input file. Doxygen will invoke the filter program
2552@@ -1463,7 +1463,7 @@
2553 # generate an XML file that captures the structure of
2554 # the code including all documentation.
2555
2556-GENERATE_XML = NO
2557+GENERATE_XML = YES
2558
2559 # The XML_OUTPUT tag is used to specify where the XML pages will be put.
2560 # If a relative path is entered the value of OUTPUT_DIRECTORY will be
2561
2562=== added file 'doc/daemon_and_cli.md'
2563--- doc/daemon_and_cli.md 1970-01-01 00:00:00 +0000
2564+++ doc/daemon_and_cli.md 2016-04-01 06:55:25 +0000
2565@@ -0,0 +1,55 @@
2566+# Service Daemon and CLI
2567+
2568+The location service offers a daemon executable and a corresponding
2569+command-line interface for interacting with it. The daemon does not
2570+necessarily require root privileges, but might so depending on your
2571+configuration.
2572+
2573+Run the following command to receive an overview of the arguments to
2574+the daemon:
2575+
2576+ ubuntu-location-serviced --help
2577+
2578+An example invocation of the daemon, configuring a GPS provider that
2579+relies on the Android HAL to talk to the chipset, exposing the service
2580+on the system DBus instance:
2581+
2582+ ubuntu-location-serviced --bus system --provider gps::Provider
2583+
2584+The cli allows for querying properties of a running service instance, e.g.:
2585+
2586+ ubuntu-location-serviced-cli --bus system --get --property is_online
2587+
2588+## Configuring an Out-Of-Process Provider
2589+
2590+If you want to run a provider out of process, the daemon executable
2591+allows you to do so by instantiating a so-called remote provider. The
2592+following invocation of the service tries to connect to the provider
2593+instance described by the given unique DBus name and path.
2594+
2595+ ubuntu-location-serviced \
2596+ --bus system \
2597+ --provider remote::Provider \
2598+ --remote::Provider::bus=system \
2599+ --remote::Provider::name=com.ubuntu.location.provider.Gps \
2600+ --remote::Provider::path=/
2601+
2602+Please note that the service allows for decorating provider names to
2603+uniquely identify per provider configuration options and to allow for
2604+loading more than one provider of a certain kind. The following
2605+configuration configures two remote providers, one relying on GPS
2606+(decorated with @gps) and another one relying on network-based
2607+positioning (decorated with @network):
2608+
2609+ ubuntu-location-serviced \
2610+ --bus system \
2611+ --provider remote::Provider@gps \
2612+ --remote::Provider@gps::bus=system \
2613+ --remote::Provider@gps::name=com.ubuntu.location.provider.Gps \
2614+ --remote::Provider@gps::path=/ \
2615+ --provider remote::Provider@network \
2616+ --remote::Provider@network::bus=system \
2617+ --remote::Provider@network::name=com.ubuntu.location.provider.Network \
2618+ --remote::Provider@network::path=/
2619+
2620+
2621
2622=== added file 'doc/debugging.md'
2623--- doc/debugging.md 1970-01-01 00:00:00 +0000
2624+++ doc/debugging.md 2016-04-01 06:55:25 +0000
2625@@ -0,0 +1,91 @@
2626+# Debugging
2627+
2628+Location not working? Here's how to debug.
2629+
2630+## Layers
2631+
2632+Test in OSMTouch (QML app using Qt API) before testing in webapps or
2633+webbrowser app. Different results? File a bug where it doesn't
2634+work. Same result of no location? Next step.
2635+
2636+## Check that stack works with dummy provider
2637+
2638+Edit /etc/init/ubuntu-location-provider.override to start
2639+location-serviced with just the dummy provider; this should
2640+work. Doesn't work? File a bug against location-service. Works? Reset
2641+config to defaults and try the next thing.
2642+
2643+## Hardware GPS breaking all of location-service
2644+
2645+GPS provider is built-in into location-service and might break all of
2646+it if it goes south (working on splitting it out); try enabling only
2647+the HERE provider on the location-serviced command-line and see if
2648+that works. Works? File a bug against location-service. Doesn't work?
2649+Move on.
2650+
2651+## HERE test
2652+
2653+To test whether the low-level HERE stack gets a location, put
2654+http://people.canonical.com/~lool/espoo-cli on your phone (will be
2655+included along HERE bits in the future) and run with:
2656+
2657+ chmod a+x espoo-cli
2658+ GLOG_logtostderr=1 GLOG_v=100 LD_LIBRARY_PATH=/custom/vendor/here/location-provider/lib/arm-linux-gnueabihf ./espoo-cli 5
2659+
2660+NB: 5 is the number of location updates after which the tool exits;
2661+updates should come in at approx 15s interval. Output looks like:
2662+
2663+ I1101 21:30:01.285964 4403 cli.cpp:117] Requested number of updates is 2
2664+ I1101 21:30:01.299002 4403 cli.cpp:133] Starting location updates
2665+ I1101 21:30:01.301888 4403 cli.cpp:141] Starting GLib main loop
2666+ I1101 21:30:11.304612 4403 cli.cpp:158] Location: tstamp=1414891811 lat=xyz long=foo hor. acc.=2569 alt=nan vert. acc.=nan tech=cell
2667+ I1101 21:30:11.306061 4403 cli.cpp:170] Remaining updates: 1
2668+ I1101 21:30:26.736821 4403 cli.cpp:158] Location: tstamp=1414891826 lat=xyz long=foo hor. acc.=2824 alt=nan vert. acc.=nan tech=cell
2669+ I1101 21:30:26.738348 4403 cli.cpp:148] Stopping location updates
2670+
2671+Low-level HERE stack works but location-serviced with just HERE
2672+provider doesn't work? File a bug against espoo projet (HERE) and/or
2673+location-service. Low-level HERE stack doesn't work? Move on
2674+
2675+## location-service and espoo-service debug
2676+
2677+Collect some debug data by editing /etc/init/ubuntu-espoo-service.conf
2678+and /etc/init/ubuntu-location-service.override and changing the start
2679+sequence to add some env vars:
2680+
2681+ export GLOG_v=200
2682+
2683+before the exec. Reboot, and start some app. You should have some log
2684+files under /var/log/upstart/ubuntu-espoo-service.log and
2685+/var/log/upstart/ubuntu-location-service.log to attach to a bug
2686+report; e.g. a working espoo log looks like this:
2687+
2688+ WARNING: Logging before InitGoogleLogging() is written to STDERR
2689+ I1105 16:30:10.221474 1620 provider.cpp:568] StartPositionUpdates
2690+ I1105 16:30:10.224901 1620 provider.cpp:122] Successfully started position updates.
2691+ I1105 16:30:10.228739 1620 provider.cpp:596] StartVelocityUpdates
2692+ I1105 16:30:13.046851 1621 provider.cpp:83] Received location: Position(lat: Coordinate(12.34 deg), lon: Coordinate(12.34 deg), alt: Coordinate(nan m), hor.acc.: 1430 m, ver.acc.: nan m)
2693+
2694+No position there? check connectivity API works by running:
2695+
2696+ cd /tmp
2697+ wget http://people.ubuntu.com/~lool/connectivity
2698+ GLOG_v=200 GLOG_logtostderr=1 ./connectivity
2699+
2700+you should see something like:
2701+
2702+ I1105 16:47:26.431466 11140 cached_radio_cell.cpp:160] (mcc: 123, mnc: 2, lac: 1234, id: 123456, asu: 1)
2703+ I1105 16:47:26.533818 11140 connectivity.cpp:47] Is wifi enabled: true
2704+ I1105 16:47:26.533963 11140 connectivity.cpp:48] Is wifi hw enabled: true
2705+ I1105 16:47:26.534010 11140 connectivity.cpp:49] Is wwan enabled: true
2706+ I1105 16:47:26.534050 11140 connectivity.cpp:50] Is wwan hw enabled: true
2707+ I1105 16:47:26.534442 11140 connectivity.cpp:122] umts(mcc: 123, mnc: 2, lac: 1234, id: 123456, asu: 1)
2708+ I1105 16:47:26.534633 11140 connectivity.cpp:155] (bssid: 12:12:12:12:12:12, ssid: xyz, last seen: 1415224046, mode: Mode::infrastructure, frequency: 2442, strength: 63)
2709+ I1105 16:47:26.534828 11140 connectivity.cpp:155] (bssid: 12:12:12:12:12:12, ssid: boing, last seen: 1415224046, mode: Mode::infrastructure, frequency: 2467, strength: 57)
2710+
2711+Also, please attach output of /usr/share/ofono/scripts/list-modems > list-modems-output.txt
2712+Please note that the command might take ~1 minute to complete.
2713+
2714+TODO: document dbus-monitor / d-feet capturing of client / system traffic with snooping config.
2715+
2716+
2717
2718=== added file 'doc/hacking.md'
2719--- doc/hacking.md 1970-01-01 00:00:00 +0000
2720+++ doc/hacking.md 2016-04-01 06:55:25 +0000
2721@@ -0,0 +1,146 @@
2722+# Hacking
2723+
2724+
2725+## Building the code
2726+
2727+By default, the code is built in release mode. To build a debug version, use
2728+
2729+ $ mkdir builddebug
2730+ $ cd builddebug
2731+ $ cmake -DCMAKE_BUILD_TYPE=debug ..
2732+ $ make
2733+
2734+For a release version, use -DCMAKE_BUILD_TYPE=release
2735+
2736+## Running the tests
2737+
2738+ $ make
2739+ $ make test
2740+
2741+Note that "make test" alone is dangerous because it does not rebuild
2742+any tests if either the library or the test files themselves need
2743+rebuilding. It's not possible to fix this with cmake because cmake cannot
2744+add build dependencies to built-in targets. To make sure that everything
2745+is up-to-date, run "make" before running "make test"!
2746+
2747+## Coverage
2748+
2749+To build with the flags for coverage testing enabled and get coverage:
2750+
2751+ $ mkdir buildcoverage
2752+ $ cd buildcoverage
2753+ $ cmake -DCMAKE_BUILD_TYPE=coverage
2754+ $ make
2755+ $ make test
2756+ $ make coverage
2757+
2758+Unfortunately, it is not possible to get 100% coverage for some files,
2759+mainly due to gcc's generation of two destructors for dynamic and non-
2760+dynamic instances. For abstract base classes and for classes that
2761+prevent stack and static allocation, this causes one of the destructors
2762+to be reported as uncovered.
2763+
2764+There are also issues with some functions in header files that are
2765+incorrectly reported as uncovered due to inlining, as well as
2766+the impossibility of covering defensive assert(false) statements,
2767+such as an assert in the default branch of a switch, where the
2768+switch is meant to handle all possible cases explicitly.
2769+
2770+If you run a binary and get lots of warnings about a "merge mismatch for summaries",
2771+this is caused by having made changes to the source that add or remove code
2772+that was previously run, so the new coverage output cannot sensibly be merged
2773+into the old coverage output. You can get rid of this problem by running
2774+
2775+ $ make clean-coverage
2776+
2777+This deletes all the .gcda files, allowing the merge to (sometimes) succeed again.
2778+If this doesn't work either, the only remedy is to do a clean build.
2779+
2780+If lcov complains about unrecognized lines involving '=====',
2781+you can patch geninfo and gcovr as explained here:
2782+
2783+https://bugs.launchpad.net/gcovr/+bug/1086695/comments/2
2784+
2785+## Code style
2786+
2787+We use a format tool that fixes a whole lot of issues
2788+regarding code style. The formatting changes made by
2789+the tool are generally sensible (even though they may not be your
2790+personal preference in all cases). If there is a case where the formatting
2791+really messes things up, consider re-arranging the code to avoid the problem.
2792+The convenience of running the entire code base through the pretty-printer
2793+far outweighs any minor glitches with pretty printing, and it means that
2794+we get consistent code style for free, rather than endlessly having to
2795+watch out for formatting issues during code reviews.
2796+
2797+As of clang-format-3.7, you can use
2798+
2799+ // clang-format off
2800+ void unformatted_code ;
2801+ // clang-format on
2802+
2803+to suppress formatting for a section of code.
2804+
2805+To format specific files:
2806+
2807+ ${CMAKE_BINARY_DIR}/tools/formatcode x.cpp x.h
2808+
2809+If no arguments are provided, formatcode reads stdin and writes
2810+stdout, so you can easily pipe code into the tool from within an
2811+editor. For example, to reformat the entire file in vi (assuming
2812+${CMAKE_BINARY_DIR}/tools is in your PATH):
2813+
2814+ 1G!Gformatcode
2815+
2816+To re-format all source and header files in the tree:
2817+
2818+ $ make formatcode
2819+
2820+## Thread and address sanitizer
2821+
2822+Set SANITIZER to "thread" or "address" to build with the
2823+corresponding sanitizer enabled.
2824+
2825+## Updating symbols file
2826+
2827+To easily spot new/removed/changed symbols in the library, the debian
2828+package maintains a .symbols file that lists all exported symbols
2829+present in the library .so. If you add new public symbols to the library,
2830+it's necessary to refresh the symbols file, otherwise the package will
2831+fail to build. The easiest way to do that is using bzr-builddeb:
2832+
2833+ $ bzr bd -- -us -uc -j8 # Don't sign source package or changes file, 8 compiles in parallel
2834+ $ # this will exit with an error if symbols file isn't up-to-date
2835+ $ cd ../build-area/location-service-[version]
2836+ $ ./obj-[arch]/tools/symbol_diff
2837+
2838+This creates a diff of the symbols in /tmp/symbols.diff.
2839+(The demangled symbols from the debian build are in ./new_symbols.)
2840+
2841+Review any changes in /tmp/symbols.diff. If they are OK:
2842+
2843+ $ cd -
2844+ $ patch -p0 < /tmp/symbols.diff
2845+
2846+## ABI compliance test
2847+
2848+To use this, install abi-compliance-checker package from the archives.
2849+
2850+You can use abi-compliance-checker to test whether a particular build
2851+is ABI compatible with another build. The tool does some source-level
2852+analysis in addition to checking library symbols, so it catches things
2853+that are potentially dangerous, but won't be picked up by just looking
2854+at the symbol table.
2855+
2856+Assume you have built devel in src/devel, and you have a later build
2857+in src/mybranch and want to check that mybranch is still compatible.
2858+To run the compliance test:
2859+
2860+ $ cd src
2861+ $ abi-compliance-checker -lib libunity-scopes.so -old devel/build/test/abi-compliance/abi.xml -new mybranch/build/test/abi-compliance/abi.xml
2862+
2863+The script will take about two minutes to run. Now point your browser at
2864+
2865+ src/compat_reports/libunity-scopes.so/[version]_to_[version]/compat_report.html
2866+
2867+The report provides a nicely layed-out page with all the details.
2868
2869=== added directory 'doc/images'
2870=== added file 'doc/images/LocationServiceHighLevel.png'
2871Binary files doc/images/LocationServiceHighLevel.png 1970-01-01 00:00:00 +0000 and doc/images/LocationServiceHighLevel.png 2016-04-01 06:55:25 +0000 differ
2872=== added file 'doc/intro.md'
2873--- doc/intro.md 1970-01-01 00:00:00 +0000
2874+++ doc/intro.md 2016-04-01 06:55:25 +0000
2875@@ -0,0 +1,67 @@
2876+# Introduction {#mainpage}
2877+
2878+Ubuntu's location service is a central hub for multiplexing access to
2879+positioning subsystems available via hard- and software. It provides a
2880+client API offering positioning capabilities to applications and other
2881+system components, abstracting away the details of individual
2882+positioning solutions.
2883+
2884+## Vocabulary
2885+
2886+To make the remainder of this documentation as easily understandable
2887+as possible, we start over with introducing some vocabulary:
2888+
2889+- Engine:
2890+ Responsible for handling input from multiple positioning
2891+ subsystems and maintaining the state of the overall system. Think
2892+ about it like the heart of the system.
2893+
2894+- Provider:
2895+ A positioning subsystem that feeds into the positioning
2896+ engine. Common examples are a GPS provider or a network-based
2897+ positioning provider.
2898+
2899+- Service:
2900+ The point of entry for applications and services that would
2901+ like to receive position data.
2902+
2903+- Session:
2904+ In order to receive position information, every application
2905+ or service has to create a session with the location Service.
2906+
2907+- Update: An update is a timestamped entity to a certain type of data.
2908+
2909+- [WGS84, http://en.wikipedia.org/wiki/World_Geodetic_System]: The coordinate system that is used throughout the entire location subsystem.
2910+
2911+## Architectural Overview
2912+
2913+The high-level architecture of the service is shown in the following diagram:
2914+
2915+![High-level architectural overview](images/LocationServiceHighLevel.png)
2916+
2917+In this diagram, the configuration of the engine refers to:
2918+
2919+ * The current state of any satellite-based positioning subsystems. Can either be off or on.
2920+ * The current state of reporting facilities responsible for harvesting wifi and cell id measurements together with location information and sending them off to remote services. Can either be off or on.
2921+ * The overall state of the engine. Can either be off, on or active.
2922+
2923+The Service takes this configuration and exposes it to client
2924+applications. In addition, mainly for debugging purposes, the set of
2925+currently visible satellites (if any) is maintained and exposed to
2926+privileged client applications.
2927+
2928+## Privacy & Access Control
2929+
2930+Location information is highly privacy relevant. For this reason, the
2931+location service is deeply integrated with AppArmor and Ubuntu's
2932+overall trust infrastructure. Every incoming session request is
2933+validated and if in doubt, the user is asked to explicitly grant trust
2934+to the application requesting access to positioning
2935+information. Please see [@ref com::ubuntu::location::service::PermissionManager]
2936+for further details.
2937+
2938+In addition, the location service allows for selectively adjusting the
2939+accuracy and reporting setup of the location Engine to provide further
2940+fine-grained control over the exposed data to user. Within this setup,
2941+a user is able to entirely disable all positioning.
2942+
2943
2944=== added file 'doc/manual_testing.md'
2945--- doc/manual_testing.md 1970-01-01 00:00:00 +0000
2946+++ doc/manual_testing.md 2016-04-01 06:55:25 +0000
2947@@ -0,0 +1,174 @@
2948+# Manual Testplan
2949+
2950+[TOC]
2951+
2952+While the automatic test suite of the location service is
2953+comprehensive and covers large parts of the functionality of the
2954+service itself, we still provide an additional level of acceptance
2955+testing covering the entire location stack/experience as a part of
2956+this document.
2957+
2958+## Dependents/Clients
2959+
2960+ - qtubuntu-sensors
2961+ - Qt/QML applications:
2962+ - Browser
2963+ - osmTouch
2964+
2965+## Test Plan
2966+
2967+This test plan is not supposed to be complete; use it to guide your
2968+manual testing so you don't miss big functional areas that are part of
2969+the component; also this should be used as guideline to inspire the
2970+exploratory testing which should be adapted smartly based on the real
2971+content of a MP.
2972+
2973+Please note that if you're testing the GPS provider, the location
2974+service relies on GPS hardware to obtain a location fix. For that, it
2975+might be required that you execute the manual steps listed before
2976+close to a window or ideally outside, with good satellite visibility
2977+conditions.
2978+
2979+__Note: It can take up to 15 minutes for the GPS device to get a lock, due to lack of assisted GPS__
2980+
2981+ - Install latest image on phone
2982+ - Install freshly built MPs that are needed for landing
2983+
2984+Depending on the default configuration of location-service on the
2985+image, you may skip parts of this test plan. E.g. if GPS hardware is
2986+disabled, skip this part. You can see which providers are enabled by
2987+looking at the list of providers on the location-serviced command-line
2988+(`ps fauxw | grep location-service`, then look at the `--provider`
2989+flags).
2990+
2991+### Dummy provider
2992+
2993+This tests forces location-service to use only the dummy provider;
2994+this providers a baseline test for the app to trust-store to
2995+location-service path.
2996+
2997+ - phablet-shell into the phone:
2998+ - `sudo service ubuntu-location-service stop && sudo /usr/bin/ubuntu-location-serviced --bus system --provider dummy::Provider --dummy::Provider::ReferenceLocationLat=48.857503 --dummy::Provider::ReferenceLocationLon=2.295072`
2999+ - As phablet, start the trust store again (it stops when location-service is stopped) with: `start ubuntu-location-service-trust-stored`
3000+ - Ensure that all AP tests for the webbrowser pass as expected
3001+ - Point the browser to maps.google.com (alternatively: here.com, maps.bing.fr).
3002+ - Request centering the map on current position and observe if it works correctly (should show the Eiffel tower)
3003+ - Install osmTouch from the app store
3004+ - Launch osmTouch and check if it centers on the Eiffel tower.
3005+ - Install a maps webapp such as HERE or Google Maps webapp from the app store
3006+ - Launch maps webapp and check if it centers on the Eiffel tower.
3007+
3008+### GPS Test Plan
3009+
3010+This applies only if GPS provider is enabled.
3011+
3012+ - (If applicable: Remember to add the silo you are testing)
3013+ - `sudo apt-get install ubuntu-location-service-tests`
3014+ - If you want to send off crowdsourced information, i.e., information about visible wifis and visible radio cells for the obtained location fixes to Mozilla's location service and our own instance:
3015+ - `sudo GLOG_v=40 GLOG_logtostderr=1 GPS_TEST_ENABLE_HARVESTING_DURING_TESTS=1 /usr/bin/uls-tests/gps_provider_test --gtest_filter=*.time_to_first_fix_cold_start_without_supl_benchmark_requires_hardware`
3016+ - If you '''don't''' want to send off crowdsourced information:
3017+ - `sudo GLOG_v=40 GLOG_logtostderr=1 /usr/bin/uls-tests/gps_provider_test --gtest_filter=*.time_to_first_fix_cold_start_without_supl_benchmark_requires_hardware`
3018+
3019+ - The test will output a lot of diagnostic information to the
3020+ terminal and will take ~30 minutes. If satellite visibility is
3021+ limited, it can take even longer. The test will automatically
3022+ report success or failure.
3023+
3024+### Preliminary AGPS Test Plan
3025+
3026+**Does not apply to Krillin**
3027+
3028+Please note that the Krillin GPS chipset driver and its integration
3029+within Ubuntu does not support vanilla AGPS (i.e., SUPL) right
3030+now. For that, this test case is irrelevant for Krillin and is likely
3031+to fail.
3032+
3033+This applied only if GPS provider and some other provider (giving
3034+_A_ssistance) are enabled.
3035+
3036+ - Add the silo.
3037+ - `sudo apt-get install ubuntu-location-service-tests`
3038+ - Obtain a (rough) location estimate for your current location on Google maps.
3039+ - Make sure to replace INSERT_ESTIMATE_HERE with the respective
3040+ values obtained from Google maps.
3041+ - If you want to send off crowdsourced information, i.e., information
3042+ about visible wifis and visible radio cells for the obtained
3043+ location fixes to Mozilla's location service and our own instance:
3044+ - `sudo GLOG_v=40 GLOG_logtostderr=1 GPS_TEST_ENABLE_HARVESTING_DURING_TESTS=1 GPS_TEST_REF_LAT=INSERT_ESTIMATE_HERE GPS_TEST_REF_LON=INSERT_ESTIMATE_HERE /usr/bin/uls-tests/gps_provider_test --gtest_filter=*.time_to_first_fix_cold_start_with_supl_benchmark_requires_hardware`
3045+ - If you '''don't''' want to send off crowdsourced information:
3046+ - `sudo GLOG_v=40 GLOG_logtostderr=1 GPS_TEST_REF_LAT=INSERT_ESTIMATE_HERE GPS_TEST_REF_LON=INSERT_ESTIMATE_HERE /usr/bin/uls-tests/gps_provider_test --gtest_filter=*.time_to_first_fix_cold_start_with_supl_benchmark_requires_hardware`
3047+
3048+ - The test will output a lot of diagnostic information to the
3049+ terminal and will take ~10 minutes or less. The test will
3050+ automatically report success or failure.
3051+
3052+### Espoo / HERE provider
3053+
3054+This applies only if the Espoo / HERE remote provider is enabled. This
3055+provider should be enabled by default and may either work standalone
3056+as the only provider or as an assistance for the GPS hardware to lock.
3057+
3058+ - Add the silo; special exception for lxc-android-config: see https://wiki.ubuntu.com/Touch/Testing/lxc-android-config
3059+ - If noted, deploy an updated custom tarball:
3060+ - Download the tarball under /tmp ('''NOT''' under /)
3061+ - Unpack there: `cd /tmp; sudo tar xvf custom-vendor-here-*.tar.xz`
3062+ - Remove older bits: `sudo rm -rf /custom/vendor/here/`
3063+ - Update custom bits: `sudo mv /tmp/system/custom/vendor/here /custom/vendor`
3064+ - Reboot
3065+ - After boot, check you have these three processes running on top of location-service:
3066+ - slpgwd
3067+ - posclientd
3068+ - ubuntu-espoo-service
3069+ - Make sure SIM is unlocked and attached to the network (has some reliable signal) and that WiFi is turned on.
3070+ - Install OSMTouch app
3071+ - Run OSMTouch app, hit the position button every other second until you get a blue circle showing your current location;
3072+
3073+# Connectivity API
3074+
3075+For integration of network-based positioning providers, the location
3076+service offers a connectivity API that provides access to wifi and
3077+cell measurements as well as information on the current overall
3078+connectivity status of the device. Please execute the following
3079+commands on a newly flashed device with a writable image:
3080+
3081+ - `sudo apt-get update && sudo apt-get build-dep location-service && sudo apt-get install libubuntu-location-service-dev ubuntu-location-service-examples`
3082+ - `mkdir /tmp/build && cd /tmp/build && cmake /usr/share/ubuntu-location-service/examples/standalone/connectivity/ && make`
3083+ - `GLOG_logtostderr=1 ./connectivity`
3084+
3085+Verify that the output looks similar to:
3086+
3087+ phablet@ubuntu-phablet:/tmp/build$ ./connectivity
3088+ Is wifi enabled: true
3089+ Is wifi hw enabled: true
3090+ Is wwan enabled: false
3091+ Is wwan hw enabled: true
3092+ umts(mcc: 262, mnc: 2, lac: 5313, id: 131948771, asu: 7)
3093+ (bssid: BC:F2:AF:AF:19:A2, ssid: devolo-bcf2afaf19a2, last seen: 1408955086, mode: Mode::infrastructure, frequency: 2462, strength: 72)
3094+ (bssid: 00:22:3F:35:43:58, ssid: JustAnotherWLAN, last seen: 1408955086, mode: Mode::infrastructure, frequency: 2412, strength: 24)
3095+ (bssid: 82:C7:A6:40:8C:4E, ssid: EasyBox-44D054, last seen: 1408955206, mode: Mode::infrastructure, frequency: 2417, strength: 17)
3096+ (bssid: 00:24:01:B8:32:8D, ssid: gra, last seen: 1408955086, mode: Mode::infrastructure, frequency: 2412, strength: 12)
3097+ (bssid: C0:25:06:3C:28:22, ssid: FRITZ!Box 6360 Cable, last seen: 1408954966, mode: Mode::infrastructure, frequency: 2412, strength: 17)
3098+ (bssid: 00:1C:4A:A5:B7:59, ssid: FRITZ!Box Fon WLAN 7170, last seen: 1408954966, mode: Mode::infrastructure, frequency: 2437, strength: 10)
3099+ Last seen changed for wifi (bssid: BC:F2:AF:AF:19:A2, ssid: devolo-bcf2afaf19a2, last seen: 1408955257, mode: Mode::infrastructure, frequency: 2462, strength: 72)
3100+ Last seen changed for wifi (bssid: 00:22:3F:35:43:58, ssid: JustAnotherWLAN, last seen: 1408955257, mode: Mode::infrastructure, frequency: 2412, strength: 24)
3101+ Signal strength changed for wifi: (bssid: BC:F2:AF:AF:19:A2, ssid: devolo-bcf2afaf19a2, last seen: 1408955257, mode: Mode::infrastructure, frequency: 2462, strength: 73)
3102+
3103+# Trust Store Integration
3104+
3105+Please note that we are assuming a freshly wiped system for testing
3106+here. If you cannot fulfill that pre-condition, please run `rm -rf
3107+/home/phablet/.local/share/UbuntuLocationService && sudo shutdown -r` prior to running the
3108+tests:
3109+
3110+## Unconfined
3111+
3112+ - Open the browser, go to maps.google.com
3113+ - Observe the in-browser dialog asking for granting access to location.
3114+
3115+## Confined Web-App
3116+
3117+ - Open the Nokia Here web app, observe the trust dialog appearing.
3118+
3119+## Confined Application
3120+
3121+ - Open osmtouch and observe the osmtouch surface sliding up, presenting you with a trust dialog.
3122
3123=== added file 'doc/tips_n_tricks.md'
3124--- doc/tips_n_tricks.md 1970-01-01 00:00:00 +0000
3125+++ doc/tips_n_tricks.md 2016-04-01 06:55:25 +0000
3126@@ -0,0 +1,21 @@
3127+# Tips'n'Tricks
3128+
3129+## Mark HERE license as accepted from cmdline
3130+
3131+ sudo LC_ALL=C gdbus call --system --dest org.freedesktop.Accounts --object-path /org/freedesktop/Accounts/User32011 --method org.freedesktop.DBus.Properties.Set com.ubuntu.location.providers.here.AccountsService LicenseAccepted '<true>'
3132+
3133+## Force startup after ofono and NM are started
3134+
3135+This is a *workaround* to get connectivity API to collect; mount your
3136+system read-write and edit
3137+/etc/init/ubuntu-location-provider-here-slpgwd.conf:
3138+
3139+ sudo mount -o remount,rw /
3140+ sudo vi /etc/init/ubuntu-location-provider-here-slpgwd.conf
3141+
3142+change: `start on started dbus and (started ofono or started network-manager)`
3143+to: `start on started dbus and started ofono and started network-manager`
3144+
3145+ sudo mount -o remount,ro /
3146+ sync
3147+ sudo reboot
3148
3149=== modified file 'examples/service/service.cpp'
3150--- examples/service/service.cpp 2014-11-14 11:26:45 +0000
3151+++ examples/service/service.cpp 2016-04-01 06:55:25 +0000
3152@@ -99,7 +99,10 @@
3153 auto selected_providers = options.value_for_key<std::vector<std::string>>("provider");
3154
3155 std::map<std::string, cul::ProviderFactory::Configuration> config_lut;
3156- std::set<cul::Provider::Ptr> instantiated_providers;
3157+
3158+ culs::DefaultConfiguration config;
3159+ auto settings = std::make_shared<cul::BoostPtreeSettings>(options.value_for_key<std::string>("config-file"));
3160+ auto engine = config.the_engine(std::set<cul::Provider::Ptr>{}, config.the_provider_selection_policy(), settings);
3161
3162 for (const std::string& provider : selected_providers)
3163 {
3164@@ -129,15 +132,15 @@
3165
3166 try
3167 {
3168- auto p = cul::ProviderFactory::instance().create_provider_for_name_with_config(
3169- provider,
3170- config_lut[provider]);
3171-
3172- if (p)
3173- instantiated_providers.insert(p);
3174- else
3175- throw std::runtime_error("Problem instantiating provider");
3176-
3177+ auto result = std::async(std::launch::async, [provider, config_lut, engine] {
3178+ return cul::ProviderFactory::instance().create_provider_for_name_with_config(
3179+ provider,
3180+ config_lut.at(provider),
3181+ [engine](cul::Provider::Ptr provider)
3182+ {
3183+ engine->add_provider(provider);
3184+ });
3185+ });
3186 } catch(const std::runtime_error& e)
3187 {
3188 std::cerr << "Exception instantiating provider: " << e.what() << " ... Aborting now." << std::endl;
3189@@ -163,15 +166,11 @@
3190 };
3191 outgoing->install_executor(dbus::asio::make_executor(outgoing));
3192
3193- auto settings = std::make_shared<cul::BoostPtreeSettings>(options.value_for_key<std::string>("config-file"));
3194-
3195- culs::DefaultConfiguration config;
3196-
3197 culs::Implementation::Configuration configuration
3198 {
3199 incoming,
3200 outgoing,
3201- config.the_engine(instantiated_providers, config.the_provider_selection_policy(), settings),
3202+ engine,
3203 config.the_permission_manager(incoming),
3204 culs::Harvester::Configuration
3205 {
3206
3207=== modified file 'include/location_service/com/ubuntu/location/provider_factory.h'
3208--- include/location_service/com/ubuntu/location/provider_factory.h 2014-10-27 21:58:16 +0000
3209+++ include/location_service/com/ubuntu/location/provider_factory.h 2016-04-01 06:55:25 +0000
3210@@ -54,6 +54,9 @@
3211 // --provider=remote::Provider@gps --remote::Provider@gps::name="com.ubuntu.android.gps.Provider" --remote::Provider@gps::path="/com/ubuntu/android/gps/Provider"
3212 Provider::Ptr create_provider_for_name_with_config(const std::string& name, const Configuration& config);
3213
3214+ // Async version of above.
3215+ void create_provider_for_name_with_config(const std::string& name, const Configuration& config, const std::function<void(Provider::Ptr)>& cb);
3216+
3217 void enumerate(const std::function<void(const std::string&, const Factory&)>& enumerator);
3218
3219 private:
3220
3221=== modified file 'po/ubuntu-location-service.pot'
3222--- po/ubuntu-location-service.pot 2014-09-19 09:06:30 +0000
3223+++ po/ubuntu-location-service.pot 2016-04-01 06:55:25 +0000
3224@@ -1,13 +1,14 @@
3225-# Copyright (C) 2014 Canonical Ltd.
3226-# This file is distributed under the same license as the ubuntu-location-service package.
3227-# Thomas Voß <thomas.voss@canonical.com>, 2014.
3228+# SOME DESCRIPTIVE TITLE.
3229+# Copyright (C) YEAR Canonical Ltd.
3230+# This file is distributed under the same license as the PACKAGE package.
3231+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
3232 #
3233 #, fuzzy
3234 msgid ""
3235 msgstr ""
3236 "Project-Id-Version: ubuntu-location-service\n"
3237 "Report-Msgid-Bugs-To: \n"
3238-"POT-Creation-Date: 2014-09-19 01:04+0200\n"
3239+"POT-Creation-Date: 2015-11-27 14:07+0100\n"
3240 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
3241 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
3242 "Language-Team: LANGUAGE <LL@li.org>\n"
3243@@ -16,11 +17,6 @@
3244 "Content-Type: text/plain; charset=CHARSET\n"
3245 "Content-Transfer-Encoding: 8bit\n"
3246
3247-#: /tmp/i18n/src/location_service/com/ubuntu/location/service/trust_store_permission_manager.cpp:170
3248-msgid "An unconfined application wants to access your current location."
3249-msgstr ""
3250-
3251-#: /tmp/i18n/src/location_service/com/ubuntu/location/service/trust_store_permission_manager.cpp:173
3252-#, boost-format
3253-msgid "%1% wants to access your current location."
3254+#: /home/tvoss/ubuntu/scratch/fix-prompt-string/src/location_service/com/ubuntu/location/service/trust_store_permission_manager.cpp:149
3255+msgid "wants to access your current location."
3256 msgstr ""
3257
3258=== modified file 'src/location_service/com/ubuntu/location/CMakeLists.txt'
3259--- src/location_service/com/ubuntu/location/CMakeLists.txt 2015-04-23 14:48:44 +0000
3260+++ src/location_service/com/ubuntu/location/CMakeLists.txt 2016-04-01 06:55:25 +0000
3261@@ -1,3 +1,7 @@
3262+if (UBUNTU_PLATFORM_HARDWARE_API_FOUND)
3263+ add_definitions(-DCOM_UBUNTU_LOCATION_SERVICE_HAVE_UBUNTU_PLATFORM_HARDWARE_API)
3264+endif()
3265+
3266 if (NET_CPP_FOUND)
3267 add_definitions(-DCOM_UBUNTU_LOCATION_SERVICE_HAVE_NET_CPP=1)
3268
3269@@ -10,6 +14,8 @@
3270 service/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/service/config.h @ONLY
3271 )
3272
3273+include_directories(${UBUNTU_PLATFORM_HARDWARE_API_INCLUDE_DIRS})
3274+
3275 add_library(
3276 ubuntu-location-service SHARED
3277
3278@@ -29,6 +35,7 @@
3279 settings.cpp
3280 time_based_update_policy.cpp
3281 set_name_for_thread.cpp
3282+ time_since_boot.cpp
3283 wifi_and_cell_reporting_state.cpp
3284
3285 boost_ptree_settings.cpp
3286@@ -38,6 +45,7 @@
3287 service/harvester.cpp
3288 service/demultiplexing_reporter.h
3289 service/demultiplexing_reporter.cpp
3290+ service/runtime.cpp
3291 service/runtime_tests.h
3292 service/runtime_tests.cpp
3293 service/trust_store_permission_manager.cpp
3294@@ -125,6 +133,7 @@
3295 ${LIBAPPARMOR_LDFLAGS}
3296 ${NET_CPP_LDFLAGS}
3297 ${TRUST_STORE_LDFLAGS}
3298+ ${UBUNTU_PLATFORM_HARDWARE_API_LDFLAGS}
3299 ${GLog_LIBRARY}
3300 ${GFlags_LIBRARY}
3301 )
3302
3303=== modified file 'src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.cpp'
3304--- src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.cpp 2015-05-28 10:57:24 +0000
3305+++ src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.cpp 2016-04-01 06:55:25 +0000
3306@@ -123,7 +123,14 @@
3307 const org::freedesktop::NetworkManager::Device& device,
3308 const org::freedesktop::NetworkManager::AccessPoint& ap)
3309 : device_(device),
3310- access_point_(ap)
3311+ access_point_(ap),
3312+ connections
3313+ {
3314+ access_point_.properties_changed->connect([this](const std::map<std::string, core::dbus::types::Variant>& dict)
3315+ {
3316+ on_access_point_properties_changed(dict);
3317+ })
3318+ }
3319 {
3320 last_seen_ = translate_time_stamp(access_point_.last_seen->get());
3321
3322@@ -138,12 +145,11 @@
3323 {
3324 static_cast<int>(access_point_.strength->get())
3325 };
3326+}
3327
3328- // Wire up all the connections
3329- access_point_.properties_changed->connect([this](const std::map<std::string, core::dbus::types::Variant>& dict)
3330- {
3331- on_access_point_properties_changed(dict);
3332- });
3333+detail::CachedWirelessNetwork::~CachedWirelessNetwork()
3334+{
3335+ access_point_.properties_changed->disconnect(connections.ap_properties_changed);
3336 }
3337
3338 void detail::CachedWirelessNetwork::on_access_point_properties_changed(const std::map<std::string, core::dbus::types::Variant>& dict)
3339
3340=== modified file 'src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.h'
3341--- src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.h 2014-08-14 20:25:22 +0000
3342+++ src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.h 2016-04-01 06:55:25 +0000
3343@@ -41,6 +41,8 @@
3344 const org::freedesktop::NetworkManager::Device& device,
3345 const org::freedesktop::NetworkManager::AccessPoint& ap);
3346
3347+ ~CachedWirelessNetwork();
3348+
3349 // Timestamp when the network became visible.
3350 const core::Property<std::chrono::system_clock::time_point>& last_seen() const override;
3351
3352@@ -67,6 +69,16 @@
3353 // The actual access point stub.
3354 org::freedesktop::NetworkManager::AccessPoint access_point_;
3355
3356+ // Encapsulates all event connections that have to be cut on destruction.
3357+ struct
3358+ {
3359+ core::dbus::Signal
3360+ <
3361+ org::freedesktop::NetworkManager::AccessPoint::PropertiesChanged,
3362+ org::freedesktop::NetworkManager::AccessPoint::PropertiesChanged::ArgumentType
3363+ >::SubscriptionToken ap_properties_changed;
3364+ } connections;
3365+
3366 core::Property<std::chrono::system_clock::time_point> last_seen_;
3367 core::Property<std::string> bssid_;
3368 core::Property<std::string> ssid_;
3369
3370=== modified file 'src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.cpp'
3371--- src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.cpp 2015-05-27 18:40:37 +0000
3372+++ src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.cpp 2016-04-01 06:55:25 +0000
3373@@ -595,7 +595,7 @@
3374
3375 xdg::NetworkManager::AccessPoint ap
3376 {
3377- network_manager->service->add_object_for_path(ap_path)
3378+ network_manager->service->object_for_path(ap_path)
3379 };
3380
3381 auto wifi = std::make_shared<detail::CachedWirelessNetwork>(itd->second, ap);
3382
3383=== modified file 'src/location_service/com/ubuntu/location/engine.cpp'
3384--- src/location_service/com/ubuntu/location/engine.cpp 2015-04-23 14:48:44 +0000
3385+++ src/location_service/com/ubuntu/location/engine.cpp 2016-04-01 06:55:25 +0000
3386@@ -97,10 +97,7 @@
3387 Configuration::Keys::engine_state,
3388 Configuration::Defaults::engine_state);
3389
3390- configuration.satellite_based_positioning_state =
3391- settings->get_enum_for_key<SatelliteBasedPositioningState>(
3392- Configuration::Keys::satellite_based_positioning_state,
3393- Configuration::Defaults::satellite_based_positioning_state);
3394+ configuration.satellite_based_positioning_state = Configuration::Defaults::satellite_based_positioning_state;
3395
3396 configuration.wifi_and_cell_id_reporting_state =
3397 settings->get_enum_for_key<WifiAndCellIdReportingState>(
3398@@ -110,12 +107,7 @@
3399 configuration.engine_state.changed().connect([this](const Engine::Status& status)
3400 {
3401 Engine::settings->set_enum_for_key<Engine::Status>(Configuration::Keys::engine_state, status);
3402- });
3403-
3404- configuration.satellite_based_positioning_state.changed().connect([this](SatelliteBasedPositioningState state)
3405- {
3406- Engine::settings->set_enum_for_key<SatelliteBasedPositioningState>(Configuration::Keys::satellite_based_positioning_state, state);
3407- });
3408+ });
3409
3410 configuration.wifi_and_cell_id_reporting_state.changed().connect([this](WifiAndCellIdReportingState state)
3411 {
3412@@ -129,10 +121,6 @@
3413 Configuration::Keys::engine_state,
3414 configuration.engine_state);
3415
3416- settings->set_enum_for_key<SatelliteBasedPositioningState>(
3417- Configuration::Keys::satellite_based_positioning_state,
3418- configuration.satellite_based_positioning_state);
3419-
3420 settings->set_enum_for_key<WifiAndCellIdReportingState>(
3421 Configuration::Keys::wifi_and_cell_id_reporting_state,
3422 configuration.wifi_and_cell_id_reporting_state);
3423@@ -169,19 +157,28 @@
3424
3425 // We wire up changes in the engine's configuration to the respective slots
3426 // of the provider.
3427- auto cp = updates.reference_location.changed().connect([provider](const cul::Update<cul::Position>& pos)
3428- {
3429- provider->on_reference_location_updated(pos);
3430- });
3431-
3432- auto cv = updates.reference_velocity.changed().connect([provider](const cul::Update<cul::Velocity>& velocity)
3433- {
3434- provider->on_reference_velocity_updated(velocity);
3435- });
3436-
3437- auto ch = updates.reference_heading.changed().connect([provider](const cul::Update<cul::Heading>& heading)
3438- {
3439- provider->on_reference_heading_updated(heading);
3440+ auto cp = updates.last_known_location.changed().connect([provider](const cul::Optional<cul::Update<cul::Position>>& pos)
3441+ {
3442+ if (pos)
3443+ {
3444+ provider->on_reference_location_updated(pos.get());
3445+ }
3446+ });
3447+
3448+ auto cv = updates.last_known_velocity.changed().connect([provider](const cul::Optional<cul::Update<cul::Velocity>>& velocity)
3449+ {
3450+ if (velocity)
3451+ {
3452+ provider->on_reference_velocity_updated(velocity.get());
3453+ }
3454+ });
3455+
3456+ auto ch = updates.last_known_heading.changed().connect([provider](const cul::Optional<cul::Update<cul::Heading>>& heading)
3457+ {
3458+ if (heading)
3459+ {
3460+ provider->on_reference_heading_updated(heading.get());
3461+ }
3462 });
3463
3464 auto cr = configuration.wifi_and_cell_id_reporting_state.changed().connect([provider](cul::WifiAndCellIdReportingState state)
3465@@ -207,7 +204,7 @@
3466 // We should come up with a better heuristic here.
3467 auto cpr = provider->updates().position.connect([this](const cul::Update<cul::Position>& src)
3468 {
3469- updates.reference_location = update_policy->verify_update(src);
3470+ updates.last_known_location = update_policy->verify_update(src);
3471 });
3472
3473 std::lock_guard<std::mutex> lg(guard);
3474
3475=== modified file 'src/location_service/com/ubuntu/location/engine.h'
3476--- src/location_service/com/ubuntu/location/engine.h 2015-04-23 14:48:44 +0000
3477+++ src/location_service/com/ubuntu/location/engine.h 2016-04-01 06:55:25 +0000
3478@@ -127,11 +127,11 @@
3479 struct Updates
3480 {
3481 /** The current best known reference location */
3482- core::Property<Update<Position>> reference_location{};
3483+ core::Property<Optional<Update<Position>>> last_known_location{};
3484 /** The current best known velocity estimate. */
3485- core::Property<Update<Velocity>> reference_velocity{};
3486+ core::Property<Optional<Update<Velocity>>> last_known_velocity{};
3487 /** The current best known heading estimate. */
3488- core::Property<Update<Heading>> reference_heading{};
3489+ core::Property<Optional<Update<Heading>>> last_known_heading{};
3490 /** The current set of visible SpaceVehicles. */
3491 core::Property<std::map<SpaceVehicle::Key, SpaceVehicle>> visible_space_vehicles{};
3492 };
3493
3494=== modified file 'src/location_service/com/ubuntu/location/provider_factory.cpp'
3495--- src/location_service/com/ubuntu/location/provider_factory.cpp 2014-10-27 21:58:16 +0000
3496+++ src/location_service/com/ubuntu/location/provider_factory.cpp 2016-04-01 06:55:25 +0000
3497@@ -52,6 +52,20 @@
3498 return cul::Provider::Ptr{factory_store.at(undecorated_name)(config)};
3499 }
3500
3501+void cul::ProviderFactory::create_provider_for_name_with_config(
3502+ const std::string& name,
3503+ const cul::ProviderFactory::Configuration& config,
3504+ const std::function<void(Provider::Ptr)>& cb)
3505+{
3506+ auto undecorated_name = name.substr(0, name.find("@"));
3507+
3508+ std::lock_guard<std::mutex> lg(guard);
3509+ if (factory_store.count(undecorated_name) == 0)
3510+ return;
3511+
3512+ cb(cul::Provider::Ptr{factory_store.at(undecorated_name)(config)});
3513+}
3514+
3515 void cul::ProviderFactory::enumerate(
3516 const std::function<void(const std::string&, const cul::ProviderFactory::Factory&)>& enumerator)
3517 {
3518
3519=== modified file 'src/location_service/com/ubuntu/location/providers/config.cpp'
3520--- src/location_service/com/ubuntu/location/providers/config.cpp 2014-09-15 08:58:50 +0000
3521+++ src/location_service/com/ubuntu/location/providers/config.cpp 2016-04-01 06:55:25 +0000
3522@@ -19,6 +19,7 @@
3523 #include <com/ubuntu/location/provider_factory.h>
3524
3525 #include "dummy/provider.h"
3526+#include "dummy/delayed_provider.h"
3527
3528 #include <map>
3529
3530@@ -41,6 +42,12 @@
3531 com::ubuntu::location::providers::dummy::Provider::create_instance
3532 };
3533
3534+static FactoryInjector dummy_delayed_injector
3535+{
3536+ "dummy::DelayedProvider",
3537+ com::ubuntu::location::providers::dummy::DelayedProvider::create_instance
3538+};
3539+
3540 #include <com/ubuntu/location/providers/remote/provider.h>
3541 static FactoryInjector remote_injector
3542 {
3543
3544=== modified file 'src/location_service/com/ubuntu/location/providers/dummy/CMakeLists.txt'
3545--- src/location_service/com/ubuntu/location/providers/dummy/CMakeLists.txt 2014-02-07 17:16:49 +0000
3546+++ src/location_service/com/ubuntu/location/providers/dummy/CMakeLists.txt 2016-04-01 06:55:25 +0000
3547@@ -2,7 +2,9 @@
3548 dummy
3549
3550 provider.h
3551- provider.cpp)
3552+ provider.cpp
3553+ delayed_provider.h
3554+ delayed_provider.cpp)
3555
3556 set(
3557 ENABLED_PROVIDER_TARGETS
3558
3559=== added file 'src/location_service/com/ubuntu/location/providers/dummy/delayed_provider.cpp'
3560--- src/location_service/com/ubuntu/location/providers/dummy/delayed_provider.cpp 1970-01-01 00:00:00 +0000
3561+++ src/location_service/com/ubuntu/location/providers/dummy/delayed_provider.cpp 2016-04-01 06:55:25 +0000
3562@@ -0,0 +1,42 @@
3563+/*
3564+ * Copyright © 2015 Canonical Ltd.
3565+ *
3566+ * This program is free software: you can redistribute it and/or modify it
3567+ * under the terms of the GNU Lesser General Public License version 3,
3568+ * as published by the Free Software Foundation.
3569+ *
3570+ * This program is distributed in the hope that it will be useful,
3571+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3572+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3573+ * GNU Lesser General Public License for more details.
3574+ *
3575+ * You should have received a copy of the GNU Lesser General Public License
3576+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3577+ *
3578+ * Authored by: Scott Sweeny <scott.sweeny@canonical.com>
3579+ */
3580+
3581+#include <com/ubuntu/location/logging.h>
3582+
3583+#include <chrono>
3584+#include <thread>
3585+
3586+#include "delayed_provider.h"
3587+
3588+namespace location = com::ubuntu::location;
3589+namespace dummy = com::ubuntu::location::providers::dummy;
3590+
3591+std::string dummy::DelayedProvider::class_name()
3592+{
3593+ return "dummy::DelayedProvider";
3594+}
3595+
3596+location::Provider::Ptr dummy::DelayedProvider::create_instance(const ProviderFactory::Configuration& config)
3597+{
3598+ int delay = config.get(dummy::DelayConfiguration::Keys::delay, 0);
3599+ VLOG(1) << __PRETTY_FUNCTION__ << ": delay for " << delay << "ms";
3600+
3601+ std::this_thread::sleep_for(std::chrono::milliseconds{delay});
3602+
3603+ return dummy::Provider::create_instance(config);
3604+}
3605
3606=== added file 'src/location_service/com/ubuntu/location/providers/dummy/delayed_provider.h'
3607--- src/location_service/com/ubuntu/location/providers/dummy/delayed_provider.h 1970-01-01 00:00:00 +0000
3608+++ src/location_service/com/ubuntu/location/providers/dummy/delayed_provider.h 2016-04-01 06:55:25 +0000
3609@@ -0,0 +1,62 @@
3610+/*
3611+ * Copyright © 2015 Canonical Ltd.
3612+ *
3613+ * This program is free software: you can redistribute it and/or modify it
3614+ * under the terms of the GNU Lesser General Public License version 3,
3615+ * as published by the Free Software Foundation.
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 Lesser 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+ * Authored by: Scott Sweeny <scott.sweeny@canonical.com>
3626+ */
3627+
3628+#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_DUMMY_DELAYED_PROVIDER_H_
3629+#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_DUMMY_DELAYED_PROVIDER_H_
3630+
3631+#include "provider.h"
3632+
3633+namespace com
3634+{
3635+namespace ubuntu
3636+{
3637+namespace location
3638+{
3639+namespace providers
3640+{
3641+namespace dummy
3642+{
3643+ struct DelayConfiguration
3644+ {
3645+ struct Keys
3646+ {
3647+ static constexpr const char* delay
3648+ {
3649+ "DelayInMs"
3650+ };
3651+ };
3652+ };
3653+
3654+class DelayedProvider : public Provider
3655+{
3656+ public:
3657+ // For integration with the Provider factory
3658+ static std::string class_name();
3659+ // Waits for "DelayInMs" from the provided property bundle then
3660+ // instantiates a new provider instance, populating the configuration object
3661+ // from the provided property bundle.
3662+ static DelayedProvider::Ptr create_instance(const ProviderFactory::Configuration&);
3663+ // Creates a new provider instance from the given configuration.
3664+ DelayedProvider(const Configuration config = Configuration{});
3665+};
3666+}
3667+}
3668+}
3669+}
3670+}
3671+#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_DUMMY_DELAYED_PROVIDER_H_
3672
3673=== modified file 'src/location_service/com/ubuntu/location/providers/gps/CMakeLists.txt'
3674--- src/location_service/com/ubuntu/location/providers/gps/CMakeLists.txt 2014-07-28 19:14:58 +0000
3675+++ src/location_service/com/ubuntu/location/providers/gps/CMakeLists.txt 2016-04-01 06:55:25 +0000
3676@@ -4,30 +4,34 @@
3677 ON
3678 )
3679
3680-if (LOCATION_SERVICE_ENABLE_GPS_PROVIDER)
3681- find_file(
3682- UBUNTU_HARDWARE_GPS_H gps.h
3683- NAMES ubuntu/hardware/gps.h
3684- )
3685-
3686- if (UBUNTU_HARDWARE_GPS_H)
3687+if ((LOCATION_SERVICE_ENABLE_GPS_PROVIDER) AND (UBUNTU_PLATFORM_HARDWARE_API_FOUND))
3688 message(STATUS "Enabling GPS location provider")
3689
3690+ include_directories(${UBUNTU_PLATFORM_HARDWARE_API_INCLUDE_DIRS})
3691+
3692 add_library(
3693 gps
3694
3695 gps.conf
3696
3697+ hardware_abstraction_layer.cpp
3698+
3699 android_hardware_abstraction_layer.h
3700 android_hardware_abstraction_layer.cpp
3701
3702+ sntp_reference_time_source.h
3703+ sntp_reference_time_source.cpp
3704+
3705+ sntp_client.h
3706+ sntp_client.cpp
3707+
3708 hardware_abstraction_layer.h
3709 # hardware_abstraction_layer.cpp
3710
3711 provider.h
3712 provider.cpp)
3713
3714- target_link_libraries(gps ubuntu_platform_hardware_api.so)
3715+ target_link_libraries(gps ${UBUNTU_PLATFORM_HARDWARE_API_LDFLAGS})
3716
3717 set(
3718 ENABLED_PROVIDER_TARGETS
3719@@ -41,5 +45,4 @@
3720 )
3721
3722 install(FILES gps.conf DESTINATION /etc/)
3723- endif (UBUNTU_HARDWARE_GPS_H)
3724-endif (LOCATION_SERVICE_ENABLE_GPS_PROVIDER)
3725+endif ()
3726
3727=== modified file 'src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp'
3728--- src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp 2014-10-27 21:58:16 +0000
3729+++ src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp 2016-04-01 06:55:25 +0000
3730@@ -17,6 +17,7 @@
3731 */
3732
3733 #include "android_hardware_abstraction_layer.h"
3734+#include "sntp_reference_time_source.h"
3735
3736 #if defined(COM_UBUNTU_LOCATION_SERVICE_HAVE_NET_CPP)
3737 #include "net_cpp_gps_xtra_downloader.h"
3738@@ -66,8 +67,6 @@
3739 if (config.count("XTRA_SERVER_3") > 0)
3740 result.xtra_hosts.push_back(config.get<std::string>("XTRA_SERVER_3"));
3741
3742- result.timeout = std::chrono::milliseconds{1500};
3743-
3744 return result;
3745 }
3746
3747@@ -325,23 +324,18 @@
3748 {
3749 VLOG(1) << __PRETTY_FUNCTION__;
3750
3751- auto thiz = static_cast<android::HardwareAbstractionLayer*>(context);
3752-
3753- if (thiz->impl.utc_time_request_handler)
3754- {
3755- thiz->impl.utc_time_request_handler();
3756- } else
3757- {
3758- auto now = location::Clock::now().time_since_epoch();
3759- auto thiz = static_cast<android::HardwareAbstractionLayer*>(context);
3760-
3761- static const int zero_uncertainty = 0;
3762-
3763- u_hardware_gps_inject_time(
3764- thiz->impl.gps_handle,
3765- now.count(),
3766- now.count(),
3767- zero_uncertainty);
3768+ try
3769+ {
3770+ if (auto thiz = static_cast<android::HardwareAbstractionLayer*>(context))
3771+ thiz->inject_reference_time(thiz->impl.reference_time_source->sample());
3772+ }
3773+ catch (const std::runtime_error& e)
3774+ {
3775+ LOG(WARNING) << "Failed to inject reference time to chipset: " << e.what();
3776+ }
3777+ catch (...)
3778+ {
3779+ LOG(WARNING) << "Failed to inject reference time to chipset.";
3780 }
3781 }
3782
3783@@ -536,19 +530,22 @@
3784 return true;
3785 }
3786
3787-bool android::HardwareAbstractionLayer::inject_reference_time(
3788- const std::chrono::microseconds& reference_time,
3789- const std::chrono::microseconds& sample_time)
3790+bool android::HardwareAbstractionLayer::inject_reference_time(const ReferenceTimeSample& sample)
3791 {
3792 if (!is_capable_of(gps::Capability::on_demand_time_injection))
3793 return false;
3794
3795 // TODO(tvoss): We should expose the int return type of the underyling
3796 // Android HAL to capture errors here.
3797+ //
3798+ // Please see:
3799+ // http://androidxref.com/5.1.1_r6/xref/frameworks/base/core/java/android/net/SntpClient.java#72
3800+ // for the bloody details of relating the system wall clock time to the elapsed realtime since boot
3801+ // including deep sleep.
3802 u_hardware_gps_inject_time(impl.gps_handle,
3803- reference_time.count(),
3804- sample_time.count(),
3805- 10);
3806+ sample.since_epoch.count(),
3807+ sample.since_boot.count(),
3808+ sample.uncertainty.count());
3809 return true;
3810 }
3811
3812@@ -559,6 +556,7 @@
3813 assistance_mode(gps::AssistanceMode::mobile_station_based),
3814 position_mode(gps::PositionMode::periodic),
3815 supl_assistant(*parent),
3816+ reference_time_source(configuration.reference_time_source),
3817 gps_xtra_configuration(configuration.gps_xtra.configuration),
3818 gps_xtra_downloader(configuration.gps_xtra.downloader)
3819 {
3820@@ -617,6 +615,22 @@
3821
3822 namespace
3823 {
3824+gps::SntpReferenceTimeSource::Configuration sntp_reference_time_source_configuration(std::istream& in)
3825+{
3826+ gps::SntpReferenceTimeSource::Configuration config;
3827+
3828+ try
3829+ {
3830+ config = gps::SntpReferenceTimeSource::Configuration::from_gps_conf_ini_file(in);
3831+ }
3832+ catch (...)
3833+ {
3834+ // Consciously dropping all exceptions here.
3835+ }
3836+
3837+ return config;
3838+}
3839+
3840 android::GpsXtraDownloader::Configuration gps_xtra_downloader_configuration(std::istream& in)
3841 {
3842 android::GpsXtraDownloader::Configuration config;
3843@@ -643,6 +657,8 @@
3844
3845 return config;
3846 }
3847+
3848+
3849 }
3850
3851 std::shared_ptr<gps::HardwareAbstractionLayer> gps::HardwareAbstractionLayer::create_default_instance()
3852@@ -666,7 +682,8 @@
3853 {
3854 create_xtra_downloader(),
3855 gps_xtra_downloader_configuration((in_system_gps_conf ? in_system_gps_conf : in_gps_conf))
3856- }
3857+ },
3858+ std::make_shared<gps::SntpReferenceTimeSource>(sntp_reference_time_source_configuration((in_system_gps_conf ? in_system_gps_conf : in_gps_conf)))
3859 };
3860
3861 static std::shared_ptr<gps::HardwareAbstractionLayer> instance
3862
3863=== modified file 'src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h'
3864--- src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h 2015-04-22 13:30:04 +0000
3865+++ src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h 2016-04-01 06:55:25 +0000
3866@@ -19,6 +19,7 @@
3867 #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_ANDROID_HARDWARE_ABSTRACTION_LAYER_H_
3868
3869 #include <com/ubuntu/location/providers/gps/hardware_abstraction_layer.h>
3870+#include <com/ubuntu/location/providers/gps/sntp_client.h>
3871
3872 #include <ubuntu/hardware/gps.h>
3873
3874@@ -49,7 +50,7 @@
3875 /** @brief Timeout on gps xtra download operations. */
3876 std::chrono::milliseconds timeout
3877 {
3878- 5000
3879+ 30000
3880 };
3881
3882 /** Set of hosts serving GPS xtra data. */
3883@@ -66,7 +67,24 @@
3884 };
3885
3886 struct HardwareAbstractionLayer : public gps::HardwareAbstractionLayer
3887-{
3888+{
3889+ /** @brief A ReferenceTimeSource provides samples of an arbitrary reference time source. */
3890+ class ReferenceTimeSource
3891+ {
3892+ public:
3893+ /** @cond */
3894+ typedef std::shared_ptr<ReferenceTimeSource> Ptr;
3895+
3896+ virtual ~ReferenceTimeSource() = default;
3897+ /** @endcond */
3898+
3899+ /** @brief sample returns a sample of the current ReferenceTimeSource. */
3900+ virtual ReferenceTimeSample sample() = 0;
3901+
3902+ protected:
3903+ ReferenceTimeSource() = default;
3904+ };
3905+
3906 /** @brief Implements gps::HardwareAbstractionLayer::SuplAssistant interface for the android gps HAL. */
3907 struct SuplAssistant : public gps::HardwareAbstractionLayer::SuplAssistant
3908 {
3909@@ -186,6 +204,8 @@
3910 std::shared_ptr<GpsXtraDownloader> downloader;
3911 GpsXtraDownloader::Configuration configuration;
3912 } gps_xtra;
3913+
3914+ ReferenceTimeSource::Ptr reference_time_source;
3915 };
3916
3917 HardwareAbstractionLayer(const Configuration& configuration);
3918@@ -227,8 +247,8 @@
3919 bool set_position_mode(gps::PositionMode mode) override;
3920
3921 bool inject_reference_position(const location::Position& position) override;
3922- bool inject_reference_time(const std::chrono::microseconds& reference_time,
3923- const std::chrono::microseconds& sample_time) override;
3924+ bool inject_reference_time(const ReferenceTimeSample& sample) override;
3925+
3926 struct Impl
3927 {
3928 // Bootstraps access to the GPS chipset, wiring up all callbacks.
3929@@ -252,8 +272,8 @@
3930 // An implementation of the gps::HardwareAbstractionLayer::SuplAssistant interface.
3931 SuplAssistant supl_assistant;
3932
3933- // Callback for handling utc time requests.
3934- gps::HardwareAbstractionLayer::UtcTimeRequestHandler utc_time_request_handler;
3935+ // An implementation of ReferenceTimeSource.
3936+ ReferenceTimeSource::Ptr reference_time_source;
3937
3938 // Emitted whenever the set of visible space vehicles changes.
3939 core::Signal<std::set<location::SpaceVehicle>> space_vehicle_updates;
3940
3941=== added file 'src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.cpp'
3942--- src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.cpp 1970-01-01 00:00:00 +0000
3943+++ src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.cpp 2016-04-01 06:55:25 +0000
3944@@ -0,0 +1,30 @@
3945+/*
3946+ * Copyright © 2012-2013 Canonical Ltd.
3947+ *
3948+ * This program is free software: you can redistribute it and/or modify it
3949+ * under the terms of the GNU Lesser General Public License version 3,
3950+ * as published by the Free Software Foundation.
3951+ *
3952+ * This program is distributed in the hope that it will be useful,
3953+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3954+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3955+ * GNU Lesser General Public License for more details.
3956+ *
3957+ * You should have received a copy of the GNU Lesser General Public License
3958+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3959+ *
3960+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
3961+ */
3962+
3963+#include <com/ubuntu/location/providers/gps/hardware_abstraction_layer.h>
3964+
3965+#include <iostream>
3966+
3967+namespace gps = com::ubuntu::location::providers::gps;
3968+
3969+std::ostream& gps::operator<<(std::ostream& out, const gps::HardwareAbstractionLayer::ReferenceTimeSample& sample)
3970+{
3971+ return out << "[since epoch: " << sample.since_epoch.count() << " [ms], since boot: "
3972+ << sample.since_boot.count() << " [ms], uncertainty: "
3973+ << sample.uncertainty.count() << " [ms]";
3974+}
3975
3976=== modified file 'src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.h'
3977--- src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.h 2014-06-06 17:52:59 +0000
3978+++ src/location_service/com/ubuntu/location/providers/gps/hardware_abstraction_layer.h 2016-04-01 06:55:25 +0000
3979@@ -18,6 +18,7 @@
3980 #ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_HARDWARE_ABSTRACTION_LAYER_H_
3981 #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_HARDWARE_ABSTRACTION_LAYER_H_
3982
3983+#include <com/ubuntu/location/clock.h>
3984 #include <com/ubuntu/location/heading.h>
3985 #include <com/ubuntu/location/position.h>
3986 #include <com/ubuntu/location/space_vehicle.h>
3987@@ -104,6 +105,13 @@
3988 class HardwareAbstractionLayer
3989 {
3990 public:
3991+ /** @brief ReferenceTimeSample bundles together the local reference. */
3992+ struct ReferenceTimeSample
3993+ {
3994+ std::chrono::milliseconds since_epoch; /**< Reference wall-clock time since the epoch (UTC). */
3995+ std::chrono::milliseconds since_boot; /**< Reference time since boot. */
3996+ std::chrono::milliseconds uncertainty; /**< Uncertainty estimate of the sample. */
3997+ };
3998
3999 class SuplAssistant
4000 {
4001@@ -304,16 +312,17 @@
4002
4003 /**
4004 * @brief Injects a new reference time to the underlying gps driver/chipset.
4005- * @param reference_time The new reference time.
4006- * @param sample_time When the reference time was sampled.
4007+ * @param sample The reference time sample
4008 * @return true iff the injection was successful, false otherwise.
4009 */
4010- virtual bool inject_reference_time(const std::chrono::microseconds& reference_time,
4011- const std::chrono::microseconds& sample_time) = 0;
4012+ virtual bool inject_reference_time(const ReferenceTimeSample& sample) = 0;
4013
4014 protected:
4015 HardwareAbstractionLayer() = default;
4016 };
4017+
4018+/** @brief operator<< inserts sample into out. */
4019+std::ostream& operator<<(std::ostream& out, const HardwareAbstractionLayer::ReferenceTimeSample& sample);
4020 }
4021 }
4022 }
4023
4024=== added file 'src/location_service/com/ubuntu/location/providers/gps/sntp_client.cpp'
4025--- src/location_service/com/ubuntu/location/providers/gps/sntp_client.cpp 1970-01-01 00:00:00 +0000
4026+++ src/location_service/com/ubuntu/location/providers/gps/sntp_client.cpp 2016-04-01 06:55:25 +0000
4027@@ -0,0 +1,210 @@
4028+/*
4029+ * Copyright © 2012-2013 Canonical Ltd.
4030+ *
4031+ * This program is free software: you can redistribute it and/or modify it
4032+ * under the terms of the GNU Lesser General Public License version 3,
4033+ * as published by the Free Software Foundation.
4034+ *
4035+ * This program is distributed in the hope that it will be useful,
4036+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4037+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4038+ * GNU Lesser General Public License for more details.
4039+ *
4040+ * You should have received a copy of the GNU Lesser General Public License
4041+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4042+ *
4043+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
4044+ */
4045+
4046+#include <com/ubuntu/location/providers/gps/sntp_client.h>
4047+
4048+#include <com/ubuntu/location/time_since_boot.h>
4049+
4050+#include <boost/asio/ip/udp.hpp>
4051+#include <boost/endian/buffers.hpp>
4052+
4053+#include <bitset>
4054+#include <fstream>
4055+#include <future>
4056+#include <iostream>
4057+#include <thread>
4058+
4059+namespace location = com::ubuntu::location;
4060+namespace gps = location::providers::gps;
4061+namespace ip = boost::asio::ip;
4062+
4063+namespace
4064+{
4065+
4066+template<typename T>
4067+T sync_or_throw(std::future<T>& f)
4068+{
4069+ return f.get();
4070+}
4071+
4072+template<>
4073+void sync_or_throw<>(std::future<void>& f)
4074+{
4075+ f.get();
4076+}
4077+
4078+struct Now
4079+{
4080+ std::chrono::nanoseconds time = std::chrono::duration_cast<std::chrono::milliseconds>(
4081+ std::chrono::system_clock::now().time_since_epoch());
4082+ std::chrono::nanoseconds ticks = location::time_since_boot();
4083+};
4084+}
4085+
4086+const std::chrono::seconds& gps::sntp::offset_1900_to_1970()
4087+{
4088+ static const std::uint64_t secs = ((365ull * 70ull) + 17ull) * 24ull * 60ull * 60ull;
4089+ static const std::chrono::seconds seconds{secs};
4090+ return seconds;
4091+}
4092+
4093+gps::sntp::LeapIndicator gps::sntp::Packet::LeapIndicatorVersionMode::leap_indicator() const
4094+{
4095+ return static_cast<LeapIndicator>((livm.value() >> 6) & 0x3);
4096+}
4097+
4098+gps::sntp::Packet::LeapIndicatorVersionMode& gps::sntp::Packet::LeapIndicatorVersionMode::leap_indicator(LeapIndicator li)
4099+{
4100+ livm = livm.value() | (static_cast<uint8_t>(li) << 6);
4101+ return *this;
4102+}
4103+
4104+std::uint8_t gps::sntp::Packet::LeapIndicatorVersionMode::version() const
4105+{
4106+ return (livm.value() >> 3) & 0x7;
4107+}
4108+
4109+gps::sntp::Packet::LeapIndicatorVersionMode& gps::sntp::Packet::LeapIndicatorVersionMode::version(std::uint8_t version)
4110+{
4111+ livm = livm.value() | (version << 3);
4112+ return *this;
4113+}
4114+
4115+gps::sntp::Mode gps::sntp::Packet::LeapIndicatorVersionMode::mode() const
4116+{
4117+ return static_cast<Mode>(livm.value() & 0x7);
4118+}
4119+
4120+gps::sntp::Packet::LeapIndicatorVersionMode& gps::sntp::Packet::LeapIndicatorVersionMode::mode(Mode m)
4121+{
4122+ livm = static_cast<uint8_t>(m) | livm.value();
4123+ return *this;
4124+}
4125+
4126+gps::sntp::Client::Response gps::sntp::Client::request_time(const std::string& host, const std::chrono::milliseconds& timeout, boost::asio::io_service& ios)
4127+{
4128+ ip::udp::resolver resolver{ios};
4129+ ip::udp::socket socket{ios};
4130+ bool timed_out{false};
4131+
4132+ std::promise<ip::udp::resolver::iterator> promise_resolve;
4133+ auto future_resolve= promise_resolve.get_future();
4134+
4135+ boost::asio::deadline_timer timer{ios};
4136+ timer.expires_from_now(boost::posix_time::milliseconds{timeout.count()});
4137+ timer.async_wait([&timed_out, &resolver, &socket](const boost::system::error_code& ec)
4138+ {
4139+ if (ec)
4140+ return;
4141+
4142+ timed_out = true;
4143+
4144+ resolver.cancel();
4145+ socket.shutdown(ip::udp::socket::shutdown_both);
4146+ socket.close();
4147+ });
4148+
4149+ ip::udp::resolver::query query{ip::udp::v4(), host, "ntp"};
4150+
4151+ resolver.async_resolve(query, [&promise_resolve](const boost::system::error_code& ec, ip::udp::resolver::iterator it)
4152+ {
4153+ if (ec)
4154+ promise_resolve.set_exception(std::make_exception_ptr(boost::system::system_error(ec)));
4155+ else
4156+ promise_resolve.set_value(it);
4157+ });
4158+
4159+ auto it = sync_or_throw(future_resolve);
4160+
4161+ std::promise<void> promise_connect;
4162+ auto future_connect = promise_connect.get_future();
4163+
4164+ socket.async_connect(*it, [&promise_connect](const boost::system::error_code& ec)
4165+ {
4166+ if (ec)
4167+ promise_connect.set_exception(std::make_exception_ptr(boost::system::system_error(ec)));
4168+ else
4169+ promise_connect.set_value();
4170+ });
4171+
4172+ sync_or_throw(future_connect);
4173+
4174+ sntp::Packet packet;
4175+
4176+ Now before;
4177+ {
4178+ packet = request(socket);
4179+ timer.cancel();
4180+
4181+ if (timed_out)
4182+ throw std::runtime_error("Operation timed out.");
4183+ }
4184+ Now after;
4185+
4186+ auto originate = packet.originate.to_milliseconds_since_epoch();
4187+ auto receive = packet.receive.to_milliseconds_since_epoch();
4188+ auto transmit = packet.transmit.to_milliseconds_since_epoch();
4189+
4190+ auto rtt = after.ticks - before.ticks - (transmit - receive);
4191+ auto offset = ((receive - originate) + (transmit - after.time))/2;
4192+
4193+ return
4194+ {
4195+ packet,
4196+ std::chrono::duration_cast<std::chrono::milliseconds>(after.time + offset),
4197+ std::chrono::duration_cast<std::chrono::milliseconds>(after.ticks),
4198+ std::chrono::duration_cast<std::chrono::milliseconds>(rtt)
4199+ };
4200+}
4201+
4202+gps::sntp::Packet gps::sntp::Client::request(boost::asio::ip::udp::socket& socket)
4203+{
4204+ sntp::Packet packet;
4205+ packet.transmit.from_milliseconds_since_epoch(
4206+ std::chrono::duration_cast<std::chrono::milliseconds>(
4207+ std::chrono::system_clock::now().time_since_epoch()));
4208+ packet.livm.mode(sntp::Mode::client).version(sntp::version);
4209+
4210+ std::promise<std::size_t> promise_send;
4211+ auto future_send = promise_send.get_future();
4212+
4213+ socket.async_send(boost::asio::buffer(&packet, sizeof(packet)), [&promise_send](const boost::system::error_code& ec, std::size_t transferred)
4214+ {
4215+ if (ec)
4216+ promise_send.set_exception(std::make_exception_ptr(boost::system::system_error(ec)));
4217+ else
4218+ promise_send.set_value(transferred);
4219+ });
4220+
4221+ sync_or_throw(future_send);
4222+
4223+ std::promise<std::size_t> promise_receive;
4224+ auto future_receive = promise_receive.get_future();
4225+
4226+ socket.async_receive(boost::asio::buffer(&packet, sizeof(packet)), [&promise_receive](const boost::system::error_code& ec, std::size_t transferred)
4227+ {
4228+ if (ec)
4229+ promise_receive.set_exception(std::make_exception_ptr(boost::system::system_error(ec)));
4230+ else
4231+ promise_receive.set_value(transferred);
4232+ });
4233+
4234+ sync_or_throw(future_receive);
4235+
4236+ return packet;
4237+}
4238
4239=== added file 'src/location_service/com/ubuntu/location/providers/gps/sntp_client.h'
4240--- src/location_service/com/ubuntu/location/providers/gps/sntp_client.h 1970-01-01 00:00:00 +0000
4241+++ src/location_service/com/ubuntu/location/providers/gps/sntp_client.h 2016-04-01 06:55:25 +0000
4242@@ -0,0 +1,210 @@
4243+/*
4244+ * Copyright © 2012-2013 Canonical Ltd.
4245+ *
4246+ * This program is free software: you can redistribute it and/or modify it
4247+ * under the terms of the GNU Lesser General Public License version 3,
4248+ * as published by the Free Software Foundation.
4249+ *
4250+ * This program is distributed in the hope that it will be useful,
4251+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4252+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4253+ * GNU Lesser General Public License for more details.
4254+ *
4255+ * You should have received a copy of the GNU Lesser General Public License
4256+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4257+ *
4258+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
4259+ */
4260+#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_CLIENT_H_
4261+#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_CLIENT_H_
4262+
4263+#include <com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h>
4264+
4265+#include <boost/asio.hpp>
4266+#include <boost/endian/buffers.hpp>
4267+
4268+#include <chrono>
4269+#include <string>
4270+
4271+namespace com { namespace ubuntu { namespace location { namespace providers { namespace gps { namespace sntp {
4272+// Please see https://tools.ietf.org/html/rfc4330 for a discussion of sntp
4273+// and for a detailed explanation of the different types and algorithms.
4274+
4275+namespace detail
4276+{
4277+// enum_constant returns a compile-time constant assembled from 4 or at least
4278+// 3 individual characters.
4279+template<std::uint8_t a, std::uint8_t b, std::uint8_t c, std::uint8_t d = 0>
4280+constexpr uint32_t enum_constant()
4281+{
4282+ return (a << 24) | (b << 16) | (c << 8) | d;
4283+}
4284+}
4285+
4286+// offset_1900_to_1970 returns the number of seconds that elapsed between 1900 and 1970.
4287+const std::chrono::seconds& offset_1900_to_1970();
4288+
4289+// LeapIndicator enumerates warnings of an impending
4290+// leap second to be inserted/deleted in the last minute of the current
4291+// day.
4292+enum class LeapIndicator : std::uint8_t
4293+{
4294+ no_warning = 0,
4295+ last_minute_has_61_seconds = 1,
4296+ last_minute_has_59_seconds = 2,
4297+ alarm = 3
4298+};
4299+
4300+// Mode enumerates the different protocol modes.
4301+enum class Mode : std::uint8_t
4302+{
4303+ reserved = 0,
4304+ symmetric_active = 1,
4305+ symmetric_passive = 2,
4306+ client = 3,
4307+ server = 4,
4308+ broadcast = 5,
4309+ reserved_for_control = 6,
4310+ reserved_for_private_use = 7
4311+};
4312+
4313+// ReferenceIdentifier enumerates known references for NTP-servers
4314+// on stratum 0 or 1.
4315+enum class ReferenceIdentifier : std::uint32_t
4316+{
4317+ locl = detail::enum_constant<'L','O','C','L'>(), // uncalibrated local clock
4318+ cesm = detail::enum_constant<'C','E','S','M'>(), // calibrated Cesium clock
4319+ rbdm = detail::enum_constant<'R','B','D','M'>(), // calibrated Rubidium clock
4320+ pps = detail::enum_constant<'P','P','S'>(), // calibrated quartz clock or other pulse-per-second source
4321+ irig = detail::enum_constant<'I','R','I','G'>(), // Inter-Range Instrumentation Group
4322+ acts = detail::enum_constant<'A','C','T','S'>(), // NIST telephone modem service
4323+ usno = detail::enum_constant<'U','S','N','O'>(), // USNO telephone modem service
4324+ ptb = detail::enum_constant<'P','T','B'>(), // PTB (Germany) telephone modem service
4325+ tdf = detail::enum_constant<'T','D','F'>(), // Allouis (France) Radio 164 kHz
4326+ dcf = detail::enum_constant<'D','C','F'>(), // Mainflingen (Germany) Radio 77.5 kHz
4327+ msf = detail::enum_constant<'M','S', 'F'>(), // Rugby (UK) Radio 60 kHz
4328+ wwv = detail::enum_constant<'W','W','V'>(), // Ft. Collins (US) Radio 2.5, 5, 10, 15, 20 MHz
4329+ wwvb = detail::enum_constant<'W','W','V','B'>(), // Boulder (US) Radio 60 kHz
4330+ wwvh = detail::enum_constant<'W','W','V','H'>(), // Kauai Hawaii (US) Radio 2.5, 5, 10, 15 MHz
4331+ chu = detail::enum_constant<'C','H','U'>(), // Ottawa (Canada) Radio 3330, 7335, 14670 kHz
4332+ lorc = detail::enum_constant<'L','O','R','C'>(), // LORAN-C radionavigation system
4333+ omeg = detail::enum_constant<'O','M','E','G'>(), // OMEGA radionavigation system
4334+ gps = detail::enum_constant<'G','P','S'>() // Global Positioning Service
4335+};
4336+
4337+// Timestamp models a fixed-point NTP timestamp relative to 01.01.1900
4338+template<typename Seconds, typename FractionalSeconds = Seconds>
4339+struct Timestamp
4340+{
4341+ // To stay on the safe side, we only allow for the types specified below.
4342+ // With that, we make sure that we only ever use endian-save types.
4343+ static_assert(std::is_same<Seconds, boost::endian::big_int16_buf_t>::value ||
4344+ std::is_same<Seconds, boost::endian::big_uint16_buf_t>::value ||
4345+ std::is_same<Seconds, boost::endian::big_int32_buf_t>::value ||
4346+ std::is_same<Seconds, boost::endian::big_uint32_buf_t>::value,
4347+ "Timestamp<> only supports boost::endian::big_{{u}int{16,32}}_buf_t");
4348+
4349+ // from_milliseconds_since_epoch fills in seconds/fractional_seconds from
4350+ // ms, converting to NTP's reference time.
4351+ void from_milliseconds_since_epoch(const std::chrono::milliseconds& ts)
4352+ {
4353+ using s = std::chrono::seconds;
4354+ using ms = std::chrono::milliseconds;
4355+
4356+ auto secs = std::chrono::duration_cast<s>(ts);
4357+ auto msecs = std::chrono::duration_cast<ms>(ts - secs);
4358+
4359+ secs += offset_1900_to_1970();
4360+
4361+ seconds = secs.count();
4362+ fractional_seconds = msecs.count() * std::numeric_limits<typename FractionalSeconds::value_type>::max() + 1 / 1000;
4363+ }
4364+
4365+ // to_milliseconds_since_epoch returns a unix timestamp calculated from
4366+ // an NTP-timestamp.
4367+ std::chrono::milliseconds to_milliseconds_since_epoch() const
4368+ {
4369+ return std::chrono::seconds{seconds.value()} - offset_1900_to_1970() +
4370+ std::chrono::milliseconds{(fractional_seconds.value() * 1000) / std::numeric_limits<typename FractionalSeconds::value_type>::max()};
4371+ }
4372+
4373+ Seconds seconds;
4374+ FractionalSeconds fractional_seconds;
4375+};
4376+
4377+// Duration is just an alias to an sntp::Timestamp.
4378+template<typename T, typename U>
4379+using Duration = Timestamp<T, U>;
4380+
4381+// Packet models the SNTP wire format.
4382+struct Packet
4383+{
4384+ // LeapIndicatorVersionMode helps in handling the bitfield setup
4385+ // for the first byte of an sntp::Packet in a portable and endianess-safe way.
4386+ struct LeapIndicatorVersionMode
4387+ {
4388+ // leap_indicator extracts the LeapIndicator from the underlying data.
4389+ LeapIndicator leap_indicator() const;
4390+ // leap_indicator sets the value of the leap_indicatorin in the underyling
4391+ // data to li.
4392+ LeapIndicatorVersionMode& leap_indicator(LeapIndicator li);
4393+
4394+ // version extracts the version from the underlying data.
4395+ std::uint8_t version() const;
4396+ // version adjusts the version to version in the underlying data.
4397+ LeapIndicatorVersionMode& version(std::uint8_t version);
4398+
4399+ // mode extracts the mode from the underlying data.
4400+ Mode mode() const;
4401+ // mode adjusts the mode to m in the underlying data.
4402+ LeapIndicatorVersionMode& mode(Mode m);
4403+
4404+ boost::endian::big_uint8_buf_t livm;
4405+ };
4406+
4407+ LeapIndicatorVersionMode livm;
4408+ boost::endian::big_uint8_buf_t stratum;
4409+ boost::endian::big_uint8_buf_t poll_interval;
4410+ boost::endian::big_int8_buf_t precision;
4411+ Duration<boost::endian::big_int16_buf_t, boost::endian::big_uint16_buf_t> root_delay;
4412+ Duration<boost::endian::big_uint16_buf_t, boost::endian::big_uint16_buf_t> root_dispersion;
4413+ boost::endian::big_uint32_buf_t reference_identifier;
4414+ Timestamp<boost::endian::big_uint32_buf_t> reference;
4415+ Timestamp<boost::endian::big_uint32_buf_t> originate;
4416+ Timestamp<boost::endian::big_uint32_buf_t> receive;
4417+ Timestamp<boost::endian::big_uint32_buf_t> transmit;
4418+};
4419+// The SNTP version we are working with.
4420+static constexpr const std::uint8_t version = 3;
4421+
4422+// SntpClient provides access to querying time from an NTP server in
4423+// a unicast scenario.
4424+class Client
4425+{
4426+public:
4427+ // Response is returned in a request for time information.
4428+ struct Response
4429+ {
4430+ // The raw packet that was returned from the request.
4431+ sntp::Packet packet;
4432+ // Time computed from the NTP transaction.
4433+ std::chrono::milliseconds ntp_time;
4434+ // Reference clock value corresponding to the NTP time.
4435+ std::chrono::milliseconds ntp_time_reference;
4436+ // Round-trip time of the last NTP transaction.
4437+ std::chrono::milliseconds round_trip_time;
4438+ };
4439+
4440+ // request_time_with_timeout reaches out to the SNTP server known under host,
4441+ // and tries to determine the current UTC reference time. The operation aborts after
4442+ // timeout milliseconds.
4443+ //
4444+ // std::runtime_error is thrown in case of issues.
4445+ Response request_time(const std::string& host, const std::chrono::milliseconds& timeout, boost::asio::io_service& ios);
4446+ sntp::Packet request(boost::asio::ip::udp::socket& socket);
4447+};
4448+}
4449+}
4450+
4451+}}}}
4452+#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_CLIENT_H_
4453
4454=== added file 'src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.cpp'
4455--- src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.cpp 1970-01-01 00:00:00 +0000
4456+++ src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.cpp 2016-04-01 06:55:25 +0000
4457@@ -0,0 +1,57 @@
4458+/*
4459+ * Copyright © 2012-2013 Canonical Ltd.
4460+ *
4461+ * This program is free software: you can redistribute it and/or modify it
4462+ * under the terms of the GNU Lesser General Public License version 3,
4463+ * as published by the Free Software Foundation.
4464+ *
4465+ * This program is distributed in the hope that it will be useful,
4466+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4467+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4468+ * GNU Lesser General Public License for more details.
4469+ *
4470+ * You should have received a copy of the GNU Lesser General Public License
4471+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4472+ *
4473+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
4474+ */
4475+
4476+#include <com/ubuntu/location/providers/gps/sntp_reference_time_source.h>
4477+
4478+#include <com/ubuntu/location/configuration.h>
4479+#include <com/ubuntu/location/service/runtime.h>
4480+
4481+#include <boost/property_tree/ini_parser.hpp>
4482+
4483+#include <future>
4484+
4485+namespace location = com::ubuntu::location;
4486+namespace gps = com::ubuntu::location::providers::gps;
4487+
4488+gps::SntpReferenceTimeSource::Configuration gps::SntpReferenceTimeSource::Configuration::from_gps_conf_ini_file(std::istream& in)
4489+{
4490+ gps::SntpReferenceTimeSource::Configuration result;
4491+
4492+ location::Configuration config;
4493+ boost::property_tree::read_ini(in, config);
4494+
4495+ if (config.count("NTP_SERVER") > 0)
4496+ result.host = config.get<std::string>("NTP_SERVER");
4497+
4498+ return result;
4499+}
4500+gps::SntpReferenceTimeSource::SntpReferenceTimeSource(const Configuration& config)
4501+ : config(config)
4502+{
4503+}
4504+
4505+gps::HardwareAbstractionLayer::ReferenceTimeSample gps::SntpReferenceTimeSource::sample()
4506+{
4507+ auto rt = location::service::Runtime::create();
4508+ rt->start();
4509+
4510+ location::providers::gps::sntp::Client sntp_client;
4511+ auto result = sntp_client.request_time(config.host, config.timeout, rt->service());
4512+
4513+ return {result.ntp_time, result.ntp_time_reference, result.round_trip_time};
4514+}
4515
4516=== added file 'src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.h'
4517--- src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.h 1970-01-01 00:00:00 +0000
4518+++ src/location_service/com/ubuntu/location/providers/gps/sntp_reference_time_source.h 2016-04-01 06:55:25 +0000
4519@@ -0,0 +1,51 @@
4520+/*
4521+ * Copyright © 2016 Canonical Ltd.
4522+ *
4523+ * This program is free software: you can redistribute it and/or modify it
4524+ * under the terms of the GNU Lesser General Public License version 3,
4525+ * as published by the Free Software Foundation.
4526+ *
4527+ * This program is distributed in the hope that it will be useful,
4528+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4529+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4530+ * GNU Lesser General Public License for more details.
4531+ *
4532+ * You should have received a copy of the GNU Lesser General Public License
4533+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4534+ *
4535+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
4536+ */
4537+#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_REFERENCE_TIME_SOURCE_H_
4538+#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_REFERENCE_TIME_SOURCE_H_
4539+
4540+#include <com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h>
4541+
4542+#include <com/ubuntu/location/providers/gps/sntp_client.h>
4543+
4544+namespace com { namespace ubuntu { namespace location { namespace providers { namespace gps {
4545+
4546+class SntpReferenceTimeSource : public android::HardwareAbstractionLayer::ReferenceTimeSource
4547+{
4548+public:
4549+
4550+ /** @brief Configuration summarizes default parameter available to implementations. */
4551+ struct Configuration
4552+ {
4553+ /** @brief Reads a configuration from a gps.conf file in INI format. */
4554+ static Configuration from_gps_conf_ini_file(std::istream& in);
4555+
4556+ std::string host{"pool.ntp.org"}; /**< NTP host. */
4557+ std::chrono::milliseconds timeout{5000}; /**< Timeout when querying the NTP server. */
4558+ };
4559+
4560+ SntpReferenceTimeSource(const Configuration& configuration);
4561+
4562+ gps::HardwareAbstractionLayer::ReferenceTimeSample sample() override;
4563+
4564+private:
4565+ const Configuration config;
4566+};
4567+
4568+}}}}}
4569+
4570+#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GPS_SNTP_REFERENCE_TIME_SOURCE_H_
4571
4572=== modified file 'src/location_service/com/ubuntu/location/providers/remote/provider.cpp'
4573--- src/location_service/com/ubuntu/location/providers/remote/provider.cpp 2015-04-14 18:54:00 +0000
4574+++ src/location_service/com/ubuntu/location/providers/remote/provider.cpp 2016-04-01 06:55:25 +0000
4575@@ -23,6 +23,7 @@
4576 #include <com/ubuntu/location/logging.h>
4577
4578 #include <core/dbus/object.h>
4579+#include <core/dbus/service_watcher.h>
4580 #include <core/dbus/signal.h>
4581 #include <core/dbus/asio/executor.h>
4582
4583@@ -191,6 +192,28 @@
4584 auto service = dbus::Service::use_service(bus, name);
4585 auto object = service->object_for_path(path);
4586
4587+ // Check if the service has come up
4588+ if (!bus->has_owner_for_name(name)) {
4589+ // If it hasn't wait for it to come up
4590+ bool valid = false;
4591+ std::mutex guard;
4592+ std::condition_variable cv;
4593+ dbus::DBus daemon(bus);
4594+ dbus::ServiceWatcher::Ptr service_watcher(
4595+ daemon.make_service_watcher(name, dbus::DBus::WatchMode::registration));
4596+
4597+ service_watcher->service_registered().connect([&valid, &guard, &cv]()
4598+ {
4599+ std::unique_lock<std::mutex> ul(guard);
4600+ valid = true;
4601+ cv.notify_all();
4602+ });
4603+
4604+ std::unique_lock<std::mutex> ul(guard);
4605+ if (not cv.wait_for(ul, std::chrono::seconds{30}, [&valid]() { return valid; }))
4606+ throw std::runtime_error("Remote service failed to start");
4607+ }
4608+
4609 return create_instance_with_config(remote::stub::Configuration{object});
4610 }
4611
4612
4613=== modified file 'src/location_service/com/ubuntu/location/service/daemon.cpp'
4614--- src/location_service/com/ubuntu/location/service/daemon.cpp 2015-04-16 10:03:29 +0000
4615+++ src/location_service/com/ubuntu/location/service/daemon.cpp 2016-04-01 06:55:25 +0000
4616@@ -20,6 +20,9 @@
4617 #include <com/ubuntu/location/boost_ptree_settings.h>
4618 #include <com/ubuntu/location/provider_factory.h>
4619
4620+#include <com/ubuntu/location/logging.h>
4621+#include <com/ubuntu/location/connectivity/dummy_connectivity_manager.h>
4622+
4623 #include <com/ubuntu/location/service/default_configuration.h>
4624 #include <com/ubuntu/location/service/demultiplexing_reporter.h>
4625 #include <com/ubuntu/location/service/ichnaea_reporter.h>
4626@@ -30,6 +33,7 @@
4627
4628 #include "program_options.h"
4629 #include "daemon.h"
4630+#include "runtime.h"
4631
4632 #include <core/dbus/announcer.h>
4633 #include <core/dbus/resolver.h>
4634@@ -37,6 +41,9 @@
4635
4636 #include <core/posix/signal.h>
4637
4638+#include <boost/asio.hpp>
4639+#include <boost/filesystem.hpp>
4640+
4641 #include <system_error>
4642 #include <thread>
4643
4644@@ -164,6 +171,20 @@
4645
4646 int location::service::Daemon::main(const location::service::Daemon::Configuration& config)
4647 {
4648+ // Ensure that log files dating back to before the fix
4649+ // for lp:1447110 are removed and do not waste space.
4650+ {
4651+ static const boost::filesystem::path old_log_dir{"/var/log/ubuntu-location-service"};
4652+ boost::system::error_code ec;
4653+ boost::filesystem::remove_all(old_log_dir, ec);
4654+ }
4655+ // Setup logging for the daemon.
4656+ FLAGS_logtostderr = true;
4657+ FLAGS_stop_logging_if_full_disk = true;
4658+ FLAGS_max_log_size = 5;
4659+
4660+ google::InitGoogleLogging("com.ubuntu.location");
4661+
4662 auto trap = core::posix::trap_signals_for_all_subsequent_threads(
4663 {
4664 core::posix::Signal::sig_term,
4665@@ -175,116 +196,55 @@
4666 trap->stop();
4667 });
4668
4669- const location::Configuration empty_provider_configuration;
4670-
4671- std::set<location::Provider::Ptr> instantiated_providers;
4672-
4673+ auto runtime = location::service::Runtime::create(4);
4674+
4675+ location::service::DefaultConfiguration dc;
4676+ auto engine = dc.the_engine(std::set<location::Provider::Ptr>{}, dc.the_provider_selection_policy(), config.settings);
4677 for (const std::string& provider : config.providers)
4678 {
4679 std::cout << "Instantiating and configuring: " << provider << std::endl;
4680
4681 try
4682 {
4683- auto p = location::ProviderFactory::instance().create_provider_for_name_with_config(
4684- provider,
4685- config.provider_options.count(provider) > 0 ?
4686- config.provider_options.at(provider) : empty_provider_configuration);
4687-
4688- if (p)
4689- instantiated_providers.insert(p);
4690- else
4691- throw std::runtime_error("Problem instantiating provider");
4692-
4693+ auto result = std::async(std::launch::async, [provider, config, engine] {
4694+ return location::ProviderFactory::instance().create_provider_for_name_with_config(
4695+ provider,
4696+ config.provider_options.count(provider) > 0 ?
4697+ config.provider_options.at(provider) : location::Configuration {},
4698+ [engine](Provider::Ptr provider)
4699+ {
4700+ engine->add_provider(provider);
4701+ }
4702+ );
4703+ });
4704 } catch(const std::runtime_error& e)
4705 {
4706 std::cerr << "Issue instantiating provider: " << e.what() << std::endl;
4707 }
4708 }
4709
4710- config.incoming->install_executor(dbus::asio::make_executor(config.incoming));
4711- config.outgoing->install_executor(dbus::asio::make_executor(config.outgoing));
4712+ config.incoming->install_executor(dbus::asio::make_executor(config.incoming, runtime->service()));
4713+ config.outgoing->install_executor(dbus::asio::make_executor(config.outgoing, runtime->service()));
4714
4715- location::service::DefaultConfiguration dc;
4716+ runtime->start();
4717
4718 location::service::Implementation::Configuration configuration
4719 {
4720 config.incoming,
4721 config.outgoing,
4722- dc.the_engine(instantiated_providers, dc.the_provider_selection_policy(), config.settings),
4723+ engine,
4724 dc.the_permission_manager(config.outgoing),
4725 location::service::Harvester::Configuration
4726 {
4727- location::connectivity::platform_default_manager(),
4728- // We submit location/wifi/cell measurements to both
4729- // Mozilla's location service and to Ubuntu's own instance.
4730- std::make_shared<service::DemultiplexingReporter>(
4731- std::initializer_list<service::Harvester::Reporter::Ptr>
4732- {
4733- std::make_shared<service::ichnaea::Reporter>(
4734- service::ichnaea::Reporter::Configuration
4735- {
4736- "https://location.services.mozilla.com",
4737- "UbuntuLocationService",
4738- "UbuntuLocationService"
4739- }
4740- ),
4741- std::make_shared<service::ichnaea::Reporter>(
4742- service::ichnaea::Reporter::Configuration
4743- {
4744- "https://162.213.35.107",
4745- "UbuntuLocationService",
4746- "UbuntuLocationService"
4747- }
4748- )
4749- })
4750+ std::make_shared<dummy::ConnectivityManager>(),
4751+ std::make_shared<NullReporter>()
4752 }
4753 };
4754
4755 auto location_service = std::make_shared<location::service::Implementation>(configuration);
4756- // We need to ensure that any exception raised by the executor does not crash the app
4757- // and also gets logged.
4758- auto execute = [] (std::shared_ptr<core::dbus::Bus> bus) {
4759- while(true)
4760- {
4761- try
4762- {
4763- VLOG(10) << "Starting a bus executor";
4764- bus->run();
4765- break; // run() exited normally
4766- }
4767- catch (const std::exception& e)
4768- {
4769- LOG(WARNING) << e.what();
4770- }
4771- catch (...)
4772- {
4773- LOG(WARNING) << "Unexpected exception was raised by the bus executor";
4774- }
4775- }
4776- };
4777-
4778- std::thread t1{execute, config.incoming};
4779- std::thread t2{execute, config.incoming};
4780- std::thread t3{execute, config.incoming};
4781- std::thread t4{execute, config.outgoing};
4782
4783 trap->run();
4784
4785- config.incoming->stop();
4786- config.outgoing->stop();
4787-
4788- if (t1.joinable())
4789- t1.join();
4790-
4791- if (t2.joinable())
4792- t2.join();
4793-
4794- if (t3.joinable())
4795- t3.join();
4796-
4797- if (t4.joinable())
4798- t4.join();
4799-
4800 return EXIT_SUCCESS;
4801 }
4802
4803
4804=== modified file 'src/location_service/com/ubuntu/location/service/daemon_main.cpp'
4805--- src/location_service/com/ubuntu/location/service/daemon_main.cpp 2015-01-13 16:35:20 +0000
4806+++ src/location_service/com/ubuntu/location/service/daemon_main.cpp 2016-04-01 06:55:25 +0000
4807@@ -18,41 +18,10 @@
4808
4809 #include "daemon.h"
4810
4811-#include <com/ubuntu/location/logging.h>
4812-
4813-#include <boost/filesystem.hpp>
4814-
4815 namespace location = com::ubuntu::location;
4816
4817-namespace
4818-{
4819-// The directory we put log files in.
4820-constexpr const char* log_dir{"/var/log/ubuntu-location-service"};
4821-}
4822-
4823 int main(int argc, const char** argv)
4824 {
4825- // Setup logging for the daemon.
4826- boost::system::error_code ec;
4827- boost::filesystem::create_directories(boost::filesystem::path{log_dir}, ec);
4828-
4829- // According to http://www.boost.org/doc/libs/1_55_0/libs/filesystem/doc/reference.html#create_directories
4830- // Creation failure because p resolves to an existing directory shall not be treated as an error.
4831- // With that, we are free to check the error condition and adjust to stderr
4832- // logging accordingly.
4833- if (ec)
4834- {
4835- FLAGS_logtostderr = true;
4836- VLOG(1) << "Problem creating directory for log files: " << ec << "."
4837- << "Falling back to stderr logging.";
4838- }
4839-
4840- FLAGS_log_dir = log_dir;
4841- FLAGS_stop_logging_if_full_disk = true;
4842- FLAGS_max_log_size = 5;
4843-
4844- google::InitGoogleLogging("com.ubuntu.location");
4845-
4846 location::service::Daemon::Configuration config;
4847 try
4848 {
4849
4850=== modified file 'src/location_service/com/ubuntu/location/service/implementation.cpp'
4851--- src/location_service/com/ubuntu/location/service/implementation.cpp 2014-08-13 13:08:22 +0000
4852+++ src/location_service/com/ubuntu/location/service/implementation.cpp 2016-04-01 06:55:25 +0000
4853@@ -113,10 +113,13 @@
4854 {
4855 visible_space_vehicles() = svs;
4856 }),
4857- configuration.engine->updates.reference_location.changed().connect(
4858- [this](const cul::Update<cul::Position>& update)
4859+ configuration.engine->updates.last_known_location.changed().connect(
4860+ [this](const cul::Optional<cul::Update<cul::Position>>& update)
4861 {
4862- harvester.report_position_update(update);
4863+ if (update)
4864+ {
4865+ harvester.report_position_update(update.get());
4866+ }
4867 })
4868 }
4869 {
4870@@ -149,5 +152,23 @@
4871 new ProxyProvider{provider_selection}
4872 };
4873
4874- return session::Interface::Ptr{new culs::session::Implementation(proxy_provider)};
4875+ session::Interface::Ptr session_iface{new session::Implementation(proxy_provider)};
4876+ std::weak_ptr<session::Interface> session_weak{session_iface};
4877+ session_iface->updates().position_status.changed().connect([this, session_weak](const session::Interface::Updates::Status& status)
4878+ {
4879+ cul::Optional<cul::Update<cul::Position>> last_known_position = configuration.engine->updates.last_known_location.get();
4880+ bool has_last_known_position = last_known_position ? true : false;
4881+ bool is_session_enabled = status == culs::session::Interface::Updates::Status::enabled;
4882+ bool is_session_on_or_active = configuration.engine->configuration.engine_state != Engine::Status::off;
4883+
4884+ if (has_last_known_position && is_session_enabled && is_session_on_or_active)
4885+ {
4886+ // Immediately send the last known position to the client
4887+ if (auto session_iface = session_weak.lock())
4888+ {
4889+ session_iface->updates().position = last_known_position.get();
4890+ }
4891+ }
4892+ });
4893+ return session_iface;
4894 }
4895
4896=== modified file 'src/location_service/com/ubuntu/location/service/provider_daemon.cpp'
4897--- src/location_service/com/ubuntu/location/service/provider_daemon.cpp 2014-10-27 21:58:16 +0000
4898+++ src/location_service/com/ubuntu/location/service/provider_daemon.cpp 2016-04-01 06:55:25 +0000
4899@@ -25,6 +25,7 @@
4900
4901 #include <com/ubuntu/location/service/configuration.h>
4902 #include <com/ubuntu/location/service/program_options.h>
4903+#include <com/ubuntu/location/service/runtime.h>
4904
4905 #include <core/dbus/asio/executor.h>
4906
4907@@ -65,7 +66,6 @@
4908 location::service::ProviderDaemon::Configuration result;
4909
4910 result.connection = factory(mutable_daemon_options().bus());
4911- result.connection->install_executor(core::dbus::asio::make_executor(result.connection));
4912
4913 auto service = core::dbus::Service::add_service(
4914 result.connection,
4915@@ -108,7 +108,15 @@
4916 return result;
4917 }
4918
4919-int location::service::ProviderDaemon::main(const location::service::ProviderDaemon::Configuration& configuration)
4920+namespace
4921+{
4922+std::shared_ptr<location::service::Runtime> runtime()
4923+{
4924+ static const auto inst = location::service::Runtime::create(2);
4925+ return inst;
4926+}
4927+}
4928+int location::service::ProviderDaemon::main(const location::service::ProviderDaemon::Configuration& config)
4929 {
4930 auto trap = core::posix::trap_signals_for_all_subsequent_threads(
4931 {
4932@@ -121,27 +129,20 @@
4933 trap->stop();
4934 });
4935
4936- std::thread worker
4937- {
4938- [configuration]()
4939- {
4940- configuration.connection->run();
4941- }
4942- };
4943+ config.connection->install_executor(core::dbus::asio::make_executor(config.connection, runtime()->service()));
4944
4945 auto skeleton = location::providers::remote::skeleton::create_with_configuration(location::providers::remote::skeleton::Configuration
4946 {
4947- configuration.object,
4948- configuration.connection,
4949- configuration.provider
4950+ config.object,
4951+ config.connection,
4952+ config.provider
4953 });
4954
4955+ runtime()->start();
4956+
4957 trap->run();
4958
4959- configuration.connection->stop();
4960-
4961- if (worker.joinable())
4962- worker.join();
4963+ config.connection->stop();
4964
4965 return EXIT_SUCCESS;
4966 }
4967
4968=== added file 'src/location_service/com/ubuntu/location/service/runtime.cpp'
4969--- src/location_service/com/ubuntu/location/service/runtime.cpp 1970-01-01 00:00:00 +0000
4970+++ src/location_service/com/ubuntu/location/service/runtime.cpp 2016-04-01 06:55:25 +0000
4971@@ -0,0 +1,109 @@
4972+/*
4973+ * Copyright © 2015 Canonical Ltd.
4974+ *
4975+ * This program is free software: you can redistribute it and/or modify it
4976+ * under the terms of the GNU Lesser General Public License version 3,
4977+ * as published by the Free Software Foundation.
4978+ *
4979+ * This program is distributed in the hope that it will be useful,
4980+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4981+ * MERCHANTABILITY or FITNESS FOR A PARTIlocationAR PURPOSE. See the
4982+ * GNU Lesser General Public License for more details.
4983+ *
4984+ * You should have received a copy of the GNU Lesser General Public License
4985+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4986+ *
4987+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
4988+ */
4989+#include <com/ubuntu/location/service/runtime.h>
4990+
4991+#include <com/ubuntu/location/logging.h>
4992+
4993+namespace culs = com::ubuntu::location::service;
4994+
4995+namespace
4996+{
4997+// exception_safe_run runs service, catching all exceptions and
4998+// restarting operation until an explicit shutdown has been requested.
4999+//
5000+// TODO(tvoss): Catching all exceptions is risky as they might signal unrecoverable
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches